(.module: [lux #* ["%" data/text/format (#+ format)] ["_" test (#+ Test)] ["r" math/random (#+ Random)] [abstract/monad (#+ Monad do)] [data ["." bit ("#@." equivalence)] [number ["n" nat] ["." int] ["f" frac]]]] {1 ["." /]} ["." / #_ ["#." infix] ["#." modular] ["#." logic #_ ["#/." continuous] ["#/." fuzzy]]]) (def: (within? margin-of-error standard value) (-> Frac Frac Frac Bit) (f.< margin-of-error (f.abs (f.- standard value)))) (def: margin Frac +0.0000001) (def: (trigonometric-symmetry forward backward angle) (-> (-> Frac Frac) (-> Frac Frac) Frac Bit) (let [normal (|> angle forward backward)] (|> normal forward backward (within? margin normal)))) (def: #export test Test (<| (_.context (%.name (name-of /._))) ($_ _.and (<| (_.context "Trigonometry") (do {@ r.monad} [angle (|> r.safe-frac (:: @ map (f.* /.tau)))] ($_ _.and (_.test "Sine and arc-sine are inverse functions." (trigonometric-symmetry /.sin /.asin angle)) (_.test "Cosine and arc-cosine are inverse functions." (trigonometric-symmetry /.cos /.acos angle)) (_.test "Tangent and arc-tangent are inverse functions." (trigonometric-symmetry /.tan /.atan angle)) ))) (<| (_.context "Rounding") (do {@ r.monad} [sample (|> r.safe-frac (:: @ map (f.* +1000.0)))] ($_ _.and (_.test "The ceiling will be an integer value, and will be >= the original." (let [ceil'd (/.ceil sample)] (and (|> ceil'd f.int int.frac (f.= ceil'd)) (f.>= sample ceil'd) (f.<= +1.0 (f.- sample ceil'd))))) (_.test "The floor will be an integer value, and will be <= the original." (let [floor'd (/.floor sample)] (and (|> floor'd f.int int.frac (f.= floor'd)) (f.<= sample floor'd) (f.<= +1.0 (f.- floor'd sample))))) (_.test "The round will be an integer value, and will be < or > or = the original." (let [round'd (/.round sample)] (and (|> round'd f.int int.frac (f.= round'd)) (f.<= +1.0 (f.abs (f.- sample round'd)))))) ))) (<| (_.context "Exponentials and logarithms") (do {@ r.monad} [sample (|> r.safe-frac (:: @ map (f.* +10.0)))] (_.test "Logarithm is the inverse of exponential." (|> sample /.exp /.log (within? +0.000000000000001 sample))))) (<| (_.context "Greatest-Common-Divisor and Least-Common-Multiple") (do {@ r.monad} [#let [gen-nat (|> r.nat (:: @ map (|>> (n.% 1000) (n.max 1))))] x gen-nat y gen-nat] ($_ _.and (_.test "GCD" (let [gcd (n.gcd x y)] (and (n.= 0 (n.% gcd x)) (n.= 0 (n.% gcd y)) (n.>= 1 gcd)))) (_.test "LCM" (let [lcm (n.lcm x y)] (and (n.= 0 (n.% x lcm)) (n.= 0 (n.% y lcm)) (n.<= (n.* x y) lcm)))) ))) /infix.test /modular.test /logic/continuous.test /logic/fuzzy.test )))