bsearch.bend
bend-osdev-algo@0.1.0.0 · 140 lines · 19 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import Base
17
18
19def bsearch.sorted.pair(xs: List<&2, U32>, x: U32) -> Bool:
20 match xs:
21 case Nil{}:
22 True{}
23 case Con{+y, t}:
24 Bool.and(U32.is_le(x, y), bsearch.sorted.pair(t, y))
25
26def bsearch.sorted(xs: List<&2, U32>) -> Bool:
27 match xs:
28 case Nil{}:
29 True{}
30 case Con{x, t}:
31 bsearch.sorted.pair(t, x)
32
33
34
35def bsearch.below.step(c: Bool, k: Nat) -> Nat:
36 match c:
37 case True{}:
38 1n+k
39 case False{}:
40 0n
41
42
43
44def bsearch.lower_bound(xs: List<&2, U32>, +key: U32) -> Nat:
45 match xs:
46 case Nil{}:
47 0n
48 case Con{x, t}:
49 bsearch.below.step(U32.is_lt(x, key), bsearch.lower_bound(t, key))
50
51def bsearch.find.hit(c: Bool, i: Nat) -> Maybe<&2, Nat>:
52 match c:
53 case True{}:
54 Some{i}
55 case False{}:
56 None{}
57
58def bsearch.find.check(+i: Nat, m: Maybe<&2, U32>, key: U32) -> Maybe<&2, Nat>:
59 match m:
60 case None{}:
61 None{}
62 case Some{x}:
63 bsearch.find.hit(U32.is_eq(x, key), i)
64
65
66def bsearch.find(+xs: List<&2, U32>, +key: U32) -> Maybe<&2, Nat>:
67 +i = bsearch.lower_bound(xs, key)
68 bsearch.find.check(i, List.get(&2, U32, xs, i), key)
69
70
71
72def bsearch.array.fin(r: Array<U32> & U32) -> Array<U32>:
73 (a, x) = r
74 a
75
76def bsearch.array.val(r: Array<U32> & U32) -> U32:
77 (a, x) = r
78 x
79
80
81type BsearchState is Type:
82 BsearchState{a: Array<U32>, lo: U32, hi: U32}
83
84
85def bsearch.array.pick(below: Bool, a: Array<U32>, +lo: U32, +hi: U32, +mid: U32) -> BsearchState:
86 match below:
87 case True{}:
88 BsearchState{a, U32.inc(mid), hi}
89 case False{}:
90 BsearchState{a, lo, mid}
91
92def bsearch.array.step(active: Bool, r: Array<U32> & U32, +key: U32, +lo: U32, +hi: U32, +mid: U32) -> BsearchState:
93 match active:
94 case True{}:
95 (a, +x) = r
96 bsearch.array.pick(U32.is_lt(x, key), a, lo, hi, mid)
97 case False{}:
98 (a, x) = r
99 BsearchState{a, lo, hi}
100
101def bsearch.array.advance(st: BsearchState, +key: U32) -> BsearchState:
102 match st:
103 case BsearchState{a, +lo, +hi}:
104 +mid = U32.add(lo, U32.shr(U32.sub(hi, lo)))
105 bsearch.array.step(U32.is_lt(lo, hi), Array.get(U32, a, mid), key, lo, hi, mid)
106
107def bsearch.array.result(st: BsearchState) -> Array<U32> & U32:
108 match st:
109 case BsearchState{a, lo, hi}:
110 (a, lo)
111
112
113
114def bsearch.array.go(fuel: Nat, st: BsearchState, +key: U32) -> Array<U32> & U32:
115 match fuel:
116 case 0n:
117 bsearch.array.result(st)
118 case 1n+f:
119 bsearch.array.go(f, bsearch.array.advance(st, key), key)
120
121
122def bsearch.array_lower_bound(a: Array<U32>, n: U32, key: U32) -> Array<U32> & U32:
123 bsearch.array.go(33n, BsearchState{a, 0, n}, key)
124
125def bsearch.array.found(inside: Bool, r: Array<U32> & U32, +i: U32, +key: U32) -> Array<U32> & Maybe<&2, U32>:
126 match inside:
127 case True{}:
128 (a, +x) = r
129 (a, Bool.pick(Maybe<&2, U32>, U32.is_eq(x, key), Some{i}, None{}))
130 case False{}:
131 (a, x) = r
132 (a, None{})
133
134def bsearch.array.find(r: Array<U32> & U32, +n: U32, +key: U32) -> Array<U32> & Maybe<&2, U32>:
135 (a, +i) = r
136 bsearch.array.found(U32.is_lt(i, n), Array.get(U32, a, i), i, key)
137
138
139def bsearch.array_find(a: Array<U32>, +n: U32, +key: U32) -> Array<U32> & Maybe<&2, U32>:
140 bsearch.array.find(bsearch.array_lower_bound(a, n, key), n, key)