(.module: [lux #* ["_" test (#+ Test)] [abstract [monad (#+ do)]] [control [pipe (#+ case>)] ["." maybe] ["." try]] [data [number ["n" nat] ["i" int]] ["." text ("#\." equivalence) ["%" format (#+ format)]] [collection ["." array (#+ Array)] ["." list ("#\." functor)]]] [math ["r" random]] ["." ffi (#+ import:)] [tool [compiler ["." analysis] ["." synthesis]]]] [/// [common (#+ Runner)]]) (import: java/lang/Integer) (def: (variant run) (-> Runner Test) (do {! r.monad} [num_tags (|> r.nat (\ ! each (|>> (n.% 10) (n.max 2)))) tag_in (|> r.nat (\ ! each (n.% num_tags))) .let [last?_in (|> num_tags -- (n.= tag_in))] value_in r.i64] (_.test (%.name (name_of synthesis.variant)) (|> (synthesis.variant {#analysis.lefts (if last?_in (-- tag_in) tag_in) #analysis.right? last?_in #analysis.value (synthesis.i64 value_in)}) (run "variant") (case> (#try.Success valueT) (let [valueT (:as (Array Any) valueT)] (and (n.= 3 (array.size valueT)) (let [tag_out (:as java/lang/Integer (maybe.trusted (array.read! 0 valueT))) last?_out (array.read! 1 valueT) value_out (:as Any (maybe.trusted (array.read! 2 valueT))) same_tag? (|> tag_out ffi.int_to_long (:as Nat) (n.= tag_in)) same_flag? (case last?_out (#.Some last?_out') (and last?_in (text\= "" (:as Text last?_out'))) #.None (not last?_in)) same_value? (|> value_out (:as Int) (i.= value_in))] (and same_tag? same_flag? same_value?)))) (#try.Failure _) false))))) (def: (tuple run) (-> Runner Test) (do {! r.monad} [size (|> r.nat (\ ! each (|>> (n.% 10) (n.max 2)))) tuple_in (r.list size r.i64)] (_.test (%.name (name_of synthesis.tuple)) (|> (synthesis.tuple (list\each (|>> synthesis.i64) tuple_in)) (run "tuple") (case> (#try.Success tuple_out) (let [tuple_out (:as (Array Any) tuple_out)] (and (n.= size (array.size tuple_out)) (list.every? (function (_ [left right]) (i.= left (:as Int right))) (list.zipped/2 tuple_in (array.list tuple_out))))) (#try.Failure _) false))))) (def: .public (spec runner) (-> Runner Test) ($_ _.and (..variant runner) (..tuple runner) ))