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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
(;module:
lux
(lux [io]
(control monad
pipe)
(data number
[text "Text/" Monoid<Text> Eq<Text>]
text/format)
["R" math/random])
lux/test)
(do-template [category rand-gen <Eq> <Order>]
[(test: (format "[" category "] " "Eq & Order")
[x rand-gen
y rand-gen]
(assert "" (and (:: <Eq> = x x)
(or (:: <Eq> = x y)
(:: <Order> < y x)
(:: <Order> > y x)))))]
["Nat" R;nat Eq<Nat> Order<Nat>]
["Int" R;int Eq<Int> Order<Int>]
["Real" R;real Eq<Real> Order<Real>]
["Deg" R;deg Eq<Deg> Order<Deg>]
)
(do-template [category rand-gen <Number> <Order>]
[(test: (format "[" category "] " "Number")
[x rand-gen
#let [(^open) <Number>
(^open) <Order>]]
(assert "" (and (>= x (abs x))
## abs(0.0) == 0.0 && negate(abs(0.0)) == -0.0
(or (Text/= "Real" category)
(not (= x (negate x))))
(= x (negate (negate x)))
## There is loss of precision when multiplying
(or (Text/= "Deg" category)
(= x (* (signum x)
(abs x)))))))]
## ["Nat" R;nat Number<Nat>]
["Int" R;int Number<Int> Order<Int>]
["Real" R;real Number<Real> Order<Real>]
["Deg" R;deg Number<Deg> Order<Deg>]
)
(do-template [category rand-gen <Enum> <Number> <Order>]
[(test: (format "[" category "] " "Enum")
[x rand-gen]
(assert "" (let [(^open) <Number>
(^open) <Order>]
(and (> x
(:: <Enum> succ x))
(< x
(:: <Enum> pred x))
(= x
(|> x (:: <Enum> pred) (:: <Enum> succ)))
(= x
(|> x (:: <Enum> succ) (:: <Enum> pred)))
))))]
["Nat" R;nat Enum<Nat> Number<Nat> Order<Nat>]
["Int" R;int Enum<Int> Number<Int> Order<Int>]
)
(do-template [category rand-gen <Number> <Order> <Interval> <test>]
[(test: (format "[" category "] " "Interval")
[x (|> rand-gen (R;filter <test>))
#let [(^open) <Number>
(^open) <Order>]]
(assert "" (and (<= x (:: <Interval> bottom))
(>= x (:: <Interval> top)))))]
["Nat" R;nat Number<Nat> Order<Nat> Interval<Nat> (function [_] true)]
["Int" R;int Number<Int> Order<Int> Interval<Int> (function [_] true)]
## Both min and max values will be positive (thus, greater than zero)
["Real" R;real Number<Real> Order<Real> Interval<Real> (r.> 0.0)]
["Deg" R;deg Number<Deg> Order<Deg> Interval<Deg> (function [_] true)]
)
(do-template [category rand-gen <Number> <Order> <Monoid> <cap> <test>]
[(test: (format "[" category "] " "Monoid")
[x (|> rand-gen (:: @ map (|>. (:: <Number> abs) <cap>)) (R;filter <test>))
#let [(^open) <Number>
(^open) <Order>
(^open) <Monoid>]]
(assert "Appending to unit doesn't change the value."
(and (= x (append unit x))
(= x (append x unit))
(= unit (append unit unit)))))]
["Nat/Add" R;nat Number<Nat> Order<Nat> Add@Monoid<Nat> (n.% +1000) (function [_] true)]
["Nat/Mul" R;nat Number<Nat> Order<Nat> Mul@Monoid<Nat> (n.% +1000) (function [_] true)]
["Nat/Min" R;nat Number<Nat> Order<Nat> Min@Monoid<Nat> (n.% +1000) (function [_] true)]
["Nat/Max" R;nat Number<Nat> Order<Nat> Max@Monoid<Nat> (n.% +1000) (function [_] true)]
["Int/Add" R;int Number<Int> Order<Int> Add@Monoid<Int> (i.% 1000) (function [_] true)]
["Int/Mul" R;int Number<Int> Order<Int> Mul@Monoid<Int> (i.% 1000) (function [_] true)]
["Int/Min" R;int Number<Int> Order<Int> Min@Monoid<Int> (i.% 1000) (function [_] true)]
["Int/Max" R;int Number<Int> Order<Int> Max@Monoid<Int> (i.% 1000) (function [_] true)]
["Real/Add" R;real Number<Real> Order<Real> Add@Monoid<Real> (r.% 1000.0) (r.> 0.0)]
["Real/Mul" R;real Number<Real> Order<Real> Mul@Monoid<Real> (r.% 1000.0) (r.> 0.0)]
["Real/Min" R;real Number<Real> Order<Real> Min@Monoid<Real> (r.% 1000.0) (r.> 0.0)]
["Real/Max" R;real Number<Real> Order<Real> Max@Monoid<Real> (r.% 1000.0) (r.> 0.0)]
["Deg/Add" R;deg Number<Deg> Order<Deg> Add@Monoid<Deg> (d.% .125) (function [_] true)]
## ["Deg/Mul" R;deg Number<Deg> Order<Deg> Mul@Monoid<Deg> (d.% .125) (function [_] true)]
["Deg/Min" R;deg Number<Deg> Order<Deg> Min@Monoid<Deg> (d.% .125) (function [_] true)]
["Deg/Max" R;deg Number<Deg> Order<Deg> Max@Monoid<Deg> (d.% .125) (function [_] true)]
)
(do-template [<category> <rand-gen> <Eq> <Codec>]
[(test: (format "[" <category> "] " "Alternative formats")
[x <rand-gen>]
(assert "Can encode/decode values."
(|> x
(:: <Codec> encode)
(:: <Codec> decode)
(case> (#;Right x')
(:: <Eq> = x x')
(#;Left _)
false))))]
["Nat/Binary" R;nat Eq<Nat> Binary@Codec<Text,Nat>]
["Nat/Octal" R;nat Eq<Nat> Octal@Codec<Text,Nat>]
["Nat/Decimal" R;nat Eq<Nat> Codec<Text,Nat>]
["Nat/Hex" R;nat Eq<Nat> Hex@Codec<Text,Nat>]
["Int/Binary" R;int Eq<Int> Binary@Codec<Text,Int>]
["Int/Octal" R;int Eq<Int> Octal@Codec<Text,Int>]
["Int/Decimal" R;int Eq<Int> Codec<Text,Int>]
["Int/Hex" R;int Eq<Int> Hex@Codec<Text,Int>]
["Deg/Binary" R;deg Eq<Deg> Binary@Codec<Text,Deg>]
["Deg/Octal" R;deg Eq<Deg> Octal@Codec<Text,Deg>]
["Deg/Decimal" R;deg Eq<Deg> Codec<Text,Deg>]
["Deg/Hex" R;deg Eq<Deg> Hex@Codec<Text,Deg>]
["Real/Binary" R;real Eq<Real> Binary@Codec<Text,Real>]
["Real/Octal" R;real Eq<Real> Octal@Codec<Text,Real>]
["Real/Decimal" R;real Eq<Real> Codec<Text,Real>]
["Real/Hex" R;real Eq<Real> Hex@Codec<Text,Real>]
)
|