src/math/number.bend
bend-collections-laws-math@1.0.0.0 · 83 lines · 8 definitions
1import Base
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20type EGcd is Data:
21 EG{gcd: Nat, x: Nat, y: Nat, neg: Bool}
22
23
24
25
26def bit_count_go(fuel: Nat, +n: Nat, +acc: Nat) -> Nat:
27 match fuel n:
28 case 0n _:
29 acc
30 case 1n+f 0n:
31 acc
32 case 1n+f 1n+ +np:
33 bit_count_go(f, Nat.div(1n+np, 2n), Nat.add(acc, Nat.mod(1n+np, 2n)))
34
35def bit_count(+n: Nat) -> Nat:
36 bit_count_go(n, n, 0n)
37
38
39
40
41
42
43def eg_up(+q: Nat, r: EGcd) -> EGcd:
44 match r:
45 case EG{+g, +x, +y, neg}:
46 EG{g, y, Nat.add(x, Nat.mul(q, y)), Bool.not(neg)}
47
48
49def egcd_go(fuel: Nat, +a: Nat, +b: Nat) -> EGcd:
50 match fuel b:
51 case 0n _:
52 EG{a, 1n, 0n, False{}}
53 case 1n+f 0n:
54 EG{a, 1n, 0n, False{}}
55 case 1n+ +f 1n+ +bp:
56 eg_up(Nat.div(a, 1n+bp), egcd_go(f, 1n+bp, Nat.mod(a, 1n+bp)))
57
58def egcd(+a: Nat, +b: Nat) -> EGcd:
59 egcd_go(b, a, b)
60
61
62
63
64
65def prime_go(fuel: Nat, +n: Nat, +d: Nat, done: Bool, divides: Bool) -> Bool:
66 match fuel done divides:
67 case 0n _ _:
68 True{}
69 case 1n+f True{} _:
70 True{}
71 case 1n+f False{} True{}:
72 False{}
73 case 1n+ +f False{} False{}:
74 prime_go(f, n, 1n+d, Nat.is_lt(n, Nat.mul(1n+d, 1n+d)), Nat.is_eq(Nat.mod(n, 1n+d), 0n))
75
76def is_prime(+n: Nat) -> Bool:
77 match n:
78 case 0n:
79 False{}
80 case 1n:
81 False{}
82 case 2n+ +p:
83 prime_go(2n+p, 2n+p, 2n, Nat.is_lt(2n+p, 4n), Nat.is_eq(Nat.mod(2n+p, 2n), 0n))