@bjornpagen/bumbledb 0.1.0 → 0.3.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 (112) hide show
  1. package/COOKBOOK.md +1450 -0
  2. package/README.md +69 -30
  3. package/dist/closed.d.ts +157 -38
  4. package/dist/closed.d.ts.map +1 -1
  5. package/dist/closed.js +232 -47
  6. package/dist/closed.js.map +1 -1
  7. package/dist/count.d.ts +64 -17
  8. package/dist/count.d.ts.map +1 -1
  9. package/dist/count.js +37 -14
  10. package/dist/count.js.map +1 -1
  11. package/dist/db.d.ts +27 -8
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +33 -10
  14. package/dist/db.js.map +1 -1
  15. package/dist/exhume.d.ts +12 -11
  16. package/dist/exhume.d.ts.map +1 -1
  17. package/dist/exhume.js +7 -6
  18. package/dist/exhume.js.map +1 -1
  19. package/dist/face.d.ts +135 -30
  20. package/dist/face.d.ts.map +1 -1
  21. package/dist/face.js +44 -19
  22. package/dist/face.js.map +1 -1
  23. package/dist/fields.d.ts +130 -130
  24. package/dist/fields.d.ts.map +1 -1
  25. package/dist/fields.js +60 -94
  26. package/dist/fields.js.map +1 -1
  27. package/dist/index.d.ts +29 -24
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +19 -14
  30. package/dist/index.js.map +1 -1
  31. package/dist/law.d.ts +224 -0
  32. package/dist/law.d.ts.map +1 -0
  33. package/dist/law.js +224 -0
  34. package/dist/law.js.map +1 -0
  35. package/dist/lower.d.ts +17 -7
  36. package/dist/lower.d.ts.map +1 -1
  37. package/dist/lower.js +66 -24
  38. package/dist/lower.js.map +1 -1
  39. package/dist/marshal.d.ts +36 -21
  40. package/dist/marshal.d.ts.map +1 -1
  41. package/dist/marshal.js +41 -25
  42. package/dist/marshal.js.map +1 -1
  43. package/dist/native.d.ts +6 -2
  44. package/dist/native.d.ts.map +1 -1
  45. package/dist/native.js +2 -2
  46. package/dist/native.js.map +1 -1
  47. package/dist/query/atom.d.ts +370 -174
  48. package/dist/query/atom.d.ts.map +1 -1
  49. package/dist/query/atom.js +75 -172
  50. package/dist/query/atom.js.map +1 -1
  51. package/dist/query/lower.d.ts +312 -109
  52. package/dist/query/lower.d.ts.map +1 -1
  53. package/dist/query/lower.js +906 -387
  54. package/dist/query/lower.js.map +1 -1
  55. package/dist/query/predicate.d.ts +70 -88
  56. package/dist/query/predicate.d.ts.map +1 -1
  57. package/dist/query/predicate.js +118 -72
  58. package/dist/query/predicate.js.map +1 -1
  59. package/dist/query/run.d.ts +19 -16
  60. package/dist/query/run.d.ts.map +1 -1
  61. package/dist/query/run.js +31 -24
  62. package/dist/query/run.js.map +1 -1
  63. package/dist/query/scope.d.ts +178 -127
  64. package/dist/query/scope.d.ts.map +1 -1
  65. package/dist/query/scope.js +111 -108
  66. package/dist/query/scope.js.map +1 -1
  67. package/dist/query/select.d.ts +102 -80
  68. package/dist/query/select.d.ts.map +1 -1
  69. package/dist/query/select.js +39 -34
  70. package/dist/query/select.js.map +1 -1
  71. package/dist/relation.d.ts +48 -38
  72. package/dist/relation.d.ts.map +1 -1
  73. package/dist/relation.js +24 -19
  74. package/dist/relation.js.map +1 -1
  75. package/dist/schema.d.ts +41 -3
  76. package/dist/schema.d.ts.map +1 -1
  77. package/dist/schema.js +34 -9
  78. package/dist/schema.js.map +1 -1
  79. package/dist/spec.d.ts +7 -5
  80. package/dist/spec.d.ts.map +1 -1
  81. package/dist/spec.js.map +1 -1
  82. package/dist/statements.d.ts +91 -36
  83. package/dist/statements.d.ts.map +1 -1
  84. package/dist/statements.js +42 -12
  85. package/dist/statements.js.map +1 -1
  86. package/package.json +4 -3
  87. package/src/closed.ts +448 -95
  88. package/src/count.ts +112 -18
  89. package/src/db.ts +45 -17
  90. package/src/exhume.ts +12 -11
  91. package/src/face.ts +211 -41
  92. package/src/fields.ts +199 -234
  93. package/src/index.ts +78 -61
  94. package/src/law.ts +519 -0
  95. package/src/lower.ts +82 -27
  96. package/src/marshal.ts +48 -30
  97. package/src/native.ts +8 -4
  98. package/src/query/atom.ts +525 -374
  99. package/src/query/lower.ts +1469 -538
  100. package/src/query/predicate.ts +208 -161
  101. package/src/query/run.ts +35 -25
  102. package/src/query/scope.ts +264 -218
  103. package/src/query/select.ts +168 -93
  104. package/src/relation.ts +47 -47
  105. package/src/schema.ts +69 -18
  106. package/src/spec.ts +7 -5
  107. package/src/statements.ts +124 -41
  108. package/dist/brand.d.ts +0 -59
  109. package/dist/brand.d.ts.map +0 -1
  110. package/dist/brand.js +0 -47
  111. package/dist/brand.js.map +0 -1
  112. package/src/brand.ts +0 -82
@@ -1,226 +1,355 @@
1
1
  /**
2
- * Query atoms and conditions (PRD-08) — the body vocabulary of a rule,
3
- * mirroring the engine IR variant for variant
2
+ * Atoms and conditions, STRUCTURAL edition — the body vocabulary of a
3
+ * rule, mirroring the engine IR variant for variant
4
4
  * (`bumbledb/crates/bumbledb/src/ir.rs`, the bijection target;
5
- * `docs/architecture/20-query-ir.md` normative): `match` is the named-field
6
- * atom (unmentioned fields ARE the wildcard no wildcard value exists),
7
- * `not` is negation-as-position (anti-join), `is`/`ne`/`lt`/`le`/`gt`/`ge`
8
- * are the comparison roster, `covers` is the IR's `PointIn` predicate,
9
- * `allen` the 13-bit-mask interval-pair comparison, `and`/`or` the input
10
- * condition-tree grammar (distributed to DNF by the engine's validation),
11
- * and `duration` the measure term. Nothing beyond the IR exists here: no
12
- * convenience operator fakes an unsupported comparison.
5
+ * `docs/architecture/20-query-ir.md` normative). A `match` binding record
6
+ * binds fields to vars, params, ∈-set params, or bare structural literals
7
+ * (unmentioned fields ARE the wildcard — no wildcard value exists);
8
+ * `not(Rel, {...})` is negation-as-position (anti-join); `eq`/`ne` and the
9
+ * order roster, `pointIn`/`covers` (both spellings of `ir::CmpOp::PointIn`,
10
+ * always lowered interval-left), `allen` (the 13-bit mask pair
11
+ * comparison), and `and`/`or` (the input condition-tree grammar) complete
12
+ * the roster. Nothing beyond the IR exists here — and the walls the engine
13
+ * enforces at prepare are TYPES first: a var joins only domain-equal
14
+ * fields (`JoinOk`, checked against the rule environment AND against the
15
+ * binding record's own same-named siblings — two first occurrences of one
16
+ * name inside one record are a join too), an
17
+ * interval-typed var under a non-`pointIn` comparison is unwritable, and a
18
+ * negated atom's variables must be positively bound (env membership IS the
19
+ * safety rule). Every condition value carries its operands raw — the
20
+ * runtime representation is the type-inference carrier, no phantoms.
21
+ *
22
+ * This module also owns the plain runtime DATA a built rule is made of
23
+ * (`RuleData`/`RecData` and friends): frozen values the lowering walks —
24
+ * pure data, so lowering stays a pure, stable function of the query value.
13
25
  */
14
- import type { IntervalValue } from "#brand.ts";
15
- import { phantom } from "#brand.ts";
16
- import type { OneOf } from "#face.ts";
17
- import type { FieldData, FieldValue } from "#fields.ts";
18
- import type { PredicateData } from "#query/predicate.ts";
19
- import type { AnyTerm, AnyVar, ItemParams, MaskParam, Param, ParamSet, ParamsRecord, ParamsShape, TermContribution, Var } from "#query/scope.ts";
20
- import type { AnyRelation, FieldsShape, Relation } from "#relation.ts";
26
+ import type { AnyClosed } from "#closed.ts";
27
+ import type { AnyField, ClosedIdField, Infer, IntervalValue } from "#fields.ts";
28
+ import type { ClassLookup, ClassRecordOf, SchemaClasses } from "#law.ts";
29
+ import type { ClassedField, Duration, EnvShape, JoinOk, MaskParam, Param, ParamValueAt, SetParam, ShapeOf, Var } from "#query/scope.ts";
30
+ import type { AnyRelation, FieldsShape, RelationFields } from "#relation.ts";
21
31
  /**
22
- * One atom-binding position as runtime data: a scope term, a host literal
23
- * (tagged at lowering by the FIELD's structural type a point-typed
24
- * literal at an interval field is the IR's membership typing rule), or an
25
- * `oneOf` literal set (lowered to a fresh variable plus a disjunctive
26
- * equality conditionthe three-confinement law's rule-level OR, spelled
27
- * for the caller as one binding).
32
+ * What a query atom matches over: an ordinary relation or a CLOSED
33
+ * vocabulary (ψ query atoms the engine folds a resolvable closed atom
34
+ * into a plan-constant member set at prepare, or joins the L1-resident
35
+ * virtual image when the shape does not fold; the SDK never pre-folds and
36
+ * never knows which transparency is the contract).
28
37
  */
29
- type BindingTerm = {
30
- readonly kind: "term";
31
- readonly value: AnyTerm;
38
+ type MatchOwner = AnyRelation | AnyClosed;
39
+ /**
40
+ * The matchable field block of an atom owner: a relation's declared
41
+ * fields; a closed relation's SEALED shape — the synthetic `id` (the
42
+ * roster-carrying descriptor) first, then the declared payload columns
43
+ * read through the typed `columns` carrier (the one source of payload
44
+ * typing — no parallel column table exists). The runtime twin is
45
+ * `matchFieldsOf` in `#query/lower.ts`; the id-first ordinal shift the two
46
+ * tiers share is pinned by the lowering golden.
47
+ */
48
+ type MatchFields<R extends MatchOwner> = R extends AnyClosed ? {
49
+ readonly id: ClosedIdField;
50
+ } & R["columns"] : R extends AnyRelation ? RelationFields<R> : never;
51
+ /** One atom-binding position as runtime data. */
52
+ type BindingTermData = {
53
+ readonly kind: "var";
54
+ readonly name: string;
55
+ } | {
56
+ readonly kind: "param";
57
+ readonly name: string;
58
+ } | {
59
+ readonly kind: "setParam";
60
+ readonly name: string;
32
61
  } | {
33
62
  readonly kind: "literal";
34
63
  readonly value: unknown;
35
- } | {
36
- readonly kind: "oneOf";
37
- readonly values: readonly unknown[];
38
64
  };
39
- /** One resolved binding: the field's name, its description, and the term. */
65
+ /** One resolved binding: the field's name, its descriptor, its law-computed class, and the term. */
40
66
  interface BindingEntry {
41
67
  readonly field: string;
42
- readonly data: FieldData;
43
- readonly term: BindingTerm;
68
+ readonly data: AnyField;
69
+ readonly class: string | undefined;
70
+ readonly term: BindingTermData;
44
71
  }
45
- /** Where an atom draws its facts: a stored relation or a scope predicate. */
46
- type AtomSourceData = {
47
- readonly kind: "relation";
48
- readonly relation: AnyRelation;
49
- } | {
50
- readonly kind: "predicate";
51
- readonly pred: PredicateData;
52
- };
53
- /**
54
- * One atom value (positive or negated — negation is a position in the
55
- * rule, not a kind of atom, exactly as the IR reuses `Atom` unchanged).
56
- * The phantom carries the params object the atom's bindings contribute.
57
- */
58
- interface MatchAtom<P extends ParamsRecord> {
59
- readonly item: "atom";
60
- readonly negated: boolean;
61
- readonly source: AtomSourceData;
72
+ /** One EDB atom as runtime data (either polarity — polarity is the rule item's; a closed owner is a ψ atom). */
73
+ interface AtomData {
74
+ readonly relation: MatchOwner;
62
75
  readonly bindings: readonly BindingEntry[];
63
- readonly [phantom]?: P;
64
76
  }
77
+ /** One comparison operator name (mirrors `ir::CmpOp`). */
78
+ type CmpKind = "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "pointIn" | "allen";
65
79
  /** One comparison side as runtime data. */
66
- type CmpTerm = {
67
- readonly kind: "term";
68
- readonly value: AnyTerm;
80
+ type CmpTermData = {
81
+ readonly kind: "var";
82
+ readonly name: string;
69
83
  } | {
70
- readonly kind: "literal";
71
- readonly value: unknown;
84
+ readonly kind: "param";
85
+ readonly name: string;
86
+ } | {
87
+ readonly kind: "setParam";
88
+ readonly name: string;
72
89
  } | {
73
90
  readonly kind: "measure";
74
- readonly over: AnyVar;
91
+ readonly name: string;
92
+ } | {
93
+ readonly kind: "literal";
94
+ readonly value: unknown;
75
95
  };
76
- /** The `allen` mask position: a literal 13-bit mask or a mask parameter. */
96
+ /** The `allen` mask position as runtime data. */
77
97
  type MaskData = {
78
98
  readonly kind: "literal";
79
99
  readonly mask: number;
80
100
  } | {
81
101
  readonly kind: "param";
82
- readonly param: MaskParam<string>;
102
+ readonly name: string;
83
103
  };
84
- /** One comparison operator as runtime data (mirrors `ir::CmpOp`). */
85
- type CmpOpData = {
86
- readonly kind: "eq";
87
- } | {
88
- readonly kind: "ne";
104
+ /** One comparison condition as runtime data (`mask` present exactly for `allen`). */
105
+ interface CmpData {
106
+ readonly kind: "cmp";
107
+ readonly op: CmpKind;
108
+ readonly mask: MaskData | undefined;
109
+ readonly lhs: CmpTermData;
110
+ readonly rhs: CmpTermData;
111
+ }
112
+ /** One condition-tree node as runtime data (`ir::ConditionTree`). */
113
+ interface TreeData {
114
+ readonly kind: "tree";
115
+ readonly op: "and" | "or";
116
+ readonly children: readonly CondData[];
117
+ }
118
+ /** Any condition node as runtime data. */
119
+ type CondData = CmpData | TreeData;
120
+ /** One aggregate's runtime description (select vocabulary, over var NAMES). */
121
+ type AggData = {
122
+ readonly op: "count";
89
123
  } | {
90
- readonly kind: "lt";
124
+ readonly op: "countDistinct";
125
+ readonly over: string;
91
126
  } | {
92
- readonly kind: "le";
127
+ readonly op: "fold";
128
+ readonly fold: "sum" | "min" | "max";
129
+ readonly over: string | {
130
+ readonly duration: string;
131
+ };
93
132
  } | {
94
- readonly kind: "gt";
133
+ readonly op: "arg";
134
+ readonly direction: "argMax" | "argMin";
135
+ readonly over: string;
136
+ readonly key: string;
95
137
  } | {
96
- readonly kind: "ge";
138
+ readonly op: "pack";
139
+ readonly over: string;
140
+ };
141
+ /** One classified select entry as runtime data. */
142
+ type SelectEntryData = {
143
+ readonly kind: "var";
144
+ readonly over: string;
97
145
  } | {
98
- readonly kind: "allen";
99
- readonly mask: MaskData;
146
+ readonly kind: "measure";
147
+ readonly over: string;
100
148
  } | {
101
- readonly kind: "pointIn";
149
+ readonly kind: "aggregate";
150
+ readonly agg: AggData;
102
151
  };
103
- /** One comparison condition value. */
104
- interface ComparisonItem<P extends ParamsRecord> {
105
- readonly item: "cmp";
106
- readonly op: CmpOpData;
107
- readonly lhs: CmpTerm;
108
- readonly rhs: CmpTerm;
109
- readonly [phantom]?: P;
152
+ /** One answer column: its name (the row object key) and its entry. */
153
+ interface SelectColumn {
154
+ readonly name: string;
155
+ readonly entry: SelectEntryData;
110
156
  }
157
+ /** One body item of a rule, in written order. */
158
+ type RuleItem = {
159
+ readonly kind: "atom";
160
+ readonly atom: AtomData;
161
+ } | {
162
+ readonly kind: "negated";
163
+ readonly atom: AtomData;
164
+ } | {
165
+ readonly kind: "idb";
166
+ readonly rec: RecData;
167
+ readonly vars: readonly string[];
168
+ } | {
169
+ readonly kind: "cond";
170
+ readonly cond: CondData;
171
+ };
111
172
  /**
112
- * One condition-tree node (`ir::ConditionTree`): any boolean combination
113
- * of comparisons the engine's validation distributes nested OR to DNF
114
- * rules; the surface admits exactly what the IR admits.
173
+ * One use of a parameter inside a rule, in written order: the census the
174
+ * query-level registry folds (first use mints the dense `ParamId`, first
175
+ * FIELD-ANCHORED use types the wire).
115
176
  */
116
- interface ConditionTreeItem<P extends ParamsRecord> {
117
- readonly item: "tree";
118
- readonly op: "and" | "or";
119
- readonly children: readonly AnyCondition[];
120
- readonly [phantom]?: P;
177
+ interface ParamUse {
178
+ readonly name: string;
179
+ readonly shape: "value" | "set" | "mask";
180
+ readonly anchor: AnyField | "measure" | undefined;
181
+ readonly op: "binding" | CmpKind;
182
+ }
183
+ /** One complete rule as runtime data. */
184
+ interface RuleData {
185
+ readonly items: readonly RuleItem[];
186
+ readonly select: readonly SelectColumn[];
187
+ /** Variable name → the classed slot its FIRST positive binding carries (the runtime env — descriptor + class). */
188
+ readonly varFields: Readonly<Record<string, ClassedField>>;
189
+ readonly paramUses: readonly ParamUse[];
121
190
  }
122
- /** Any condition value, whatever its params. */
123
- type AnyCondition = ComparisonItem<ParamsRecord> | ConditionTreeItem<ParamsRecord>;
124
- /** Any rule body item: an atom (either polarity) or a condition. */
125
- type AnyBodyItem = MatchAtom<ParamsRecord> | AnyCondition;
126
191
  /**
127
- * The measure of an interval-typed variable (`ir::Term::Measure`, surface
128
- * `Duration`): `|[s, e)| = e s`, u64 legal as one side of an order
129
- * comparison, as a projected select entry, and as the input of
130
- * `sum`/`min`/`max`; every other position is unwritable here exactly as
131
- * the IR rejects it typed. A ray has no finite measure — the engine's
132
- * `MeasureOfRay` execution error; exclude rays first (`allen` against a
133
- * bounded window).
192
+ * One recursive predicate's runtime description identity keys the dense
193
+ * `PredId` at lowering. `rules` is appended by `rec.rule(...)` and sealed
194
+ * (frozen) when the program's output is declared.
134
195
  */
135
- interface Duration {
136
- readonly measure: AnyVar;
137
- readonly [phantom]?: bigint;
196
+ interface RecData {
197
+ readonly name: string;
198
+ readonly rules: RuleData[];
138
199
  }
139
200
  /**
140
- * What a binding position of value type `V` accepts: a branded literal, a
141
- * disjunctive `oneOf` literal set, a `Var`/`Param`/`ParamSet` of the same
142
- * brand — and, when the field is interval-typed, a point-typed term (the
143
- * IR's membership typing rule: an element-typed term at an interval field
144
- * is point membership; an interval-typed term is value equality).
201
+ * What a binding position of field `F` accepts: a bare structural literal
202
+ * of the field's value type, a var/param/∈-set-param term — and, when the
203
+ * field is interval-typed, a bare point literal (the IR's membership
204
+ * typing rule: an element-typed term at an interval field is point
205
+ * membership; an interval-typed term is value equality).
145
206
  */
146
- type TermInput<V> = V | OneOf<V> | Var<V> | Param<string, V> | ParamSet<string, V> | (V extends IntervalValue ? PointTermInput : never);
147
- /** The point-typed terms an interval field position additionally accepts. */
148
- type PointTermInput = bigint | Var<bigint> | Param<string, bigint> | ParamSet<string, bigint>;
207
+ type BindingInput<F extends AnyField> = Infer<F> | (F extends {
208
+ readonly kind: "interval";
209
+ } ? bigint : never) | Var<string> | Param<string> | SetParam<string>;
149
210
  /**
150
- * The `match` bindings record: per field, a term of that field's brand;
151
- * unmentioned fields are wildcards (absence IS the wildcard — the IR has
152
- * no wildcard variant to spell).
211
+ * The `match`/`not` bindings record: per field, a term or literal of that
212
+ * field's structural type; unmentioned fields are wildcards (absence IS
213
+ * the wildcard — the IR has no wildcard variant to spell).
153
214
  */
154
- type MatchInput<Fields extends FieldsShape> = {
155
- readonly [K in keyof Fields]?: TermInput<FieldValue<Fields[K]>>;
215
+ type MatchShape<F extends FieldsShape> = {
216
+ readonly [K in keyof F]?: BindingInput<F[K]>;
156
217
  };
157
- /** The params object a bindings record contributes (used by `match`). */
158
- type BindingsParams<B> = ParamsShape<TermContribution<B[keyof B]>>;
159
218
  /**
160
- * Resolves a bindings record against an ordered field roster (shared by
161
- * relation atoms here and predicate atoms in `#query/predicate.ts`), in
162
- * the record's written order.
219
+ * One field position of a bindings record as a classed slot: the declared
220
+ * descriptor plus the slot's law-computed class, read off the relation's
221
+ * class record (`CR` — the schema class map's entry for the atom's
222
+ * relation). The one shape every join judgment compares.
163
223
  */
164
- declare function resolveBindings(context: string, fields: ReadonlyArray<{
165
- readonly name: string;
166
- readonly field: FieldData;
167
- }>, bindings: Readonly<Record<string, unknown>>): readonly BindingEntry[];
224
+ type SlotAt<F extends FieldsShape, CR, K> = {
225
+ readonly field: F[K & keyof F];
226
+ readonly class: ClassLookup<CR, K>;
227
+ };
168
228
  /**
169
- * The named-field atom the semantic twin of `query!`'s `Node(id: c)`:
170
- * fields bind vars, params, branded literals, `oneOf` sets, or (interval
171
- * fields) point terms; unmentioned fields are wildcards; a zero-binding
172
- * atom is a nonemptiness gate on the relation (IR-legal, so writable).
229
+ * The var binding's judgment against the incoming rule environment: a name
230
+ * already bound must land on a class-equal slot (bare pairs only with bare).
173
231
  */
174
- declare function match<Name extends string, Fields extends FieldsShape, const B extends MatchInput<Fields>>(relation: Relation<Name, Fields>, bindings: B): MatchAtom<BindingsParams<B>>;
232
+ type EnvJoinOk<Env extends EnvShape, F extends FieldsShape, CR, K, N extends string> = N extends keyof Env ? JoinOk<Env[N], SlotAt<F, CR, K>> : true;
175
233
  /**
176
- * Negation anti-join over sets, no null trick: a binding satisfies the
177
- * negated atom iff NO fact matches it. Safety (every negated var bound
178
- * positively) is validated at `query()` construction with an error naming
179
- * the variable; the negated atom binds nothing, only rejects. An `oneOf`
180
- * binding is refused HERE, at construction: it lowers to a synthetic
181
- * variable bound only inside the atom plus a rule-level OR — which is
182
- * exactly the shape the safety rule rejects, and semantically wrong for
183
- * negation anyway (¬∃(f = a ∨ f = b) is a CONJUNCTION of negated atoms,
184
- * ¬∃(f = a) ∧ ¬∃(f = b), never one negated atom's OR).
234
+ * The var binding's judgment against its OWN record's siblings: two
235
+ * bindings of one var name inside a single bindings record are the same
236
+ * join the environment check judges across atoms, so every same-named
237
+ * sibling must be class-equal too. Without this arm two FIRST occurrences
238
+ * of one name (a record the environment has not seen yet) would meet no
239
+ * check at all the intra-atom join would silently cross classes.
185
240
  */
186
- declare function not<P extends ParamsRecord>(atom: MatchAtom<P>): MatchAtom<P>;
241
+ type SiblingJoinOk<F extends FieldsShape, CR, B, K extends keyof B, N extends string> = false extends {
242
+ [K2 in Exclude<keyof B & keyof F, K>]: B[K2] extends Var<N> ? JoinOk<SlotAt<F, CR, K2>, SlotAt<F, CR, K>> : true;
243
+ }[Exclude<keyof B & keyof F, K>] ? false : true;
187
244
  /**
188
- * The equality atom (`ir::CmpOp::Eq`) for binding a var to a param or
189
- * literal where punning inside `match` doesn't apply, and for var-to-var
190
- * unification. Prefer direct placement (`match(Account, { kind:
191
- * Kind.Savings })`); `is` exists for the var-to-param case. `ParamSet` is
192
- * legal here and under no other operator (the IR's `Eq`-only set rule).
245
+ * The per-property join judgment of a bindings record: a var binding must
246
+ * be class-equal to the rule environment's binding of the name AND to
247
+ * every same-named sibling of its own record (a cross-class reuse maps
248
+ * the property to `never` the compile error the old value brand carried,
249
+ * now law-born off the schema type's class map).
193
250
  */
194
- declare function is<V, const R extends Var<V> | Param<string, V> | ParamSet<string, V> | V>(left: Var<V>, right: R): ComparisonItem<ParamsShape<TermContribution<R>>>;
195
- /** Typed disequality (`ir::CmpOp::Ne`). "Not in set" has no operatorwrite a negated atom. */
196
- declare function ne<V, const R extends Var<V> | Param<string, V> | V>(left: Var<V>, right: R): ComparisonItem<ParamsShape<TermContribution<R>>>;
251
+ type BindingOk<Env extends EnvShape, F extends FieldsShape, CR, B, K extends keyof B> = B[K] extends Var<infer N extends string> ? [EnvJoinOk<Env, F, CR, K, N>, SiblingJoinOk<F, CR, B, K, N>] extends [true, true] ? true : false : true;
252
+ /** The validated bindings record (intersect with the inferred `B`errors land on the offending property). */
253
+ type CheckBindings<Env extends EnvShape, F extends FieldsShape, CR, B> = {
254
+ readonly [K in keyof B]: K extends keyof F ? (BindingOk<Env, F, CR, B, K> extends true ? B[K] : never) : never;
255
+ };
256
+ /** The environment a bindings record contributes: var name → the bound slot (descriptor + class). */
257
+ type BindEnv<F extends FieldsShape, CR, B> = {
258
+ readonly [K in keyof B & keyof F as B[K] extends Var<infer N extends string> ? N : never]: SlotAt<F, CR, K>;
259
+ };
260
+ /** The params-object fragments a bindings record contributes (one union member per param use). */
261
+ type BindParams<F extends FieldsShape, B> = {
262
+ [K in keyof B & keyof F]: B[K] extends Param<infer P extends string> ? {
263
+ readonly [Q in P]: ParamValueAt<F[K]>;
264
+ } : B[K] extends SetParam<infer P extends string> ? {
265
+ readonly [Q in P]: readonly ParamValueAt<F[K]>[];
266
+ } : never;
267
+ }[keyof B & keyof F];
197
268
  /**
198
- * One side of an order comparison: a u64/i64-typed var or param, a bigint
199
- * literal, or the measure (`duration(v)`) order operators are legal for
200
- * the orderable types only, never intervals/bytes/strings/bools (the IR's
201
- * comparison rules; each refusal is the engine's own typed diagnostic).
269
+ * One comparison VALUE: op plus its operands, raw the runtime
270
+ * representation carries the operand types, so `.where`'s environment
271
+ * check and the params inference both read the value itself (no phantom).
272
+ * `mask` is populated exactly for `allen`.
202
273
  */
203
- type OrderInput = Var<bigint> | Param<string, bigint> | bigint | Duration;
204
- /** Strict less-than (`ir::CmpOp::Lt`). */
205
- declare function lt<const L extends OrderInput, const R extends OrderInput>(left: L, right: R): ComparisonItem<ParamsShape<TermContribution<L> | TermContribution<R>>>;
274
+ interface Cmp<Op extends CmpKind, L, R, M = undefined> {
275
+ readonly cond: "cmp";
276
+ readonly op: Op;
277
+ readonly lhs: L;
278
+ readonly rhs: R;
279
+ readonly mask: M;
280
+ }
281
+ /** One condition-tree VALUE (`and`/`or` over comparisons and nested trees). */
282
+ interface Tree<Ch extends readonly AnyTreeChild[]> {
283
+ readonly cond: "tree";
284
+ readonly op: "and" | "or";
285
+ readonly children: Ch;
286
+ }
287
+ /**
288
+ * One negated-atom VALUE — negation is a position in the rule (anti-join
289
+ * over sets, no null trick): a binding satisfies it iff NO fact matches.
290
+ * Its variables must be positively bound in the rule — environment
291
+ * membership at `.where` IS the safety rule, a compile error before it is
292
+ * the engine's refusal.
293
+ */
294
+ interface NotAtom<R extends MatchOwner, B> {
295
+ readonly cond: "not";
296
+ readonly relation: R;
297
+ readonly bindings: B;
298
+ }
299
+ /** Any comparison value. */
300
+ type AnyCmp = Cmp<CmpKind, unknown, unknown, unknown>;
301
+ /** Any condition-tree child (trees hold comparisons and trees — never atoms). */
302
+ type AnyTreeChild = AnyCmp | Tree<readonly AnyTreeChild[]>;
303
+ /** Any negated-atom value. */
304
+ type AnyNotAtom = NotAtom<MatchOwner, unknown>;
305
+ /** Any `.where` input: a comparison, a condition tree, or a negated atom. */
306
+ type AnyCond = AnyCmp | Tree<readonly AnyTreeChild[]> | AnyNotAtom;
307
+ /** What `eq`'s right side accepts (`ParamSet` is `Eq`-only — the IR's rule). */
308
+ type EqRight = Var<string> | Param<string> | SetParam<string> | bigint | string | boolean | Uint8Array | IntervalValue;
309
+ /** What `ne`'s right side accepts. */
310
+ type NeRight = Var<string> | Param<string> | bigint | string | boolean | Uint8Array | IntervalValue;
311
+ /** One side of an order comparison: orderable terms only (the IR's comparison rules). */
312
+ type OrderSide = Var<string> | Param<string> | Duration<string> | bigint;
313
+ /** The point side of `pointIn`/`covers`. */
314
+ type PointSide = Var<string> | Param<string> | bigint;
315
+ /** The interval side of `pointIn`/`covers`/`allen`. */
316
+ type IntervalSide = Var<string> | Param<string> | IntervalValue;
317
+ /** Builds one comparison value. */
318
+ declare function comparison<Op extends CmpKind, L, R, M>(op: Op, lhs: L, rhs: R, mask: M): Cmp<Op, L, R, M>;
319
+ /**
320
+ * The equality comparison (`ir::CmpOp::Eq`) — a bound variable against a
321
+ * variable (var-to-var unification, domain-equal by the environment
322
+ * check), a param (typed by the variable), an ∈-set param (`Eq`-only, the
323
+ * IR's set rule), or a bare literal of the variable's own value type.
324
+ * Prefer direct placement in `match` where punning applies.
325
+ */
326
+ declare function eq<L extends Var<string>, const R extends EqRight>(left: L, right: R): Cmp<"eq", L, R>;
327
+ /** Typed disequality (`ir::CmpOp::Ne`). "Not in set" has no operator — write a negated atom. */
328
+ declare function ne<L extends Var<string>, const R extends NeRight>(left: L, right: R): Cmp<"ne", L, R>;
329
+ /** Strict less-than (`ir::CmpOp::Lt`) — orderable sides only, never intervals/bytes/strings/bools. */
330
+ declare function lt<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"lt", L, R>;
206
331
  /** Less-or-equal (`ir::CmpOp::Le`). */
207
- declare function le<const L extends OrderInput, const R extends OrderInput>(left: L, right: R): ComparisonItem<ParamsShape<TermContribution<L> | TermContribution<R>>>;
332
+ declare function le<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"le", L, R>;
208
333
  /** Strict greater-than (`ir::CmpOp::Gt`). */
209
- declare function gt<const L extends OrderInput, const R extends OrderInput>(left: L, right: R): ComparisonItem<ParamsShape<TermContribution<L> | TermContribution<R>>>;
334
+ declare function gt<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"gt", L, R>;
210
335
  /** Greater-or-equal (`ir::CmpOp::Ge`). */
211
- declare function ge<const L extends OrderInput, const R extends OrderInput>(left: L, right: R): ComparisonItem<ParamsShape<TermContribution<L> | TermContribution<R>>>;
212
- /** An interval-typed comparison side: a var, a param, or a `span` literal. */
213
- type IntervalInput = Var<IntervalValue> | Param<string, IntervalValue> | IntervalValue;
214
- /** A point-typed comparison side. */
215
- type PointInput = Var<bigint> | Param<string, bigint> | bigint;
336
+ declare function ge<const L extends OrderSide, const R extends OrderSide>(left: L, right: R): Cmp<"ge", L, R>;
337
+ /**
338
+ * Point membership as a predicate (`ir::CmpOp::PointIn`), membership
339
+ * spelling: `pointIn(t, w)` holds iff `w.start ≤ t < w.end`. The IR
340
+ * orders the operands interval-left, point-right; the value stores them
341
+ * that way whatever the surface spelling.
342
+ */
343
+ declare function pointIn<const P extends PointSide, const I extends IntervalSide>(point: P, interval: I): Cmp<"pointIn", I, P>;
216
344
  /**
217
- * Point membership as a predicate (`ir::CmpOp::PointIn`): `covers(iv, t)`
218
- * holds iff `iv.start t < iv.end` the predicate form of the membership
219
- * typing rule, for terms already bound elsewhere. Interval interval is
220
- * NOT this operator; that predicate is `allen(a, ALLEN.covers, b)`. The IR
221
- * orders the operands interval-left, point-right; so does this surface.
345
+ * Point membership, coverage spelling `covers(w, t)` is `pointIn(t, w)`
346
+ * with the interval written first (the IR's own operand order; a literal
347
+ * `span(...)` left operand is legal and tags by the point sibling's
348
+ * element domain the bug-hunt fix, now also a type-level guarantee).
349
+ * Interval interval is NOT this operator; that predicate is
350
+ * `allen(a, ALLEN.covers, b)`.
222
351
  */
223
- declare function covers<const I extends IntervalInput, const T extends PointInput>(interval: I, point: T): ComparisonItem<ParamsShape<TermContribution<I> | TermContribution<T>>>;
352
+ declare function covers<const I extends IntervalSide, const P extends PointSide>(interval: I, point: P): Cmp<"pointIn", I, P>;
224
353
  /**
225
354
  * The Allen coordinate system's named constants — the 13 basics in the
226
355
  * engine's palindromic bit order (bit i = basic i:
@@ -255,31 +384,98 @@ declare const ALLEN: Readonly<{
255
384
  * THE interval-pair comparison (`ir::CmpOp::Allen`): two interval terms of
256
385
  * one element type, satisfied iff the pair's classification is in the
257
386
  * 13-bit mask — a literal built from the `ALLEN` constants, or a mask
258
- * parameter (`$.allenParam`). Vacuous masks (empty/full) are the engine's
387
+ * parameter (`r.maskParam`). Vacuous masks (empty/full) are the engine's
259
388
  * two distinct typed rejections; nothing is pre-judged here beyond the
260
389
  * representable bit range.
261
390
  */
262
- declare function allen<const A extends IntervalInput, const M extends number | MaskParam<string>, const B extends IntervalInput>(left: A, mask: M, right: B): ComparisonItem<ParamsShape<TermContribution<A> | TermContribution<M> | TermContribution<B>>>;
391
+ declare function allen<const A extends IntervalSide, const M extends number | MaskParam<string>, const B extends IntervalSide>(left: A, mask: M, right: B): Cmp<"allen", A, B, M>;
263
392
  /**
264
393
  * Conjunction node of the input condition grammar (`ConditionTree::And`).
265
394
  * The rule's condition list is already a conjunction — `and` exists for
266
395
  * nesting under `or`, and the empty combination keeps the IR's algebraic
267
396
  * reading (`And([])` is true).
268
397
  */
269
- declare function and<const C extends readonly AnyCondition[]>(...children: C): ConditionTreeItem<ParamsShape<ItemParams<C[number]>>>;
398
+ declare function and<const C extends readonly AnyTreeChild[]>(...children: C): Tree<C>;
270
399
  /**
271
400
  * Disjunction node of the input condition grammar (`ConditionTree::Or`) —
272
401
  * the one place the surface admits a nested OR; validation distributes it
273
402
  * to DNF rules engine-side (OR is data or it is nothing). `Or([])` keeps
274
403
  * its algebraic reading (false: the rule denotes nothing).
275
404
  */
276
- declare function or<const C extends readonly AnyCondition[]>(...children: C): ConditionTreeItem<ParamsShape<ItemParams<C[number]>>>;
405
+ declare function or<const C extends readonly AnyTreeChild[]>(...children: C): Tree<C>;
406
+ /**
407
+ * Negation — anti-join over sets: `not(Rel, { field: r.var("x"), ... })`
408
+ * rejects every binding some matching fact extends. A negated atom binds
409
+ * nothing, only rejects: every variable it names must be positively bound
410
+ * in the rule, which `.where`'s environment check makes a COMPILE error
411
+ * (the engine's safety refusal stands behind it). A CLOSED owner is legal
412
+ * here too — the engine folds a resolvable negated closed atom to the
413
+ * COMPLEMENT of its member set (domain-witness guarded), and the SDK's
414
+ * negation rules apply to it unchanged.
415
+ */
416
+ declare function not<R extends MatchOwner, const B extends MatchShape<MatchFields<R>>>(relation: R, bindings: B): NotAtom<R, B>;
417
+ /** Whether a var name is bound in the environment at an orderable (u64/i64) field. */
418
+ type OrderVarOk<Env extends EnvShape, N extends string> = N extends keyof Env ? Env[N]["field"]["kind"] extends "u64" | "i64" ? true : false : false;
419
+ /** Whether a var name is bound at an interval field. */
420
+ type IntervalVarOk<Env extends EnvShape, N extends string> = N extends keyof Env ? Env[N]["field"]["kind"] extends "interval" ? true : false : false;
421
+ /** One order-comparison side's judgment against the environment. */
422
+ type OrderSideOk<Env extends EnvShape, T> = T extends Var<infer N extends string> ? OrderVarOk<Env, N> : T extends Duration<infer N extends string> ? IntervalVarOk<Env, N> : true;
423
+ /** One point side's judgment. */
424
+ type PointSideOk<Env extends EnvShape, T> = T extends Var<infer N extends string> ? OrderVarOk<Env, N> : true;
425
+ /** One interval side's judgment. */
426
+ type IntervalSideOk<Env extends EnvShape, T> = T extends Var<infer N extends string> ? IntervalVarOk<Env, N> : true;
427
+ /** The `eq`/`ne` judgment: left var bound; right joins it (class-equal var, param, or an exact-type literal). */
428
+ type EqOk<Env extends EnvShape, L, R> = L extends Var<infer N extends string> ? N extends keyof Env ? R extends Var<infer M extends string> ? M extends keyof Env ? JoinOk<Env[N], Env[M]> : false : R extends Param<string> | SetParam<string> ? true : [R] extends [Infer<Env[N]["field"]>] ? true : false : false : false;
429
+ /** One negated-atom binding's judgment: a var must be positively bound (safety) AND class-equal. */
430
+ type NotBindingOk<Env extends EnvShape, S extends ClassedField, T> = T extends Var<infer N extends string> ? (N extends keyof Env ? JoinOk<Env[N], S> : false) : true;
431
+ /** The whole negated atom's judgment (`CR` — the negated relation's class record off the schema class map). */
432
+ type NotOk<Env extends EnvShape, F extends FieldsShape, CR, B> = false extends {
433
+ [K in keyof B]: NotBindingOk<Env, SlotAt<F, CR, K>, B[K]>;
434
+ }[keyof B] ? false : true;
435
+ /**
436
+ * One condition's judgment against the rule environment — the type-level
437
+ * twin of the engine's comparison roster: class-equal joins (off the
438
+ * schema type's class map), orderable order sides (an interval var under a
439
+ * non-`pointIn` op is exactly here refused), kind-correct
440
+ * `pointIn`/`covers`/`allen` sides, and negated-atom safety (the negated
441
+ * relation's class record is resolved through `Classes` by its name). The
442
+ * leading `[AnyTreeChild] extends [C]` arm is the recursion's base case:
443
+ * at an UNRESOLVED constraint (the whole condition union — or a tree's
444
+ * child union, which is the union itself) the judgment is vacuously true —
445
+ * without it the constraint instantiation recurses into itself.
446
+ */
447
+ type CondOkBool<Env extends EnvShape, Classes extends SchemaClasses, C> = [AnyTreeChild] extends [C] ? true : C extends Cmp<infer Op, infer L, infer R, unknown> ? Op extends "eq" | "ne" ? EqOk<Env, L, R> : Op extends "lt" | "le" | "gt" | "ge" ? [OrderSideOk<Env, L>, OrderSideOk<Env, R>] extends [true, true] ? true : false : Op extends "pointIn" ? [IntervalSideOk<Env, L>, PointSideOk<Env, R>] extends [true, true] ? true : false : Op extends "allen" ? [IntervalSideOk<Env, L>, IntervalSideOk<Env, R>] extends [true, true] ? true : false : false : C extends Tree<infer Ch extends readonly AnyTreeChild[]> ? false extends CondOkBool<Env, Classes, Ch[number]> ? false : true : C extends NotAtom<infer R extends MatchOwner, infer B> ? NotOk<Env, MatchFields<R>, ClassRecordOf<Classes, R["name"]>, B> : false;
448
+ /** The validated `.where` argument (intersect with the inferred condition type). */
449
+ type CheckCond<Env extends EnvShape, Classes extends SchemaClasses, C> = CondOkBool<Env, Classes, C> extends true ? C : never;
450
+ /** The `eq`/`ne` params contribution: the param typed by the left variable's field. */
451
+ type EqParams<Env extends EnvShape, L, R> = L extends Var<infer N extends string> ? R extends Param<infer P extends string> ? {
452
+ readonly [Q in P]: Infer<Env[N & keyof Env]["field"]>;
453
+ } : R extends SetParam<infer P extends string> ? {
454
+ readonly [Q in P]: readonly Infer<Env[N & keyof Env]["field"]>[];
455
+ } : never : never;
456
+ /** An order side's params contribution (order params are always `bigint`). */
457
+ type OrderSideParams<T> = T extends Param<infer P extends string> ? {
458
+ readonly [Q in P]: bigint;
459
+ } : never;
460
+ /** An interval side's params contribution. */
461
+ type IntervalSideParams<T> = T extends Param<infer P extends string> ? {
462
+ readonly [Q in P]: IntervalValue;
463
+ } : never;
464
+ /** The mask position's params contribution. */
465
+ type MaskParams<M> = M extends MaskParam<infer P extends string> ? {
466
+ readonly [Q in P]: number;
467
+ } : never;
277
468
  /**
278
- * The measure term surface `Duration`, IR `Measure`: the point-set
279
- * cardinality `end start` of an interval-typed variable, u64. See
280
- * {@link Duration} for the legal positions.
469
+ * One condition's params-object fragments (a union; the rule builder folds
470
+ * them into the inferred `Params` record) every param typed by its use.
471
+ * The leading arm is the same base case as {@link CondOkBool}'s: the
472
+ * unresolved constraint contributes nothing.
281
473
  */
282
- declare function duration<IV extends IntervalValue>(over: Var<IV>): Duration;
283
- export type { AnyBodyItem, AnyCondition, AtomSourceData, BindingEntry, BindingsParams, BindingTerm, CmpOpData, CmpTerm, ComparisonItem, ConditionTreeItem, Duration, IntervalInput, MaskData, MatchAtom, MatchInput, OrderInput, PointInput, PointTermInput, TermInput };
284
- export { ALLEN, allen, and, covers, duration, ge, gt, is, le, lt, match, ne, not, or, resolveBindings };
474
+ type CondParams<Env extends EnvShape, C> = [AnyTreeChild] extends [C] ? never : C extends Cmp<infer Op, infer L, infer R, infer M> ? Op extends "eq" | "ne" ? EqParams<Env, L, R> : Op extends "lt" | "le" | "gt" | "ge" ? OrderSideParams<L> | OrderSideParams<R> : Op extends "pointIn" ? IntervalSideParams<L> | OrderSideParams<R> : Op extends "allen" ? IntervalSideParams<L> | IntervalSideParams<R> | MaskParams<M> : never : C extends Tree<infer Ch extends readonly AnyTreeChild[]> ? CondParams<Env, Ch[number]> : C extends NotAtom<infer R extends MatchOwner, infer B> ? BindParams<MatchFields<R>, B> : never;
475
+ /** The flattened params record one bindings record contributes. */
476
+ type BindParamsShape<F extends FieldsShape, B> = ShapeOf<BindParams<F, B>>;
477
+ /** The flattened params record one condition contributes. */
478
+ type CondParamsShape<Env extends EnvShape, C> = ShapeOf<CondParams<Env, C>>;
479
+ export type { AggData, AnyCmp, AnyCond, AnyNotAtom, AnyTreeChild, AtomData, BindEnv, BindingEntry, BindingInput, BindingTermData, BindParams, BindParamsShape, CheckBindings, CheckCond, Cmp, CmpData, CmpKind, CmpTermData, CondData, CondOkBool, CondParams, CondParamsShape, IntervalSide, IntervalVarOk, MaskData, MatchFields, MatchOwner, MatchShape, NotAtom, OrderSide, OrderVarOk, ParamUse, PointSide, RecData, RuleData, RuleItem, SelectColumn, SelectEntryData, Tree, TreeData };
480
+ export { ALLEN, allen, and, comparison, covers, eq, ge, gt, le, lt, ne, not, or, pointIn };
285
481
  //# sourceMappingURL=atom.d.ts.map