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)