@orkestrel/reason 0.0.13 → 0.0.14

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.
@@ -1,6 +1,6 @@
1
- import { GUARD_DEPTH_LIMIT, arrayOf, holds, isArray, isBoolean, isError, isFiniteNumber, isFunction, isInstance, isNumber, isObject, isRecord, isString, lazyOf, literalOf, notOf, orOf, parseJSONAs, parseNumber, parseNumberField, readArrayEntries, recordOf, resolveField, unionOf, whereOf } from "@orkestrel/contract";
1
+ import { GUARD_DEPTH_LIMIT, INTRINSICS, arrayOf, holds, isArray, isBoolean, isError, isFiniteNumber, isFunction, isInstance, isNumber, isObject, isRecord, isString, lazyOf, literalOf, notOf, orOf, parseJSONAs, parseNumber, parseNumberField, readArrayEntries, recordOf, resolveField, unionOf, whereOf } from "@orkestrel/contract";
2
2
  import { Emitter } from "@orkestrel/emitter";
3
- //#region src/core/constants.ts
3
+ // src/core/constants.ts
4
4
  /**
5
5
  * Holds the default `bail` for the `Reason` orchestrator — a reasoner throw is rethrown
6
6
  * after the `error` emit. Default: `true`.
@@ -97,8 +97,7 @@ var DEFINITION_BUILDER_BRAND = Symbol("reasons.definitionBuilder");
97
97
  * match the other's guard.
98
98
  */
99
99
  var SUBJECT_BUILDER_BRAND = Symbol("reasons.subjectBuilder");
100
- //#endregion
101
- //#region src/core/errors.ts
100
+ // src/core/errors.ts
102
101
  /**
103
102
  * Represents an error thrown by the reasons layer.
104
103
  *
@@ -122,6 +121,7 @@ var ReasonError = class extends Error {
122
121
  context;
123
122
  constructor(code, message, context) {
124
123
  super(message);
124
+ Object.defineProperty(this, Symbol.for("@orkestrel/reason.ReasonError"), { value: this });
125
125
  this.name = "ReasonError";
126
126
  this.code = code;
127
127
  if (context !== void 0) this.context = context;
@@ -130,6 +130,13 @@ var ReasonError = class extends Error {
130
130
  /**
131
131
  * Narrows an unknown caught value to a {@link ReasonError}.
132
132
  *
133
+ * @remarks
134
+ * Accepts errors from another installed copy and subclasses regardless of `name`.
135
+ * Requires the own self-valued `Symbol.for('@orkestrel/reason.ReasonError')`
136
+ * brand, a non-base global `Error` prototype, and valid declared members.
137
+ * Plain objects, unbranded look-alikes, and transparent proxies are rejected.
138
+ * Hostile reads return false through the contract intrinsics inside `holds`.
139
+ *
133
140
  * @param value - The value to test (typically a `catch` binding)
134
141
  * @returns True if `value` is a {@link ReasonError}; false otherwise
135
142
  *
@@ -143,10 +150,15 @@ var ReasonError = class extends Error {
143
150
  * ```
144
151
  */
145
152
  function isReasonError(value) {
146
- return isInstance(value, ReasonError);
153
+ return holds(() => {
154
+ if (!isInstance(value, Error) || INTRINSICS.prototype(value) === Error.prototype) return false;
155
+ if (INTRINSICS.describe(value, Symbol.for("@orkestrel/reason.ReasonError"))?.value !== value) return false;
156
+ const code = INTRINSICS.reflect.read(value, "code");
157
+ const context = INTRINSICS.reflect.read(value, "context");
158
+ return (code === "MISSING" || code === "INVALID" || code === "MISMATCH" || code === "DESTROYED" || code === "TARGET" || code === "OPERATOR") && isString(INTRINSICS.reflect.read(value, "message")) && (context === void 0 || isObject(context) || isFunction(context));
159
+ });
147
160
  }
148
- //#endregion
149
- //#region src/core/validators.ts
161
+ // src/core/validators.ts
150
162
  /**
151
163
  * Determines whether a value is a {@link Reasoning} literal.
152
164
  *
@@ -163,20 +175,20 @@ function isReasonError(value) {
163
175
  */
164
176
  var isReasoning = literalOf("quantitative", "logical", "symbolic", "inferential");
165
177
  /**
166
- * Determines whether a value is a {@link ChainingStrategy} literal.
178
+ * Determines whether a value is a {@link ChainStrategy} literal.
167
179
  *
168
180
  * @param value - The value to test
169
181
  * @returns True if `value` is `'forward'` or `'backward'`; false otherwise
170
182
  *
171
183
  * @example
172
184
  * ```ts
173
- * import { isChainingStrategy } from '@src/core'
185
+ * import { isChainStrategy } from '@src/core'
174
186
  *
175
- * isChainingStrategy('forward') // true
176
- * isChainingStrategy('upward') // false
187
+ * isChainStrategy('forward') // true
188
+ * isChainStrategy('upward') // false
177
189
  * ```
178
190
  */
179
- var isChainingStrategy = literalOf("forward", "backward");
191
+ var isChainStrategy = literalOf("forward", "backward");
180
192
  /**
181
193
  * Determines whether a value is a {@link MathOperation} literal.
182
194
  *
@@ -699,7 +711,7 @@ function isLogicalDefinition(value) {
699
711
  name: isString,
700
712
  description: isString,
701
713
  rules: arrayOf(isRule),
702
- strategy: isChainingStrategy,
714
+ strategy: isChainStrategy,
703
715
  depth: isFiniteNumber
704
716
  }, ["description", "depth"])(value);
705
717
  }
@@ -750,7 +762,7 @@ function isInferentialDefinition(value) {
750
762
  description: isString,
751
763
  inferences: arrayOf(isInference),
752
764
  facts: arrayOf(isFact),
753
- strategy: isChainingStrategy,
765
+ strategy: isChainStrategy,
754
766
  depth: isFiniteNumber
755
767
  }, ["description", "depth"])(value);
756
768
  }
@@ -1011,8 +1023,7 @@ function isProofNode(value) {
1011
1023
  if (!isArray(children)) return false;
1012
1024
  const entries = readArrayEntries(children);
1013
1025
  if (!entries.success || !entries.value.dense) return false;
1014
- for (let index = entries.value.entries.length - 1; index >= 0; index -= 1) {
1015
- const child = entries.value.entries[index];
1026
+ for (const child of entries.value.entries.toReversed()) {
1016
1027
  if (!isObject(child) || isArray(child)) return false;
1017
1028
  worklist.push([
1018
1029
  child,
@@ -1199,8 +1210,7 @@ function isDefinitionBuilder(value) {
1199
1210
  function isSubjectBuilder(value) {
1200
1211
  return isObject(value) && Reflect.get(value, SUBJECT_BUILDER_BRAND) === true;
1201
1212
  }
1202
- //#endregion
1203
- //#region src/core/helpers.ts
1213
+ // src/core/helpers.ts
1204
1214
  /**
1205
1215
  * Formats a {@link FieldPath} for display — the single string key itself, or the
1206
1216
  * array segments joined with `.`.
@@ -1222,6 +1232,19 @@ function formatField(field) {
1222
1232
  return isString(field) ? field : field.join(".");
1223
1233
  }
1224
1234
  /**
1235
+ * Iterates nonnegative indices below a numeric limit without allocating a range.
1236
+ *
1237
+ * @example
1238
+ * ```ts
1239
+ * [...iterateIndices(2.5)] // [0, 1, 2]
1240
+ * ```
1241
+ */
1242
+ function* iterateIndices(limit) {
1243
+ yield* Array.prototype.keys.call({ length: Math.max(0, Math.ceil(limit)) });
1244
+ if (limit > Number.MAX_SAFE_INTEGER) yield Number.MAX_SAFE_INTEGER;
1245
+ if (limit > Number.MAX_SAFE_INTEGER + 1) for (;;) yield Number.MAX_SAFE_INTEGER + 1;
1246
+ }
1247
+ /**
1225
1248
  * Clamps a number to inclusive {@link Bounds}.
1226
1249
  *
1227
1250
  * @remarks
@@ -1242,10 +1265,8 @@ function formatField(field) {
1242
1265
  */
1243
1266
  function clamp(value, limit) {
1244
1267
  if (!limit) return value;
1245
- let result = value;
1246
- if (limit.minimum !== void 0 && result < limit.minimum) result = limit.minimum;
1247
- if (limit.maximum !== void 0 && result > limit.maximum) result = limit.maximum;
1248
- return result;
1268
+ const minimum = limit.minimum !== void 0 && value < limit.minimum ? limit.minimum : value;
1269
+ return limit.maximum !== void 0 && minimum > limit.maximum ? limit.maximum : minimum;
1249
1270
  }
1250
1271
  /**
1251
1272
  * Checks whether a value falls inside an inclusive range expressed as an array.
@@ -1441,12 +1462,7 @@ function equalValues(left, right) {
1441
1462
  * ```
1442
1463
  */
1443
1464
  function sortByPriority(items) {
1444
- const usable = [];
1445
- for (const item of items) {
1446
- if (!isObject(item)) continue;
1447
- usable.push(item);
1448
- }
1449
- return usable.sort((left, right) => (left.priority ?? 0) - (right.priority ?? 0));
1465
+ return Iterator.from(items).filter(isObject).toArray().sort((left, right) => (left.priority ?? 0) - (right.priority ?? 0));
1450
1466
  }
1451
1467
  /**
1452
1468
  * Collects the ids that appear more than once in an id-carrying list — each
@@ -1469,9 +1485,10 @@ function sortByPriority(items) {
1469
1485
  * ```
1470
1486
  */
1471
1487
  function findDuplicates(items) {
1472
- const counts = /* @__PURE__ */ new Map();
1473
- for (const item of items) counts.set(item.id, (counts.get(item.id) ?? 0) + 1);
1474
- return [...counts.entries()].filter(([, count]) => count > 1).map(([id]) => id);
1488
+ const indexed = Iterator.from(items).map((item, index) => [item.id, index]).toArray();
1489
+ const first = new Map(indexed.toReversed());
1490
+ const duplicates = new Set(indexed.filter(([id, index]) => first.get(id) !== index).map(([id]) => id));
1491
+ return indexed.filter(([id, index]) => first.get(id) === index && duplicates.has(id)).map(([id]) => id);
1475
1492
  }
1476
1493
  /**
1477
1494
  * Derives a fact's predicate+arity bucket key — length-prefixed so the
@@ -1527,14 +1544,7 @@ function factToArityKey(fact) {
1527
1544
  * ```
1528
1545
  */
1529
1546
  function indexByArity(facts) {
1530
- const index = /* @__PURE__ */ new Map();
1531
- for (const entry of facts) {
1532
- const key = factToArityKey(entry);
1533
- const bucket = index.get(key);
1534
- if (bucket) bucket.push(entry);
1535
- else index.set(key, [entry]);
1536
- }
1537
- return index;
1547
+ return Map.groupBy(facts, factToArityKey);
1538
1548
  }
1539
1549
  /**
1540
1550
  * Derives one fact term's contribution to a dedup key — reference identity for
@@ -1634,21 +1644,20 @@ function factToKey(fact, identities) {
1634
1644
  function matchFacts(pattern, candidate) {
1635
1645
  if (pattern.predicate !== candidate.predicate) return void 0;
1636
1646
  if (pattern.terms.length !== candidate.terms.length) return void 0;
1637
- const bindings = {};
1638
- for (let index = 0; index < pattern.terms.length; index++) {
1639
- const patternTerm = pattern.terms[index];
1647
+ const bindings = /* @__PURE__ */ new Map();
1648
+ for (const [index, patternTerm] of pattern.terms.entries()) {
1640
1649
  const factTerm = candidate.terms[index];
1641
1650
  if (isString(patternTerm) && patternTerm.startsWith("?")) {
1642
- if (patternTerm in bindings) {
1643
- if (bindings[patternTerm] !== factTerm) return void 0;
1644
- } else bindings[patternTerm] = factTerm;
1651
+ if (bindings.has(patternTerm)) {
1652
+ if (bindings.get(patternTerm) !== factTerm) return void 0;
1653
+ } else bindings.set(patternTerm, factTerm);
1645
1654
  } else if (isString(factTerm) && factTerm.startsWith("?")) {
1646
- if (factTerm in bindings) {
1647
- if (bindings[factTerm] !== patternTerm) return void 0;
1648
- } else bindings[factTerm] = patternTerm;
1655
+ if (bindings.has(factTerm)) {
1656
+ if (bindings.get(factTerm) !== patternTerm) return void 0;
1657
+ } else bindings.set(factTerm, patternTerm);
1649
1658
  } else if (patternTerm !== factTerm) return;
1650
1659
  }
1651
- return bindings;
1660
+ return Object.fromEntries(bindings);
1652
1661
  }
1653
1662
  /**
1654
1663
  * Substitutes a fact's bound `'?'`-variables with their values — a fresh fact
@@ -1710,15 +1719,11 @@ function instantiateFact(fact, bindings) {
1710
1719
  * ```
1711
1720
  */
1712
1721
  function computePremiseConfidence(premises, index, bindings) {
1713
- let confidence = 1;
1714
- for (const premise of premises) {
1722
+ return Iterator.from(premises).reduce((confidence, premise) => {
1715
1723
  const instantiated = instantiateFact(premise, bindings);
1716
- for (const candidate of index.get(factToArityKey(premise)) ?? []) if (matchFacts(instantiated, candidate)) {
1717
- confidence *= candidate.confidence ?? 1;
1718
- break;
1719
- }
1720
- }
1721
- return confidence;
1724
+ for (const candidate of index.get(factToArityKey(premise)) ?? []) if (matchFacts(instantiated, candidate)) return confidence * (candidate.confidence ?? 1);
1725
+ return confidence;
1726
+ }, 1);
1722
1727
  }
1723
1728
  /**
1724
1729
  * Projects a subject's scalar fields into `has(key, value)` base facts — the
@@ -1742,25 +1747,24 @@ function computePremiseConfidence(premises, index, bindings) {
1742
1747
  * ```
1743
1748
  */
1744
1749
  function subjectToFacts(subject) {
1745
- const facts = [];
1746
- const trace = [];
1747
- for (const key of Object.keys(subject)) {
1748
- if (key === "id") continue;
1750
+ const rows = Object.keys(subject).flatMap((key) => {
1751
+ if (key === "id") return [];
1749
1752
  const value = subject[key];
1750
- if (value === void 0 || value === null) continue;
1751
- if (isObject(value)) continue;
1752
- facts.push({
1753
- id: `subject:${key}`,
1754
- predicate: "has",
1755
- terms: [key, value],
1756
- confidence: 1
1757
- });
1758
- trace.push(`Subject field "${key}" → has(${key}, ${String(value)})`);
1759
- }
1760
- if (facts.length > 0) trace.push(`Injected ${facts.length} fact(s) from subject`);
1753
+ if (value === void 0 || value === null) return [];
1754
+ if (isObject(value)) return [];
1755
+ return [{
1756
+ fact: {
1757
+ id: `subject:${key}`,
1758
+ predicate: "has",
1759
+ terms: [key, value],
1760
+ confidence: 1
1761
+ },
1762
+ trace: `Subject field "${key}" → has(${key}, ${String(value)})`
1763
+ }];
1764
+ });
1761
1765
  return {
1762
- facts,
1763
- trace
1766
+ facts: rows.map((row) => row.fact),
1767
+ trace: [...rows.map((row) => row.trace), ...rows.length > 0 ? [`Injected ${rows.length} fact(s) from subject`] : []]
1764
1768
  };
1765
1769
  }
1766
1770
  /**
@@ -1790,17 +1794,8 @@ function subjectToFacts(subject) {
1790
1794
  * ```
1791
1795
  */
1792
1796
  function findUnboundVariables(inference) {
1793
- const bound = /* @__PURE__ */ new Set();
1794
- for (const premise of inference.premises) for (const term of premise.terms) if (isString(term) && term.startsWith("?")) bound.add(term);
1795
- const unbound = [];
1796
- const seen = /* @__PURE__ */ new Set();
1797
- for (const term of inference.conclusion.terms) {
1798
- if (!isString(term) || !term.startsWith("?")) continue;
1799
- if (bound.has(term) || seen.has(term)) continue;
1800
- seen.add(term);
1801
- unbound.push(term);
1802
- }
1803
- return unbound;
1797
+ const bound = new Set(Iterator.from(inference.premises).flatMap((premise) => Iterator.from(premise.terms).filter((term) => isString(term) && term.startsWith("?"))));
1798
+ return [...new Set(Iterator.from(inference.conclusion.terms).filter((term) => isString(term) && term.startsWith("?") && !bound.has(term)))];
1804
1799
  }
1805
1800
  /**
1806
1801
  * Determines whether a symbolic expression contains an unbound occurrence of a
@@ -2017,8 +2012,9 @@ function extractAtoms(expression) {
2017
2012
  continue;
2018
2013
  }
2019
2014
  const operands = node.operands;
2020
- for (let index = operands.length - 1; index >= 0; index--) {
2021
- const operand = operands[index];
2015
+ const length = operands.length;
2016
+ for (const offset of iterateIndices(length)) {
2017
+ const operand = operands[length - 1 - offset];
2022
2018
  if (operand !== void 0) stack.push(operand);
2023
2019
  }
2024
2020
  }
@@ -2088,21 +2084,9 @@ function extractConclusions(expression) {
2088
2084
  * ```
2089
2085
  */
2090
2086
  function findOverlayMismatches(rules) {
2091
- const writeKeys = [];
2092
- const seenWrites = /* @__PURE__ */ new Set();
2093
- for (const candidate of rules) for (const atomLeaf of extractAtoms(candidate.conclusion)) {
2094
- if (!isArray(atomLeaf.check.field)) continue;
2095
- const key = formatField(atomLeaf.check.field);
2096
- if (seenWrites.has(key)) continue;
2097
- seenWrites.add(key);
2098
- writeKeys.push(key);
2099
- }
2100
- const readKeys = /* @__PURE__ */ new Set();
2101
- for (const candidate of rules) for (const premise of candidate.premises) for (const atomLeaf of extractAtoms(premise)) {
2102
- if (!isArray(atomLeaf.check.field)) continue;
2103
- readKeys.add(formatField(atomLeaf.check.field));
2104
- }
2105
- return writeKeys.filter((key) => readKeys.has(key));
2087
+ const writeKeys = new Set(Iterator.from(rules).flatMap((candidate) => extractAtoms(candidate.conclusion).flatMap((atom) => isArray(atom.check.field) ? [formatField(atom.check.field)] : [])));
2088
+ const readKeys = new Set(Iterator.from(rules).flatMap((candidate) => Iterator.from(candidate.premises).flatMap((premise) => extractAtoms(premise).flatMap((atom) => isArray(atom.check.field) ? [formatField(atom.check.field)] : []))));
2089
+ return [...writeKeys].filter((key) => readKeys.has(key));
2106
2090
  }
2107
2091
  /**
2108
2092
  * Builds the empty, type-shaped failure {@link ReasonResult} matching a
@@ -2370,20 +2354,20 @@ function removeById(items, id) {
2370
2354
  function mergeById(base, incoming, resolve) {
2371
2355
  const baseById = /* @__PURE__ */ new Map();
2372
2356
  for (const item of base) if (!baseById.has(item.id)) baseById.set(item.id, item);
2373
- const seen = /* @__PURE__ */ new Set();
2374
- const merged = [];
2357
+ const merged = /* @__PURE__ */ new Map();
2375
2358
  for (const item of incoming) {
2376
- if (seen.has(item.id)) continue;
2377
- seen.add(item.id);
2359
+ const query = item.id;
2360
+ if (merged.has(query)) continue;
2361
+ const id = item.id;
2378
2362
  const existing = baseById.get(item.id);
2379
- merged.push(existing === void 0 ? item : resolve ? resolve(existing, item) : item);
2363
+ merged.set(id, existing === void 0 ? item : resolve ? resolve(existing, item) : item);
2380
2364
  }
2381
2365
  for (const item of base) {
2382
- if (seen.has(item.id)) continue;
2383
- seen.add(item.id);
2384
- merged.push(item);
2366
+ const query = item.id;
2367
+ if (merged.has(query)) continue;
2368
+ merged.set(item.id, item);
2385
2369
  }
2386
- return merged;
2370
+ return [...merged.values()];
2387
2371
  }
2388
2372
  /**
2389
2373
  * Inserts `group` into a {@link QuantitativeDefinition}'s `groups` — dedup-then-
@@ -3342,15 +3326,12 @@ function mergeSubjects(base, incoming) {
3342
3326
  */
3343
3327
  function repeatSubject(subject, count) {
3344
3328
  const baseId = subject.id;
3345
- const clones = [];
3346
- for (let index = 0; index < count; index += 1) clones.push(isString(baseId) ? {
3329
+ return iterateIndices(count).map((index) => isString(baseId) ? {
3347
3330
  ...subject,
3348
3331
  id: `${baseId}-${index}`
3349
- } : { ...subject });
3350
- return clones;
3332
+ } : { ...subject }).toArray();
3351
3333
  }
3352
- //#endregion
3353
- //#region src/core/parsers.ts
3334
+ // src/core/parsers.ts
3354
3335
  /**
3355
3336
  * Parses a JSON string into a {@link Definition}, failing safe to `undefined`.
3356
3337
  *
@@ -3377,8 +3358,7 @@ function repeatSubject(subject, count) {
3377
3358
  function parseDefinition(json) {
3378
3359
  return parseJSONAs(json, isDefinition);
3379
3360
  }
3380
- //#endregion
3381
- //#region src/core/Reason.ts
3361
+ // src/core/Reason.ts
3382
3362
  /**
3383
3363
  * Implements the reasoning orchestrator — a thin router over registered
3384
3364
  * {@link ReasonerInterface}s.
@@ -3505,8 +3485,7 @@ var Reason = class {
3505
3485
  if (this.#destroyed) throw new ReasonError("DESTROYED", "Reason has been destroyed");
3506
3486
  }
3507
3487
  };
3508
- //#endregion
3509
- //#region src/core/operators/Evaluator.ts
3488
+ // src/core/operators/Evaluator.ts
3510
3489
  /**
3511
3490
  * Evaluates {@link Check}s against subjects — the shared predicate engine of the
3512
3491
  * quantitative and logical reasoners.
@@ -3576,8 +3555,7 @@ var Evaluator = class {
3576
3555
  }
3577
3556
  }
3578
3557
  };
3579
- //#endregion
3580
- //#region src/core/operators/Transformer.ts
3558
+ // src/core/operators/Transformer.ts
3581
3559
  /**
3582
3560
  * Applies math {@link Transform}s to numbers — the quantitative reasoner's
3583
3561
  * per-factor pipeline stage.
@@ -3616,8 +3594,7 @@ var Transformer = class {
3616
3594
  return transforms.reduce((result, transform) => this.apply(result, transform), value);
3617
3595
  }
3618
3596
  };
3619
- //#endregion
3620
- //#region src/core/operators/Aggregator.ts
3597
+ // src/core/operators/Aggregator.ts
3621
3598
  /**
3622
3599
  * Reduces number lists to one number per {@link Aggregation} — the quantitative
3623
3600
  * reasoner's group and definition combiner.
@@ -3667,8 +3644,7 @@ var Aggregator = class {
3667
3644
  }
3668
3645
  }
3669
3646
  };
3670
- //#endregion
3671
- //#region src/core/reasoners/QuantitativeReasoner.ts
3647
+ // src/core/reasoners/QuantitativeReasoner.ts
3672
3648
  /**
3673
3649
  * Performs factor-based numeric scoring.
3674
3650
  *
@@ -3775,24 +3751,19 @@ var QuantitativeReasoner = class {
3775
3751
  };
3776
3752
  const trace = [];
3777
3753
  const errors = [];
3778
- let count = 0;
3779
- const groupResults = [];
3780
- for (const group of definition.groups) {
3781
- if (!isObject(group)) continue;
3754
+ const groupResults = Iterator.from(definition.groups).flatMap((group) => {
3755
+ if (!isObject(group)) return [];
3782
3756
  if (group.enabled === false) {
3783
3757
  trace.push(`Skipped group "${group.id}" (disabled)`);
3784
- continue;
3758
+ return [];
3785
3759
  }
3786
- const groupResult = this.#evaluateGroup(group, subject, trace, errors);
3787
- groupResults.push(groupResult);
3788
- if (groupResult.applied) count++;
3789
- }
3760
+ return [this.#evaluateGroup(group, subject, trace, errors)];
3761
+ }).toArray();
3790
3762
  const groupValues = groupResults.filter((group) => group.applied).map((group) => group.value);
3791
3763
  const base = definition.base ?? 0;
3792
- let value = base + this.#aggregator.aggregate(groupValues, definition.aggregation);
3793
- trace.push(`Aggregated ${groupValues.length} groups with "${definition.aggregation}": base=${base}, raw=${value}`);
3794
- value = clamp(value, definition.bounds);
3795
- value = roundTo(value, definition.precision ?? 4);
3764
+ const raw = base + this.#aggregator.aggregate(groupValues, definition.aggregation);
3765
+ trace.push(`Aggregated ${groupValues.length} groups with "${definition.aggregation}": base=${base}, raw=${raw}`);
3766
+ const value = roundTo(clamp(raw, definition.bounds), definition.precision ?? 4);
3796
3767
  if (!isFiniteNumber(value)) {
3797
3768
  const description = Number.isNaN(value) ? "NaN" : String(value);
3798
3769
  trace.push(`Definition "${definition.id}": produced non-finite value (${description})`);
@@ -3802,7 +3773,7 @@ var QuantitativeReasoner = class {
3802
3773
  reasoning: "quantitative",
3803
3774
  value,
3804
3775
  groups: groupResults,
3805
- count,
3776
+ count: groupValues.length,
3806
3777
  success: errors.length === 0,
3807
3778
  trace,
3808
3779
  errors
@@ -3818,14 +3789,13 @@ var QuantitativeReasoner = class {
3818
3789
  factors: []
3819
3790
  };
3820
3791
  }
3821
- const factorResults = [];
3822
- for (const factor of sortByPriority(group.factors)) {
3792
+ const factorResults = Iterator.from(sortByPriority(group.factors)).flatMap((factor) => {
3823
3793
  if (factor.enabled === false) {
3824
3794
  trace.push(`Skipped factor "${factor.id}" (disabled)`);
3825
- continue;
3795
+ return [];
3826
3796
  }
3827
- factorResults.push(this.#evaluateFactor(factor, subject, trace, errors));
3828
- }
3797
+ return [this.#evaluateFactor(factor, subject, trace, errors)];
3798
+ }).toArray();
3829
3799
  const appliedFactors = factorResults.filter((factor) => factor.applied);
3830
3800
  if (group.strict && appliedFactors.length !== factorResults.length) {
3831
3801
  trace.push(`Group "${group.id}" strict mode: not all factors applied`);
@@ -3843,8 +3813,7 @@ var QuantitativeReasoner = class {
3843
3813
  if (!weightById.has(original.id)) weightById.set(original.id, original.weight ?? 1);
3844
3814
  }
3845
3815
  const weights = appliedFactors.map((factor) => weightById.get(factor.id) ?? 1);
3846
- let value = (group.base ?? 0) + this.#aggregator.aggregate(factorValues, group.aggregation, weights);
3847
- value = clamp(value, group.bounds);
3816
+ const value = clamp((group.base ?? 0) + this.#aggregator.aggregate(factorValues, group.aggregation, weights), group.bounds);
3848
3817
  trace.push(`Group "${group.id}": ${appliedFactors.length}/${factorResults.length} factors applied, value=${value}`);
3849
3818
  return {
3850
3819
  id: group.id,
@@ -3888,9 +3857,7 @@ var QuantitativeReasoner = class {
3888
3857
  raw
3889
3858
  };
3890
3859
  }
3891
- let value = raw;
3892
- if (factor.transforms && factor.transforms.length > 0) value = this.#transformer.chain(value, factor.transforms);
3893
- value = clamp(value, factor.bounds);
3860
+ const value = clamp(factor.transforms && factor.transforms.length > 0 ? this.#transformer.chain(raw, factor.transforms) : raw, factor.bounds);
3894
3861
  if (!isFiniteNumber(value)) {
3895
3862
  const description = Number.isNaN(value) ? "NaN" : String(value);
3896
3863
  trace.push(`Factor "${factor.id}": produced non-finite value (${description})`);
@@ -3911,8 +3878,30 @@ var QuantitativeReasoner = class {
3911
3878
  };
3912
3879
  }
3913
3880
  };
3914
- //#endregion
3915
- //#region src/core/reasoners/LogicalReasoner.ts
3881
+ // src/core/LogicalState.ts
3882
+ /**
3883
+ * Stores the derived fields and rule results of one logical reasoning call.
3884
+ */
3885
+ var LogicalState = class {
3886
+ #fields = {};
3887
+ #rules = /* @__PURE__ */ new Map();
3888
+ get fields() {
3889
+ return this.#fields;
3890
+ }
3891
+ field(key) {
3892
+ return this.#fields[key];
3893
+ }
3894
+ set(key, value) {
3895
+ this.#fields[key] = value;
3896
+ }
3897
+ rule(id) {
3898
+ return this.#rules.get(id);
3899
+ }
3900
+ record(result) {
3901
+ this.#rules.set(result.id, result);
3902
+ }
3903
+ };
3904
+ // src/core/reasoners/LogicalReasoner.ts
3916
3905
  /**
3917
3906
  * Deduces booleans from rules with forward or backward chaining.
3918
3907
  *
@@ -4027,58 +4016,59 @@ var LogicalReasoner = class {
4027
4016
  }
4028
4017
  #forward(definition, subject, trace, errors) {
4029
4018
  const maxDepth = definition.depth ?? 10;
4030
- const derived = {};
4019
+ const state = new LogicalState();
4031
4020
  if (definition.rules.length === 0) trace.push("No rules defined");
4032
4021
  const sortedRules = sortByPriority(definition.rules);
4033
- const reportedErrors = /* @__PURE__ */ new Set();
4034
- for (const rule of sortedRules) {
4035
- if (!isObject(rule)) continue;
4036
- if (rule.enabled === false) continue;
4022
+ const reportedErrors = new Set(sortedRules.flatMap((rule) => {
4023
+ if (!isObject(rule)) return [];
4024
+ if (rule.enabled === false) return [];
4037
4025
  if (!rule.premises || rule.premises.length === 0) {
4038
4026
  errors.push(`Rule "${rule.id}" has no premises — skipped`);
4039
- reportedErrors.add(rule.id);
4027
+ return [rule.id];
4040
4028
  } else if (!rule.conclusion) {
4041
4029
  errors.push(`Rule "${rule.id}" has no conclusion — skipped`);
4042
- reportedErrors.add(rule.id);
4030
+ return [rule.id];
4043
4031
  }
4044
- }
4045
- for (let iteration = 0; iteration < maxDepth; iteration++) {
4046
- let newDerivation = false;
4032
+ return [];
4033
+ }));
4034
+ for (const iteration of iterateIndices(maxDepth)) {
4047
4035
  const currentSubject = {
4048
4036
  ...subject,
4049
- ...derived
4037
+ ...state.fields
4050
4038
  };
4051
- for (const rule of sortedRules) {
4039
+ if (!sortedRules.reduce((previous, rule) => {
4052
4040
  if (rule.enabled === false) {
4053
4041
  trace.push(`Skipped rule "${rule.id}" (disabled)`);
4054
- continue;
4042
+ return previous;
4055
4043
  }
4056
- if (reportedErrors.has(rule.id)) continue;
4044
+ if (reportedErrors.has(rule.id)) return previous;
4057
4045
  if (this.#evaluateRule(rule, currentSubject).applied) {
4058
4046
  const conclusions = extractConclusions(rule.conclusion);
4059
- for (const [key, value] of Object.entries(conclusions)) if (!equalValues(derived[key], value)) {
4060
- derived[key] = value;
4061
- newDerivation = true;
4062
- trace.push(`Rule "${rule.id}" derived: ${key}=${String(value)} (iteration ${iteration + 1})`);
4063
- }
4047
+ return Object.entries(conclusions).reduce((updated, [key, value]) => {
4048
+ if (!equalValues(state.field(key), value)) {
4049
+ state.set(key, value);
4050
+ trace.push(`Rule "${rule.id}" derived: ${key}=${String(value)} (iteration ${iteration + 1})`);
4051
+ return true;
4052
+ }
4053
+ return updated;
4054
+ }, previous);
4064
4055
  }
4065
- }
4066
- if (!newDerivation) {
4056
+ return previous;
4057
+ }, false)) {
4067
4058
  trace.push(`Forward chaining converged at iteration ${iteration + 1}`);
4068
4059
  break;
4069
4060
  }
4070
4061
  }
4071
4062
  const finalSubject = {
4072
4063
  ...subject,
4073
- ...derived
4064
+ ...state.fields
4074
4065
  };
4075
- const finalResults = [];
4076
- for (const rule of definition.rules) {
4077
- if (!isObject(rule)) continue;
4078
- if (rule.enabled === false) continue;
4079
- if (reportedErrors.has(rule.id)) continue;
4080
- finalResults.push(this.#evaluateRule(rule, finalSubject));
4081
- }
4066
+ const finalResults = Iterator.from(definition.rules).flatMap((rule) => {
4067
+ if (!isObject(rule)) return [];
4068
+ if (rule.enabled === false) return [];
4069
+ if (reportedErrors.has(rule.id)) return [];
4070
+ return [this.#evaluateRule(rule, finalSubject)];
4071
+ }).toArray();
4082
4072
  return {
4083
4073
  conclusion: finalResults.length > 0 ? finalResults[finalResults.length - 1]?.applied ?? false : false,
4084
4074
  rules: finalResults
@@ -4086,8 +4076,7 @@ var LogicalReasoner = class {
4086
4076
  }
4087
4077
  #backward(definition, subject, trace, errors) {
4088
4078
  const maxDepth = definition.depth ?? 10;
4089
- const derived = {};
4090
- const ruleResults = /* @__PURE__ */ new Map();
4079
+ const state = new LogicalState();
4091
4080
  if (definition.rules.length === 0) trace.push("No rules defined");
4092
4081
  const sortedRules = sortByPriority(definition.rules.filter((rule) => {
4093
4082
  if (!isObject(rule)) return false;
@@ -4106,52 +4095,45 @@ var LogicalReasoner = class {
4106
4095
  if (!isObject(rule)) continue;
4107
4096
  if (rule.enabled === false) trace.push(`Skipped rule "${rule.id}" (disabled)`);
4108
4097
  }
4109
- for (const rule of sortedRules) this.#proveRule(rule, 0, /* @__PURE__ */ new Set(), sortedRules, derived, subject, trace, ruleResults, maxDepth);
4110
- const finalResults = [];
4111
- for (const rule of sortedRules) {
4112
- const existing = ruleResults.get(rule.id);
4113
- if (existing) finalResults.push(existing);
4114
- else finalResults.push(this.#evaluateRule(rule, {
4115
- ...subject,
4116
- ...derived
4117
- }));
4118
- }
4098
+ for (const rule of sortedRules) this.#proveRule(rule, 0, /* @__PURE__ */ new Set(), sortedRules, state, subject, trace, maxDepth);
4099
+ const finalResults = sortedRules.map((rule) => state.rule(rule.id) ?? this.#evaluateRule(rule, {
4100
+ ...subject,
4101
+ ...state.fields
4102
+ }));
4119
4103
  return {
4120
4104
  conclusion: finalResults.length > 0 ? finalResults[finalResults.length - 1]?.applied ?? false : false,
4121
4105
  rules: finalResults
4122
4106
  };
4123
4107
  }
4124
- #proveRule(rule, depth, visited, rules, derived, subject, trace, ruleResults, maxDepth) {
4108
+ #proveRule(rule, depth, visited, rules, state, subject, trace, maxDepth) {
4125
4109
  if (depth > maxDepth) return false;
4126
4110
  if (visited.has(rule.id)) return false;
4127
- const nextVisited = new Set(visited);
4128
- nextVisited.add(rule.id);
4111
+ const nextVisited = /* @__PURE__ */ new Set([...visited, rule.id]);
4129
4112
  const currentSubject = {
4130
4113
  ...subject,
4131
- ...derived
4114
+ ...state.fields
4132
4115
  };
4133
- const premiseResults = [];
4134
- for (const premise of rule.premises) premiseResults.push(this.#establish(premise, currentSubject, rules, depth + 1, nextVisited, derived, subject, trace, ruleResults, maxDepth));
4116
+ const premiseResults = Iterator.from(rule.premises).map((premise) => this.#establish(premise, currentSubject, rules, depth + 1, nextVisited, state, subject, trace, maxDepth)).toArray();
4135
4117
  const allMet = premiseResults.every(Boolean);
4136
- ruleResults.set(rule.id, {
4118
+ state.record({
4137
4119
  id: rule.id,
4138
4120
  applied: allMet,
4139
4121
  premises: premiseResults
4140
4122
  });
4141
4123
  if (allMet) {
4142
4124
  const conclusions = extractConclusions(rule.conclusion);
4143
- for (const [key, value] of Object.entries(conclusions)) if (!equalValues(derived[key], value)) {
4144
- derived[key] = value;
4125
+ for (const [key, value] of Object.entries(conclusions)) if (!equalValues(state.field(key), value)) {
4126
+ state.set(key, value);
4145
4127
  trace.push(`Rule "${rule.id}" derived: ${key}=${String(value)} (backward, depth ${depth})`);
4146
4128
  }
4147
4129
  } else trace.push(`Rule "${rule.id}": does not hold (backward, depth ${depth})`);
4148
4130
  return allMet;
4149
4131
  }
4150
- #establish(expression, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth) {
4132
+ #establish(expression, currentSubject, rules, depth, visited, state, subject, trace, maxDepth) {
4151
4133
  if (this.#evaluateExpression(expression, currentSubject)) return true;
4152
- return this.#proveExpression(expression, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth);
4134
+ return this.#proveExpression(expression, rules, depth, visited, state, subject, trace, maxDepth);
4153
4135
  }
4154
- #proveExpression(expression, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth) {
4136
+ #proveExpression(expression, rules, depth, visited, state, subject, trace, maxDepth) {
4155
4137
  if (depth > maxDepth) return false;
4156
4138
  if (expression.form === "atom") for (const rule of rules) {
4157
4139
  if (!isObject(rule)) continue;
@@ -4160,30 +4142,25 @@ var LogicalReasoner = class {
4160
4142
  const field = formatField(expression.check.field);
4161
4143
  const value = expression.check.value;
4162
4144
  if (field in conclusionFacts && conclusionFacts[field] === value) {
4163
- const nextVisited = new Set(visited);
4164
- nextVisited.add(rule.id);
4145
+ const nextVisited = /* @__PURE__ */ new Set([...visited, rule.id]);
4165
4146
  const currentSubject = {
4166
4147
  ...subject,
4167
- ...derived
4148
+ ...state.fields
4168
4149
  };
4169
4150
  const premiseResults = [];
4170
- let allMet = true;
4171
- for (const premise of rule.premises) {
4172
- const met = this.#establish(premise, currentSubject, rules, depth + 1, nextVisited, derived, subject, trace, ruleResults, maxDepth);
4151
+ const allMet = Iterator.from(rule.premises).every((premise) => {
4152
+ const met = this.#establish(premise, currentSubject, rules, depth + 1, nextVisited, state, subject, trace, maxDepth);
4173
4153
  premiseResults.push(met);
4174
- if (!met) {
4175
- allMet = false;
4176
- break;
4177
- }
4178
- }
4179
- ruleResults.set(rule.id, {
4154
+ return met;
4155
+ });
4156
+ state.record({
4180
4157
  id: rule.id,
4181
4158
  applied: allMet,
4182
4159
  premises: premiseResults
4183
4160
  });
4184
4161
  if (allMet) {
4185
- for (const [key, entry] of Object.entries(conclusionFacts)) if (!equalValues(derived[key], entry)) {
4186
- derived[key] = entry;
4162
+ for (const [key, entry] of Object.entries(conclusionFacts)) if (!equalValues(state.field(key), entry)) {
4163
+ state.set(key, entry);
4187
4164
  trace.push(`Rule "${rule.id}" derived: ${key}=${String(entry)} (backward, depth ${depth})`);
4188
4165
  }
4189
4166
  return true;
@@ -4193,31 +4170,31 @@ var LogicalReasoner = class {
4193
4170
  if (expression.form === "compound") {
4194
4171
  const currentSubject = {
4195
4172
  ...subject,
4196
- ...derived
4173
+ ...state.fields
4197
4174
  };
4198
4175
  switch (expression.operator) {
4199
- case "and": return expression.operands.every((operand) => this.#establish(operand, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth));
4200
- case "or": return expression.operands.some((operand) => this.#establish(operand, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth));
4176
+ case "and": return expression.operands.every((operand) => this.#establish(operand, currentSubject, rules, depth, visited, state, subject, trace, maxDepth));
4177
+ case "or": return expression.operands.some((operand) => this.#establish(operand, currentSubject, rules, depth, visited, state, subject, trace, maxDepth));
4201
4178
  case "not": {
4202
4179
  if (expression.operands.length === 0) return true;
4203
4180
  const first = expression.operands[0];
4204
4181
  if (!first) return true;
4205
- return !this.#establish(first, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth);
4182
+ return !this.#establish(first, currentSubject, rules, depth, visited, state, subject, trace, maxDepth);
4206
4183
  }
4207
4184
  case "implies": {
4208
4185
  if (expression.operands.length < 2) return true;
4209
4186
  const antecedent = expression.operands[0];
4210
4187
  const consequent = expression.operands[1];
4211
4188
  if (!antecedent || !consequent) return true;
4212
- if (!this.#establish(antecedent, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth)) return true;
4213
- return this.#establish(consequent, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth);
4189
+ if (!this.#establish(antecedent, currentSubject, rules, depth, visited, state, subject, trace, maxDepth)) return true;
4190
+ return this.#establish(consequent, currentSubject, rules, depth, visited, state, subject, trace, maxDepth);
4214
4191
  }
4215
4192
  case "xor": {
4216
4193
  if (expression.operands.length < 2) return false;
4217
4194
  const left = expression.operands[0];
4218
4195
  const right = expression.operands[1];
4219
4196
  if (!left || !right) return false;
4220
- return this.#establish(left, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth) !== this.#establish(right, currentSubject, rules, depth, visited, derived, subject, trace, ruleResults, maxDepth);
4197
+ return this.#establish(left, currentSubject, rules, depth, visited, state, subject, trace, maxDepth) !== this.#establish(right, currentSubject, rules, depth, visited, state, subject, trace, maxDepth);
4221
4198
  }
4222
4199
  default: return false;
4223
4200
  }
@@ -4255,8 +4232,23 @@ var LogicalReasoner = class {
4255
4232
  }
4256
4233
  }
4257
4234
  };
4258
- //#endregion
4259
- //#region src/core/reasoners/SymbolicReasoner.ts
4235
+ // src/core/SymbolicState.ts
4236
+ /**
4237
+ * Stores numeric bindings for one symbolic reasoning call.
4238
+ */
4239
+ var SymbolicState = class {
4240
+ #values;
4241
+ constructor(values) {
4242
+ this.#values = { ...values };
4243
+ }
4244
+ get values() {
4245
+ return this.#values;
4246
+ }
4247
+ set(name, value) {
4248
+ this.#values[name] = value;
4249
+ }
4250
+ };
4251
+ // src/core/reasoners/SymbolicReasoner.ts
4260
4252
  /**
4261
4253
  * Solves algebraic equations by variable isolation.
4262
4254
  *
@@ -4350,17 +4342,17 @@ var SymbolicReasoner = class {
4350
4342
  const trace = [];
4351
4343
  const errors = [];
4352
4344
  const precision = definition.precision ?? 4;
4353
- const bindings = { ...definition.variables };
4354
- let bound = 0;
4355
- for (const key of Object.keys(subject)) {
4356
- if (key === "id") continue;
4345
+ const state = new SymbolicState(definition.variables);
4346
+ const bound = Object.keys(subject).reduce((count, key) => {
4347
+ if (key === "id") return count;
4357
4348
  const value = parseNumber(subject[key]);
4358
4349
  if (value !== void 0) {
4359
- bindings[key] = value;
4350
+ state.set(key, value);
4360
4351
  trace.push(`Subject field "${key}" bound as ${key} = ${value}`);
4361
- bound++;
4352
+ return count + 1;
4362
4353
  }
4363
- }
4354
+ return count;
4355
+ }, 0);
4364
4356
  if (bound > 0) trace.push(`Bound ${bound} variable(s) from subject`);
4365
4357
  if (definition.equations.length === 0) {
4366
4358
  trace.push("No equations to solve");
@@ -4375,7 +4367,7 @@ var SymbolicReasoner = class {
4375
4367
  for (const equation of definition.equations) {
4376
4368
  if (!isObject(equation)) continue;
4377
4369
  try {
4378
- const value = this.#solve(equation, bindings);
4370
+ const value = this.#solve(equation, state.values);
4379
4371
  const rounded = roundTo(value, precision);
4380
4372
  if (!isFiniteNumber(value) || !isFiniteNumber(rounded)) {
4381
4373
  const offender = isFiniteNumber(value) ? rounded : value;
@@ -4384,7 +4376,7 @@ var SymbolicReasoner = class {
4384
4376
  trace.push(`Equation "${equation.id}": FAILED — produced non-finite value (${description})`);
4385
4377
  continue;
4386
4378
  }
4387
- bindings[equation.target] = rounded;
4379
+ state.set(equation.target, rounded);
4388
4380
  trace.push(`Equation "${equation.id}": ${equation.target} = ${rounded}`);
4389
4381
  } catch (error) {
4390
4382
  const message = isError(error) ? error.message : String(error);
@@ -4392,15 +4384,15 @@ var SymbolicReasoner = class {
4392
4384
  trace.push(`Equation "${equation.id}": FAILED — ${message}`);
4393
4385
  }
4394
4386
  }
4395
- const solutions = {};
4387
+ const solutions = new SymbolicState();
4396
4388
  for (const equation of definition.equations) {
4397
4389
  if (!isObject(equation)) continue;
4398
- const value = bindings[equation.target];
4399
- if (value !== void 0) solutions[equation.target] = value;
4390
+ const value = state.values[equation.target];
4391
+ if (value !== void 0) solutions.set(equation.target, value);
4400
4392
  }
4401
4393
  return {
4402
4394
  reasoning: "symbolic",
4403
- solutions,
4395
+ solutions: solutions.values,
4404
4396
  success: errors.length === 0,
4405
4397
  trace,
4406
4398
  errors
@@ -4458,8 +4450,37 @@ var SymbolicReasoner = class {
4458
4450
  }
4459
4451
  }
4460
4452
  };
4461
- //#endregion
4462
- //#region src/core/reasoners/InferentialReasoner.ts
4453
+ // src/core/InferenceJoin.ts
4454
+ /**
4455
+ * Joins premise bindings against a predicate-and-arity fact index.
4456
+ */
4457
+ var InferenceJoin = class {
4458
+ #index;
4459
+ #bindings = [{}];
4460
+ constructor(index) {
4461
+ this.#index = index;
4462
+ }
4463
+ resolve(premises) {
4464
+ this.#bindings = [{}];
4465
+ if (premises.length === 0) return this.#bindings;
4466
+ for (const premise of premises) {
4467
+ const candidates = this.#index.get(factToArityKey(premise)) ?? [];
4468
+ this.#bindings = this.#bindings.flatMap((existing) => {
4469
+ const instantiated = instantiateFact(premise, existing);
4470
+ return Iterator.from(candidates).flatMap((fact) => {
4471
+ const match = matchFacts(instantiated, fact);
4472
+ return match ? [{
4473
+ ...existing,
4474
+ ...match
4475
+ }] : [];
4476
+ }).toArray();
4477
+ });
4478
+ if (this.#bindings.length === 0) break;
4479
+ }
4480
+ return this.#bindings;
4481
+ }
4482
+ };
4483
+ // src/core/reasoners/InferentialReasoner.ts
4463
4484
  /**
4464
4485
  * Derives facts with unification variables and proof trees.
4465
4486
  *
@@ -4614,35 +4635,31 @@ var InferentialReasoner = class {
4614
4635
  }
4615
4636
  validInferences.push(inference);
4616
4637
  }
4617
- for (let iteration = 0; iteration < maxDepth; iteration++) {
4618
- let newDerivation = false;
4619
- for (const inference of validInferences) {
4620
- const allBindings = this.#findAllBindings(inference.premises, byArity);
4621
- for (const bindings of allBindings) {
4622
- const conclusion = instantiateFact(inference.conclusion, bindings);
4623
- const finalConfidence = computePremiseConfidence(inference.premises, byArity, bindings) * (inference.confidence ?? 1);
4624
- const derivedFact = {
4625
- ...conclusion,
4626
- confidence: roundTo(finalConfidence, 4)
4627
- };
4628
- const key = factToKey(derivedFact, identities);
4629
- if (!seen.has(key)) {
4630
- knownFacts.push(derivedFact);
4631
- const arityKey = factToArityKey(derivedFact);
4632
- const bucket = byArity.get(arityKey);
4633
- if (bucket) bucket.push(derivedFact);
4634
- else byArity.set(arityKey, [derivedFact]);
4635
- seen.add(key);
4636
- derived.push(derivedFact);
4637
- newDerivation = true;
4638
- trace.push(`Derived ${derivedFact.predicate}(${derivedFact.terms.join(", ")}) through "${inference.id}" [confidence: ${derivedFact.confidence}] (iteration ${iteration + 1})`);
4639
- }
4638
+ for (const iteration of iterateIndices(maxDepth)) if (!validInferences.reduce((previous, inference) => {
4639
+ return new InferenceJoin(byArity).resolve(inference.premises).reduce((updated, bindings) => {
4640
+ const conclusion = instantiateFact(inference.conclusion, bindings);
4641
+ const finalConfidence = computePremiseConfidence(inference.premises, byArity, bindings) * (inference.confidence ?? 1);
4642
+ const derivedFact = {
4643
+ ...conclusion,
4644
+ confidence: roundTo(finalConfidence, 4)
4645
+ };
4646
+ const key = factToKey(derivedFact, identities);
4647
+ if (!seen.has(key)) {
4648
+ knownFacts.push(derivedFact);
4649
+ const arityKey = factToArityKey(derivedFact);
4650
+ const bucket = byArity.get(arityKey);
4651
+ if (bucket) bucket.push(derivedFact);
4652
+ else byArity.set(arityKey, [derivedFact]);
4653
+ seen.add(key);
4654
+ derived.push(derivedFact);
4655
+ trace.push(`Derived ${derivedFact.predicate}(${derivedFact.terms.join(", ")}) through "${inference.id}" [confidence: ${derivedFact.confidence}] (iteration ${iteration + 1})`);
4656
+ return true;
4640
4657
  }
4641
- }
4642
- if (!newDerivation) {
4643
- trace.push(`Forward chaining converged at iteration ${iteration + 1}`);
4644
- break;
4645
- }
4658
+ return updated;
4659
+ }, previous);
4660
+ }, false)) {
4661
+ trace.push(`Forward chaining converged at iteration ${iteration + 1}`);
4662
+ break;
4646
4663
  }
4647
4664
  return { derived };
4648
4665
  }
@@ -4695,17 +4712,15 @@ var InferentialReasoner = class {
4695
4712
  const conclusionBindings = matchFacts(goal, inference.conclusion);
4696
4713
  if (!conclusionBindings) continue;
4697
4714
  const children = [];
4698
- let allProved = true;
4699
- for (const premise of inference.premises) {
4715
+ if (Iterator.from(inference.premises).every((premise) => {
4700
4716
  const instantiated = instantiateFact(premise, conclusionBindings);
4701
4717
  const child = this.#prove(instantiated, inferences, baseFacts, depth + 1, maxDepth);
4702
- if (child) children.push(child);
4703
- else {
4704
- allProved = false;
4705
- break;
4718
+ if (child) {
4719
+ children.push(child);
4720
+ return true;
4706
4721
  }
4707
- }
4708
- if (allProved) return {
4722
+ return false;
4723
+ })) return {
4709
4724
  fact: goal.id,
4710
4725
  inference: inference.id,
4711
4726
  children,
@@ -4713,30 +4728,8 @@ var InferentialReasoner = class {
4713
4728
  };
4714
4729
  }
4715
4730
  }
4716
- #findAllBindings(premises, byArity) {
4717
- if (premises.length === 0) return [{}];
4718
- let currentBindings = [{}];
4719
- for (const premise of premises) {
4720
- const nextBindings = [];
4721
- const candidates = byArity.get(factToArityKey(premise)) ?? [];
4722
- for (const existing of currentBindings) {
4723
- const instantiated = instantiateFact(premise, existing);
4724
- for (const fact of candidates) {
4725
- const match = matchFacts(instantiated, fact);
4726
- if (match) nextBindings.push({
4727
- ...existing,
4728
- ...match
4729
- });
4730
- }
4731
- }
4732
- currentBindings = nextBindings;
4733
- if (currentBindings.length === 0) break;
4734
- }
4735
- return currentBindings;
4736
- }
4737
4731
  };
4738
- //#endregion
4739
- //#region src/core/builders/managers/Collection.ts
4732
+ // src/core/builders/managers/Collection.ts
4740
4733
  /**
4741
4734
  * Holds the id-keyed collection state the `DefinitionBuilder`'s list managers
4742
4735
  * share — the array, the placement verbs, the silent re-seat, and the
@@ -4802,8 +4795,7 @@ var Collection = class {
4802
4795
  if (this.#destroyed) throw new ReasonError("DESTROYED", `${this.#owner} has been destroyed`);
4803
4796
  }
4804
4797
  };
4805
- //#endregion
4806
- //#region src/core/builders/managers/EquationManager.ts
4798
+ // src/core/builders/managers/EquationManager.ts
4807
4799
  /**
4808
4800
  * Implements the {@link EquationManagerInterface} — a self-owning,
4809
4801
  * kind-free manager over a symbolic definition's `equations`.
@@ -4874,11 +4866,7 @@ var EquationManager = class {
4874
4866
  for (const equation of this.#equations.items()) this.#removeOne(equation.id);
4875
4867
  return;
4876
4868
  }
4877
- if (isArray(idOrIds)) {
4878
- let all = true;
4879
- for (const id of idOrIds) if (!this.#removeOne(id)) all = false;
4880
- return all;
4881
- }
4869
+ if (isArray(idOrIds)) return Iterator.from(idOrIds).reduce((all, id) => this.#removeOne(id) && all, true);
4882
4870
  return this.#removeOne(idOrIds);
4883
4871
  }
4884
4872
  seat(equations) {
@@ -4895,8 +4883,7 @@ var EquationManager = class {
4895
4883
  return true;
4896
4884
  }
4897
4885
  };
4898
- //#endregion
4899
- //#region src/core/builders/managers/FactManager.ts
4886
+ // src/core/builders/managers/FactManager.ts
4900
4887
  /**
4901
4888
  * Implements the {@link FactManagerInterface} — a self-owning, kind-free
4902
4889
  * manager over an inferential definition's `facts`.
@@ -4962,11 +4949,7 @@ var FactManager = class {
4962
4949
  for (const fact of this.#facts.items()) this.#removeOne(fact.id);
4963
4950
  return;
4964
4951
  }
4965
- if (isArray(idOrIds)) {
4966
- let all = true;
4967
- for (const id of idOrIds) if (!this.#removeOne(id)) all = false;
4968
- return all;
4969
- }
4952
+ if (isArray(idOrIds)) return Iterator.from(idOrIds).reduce((all, id) => this.#removeOne(id) && all, true);
4970
4953
  return this.#removeOne(idOrIds);
4971
4954
  }
4972
4955
  seat(facts) {
@@ -4983,8 +4966,7 @@ var FactManager = class {
4983
4966
  return true;
4984
4967
  }
4985
4968
  };
4986
- //#endregion
4987
- //#region src/core/builders/managers/FactorManager.ts
4969
+ // src/core/builders/managers/FactorManager.ts
4988
4970
  /**
4989
4971
  * Implements the {@link FactorManagerInterface} — the one divergent
4990
4972
  * manager: factors nest inside groups, so it holds no collection state of its
@@ -5068,11 +5050,7 @@ var FactorManager = class {
5068
5050
  for (const factor of this.#locate(groupId).factors) this.#removeOne(groupId, factor.id);
5069
5051
  return;
5070
5052
  }
5071
- if (isArray(idOrIds)) {
5072
- let all = true;
5073
- for (const id of idOrIds) if (!this.#removeOne(groupId, id)) all = false;
5074
- return all;
5075
- }
5053
+ if (isArray(idOrIds)) return Iterator.from(idOrIds).reduce((all, id) => this.#removeOne(groupId, id) && all, true);
5076
5054
  return this.#removeOne(groupId, idOrIds);
5077
5055
  }
5078
5056
  destroy() {
@@ -5096,8 +5074,7 @@ var FactorManager = class {
5096
5074
  return group;
5097
5075
  }
5098
5076
  };
5099
- //#endregion
5100
- //#region src/core/builders/managers/GroupManager.ts
5077
+ // src/core/builders/managers/GroupManager.ts
5101
5078
  /**
5102
5079
  * Implements the {@link GroupManagerInterface} — a self-owning, kind-free
5103
5080
  * manager over a quantitative definition's `groups`.
@@ -5163,11 +5140,7 @@ var GroupManager = class {
5163
5140
  for (const group of this.#groups.items()) this.#removeOne(group.id);
5164
5141
  return;
5165
5142
  }
5166
- if (isArray(idOrIds)) {
5167
- let all = true;
5168
- for (const id of idOrIds) if (!this.#removeOne(id)) all = false;
5169
- return all;
5170
- }
5143
+ if (isArray(idOrIds)) return Iterator.from(idOrIds).reduce((all, id) => this.#removeOne(id) && all, true);
5171
5144
  return this.#removeOne(idOrIds);
5172
5145
  }
5173
5146
  seat(groups) {
@@ -5184,8 +5157,7 @@ var GroupManager = class {
5184
5157
  return true;
5185
5158
  }
5186
5159
  };
5187
- //#endregion
5188
- //#region src/core/builders/managers/InferenceManager.ts
5160
+ // src/core/builders/managers/InferenceManager.ts
5189
5161
  /**
5190
5162
  * Implements the {@link InferenceManagerInterface} — a self-owning,
5191
5163
  * kind-free manager over an inferential definition's `inferences`.
@@ -5261,11 +5233,7 @@ var InferenceManager = class {
5261
5233
  for (const inference of this.#inferences.items()) this.#removeOne(inference.id);
5262
5234
  return;
5263
5235
  }
5264
- if (isArray(idOrIds)) {
5265
- let all = true;
5266
- for (const id of idOrIds) if (!this.#removeOne(id)) all = false;
5267
- return all;
5268
- }
5236
+ if (isArray(idOrIds)) return Iterator.from(idOrIds).reduce((all, id) => this.#removeOne(id) && all, true);
5269
5237
  return this.#removeOne(idOrIds);
5270
5238
  }
5271
5239
  seat(inferences) {
@@ -5282,8 +5250,7 @@ var InferenceManager = class {
5282
5250
  return true;
5283
5251
  }
5284
5252
  };
5285
- //#endregion
5286
- //#region src/core/builders/managers/RuleManager.ts
5253
+ // src/core/builders/managers/RuleManager.ts
5287
5254
  /**
5288
5255
  * Implements the {@link RuleManagerInterface} — a self-owning, kind-free
5289
5256
  * manager over a logical definition's `rules`.
@@ -5352,11 +5319,7 @@ var RuleManager = class {
5352
5319
  for (const rule of this.#rules.items()) this.#removeOne(rule.id);
5353
5320
  return;
5354
5321
  }
5355
- if (isArray(idOrIds)) {
5356
- let all = true;
5357
- for (const id of idOrIds) if (!this.#removeOne(id)) all = false;
5358
- return all;
5359
- }
5322
+ if (isArray(idOrIds)) return Iterator.from(idOrIds).reduce((all, id) => this.#removeOne(id) && all, true);
5360
5323
  return this.#removeOne(idOrIds);
5361
5324
  }
5362
5325
  seat(rules) {
@@ -5373,8 +5336,7 @@ var RuleManager = class {
5373
5336
  return true;
5374
5337
  }
5375
5338
  };
5376
- //#endregion
5377
- //#region src/core/builders/managers/VariableManager.ts
5339
+ // src/core/builders/managers/VariableManager.ts
5378
5340
  /**
5379
5341
  * Implements the {@link VariableManagerInterface} — a self-owning,
5380
5342
  * kind-free manager over a symbolic definition's `variables`, a name-keyed
@@ -5441,11 +5403,7 @@ var VariableManager = class {
5441
5403
  for (const name of Object.keys(this.#variables)) this.#removeOne(name);
5442
5404
  return;
5443
5405
  }
5444
- if (isArray(nameOrNames)) {
5445
- let all = true;
5446
- for (const name of nameOrNames) if (!this.#removeOne(name)) all = false;
5447
- return all;
5448
- }
5406
+ if (isArray(nameOrNames)) return Iterator.from(nameOrNames).reduce((all, name) => this.#removeOne(name) && all, true);
5449
5407
  return this.#removeOne(nameOrNames);
5450
5408
  }
5451
5409
  seat(variables) {
@@ -5468,8 +5426,7 @@ var VariableManager = class {
5468
5426
  return true;
5469
5427
  }
5470
5428
  };
5471
- //#endregion
5472
- //#region src/core/builders/DefinitionBuilder.ts
5429
+ // src/core/builders/DefinitionBuilder.ts
5473
5430
  /**
5474
5431
  * Implements a stateful workspace builder accumulating a {@link Definition}
5475
5432
  * through always-present self-owning manager properties: a private scalar
@@ -5581,28 +5538,13 @@ var DefinitionBuilder = class {
5581
5538
  definition: this.#id,
5582
5539
  reasoning: current.reasoning
5583
5540
  });
5584
- let merged;
5585
- if (current.reasoning === "quantitative" && incoming.reasoning === "quantitative") merged = mergeQuantitativeDefinition(current, incoming);
5586
- else if (current.reasoning === "logical" && incoming.reasoning === "logical") merged = mergeLogicalDefinition(current, incoming);
5587
- else if (current.reasoning === "symbolic" && incoming.reasoning === "symbolic") merged = mergeSymbolicDefinition(current, incoming);
5588
- else if (current.reasoning === "inferential" && incoming.reasoning === "inferential") merged = mergeInferentialDefinition(current, incoming);
5589
- else merged = current;
5541
+ const merged = current.reasoning === "quantitative" && incoming.reasoning === "quantitative" ? mergeQuantitativeDefinition(current, incoming) : current.reasoning === "logical" && incoming.reasoning === "logical" ? mergeLogicalDefinition(current, incoming) : current.reasoning === "symbolic" && incoming.reasoning === "symbolic" ? mergeSymbolicDefinition(current, incoming) : current.reasoning === "inferential" && incoming.reasoning === "inferential" ? mergeInferentialDefinition(current, incoming) : current;
5590
5542
  this.#seat(merged);
5591
5543
  this.#emitter.emit("merge", merged.reasoning);
5592
5544
  }
5593
5545
  clear(key) {
5594
5546
  this.#ensureAlive();
5595
- const current = this.#compose();
5596
- let next;
5597
- if (current.reasoning === "quantitative" && isQuantitativeClearKey(key)) next = clearQuantitativeDefinition(current, key);
5598
- else if (current.reasoning === "logical" && isLogicalClearKey(key)) next = clearLogicalDefinition(current, key);
5599
- else if (current.reasoning === "symbolic" && isSymbolicClearKey(key)) next = clearSymbolicDefinition(current, key);
5600
- else if (current.reasoning === "inferential" && isInferentialClearKey(key)) next = clearInferentialDefinition(current, key);
5601
- else throw new ReasonError("MISMATCH", `"${key}" is not a clearable field for reasoning "${current.reasoning}"`, {
5602
- key,
5603
- reasoning: current.reasoning
5604
- });
5605
- this.#envelope = definitionToEnvelope(next);
5547
+ this.#envelope = definitionToEnvelope(this.#clear(key));
5606
5548
  this.#emitter.emit("clear", key);
5607
5549
  }
5608
5550
  destroy() {
@@ -5617,6 +5559,17 @@ var DefinitionBuilder = class {
5617
5559
  this.#emitter.emit("destroy");
5618
5560
  this.#emitter.destroy();
5619
5561
  }
5562
+ #clear(key) {
5563
+ const current = this.#compose();
5564
+ if (current.reasoning === "quantitative" && isQuantitativeClearKey(key)) return clearQuantitativeDefinition(current, key);
5565
+ else if (current.reasoning === "logical" && isLogicalClearKey(key)) return clearLogicalDefinition(current, key);
5566
+ else if (current.reasoning === "symbolic" && isSymbolicClearKey(key)) return clearSymbolicDefinition(current, key);
5567
+ else if (current.reasoning === "inferential" && isInferentialClearKey(key)) return clearInferentialDefinition(current, key);
5568
+ else throw new ReasonError("MISMATCH", `"${key}" is not a clearable field for reasoning "${current.reasoning}"`, {
5569
+ key,
5570
+ reasoning: current.reasoning
5571
+ });
5572
+ }
5620
5573
  #compose() {
5621
5574
  const envelope = this.#envelope;
5622
5575
  switch (envelope.reasoning) {
@@ -5662,8 +5615,7 @@ var DefinitionBuilder = class {
5662
5615
  if (this.#destroyed) throw new ReasonError("DESTROYED", "DefinitionBuilder has been destroyed");
5663
5616
  }
5664
5617
  };
5665
- //#endregion
5666
- //#region src/core/builders/SubjectBuilder.ts
5618
+ // src/core/builders/SubjectBuilder.ts
5667
5619
  /**
5668
5620
  * Implements a stateful workspace builder accumulating a {@link Subject} — one
5669
5621
  * flat key-value collection, no managers.
@@ -5751,11 +5703,7 @@ var SubjectBuilder = class {
5751
5703
  for (const key of Object.keys(this.#subject)) if (key !== "id") this.#removeOne(key);
5752
5704
  return;
5753
5705
  }
5754
- if (isArray(keyOrKeys)) {
5755
- let all = true;
5756
- for (const key of keyOrKeys) if (!this.#removeOne(key)) all = false;
5757
- return all;
5758
- }
5706
+ if (isArray(keyOrKeys)) return Iterator.from(keyOrKeys).reduce((all, key) => this.#removeOne(key) && all, true);
5759
5707
  return this.#removeOne(keyOrKeys);
5760
5708
  }
5761
5709
  merge(incoming) {
@@ -5799,8 +5747,7 @@ var SubjectBuilder = class {
5799
5747
  return existed;
5800
5748
  }
5801
5749
  };
5802
- //#endregion
5803
- //#region src/core/factories.ts
5750
+ // src/core/factories.ts
5804
5751
  /**
5805
5752
  * Creates a check evaluator.
5806
5753
  *
@@ -6872,7 +6819,6 @@ function createInferentialDefinition(id, name, facts, inferences, overrides) {
6872
6819
  ...overrides
6873
6820
  };
6874
6821
  }
6875
- //#endregion
6876
- export { AGGREGATOR_ID, Aggregator, CONFIDENCE_PRECISION, DEFAULT_BASE, DEFAULT_CONFIDENCE, DEFAULT_DEPTH, DEFAULT_PRECISION, DEFAULT_PRIORITY, DEFAULT_REASON_BAIL, DEFAULT_VALIDATE, DEFAULT_WEIGHT, DEFINITION_BUILDER_BRAND, DefinitionBuilder, EVALUATOR_ID, EquationManager, Evaluator, FactManager, FactorManager, GroupManager, INFERENTIAL_ID, INVERTIBLE_OPERATIONS, InferenceManager, InferentialReasoner, LOGICAL_ID, LogicalReasoner, QUANTITATIVE_ID, QuantitativeReasoner, Reason, ReasonError, RuleManager, SUBJECT_BUILDER_BRAND, SYMBOLIC_ID, SubjectBuilder, SymbolicReasoner, TRANSFORMER_ID, Transformer, VariableManager, addVariable, appendById, appendEquation, appendFact, appendFactor, appendGroup, appendInference, appendRule, applyOperation, assignField, buildErrorResult, clamp, clearInferentialDefinition, clearLogicalDefinition, clearQuantitativeDefinition, clearSymbolicDefinition, computePremiseConfidence, containsVariable, createAggregator, createAtom, createBounds, createCheck, createCompound, createConstant, createDefinitionBuilder, createEquation, createEquationManager, createEvaluator, createFact, createFactManager, createFactorGroup, createFactorManager, createFieldFactor, createFieldSource, createGroupManager, createInference, createInferenceManager, createInferentialDefinition, createInferentialReasoner, createLogicalDefinition, createLogicalReasoner, createLookupFactor, createLookupSource, createOperation, createQuantitativeDefinition, createQuantitativeReasoner, createRangeFactor, createRangeSource, createReason, createRule, createRuleManager, createStaticFactor, createStaticSource, createSubjectBuilder, createSymbolicDefinition, createSymbolicReasoner, createTransform, createTransformer, createVariable, createVariableManager, definitionToEnvelope, emptyAggregate, equalValues, extractAtoms, extractConclusions, factToArityKey, factToKey, findDuplicates, findOverlayMismatches, findUnboundVariables, formatField, indexByArity, instantiateFact, invertLeft, invertRight, isAggregation, isBounds, isChainingStrategy, isCheck, isCheckResult, isComparison, isDefinition, isDefinitionBuilder, isEquation, isExpression, isFact, isFactor, isFactorGroup, isFactorRange, isFactorResult, isFieldPath, isGroupResult, isInference, isInferentialClearKey, isInferentialDefinition, isInferentialResult, isLogicalClearKey, isLogicalDefinition, isLogicalOperator, isLogicalResult, isMathOperation, isNumberRecord, isProofNode, isQuantitativeClearKey, isQuantitativeDefinition, isQuantitativeResult, isReasonError, isReasonResult, isReasonValidationResult, isReasoning, isResultFact, isRule, isRuleResult, isSource, isSubjectBuilder, isSymbolicClearKey, isSymbolicDefinition, isSymbolicExpression, isSymbolicResult, isTransform, matchFacts, matchesBounds, mergeById, mergeInferentialDefinition, mergeLogicalDefinition, mergeQuantitativeDefinition, mergeSubjects, mergeSymbolicDefinition, parseDefinition, prependById, prependEquation, prependFact, prependFactor, prependGroup, prependInference, prependRule, removeById, removeEquation, removeFact, removeFactor, removeField, removeGroup, removeInference, removeRule, removeVariable, repeatSubject, replaceById, replaceEquation, replaceFact, replaceFactor, replaceGroup, replaceInference, replaceRule, resolveOperand, resolveSource, roundTo, sortByPriority, subjectToFacts, termToKey };
6822
+ export { AGGREGATOR_ID, Aggregator, CONFIDENCE_PRECISION, DEFAULT_BASE, DEFAULT_CONFIDENCE, DEFAULT_DEPTH, DEFAULT_PRECISION, DEFAULT_PRIORITY, DEFAULT_REASON_BAIL, DEFAULT_VALIDATE, DEFAULT_WEIGHT, DEFINITION_BUILDER_BRAND, DefinitionBuilder, EVALUATOR_ID, EquationManager, Evaluator, FactManager, FactorManager, GroupManager, INFERENTIAL_ID, INVERTIBLE_OPERATIONS, InferenceManager, InferentialReasoner, LOGICAL_ID, LogicalReasoner, QUANTITATIVE_ID, QuantitativeReasoner, Reason, ReasonError, RuleManager, SUBJECT_BUILDER_BRAND, SYMBOLIC_ID, SubjectBuilder, SymbolicReasoner, TRANSFORMER_ID, Transformer, VariableManager, addVariable, appendById, appendEquation, appendFact, appendFactor, appendGroup, appendInference, appendRule, applyOperation, assignField, buildErrorResult, clamp, clearInferentialDefinition, clearLogicalDefinition, clearQuantitativeDefinition, clearSymbolicDefinition, computePremiseConfidence, containsVariable, createAggregator, createAtom, createBounds, createCheck, createCompound, createConstant, createDefinitionBuilder, createEquation, createEquationManager, createEvaluator, createFact, createFactManager, createFactorGroup, createFactorManager, createFieldFactor, createFieldSource, createGroupManager, createInference, createInferenceManager, createInferentialDefinition, createInferentialReasoner, createLogicalDefinition, createLogicalReasoner, createLookupFactor, createLookupSource, createOperation, createQuantitativeDefinition, createQuantitativeReasoner, createRangeFactor, createRangeSource, createReason, createRule, createRuleManager, createStaticFactor, createStaticSource, createSubjectBuilder, createSymbolicDefinition, createSymbolicReasoner, createTransform, createTransformer, createVariable, createVariableManager, definitionToEnvelope, emptyAggregate, equalValues, extractAtoms, extractConclusions, factToArityKey, factToKey, findDuplicates, findOverlayMismatches, findUnboundVariables, formatField, indexByArity, instantiateFact, invertLeft, invertRight, isAggregation, isBounds, isChainStrategy, isCheck, isCheckResult, isComparison, isDefinition, isDefinitionBuilder, isEquation, isExpression, isFact, isFactor, isFactorGroup, isFactorRange, isFactorResult, isFieldPath, isGroupResult, isInference, isInferentialClearKey, isInferentialDefinition, isInferentialResult, isLogicalClearKey, isLogicalDefinition, isLogicalOperator, isLogicalResult, isMathOperation, isNumberRecord, isProofNode, isQuantitativeClearKey, isQuantitativeDefinition, isQuantitativeResult, isReasonError, isReasonResult, isReasonValidationResult, isReasoning, isResultFact, isRule, isRuleResult, isSource, isSubjectBuilder, isSymbolicClearKey, isSymbolicDefinition, isSymbolicExpression, isSymbolicResult, isTransform, iterateIndices, matchFacts, matchesBounds, mergeById, mergeInferentialDefinition, mergeLogicalDefinition, mergeQuantitativeDefinition, mergeSubjects, mergeSymbolicDefinition, parseDefinition, prependById, prependEquation, prependFact, prependFactor, prependGroup, prependInference, prependRule, removeById, removeEquation, removeFact, removeFactor, removeField, removeGroup, removeInference, removeRule, removeVariable, repeatSubject, replaceById, replaceEquation, replaceFact, replaceFactor, replaceGroup, replaceInference, replaceRule, resolveOperand, resolveSource, roundTo, sortByPriority, subjectToFacts, termToKey };
6877
6823
 
6878
6824
  //# sourceMappingURL=index.js.map