aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/specification/compositor/generation/function.lux
diff options
context:
space:
mode:
authorEduardo Julian2021-07-15 00:45:15 -0400
committerEduardo Julian2021-07-15 00:45:15 -0400
commit0abd5bd3c0e38e352e9ba38268e04e1c858ab01e (patch)
treefe0af9e70413e9fc4f3848e0642920fca501c626 /stdlib/source/specification/compositor/generation/function.lux
parent89ca40f2f101b2b38187eab5cf905371cd47eb57 (diff)
Re-named "spec" hierarchy to "specification".
Diffstat (limited to 'stdlib/source/specification/compositor/generation/function.lux')
-rw-r--r--stdlib/source/specification/compositor/generation/function.lux93
1 files changed, 93 insertions, 0 deletions
diff --git a/stdlib/source/specification/compositor/generation/function.lux b/stdlib/source/specification/compositor/generation/function.lux
new file mode 100644
index 000000000..6d0f8d541
--- /dev/null
+++ b/stdlib/source/specification/compositor/generation/function.lux
@@ -0,0 +1,93 @@
+(.module:
+ [lux (#- function)
+ ["_" test (#+ Test)]
+ [abstract
+ [monad (#+ do)]
+ ["." enum]]
+ [control
+ [pipe (#+ case>)]]
+ [data
+ ["." maybe]
+ [number
+ ["n" nat]]
+ [collection
+ ["." list ("#\." functor)]]]
+ [math
+ ["r" random (#+ Random) ("#\." monad)]]
+ [tool
+ [compiler
+ [analysis (#+ Arity)]
+ ["." reference (#+ Register)]
+ ["." synthesis (#+ Synthesis)]]]]
+ ["." // #_
+ ["#." case]
+ [//
+ [common (#+ Runner)]]])
+
+(def: max-arity Arity 10)
+
+(def: arity
+ (Random Arity)
+ (|> r.nat (r\map (|>> (n.% max-arity) (n.max 1)))))
+
+(def: (local arity)
+ (-> Arity (Random Register))
+ (|> r.nat (r\map (|>> (n.% arity) inc))))
+
+(def: function
+ (Random [Arity Register Synthesis])
+ (do r.monad
+ [arity ..arity
+ local (..local arity)]
+ (wrap [arity local
+ (synthesis.function/abstraction
+ {#synthesis.environment (list)
+ #synthesis.arity arity
+ #synthesis.body (synthesis.variable/local local)})])))
+
+(def: #export (spec run)
+ (-> Runner Test)
+ (do {! r.monad}
+ [[arity local functionS] ..function
+ partial-arity (|> r.nat (\ ! map (|>> (n.% arity) (n.max 1))))
+ inputs (r.list arity r.safe-frac)
+ #let [expectation (maybe.assume (list.nth (dec local) inputs))
+ inputsS (list\map (|>> 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.take partial-arity inputsS)
+ postS (list.drop 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\map (|>> #reference.Local)))
+ variableS (if (n.<= partial-arity local)
+ (synthesis.variable/foreign (dec 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)))))
+ )))