src/Keys.bend
mylsm-lsm-store@0.6.0.0 · 135 lines · 0 definitions
1import Base
2import bend-mathlib@0.7.5.0/string.bend as MString
3import bend-mathlib@0.7.5.0/bool.bend as MBool
4import bend-kit-bytes@0.3.2.0/bytes.bend as PackedBytes
5
6def Bytes.cmp.order(pair: PackedBytes.Bytes & PackedBytes.Bytes & Cmp) -> Cmp:
7 match pair:
8 case (_, _, order):
9 order
10
11def Bytes.cmp.with_inputs(
12 left: PackedBytes.Bytes,
13 right: PackedBytes.Bytes
14) -> PackedBytes.Bytes & PackedBytes.Bytes & Cmp:
15 PackedBytes.cmp(left, right)
16
17def Bytes.cmp(left: PackedBytes.Bytes, right: PackedBytes.Bytes) -> Cmp:
18 Bytes.cmp.order(Bytes.cmp.with_inputs(left, right))
19
20def Bytes.eq(left: PackedBytes.Bytes, right: PackedBytes.Bytes) -> Bool:
21 Cmp.is_eq(Bytes.cmp(left, right))
22
23# Total-order comparison for keys. Base's String.cmp hands the strings back
24# beside the verdict ((s1, s2), c); we take reusable copies and unpack via a
25# helper (a match cannot scrutinize the computed call directly).
26def unpack(pair: (String & String) & Cmp) -> Cmp:
27 match pair:
28 case ((_, _), c):
29 c
30
31# Handle cmp in the key ordering and comparison.
32def cmp(+s1: String, +s2: String) -> Cmp:
33 unpack(String.cmp(s1, s2))
34
35# Handle eq in the key ordering and comparison.
36def eq(+s1: String, +s2: String) -> Bool:
37 String.eq(s1, s2)
38
39# Small, coherent views of Cmp used by key-order laws and sorted-run code.
40def cmp_is_lt(ord: Cmp) -> Bool:
41 Cmp.is_lt(ord)
42
43# Compare whether is eq holds for the key ordering and comparison.
44def cmp_is_eq(ord: Cmp) -> Bool:
45 Cmp.is_eq(ord)
46
47# Compare whether is gt holds for the key ordering and comparison.
48def cmp_is_gt(ord: Cmp) -> Bool:
49 Cmp.is_gt(ord)
50
51# Compare whether is le holds for the key ordering and comparison.
52def cmp_is_le(ord: Cmp) -> Bool:
53 Cmp.is_le(ord)
54
55# Handle lt in the key ordering and comparison.
56def lt(+s1: String, +s2: String) -> Bool:
57 cmp_is_lt(cmp(s1, s2))
58
59# Handle le in the key ordering and comparison.
60def le(+s1: String, +s2: String) -> Bool:
61 cmp_is_le(cmp(s1, s2))
62
63# Handle implies in the key ordering and comparison.
64def implies(s1: Bool, s2: Bool) -> Bool:
65 match s1:
66 case False{}:
67 True{}
68 case True{}:
69 s2
70
71# True exactly when one of three arbitrary predicates is true.
72def one_hot3(first: Bool, second: Bool, third: Bool) -> Bool:
73 match first second third:
74 case True{} False{} False{}:
75 True{}
76 case False{} True{} False{}:
77 True{}
78 case False{} False{} True{}:
79 True{}
80 case _ _ _:
81 False{}
82
83# Cmp is intrinsically one-hot; this predicate gives K6 a reusable statement.
84def cmp_one_hot(+ord: Cmp) -> Bool:
85 one_hot3(cmp_is_lt(ord), cmp_is_eq(ord), cmp_is_gt(ord))
86
87# Compare whether one hot proof holds for the key ordering and comparison.
88def cmp_one_hot_proof(+ord: Cmp) -> {cmp_one_hot(ord) == True{} : Bool}:
89 match ord:
90 case LT{}:
91 {==}
92 case EQ{}:
93 {==}
94 case GT{}:
95 {==}
96
97# `String.eq` is defined by the EQ projection of `String.cmp` (Cmp.is_eq of
98# Pair.snd since bend 2.0.33); matching the handed-back comparison pair
99# exposes that definitional correspondence.
100def cmp_eq_pair(
101 pair: (String & String) & Cmp
102) -> {cmp_is_eq(unpack(pair)) == Cmp.is_eq(Pair.snd(String & String, Cmp, pair)) : Bool}:
103 match pair:
104 case ((a, b), c):
105 match c:
106 case LT{}:
107 {==}
108 case EQ{}:
109 {==}
110 case GT{}:
111 {==}
112
113# Compare whether eq bridge holds for the key ordering and comparison.
114def cmp_eq_bridge(+s1: String, +s2: String) -> {cmp_is_eq(cmp(s1, s2)) == eq(s1, s2) : Bool}:
115 %MString.internal_order_cmp(s1, s2) : {cmp_is_eq(cmp(s1, s2)) == Cmp.is_eq(_) : Bool}
116 cmp_eq_pair(String.cmp(s1, s2))
117
118# Reflexivity chain for open keys. Every product law about keyed lookup
119# rewrites with str_eq_refl; it rests on the layers below, down to bits,
120# proved in bend-mathlib's bool and string modules (hash-pinned by version).
121# (Proving Base's own primitives is the one exception to the trust-root
122# rule: without open-key comparison facts, NO keyed law is provable.)
123
124# Handle s cmp pair refl in the key ordering and comparison.
125def s_cmp_pair_refl(+str: String) -> {String.cmp(str, str) == ((str, str), EQ{}) : (String & String) & Cmp}:
126 MString.cmp_refl(str)
127
128# Handle str refl in the key ordering and comparison.
129def str_refl(+str: String) -> {cmp(str, str) == EQ{} : Cmp}:
130 %Equal.sym((String & String) & Cmp, String.cmp(str, str), ((str, str), EQ{}), s_cmp_pair_refl(str)) : {unpack(_) == EQ{} : Cmp}
131 {==}
132
133# Handle str eq refl in the key ordering and comparison.
134def str_eq_refl(+str: String) -> {eq(str, str) == True{} : Bool}:
135 MString.eq_refl(str)