blob: 3f313bd1237d5c28063417b6dee09d1b56e2145d (
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
|
(.module:
[library
[lux #*
["_" test (#+ Test)]
["." type ("#\." equivalence)]
[abstract
[monad (#+ do)]
["." predicate]
[\\specification
["$." equivalence]
["$." order]
["$." monoid]
["$." codec]]]
[control
["." try]
["." exception]]
[data
["." product]
["." bit ("#\." equivalence)]]
[math
["." random (#+ Random)]
[number
["i" int]]]]]
["$." // #_
["#" modulus]]
[\\library
["." /
["/#" // #_
["#" modulus]]]])
(def: #export (random modulus)
(All [%] (-> (//.Modulus %) (Random (/.Mod %))))
(\ random.monad map
(/.modular modulus)
random.int))
(def: #export test
Test
(<| (_.covering /._)
(_.for [/.Mod])
(do random.monad
[param\\% ($//.random +1,000,000)
param (..random param\\%)
subject\\% (random.only (predicate.intersect (|>> //.divisor (i.> +2))
(|>> (//.= param\\%) not))
($//.random +1,000,000))
subject (..random subject\\%)
another (..random subject\\%)]
(`` ($_ _.and
(_.for [/.equivalence /.=]
($equivalence.spec /.equivalence (..random subject\\%)))
(_.for [/.order /.<]
($order.spec /.order (..random subject\\%)))
(~~ (template [<compose> <monoid>]
[(_.for [<monoid> <compose>]
($monoid.spec /.equivalence (<monoid> subject\\%) (..random subject\\%)))]
[/.+ /.addition]
[/.* /.multiplication]
))
(_.for [/.codec]
($codec.spec /.equivalence (/.codec subject\\%) (..random subject\\%)))
(_.cover [/.incorrect_modulus]
(case (|> param
(\ (/.codec param\\%) encode)
(\ (/.codec subject\\%) decode))
(#try.Failure error)
(exception.match? /.incorrect_modulus error)
(#try.Success _)
false))
(_.cover [/.modulus]
(and (type\= (:of (/.modulus subject))
(:of (/.modulus subject)))
(not (type\= (:of (/.modulus subject))
(:of (/.modulus param))))))
(_.cover [/.modular /.value]
(/.= subject
(/.modular (/.modulus subject) (/.value subject))))
(_.cover [/.>]
(bit\= (/.> another subject)
(/.< subject another)))
(_.cover [/.<= /.>=]
(bit\= (/.<= another subject)
(/.>= subject another)))
(_.cover [/.-]
(let [zero (/.modular (/.modulus subject) +0)]
(and (/.= zero
(/.- subject subject))
(/.= subject
(/.- zero subject)))))
(_.cover [/.inverse]
(let [one (/.modular (/.modulus subject) +1)
co_prime? (i.co_prime? (//.divisor (/.modulus subject))
(/.value subject))]
(case (/.inverse subject)
(#.Some subject^-1)
(and co_prime?
(|> subject
(/.* subject^-1)
(/.= one)))
#.None
(not co_prime?))))
(_.cover [/.adapter]
(<| (try.default false)
(do try.monad
[copy\\% (//.modulus (//.divisor subject\\%))
adapt (/.adapter subject\\% copy\\%)]
(wrap (|> subject
/.value
(/.modular copy\\%)
adapt
(/.= subject))))))
(_.cover [/.moduli_are_not_equal]
(case (/.adapter subject\\% param\\%)
(#try.Failure error)
(exception.match? /.moduli_are_not_equal error)
(#try.Success _)
false))
)))))
|