(.module: [lux {"-" [function]} ["_" test {"+" [Test]}] [abstract [monad {"+" [do]}] ["[0]" enum]] [control [pipe {"+" [case>]}] ["[0]" maybe]] [data [number ["n" nat]] [collection ["[0]" list ("[1]\[0]" functor)]]] [math ["r" random {"+" [Random]} ("[1]\[0]" monad)]] [tool [compiler [analysis {"+" [Arity]}] ["[0]" reference {"+" [Register]}] ["[0]" synthesis {"+" [Synthesis]}]]]] ["[0]" // "_" ["[1][0]" case] [// [common {"+" [Runner]}]]]) (def: max_arity Arity 10) (def: arity (Random Arity) (|> r.nat (r\each (|>> (n.% max_arity) (n.max 1))))) (def: (local arity) (-> Arity (Random Register)) (|> r.nat (r\each (|>> (n.% arity) ++)))) (def: function (Random [Arity Register Synthesis]) (do r.monad [arity ..arity local (..local arity)] (in [arity local (synthesis.function/abstraction [synthesis.#environment (list) synthesis.#arity arity synthesis.#body (synthesis.variable/local local)])]))) (def: .public (spec run) (-> Runner Test) (do [! r.monad] [[arity local functionS] ..function partial_arity (|> r.nat (\ ! each (|>> (n.% arity) (n.max 1)))) inputs (r.list arity r.safe_frac) .let [expectation (maybe.trusted (list.item (-- local) inputs)) inputsS (list\each (|>> synthesis.f64) inputs)]] ($_ _.and (_.test "Can read arguments." (|> (synthesis.function/apply [synthesis.#function functionS synthesis.#arguments inputsS]) (run "with_local") (//case.verify expectation))) (_.test "Can partially apply functions." (or (n.= 1 arity) (let [preS (list.first partial_arity inputsS) postS (list.after partial_arity inputsS) partialS (synthesis.function/apply [synthesis.#function functionS synthesis.#arguments preS])] (|> (synthesis.function/apply [synthesis.#function partialS synthesis.#arguments postS]) (run "partial_application") (//case.verify expectation))))) (_.test "Can read environment." (or (n.= 1 arity) (let [environment (|> partial_arity (enum.range n.enum 1) (list\each (|>> {reference.#Local}))) variableS (if (n.<= partial_arity local) (synthesis.variable/foreign (-- local)) (synthesis.variable/local (|> local (n.- partial_arity)))) inner_arity (n.- partial_arity arity) innerS (synthesis.function/abstraction [synthesis.#environment environment synthesis.#arity inner_arity synthesis.#body variableS]) outerS (synthesis.function/abstraction [synthesis.#environment (list) synthesis.#arity partial_arity synthesis.#body innerS])] (|> (synthesis.function/apply [synthesis.#function outerS synthesis.#arguments inputsS]) (run "with_foreign") (//case.verify expectation))))) )))