Type Parameters
- TExpr extends TCorePropositionalExpression = TCorePropositionalExpression
- TVar extends
| {
argumentId: string;
argumentVersion: number;
checksum: string;
claimId: string;
claimVersion: number;
id: string;
symbol: string;
}
| {
argumentId: string;
argumentVersion: number;
boundArgumentId: string;
boundArgumentVersion: number;
boundPremiseId: string;
checksum: string;
id: string;
symbol: string;
}
| {
argumentId: string;
argumentVersion: number;
boundArgumentId: string;
boundArgumentVersion: number;
boundAspect: "statement"
| "inference";
boundExpressionId: string;
checksum: string;
id: string;
symbol: string;
} =
| {
argumentId: string;
argumentVersion: number;
checksum: string;
claimId: string;
claimVersion: number;
id: string;
symbol: string;
}
| {
argumentId: string;
argumentVersion: number;
boundArgumentId: string;
boundArgumentVersion: number;
boundPremiseId: string;
checksum: string;
id: string;
symbol: string;
}
| {
argumentId: string;
argumentVersion: number;
boundArgumentId: string;
boundArgumentVersion: number;
boundAspect: "statement"
| "inference";
boundExpressionId: string;
checksum: string;
id: string;
symbol: string;
} - TPremise extends
| {
argumentId: string;
argumentVersion: number;
checksum: string;
combinedChecksum: string;
descendantChecksum: string
| null;
id: string;
type: "freeform";
}
| {
argumentId: string;
argumentVersion: number;
checksum: string;
combinedChecksum: string;
derivedClaimId: string;
descendantChecksum: string
| null;
id: string;
type: "derivation";
} =
| {
argumentId: string;
argumentVersion: number;
checksum: string;
combinedChecksum: string;
descendantChecksum: string
| null;
id: string;
type: "freeform";
}
| {
argumentId: string;
argumentVersion: number;
checksum: string;
combinedChecksum: string;
derivedClaimId: string;
descendantChecksum: string
| null;
id: string;
type: "derivation";
} - TArg extends {
checksum: string;
combinedChecksum: string;
descendantChecksum: string | null;
id: string;
respondsTo?: { argumentId: string; argumentVersion: number };
version: number;
} = {
checksum: string;
combinedChecksum: string;
descendantChecksum: string | null;
id: string;
respondsTo?: { argumentId: string; argumentVersion: number };
version: number;
}
A flat array of TOrderedOperation entries in FK-safe
execution order. Returns an empty array if the changeset is empty.
Converts a changeset into a flat, ordered array of persistence operations that is safe to execute sequentially against a relational store with foreign-key constraints.
The FK dependency chain is:
expression.premiseId→premise.idexpression.variableId→variable.id(for variable-type expressions)expression.parentId→expression.id(self-FK for tree structure)variable.boundPremiseId→premise.id(for premise-bound variables)variable.argumentId→argument.idpremise.argumentId→argument.idThe resulting order guarantees that every referenced row exists before any row that depends on it is inserted, and that every dependent row is removed before the row it references is deleted.
It does so without knowing what the store holds. A removed expression's entry carries its parent at removal time, and a change in the same changeset may have moved it first, so the stored row can still point at a different parent. Every removed expression is therefore detached before any expression is deleted, by an update that carries only its
id,parentId: nullandpositionPOSITION_INITIAL. Two conditions follow for the store:An expression updated to point at a parent, a variable or a premise that the same changeset inserts is moved to the root in phase 2 and updated in full after the inserts. In phase 2, one late only for its new parent is written whole with the parent cleared, since its variable and premise are not new ones, so it leaves its old variable before that can be deleted. One that names a new variable or premise can only be detached (
id,parentId,position), so the variable and premise deletes (phases 4 and 5) wait until after its full update: the stored row still names its old variable and premise, which may be among them, and a store whose keys cascade would otherwise delete the row.Variable updates run between the variable and premise deletes, so a rebound variable leaves its old premise before that premise is deleted, and a rename can take a symbol a removed variable frees. One bound to a premise the same changeset inserts runs after that insert instead, and the premise deletes wait for it. A changeset with no variable update and no expression update that needs an insert first keeps its previous order exactly: the phase list below with every step for those two left out.
Known exceptions, only when deletes wait, for a store that checks the rule per statement. The inserts then run while the removed rows still exist, so:
Ordering phases:
id,parentIdandposition. An update that needs an insert first is written early here too (see above).