@polintpro/proposit-core 0.3.0 → 0.4.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 +175 -0
- package/dist/cli/commands/sources.js.map +1 -0
- 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 +39 -1
- package/dist/cli/engine.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 +19 -0
- package/dist/lib/consts.js.map +1 -1
- package/dist/lib/core/argument-engine.d.ts +42 -134
- package/dist/lib/core/argument-engine.d.ts.map +1 -1
- package/dist/lib/core/argument-engine.js +299 -116
- package/dist/lib/core/argument-engine.js.map +1 -1
- package/dist/lib/core/change-collector.d.ts +12 -2
- package/dist/lib/core/change-collector.d.ts.map +1 -1
- package/dist/lib/core/change-collector.js +27 -0
- package/dist/lib/core/change-collector.js.map +1 -1
- package/dist/lib/core/diff.d.ts +8 -2
- package/dist/lib/core/diff.d.ts.map +1 -1
- package/dist/lib/core/diff.js +58 -0
- package/dist/lib/core/diff.js.map +1 -1
- package/dist/lib/core/interfaces/argument-engine.interfaces.d.ts +334 -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 +5 -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/premise-engine.interfaces.d.ts +317 -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 +110 -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 +19 -153
- package/dist/lib/core/premise-engine.d.ts.map +1 -1
- package/dist/lib/core/premise-engine.js +95 -143
- package/dist/lib/core/premise-engine.js.map +1 -1
- package/dist/lib/core/source-manager.d.ts +109 -0
- package/dist/lib/core/source-manager.d.ts.map +1 -0
- package/dist/lib/core/source-manager.js +420 -0
- package/dist/lib/core/source-manager.js.map +1 -0
- package/dist/lib/index.d.ts +4 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +2 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/schemata/index.d.ts +1 -0
- package/dist/lib/schemata/index.d.ts.map +1 -1
- package/dist/lib/schemata/index.js +1 -0
- package/dist/lib/schemata/index.js.map +1 -1
- package/dist/lib/schemata/source.d.ts +28 -0
- package/dist/lib/schemata/source.d.ts.map +1 -0
- package/dist/lib/schemata/source.js +35 -0
- package/dist/lib/schemata/source.js.map +1 -0
- package/dist/lib/types/checksum.d.ts +6 -0
- package/dist/lib/types/checksum.d.ts.map +1 -1
- package/dist/lib/types/diff.d.ts +9 -3
- 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 +7 -3
- package/dist/lib/types/mutation.d.ts.map +1 -1
- package/dist/lib/types/reactive.d.ts +5 -2
- 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, TCoreSource, 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, TSource extends TCoreSource = TCoreSource> implements TExpressionMutations<TArg, TPremise, TExpr, TVar, TSource>, TExpressionQueries<TExpr>, TVariableReferences<TArg, TPremise, TExpr, TVar, TSource>, TPremiseClassification, TPremiseEvaluation, TPremiseLifecycle<TPremise, TExpr>, TPremiseIdentity<TArg, TPremise, TExpr, TVar, TSource>, 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<TSource>;
|
|
29
33
|
}, config?: TLogicEngineOptions);
|
|
30
34
|
setOnMutate(callback: (() => void) | undefined): void;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
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
|
-
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
|
-
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
|
-
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
|
-
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
|
-
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
|
-
wrapExpression(operator: TExpressionWithoutPosition<TExpr>, newSibling: TExpressionWithoutPosition<TExpr>, leftNodeId?: string, rightNodeId?: string): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg>;
|
|
129
|
-
/**
|
|
130
|
-
* Returns an expression by ID, or `undefined` if not found in this
|
|
131
|
-
* premise.
|
|
132
|
-
*/
|
|
35
|
+
deleteExpressionsUsingVariable(variableId: string): TCoreMutationResult<TExpr[], TExpr, TVar, TPremise, TArg, TSource>;
|
|
36
|
+
addExpression(expression: TExpressionInput<TExpr>): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg, TSource>;
|
|
37
|
+
appendExpression(parentId: string | null, expression: TExpressionWithoutPosition<TExpr>): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg, TSource>;
|
|
38
|
+
addExpressionRelative(siblingId: string, relativePosition: "before" | "after", expression: TExpressionWithoutPosition<TExpr>): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg, TSource>;
|
|
39
|
+
updateExpression(expressionId: string, updates: TExpressionUpdate): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg, TSource>;
|
|
40
|
+
removeExpression(expressionId: string, deleteSubtree: boolean): TCoreMutationResult<TExpr | undefined, TExpr, TVar, TPremise, TArg, TSource>;
|
|
41
|
+
insertExpression(expression: TExpressionInput<TExpr>, leftNodeId?: string, rightNodeId?: string): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg, TSource>;
|
|
42
|
+
wrapExpression(operator: TExpressionWithoutPosition<TExpr>, newSibling: TExpressionWithoutPosition<TExpr>, leftNodeId?: string, rightNodeId?: string): TCoreMutationResult<TExpr, TExpr, TVar, TPremise, TArg, TSource>;
|
|
43
|
+
addExpressionSourceAssociation(sourceId: string, expressionId: string): TCoreMutationResult<TCoreExpressionSourceAssociation, TExpr, TVar, TPremise, TArg, TSource>;
|
|
44
|
+
removeExpressionSourceAssociation(associationId: string): TCoreMutationResult<TCoreExpressionSourceAssociation | undefined, TExpr, TVar, TPremise, TArg, TSource>;
|
|
45
|
+
getSourceAssociationsForExpression(expressionId: string): TCoreExpressionSourceAssociation[];
|
|
133
46
|
getExpression(id: string): TExpr | undefined;
|
|
134
47
|
getId(): string;
|
|
135
48
|
getExtras(): Record<string, unknown>;
|
|
136
|
-
setExtras(extras: Record<string, unknown>): TCoreMutationResult<Record<string, unknown>, TExpr, TVar, TPremise, TArg>;
|
|
49
|
+
setExtras(extras: Record<string, unknown>): TCoreMutationResult<Record<string, unknown>, TExpr, TVar, TPremise, TArg, TSource>;
|
|
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>): PremiseEngine<TArg, TPremise, TExpr, TVar>;
|
|
79
|
+
static fromSnapshot<TArg extends TCoreArgument = TCoreArgument, TPremise extends TCorePremise = TCorePremise, TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable, TSource extends TCoreSource = TCoreSource>(snapshot: TPremiseEngineSnapshot<TPremise, TExpr>, argument: TOptionalChecksum<TArg>, variables: VariableManager<TVar>, expressionIndex?: Map<string, string>, sourceManager?: SourceManager<TSource>): PremiseEngine<TArg, TPremise, TExpr, TVar, TSource>;
|
|
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,17 @@ 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
|
+
}
|
|
69
|
+
if (changes.sources) {
|
|
70
|
+
for (const s of changes.sources.removed) {
|
|
71
|
+
collector.removedSource(s);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
65
74
|
}
|
|
66
75
|
// Expressions in the collector already have checksums attached
|
|
67
76
|
// (from ExpressionManager which stores expressions with checksums).
|
|
@@ -82,21 +91,6 @@ export class PremiseEngine {
|
|
|
82
91
|
throw e;
|
|
83
92
|
}
|
|
84
93
|
}
|
|
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
94
|
addExpression(expression) {
|
|
101
95
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
102
96
|
if (expression.type === "variable" &&
|
|
@@ -140,16 +134,6 @@ export class PremiseEngine {
|
|
|
140
134
|
this.expressions.setCollector(null);
|
|
141
135
|
}
|
|
142
136
|
}
|
|
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
137
|
appendExpression(parentId, expression) {
|
|
154
138
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
155
139
|
if (expression.type === "variable" &&
|
|
@@ -191,14 +175,6 @@ export class PremiseEngine {
|
|
|
191
175
|
this.expressions.setCollector(null);
|
|
192
176
|
}
|
|
193
177
|
}
|
|
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
178
|
addExpressionRelative(siblingId, relativePosition, expression) {
|
|
203
179
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
204
180
|
if (expression.type === "variable" &&
|
|
@@ -230,21 +206,6 @@ export class PremiseEngine {
|
|
|
230
206
|
this.expressions.setCollector(null);
|
|
231
207
|
}
|
|
232
208
|
}
|
|
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
209
|
updateExpression(expressionId, updates) {
|
|
249
210
|
const existing = this.expressions.getExpression(expressionId);
|
|
250
211
|
if (!existing) {
|
|
@@ -285,15 +246,6 @@ export class PremiseEngine {
|
|
|
285
246
|
this.expressions.setCollector(null);
|
|
286
247
|
}
|
|
287
248
|
}
|
|
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
249
|
removeExpression(expressionId, deleteSubtree) {
|
|
298
250
|
// Snapshot the expression before removal (for result).
|
|
299
251
|
const snapshot = this.expressions.getExpression(expressionId);
|
|
@@ -332,6 +284,21 @@ export class PremiseEngine {
|
|
|
332
284
|
}
|
|
333
285
|
this.syncRootExpressionId();
|
|
334
286
|
this.markDirty();
|
|
287
|
+
// Cascade: remove source associations for all removed expressions
|
|
288
|
+
if (this.sourceManager) {
|
|
289
|
+
const removedExprs = collector.toChangeset().expressions;
|
|
290
|
+
if (removedExprs) {
|
|
291
|
+
for (const expr of removedExprs.removed) {
|
|
292
|
+
const sourceResult = this.sourceManager.removeAssociationsForExpression(expr.id);
|
|
293
|
+
for (const assoc of sourceResult.removedExpressionAssociations) {
|
|
294
|
+
collector.removedExpressionSourceAssociation(assoc);
|
|
295
|
+
}
|
|
296
|
+
for (const orphan of sourceResult.removedOrphanSources) {
|
|
297
|
+
collector.removedSource(orphan);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
335
302
|
const changes = collector.toChangeset();
|
|
336
303
|
this.syncExpressionIndex(changes);
|
|
337
304
|
this.onMutate?.();
|
|
@@ -344,20 +311,6 @@ export class PremiseEngine {
|
|
|
344
311
|
this.expressions.setCollector(null);
|
|
345
312
|
}
|
|
346
313
|
}
|
|
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
314
|
insertExpression(expression, leftNodeId, rightNodeId) {
|
|
362
315
|
this.assertBelongsToArgument(expression.argumentId, expression.argumentVersion);
|
|
363
316
|
if (expression.type === "variable" &&
|
|
@@ -387,20 +340,6 @@ export class PremiseEngine {
|
|
|
387
340
|
this.expressions.setCollector(null);
|
|
388
341
|
}
|
|
389
342
|
}
|
|
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
343
|
wrapExpression(operator, newSibling, leftNodeId, rightNodeId) {
|
|
405
344
|
this.assertBelongsToArgument(operator.argumentId, operator.argumentVersion);
|
|
406
345
|
this.assertBelongsToArgument(newSibling.argumentId, newSibling.argumentVersion);
|
|
@@ -431,10 +370,70 @@ export class PremiseEngine {
|
|
|
431
370
|
this.expressions.setCollector(null);
|
|
432
371
|
}
|
|
433
372
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
373
|
+
// -------------------------------------------------------------------------
|
|
374
|
+
// Source association convenience methods
|
|
375
|
+
// -------------------------------------------------------------------------
|
|
376
|
+
addExpressionSourceAssociation(sourceId, expressionId) {
|
|
377
|
+
if (!this.sourceManager) {
|
|
378
|
+
throw new Error("No SourceManager available.");
|
|
379
|
+
}
|
|
380
|
+
if (!this.sourceManager.getSource(sourceId)) {
|
|
381
|
+
throw new Error(`Source "${sourceId}" does not exist.`);
|
|
382
|
+
}
|
|
383
|
+
if (!this.expressions.getExpression(expressionId)) {
|
|
384
|
+
throw new Error(`Expression "${expressionId}" does not exist in premise "${this.premise.id}".`);
|
|
385
|
+
}
|
|
386
|
+
const assoc = {
|
|
387
|
+
id: randomUUID(),
|
|
388
|
+
sourceId,
|
|
389
|
+
expressionId,
|
|
390
|
+
premiseId: this.premise.id,
|
|
391
|
+
argumentId: this.argument.id,
|
|
392
|
+
argumentVersion: this.argument.version,
|
|
393
|
+
checksum: "",
|
|
394
|
+
};
|
|
395
|
+
const fields = this.checksumConfig?.expressionSourceAssociationFields ??
|
|
396
|
+
DEFAULT_CHECKSUM_CONFIG.expressionSourceAssociationFields;
|
|
397
|
+
const assocWithChecksum = {
|
|
398
|
+
...assoc,
|
|
399
|
+
checksum: entityChecksum(assoc, fields),
|
|
400
|
+
};
|
|
401
|
+
this.sourceManager.addExpressionSourceAssociation(assocWithChecksum);
|
|
402
|
+
const collector = new ChangeCollector();
|
|
403
|
+
collector.addedExpressionSourceAssociation(assocWithChecksum);
|
|
404
|
+
this.markDirty();
|
|
405
|
+
this.onMutate?.();
|
|
406
|
+
return { result: assocWithChecksum, changes: collector.toChangeset() };
|
|
407
|
+
}
|
|
408
|
+
removeExpressionSourceAssociation(associationId) {
|
|
409
|
+
if (!this.sourceManager) {
|
|
410
|
+
return { result: undefined, changes: {} };
|
|
411
|
+
}
|
|
412
|
+
const allExprAssocs = this.sourceManager.getAllExpressionSourceAssociations();
|
|
413
|
+
if (!allExprAssocs.some((a) => a.id === associationId)) {
|
|
414
|
+
return { result: undefined, changes: {} };
|
|
415
|
+
}
|
|
416
|
+
const removalResult = this.sourceManager.removeExpressionSourceAssociation(associationId);
|
|
417
|
+
const collector = new ChangeCollector();
|
|
418
|
+
for (const assoc of removalResult.removedExpressionAssociations) {
|
|
419
|
+
collector.removedExpressionSourceAssociation(assoc);
|
|
420
|
+
}
|
|
421
|
+
for (const orphan of removalResult.removedOrphanSources) {
|
|
422
|
+
collector.removedSource(orphan);
|
|
423
|
+
}
|
|
424
|
+
this.markDirty();
|
|
425
|
+
this.onMutate?.();
|
|
426
|
+
return {
|
|
427
|
+
result: removalResult.removedExpressionAssociations[0],
|
|
428
|
+
changes: collector.toChangeset(),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
getSourceAssociationsForExpression(expressionId) {
|
|
432
|
+
if (!this.sourceManager) {
|
|
433
|
+
return [];
|
|
434
|
+
}
|
|
435
|
+
return this.sourceManager.getAssociationsForExpression(expressionId);
|
|
436
|
+
}
|
|
438
437
|
getExpression(id) {
|
|
439
438
|
return this.expressions.getExpression(id);
|
|
440
439
|
}
|
|
@@ -469,12 +468,6 @@ export class PremiseEngine {
|
|
|
469
468
|
}
|
|
470
469
|
return this.expressions.getExpression(this.rootExpressionId);
|
|
471
470
|
}
|
|
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
471
|
getVariables() {
|
|
479
472
|
return sortedCopyById(this.variables.toArray());
|
|
480
473
|
}
|
|
@@ -484,19 +477,11 @@ export class PremiseEngine {
|
|
|
484
477
|
getChildExpressions(parentId) {
|
|
485
478
|
return this.expressions.getChildExpressions(parentId);
|
|
486
479
|
}
|
|
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
480
|
isInference() {
|
|
492
481
|
const root = this.getRootExpression();
|
|
493
482
|
return (root?.type === "operator" &&
|
|
494
483
|
(root.operator === "implies" || root.operator === "iff"));
|
|
495
484
|
}
|
|
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
485
|
isConstraint() {
|
|
501
486
|
return !this.isInference();
|
|
502
487
|
}
|
|
@@ -607,17 +592,6 @@ export class PremiseEngine {
|
|
|
607
592
|
}
|
|
608
593
|
return makeValidationResult(issues);
|
|
609
594
|
}
|
|
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
595
|
evaluate(assignment, options) {
|
|
622
596
|
const validation = this.validateEvaluability();
|
|
623
597
|
if (!validation.ok) {
|
|
@@ -746,22 +720,12 @@ export class PremiseEngine {
|
|
|
746
720
|
inferenceDiagnostic,
|
|
747
721
|
};
|
|
748
722
|
}
|
|
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
723
|
toDisplayString() {
|
|
755
724
|
if (this.rootExpressionId === undefined) {
|
|
756
725
|
return "";
|
|
757
726
|
}
|
|
758
727
|
return this.renderExpression(this.rootExpressionId);
|
|
759
728
|
}
|
|
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
729
|
getReferencedVariableIds() {
|
|
766
730
|
const ids = new Set();
|
|
767
731
|
for (const expr of this.expressions.toArray()) {
|
|
@@ -771,22 +735,12 @@ export class PremiseEngine {
|
|
|
771
735
|
}
|
|
772
736
|
return ids;
|
|
773
737
|
}
|
|
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
738
|
toPremiseData() {
|
|
781
739
|
return {
|
|
782
740
|
...this.premise,
|
|
783
741
|
checksum: this.checksum(),
|
|
784
742
|
};
|
|
785
743
|
}
|
|
786
|
-
/**
|
|
787
|
-
* Returns a premise-level checksum combining all entity checksums.
|
|
788
|
-
* Computed lazily -- only recalculated when state has changed.
|
|
789
|
-
*/
|
|
790
744
|
checksum() {
|
|
791
745
|
if (this.checksumDirty || this.cachedChecksum === undefined) {
|
|
792
746
|
this.cachedChecksum = this.computeChecksum();
|
|
@@ -809,7 +763,6 @@ export class PremiseEngine {
|
|
|
809
763
|
}
|
|
810
764
|
return computeHash(canonicalSerialize(checksumMap));
|
|
811
765
|
}
|
|
812
|
-
/** Invalidate the cached checksum so the next call recomputes it. */
|
|
813
766
|
markDirty() {
|
|
814
767
|
this.checksumDirty = true;
|
|
815
768
|
}
|
|
@@ -890,7 +843,6 @@ export class PremiseEngine {
|
|
|
890
843
|
return "¬";
|
|
891
844
|
}
|
|
892
845
|
}
|
|
893
|
-
/** Returns a serializable snapshot of the premise's owned state. */
|
|
894
846
|
snapshot() {
|
|
895
847
|
const exprSnapshot = this.expressions.snapshot();
|
|
896
848
|
return {
|
|
@@ -904,8 +856,8 @@ export class PremiseEngine {
|
|
|
904
856
|
};
|
|
905
857
|
}
|
|
906
858
|
/** 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);
|
|
859
|
+
static fromSnapshot(snapshot, argument, variables, expressionIndex, sourceManager) {
|
|
860
|
+
const pe = new PremiseEngine(snapshot.premise, { argument, variables, expressionIndex, sourceManager }, snapshot.config);
|
|
909
861
|
// Restore expressions from the snapshot
|
|
910
862
|
pe.expressions = ExpressionManager.fromSnapshot(snapshot.expressions);
|
|
911
863
|
// Restore rootExpressionId from snapshot
|