@polintpro/proposit-core 0.8.0 → 0.8.3

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 (116) hide show
  1. package/README.md +30 -3
  2. package/dist/cli/commands/analysis.d.ts.map +1 -1
  3. package/dist/cli/commands/analysis.js +148 -42
  4. package/dist/cli/commands/analysis.js.map +1 -1
  5. package/dist/cli/commands/arguments.d.ts.map +1 -1
  6. package/dist/cli/commands/arguments.js +25 -7
  7. package/dist/cli/commands/arguments.js.map +1 -1
  8. package/dist/cli/commands/claims.d.ts.map +1 -1
  9. package/dist/cli/commands/claims.js +16 -16
  10. package/dist/cli/commands/claims.js.map +1 -1
  11. package/dist/cli/commands/diff.d.ts.map +1 -1
  12. package/dist/cli/commands/diff.js +19 -4
  13. package/dist/cli/commands/diff.js.map +1 -1
  14. package/dist/cli/commands/expressions.d.ts.map +1 -1
  15. package/dist/cli/commands/expressions.js +56 -0
  16. package/dist/cli/commands/expressions.js.map +1 -1
  17. package/dist/cli/commands/graph.d.ts +13 -0
  18. package/dist/cli/commands/graph.d.ts.map +1 -0
  19. package/dist/cli/commands/graph.js +382 -0
  20. package/dist/cli/commands/graph.js.map +1 -0
  21. package/dist/cli/commands/parse.d.ts.map +1 -1
  22. package/dist/cli/commands/parse.js +13 -6
  23. package/dist/cli/commands/parse.js.map +1 -1
  24. package/dist/cli/commands/premises.d.ts.map +1 -1
  25. package/dist/cli/commands/premises.js +21 -17
  26. package/dist/cli/commands/premises.js.map +1 -1
  27. package/dist/cli/commands/render.d.ts.map +1 -1
  28. package/dist/cli/commands/render.js +23 -12
  29. package/dist/cli/commands/render.js.map +1 -1
  30. package/dist/cli/commands/repair.d.ts +3 -0
  31. package/dist/cli/commands/repair.d.ts.map +1 -0
  32. package/dist/cli/commands/repair.js +53 -0
  33. package/dist/cli/commands/repair.js.map +1 -0
  34. package/dist/cli/commands/sources.d.ts.map +1 -1
  35. package/dist/cli/commands/sources.js +17 -17
  36. package/dist/cli/commands/sources.js.map +1 -1
  37. package/dist/cli/commands/validate.d.ts +3 -0
  38. package/dist/cli/commands/validate.d.ts.map +1 -0
  39. package/dist/cli/commands/validate.js +27 -0
  40. package/dist/cli/commands/validate.js.map +1 -0
  41. package/dist/cli/commands/variables.d.ts.map +1 -1
  42. package/dist/cli/commands/variables.js +11 -4
  43. package/dist/cli/commands/variables.js.map +1 -1
  44. package/dist/cli/engine.d.ts +6 -19
  45. package/dist/cli/engine.d.ts.map +1 -1
  46. package/dist/cli/engine.js +72 -73
  47. package/dist/cli/engine.js.map +1 -1
  48. package/dist/cli/output.d.ts.map +1 -1
  49. package/dist/cli/output.js +4 -0
  50. package/dist/cli/output.js.map +1 -1
  51. package/dist/cli/storage/analysis.d.ts +2 -1
  52. package/dist/cli/storage/analysis.d.ts.map +1 -1
  53. package/dist/cli/storage/analysis.js +40 -2
  54. package/dist/cli/storage/analysis.js.map +1 -1
  55. package/dist/cli/storage/libraries.d.ts +3 -0
  56. package/dist/cli/storage/libraries.d.ts.map +1 -1
  57. package/dist/cli/storage/libraries.js +19 -0
  58. package/dist/cli/storage/libraries.js.map +1 -1
  59. package/dist/cli.js +6 -0
  60. package/dist/cli.js.map +1 -1
  61. package/dist/lib/consts.d.ts.map +1 -1
  62. package/dist/lib/consts.js +4 -7
  63. package/dist/lib/consts.js.map +1 -1
  64. package/dist/lib/core/argument-engine.d.ts +12 -1
  65. package/dist/lib/core/argument-engine.d.ts.map +1 -1
  66. package/dist/lib/core/argument-engine.js +295 -17
  67. package/dist/lib/core/argument-engine.js.map +1 -1
  68. package/dist/lib/core/argument-library.d.ts.map +1 -1
  69. package/dist/lib/core/argument-library.js +1 -1
  70. package/dist/lib/core/argument-library.js.map +1 -1
  71. package/dist/lib/core/evaluation/grading.d.ts +28 -0
  72. package/dist/lib/core/evaluation/grading.d.ts.map +1 -0
  73. package/dist/lib/core/evaluation/grading.js +44 -0
  74. package/dist/lib/core/evaluation/grading.js.map +1 -0
  75. package/dist/lib/core/expression-manager.d.ts +2 -1
  76. package/dist/lib/core/expression-manager.d.ts.map +1 -1
  77. package/dist/lib/core/expression-manager.js +12 -8
  78. package/dist/lib/core/expression-manager.js.map +1 -1
  79. package/dist/lib/core/fork.d.ts.map +1 -1
  80. package/dist/lib/core/fork.js +3 -3
  81. package/dist/lib/core/fork.js.map +1 -1
  82. package/dist/lib/core/interfaces/library.interfaces.d.ts +2 -0
  83. package/dist/lib/core/interfaces/library.interfaces.d.ts.map +1 -1
  84. package/dist/lib/core/premise-engine.d.ts +3 -2
  85. package/dist/lib/core/premise-engine.d.ts.map +1 -1
  86. package/dist/lib/core/premise-engine.js +17 -11
  87. package/dist/lib/core/premise-engine.js.map +1 -1
  88. package/dist/lib/core/proposit-core.d.ts +3 -2
  89. package/dist/lib/core/proposit-core.d.ts.map +1 -1
  90. package/dist/lib/core/proposit-core.js +19 -11
  91. package/dist/lib/core/proposit-core.js.map +1 -1
  92. package/dist/lib/index.d.ts +3 -1
  93. package/dist/lib/index.d.ts.map +1 -1
  94. package/dist/lib/index.js +2 -1
  95. package/dist/lib/index.js.map +1 -1
  96. package/dist/lib/parsing/argument-parser.d.ts.map +1 -1
  97. package/dist/lib/parsing/argument-parser.js +17 -14
  98. package/dist/lib/parsing/argument-parser.js.map +1 -1
  99. package/dist/lib/parsing/clamp-max-lengths.d.ts +11 -0
  100. package/dist/lib/parsing/clamp-max-lengths.d.ts.map +1 -0
  101. package/dist/lib/parsing/clamp-max-lengths.js +56 -0
  102. package/dist/lib/parsing/clamp-max-lengths.js.map +1 -0
  103. package/dist/lib/parsing/prompt-builder.d.ts.map +1 -1
  104. package/dist/lib/parsing/prompt-builder.js +14 -1
  105. package/dist/lib/parsing/prompt-builder.js.map +1 -1
  106. package/dist/lib/parsing/types.d.ts +2 -0
  107. package/dist/lib/parsing/types.d.ts.map +1 -1
  108. package/dist/lib/schemata/analysis.d.ts +1 -1
  109. package/dist/lib/schemata/analysis.d.ts.map +1 -1
  110. package/dist/lib/schemata/analysis.js +2 -2
  111. package/dist/lib/schemata/analysis.js.map +1 -1
  112. package/dist/lib/types/checksum.d.ts +7 -7
  113. package/dist/lib/types/checksum.d.ts.map +1 -1
  114. package/dist/lib/types/evaluation.d.ts +5 -3
  115. package/dist/lib/types/evaluation.d.ts.map +1 -1
  116. package/package.json +1 -1
@@ -1,4 +1,3 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import { Value } from "typebox/value";
3
2
  import { CoreArgumentSchema, isClaimBound, isPremiseBound, } from "../schemata/index.js";
4
3
  import { DEFAULT_GRAMMAR_CONFIG, PERMISSIVE_GRAMMAR_CONFIG, } from "../types/grammar.js";
@@ -7,11 +6,13 @@ import { DEFAULT_CHECKSUM_CONFIG, normalizeChecksumConfig, serializeChecksumConf
7
6
  import { getOrCreate, sortedUnique } from "../utils/collections.js";
8
7
  import { ChangeCollector } from "./change-collector.js";
9
8
  import { canonicalSerialize, computeHash, entityChecksum } from "./checksum.js";
10
- import { kleeneAnd, kleeneNot } from "./evaluation/kleene.js";
9
+ import { kleeneAnd, kleeneNot, kleeneOr, kleeneImplies, kleeneIff, } from "./evaluation/kleene.js";
11
10
  import { makeErrorIssue, makeValidationResult, } from "./evaluation/validation.js";
12
11
  import { InvariantViolationError } from "./invariant-violation-error.js";
13
12
  import { PremiseEngine } from "./premise-engine.js";
14
13
  import { VariableManager } from "./variable-manager.js";
14
+ /** Default ID generator using the Web Crypto API (Node.js 20+, all modern browsers). */
15
+ export const defaultGenerateId = () => globalThis.crypto.randomUUID();
15
16
  /**
16
17
  * Manages a propositional logic argument composed of premises, variable
17
18
  * assignments, and logical roles (supporting premises and a conclusion).
@@ -30,6 +31,7 @@ export class ArgumentEngine {
30
31
  checksumConfig;
31
32
  positionConfig;
32
33
  grammarConfig;
34
+ generateId;
33
35
  restoringFromSnapshot = false;
34
36
  checksumDirty = true;
35
37
  cachedMetaChecksum;
@@ -56,9 +58,11 @@ export class ArgumentEngine {
56
58
  this.checksumConfig = options?.checksumConfig;
57
59
  this.positionConfig = options?.positionConfig;
58
60
  this.grammarConfig = options?.grammarConfig;
61
+ this.generateId = options?.generateId ?? defaultGenerateId;
59
62
  this.variables = new VariableManager({
60
63
  checksumConfig: this.checksumConfig,
61
64
  positionConfig: this.positionConfig,
65
+ generateId: this.generateId,
62
66
  });
63
67
  this.expressionIndex = new Map();
64
68
  this.conclusionPremiseId = undefined;
@@ -320,7 +324,7 @@ export class ArgumentEngine {
320
324
  return lines.join("\n");
321
325
  }
322
326
  createPremise(extras, symbol) {
323
- return this.createPremiseWithId(randomUUID(), extras, symbol);
327
+ return this.createPremiseWithId(this.generateId(), extras, symbol);
324
328
  }
325
329
  createPremiseWithId(id, extras, symbol) {
326
330
  return this.withValidation(() => {
@@ -341,6 +345,7 @@ export class ArgumentEngine {
341
345
  checksumConfig: this.checksumConfig,
342
346
  positionConfig: this.positionConfig,
343
347
  grammarConfig: this.grammarConfig,
348
+ generateId: this.generateId,
344
349
  });
345
350
  this.premises.set(id, pm);
346
351
  this.wireCircularityCheck(pm);
@@ -363,7 +368,7 @@ export class ArgumentEngine {
363
368
  if (!this.restoringFromSnapshot) {
364
369
  const autoSymbol = symbol ?? this.generateUniqueSymbol();
365
370
  const autoVariable = {
366
- id: randomUUID(),
371
+ id: this.generateId(),
367
372
  argumentId: this.argument.id,
368
373
  argumentVersion: this.argument.version,
369
374
  symbol: autoSymbol,
@@ -800,17 +805,20 @@ export class ArgumentEngine {
800
805
  };
801
806
  }
802
807
  /** Creates a new ArgumentEngine from a previously captured snapshot. */
803
- static fromSnapshot(snapshot, claimLibrary, sourceLibrary, claimSourceLibrary, grammarConfig, checksumVerification) {
808
+ static fromSnapshot(snapshot, claimLibrary, sourceLibrary, claimSourceLibrary, grammarConfig, checksumVerification, generateId) {
804
809
  const engine = new ArgumentEngine(snapshot.argument, claimLibrary, sourceLibrary, claimSourceLibrary, snapshot.config
805
810
  ? {
806
811
  ...snapshot.config,
807
812
  checksumConfig: normalizeChecksumConfig(snapshot.config.checksumConfig),
813
+ generateId: generateId ?? snapshot.config.generateId,
808
814
  }
809
- : undefined);
815
+ : generateId
816
+ ? { generateId }
817
+ : undefined);
810
818
  engine.restoringFromSnapshot = true;
811
819
  // Restore premises first (premise-bound variables reference them)
812
820
  for (const premiseSnap of snapshot.premises) {
813
- const pe = PremiseEngine.fromSnapshot(premiseSnap, snapshot.argument, engine.variables, engine.expressionIndex, grammarConfig);
821
+ const pe = PremiseEngine.fromSnapshot(premiseSnap, snapshot.argument, engine.variables, engine.expressionIndex, grammarConfig, generateId);
814
822
  engine.premises.set(pe.getId(), pe);
815
823
  engine.wireCircularityCheck(pe);
816
824
  engine.wireEmptyBoundPremiseCheck(pe);
@@ -1488,6 +1496,270 @@ export class ArgumentEngine {
1488
1496
  }
1489
1497
  return makeValidationResult(issues);
1490
1498
  }
1499
+ /**
1500
+ * Run fixed-point constraint propagation over accepted operators.
1501
+ * Fills unknown (null) variable values based on operator semantics.
1502
+ * Never overwrites user-assigned values (true/false).
1503
+ */
1504
+ propagateOperatorConstraints(assignment) {
1505
+ const vars = { ...assignment.variables };
1506
+ const opAssignments = assignment.operatorAssignments;
1507
+ // Collect all expressions across all premises, indexed by id
1508
+ const exprById = new Map();
1509
+ // Children lookup: parentId -> sorted children
1510
+ const childrenOf = new Map();
1511
+ for (const pm of this.listPremises()) {
1512
+ for (const expr of pm.getExpressions()) {
1513
+ exprById.set(expr.id, expr);
1514
+ }
1515
+ // Build children map using getChildExpressions for each operator/formula
1516
+ for (const expr of pm.getExpressions()) {
1517
+ if (expr.type === "operator" || expr.type === "formula") {
1518
+ childrenOf.set(expr.id, pm.getChildExpressions(expr.id));
1519
+ }
1520
+ }
1521
+ }
1522
+ /**
1523
+ * Resolve the current Kleene value of an expression subtree
1524
+ * given the current variable assignments. Does not force-accept
1525
+ * nested operators — evaluates them normally via Kleene logic.
1526
+ */
1527
+ const resolveValue = (exprId) => {
1528
+ const expr = exprById.get(exprId);
1529
+ if (!expr)
1530
+ return null;
1531
+ if (expr.type === "variable") {
1532
+ return (vars[expr
1533
+ .variableId] ?? null);
1534
+ }
1535
+ if (expr.type === "formula") {
1536
+ const children = childrenOf.get(expr.id) ?? [];
1537
+ return children.length > 0 ? resolveValue(children[0].id) : null;
1538
+ }
1539
+ // operator
1540
+ const op = expr
1541
+ .operator;
1542
+ const children = childrenOf.get(expr.id) ?? [];
1543
+ switch (op) {
1544
+ case "not":
1545
+ return kleeneNot(resolveValue(children[0].id));
1546
+ case "and":
1547
+ return children.reduce((acc, child) => kleeneAnd(acc, resolveValue(child.id)), true);
1548
+ case "or":
1549
+ return children.reduce((acc, child) => kleeneOr(acc, resolveValue(child.id)), false);
1550
+ case "implies": {
1551
+ return kleeneImplies(resolveValue(children[0].id), resolveValue(children[1].id));
1552
+ }
1553
+ case "iff": {
1554
+ return kleeneIff(resolveValue(children[0].id), resolveValue(children[1].id));
1555
+ }
1556
+ }
1557
+ };
1558
+ /**
1559
+ * Unwrap formula wrappers to find the leaf variable expression.
1560
+ * Returns the variableId if the leaf is a variable, otherwise null.
1561
+ */
1562
+ const resolveLeafVariableId = (expr) => {
1563
+ if (expr.type === "variable") {
1564
+ return expr.variableId;
1565
+ }
1566
+ if (expr.type === "formula") {
1567
+ const children = childrenOf.get(expr.id) ?? [];
1568
+ if (children.length > 0) {
1569
+ return resolveLeafVariableId(children[0]);
1570
+ }
1571
+ }
1572
+ return null;
1573
+ };
1574
+ // Track which variable IDs were explicitly set by the user
1575
+ // (true or false). These are never overwritten by propagation.
1576
+ const userAssigned = new Set();
1577
+ for (const [varId, val] of Object.entries(vars)) {
1578
+ if (val !== null && val !== undefined)
1579
+ userAssigned.add(varId);
1580
+ }
1581
+ /**
1582
+ * Try to set a child expression's variable to a value.
1583
+ * Never overwrites user-assigned values.
1584
+ * False overrides propagated true (rejection wins).
1585
+ * Returns true if a value changed.
1586
+ */
1587
+ const trySetChild = (child, value) => {
1588
+ const varId = resolveLeafVariableId(child);
1589
+ if (varId == null || userAssigned.has(varId))
1590
+ return false;
1591
+ const current = vars[varId] ?? null;
1592
+ if (current === null) {
1593
+ vars[varId] = value;
1594
+ return true;
1595
+ }
1596
+ // False overrides propagated true
1597
+ if (value === false && current === true) {
1598
+ vars[varId] = false;
1599
+ return true;
1600
+ }
1601
+ return false;
1602
+ };
1603
+ // Two-phase propagation: rejections first (to establish false values),
1604
+ // then acceptances (which only fill remaining unknowns).
1605
+ // This prevents acceptance from deriving values through chains that
1606
+ // are later invalidated by rejection.
1607
+ for (const phase of ["rejected", "accepted"]) {
1608
+ let changed = true;
1609
+ while (changed) {
1610
+ changed = false;
1611
+ for (const [exprId, expr] of exprById) {
1612
+ if (expr.type !== "operator")
1613
+ continue;
1614
+ const state = opAssignments[exprId];
1615
+ if (state !== phase)
1616
+ continue;
1617
+ const op = expr.operator;
1618
+ const children = childrenOf.get(exprId) ?? [];
1619
+ if (state === "accepted") {
1620
+ switch (op) {
1621
+ case "not": {
1622
+ // ¬A accepted (= true) => child must be false
1623
+ if (children.length > 0) {
1624
+ if (trySetChild(children[0], false))
1625
+ changed = true;
1626
+ }
1627
+ break;
1628
+ }
1629
+ case "and": {
1630
+ // A ∧ B accepted => all children must be true
1631
+ for (const child of children) {
1632
+ if (trySetChild(child, true))
1633
+ changed = true;
1634
+ }
1635
+ break;
1636
+ }
1637
+ case "or": {
1638
+ // A ∨ B accepted: if all-but-one are false, remaining must be true
1639
+ const unknownChildren = [];
1640
+ let allOthersAreFalse = true;
1641
+ for (const child of children) {
1642
+ const childValue = resolveValue(child.id);
1643
+ if (childValue === null) {
1644
+ unknownChildren.push(child);
1645
+ }
1646
+ else if (childValue !== false) {
1647
+ allOthersAreFalse = false;
1648
+ }
1649
+ }
1650
+ if (unknownChildren.length === 1 &&
1651
+ allOthersAreFalse) {
1652
+ if (trySetChild(unknownChildren[0], true))
1653
+ changed = true;
1654
+ }
1655
+ break;
1656
+ }
1657
+ case "implies": {
1658
+ // A → B accepted: if A=true => B=true; if B=false => A=false
1659
+ if (children.length >= 2) {
1660
+ const leftValue = resolveValue(children[0].id);
1661
+ const rightValue = resolveValue(children[1].id);
1662
+ if (leftValue === true) {
1663
+ if (trySetChild(children[1], true))
1664
+ changed = true;
1665
+ }
1666
+ if (rightValue === false) {
1667
+ if (trySetChild(children[0], false))
1668
+ changed = true;
1669
+ }
1670
+ }
1671
+ break;
1672
+ }
1673
+ case "iff": {
1674
+ // A ↔ B accepted: if A known => B matches; if B known => A matches
1675
+ if (children.length >= 2) {
1676
+ const leftValue = resolveValue(children[0].id);
1677
+ const rightValue = resolveValue(children[1].id);
1678
+ if (leftValue !== null) {
1679
+ if (trySetChild(children[1], leftValue))
1680
+ changed = true;
1681
+ }
1682
+ if (rightValue !== null) {
1683
+ if (trySetChild(children[0], rightValue))
1684
+ changed = true;
1685
+ }
1686
+ }
1687
+ break;
1688
+ }
1689
+ }
1690
+ }
1691
+ else {
1692
+ // state === "rejected" — expression forced false
1693
+ switch (op) {
1694
+ case "not": {
1695
+ // ¬A rejected (= false) => child must be true
1696
+ if (children.length > 0) {
1697
+ if (trySetChild(children[0], true))
1698
+ changed = true;
1699
+ }
1700
+ break;
1701
+ }
1702
+ case "and": {
1703
+ // A ∧ B rejected (= false): if all-but-one are true, remaining must be false
1704
+ const unknownChildren = [];
1705
+ let allOthersAreTrue = true;
1706
+ for (const child of children) {
1707
+ const childValue = resolveValue(child.id);
1708
+ if (childValue === null) {
1709
+ unknownChildren.push(child);
1710
+ }
1711
+ else if (childValue !== true) {
1712
+ allOthersAreTrue = false;
1713
+ }
1714
+ }
1715
+ if (unknownChildren.length === 1 &&
1716
+ allOthersAreTrue) {
1717
+ if (trySetChild(unknownChildren[0], false))
1718
+ changed = true;
1719
+ }
1720
+ break;
1721
+ }
1722
+ case "or": {
1723
+ // A ∨ B rejected (= false) => all children must be false
1724
+ for (const child of children) {
1725
+ if (trySetChild(child, false))
1726
+ changed = true;
1727
+ }
1728
+ break;
1729
+ }
1730
+ case "implies": {
1731
+ // A → B rejected (= false) => A must be true, B must be false
1732
+ if (children.length >= 2) {
1733
+ if (trySetChild(children[0], true))
1734
+ changed = true;
1735
+ if (trySetChild(children[1], false))
1736
+ changed = true;
1737
+ }
1738
+ break;
1739
+ }
1740
+ case "iff": {
1741
+ // A ↔ B rejected (= false): if A known => B is opposite; if B known => A is opposite
1742
+ if (children.length >= 2) {
1743
+ const leftValue = resolveValue(children[0].id);
1744
+ const rightValue = resolveValue(children[1].id);
1745
+ if (leftValue !== null) {
1746
+ if (trySetChild(children[1], !leftValue))
1747
+ changed = true;
1748
+ }
1749
+ if (rightValue !== null) {
1750
+ if (trySetChild(children[0], !rightValue))
1751
+ changed = true;
1752
+ }
1753
+ }
1754
+ break;
1755
+ }
1756
+ }
1757
+ }
1758
+ }
1759
+ }
1760
+ }
1761
+ return vars;
1762
+ }
1491
1763
  evaluate(assignment, options) {
1492
1764
  const validateFirst = options?.validateFirst ?? true;
1493
1765
  if (validateFirst) {
@@ -1538,6 +1810,12 @@ export class ArgumentEngine {
1538
1810
  return true;
1539
1811
  return false;
1540
1812
  });
1813
+ // Run operator constraint propagation
1814
+ const propagatedVars = this.propagateOperatorConstraints(assignment);
1815
+ const propagatedAssignment = {
1816
+ variables: propagatedVars,
1817
+ operatorAssignments: assignment.operatorAssignments,
1818
+ };
1541
1819
  try {
1542
1820
  // Build a resolver that lazily evaluates premise-bound variables
1543
1821
  // by evaluating their bound premise's expression tree under the
@@ -1552,7 +1830,7 @@ export class ArgumentEngine {
1552
1830
  !isPremiseBound(variable) ||
1553
1831
  variable.boundArgumentId !== this.argument.id) {
1554
1832
  // Claim-bound or externally-bound: read from assignment
1555
- return assignment.variables[variableId] ?? null;
1833
+ return propagatedAssignment.variables[variableId] ?? null;
1556
1834
  }
1557
1835
  // Internal premise-bound: lazy resolution
1558
1836
  const boundPremiseId = variable.boundPremiseId;
@@ -1561,7 +1839,7 @@ export class ArgumentEngine {
1561
1839
  resolverCache.set(variableId, null);
1562
1840
  return null;
1563
1841
  }
1564
- const premiseResult = boundPremise.evaluate(assignment, {
1842
+ const premiseResult = boundPremise.evaluate(propagatedAssignment, {
1565
1843
  resolver,
1566
1844
  });
1567
1845
  const value = premiseResult?.rootValue ?? null;
@@ -1572,9 +1850,9 @@ export class ArgumentEngine {
1572
1850
  strictUnknownKeys: options?.strictUnknownAssignmentKeys ?? false,
1573
1851
  resolver,
1574
1852
  };
1575
- const conclusionEvaluation = conclusion.evaluate(assignment, evalOpts);
1576
- const supportingEvaluations = supportingPremises.map((pm) => pm.evaluate(assignment, evalOpts));
1577
- const constraintEvaluations = constraintPremises.map((pm) => pm.evaluate(assignment, evalOpts));
1853
+ const conclusionEvaluation = conclusion.evaluate(propagatedAssignment, evalOpts);
1854
+ const supportingEvaluations = supportingPremises.map((pm) => pm.evaluate(propagatedAssignment, evalOpts));
1855
+ const constraintEvaluations = constraintPremises.map((pm) => pm.evaluate(propagatedAssignment, evalOpts));
1578
1856
  const isAdmissibleAssignment = constraintEvaluations.reduce((acc, result) => kleeneAnd(acc, result.rootValue ?? null), true);
1579
1857
  const allSupportingPremisesTrue = supportingEvaluations.reduce((acc, result) => kleeneAnd(acc, result.rootValue ?? null), true);
1580
1858
  const conclusionTrue = conclusionEvaluation.rootValue ?? null;
@@ -1593,10 +1871,10 @@ export class ArgumentEngine {
1593
1871
  return {
1594
1872
  ok: true,
1595
1873
  assignment: {
1596
- variables: { ...assignment.variables },
1597
- rejectedExpressionIds: [
1598
- ...assignment.rejectedExpressionIds,
1599
- ],
1874
+ variables: { ...propagatedAssignment.variables },
1875
+ operatorAssignments: {
1876
+ ...propagatedAssignment.operatorAssignments,
1877
+ },
1600
1878
  },
1601
1879
  referencedVariableIds,
1602
1880
  conclusion: strip(conclusionEvaluation),
@@ -1699,7 +1977,7 @@ export class ArgumentEngine {
1699
1977
  }
1700
1978
  const assignment = {
1701
1979
  variables: {},
1702
- rejectedExpressionIds: [],
1980
+ operatorAssignments: {},
1703
1981
  };
1704
1982
  for (let i = 0; i < checkedVariableIds.length; i++) {
1705
1983
  assignment.variables[checkedVariableIds[i]] = Boolean(mask & (1 << i));