@factoidal/core 0.1.0 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 — both engines in one package, with a backend selector
4
+
5
+ - The Lean 4 engine (`L4Factoidal`, wasm) now ships INSIDE
6
+ `@factoidal/core` as `l4-assets/`, alongside the F\*-extracted
7
+ engine. One install gets both. `require('factoidal/l4')` and
8
+ `factoidal/l4-core` are unchanged; the resolver checks in-package
9
+ assets first, then falls through to the old order (companion
10
+ package, `$FACTOIDAL_L4_ASSETS`, repo checkout).
11
+ - `@factoidal/lean` is superseded and was never published.
12
+ - New subpath `factoidal/select`: a backend selector, per-instance
13
+ with per-call override. Values `lean`, `fstar`, `lean1st`,
14
+ `fstar1st`, `slowcompareboth`. A request naming exactly one engine
15
+ never gets an answer from the other -- `lean` and `fstar` throw on a
16
+ function that engine does not implement; `lean1st` / `fstar1st` fall
17
+ through, and `lean1st` also takes a list of functions to route to
18
+ F\* regardless. Every result carries the answering engine.
19
+ `slowcompareboth` runs both and REPORTS disagreement rather than
20
+ throwing; comparison is RDFC-1.0 isomorphism for Dataset-shaped
21
+ results and bag equality (blank nodes relabelled per side) for
22
+ SELECT bindings.
23
+ - Measured on the typed API surface at this release: 15 functions both
24
+ engines answer, 38 F\*-only, 4 Lean-only (out of 57). This measures
25
+ the typed wrapper surface, not the Lean engine's total capability --
26
+ `l4-core.js` wires 16 of the engine's 21 dispatch ops.
27
+ - `clParse` (Common Logic Interchange Format text, ISO/IEC 24707:2018,
28
+ with the IKL `that`-operator extension) is now wired into the typed
29
+ API -- `l4-core.js`/`lib/api.js`/`select.js`, with `.d.ts` types and
30
+ tests. It reads CLIF text and reports its shape (sentence count,
31
+ `pureCL` dialect flag, canonical re-serialisation); it never produces
32
+ RDF. `pureCL` is a DIALECT flag, not a validity or quality signal:
33
+ true while the text stays inside ISO/IEC 24707 Common Logic, false
34
+ once it uses IKL's `that` operator. It is the first Lean-only entry
35
+ on the typed capability table -- formal/fstar has no CL/IKL parser at
36
+ all, so `index.js`/`wasm.js` never export it, `factoidal/select`'s
37
+ `backend:'fstar'` throws for it (never falls back to Lean), and
38
+ `backend:'slowcompareboth'` fails the capability precondition rather
39
+ than comparing one side against nothing.
40
+ - `clSerialize`, `clAlphaNorm` and `clNormalize` join `clParse` on the
41
+ same Lean-only typed surface (owner instruction, 2026-08-26 -- "wire
42
+ into js functional api"), same `.d.ts`-typed, test-covered pattern:
43
+ `clSerialize` reads CLIF text and writes it back in canonical
44
+ spacing, surfacing `roundTripProved: false` unmodified (the
45
+ round-trip lemma `clif_roundTrip`, `CL/ClifAdequacy.lean`, is OPEN --
46
+ the fragment boundary `marksLexable` is measured, not proved).
47
+ `clAlphaNorm` gives each sentence's bound-variable-renaming canonical
48
+ form (IKL GUIDE Appendix B condition (1)). `clNormalize` is Hayes's
49
+ satisfiability-preserving reduction of IKL to Common Logic
50
+ ([#625](https://github.com/danbri/factoidal/issues/625)): it
51
+ surfaces `preserves: "satisfiability"` (not equivalence -- suited to
52
+ entailment/consistency testing, not to transforming data you intend
53
+ to keep) and `noIntrusion` (the proof hypothesis `CL.noIntrSs [] []`
54
+ decides, not a paraphrase of it). `clFiniteSat`, the fifth CL/IKL op,
55
+ is DEFERRED rather than wired: it takes a caller-supplied finite-
56
+ interpretation JSON encoding with no user yet, and a typed wrapper
57
+ would freeze that shape before it is known to be right; it stays
58
+ reachable through the raw dispatch ABI.
59
+ - The IKL-to-RDF projection ops (`clToDataset`, `queryWithIklService`)
60
+ are DELETED from the engine source (danbri/factoidal#626), along with
61
+ the content-addressed proposition graph names they minted. They were
62
+ never exposed through the npm API. `x-ikl-*` entailment regimes are
63
+ still rejected at the JS layer, and the engine no longer defines the
64
+ family either. The two ops remain present in the compiled wasm
65
+ artifact until it is rebuilt (danbri/factoidal#627) -- the artifact
66
+ is ahead of its source. `clParse` is a different op (it never
67
+ produces RDF) and is unaffected.
68
+
69
+ ## 0.2.0 — Lean 4 engine subpath
70
+
71
+ - New `factoidal/l4-core` subpath: the same typed API served by the
72
+ Lean 4-extracted wasm engine instead of the F\*-extracted one
73
+ ([#476](https://github.com/danbri/factoidal/issues/476)). Engine
74
+ assets resolve from the `@factoidal/lean` companion package, the
75
+ `FACTOIDAL_L4_ASSETS` environment variable, or the repository
76
+ checkout, in that order. `capabilities()` reports the Lean engine's
77
+ actual surface; `shaclValidate`/`owlIsConsistent`/`owlEntails`
78
+ raise pinned errors rather than returning wrong answers
79
+ ([#586](https://github.com/danbri/factoidal/issues/586) tracks the
80
+ OWL verdicts).
81
+ - `serialize({ format: "nquads" })` now normalizes through the entry
82
+ ABI instead of the CLI path.
83
+
84
+
3
85
  ## 0.1.0 — First published release (as `@factoidal/core`)
4
86
 
5
87
  - SPARQL 1.1 §17.6 extension functions
package/README.md CHANGED
@@ -306,6 +306,58 @@ const tabular = await fromCsvw(csvText, csvwMetadataJson, { mode: 'minimal' });
306
306
  const saturated = await rif(data, rifRulesXml); // RIF Core forward chaining
307
307
  ```
308
308
 
309
+ ## Lean engine (new in 0.2.0)
310
+
311
+ Two engines now ship in one package. `factoidal` and `factoidal/wasm`
312
+ are the F\*-extracted engine, unchanged. The subpaths below are the
313
+ Lean 4 engine (`L4Factoidal`, compiled to wasm).
314
+
315
+ ```js
316
+ const l4 = require('factoidal/l4-core'); // Lean engine, same API shape
317
+ const { select } = require('factoidal/select'); // choose an engine per call
318
+ ```
319
+
320
+ ### `factoidal/l4-core`
321
+
322
+ Same call shape as the main API — `parse`, `query`, `update`,
323
+ `serialize`, `canonicalize`, `graphs`, `canonicalHash`, `owlClosure`,
324
+ `coreRdfsClosure`, `coreRdfsCheck`, `rhoDfClosure`,
325
+ `rhoDfFragmentCheck`, `rdfsPlusClosure`, `owlIsConsistent` — plus four
326
+ Common Logic / IKL operations that exist only here, because the F\* tree
327
+ has no CL parser.
328
+
329
+ | Function | In → out | What the answer is worth |
330
+ |---|---|---|
331
+ | `clParse(clifText)` | CLIF text → shape report | sentence count, CL-vs-IKL dialect, canonical re-serialisation. Reads CLIF; never produces RDF |
332
+ | `clSerialize(clifText)` | CLIF → CLIF | canonical writer. Returns `roundTripProved: false` — `clif_roundTrip` is an open lemma and the fragment boundary is measured, not proved |
333
+ | `clAlphaNorm(clifText)` | CLIF → CLIF | alpha-equivalence canonical form (IKL Appendix B condition 1) |
334
+ | `clNormalize(clifText)` | CLIF → CLIF | Hayes's IKL-to-CL reduction. Returns `preserves: "satisfiability"` — **not** equivalence — and `noIntrusion`, the proof hypothesis decided rather than assumed |
335
+
336
+ A fifth op, `clFiniteSat(interpJson, clifText)`, is reachable only
337
+ through the raw dispatch ABI: `l4.call('clFiniteSat', [interpJson,
338
+ clifText])`. It is not in the typed layer.
339
+
340
+ ### `factoidal/select`
341
+
342
+ Per-instance backend choice with a per-call override.
343
+
344
+ | Value | Behaviour |
345
+ |---|---|
346
+ | `lean` / `fstar` | that engine only; **throws** if it does not implement the function |
347
+ | `lean1st` / `fstar1st` | prefer that engine, fall through to the other for unimplemented functions |
348
+ | `slowcompareboth` | run both and **report** disagreement rather than throwing |
349
+
350
+ Every result names the engine that answered. `capabilityTable()`
351
+ returns which functions each engine implements.
352
+
353
+ ### What this surface is, honestly
354
+
355
+ Four `String → String` operations plus one through raw dispatch. The
356
+ Lean tree behind them is larger than that — the CL/IKL and unified
357
+ model-theory modules run to about 22,000 lines — but only these reach
358
+ JavaScript today. Everything else in the Lean tree is used through
359
+ `parse`/`query`/`closure`, or not exposed at all.
360
+
309
361
  ## API (draft)
310
362
 
311
363
  The `factoidal` CLI (`bin/factoidal-cli/factoidal_cli.ml`, built to