@polintpro/proposit-core 0.2.3 → 0.2.4

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 (48) hide show
  1. package/README.md +14 -11
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/core/ArgumentEngine.d.ts +23 -19
  7. package/dist/lib/core/ArgumentEngine.d.ts.map +1 -1
  8. package/dist/lib/core/ArgumentEngine.js +11 -11
  9. package/dist/lib/core/ArgumentEngine.js.map +1 -1
  10. package/dist/lib/core/ChangeCollector.d.ts +13 -14
  11. package/dist/lib/core/ChangeCollector.d.ts.map +1 -1
  12. package/dist/lib/core/ChangeCollector.js.map +1 -1
  13. package/dist/lib/core/ExpressionManager.d.ts +15 -13
  14. package/dist/lib/core/ExpressionManager.d.ts.map +1 -1
  15. package/dist/lib/core/ExpressionManager.js +52 -22
  16. package/dist/lib/core/ExpressionManager.js.map +1 -1
  17. package/dist/lib/core/PremiseManager.d.ts +21 -20
  18. package/dist/lib/core/PremiseManager.d.ts.map +1 -1
  19. package/dist/lib/core/PremiseManager.js +19 -24
  20. package/dist/lib/core/PremiseManager.js.map +1 -1
  21. package/dist/lib/core/VariableManager.d.ts +7 -8
  22. package/dist/lib/core/VariableManager.d.ts.map +1 -1
  23. package/dist/lib/core/VariableManager.js +4 -1
  24. package/dist/lib/core/VariableManager.js.map +1 -1
  25. package/dist/lib/core/diff.d.ts +1 -1
  26. package/dist/lib/core/diff.d.ts.map +1 -1
  27. package/dist/lib/core/diff.js +19 -11
  28. package/dist/lib/core/diff.js.map +1 -1
  29. package/dist/lib/schemata/propositional.d.ts.map +1 -1
  30. package/dist/lib/schemata/propositional.js +0 -1
  31. package/dist/lib/schemata/propositional.js.map +1 -1
  32. package/dist/lib/schemata/shared.d.ts +4 -0
  33. package/dist/lib/schemata/shared.d.ts.map +1 -1
  34. package/dist/lib/types/diff.d.ts +15 -15
  35. package/dist/lib/types/diff.d.ts.map +1 -1
  36. package/dist/lib/types/mutation.d.ts +7 -20
  37. package/dist/lib/types/mutation.d.ts.map +1 -1
  38. package/dist/lib/utils/position.d.ts +9 -3
  39. package/dist/lib/utils/position.d.ts.map +1 -1
  40. package/dist/lib/utils/position.js +8 -3
  41. package/dist/lib/utils/position.js.map +1 -1
  42. package/package.json +3 -2
  43. package/skills/proposit-core/SKILL.md +35 -0
  44. package/skills/proposit-core/docs/api-usage.md +442 -0
  45. package/skills/proposit-core/docs/architecture.md +256 -0
  46. package/skills/proposit-core/docs/cli.md +304 -0
  47. package/skills/proposit-core/docs/testing.md +281 -0
  48. package/skills/proposit-core/docs/types-schemas.md +648 -0
@@ -0,0 +1,442 @@
1
+ # proposit-core API Reference
2
+
3
+ ## 1. Creating an Argument
4
+
5
+ ```typescript
6
+ import { ArgumentEngine } from "@polintpro/proposit-core"
7
+
8
+ const engine = new ArgumentEngine({
9
+ id: "arg-1",
10
+ version: 0,
11
+ title: "My Argument",
12
+ description: "Description",
13
+ })
14
+ ```
15
+
16
+ - Constructor accepts `Omit<TCoreArgument, "checksum">` -- extra fields allowed (`additionalProperties: true` in schema).
17
+ - Optional second parameter: `{ checksumConfig?: TCoreChecksumConfig }`.
18
+ - Retrieve metadata: `engine.getArgument()` returns `TCoreArgument` (with checksum).
19
+
20
+ ## 2. Variable Management
21
+
22
+ Variables are argument-scoped. A single `VariableManager` is shared across all premises.
23
+
24
+ ```typescript
25
+ // Add
26
+ const { result: variable, changes } = engine.addVariable({
27
+ id: "v1",
28
+ argumentId: "arg-1",
29
+ argumentVersion: 0,
30
+ symbol: "P",
31
+ })
32
+
33
+ // Update (rename)
34
+ engine.updateVariable("v1", { symbol: "Q" })
35
+
36
+ // Remove -- cascades: deletes all referencing expressions across all premises (with operator collapse)
37
+ engine.removeVariable("v1")
38
+
39
+ // Read
40
+ engine.getVariables() // TCorePropositionalVariable[] (sorted by ID, with checksums)
41
+ ```
42
+
43
+ **Signatures:**
44
+
45
+ | Method | Returns |
46
+ | ------------------------------------------------ | -------------------------------------------------------------- |
47
+ | `engine.addVariable(variable)` | `TCoreMutationResult<TCorePropositionalVariable>` |
48
+ | `engine.updateVariable(variableId, { symbol? })` | `TCoreMutationResult<TCorePropositionalVariable \| undefined>` |
49
+ | `engine.removeVariable(variableId)` | `TCoreMutationResult<TCorePropositionalVariable \| undefined>` |
50
+ | `engine.getVariables()` | `TCorePropositionalVariable[]` |
51
+
52
+ **Throws:** duplicate symbol, duplicate ID, mismatched `argumentId`/`argumentVersion`.
53
+
54
+ ## 3. Premise CRUD
55
+
56
+ ```typescript
57
+ // Create (auto-generated UUID)
58
+ const { result: pm, changes } = engine.createPremise({ title: "Premise 1" })
59
+
60
+ // Create with explicit ID
61
+ const { result: pm2 } = engine.createPremiseWithId("p-1", {
62
+ title: "Premise 1",
63
+ })
64
+
65
+ // Remove
66
+ const { result: removedData } = engine.removePremise("p-1")
67
+
68
+ // Read
69
+ engine.getPremise("p-1") // PremiseManager | undefined
70
+ engine.hasPremise("p-1") // boolean
71
+ engine.listPremiseIds() // string[] (sorted)
72
+ engine.listPremises() // PremiseManager[] (sorted by ID)
73
+ ```
74
+
75
+ - `extras` is `Record<string, unknown>` -- preserved via `additionalProperties` (e.g. `{ title: "..." }`).
76
+ - First premise created is auto-assigned as conclusion (reflected in changeset `changes.roles`).
77
+
78
+ **Signatures:**
79
+
80
+ | Method | Returns |
81
+ | ----------------------------------------- | ------------------------------------------------ |
82
+ | `engine.createPremise(extras?)` | `TCoreMutationResult<PremiseManager>` |
83
+ | `engine.createPremiseWithId(id, extras?)` | `TCoreMutationResult<PremiseManager>` |
84
+ | `engine.removePremise(premiseId)` | `TCoreMutationResult<TCorePremise \| undefined>` |
85
+
86
+ ## 4. Expression Tree
87
+
88
+ ### Insertion APIs (prefer the top two)
89
+
90
+ ```typescript
91
+ const pm = engine.getPremise("p-1")!
92
+
93
+ // 1. Append as last child (position auto-computed)
94
+ const { result: expr } = pm.appendExpression(null, {
95
+ id: "e-root",
96
+ type: "operator",
97
+ operator: "implies",
98
+ argumentId: "arg-1",
99
+ argumentVersion: 0,
100
+ parentId: null, // ignored for appendExpression -- parentId comes from first arg
101
+ })
102
+
103
+ // 2. Insert relative to sibling
104
+ pm.addExpressionRelative("e-sibling", "before", {
105
+ id: "e-new",
106
+ type: "variable",
107
+ variableId: "v1",
108
+ argumentId: "arg-1",
109
+ argumentVersion: 0,
110
+ parentId: "e-root", // ignored -- derived from sibling's parent
111
+ })
112
+
113
+ // 3. Low-level with explicit position
114
+ pm.addExpression({
115
+ id: "e-3",
116
+ type: "variable",
117
+ variableId: "v1",
118
+ argumentId: "arg-1",
119
+ argumentVersion: 0,
120
+ parentId: "e-root",
121
+ position: 0,
122
+ })
123
+ ```
124
+
125
+ **Input types:**
126
+
127
+ - `appendExpression` and `addExpressionRelative`: `TExpressionWithoutPosition` (no `position` or `checksum`).
128
+ - `addExpression`: `TExpressionInput` (no `checksum`, but has `position`).
129
+
130
+ ### Other mutations
131
+
132
+ ```typescript
133
+ // Insert (wraps existing nodes under new operator)
134
+ pm.insertExpression(newOperatorExpr, leftNodeId, rightNodeId)
135
+
136
+ // Update in-place (restricted swaps: and<->or, implies<->iff)
137
+ pm.updateExpression("e-1", { operator: "or" })
138
+ pm.updateExpression("e-var", { variableId: "v2" })
139
+ pm.updateExpression("e-1", { position: 5 })
140
+
141
+ // Remove
142
+ pm.removeExpression("e-1", true) // deleteSubtree=true: delete subtree + operator collapse
143
+ pm.removeExpression("e-1", false) // deleteSubtree=false: promote single child into slot
144
+ ```
145
+
146
+ **Signatures:**
147
+
148
+ | Method | Returns |
149
+ | -------------------------------------------------------------- | ---------------------------------------------------------------- |
150
+ | `pm.appendExpression(parentId, expr)` | `TCoreMutationResult<TCorePropositionalExpression>` |
151
+ | `pm.addExpressionRelative(siblingId, "before"\|"after", expr)` | `TCoreMutationResult<TCorePropositionalExpression>` |
152
+ | `pm.addExpression(expr)` | `TCoreMutationResult<TCorePropositionalExpression>` |
153
+ | `pm.insertExpression(expr, leftNodeId?, rightNodeId?)` | `TCoreMutationResult<TCorePropositionalExpression>` |
154
+ | `pm.updateExpression(id, updates)` | `TCoreMutationResult<TCorePropositionalExpression>` |
155
+ | `pm.removeExpression(id, deleteSubtree)` | `TCoreMutationResult<TCorePropositionalExpression \| undefined>` |
156
+
157
+ **Read methods:**
158
+
159
+ | Method | Returns |
160
+ | ---------------------------------- | ----------------------------------------------------- |
161
+ | `pm.getExpression(id)` | `TCorePropositionalExpression \| undefined` |
162
+ | `pm.getExpressions()` | `TCorePropositionalExpression[]` (sorted by ID) |
163
+ | `pm.getChildExpressions(parentId)` | `TCorePropositionalExpression[]` (sorted by position) |
164
+ | `pm.getRootExpression()` | `TCorePropositionalExpression \| undefined` |
165
+ | `pm.getRootExpressionId()` | `string \| undefined` |
166
+
167
+ ### Expression type rules
168
+
169
+ - `implies` and `iff` must be root (`parentId: null`). Cannot be nested.
170
+ - `not`: exactly 1 child. Cannot swap operator (delete and re-create instead).
171
+ - `and`/`or`: 2+ children. Can swap between each other.
172
+ - `implies`/`iff`: exactly 2 children at positions 0 and 1. Can swap between each other.
173
+ - `formula`: transparent unary wrapper (1 child). Equivalent to parentheses.
174
+
175
+ ### Operator collapse (on remove with `deleteSubtree: true`)
176
+
177
+ After deleting a subtree, `collapseIfNeeded` runs on the parent:
178
+
179
+ - **0 children left**: parent operator/formula deleted, recurse to grandparent.
180
+ - **1 child left**: parent deleted, surviving child promoted into parent's slot.
181
+
182
+ ## 5. Roles
183
+
184
+ ```typescript
185
+ engine.setConclusionPremise("p-1")
186
+ engine.clearConclusionPremise()
187
+ engine.getConclusionPremise() // PremiseManager | undefined
188
+ engine.listSupportingPremises() // PremiseManager[] -- derived: inference premises not the conclusion
189
+ engine.getRoleState() // TCoreArgumentRoleState: { conclusionPremiseId?: string }
190
+ ```
191
+
192
+ - Supporting premises are **derived**, not explicitly managed. Any inference premise (`implies`/`iff` root) that is not the conclusion is automatically supporting.
193
+ - `setConclusionPremise` and `clearConclusionPremise` return `TCoreMutationResult<TCoreArgumentRoleState>`.
194
+
195
+ ## 6. Evaluation
196
+
197
+ ### Premise-level
198
+
199
+ ```typescript
200
+ const result = pm.evaluate({
201
+ variables: { v1: true, v2: false, v3: null },
202
+ rejectedExpressionIds: ["e-5"],
203
+ })
204
+ // result: TCorePremiseEvaluationResult
205
+ // result.rootValue -- TCoreTrivalentValue (true | false | null)
206
+ // result.expressionValues -- Record<string, TCoreTrivalentValue>
207
+ // result.inferenceDiagnostic -- for implies/iff roots
208
+ ```
209
+
210
+ ### Argument-level
211
+
212
+ ```typescript
213
+ const result = engine.evaluate({
214
+ variables: { v1: true, v2: false },
215
+ rejectedExpressionIds: [],
216
+ })
217
+
218
+ if (result.ok) {
219
+ result.isAdmissibleAssignment // TCoreTrivalentValue
220
+ result.allSupportingPremisesTrue // TCoreTrivalentValue
221
+ result.conclusionTrue // TCoreTrivalentValue
222
+ result.isCounterexample // TCoreTrivalentValue
223
+ result.preservesTruthUnderAssignment // TCoreTrivalentValue
224
+ result.conclusion // TCorePremiseEvaluationResult
225
+ result.supportingPremises // TCorePremiseEvaluationResult[]
226
+ result.constraintPremises // TCorePremiseEvaluationResult[]
227
+ }
228
+ ```
229
+
230
+ **Options:** `engine.evaluate(assignment, { validateFirst?, includeExpressionValues?, includeDiagnostics?, strictUnknownAssignmentKeys? })`
231
+
232
+ ### Validity check
233
+
234
+ ```typescript
235
+ const result = engine.checkValidity({
236
+ mode: "firstCounterexample", // or "exhaustive"
237
+ maxVariables: 20,
238
+ maxAssignmentsChecked: 1_000_000,
239
+ })
240
+
241
+ if (result.ok) {
242
+ result.isValid // true | false | undefined (undefined = truncated)
243
+ result.counterexamples // TCoreCounterexample[]
244
+ result.checkedVariableIds // string[]
245
+ result.numAssignmentsChecked
246
+ result.numAdmissibleAssignments
247
+ result.truncated // boolean
248
+ }
249
+ ```
250
+
251
+ ### Structural validation
252
+
253
+ ```typescript
254
+ const validation = engine.validateEvaluability()
255
+ // validation: TCoreValidationResult { ok: boolean, issues: TCoreValidationIssue[] }
256
+ // Also: pm.validateEvaluability() for premise-level
257
+ ```
258
+
259
+ ## 7. Diffing
260
+
261
+ ```typescript
262
+ import {
263
+ diffArguments,
264
+ defaultCompareArgument,
265
+ defaultCompareVariable,
266
+ defaultComparePremise,
267
+ defaultCompareExpression,
268
+ } from "@polintpro/proposit-core"
269
+
270
+ const diff = diffArguments(engineA, engineB, {
271
+ compareArgument: defaultCompareArgument,
272
+ compareVariable: defaultCompareVariable,
273
+ comparePremise: defaultComparePremise,
274
+ compareExpression: defaultCompareExpression,
275
+ })
276
+ // diff: TCoreArgumentDiff
277
+ // diff.argument -- TCoreEntityFieldDiff<TCoreArgument>
278
+ // diff.variables -- TCoreEntitySetDiff<TCorePropositionalVariable>
279
+ // diff.premises -- TCorePremiseSetDiff (with nested expression diffs)
280
+ // diff.roles -- TCoreRoleDiff
281
+ ```
282
+
283
+ - Standalone function. Pluggable comparators (each receives before/after, returns `TCoreFieldChange[]`).
284
+ - All options optional -- defaults are used when omitted.
285
+
286
+ ## 8. Relationship Analysis
287
+
288
+ ```typescript
289
+ import {
290
+ analyzePremiseRelationships,
291
+ buildPremiseProfile,
292
+ } from "@polintpro/proposit-core"
293
+
294
+ // Analyze how all premises relate to a focused premise
295
+ const analysis = analyzePremiseRelationships(engine, "p-conclusion")
296
+ // analysis: TCorePremiseRelationshipAnalysis
297
+ // analysis.focusedPremiseId
298
+ // analysis.premises -- TCorePremiseRelationResult[] per other premise
299
+ // each: { premiseId, relationship, variableDetails, transitive }
300
+ // relationship: "supporting" | "contradicting" | "restricting" | "downstream" | "unrelated"
301
+
302
+ // Build a variable profile for a single premise
303
+ const profile = buildPremiseProfile(pm)
304
+ // profile: TCorePremiseProfile
305
+ // profile.premiseId
306
+ // profile.appearances -- TCoreVariableAppearance[]
307
+ ```
308
+
309
+ Both are standalone functions.
310
+
311
+ ## 9. Formula Parsing
312
+
313
+ ```typescript
314
+ import { parseFormula } from "@polintpro/proposit-core"
315
+ import type { FormulaAST } from "@polintpro/proposit-core"
316
+
317
+ const ast: FormulaAST = parseFormula("P -> (Q & R)")
318
+ ```
319
+
320
+ **Supported syntax:** `&&`/`∧` (AND), `||`/`∨` (OR), `!`/`¬` (NOT), `->`/`→` (implies), `<->`/`↔` (iff), parentheses.
321
+
322
+ **AST types:**
323
+
324
+ ```typescript
325
+ type FormulaAST =
326
+ | { type: "variable"; name: string }
327
+ | { type: "not"; operand: FormulaAST }
328
+ | { type: "and"; operands: FormulaAST[] }
329
+ | { type: "or"; operands: FormulaAST[] }
330
+ | { type: "implies"; left: FormulaAST; right: FormulaAST }
331
+ | { type: "iff"; left: FormulaAST; right: FormulaAST }
332
+ ```
333
+
334
+ ## 10. Mutation Result Pattern
335
+
336
+ Every mutating method returns `TCoreMutationResult<T>`:
337
+
338
+ ```typescript
339
+ interface TCoreMutationResult<T> {
340
+ result: T
341
+ changes: TCoreChangeset
342
+ }
343
+
344
+ interface TCoreChangeset {
345
+ expressions?: TCoreEntityChanges<TCorePropositionalExpression>
346
+ variables?: TCoreEntityChanges<TCorePropositionalVariable>
347
+ premises?: TCoreEntityChanges<TCorePremise>
348
+ roles?: TCoreArgumentRoleState // present only when roles changed
349
+ argument?: TCoreArgument // present only when argument changed
350
+ }
351
+
352
+ interface TCoreEntityChanges<T> {
353
+ added: T[]
354
+ modified: T[]
355
+ removed: T[]
356
+ }
357
+ ```
358
+
359
+ **Usage pattern:**
360
+
361
+ ```typescript
362
+ const { result: premise, changes } = engine.createPremise()
363
+ changes.premises?.added // newly added premise
364
+ changes.roles // new role state (if changed, e.g. auto-conclusion)
365
+ changes.expressions?.removed // cascaded removals (e.g. from removeVariable)
366
+ ```
367
+
368
+ ## 11. Serialization
369
+
370
+ ### PremiseManager
371
+
372
+ | Method | Returns | Description |
373
+ | ------------------------------------------ | ----------------------------------------------------- | ------------------------------------------------- |
374
+ | `pm.toData()` | `TCorePremise` | Serializable snapshot (only referenced variables) |
375
+ | `pm.toDisplayString()` | `string` | Human-readable formula (`P -> (Q /\ R)`) |
376
+ | `pm.isInference()` | `boolean` | Root is `implies` or `iff` |
377
+ | `pm.isConstraint()` | `boolean` | Not an inference (inverse of above) |
378
+ | `pm.checksum()` | `string` | Premise-level checksum (lazy) |
379
+ | `pm.getId()` | `string` | Premise ID |
380
+ | `pm.getExtras()` | `Record<string, unknown>` | Extra fields (e.g. title) |
381
+ | `pm.setExtras(extras)` | `TCoreMutationResult<Record<string, unknown>>` | Replace extras |
382
+ | `pm.getReferencedVariableIds()` | `Set<string>` | Variable IDs used in expressions |
383
+ | `pm.getVariables()` | `TCorePropositionalVariable[]` | All argument-level variables |
384
+ | `pm.deleteExpressionsUsingVariable(varId)` | `TCoreMutationResult<TCorePropositionalExpression[]>` | Cascade delete |
385
+
386
+ ### ArgumentEngine
387
+
388
+ | Method | Returns | Description |
389
+ | ------------------------------------- | --------------------------------- | ------------------------------- |
390
+ | `engine.toData()` | `TCoreArgumentEngineData` | Full state snapshot |
391
+ | `engine.exportState()` | `TCoreArgumentEngineData` | Alias for `toData()` |
392
+ | `engine.getArgument()` | `TCoreArgument` | Argument metadata with checksum |
393
+ | `engine.checksum()` | `string` | Argument-level checksum (lazy) |
394
+ | `engine.collectReferencedVariables()` | `{ variableIds, byId, bySymbol }` | Cross-premise variable index |
395
+
396
+ ## 12. Checksum Utilities
397
+
398
+ ```typescript
399
+ import {
400
+ computeHash,
401
+ canonicalSerialize,
402
+ entityChecksum,
403
+ DEFAULT_CHECKSUM_CONFIG,
404
+ createChecksumConfig,
405
+ } from "@polintpro/proposit-core"
406
+
407
+ // Low-level hash
408
+ const hash = computeHash("input string")
409
+
410
+ // Serialize object to canonical deterministic JSON (sorted keys)
411
+ const serialized = canonicalSerialize({ a: 1, b: 2 })
412
+
413
+ // Entity checksum
414
+ const checksum = entityChecksum(entity, new Set(["id", "symbol"]))
415
+
416
+ // Custom config
417
+ const config = createChecksumConfig({
418
+ expressionFields: new Set([
419
+ "id",
420
+ "type",
421
+ "operator",
422
+ "variableId",
423
+ "parentId",
424
+ "position",
425
+ ]),
426
+ variableFields: new Set(["id", "symbol"]),
427
+ })
428
+ const engine = new ArgumentEngine(arg, { checksumConfig: config })
429
+ ```
430
+
431
+ ## 13. Position Utilities
432
+
433
+ ```typescript
434
+ import {
435
+ POSITION_MIN, // 0
436
+ POSITION_MAX, // Number.MAX_SAFE_INTEGER
437
+ POSITION_INITIAL, // midpoint(POSITION_MIN, POSITION_MAX)
438
+ midpoint, // (a, b) => a + (b - a) / 2
439
+ } from "@polintpro/proposit-core"
440
+ ```
441
+
442
+ Positions are opaque numbers. Only relative ordering matters. The `appendExpression` and `addExpressionRelative` APIs compute positions automatically -- prefer those over manual positioning.