aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/number/nat.lux
blob: 97f93dc538af3eb9953e34f971abf317319d6b9c (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
127
(.module:
  [lux #*
   ["_" test (#+ Test)]
   [abstract
    [monad (#+ do)]
    {[0 #spec]
     [/
      ["$." equivalence]
      ["$." hash]
      ["$." order]
      ["$." enum]
      ["$." interval]
      ["$." monoid]
      ["$." codec]]}]
   [data
    ["." bit ("#\." equivalence)]
    [number
     ["f" frac]]]
   [math
    ["." random]]]
  {1
   ["." /]})

(def: signature
  Test
  (`` ($_ _.and
          (_.for [/.equivalence /.=]
                 ($equivalence.spec /.equivalence random.nat))
          (_.for [/.hash]
                 ($hash.spec /.hash random.nat))
          (_.for [/.order /.<]
                 ($order.spec /.order random.nat))
          (_.for [/.enum]
                 ($enum.spec /.enum random.nat))
          (_.for [/.interval]
                 ($interval.spec /.interval random.nat))
          (~~ (template [<compose> <monoid>]
                [(_.for [<monoid> <compose>]
                        ($monoid.spec /.equivalence <monoid> random.nat))]
                
                [/.+ /.addition]
                [/.* /.multiplication]

                [/.min /.minimum]
                [/.max /.maximum]
                ))
          (~~ (template [<codec>]
                [(_.for [<codec>]
                        ($codec.spec /.equivalence <codec> random.nat))]

                [/.binary] [/.octal] [/.decimal] [/.hex]
                ))
          )))

(def: predicate
  Test
  (do {! random.monad}
    [sample random.nat]
    ($_ _.and
        (_.cover [/.even? /.odd?]
                 (bit\= (/.even? sample)
                        (not (/.odd? sample))))
        )))

(def: #export test
  Test
  (<| (_.covering /._)
      (_.for [.Nat])
      ($_ _.and
          (do random.monad
            [sample random.nat]
            ($_ _.and
                (_.cover [/.-]
                         (and (/.= 0 (/.- sample sample))
                              (/.= sample (/.- 0 sample))))
                (_.cover [/./]
                         (and (/.= 1 (/./ sample sample))
                              (/.= sample (/./ 1 sample))))
                ))
          (do random.monad
            [left random.nat
             right random.nat]
            ($_ _.and
                (_.cover [/.>]
                         (bit\= (/.> left right)
                                (/.< right left)))
                (_.cover [/.<= /.>=]
                         (bit\= (/.<= left right)
                                (/.>= right left)))
                ))
          (do random.monad
            [left (random.filter (|>> (/.= 0) not)
                                 random.nat)
             right random.nat]
            ($_ _.and
                (_.cover [/.%]
                         (let [rem (/.% left right)
                               div (|> right (/.- rem) (/./ left))]
                           (/.= right
                                (|> div (/.* left) (/.+ rem)))))
                (_.cover [/./%]
                         (let [[div rem] (/./% left right)]
                           (and (/.= div (/./ left right))
                                (/.= rem (/.% left right)))))
                ))
          (do {! random.monad}
            [#let [random (\ ! map (|>> (/.% 1,000) inc) random.nat)]
             left random
             right random]
            ($_ _.and
                (_.cover [/.gcd]
                         (let [gcd (/.gcd left right)]
                           (and (/.= 0 (/.% gcd left))
                                (/.= 0 (/.% gcd right)))))
                (_.cover [/.lcm]
                         (let [lcm (/.lcm left right)]
                           (and (/.= 0 (/.% left lcm))
                                (/.= 0 (/.% right lcm)))))
                ))
          (do {! random.monad}
            [expected (\ ! map (/.% 1,000,000) random.nat)]
            (_.cover [/.frac]
                     (|> expected /.frac f.nat (/.= expected))))

          ..predicate
          ..signature
          )))