blob: 0ed9cab76289353743e121310718f50f6e1a139f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
(.module:
[lux #*
[control
[monad (#+ Monad do)]]
[data
["." bit ("#/." equivalence)]
[number
["." frac ("#/." number)]]]
["&" math
infix
["r" random]]]
lux/test)
(def: (within? margin-of-error standard value)
(-> Frac Frac Frac Bit)
(f/< margin-of-error
(frac/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))))
(context: "Trigonometry"
(<| (times 100)
(do @
[angle (|> r.frac (:: @ map (f/* &.tau)))]
($_ seq
(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"
(<| (times 100)
(do @
[sample (|> r.frac (:: @ map (f/* +1000.0)))]
($_ seq
(test "The ceiling will be an integer value, and will be >= the original."
(let [ceil'd (&.ceil sample)]
(and (|> ceil'd frac-to-int int-to-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 frac-to-int int-to-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 frac-to-int int-to-frac (f/= round'd))
(f/<= +1.0 (frac/abs (f/- sample round'd))))))
))))
(context: "Exponentials and logarithms"
(<| (times 100)
(do @
[sample (|> r.frac (:: @ map (f/* +10.0)))]
(test "Logarithm is the inverse of exponential."
(|> sample &.exp &.log (within? +1.0e-15 sample))))))
(context: "Greatest-Common-Divisor and Least-Common-Multiple"
(<| (times 100)
(do @
[#let [gen-nat (|> r.nat (:: @ map (|>> (n/% 1000) (n/max 1))))]
x gen-nat
y gen-nat]
($_ seq
(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))))
))))
(context: "Infix syntax"
(<| (times 100)
(do @
[x r.nat
y r.nat
z r.nat
theta r.frac
#let [top (|> x (n/max y) (n/max z))
bottom (|> x (n/min y) (n/min z))]]
($_ seq
(test "Constant values don't change."
(n/= x
(infix x)))
(test "Can call binary functions."
(n/= (&.n/gcd y x)
(infix [x &.n/gcd y])))
(test "Can call unary functions."
(f/= (&.sin theta)
(infix [&.sin theta])))
(test "Can use regular syntax in the middle of infix code."
(n/= (&.n/gcd 450 (n/* 3 9))
(infix [(n/* 3 9) &.n/gcd 450])))
(test "Can use non-numerical functions/macros as operators."
(bit/= (and (n/< y x) (n/< z y))
(infix [[x n/< y] and [y n/< z]])))
(test "Can combine bit operations in special ways via special keywords."
(and (bit/= (and (n/< y x) (n/< z y))
(infix [#and x n/< y n/< z]))
(bit/= (and (n/< y x) (n/> z y))
(infix [#and x n/< y n/> z]))))
))))
|