@polintpro/proposit-core 0.3.0 → 0.5.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.
- package/README.md +13 -0
- package/dist/cli/commands/sources.d.ts +3 -0
- package/dist/cli/commands/sources.d.ts.map +1 -0
- package/dist/cli/commands/sources.js +118 -0
- package/dist/cli/commands/sources.js.map +1 -0
- package/dist/cli/commands/variables.d.ts.map +1 -1
- package/dist/cli/commands/variables.js +3 -0
- package/dist/cli/commands/variables.js.map +1 -1
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +6 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/engine.d.ts.map +1 -1
- package/dist/cli/engine.js +35 -2
- package/dist/cli/engine.js.map +1 -1
- package/dist/cli/import.d.ts.map +1 -1
- package/dist/cli/import.js +7 -1
- package/dist/cli/import.js.map +1 -1
- package/dist/cli/schemata.d.ts +8 -0
- package/dist/cli/schemata.d.ts.map +1 -1
- package/dist/cli/schemata.js +10 -0
- package/dist/cli/schemata.js.map +1 -1
- package/dist/cli/storage/sources.d.ts +11 -0
- package/dist/cli/storage/sources.d.ts.map +1 -0
- package/dist/cli/storage/sources.js +105 -0
- package/dist/cli/storage/sources.js.map +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/extensions/ieee/index.d.ts +3 -0
- package/dist/extensions/ieee/index.d.ts.map +1 -0
- package/dist/extensions/ieee/index.js +3 -0
- package/dist/extensions/ieee/index.js.map +1 -0
- package/dist/extensions/ieee/references.d.ts +620 -0
- package/dist/extensions/ieee/references.d.ts.map +1 -0
- package/dist/extensions/ieee/references.js +450 -0
- package/dist/extensions/ieee/references.js.map +1 -0
- package/dist/extensions/ieee/source.d.ts +286 -0
- package/dist/extensions/ieee/source.d.ts.map +1 -0
- package/dist/extensions/ieee/source.js +12 -0
- package/dist/extensions/ieee/source.js.map +1 -0
- package/dist/lib/consts.d.ts.map +1 -1
- package/dist/lib/consts.js +31 -1
- package/dist/lib/consts.js.map +1 -1
- package/dist/lib/core/argument-engine.d.ts +25 -117
- package/dist/lib/core/argument-engine.d.ts.map +1 -1
- package/dist/lib/core/argument-engine.js +239 -123
- package/dist/lib/core/argument-engine.js.map +1 -1
- package/dist/lib/core/assertion-library.d.ts +27 -0
- package/dist/lib/core/assertion-library.d.ts.map +1 -0
- package/dist/lib/core/assertion-library.js +129 -0
- package/dist/lib/core/assertion-library.js.map +1 -0
- package/dist/lib/core/change-collector.d.ts +7 -5
- package/dist/lib/core/change-collector.d.ts.map +1 -1
- package/dist/lib/core/change-collector.js +18 -5
- package/dist/lib/core/change-collector.js.map +1 -1
- package/dist/lib/core/diff.d.ts +6 -2
- package/dist/lib/core/diff.d.ts.map +1 -1
- package/dist/lib/core/diff.js +80 -1
- package/dist/lib/core/diff.js.map +1 -1
- package/dist/lib/core/interfaces/argument-engine.interfaces.d.ts +338 -0
- package/dist/lib/core/interfaces/argument-engine.interfaces.d.ts.map +1 -0
- package/dist/lib/core/interfaces/argument-engine.interfaces.js +2 -0
- package/dist/lib/core/interfaces/argument-engine.interfaces.js.map +1 -0
- package/dist/lib/core/interfaces/index.d.ts +6 -0
- package/dist/lib/core/interfaces/index.d.ts.map +1 -0
- package/dist/lib/core/interfaces/index.js +2 -0
- package/dist/lib/core/interfaces/index.js.map +1 -0
- package/dist/lib/core/interfaces/library.interfaces.d.ts +19 -0
- package/dist/lib/core/interfaces/library.interfaces.d.ts.map +1 -0
- package/dist/lib/core/interfaces/library.interfaces.js +2 -0
- package/dist/lib/core/interfaces/library.interfaces.js.map +1 -0
- package/dist/lib/core/interfaces/premise-engine.interfaces.d.ts +318 -0
- package/dist/lib/core/interfaces/premise-engine.interfaces.d.ts.map +1 -0
- package/dist/lib/core/interfaces/premise-engine.interfaces.js +2 -0
- package/dist/lib/core/interfaces/premise-engine.interfaces.js.map +1 -0
- package/dist/lib/core/interfaces/shared.interfaces.d.ts +24 -0
- package/dist/lib/core/interfaces/shared.interfaces.d.ts.map +1 -0
- package/dist/lib/core/interfaces/shared.interfaces.js +2 -0
- package/dist/lib/core/interfaces/shared.interfaces.js.map +1 -0
- package/dist/lib/core/interfaces/source-management.interfaces.d.ts +63 -0
- package/dist/lib/core/interfaces/source-management.interfaces.d.ts.map +1 -0
- package/dist/lib/core/interfaces/source-management.interfaces.js +2 -0
- package/dist/lib/core/interfaces/source-management.interfaces.js.map +1 -0
- package/dist/lib/core/premise-engine.d.ts +10 -144
- package/dist/lib/core/premise-engine.d.ts.map +1 -1
- package/dist/lib/core/premise-engine.js +82 -143
- package/dist/lib/core/premise-engine.js.map +1 -1
- package/dist/lib/core/source-library.d.ts +27 -0
- package/dist/lib/core/source-library.d.ts.map +1 -0
- package/dist/lib/core/source-library.js +129 -0
- package/dist/lib/core/source-library.js.map +1 -0
- package/dist/lib/core/source-manager.d.ts +38 -0
- package/dist/lib/core/source-manager.d.ts.map +1 -0
- package/dist/lib/core/source-manager.js +266 -0
- package/dist/lib/core/source-manager.js.map +1 -0
- package/dist/lib/index.d.ts +6 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +4 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/schemata/assertion.d.ts +9 -0
- package/dist/lib/schemata/assertion.d.ts.map +1 -0
- package/dist/lib/schemata/assertion.js +18 -0
- package/dist/lib/schemata/assertion.js.map +1 -0
- package/dist/lib/schemata/index.d.ts +2 -0
- package/dist/lib/schemata/index.d.ts.map +1 -1
- package/dist/lib/schemata/index.js +2 -0
- package/dist/lib/schemata/index.js.map +1 -1
- package/dist/lib/schemata/propositional.d.ts +2 -0
- package/dist/lib/schemata/propositional.d.ts.map +1 -1
- package/dist/lib/schemata/propositional.js +5 -1
- package/dist/lib/schemata/propositional.js.map +1 -1
- package/dist/lib/schemata/source.d.ts +30 -0
- package/dist/lib/schemata/source.d.ts.map +1 -0
- package/dist/lib/schemata/source.js +45 -0
- package/dist/lib/schemata/source.js.map +1 -0
- package/dist/lib/types/checksum.d.ts +8 -0
- package/dist/lib/types/checksum.d.ts.map +1 -1
- package/dist/lib/types/diff.d.ts +5 -1
- package/dist/lib/types/diff.d.ts.map +1 -1
- package/dist/lib/types/evaluation.d.ts +1 -1
- package/dist/lib/types/evaluation.d.ts.map +1 -1
- package/dist/lib/types/mutation.d.ts +3 -0
- package/dist/lib/types/mutation.d.ts.map +1 -1
- package/dist/lib/types/reactive.d.ts +3 -1
- package/dist/lib/types/reactive.d.ts.map +1 -1
- package/package.json +5 -1
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import type { TCoreArgument, TCorePremise, TCorePropositionalExpression, TCorePropositionalVariable, TOptionalChecksum } from "../schemata/index.js";
|
|
1
|
+
import type { TCoreArgument, TCorePremise, TCorePropositionalExpression, TCorePropositionalVariable, TOptionalChecksum, TCoreExpressionSourceAssociation } from "../schemata/index.js";
|
|
2
2
|
import type { TCoreExpressionAssignment, TCorePremiseEvaluationResult, TCoreValidationResult } from "../types/evaluation.js";
|
|
3
3
|
import type { TCoreMutationResult } from "../types/mutation.js";
|
|
4
4
|
import type { TLogicEngineOptions } from "./argument-engine.js";
|
|
5
5
|
import type { TExpressionInput, TExpressionManagerSnapshot, TExpressionWithoutPosition, TExpressionUpdate } from "./expression-manager.js";
|
|
6
6
|
import { VariableManager } from "./variable-manager.js";
|
|
7
|
+
import type { SourceManager } from "./source-manager.js";
|
|
8
|
+
import type { TExpressionMutations, TExpressionQueries, TVariableReferences, TPremiseClassification, TPremiseEvaluation, TPremiseLifecycle, TPremiseIdentity, TDisplayable, TChecksummable } from "./interfaces/index.js";
|
|
7
9
|
export type TPremiseEngineSnapshot<TPremise extends TCorePremise = TCorePremise, TExpr extends TCorePropositionalExpression = TCorePropositionalExpression> = {
|
|
8
10
|
premise: TOptionalChecksum<TPremise>;
|
|
9
11
|
rootExpressionId?: string;
|
|
10
12
|
expressions: TExpressionManagerSnapshot<TExpr>;
|
|
11
13
|
config?: TLogicEngineOptions;
|
|
12
14
|
};
|
|
13
|
-
export declare class PremiseEngine<TArg extends TCoreArgument = TCoreArgument, TPremise extends TCorePremise = TCorePremise, TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable> {
|
|
15
|
+
export declare class PremiseEngine<TArg extends TCoreArgument = TCoreArgument, TPremise extends TCorePremise = TCorePremise, TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable> implements TExpressionMutations<TArg, TPremise, TExpr, TVar>, TExpressionQueries<TExpr>, TVariableReferences<TArg, TPremise, TExpr, TVar>, TPremiseClassification, TPremiseEvaluation, TPremiseLifecycle<TPremise, TExpr>, TPremiseIdentity<TArg, TPremise, TExpr, TVar>, TDisplayable, TChecksummable {
|
|
14
16
|
private premise;
|
|
15
17
|
private rootExpressionId;
|
|
16
18
|
private variables;
|
|
@@ -21,182 +23,47 @@ export declare class PremiseEngine<TArg extends TCoreArgument = TCoreArgument, T
|
|
|
21
23
|
private checksumDirty;
|
|
22
24
|
private cachedChecksum;
|
|
23
25
|
private expressionIndex?;
|
|
26
|
+
private sourceManager?;
|
|
24
27
|
private onMutate?;
|
|
25
28
|
constructor(premise: TOptionalChecksum<TPremise>, deps: {
|
|
26
29
|
argument: TOptionalChecksum<TArg>;
|
|
27
30
|
variables: VariableManager<TVar>;
|
|
28
31
|
expressionIndex?: Map<string, string>;
|
|
32
|
+
sourceManager?: SourceManager;
|
|
29
33
|
}, config?: TLogicEngineOptions);
|
|
30
34
|
setOnMutate(callback: (() => void) | undefined): void;
|
|
31
|
-
/**
|
|
32
|
-
* Deletes all expressions that reference the given variable ID,
|
|
33
|
-
* including their subtrees. Operator collapse runs after each removal.
|
|
34
|
-
* Returns all removed expressions in the changeset.
|
|
35
|
-
*/
|
|
36
35
|
deleteExpressionsUsingVariable(variableId: string): TCoreMutationResult<TExpr[], TExpr, TVar, TPremise, TArg>;
|
|
37
|
-
/**
|
|
38
|
-
* Adds an expression to this premise's tree.
|
|
39
|
-
*
|
|
40
|
-
* If the expression has `parentId: null` it becomes the root; only one
|
|
41
|
-
* root is permitted per premise. If `parentId` is non-null the parent
|
|
42
|
-
* must already exist within this premise.
|
|
43
|
-
*
|
|
44
|
-
* All other structural rules (`implies`/`iff` root-only, child limits,
|
|
45
|
-
* position uniqueness) are enforced by the underlying `ExpressionManager`.
|
|
46
|
-
*
|
|
47
|
-
* @throws If the premise already has a root expression and this one is also a root.
|
|
48
|
-
* @throws If the expression's parent does not exist in this premise.
|
|
49
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
50
|
-
* @throws If the expression does not belong to this argument.
|
|
51
|
-
*/
|
|
52
36
|
addExpression(expression: TExpressionInput<TExpr>): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
53
|
-
/**
|
|
54
|
-
* Adds an expression as the last child of the given parent, with
|
|
55
|
-
* position computed automatically.
|
|
56
|
-
*
|
|
57
|
-
* If `parentId` is `null`, the expression becomes the root.
|
|
58
|
-
*
|
|
59
|
-
* @throws If the premise already has a root and parentId is null.
|
|
60
|
-
* @throws If the expression does not belong to this argument.
|
|
61
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
62
|
-
*/
|
|
63
37
|
appendExpression(parentId: string | null, expression: TExpressionWithoutPosition<TExpr>): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
64
|
-
/**
|
|
65
|
-
* Adds an expression immediately before or after an existing sibling,
|
|
66
|
-
* with position computed automatically.
|
|
67
|
-
*
|
|
68
|
-
* @throws If the sibling does not exist in this premise.
|
|
69
|
-
* @throws If the expression does not belong to this argument.
|
|
70
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
71
|
-
*/
|
|
72
38
|
addExpressionRelative(siblingId: string, relativePosition: "before" | "after", expression: TExpressionWithoutPosition<TExpr>): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
73
|
-
/**
|
|
74
|
-
* Updates mutable fields of an existing expression in this premise.
|
|
75
|
-
*
|
|
76
|
-
* Only `position`, `variableId`, and `operator` may be updated. Structural
|
|
77
|
-
* fields (`id`, `parentId`, `type`, `argumentId`, `argumentVersion`,
|
|
78
|
-
* `checksum`) are forbidden — enforced by the underlying
|
|
79
|
-
* `ExpressionManager`.
|
|
80
|
-
*
|
|
81
|
-
* If `variableId` changes, the internal `expressionsByVariableId` index is
|
|
82
|
-
* updated so that cascade deletion (`deleteExpressionsUsingVariable`) stays
|
|
83
|
-
* correct.
|
|
84
|
-
*
|
|
85
|
-
* @throws If the expression does not exist in this premise.
|
|
86
|
-
* @throws If `variableId` references a non-existent variable.
|
|
87
|
-
*/
|
|
88
39
|
updateExpression(expressionId: string, updates: TExpressionUpdate): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
89
|
-
/**
|
|
90
|
-
* Removes an expression and its entire descendant subtree, then collapses
|
|
91
|
-
* any ancestor operators with fewer than two children (same semantics as
|
|
92
|
-
* before). Returns the removed root expression, or `undefined` if not
|
|
93
|
-
* found.
|
|
94
|
-
*
|
|
95
|
-
* `rootExpressionId` is recomputed after every removal because operator
|
|
96
|
-
* collapse can silently promote a new expression into the root slot.
|
|
97
|
-
*/
|
|
98
40
|
removeExpression(expressionId: string, deleteSubtree: boolean): TCoreMutationResult<TExpr | undefined, TExpr, TVar, TPremise, TArg>;
|
|
99
|
-
/**
|
|
100
|
-
* Splices a new expression between existing nodes in the tree. The new
|
|
101
|
-
* expression inherits the tree slot of the anchor node
|
|
102
|
-
* (`leftNodeId ?? rightNodeId`).
|
|
103
|
-
*
|
|
104
|
-
* `rootExpressionId` is recomputed after every insertion because the
|
|
105
|
-
* anchor may have been the root.
|
|
106
|
-
*
|
|
107
|
-
* See `ArgumentEngine.insertExpression` for the full contract; the same
|
|
108
|
-
* rules apply here.
|
|
109
|
-
*
|
|
110
|
-
* @throws If the expression does not belong to this argument.
|
|
111
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
112
|
-
*/
|
|
113
41
|
insertExpression(expression: TExpressionInput<TExpr>, leftNodeId?: string, rightNodeId?: string): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
114
|
-
/**
|
|
115
|
-
* Wraps an existing expression with a new operator and a new sibling
|
|
116
|
-
* expression in a single atomic operation.
|
|
117
|
-
*
|
|
118
|
-
* The operator takes the existing node's slot in the tree. Both the
|
|
119
|
-
* existing node and the new sibling become children of the operator.
|
|
120
|
-
*
|
|
121
|
-
* Exactly one of `leftNodeId` / `rightNodeId` must be provided — it
|
|
122
|
-
* identifies the existing node and which child slot it occupies.
|
|
123
|
-
* The new sibling fills the other slot.
|
|
124
|
-
*
|
|
125
|
-
* @throws If the expression does not belong to this argument.
|
|
126
|
-
* @throws If the new sibling is a variable reference and the variable has not been registered.
|
|
127
|
-
*/
|
|
128
42
|
wrapExpression(operator: TExpressionWithoutPosition<TExpr>, newSibling: TExpressionWithoutPosition<TExpr>, leftNodeId?: string, rightNodeId?: string): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
*/
|
|
43
|
+
addExpressionSourceAssociation(sourceId: string, sourceVersion: number, expressionId: string): TCoreMutationResult<TCoreExpressionSourceAssociation, TExpr, TVar, TPremise, TArg>;
|
|
44
|
+
removeExpressionSourceAssociation(associationId: string): TCoreMutationResult<TCoreExpressionSourceAssociation | undefined, TExpr, TVar, TPremise, TArg>;
|
|
45
|
+
getSourceAssociationsForExpression(expressionId: string): TCoreExpressionSourceAssociation[];
|
|
133
46
|
getExpression(id: string): TExpr | undefined;
|
|
134
47
|
getId(): string;
|
|
135
48
|
getExtras(): Record<string, unknown>;
|
|
136
49
|
setExtras(extras: Record<string, unknown>): TCoreMutationResult<Record<string, unknown>, TExpr, TVar, TPremise, TArg>;
|
|
137
50
|
getRootExpressionId(): string | undefined;
|
|
138
51
|
getRootExpression(): TExpr | undefined;
|
|
139
|
-
/**
|
|
140
|
-
* Returns all argument-level variables (from the shared VariableManager)
|
|
141
|
-
* sorted by ID. Since the VariableManager is shared across all premises,
|
|
142
|
-
* this returns every registered variable — not just those referenced by
|
|
143
|
-
* expressions in this premise.
|
|
144
|
-
*/
|
|
145
52
|
getVariables(): TVar[];
|
|
146
53
|
getExpressions(): TExpr[];
|
|
147
54
|
getChildExpressions(parentId: string | null): TExpr[];
|
|
148
|
-
/**
|
|
149
|
-
* Returns `true` if the root expression is an `implies` or `iff` operator,
|
|
150
|
-
* meaning this premise expresses a logical inference relationship.
|
|
151
|
-
*/
|
|
152
55
|
isInference(): boolean;
|
|
153
|
-
/**
|
|
154
|
-
* Returns `true` if this premise does not have an inference operator at its
|
|
155
|
-
* root (i.e. it is a constraint premise). Equivalent to `!isInference()`.
|
|
156
|
-
*/
|
|
157
56
|
isConstraint(): boolean;
|
|
158
57
|
validateEvaluability(): TCoreValidationResult;
|
|
159
|
-
/**
|
|
160
|
-
* Evaluates the premise under a three-valued expression assignment.
|
|
161
|
-
*
|
|
162
|
-
* Variable values are looked up in `assignment.variables` using Kleene
|
|
163
|
-
* three-valued logic (`null` = unknown). Missing variables default to `null`.
|
|
164
|
-
* Expressions listed in `assignment.rejectedExpressionIds` evaluate to
|
|
165
|
-
* `false` and their children are not evaluated.
|
|
166
|
-
*
|
|
167
|
-
* For inference premises (`implies`/`iff`), an `inferenceDiagnostic` is
|
|
168
|
-
* computed with three-valued fields unless the root is rejected.
|
|
169
|
-
*/
|
|
170
58
|
evaluate(assignment: TCoreExpressionAssignment, options?: {
|
|
171
59
|
strictUnknownKeys?: boolean;
|
|
172
60
|
requireExactCoverage?: boolean;
|
|
173
61
|
}): TCorePremiseEvaluationResult;
|
|
174
|
-
/**
|
|
175
|
-
* Returns a human-readable string of this premise's expression tree using
|
|
176
|
-
* standard logical notation (∧ ∨ ¬ → ↔). Missing operands are rendered
|
|
177
|
-
* as `(?)`. Returns an empty string when the premise has no expressions.
|
|
178
|
-
*/
|
|
179
62
|
toDisplayString(): string;
|
|
180
|
-
/**
|
|
181
|
-
* Returns the set of variable IDs referenced by expressions in this premise.
|
|
182
|
-
* Only variables that appear in `type: "variable"` expression nodes are
|
|
183
|
-
* included — not all variables in the shared VariableManager.
|
|
184
|
-
*/
|
|
185
63
|
getReferencedVariableIds(): Set<string>;
|
|
186
|
-
/**
|
|
187
|
-
* Returns a serializable TPremise representation of this premise.
|
|
188
|
-
* Contains only premise identity/metadata and checksum — use
|
|
189
|
-
* getRootExpressionId(), getExpressions(), getReferencedVariableIds()
|
|
190
|
-
* for runtime state.
|
|
191
|
-
*/
|
|
192
64
|
toPremiseData(): TPremise;
|
|
193
|
-
/**
|
|
194
|
-
* Returns a premise-level checksum combining all entity checksums.
|
|
195
|
-
* Computed lazily -- only recalculated when state has changed.
|
|
196
|
-
*/
|
|
197
65
|
checksum(): string;
|
|
198
66
|
private computeChecksum;
|
|
199
|
-
/** Invalidate the cached checksum so the next call recomputes it. */
|
|
200
67
|
markDirty(): void;
|
|
201
68
|
/**
|
|
202
69
|
* Re-reads the single root from ExpressionManager after any operation
|
|
@@ -207,10 +74,9 @@ export declare class PremiseEngine<TArg extends TCoreArgument = TCoreArgument, T
|
|
|
207
74
|
private assertBelongsToArgument;
|
|
208
75
|
private renderExpression;
|
|
209
76
|
private operatorSymbol;
|
|
210
|
-
/** Returns a serializable snapshot of the premise's owned state. */
|
|
211
77
|
snapshot(): TPremiseEngineSnapshot<TPremise, TExpr>;
|
|
212
78
|
/** Creates a new PremiseEngine from a previously captured snapshot. */
|
|
213
|
-
static fromSnapshot<TArg extends TCoreArgument = TCoreArgument, TPremise extends TCorePremise = TCorePremise, TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable>(snapshot: TPremiseEngineSnapshot<TPremise, TExpr>, argument: TOptionalChecksum<TArg>, variables: VariableManager<TVar>, expressionIndex?: Map<string, string
|
|
79
|
+
static fromSnapshot<TArg extends TCoreArgument = TCoreArgument, TPremise extends TCorePremise = TCorePremise, TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable>(snapshot: TPremiseEngineSnapshot<TPremise, TExpr>, argument: TOptionalChecksum<TArg>, variables: VariableManager<TVar>, expressionIndex?: Map<string, string>, sourceManager?: SourceManager): PremiseEngine<TArg, TPremise, TExpr, TVar>;
|
|
214
80
|
private syncExpressionIndex;
|
|
215
81
|
private rebuildVariableIndex;
|
|
216
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"premise-engine.d.ts","sourceRoot":"","sources":["../../../src/lib/core/premise-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"premise-engine.d.ts","sourceRoot":"","sources":["../../../src/lib/core/premise-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { DefaultMap } from "../utils/default-map.js";
|
|
2
3
|
import { sortedCopyById, sortedUnique } from "../utils/collections.js";
|
|
3
4
|
import { kleeneAnd, kleeneIff, kleeneImplies, kleeneNot, kleeneOr, } from "./evaluation/kleene.js";
|
|
@@ -18,6 +19,7 @@ export class PremiseEngine {
|
|
|
18
19
|
checksumDirty = true;
|
|
19
20
|
cachedChecksum;
|
|
20
21
|
expressionIndex;
|
|
22
|
+
sourceManager;
|
|
21
23
|
onMutate;
|
|
22
24
|
constructor(premise, deps, config) {
|
|
23
25
|
this.premise = { ...premise };
|
|
@@ -28,15 +30,11 @@ export class PremiseEngine {
|
|
|
28
30
|
this.expressions = new ExpressionManager(config);
|
|
29
31
|
this.expressionsByVariableId = new DefaultMap(() => new Set());
|
|
30
32
|
this.expressionIndex = deps.expressionIndex;
|
|
33
|
+
this.sourceManager = deps.sourceManager;
|
|
31
34
|
}
|
|
32
35
|
setOnMutate(callback) {
|
|
33
36
|
this.onMutate = callback;
|
|
34
37
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Deletes all expressions that reference the given variable ID,
|
|
37
|
-
* including their subtrees. Operator collapse runs after each removal.
|
|
38
|
-
* Returns all removed expressions in the changeset.
|
|
39
|
-
*/
|
|
40
38
|
deleteExpressionsUsingVariable(variableId) {
|
|
41
39
|
const expressionIds = this.expressionsByVariableId.get(variableId);
|
|
42
40
|
if (expressionIds.size === 0) {
|
|
@@ -62,6 +60,12 @@ export class PremiseEngine {
|
|
|
62
60
|
collector.removedExpression(e);
|
|
63
61
|
}
|
|
64
62
|
}
|
|
63
|
+
if (changes.expressionSourceAssociations) {
|
|
64
|
+
for (const a of changes.expressionSourceAssociations
|
|
65
|
+
.removed) {
|
|
66
|
+
collector.removedExpressionSourceAssociation(a);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
65
69
|
}
|
|
66
70
|
// Expressions in the collector already have checksums attached
|
|
67
71
|
// (from ExpressionManager which stores expressions with checksums).
|
|
@@ -82,21 +86,6 @@ export class PremiseEngine {
|
|
|
82
86
|
throw e;
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Adds an expression to this premise's tree.
|
|
87
|
-
*
|
|
88
|
-
* If the expression has `parentId: null` it becomes the root; only one
|
|
89
|
-
* root is permitted per premise. If `parentId` is non-null the parent
|
|
90
|
-
* must already exist within this premise.
|
|
91
|
-
*
|
|
92
|
-
* All other structural rules (`implies`/`iff` root-only, child limits,
|
|
93
|
-
* position uniqueness) are enforced by the underlying `ExpressionManager`.
|
|
94
|
-
*
|
|
95
|
-
* @throws If the premise already has a root expression and this one is also a root.
|
|
96
|
-
* @throws If the expression's parent does not exist in this premise.
|
|
97
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
98
|
-
* @throws If the expression does not belong to this argument.
|
|
99
|
-
*/
|
|
100
89
|
addExpression(expression) {
|
|
101
90
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
102
91
|
if (expression.type === "variable" &&
|
|
@@ -140,16 +129,6 @@ export class PremiseEngine {
|
|
|
140
129
|
this.expressions.setCollector(null);
|
|
141
130
|
}
|
|
142
131
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Adds an expression as the last child of the given parent, with
|
|
145
|
-
* position computed automatically.
|
|
146
|
-
*
|
|
147
|
-
* If `parentId` is `null`, the expression becomes the root.
|
|
148
|
-
*
|
|
149
|
-
* @throws If the premise already has a root and parentId is null.
|
|
150
|
-
* @throws If the expression does not belong to this argument.
|
|
151
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
152
|
-
*/
|
|
153
132
|
appendExpression(parentId, expression) {
|
|
154
133
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
155
134
|
if (expression.type === "variable" &&
|
|
@@ -191,14 +170,6 @@ export class PremiseEngine {
|
|
|
191
170
|
this.expressions.setCollector(null);
|
|
192
171
|
}
|
|
193
172
|
}
|
|
194
|
-
/**
|
|
195
|
-
* Adds an expression immediately before or after an existing sibling,
|
|
196
|
-
* with position computed automatically.
|
|
197
|
-
*
|
|
198
|
-
* @throws If the sibling does not exist in this premise.
|
|
199
|
-
* @throws If the expression does not belong to this argument.
|
|
200
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
201
|
-
*/
|
|
202
173
|
addExpressionRelative(siblingId, relativePosition, expression) {
|
|
203
174
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
204
175
|
if (expression.type === "variable" &&
|
|
@@ -230,21 +201,6 @@ export class PremiseEngine {
|
|
|
230
201
|
this.expressions.setCollector(null);
|
|
231
202
|
}
|
|
232
203
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Updates mutable fields of an existing expression in this premise.
|
|
235
|
-
*
|
|
236
|
-
* Only `position`, `variableId`, and `operator` may be updated. Structural
|
|
237
|
-
* fields (`id`, `parentId`, `type`, `argumentId`, `argumentVersion`,
|
|
238
|
-
* `checksum`) are forbidden — enforced by the underlying
|
|
239
|
-
* `ExpressionManager`.
|
|
240
|
-
*
|
|
241
|
-
* If `variableId` changes, the internal `expressionsByVariableId` index is
|
|
242
|
-
* updated so that cascade deletion (`deleteExpressionsUsingVariable`) stays
|
|
243
|
-
* correct.
|
|
244
|
-
*
|
|
245
|
-
* @throws If the expression does not exist in this premise.
|
|
246
|
-
* @throws If `variableId` references a non-existent variable.
|
|
247
|
-
*/
|
|
248
204
|
updateExpression(expressionId, updates) {
|
|
249
205
|
const existing = this.expressions.getExpression(expressionId);
|
|
250
206
|
if (!existing) {
|
|
@@ -285,15 +241,6 @@ export class PremiseEngine {
|
|
|
285
241
|
this.expressions.setCollector(null);
|
|
286
242
|
}
|
|
287
243
|
}
|
|
288
|
-
/**
|
|
289
|
-
* Removes an expression and its entire descendant subtree, then collapses
|
|
290
|
-
* any ancestor operators with fewer than two children (same semantics as
|
|
291
|
-
* before). Returns the removed root expression, or `undefined` if not
|
|
292
|
-
* found.
|
|
293
|
-
*
|
|
294
|
-
* `rootExpressionId` is recomputed after every removal because operator
|
|
295
|
-
* collapse can silently promote a new expression into the root slot.
|
|
296
|
-
*/
|
|
297
244
|
removeExpression(expressionId, deleteSubtree) {
|
|
298
245
|
// Snapshot the expression before removal (for result).
|
|
299
246
|
const snapshot = this.expressions.getExpression(expressionId);
|
|
@@ -332,6 +279,18 @@ export class PremiseEngine {
|
|
|
332
279
|
}
|
|
333
280
|
this.syncRootExpressionId();
|
|
334
281
|
this.markDirty();
|
|
282
|
+
// Cascade: remove source associations for all removed expressions
|
|
283
|
+
if (this.sourceManager) {
|
|
284
|
+
const removedExprs = collector.toChangeset().expressions;
|
|
285
|
+
if (removedExprs) {
|
|
286
|
+
for (const expr of removedExprs.removed) {
|
|
287
|
+
const sourceResult = this.sourceManager.removeAssociationsForExpression(expr.id);
|
|
288
|
+
for (const assoc of sourceResult.removedExpressionAssociations) {
|
|
289
|
+
collector.removedExpressionSourceAssociation(assoc);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
335
294
|
const changes = collector.toChangeset();
|
|
336
295
|
this.syncExpressionIndex(changes);
|
|
337
296
|
this.onMutate?.();
|
|
@@ -344,20 +303,6 @@ export class PremiseEngine {
|
|
|
344
303
|
this.expressions.setCollector(null);
|
|
345
304
|
}
|
|
346
305
|
}
|
|
347
|
-
/**
|
|
348
|
-
* Splices a new expression between existing nodes in the tree. The new
|
|
349
|
-
* expression inherits the tree slot of the anchor node
|
|
350
|
-
* (`leftNodeId ?? rightNodeId`).
|
|
351
|
-
*
|
|
352
|
-
* `rootExpressionId` is recomputed after every insertion because the
|
|
353
|
-
* anchor may have been the root.
|
|
354
|
-
*
|
|
355
|
-
* See `ArgumentEngine.insertExpression` for the full contract; the same
|
|
356
|
-
* rules apply here.
|
|
357
|
-
*
|
|
358
|
-
* @throws If the expression does not belong to this argument.
|
|
359
|
-
* @throws If the expression is a variable reference and the variable has not been registered.
|
|
360
|
-
*/
|
|
361
306
|
insertExpression(expression, leftNodeId, rightNodeId) {
|
|
362
307
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
363
308
|
if (expression.type === "variable" &&
|
|
@@ -387,20 +332,6 @@ export class PremiseEngine {
|
|
|
387
332
|
this.expressions.setCollector(null);
|
|
388
333
|
}
|
|
389
334
|
}
|
|
390
|
-
/**
|
|
391
|
-
* Wraps an existing expression with a new operator and a new sibling
|
|
392
|
-
* expression in a single atomic operation.
|
|
393
|
-
*
|
|
394
|
-
* The operator takes the existing node's slot in the tree. Both the
|
|
395
|
-
* existing node and the new sibling become children of the operator.
|
|
396
|
-
*
|
|
397
|
-
* Exactly one of `leftNodeId` / `rightNodeId` must be provided — it
|
|
398
|
-
* identifies the existing node and which child slot it occupies.
|
|
399
|
-
* The new sibling fills the other slot.
|
|
400
|
-
*
|
|
401
|
-
* @throws If the expression does not belong to this argument.
|
|
402
|
-
* @throws If the new sibling is a variable reference and the variable has not been registered.
|
|
403
|
-
*/
|
|
404
335
|
wrapExpression(operator, newSibling, leftNodeId, rightNodeId) {
|
|
405
336
|
this.assertBelongsToArgument(operator.argumentId, operator.argumentVersion);
|
|
406
337
|
this.assertBelongsToArgument(newSibling.argumentId, newSibling.argumentVersion);
|
|
@@ -431,10 +362,65 @@ export class PremiseEngine {
|
|
|
431
362
|
this.expressions.setCollector(null);
|
|
432
363
|
}
|
|
433
364
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
365
|
+
// -------------------------------------------------------------------------
|
|
366
|
+
// Source association convenience methods
|
|
367
|
+
// -------------------------------------------------------------------------
|
|
368
|
+
addExpressionSourceAssociation(sourceId, sourceVersion, expressionId) {
|
|
369
|
+
if (!this.sourceManager) {
|
|
370
|
+
throw new Error("No SourceManager available.");
|
|
371
|
+
}
|
|
372
|
+
if (!this.expressions.getExpression(expressionId)) {
|
|
373
|
+
throw new Error(`Expression "${expressionId}" does not exist in premise "${this.premise.id}".`);
|
|
374
|
+
}
|
|
375
|
+
const assoc = {
|
|
376
|
+
id: randomUUID(),
|
|
377
|
+
sourceId,
|
|
378
|
+
sourceVersion,
|
|
379
|
+
expressionId,
|
|
380
|
+
premiseId: this.premise.id,
|
|
381
|
+
argumentId: this.argument.id,
|
|
382
|
+
argumentVersion: this.argument.version,
|
|
383
|
+
checksum: "",
|
|
384
|
+
};
|
|
385
|
+
const fields = this.checksumConfig?.expressionSourceAssociationFields ??
|
|
386
|
+
DEFAULT_CHECKSUM_CONFIG.expressionSourceAssociationFields;
|
|
387
|
+
const assocWithChecksum = {
|
|
388
|
+
...assoc,
|
|
389
|
+
checksum: entityChecksum(assoc, fields),
|
|
390
|
+
};
|
|
391
|
+
this.sourceManager.addExpressionSourceAssociation(assocWithChecksum);
|
|
392
|
+
const collector = new ChangeCollector();
|
|
393
|
+
collector.addedExpressionSourceAssociation(assocWithChecksum);
|
|
394
|
+
this.markDirty();
|
|
395
|
+
this.onMutate?.();
|
|
396
|
+
return { result: assocWithChecksum, changes: collector.toChangeset() };
|
|
397
|
+
}
|
|
398
|
+
removeExpressionSourceAssociation(associationId) {
|
|
399
|
+
if (!this.sourceManager) {
|
|
400
|
+
return { result: undefined, changes: {} };
|
|
401
|
+
}
|
|
402
|
+
const allExprAssocs = this.sourceManager.getAllExpressionSourceAssociations();
|
|
403
|
+
if (!allExprAssocs.some((a) => a.id === associationId)) {
|
|
404
|
+
return { result: undefined, changes: {} };
|
|
405
|
+
}
|
|
406
|
+
const removalResult = this.sourceManager.removeExpressionSourceAssociation(associationId);
|
|
407
|
+
const collector = new ChangeCollector();
|
|
408
|
+
for (const assoc of removalResult.removedExpressionAssociations) {
|
|
409
|
+
collector.removedExpressionSourceAssociation(assoc);
|
|
410
|
+
}
|
|
411
|
+
this.markDirty();
|
|
412
|
+
this.onMutate?.();
|
|
413
|
+
return {
|
|
414
|
+
result: removalResult.removedExpressionAssociations[0],
|
|
415
|
+
changes: collector.toChangeset(),
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
getSourceAssociationsForExpression(expressionId) {
|
|
419
|
+
if (!this.sourceManager) {
|
|
420
|
+
return [];
|
|
421
|
+
}
|
|
422
|
+
return this.sourceManager.getAssociationsForExpression(expressionId);
|
|
423
|
+
}
|
|
438
424
|
getExpression(id) {
|
|
439
425
|
return this.expressions.getExpression(id);
|
|
440
426
|
}
|
|
@@ -469,12 +455,6 @@ export class PremiseEngine {
|
|
|
469
455
|
}
|
|
470
456
|
return this.expressions.getExpression(this.rootExpressionId);
|
|
471
457
|
}
|
|
472
|
-
/**
|
|
473
|
-
* Returns all argument-level variables (from the shared VariableManager)
|
|
474
|
-
* sorted by ID. Since the VariableManager is shared across all premises,
|
|
475
|
-
* this returns every registered variable — not just those referenced by
|
|
476
|
-
* expressions in this premise.
|
|
477
|
-
*/
|
|
478
458
|
getVariables() {
|
|
479
459
|
return sortedCopyById(this.variables.toArray());
|
|
480
460
|
}
|
|
@@ -484,19 +464,11 @@ export class PremiseEngine {
|
|
|
484
464
|
getChildExpressions(parentId) {
|
|
485
465
|
return this.expressions.getChildExpressions(parentId);
|
|
486
466
|
}
|
|
487
|
-
/**
|
|
488
|
-
* Returns `true` if the root expression is an `implies` or `iff` operator,
|
|
489
|
-
* meaning this premise expresses a logical inference relationship.
|
|
490
|
-
*/
|
|
491
467
|
isInference() {
|
|
492
468
|
const root = this.getRootExpression();
|
|
493
469
|
return (root?.type === "operator" &&
|
|
494
470
|
(root.operator === "implies" || root.operator === "iff"));
|
|
495
471
|
}
|
|
496
|
-
/**
|
|
497
|
-
* Returns `true` if this premise does not have an inference operator at its
|
|
498
|
-
* root (i.e. it is a constraint premise). Equivalent to `!isInference()`.
|
|
499
|
-
*/
|
|
500
472
|
isConstraint() {
|
|
501
473
|
return !this.isInference();
|
|
502
474
|
}
|
|
@@ -607,17 +579,6 @@ export class PremiseEngine {
|
|
|
607
579
|
}
|
|
608
580
|
return makeValidationResult(issues);
|
|
609
581
|
}
|
|
610
|
-
/**
|
|
611
|
-
* Evaluates the premise under a three-valued expression assignment.
|
|
612
|
-
*
|
|
613
|
-
* Variable values are looked up in `assignment.variables` using Kleene
|
|
614
|
-
* three-valued logic (`null` = unknown). Missing variables default to `null`.
|
|
615
|
-
* Expressions listed in `assignment.rejectedExpressionIds` evaluate to
|
|
616
|
-
* `false` and their children are not evaluated.
|
|
617
|
-
*
|
|
618
|
-
* For inference premises (`implies`/`iff`), an `inferenceDiagnostic` is
|
|
619
|
-
* computed with three-valued fields unless the root is rejected.
|
|
620
|
-
*/
|
|
621
582
|
evaluate(assignment, options) {
|
|
622
583
|
const validation = this.validateEvaluability();
|
|
623
584
|
if (!validation.ok) {
|
|
@@ -746,22 +707,12 @@ export class PremiseEngine {
|
|
|
746
707
|
inferenceDiagnostic,
|
|
747
708
|
};
|
|
748
709
|
}
|
|
749
|
-
/**
|
|
750
|
-
* Returns a human-readable string of this premise's expression tree using
|
|
751
|
-
* standard logical notation (∧ ∨ ¬ → ↔). Missing operands are rendered
|
|
752
|
-
* as `(?)`. Returns an empty string when the premise has no expressions.
|
|
753
|
-
*/
|
|
754
710
|
toDisplayString() {
|
|
755
711
|
if (this.rootExpressionId === undefined) {
|
|
756
712
|
return "";
|
|
757
713
|
}
|
|
758
714
|
return this.renderExpression(this.rootExpressionId);
|
|
759
715
|
}
|
|
760
|
-
/**
|
|
761
|
-
* Returns the set of variable IDs referenced by expressions in this premise.
|
|
762
|
-
* Only variables that appear in `type: "variable"` expression nodes are
|
|
763
|
-
* included — not all variables in the shared VariableManager.
|
|
764
|
-
*/
|
|
765
716
|
getReferencedVariableIds() {
|
|
766
717
|
const ids = new Set();
|
|
767
718
|
for (const expr of this.expressions.toArray()) {
|
|
@@ -771,22 +722,12 @@ export class PremiseEngine {
|
|
|
771
722
|
}
|
|
772
723
|
return ids;
|
|
773
724
|
}
|
|
774
|
-
/**
|
|
775
|
-
* Returns a serializable TPremise representation of this premise.
|
|
776
|
-
* Contains only premise identity/metadata and checksum — use
|
|
777
|
-
* getRootExpressionId(), getExpressions(), getReferencedVariableIds()
|
|
778
|
-
* for runtime state.
|
|
779
|
-
*/
|
|
780
725
|
toPremiseData() {
|
|
781
726
|
return {
|
|
782
727
|
...this.premise,
|
|
783
728
|
checksum: this.checksum(),
|
|
784
729
|
};
|
|
785
730
|
}
|
|
786
|
-
/**
|
|
787
|
-
* Returns a premise-level checksum combining all entity checksums.
|
|
788
|
-
* Computed lazily -- only recalculated when state has changed.
|
|
789
|
-
*/
|
|
790
731
|
checksum() {
|
|
791
732
|
if (this.checksumDirty || this.cachedChecksum === undefined) {
|
|
792
733
|
this.cachedChecksum = this.computeChecksum();
|
|
@@ -809,7 +750,6 @@ export class PremiseEngine {
|
|
|
809
750
|
}
|
|
810
751
|
return computeHash(canonicalSerialize(checksumMap));
|
|
811
752
|
}
|
|
812
|
-
/** Invalidate the cached checksum so the next call recomputes it. */
|
|
813
753
|
markDirty() {
|
|
814
754
|
this.checksumDirty = true;
|
|
815
755
|
}
|
|
@@ -890,7 +830,6 @@ export class PremiseEngine {
|
|
|
890
830
|
return "¬";
|
|
891
831
|
}
|
|
892
832
|
}
|
|
893
|
-
/** Returns a serializable snapshot of the premise's owned state. */
|
|
894
833
|
snapshot() {
|
|
895
834
|
const exprSnapshot = this.expressions.snapshot();
|
|
896
835
|
return {
|
|
@@ -904,8 +843,8 @@ export class PremiseEngine {
|
|
|
904
843
|
};
|
|
905
844
|
}
|
|
906
845
|
/** Creates a new PremiseEngine from a previously captured snapshot. */
|
|
907
|
-
static fromSnapshot(snapshot, argument, variables, expressionIndex) {
|
|
908
|
-
const pe = new PremiseEngine(snapshot.premise, { argument, variables, expressionIndex }, snapshot.config);
|
|
846
|
+
static fromSnapshot(snapshot, argument, variables, expressionIndex, sourceManager) {
|
|
847
|
+
const pe = new PremiseEngine(snapshot.premise, { argument, variables, expressionIndex, sourceManager }, snapshot.config);
|
|
909
848
|
// Restore expressions from the snapshot
|
|
910
849
|
pe.expressions = ExpressionManager.fromSnapshot(snapshot.expressions);
|
|
911
850
|
// Restore rootExpressionId from snapshot
|