(.require [lux (.except function) ["_" test (.only Test)] [abstract [monad (.only do)] ["[0]" enum]] [control ["[0]" maybe]] [data [number ["n" nat]] [collection ["[0]" list (.use "[1]#[0]" functor)]]] [math ["r" random (.only Random) (.use "[1]#[0]" monad)]] [meta [compiler [analysis (.only Arity)] ["[0]" reference (.only Register)] ["[0]" synthesis (.only Synthesis)]]]] ["[0]" // ["[1][0]" case] [// [common (.only 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 (at ! 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)]] (all _.and (_.property "Can read arguments." (|> (synthesis.function/apply [synthesis.#function functionS synthesis.#arguments inputsS]) (run "with_local") (//case.verify expectation))) (_.property "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))))) (_.property "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))))) )))