@bjornpagen/bumbledb 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/COOKBOOK.md +33 -49
  2. package/README.md +3 -3
  3. package/dist/capacity.d.ts +24 -136
  4. package/dist/capacity.d.ts.map +1 -1
  5. package/dist/capacity.js +18 -40
  6. package/dist/capacity.js.map +1 -1
  7. package/dist/closed.d.ts +0 -156
  8. package/dist/closed.d.ts.map +1 -1
  9. package/dist/closed.js +0 -104
  10. package/dist/closed.js.map +1 -1
  11. package/dist/db.d.ts +7 -223
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +147 -396
  14. package/dist/db.js.map +1 -1
  15. package/dist/face.d.ts +0 -133
  16. package/dist/face.d.ts.map +1 -1
  17. package/dist/face.js +0 -33
  18. package/dist/face.js.map +1 -1
  19. package/dist/fields.d.ts +1 -145
  20. package/dist/fields.d.ts.map +1 -1
  21. package/dist/fields.js +2 -91
  22. package/dist/fields.js.map +1 -1
  23. package/dist/index.d.ts +11 -15
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +9 -13
  26. package/dist/index.js.map +1 -1
  27. package/dist/law.d.ts +111 -93
  28. package/dist/law.d.ts.map +1 -1
  29. package/dist/law.js +23 -27
  30. package/dist/law.js.map +1 -1
  31. package/dist/lower.d.ts +9 -35
  32. package/dist/lower.d.ts.map +1 -1
  33. package/dist/lower.js +8 -53
  34. package/dist/lower.js.map +1 -1
  35. package/dist/marshal.d.ts +0 -65
  36. package/dist/marshal.d.ts.map +1 -1
  37. package/dist/marshal.js +0 -72
  38. package/dist/marshal.js.map +1 -1
  39. package/dist/native.d.ts +25 -290
  40. package/dist/native.d.ts.map +1 -1
  41. package/dist/native.js +6 -66
  42. package/dist/native.js.map +1 -1
  43. package/dist/query/atom.d.ts +10 -276
  44. package/dist/query/atom.d.ts.map +1 -1
  45. package/dist/query/atom.js +1 -96
  46. package/dist/query/atom.js.map +1 -1
  47. package/dist/query/find.d.ts +10 -76
  48. package/dist/query/find.d.ts.map +1 -1
  49. package/dist/query/find.js +0 -30
  50. package/dist/query/find.js.map +1 -1
  51. package/dist/query/lower.d.ts +64 -146
  52. package/dist/query/lower.d.ts.map +1 -1
  53. package/dist/query/lower.js +19 -256
  54. package/dist/query/lower.js.map +1 -1
  55. package/dist/query/parse-ir.d.ts +0 -7
  56. package/dist/query/parse-ir.d.ts.map +1 -1
  57. package/dist/query/parse-ir.js +1 -13
  58. package/dist/query/parse-ir.js.map +1 -1
  59. package/dist/query/run.d.ts +0 -36
  60. package/dist/query/run.d.ts.map +1 -1
  61. package/dist/query/run.js +0 -44
  62. package/dist/query/run.js.map +1 -1
  63. package/dist/query/scope.d.ts +24 -180
  64. package/dist/query/scope.d.ts.map +1 -1
  65. package/dist/query/scope.js +2 -66
  66. package/dist/query/scope.js.map +1 -1
  67. package/dist/relation.d.ts +2 -50
  68. package/dist/relation.d.ts.map +1 -1
  69. package/dist/relation.js +2 -37
  70. package/dist/relation.js.map +1 -1
  71. package/dist/schema.d.ts +13 -63
  72. package/dist/schema.d.ts.map +1 -1
  73. package/dist/schema.js +118 -92
  74. package/dist/schema.js.map +1 -1
  75. package/dist/spec.d.ts +1 -140
  76. package/dist/spec.d.ts.map +1 -1
  77. package/dist/spec.js +1 -68
  78. package/dist/spec.js.map +1 -1
  79. package/dist/statements.d.ts +6 -137
  80. package/dist/statements.d.ts.map +1 -1
  81. package/dist/statements.js +16 -119
  82. package/dist/statements.js.map +1 -1
  83. package/package.json +2 -2
  84. package/src/capacity.ts +26 -140
  85. package/src/closed.ts +5 -206
  86. package/src/db.ts +203 -692
  87. package/src/face.ts +0 -142
  88. package/src/fields.ts +4 -172
  89. package/src/index.ts +9 -15
  90. package/src/law.ts +201 -129
  91. package/src/lower.ts +8 -53
  92. package/src/marshal.ts +1 -85
  93. package/src/native.ts +47 -323
  94. package/src/query/atom.ts +26 -313
  95. package/src/query/find.ts +24 -110
  96. package/src/query/lower.ts +132 -377
  97. package/src/query/parse-ir.ts +1 -14
  98. package/src/query/run.ts +0 -45
  99. package/src/query/scope.ts +25 -186
  100. package/src/relation.ts +2 -66
  101. package/src/schema.ts +143 -122
  102. package/src/spec.ts +1 -160
  103. package/src/statements.ts +22 -174
package/src/query/atom.ts CHANGED
@@ -1,40 +1,9 @@
1
- /**
2
- * Atoms and conditions, REFERENCE-IDENTITY edition — the body vocabulary of
3
- * a rule, mirroring the engine IR variant for variant
4
- * (`bumbledb/crates/bumbledb/src/ir.rs`, the bijection target;
5
- * `docs/architecture/20-query-ir.md` normative). A `match` binding record
6
- * binds fields to VARIABLES (minted by {@link v}), params, ∈-set params, or
7
- * bare structural literals — a closed-reference field's literal is its
8
- * handle NAME, and a plain ARRAY of names there is membership
9
- * (unmentioned fields ARE the wildcard — no wildcard value exists);
10
- * `not(Rel, {...})` is negation-as-position (anti-join); `eq`/`ne` and the
11
- * order roster, `pointIn` (the one spelling of `ir::CmpOp::PointIn`,
12
- * always lowered interval-left), `allen` (the 13-bit mask pair
13
- * comparison), and `and`/`or` (the input condition-tree grammar) complete
14
- * the roster. Nothing beyond the IR exists here — and the walls the engine
15
- * enforces at prepare are TYPES first: a variable joins only class-equal
16
- * fields, judged at every binding position against the var's MINT slot
17
- * ({@link MintSlotOf}); because {@link JoinOk} is an equality, that ALONE
18
- * makes every cross-binding join transitively class-equal (the env/sibling
19
- * checks the name-keyed edition needed are gone). An interval-typed var
20
- * under a non-`pointIn` comparison is unwritable. BOUNDNESS (a negated
21
- * atom's variables must be positively bound) is the one check types cannot
22
- * carry — object identity is invisible to TS — so it is a construction-time
23
- * wall only.
24
- *
25
- * This module also owns the plain runtime DATA a built rule is made of
26
- * (`RuleData`/`InteriorData`/`RecData` and friends): frozen values the
27
- * lowering walks — pure data (variable references included), so lowering
28
- * stays a pure, stable function of the query value.
29
- */
30
-
31
1
  import * as errors from "@superbuilders/errors"
32
2
  import type { AnyField, ClosedIdField, ClosedRoster, Infer, IntervalValue } from "#fields.ts"
33
3
  import type { ClassLookup, ClassRecordOf, SchemaClasses } from "#law.ts"
34
4
  import type {
35
5
  AnyVar,
36
6
  ClassedField,
37
- Duration,
38
7
  JoinOk,
39
8
  MatchFields,
40
9
  MatchOwner,
@@ -47,11 +16,6 @@ import type {
47
16
  import { isTerm, term } from "#query/scope.ts"
48
17
  import type { FieldsShape } from "#relation.ts"
49
18
 
50
- /**
51
- * One atom-binding position as runtime data. A variable rides BY REFERENCE
52
- * (`ref`) — object identity is the join. `literalSet` is a membership
53
- * ARRAY at a closed-reference field, folded into the query.
54
- */
55
19
  type BindingTermData =
56
20
  | { readonly kind: "var"; readonly ref: AnyVar }
57
21
  | { readonly kind: "param"; readonly name: string }
@@ -59,7 +23,6 @@ type BindingTermData =
59
23
  | { readonly kind: "literalSet"; readonly name: string; readonly members: readonly string[] }
60
24
  | { readonly kind: "literal"; readonly value: unknown }
61
25
 
62
- /** One resolved binding: the field's name, its descriptor, its law-computed class, and the term. */
63
26
  interface BindingEntry {
64
27
  readonly field: string
65
28
  readonly data: AnyField
@@ -67,24 +30,19 @@ interface BindingEntry {
67
30
  readonly term: BindingTermData
68
31
  }
69
32
 
70
- /** One EDB atom as runtime data (either polarity — polarity is the rule item's; a closed owner is a ψ atom). */
71
33
  interface AtomData {
72
34
  readonly relation: MatchOwner
73
35
  readonly bindings: readonly BindingEntry[]
74
36
  }
75
37
 
76
- /** One comparison operator name (mirrors `ir::CmpOp`). */
77
38
  type CmpKind = "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "pointIn" | "allen"
78
39
 
79
- /** One comparison side as runtime data (variables and the measure ride BY REFERENCE). */
80
40
  type CmpTermData =
81
41
  | { readonly kind: "var"; readonly ref: AnyVar }
82
42
  | { readonly kind: "param"; readonly name: string }
83
43
  | { readonly kind: "setParam"; readonly name: string }
84
- | { readonly kind: "measure"; readonly ref: AnyVar }
85
44
  | { readonly kind: "literal"; readonly value: unknown }
86
45
 
87
- /** One comparison condition as runtime data; the mask lives inside `allen`. */
88
46
  type CmpData = {
89
47
  readonly kind: "cmp"
90
48
  readonly lhs: CmpTermData
@@ -94,42 +52,27 @@ type CmpData = {
94
52
  | { readonly op: { readonly kind: Exclude<CmpKind, "allen"> } }
95
53
  )
96
54
 
97
- /** One condition-tree node as runtime data (`ir::ConditionTree`). */
98
55
  interface TreeData {
99
56
  readonly kind: "tree"
100
57
  readonly op: "and" | "or"
101
58
  readonly children: readonly CondData[]
102
59
  }
103
60
 
104
- /** Any condition node as runtime data. */
105
61
  type CondData = CmpData | TreeData
106
62
 
107
- /** One aggregate's runtime description (find vocabulary, over variable REFERENCES). */
108
63
  type AggData =
109
64
  | { readonly op: "count" }
110
65
  | {
111
66
  readonly op: "fold"
112
67
  readonly fold: "sum" | "min" | "max"
113
- readonly over: AnyVar | { readonly duration: AnyVar }
68
+ readonly over: AnyVar
114
69
  }
115
70
  | { readonly op: "pack"; readonly over: AnyVar }
116
71
 
117
- /** One classified find entry as runtime data (variables and the measure ride BY REFERENCE). */
118
72
  type FindEntryData =
119
73
  | { readonly kind: "var"; readonly over: AnyVar }
120
- | { readonly kind: "measure"; readonly over: AnyVar }
121
74
  | { readonly kind: "aggregate"; readonly agg: AggData }
122
75
 
123
- /**
124
- * One answer column: its name (the row object key — the find record's key,
125
- * so renames are real and a duplicate column is unrepresentable), its entry,
126
- * the classed mint SLOT its values flow from (a projected var;
127
- * `undefined` for counts/folds/measures/pack, which derive numbers or
128
- * intervals), and — when that slot is a closed reference —
129
- * the roster the decode lifts row ids back to handle NAMES through
130
- * (`undefined` on every bare column). The slice is SDK-side marshaling data
131
- * only: the wire `QueryIr` never carries it.
132
- */
133
76
  interface FindColumn {
134
77
  readonly name: string
135
78
  readonly entry: FindEntryData
@@ -137,12 +80,6 @@ interface FindColumn {
137
80
  readonly slot: ClassedField | undefined
138
81
  }
139
82
 
140
- /**
141
- * One body item of a rule, in written order. An interior join is a NAMED
142
- * record over the derived table's head keys (`key`) bound to local
143
- * variables (`ref`) — the typed wall a record's unordered keys would
144
- * otherwise lose.
145
- */
146
83
  type RuleItem =
147
84
  | { readonly kind: "atom"; readonly atom: AtomData }
148
85
  | { readonly kind: "negated"; readonly atom: AtomData }
@@ -158,35 +95,26 @@ type RuleItem =
158
95
  }
159
96
  | { readonly kind: "cond"; readonly cond: CondData }
160
97
 
161
- /**
162
- * One use of a parameter inside a rule, in written order: the census the
163
- * query-level registry folds (first use mints the dense `ParamId`, first
164
- * FIELD-ANCHORED use types the wire). `members` is present exactly on a
165
- * membership-array use.
166
- */
167
98
  interface ParamUse {
168
99
  readonly name: string
169
100
  readonly shape: "value" | "set"
170
- readonly anchor: AnyField | "measure" | undefined
101
+ readonly anchor: AnyField | undefined
171
102
  readonly op: "binding" | CmpKind
172
103
  readonly members: readonly string[] | undefined
173
104
  }
174
105
 
175
- /** One complete rule as runtime data. */
176
106
  interface RuleData {
177
107
  readonly items: readonly RuleItem[]
178
108
  readonly finds: readonly FindColumn[]
179
109
  readonly paramUses: readonly ParamUse[]
180
110
  }
181
111
 
182
- /** One named interior's runtime description — identity keys the dense `InteriorId` at lowering. */
183
112
  interface InteriorData {
184
113
  readonly name: string
185
114
  readonly finds: readonly FindColumn[]
186
115
  readonly rules: readonly RuleData[]
187
116
  }
188
117
 
189
- /** A nonempty frozen list — empty base/rec/finds are unrepresentable on RecData. */
190
118
  type NonEmpty<T> = readonly [T, ...T[]]
191
119
 
192
120
  /**
@@ -197,34 +125,18 @@ interface RecHandle {
197
125
  readonly name: string
198
126
  }
199
127
 
200
- /**
201
- * Rec identity plus the sealed head, used while rec arms are in flight
202
- * and as the target those arms capture.
203
- */
204
128
  interface RecHead {
205
129
  readonly name: string
206
130
  readonly finds: NonEmpty<FindColumn>
207
131
  }
208
132
 
209
- /**
210
- * The linear rec's runtime description — identity keys the dense
211
- * `InteriorId` (`interiors.length`) at lowering. Base and rec arms are
212
- * nonempty by type and sealed in one assignment.
213
- */
214
133
  interface RecData extends RecHead {
215
134
  readonly base: NonEmpty<RuleData>
216
135
  readonly rec: NonEmpty<RuleData>
217
136
  }
218
137
 
219
- /** A named derived table (an interior or the rec) as `.interior(name)` / `r.not(name)` resolve it. */
220
138
  type DerivedTable = InteriorData | RecHead
221
139
 
222
- /**
223
- * What a binding position of field `F` accepts: a bare structural literal
224
- * of the field's value type, a variable/param/∈-set-param term — and, when
225
- * the field is interval-typed, a bare point literal. A CLOSED-reference
226
- * field additionally takes a plain ARRAY of handle names read as membership.
227
- */
228
140
  type BindingInput<F extends AnyField> =
229
141
  | Infer<F>
230
142
  | (F extends ClosedIdField ? readonly Infer<F>[] : never)
@@ -233,33 +145,15 @@ type BindingInput<F extends AnyField> =
233
145
  | Param<string>
234
146
  | SetParam<string>
235
147
 
236
- /**
237
- * The `match`/`not` bindings record: per field, a term or literal of that
238
- * field's structural type; unmentioned fields are wildcards (absence IS
239
- * the wildcard — the IR has no wildcard variant to spell).
240
- */
241
148
  type MatchShape<F extends FieldsShape> = {
242
149
  readonly [K in keyof F]?: BindingInput<F[K]>
243
150
  }
244
151
 
245
- /**
246
- * One field position of a bindings record as a classed slot: the declared
247
- * descriptor plus the slot's law-computed class, read off the relation's
248
- * class record (`CR`). The one shape a binding position's join judgment
249
- * compares against.
250
- */
251
152
  type SlotAt<F extends FieldsShape, CR, K> = {
252
153
  readonly field: F[K & keyof F]
253
154
  readonly class: ClassLookup<CR, K>
254
155
  }
255
156
 
256
- /**
257
- * The per-property join judgment of a bindings record: a VARIABLE binding
258
- * must join its own MINT slot to the position slot (a cross-class reuse maps
259
- * the property to `never`). Because {@link JoinOk} is an equality, judging
260
- * every position against the mint slot makes all cross-binding joins
261
- * mutually class-equal by transitivity — no env or sibling arm is needed.
262
- */
263
157
  type CheckBindings<Classes extends SchemaClasses, F extends FieldsShape, CR, B> = {
264
158
  readonly [K in keyof B]: K extends keyof F
265
159
  ? B[K] extends AnyVar
@@ -270,7 +164,6 @@ type CheckBindings<Classes extends SchemaClasses, F extends FieldsShape, CR, B>
270
164
  : never
271
165
  }
272
166
 
273
- /** The params-object fragments a bindings record contributes (one union member per param use). */
274
167
  type BindParams<F extends FieldsShape, B> = {
275
168
  [K in keyof B & keyof F]: B[K] extends Param<infer P extends string>
276
169
  ? { readonly [Q in P]: ParamValueAt<F[K]> }
@@ -279,12 +172,6 @@ type BindParams<F extends FieldsShape, B> = {
279
172
  : never
280
173
  }[keyof B & keyof F]
281
174
 
282
- /**
283
- * One comparison VALUE: op plus its operands, raw — the runtime
284
- * representation carries the operands (variable references included), so
285
- * `.where`'s judgment and the params inference both read the value itself.
286
- * `mask` is populated exactly for `allen`.
287
- */
288
175
  interface Cmp<Op extends CmpKind, L, R, M = undefined> {
289
176
  readonly cond: "cmp"
290
177
  readonly op: Op
@@ -293,7 +180,6 @@ interface Cmp<Op extends CmpKind, L, R, M = undefined> {
293
180
  readonly mask: M
294
181
  }
295
182
 
296
- /** One condition-tree VALUE (`and`/`or` over comparisons and nested trees). */
297
183
  interface Tree<Ch extends readonly AnyTreeChild[]> {
298
184
  readonly cond: "tree"
299
185
  readonly op: "and" | "or"
@@ -313,73 +199,40 @@ interface NotAtom<R extends MatchOwner, B> {
313
199
  readonly bindings: B
314
200
  }
315
201
 
316
- /**
317
- * One negated finished-table atom — negation OF an interior or of the
318
- * finished rec is engine-legal in main (a finished set is a set), and
319
- * this value is its one spelling: `r.not("reach", { c })`. Binds nothing,
320
- * only rejects — every variable it names must be positively bound in the
321
- * rule (the same safety rule as EDB negation).
322
- */
323
202
  interface NotInteriorAtom<B> {
324
203
  readonly cond: "notInterior"
325
204
  readonly name: string
326
205
  readonly bindings: B
327
206
  }
328
207
 
329
- /** Any comparison value. */
330
208
  type AnyCmp = Cmp<CmpKind, unknown, unknown, unknown>
331
209
 
332
- /** Any condition-tree child (trees hold comparisons and trees — never atoms). */
333
210
  type AnyTreeChild = AnyCmp | Tree<readonly AnyTreeChild[]>
334
211
 
335
- /** Any negated-atom value. */
336
212
  type AnyNotAtom = NotAtom<MatchOwner, unknown>
337
213
 
338
- /** Any negated finished-table value. */
339
214
  type AnyNotInteriorAtom = NotInteriorAtom<unknown>
340
215
 
341
- /** Any `.where` input: a comparison, a condition tree, or a negated atom (EDB, closed, or finished table). */
342
216
  type AnyCond = AnyCmp | Tree<readonly AnyTreeChild[]> | AnyNotAtom | AnyNotInteriorAtom
343
217
 
344
- /** What `eq`'s right side accepts (`ParamSet` is `Eq`-only — the IR's rule). */
345
218
  type EqRight = AnyVar | Param<string> | SetParam<string> | bigint | string | boolean | Uint8Array | IntervalValue
346
219
 
347
- /** What `ne`'s right side accepts. */
348
220
  type NeRight = AnyVar | Param<string> | bigint | string | boolean | Uint8Array | IntervalValue
349
221
 
350
- /** One side of an order comparison: orderable terms only (the IR's comparison rules — bool orders, `false < true`, R3). */
351
- type OrderSide = AnyVar | Param<string> | Duration | bigint | boolean
222
+ type OrderSide = AnyVar | Param<string> | bigint | boolean
352
223
 
353
- /** The point side of `pointIn`. */
354
224
  type PointSide = AnyVar | Param<string> | bigint
355
225
 
356
- /** The interval side of `pointIn`/`allen`. */
357
226
  type IntervalSide = AnyVar | Param<string> | IntervalValue
358
227
 
359
- /** Builds one comparison value. */
360
228
  function comparison<Op extends CmpKind, L, R, M>(op: Op, lhs: L, rhs: R, mask: M): Cmp<Op, L, R, M> {
361
229
  return Object.freeze({ cond: "cmp", op, lhs, rhs, mask })
362
230
  }
363
231
 
364
- /**
365
- * Whether a comparison side is a VARIABLE side in the engine's sense — a
366
- * bound variable or the measure. A param is a constant at execution, so a
367
- * comparison whose every side is a param or literal is constant-valued:
368
- * the engine's `ConstantComparison` conviction
369
- * (`bumbledb/crates/bumbledb/src/ir/validate/context.rs`,
370
- * `comparison_shape`'s last arm).
371
- */
372
232
  function isVariableSide(value: unknown): boolean {
373
- return isTerm(value) && (value[term] === "var" || value[term] === "duration")
233
+ return isTerm(value) && value[term] === "var"
374
234
  }
375
235
 
376
- /**
377
- * Rejects a comparison with no variable side: it is constant-valued —
378
- * params included, a param is a constant the moment it binds — the
379
- * engine's own validation refuses it (`ConstantComparison`), and the
380
- * lowering has no anchored position to type the literals by — fail here
381
- * with the same verdict.
382
- */
383
236
  function assertTermSide(op: string, lhs: unknown, rhs: unknown): void {
384
237
  if (!isVariableSide(lhs) && !isVariableSide(rhs)) {
385
238
  throw errors.new(
@@ -388,23 +241,14 @@ function assertTermSide(op: string, lhs: unknown, rhs: unknown): void {
388
241
  }
389
242
  }
390
243
 
391
- /**
392
- * The equality comparison (`ir::CmpOp::Eq`) — a bound variable against a
393
- * variable (var-to-var unification, class-equal by the join judgment), a
394
- * param (typed by the variable), an ∈-set param (`Eq`-only), or a bare
395
- * literal of the variable's own value type. Prefer direct placement in
396
- * `match` where punning applies.
397
- */
398
244
  function eq<L extends AnyVar, const R extends EqRight>(left: L, right: R): Cmp<"eq", L, R> {
399
245
  return comparison("eq", left, right, undefined)
400
246
  }
401
247
 
402
- /** Typed disequality (`ir::CmpOp::Ne`). "Not in set" has no operator — write a negated atom. */
403
248
  function ne<L extends AnyVar, const R extends NeRight>(left: L, right: R): Cmp<"ne", L, R> {
404
249
  return comparison("ne", left, right, undefined)
405
250
  }
406
251
 
407
- /** The shared order-comparison constructor. */
408
252
  function order<Op extends "lt" | "le" | "gt" | "ge", const L extends OrderSide, const R extends OrderSide>(
409
253
  op: Op,
410
254
  left: L,
@@ -414,50 +258,29 @@ function order<Op extends "lt" | "le" | "gt" | "ge", const L extends OrderSide,
414
258
  return comparison(op, left, right, undefined)
415
259
  }
416
260
 
417
- /** Strict less-than (`ir::CmpOp::Lt`) — orderable sides only (bool included: `false < true`, R3), never intervals/bytes/strings. */
418
261
  function lt<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"lt", L, R> {
419
262
  return order("lt", left, right)
420
263
  }
421
264
 
422
- /** Less-or-equal (`ir::CmpOp::Le`). */
423
265
  function le<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"le", L, R> {
424
266
  return order("le", left, right)
425
267
  }
426
268
 
427
- /** Strict greater-than (`ir::CmpOp::Gt`). */
428
269
  function gt<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"gt", L, R> {
429
270
  return order("gt", left, right)
430
271
  }
431
272
 
432
- /** Greater-or-equal (`ir::CmpOp::Ge`). */
433
273
  function ge<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"ge", L, R> {
434
274
  return order("ge", left, right)
435
275
  }
436
276
 
437
- /**
438
- * Point membership as a predicate (`ir::CmpOp::PointIn`) — THE one
439
- * spelling: `pointIn(t, w)` holds iff `w.start ≤ t < w.end`. The IR
440
- * orders the operands interval-left, point-right; the value stores them
441
- * that way whatever the surface argument order. Interval ⊇ interval is NOT
442
- * this operator; that predicate is `allen(a, ALLEN.covers, b)`.
443
- */
444
277
  function pointIn<const P extends PointSide, const I extends IntervalSide>(point: P, interval: I): Cmp<"pointIn", I, P> {
445
278
  assertTermSide("pointIn", point, interval)
446
279
  return comparison("pointIn", interval, point, undefined)
447
280
  }
448
281
 
449
- /**
450
- * The 13-bit mask range: bits above the low 13 are unrepresentable in the
451
- * engine's `AllenMask` (`bumbledb/crates/bumbledb/src/allen.rs`:
452
- * `AllenMask::new` refuses them).
453
- */
454
282
  const ALLEN_ALL_BITS = (1 << 13) - 1
455
283
 
456
- /**
457
- * The Allen coordinate system's named constants — the 13 basics in the
458
- * engine's palindromic bit order plus the workload composites, values
459
- * identical to the engine's. Compose with `|`: `ALLEN.before | ALLEN.meets`.
460
- */
461
284
  const ALLEN = Object.freeze({
462
285
  before: 1 << 0,
463
286
  meets: 1 << 1,
@@ -472,21 +295,16 @@ const ALLEN = Object.freeze({
472
295
  overlappedBy: 1 << 10,
473
296
  metBy: 1 << 11,
474
297
  after: 1 << 12,
475
- /** The point-sets share a point (9 bits; under half-open intervals *meets* shares none). */
298
+
476
299
  intersects: (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10),
477
- /** Point-set ⊇: equals ∪ contains ∪ started-by ∪ finished-by. */
300
+
478
301
  covers: (1 << 6) | (1 << 8) | (1 << 9) | (1 << 7),
479
- /** Point-set ⊆ — `covers`' converse: equals ∪ during ∪ starts ∪ finishes. */
302
+
480
303
  coveredBy: (1 << 6) | (1 << 4) | (1 << 3) | (1 << 5),
481
- /** The point-sets share no point: before ∪ meets ∪ met-by ∪ after. */
304
+
482
305
  disjoint: (1 << 0) | (1 << 1) | (1 << 11) | (1 << 12)
483
306
  })
484
307
 
485
- /**
486
- * THE interval-pair comparison (`ir::CmpOp::Allen`): two interval terms of
487
- * one element type, satisfied iff the pair's classification is in the
488
- * 13-bit mask — a literal built from the `ALLEN` constants.
489
- */
490
308
  function allen<const A extends IntervalSide, const B extends IntervalSide>(
491
309
  left: A,
492
310
  mask: number,
@@ -501,27 +319,16 @@ function allen<const A extends IntervalSide, const B extends IntervalSide>(
501
319
  return comparison("allen", left, right, mask)
502
320
  }
503
321
 
504
- /**
505
- * Conjunction node of the input condition grammar (`ConditionTree::And`).
506
- * The rule's condition list is already a conjunction — `and` exists for
507
- * nesting under `or`, and the empty combination keeps the IR's algebraic
508
- * reading (`And([])` is true).
509
- */
510
322
  function and<const C extends readonly AnyTreeChild[]>(...children: C): Tree<C> {
511
323
  return Object.freeze({ cond: "tree", op: "and", children: Object.freeze(children) })
512
324
  }
513
325
 
514
- /**
515
- * Disjunction node of the input condition grammar (`ConditionTree::Or`) —
516
- * the one place the surface admits a nested OR; validation distributes it
517
- * to DNF rules engine-side. `Or([])` keeps its algebraic reading (false).
518
- */
519
326
  function or<const C extends readonly AnyTreeChild[]>(...children: C): Tree<C> {
520
327
  return Object.freeze({ cond: "tree", op: "or", children: Object.freeze(children) })
521
328
  }
522
329
 
523
330
  /**
524
- * Negation — anti-join over sets: `not(Rel, { field: someVar, ... })`
331
+ * Negation — anti-join over sets: `not(Rel, { field: someVar,... })`
525
332
  * rejects every binding some matching fact extends. A negated atom binds
526
333
  * nothing, only rejects: every variable it names must be positively bound
527
334
  * in the rule, a construction-time wall (the engine's safety refusal stands
@@ -551,7 +358,7 @@ function not(
551
358
  * interval's element domain, and a quantifier is not an addition, so bool
552
359
  * (orderable, never numeric) is exactly here refused. A CLOSED reference
553
360
  * is excluded even though its kind is `u64`: a vocabulary's declaration-id
554
- * order is an accident, not semantics (`docs/architecture/10-data-model.md`
361
+ * order is an accident, not semantics
555
362
  * § orderability), so every order-comparison and fold position refuses
556
363
  * closed-bound terms — the construction-time validations in
557
364
  * `#query/lower.ts` are that ban's runtime twin.
@@ -562,63 +369,24 @@ type NumericVarOk<V extends AnyVar> = V["field"] extends { readonly closed: Clos
562
369
  ? true
563
370
  : false
564
371
 
565
- /**
566
- * Whether a variable's OWN field is ORDERABLE (u64/i64/bool) — the one gate
567
- * every order-comparison side, `min`/`max` input, and Arg key reads. Bool
568
- * orders: `false < true`, the strict 0/1 encoding IS the order (ruled R3),
569
- * exactly the engine's operand screen
570
- * (`bumbledb/crates/bumbledb/src/ir/validate/context.rs`); bool has no
571
- * closed variant, so the closed exclusion rides in {@link NumericVarOk}.
572
- */
573
372
  type OrderVarOk<V extends AnyVar> = V["field"]["kind"] extends "bool" ? true : NumericVarOk<V>
574
373
 
575
- /** Whether a variable's OWN field is interval-typed. */
576
374
  type IntervalVarOk<V extends AnyVar> = V["field"]["kind"] extends "interval" ? true : false
577
375
 
578
- /**
579
- * Whether a comparison has a VARIABLE side (a var or the measure) — the
580
- * type-level twin of the engine's `ConstantComparison` rule: a param is a
581
- * constant at execution, so param-vs-param and param-vs-literal are
582
- * constant-valued whatever their domains ({@link assertTermSide} is the
583
- * runtime wall behind this one).
584
- */
585
- type CmpVarSideOk<L, R> = L extends AnyVar | Duration ? true : R extends AnyVar | Duration ? true : false
376
+ type CmpVarSideOk<L, R> = L extends AnyVar ? true : R extends AnyVar ? true : false
586
377
 
587
- /**
588
- * One order side's DOMAIN — the type-level twin of the engine's resolved
589
- * operand type (`ir/validate/context.rs`, `classify`'s `Ord*` arms): a
590
- * variable names its own field kind, the measure is u64 by definition (and
591
- * never meets another measure — `DurationBothSides`), a bigint literal
592
- * spans the integer domains, a param is typed by its sibling (`"open"`).
593
- * `never` marks a side that is itself unorderable: interval/bytes/string
594
- * vars (the operand screen), closed-bound vars (R4), a measure over a
595
- * non-interval var.
596
- */
597
378
  type OrderDomain<T> = T extends AnyVar
598
379
  ? OrderVarOk<T> extends true
599
380
  ? T["field"]["kind"]
600
381
  : never
601
- : T extends Duration<infer V extends AnyVar>
602
- ? IntervalVarOk<V> extends true
603
- ? "duration"
604
- : never
605
- : T extends Param<string>
606
- ? "open"
607
- : T extends bigint
608
- ? "integer"
609
- : T extends boolean
610
- ? "bool"
611
- : never
382
+ : T extends Param<string>
383
+ ? "open"
384
+ : T extends bigint
385
+ ? "integer"
386
+ : T extends boolean
387
+ ? "bool"
388
+ : never
612
389
 
613
- /**
614
- * Whether two order domains may MEET under one operator — the engine's
615
- * same-type rule judged pairwise, not per side: bool meets only bool (a
616
- * bigint literal against a bool var is exactly `check_const`'s
617
- * conviction; R3 made bool orderable, never cross-orderable), u64 and i64
618
- * never meet, the measure's sibling must live in u64 (`OrdMeasureVar`:
619
- * scalar ≠ U64 is `IllegalComparison`), two measures never meet, and an
620
- * open side (param, integer literal) takes whatever its sibling names.
621
- */
622
390
  type OrderDomainsOk<A, B> = [A] extends [never]
623
391
  ? false
624
392
  : [B] extends [never]
@@ -627,51 +395,30 @@ type OrderDomainsOk<A, B> = [A] extends [never]
627
395
  ? true
628
396
  : B extends "open"
629
397
  ? true
630
- : A extends "duration"
631
- ? B extends "u64" | "integer"
398
+ : A extends "bool"
399
+ ? B extends "bool"
632
400
  ? true
633
401
  : false
634
- : B extends "duration"
635
- ? A extends "u64" | "integer"
402
+ : B extends "bool"
403
+ ? false
404
+ : A extends "integer"
636
405
  ? true
637
- : false
638
- : A extends "bool"
639
- ? B extends "bool"
406
+ : B extends "integer"
640
407
  ? true
641
- : false
642
- : B extends "bool"
643
- ? false
644
- : A extends "integer"
408
+ : A extends B
645
409
  ? true
646
- : B extends "integer"
647
- ? true
648
- : A extends B
649
- ? true
650
- : false
410
+ : false
651
411
 
652
- /** The whole order comparison's judgment: a variable side exists, and the sides' domains meet. */
653
412
  type OrderPairOk<L, R> = CmpVarSideOk<L, R> extends true ? OrderDomainsOk<OrderDomain<L>, OrderDomain<R>> : false
654
413
 
655
- /**
656
- * An interval side's ELEMENT domain: a variable names its field's element
657
- * (`never` on a non-interval var), a param or bare interval literal is
658
- * `"open"` — no type exists to name its element at this tier; the engine
659
- * anchors it at prepare.
660
- */
661
414
  type IntervalElementDomain<T> = T extends AnyVar
662
415
  ? T["field"] extends { readonly kind: "interval"; readonly element: infer E extends "u64" | "i64" }
663
416
  ? E
664
417
  : never
665
418
  : "open"
666
419
 
667
- /**
668
- * The point side's domain — a point lives in the interval's element
669
- * domain: a numeric var names its kind (never bool, never closed), a
670
- * param or bigint literal is open.
671
- */
672
420
  type PointDomain<T> = T extends AnyVar ? (NumericVarOk<T> extends true ? T["field"]["kind"] : never) : "open"
673
421
 
674
- /** Whether two element domains meet: both legal, and equal unless one is open. */
675
422
  type ElementMeets<A, B> = [A] extends [never]
676
423
  ? false
677
424
  : [B] extends [never]
@@ -684,23 +431,12 @@ type ElementMeets<A, B> = [A] extends [never]
684
431
  ? true
685
432
  : false
686
433
 
687
- /**
688
- * The whole `pointIn` judgment (operands already sealed interval-left):
689
- * the point's domain must BE the interval's element domain — `pointIn(t,
690
- * w)` with an i64-typed `t` against `interval(u64)` is the engine's
691
- * `IllegalComparison`, judged here first.
692
- */
693
434
  type PointInPairOk<L, R> =
694
435
  CmpVarSideOk<L, R> extends true ? ElementMeets<IntervalElementDomain<L>, PointDomain<R>> : false
695
436
 
696
- /**
697
- * The whole `allen` judgment: two interval sides of ONE element domain
698
- * (Q1 — widths meet freely, u64-vs-i64 stays illegal), judged pairwise.
699
- */
700
437
  type AllenPairOk<L, R> =
701
438
  CmpVarSideOk<L, R> extends true ? ElementMeets<IntervalElementDomain<L>, IntervalElementDomain<R>> : false
702
439
 
703
- /** The `eq`/`ne` judgment: var-var joins by mint slot; var-literal is exact-typed by the var's own field. */
704
440
  type EqOk<Classes extends SchemaClasses, L, R> = L extends AnyVar
705
441
  ? R extends AnyVar
706
442
  ? JoinOk<MintSlotOf<Classes, L>, MintSlotOf<Classes, R>> extends true
@@ -713,28 +449,20 @@ type EqOk<Classes extends SchemaClasses, L, R> = L extends AnyVar
713
449
  : false
714
450
  : false
715
451
 
716
- /** One negated-atom binding's judgment: a variable must be class-equal (boundness is a runtime wall). */
717
452
  type NotBindingOk<Classes extends SchemaClasses, S extends ClassedField, T> = T extends AnyVar
718
453
  ? JoinOk<MintSlotOf<Classes, T>, S> extends true
719
454
  ? true
720
455
  : false
721
456
  : true
722
457
 
723
- /** The whole negated atom's judgment (`CR` — the negated relation's class record off the schema class map). */
724
458
  type NotOk<Classes extends SchemaClasses, F extends FieldsShape, CR, B> = false extends {
725
459
  [K in keyof B]: NotBindingOk<Classes, SlotAt<F, CR, K>, B[K]>
726
460
  }[keyof B]
727
461
  ? false
728
462
  : true
729
463
 
730
- /** One negated finished-table position's judgment: a variable. */
731
464
  type NotInteriorBindingOk<V> = V extends AnyVar ? true : false
732
465
 
733
- /**
734
- * The whole negated finished-table atom's judgment — variables only;
735
- * arity and class against the named table's head are construction-time
736
- * (the name is a string, so the head is not a type-level fact).
737
- */
738
466
  type NotInteriorOk<B> = false extends { [K in keyof B]: NotInteriorBindingOk<B[K]> }[keyof B] ? false : true
739
467
 
740
468
  /**
@@ -769,10 +497,8 @@ type CondOkBool<Classes extends SchemaClasses, C> = [AnyTreeChild] extends [C]
769
497
  ? NotOk<Classes, MatchFields<R>, ClassRecordOf<Classes, R["name"]>, B>
770
498
  : false
771
499
 
772
- /** The validated `.where` argument (intersect with the inferred condition type). */
773
500
  type CheckCond<Classes extends SchemaClasses, C> = CondOkBool<Classes, C> extends true ? C : never
774
501
 
775
- /** The `eq`/`ne` params contribution: the param typed by the left variable's own field. */
776
502
  type EqParams<L, R> = L extends AnyVar
777
503
  ? R extends Param<infer P extends string>
778
504
  ? { readonly [Q in P]: Infer<L["field"]> }
@@ -781,27 +507,15 @@ type EqParams<L, R> = L extends AnyVar
781
507
  : never
782
508
  : never
783
509
 
784
- /**
785
- * An order side's params contribution, typed by the SIBLING side — the
786
- * runtime anchors a param to its sibling variable's field, so a bool var
787
- * orders against a `boolean` param; every var-less pairing stays `bigint`.
788
- */
789
510
  type OrderSideParams<T, Sib> =
790
511
  T extends Param<infer P extends string>
791
512
  ? { readonly [Q in P]: Sib extends AnyVar ? Infer<Sib["field"]> : bigint }
792
513
  : never
793
514
 
794
- /** The point side's params contribution (a point is always `bigint`). */
795
515
  type PointParams<T> = T extends Param<infer P extends string> ? { readonly [Q in P]: bigint } : never
796
516
 
797
- /** An interval side's params contribution. */
798
517
  type IntervalSideParams<T> = T extends Param<infer P extends string> ? { readonly [Q in P]: IntervalValue } : never
799
518
 
800
- /**
801
- * One condition's params-object fragments (a union; the rule builder folds
802
- * them into the inferred `Params` record) — every param typed by its use.
803
- * The leading arm is the same base case as {@link CondOkBool}'s.
804
- */
805
519
  type CondParams<C> = [AnyTreeChild] extends [C]
806
520
  ? never
807
521
  : C extends Cmp<infer Op, infer L, infer R, infer _M>
@@ -863,7 +577,6 @@ export type {
863
577
  NotInteriorAtom,
864
578
  NumericVarOk,
865
579
  OrderSide,
866
- OrderVarOk,
867
580
  ParamUse,
868
581
  PointSide,
869
582
  RecData,