@factoidal/core 0.7.1 → 0.11.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.
Files changed (195) hide show
  1. package/CHANGELOG.md +616 -1
  2. package/NOTICE +2 -21
  3. package/README.md +123 -993
  4. package/api.d.ts +53 -0
  5. package/api.js +5 -0
  6. package/api.mjs +56 -0
  7. package/bin/engine.mjs +38 -19
  8. package/bin/ext.mjs +16 -20
  9. package/bin/factoidal.mjs +667 -118
  10. package/bin/pack.mjs +37 -0
  11. package/bin/serve-worker.mjs +32 -0
  12. package/bin/serve.mjs +423 -0
  13. package/bin/store-worker-host.mjs +1 -1
  14. package/bin/store.mjs +1 -1
  15. package/browser.d.ts +114 -507
  16. package/browser.js +155 -2257
  17. package/docs/fuseki-replacement.md +108 -0
  18. package/fn.d.ts +25 -96
  19. package/fn.js +131 -240
  20. package/index.d.ts +620 -260
  21. package/index.js +4 -234
  22. package/index.mjs +180 -84
  23. package/l4-assets/l4factoidal.js +47 -7
  24. package/l4-assets/l4factoidal.mjs +1 -1
  25. package/l4-assets/l4factoidal.wasm +0 -0
  26. package/l4-assets/version.json +11 -7
  27. package/lib/api.mjs +2337 -0
  28. package/lib/browser-engine.mjs +69 -0
  29. package/lib/dataset.mjs +471 -0
  30. package/lib/delta-log-hosts.mjs +191 -0
  31. package/lib/lean-entry.mjs +213 -0
  32. package/lib/pure.mjs +98 -0
  33. package/lib/store.mjs +115 -0
  34. package/lib/version.mjs +5 -0
  35. package/lws/README.md +137 -0
  36. package/lws/persist.mjs +78 -0
  37. package/lws/server.mjs +416 -0
  38. package/package.json +59 -61
  39. package/rdfjs.js +5 -536
  40. package/rdfjs.mjs +517 -0
  41. package/sample-store.d.ts +8 -16
  42. package/sample-store.mjs +39 -29
  43. package/solid/client/README.md +100 -0
  44. package/solid/client/index.mjs +293 -0
  45. package/solid/server/README.md +96 -0
  46. package/solid/server/index.mjs +395 -0
  47. package/store-host/deno.mjs +8 -0
  48. package/store-host/index.mjs +12 -0
  49. package/store-host/node.mjs +8 -0
  50. package/xmpp/README.md +107 -0
  51. package/xmpp/index.mjs +229 -0
  52. package/browser-wasm.js +0 -872
  53. package/factoidal-npm-entry.js +0 -15477
  54. package/factoidal-npm-entry.wasm.assets/code-5a7fc68f2ab1323718b8.wasm +0 -0
  55. package/factoidal-npm-entry.wasm.js +0 -455
  56. package/factoidal.js +0 -13118
  57. package/factoidal.wasm.assets/code-bbe6099bfb5b10c4c3ab.wasm +0 -0
  58. package/factoidal.wasm.js +0 -457
  59. package/hacl-init.js +0 -92
  60. package/hacl-wasm/FStar.wasm +0 -0
  61. package/hacl-wasm/Hacl_Bignum.wasm +0 -0
  62. package/hacl-wasm/Hacl_Bignum25519_51.wasm +0 -0
  63. package/hacl-wasm/Hacl_Bignum_Base.wasm +0 -0
  64. package/hacl-wasm/Hacl_Curve25519_51.wasm +0 -0
  65. package/hacl-wasm/Hacl_Ed25519.wasm +0 -0
  66. package/hacl-wasm/Hacl_Ed25519_PrecompTable.wasm +0 -0
  67. package/hacl-wasm/Hacl_Hash_Base.wasm +0 -0
  68. package/hacl-wasm/Hacl_Hash_SHA2.wasm +0 -0
  69. package/hacl-wasm/Hacl_IntTypes_Intrinsics.wasm +0 -0
  70. package/hacl-wasm/LowStar_Endianness.wasm +0 -0
  71. package/hacl-wasm/WasmSupport.wasm +0 -0
  72. package/hacl-wasm/api.js +0 -775
  73. package/hacl-wasm/api.json +0 -3787
  74. package/hacl-wasm/layouts.json +0 -1
  75. package/hacl-wasm/loader.js +0 -568
  76. package/hacl-wasm/shell.js +0 -12
  77. package/l4-core.d.ts +0 -159
  78. package/l4-core.js +0 -188
  79. package/l4.d.ts +0 -50
  80. package/l4.js +0 -104
  81. package/lib/api.js +0 -2300
  82. package/lib/engine-js.js +0 -165
  83. package/lib/engine-wasm.js +0 -300
  84. package/sample-store/CURRENT +0 -1
  85. package/sample-store/gen-1/manifest.sbm2 +0 -0
  86. package/sample-store/gen-1/manifest.tsv +0 -14
  87. package/sample-store/gen-1/predicate-0.ibk3 +0 -0
  88. package/sample-store/gen-1/predicate-0.ibk3.merkle +0 -1
  89. package/sample-store/gen-1/predicate-0.ibk3.oli2 +0 -0
  90. package/sample-store/gen-1/predicate-0.ibk3.oli2.merkle +0 -1
  91. package/sample-store/gen-1/predicate-0.ibk3.sri2 +0 -0
  92. package/sample-store/gen-1/predicate-0.ibk3.sri2.merkle +0 -1
  93. package/sample-store/gen-1/predicate-0.ibk3.tli1 +0 -0
  94. package/sample-store/gen-1/predicate-0.ibk3.tli1.merkle +0 -0
  95. package/sample-store/gen-1/predicate-1.ibk3 +0 -0
  96. package/sample-store/gen-1/predicate-1.ibk3.merkle +0 -0
  97. package/sample-store/gen-1/predicate-1.ibk3.oli2 +0 -0
  98. package/sample-store/gen-1/predicate-1.ibk3.oli2.merkle +0 -0
  99. package/sample-store/gen-1/predicate-1.ibk3.sri2 +0 -0
  100. package/sample-store/gen-1/predicate-1.ibk3.sri2.merkle +0 -1
  101. package/sample-store/gen-1/predicate-1.ibk3.tli1 +0 -0
  102. package/sample-store/gen-1/predicate-1.ibk3.tli1.merkle +0 -1
  103. package/sample-store/gen-1/predicate-10.ibk3 +0 -0
  104. package/sample-store/gen-1/predicate-10.ibk3.merkle +0 -1
  105. package/sample-store/gen-1/predicate-10.ibk3.oli2 +0 -0
  106. package/sample-store/gen-1/predicate-10.ibk3.oli2.merkle +0 -0
  107. package/sample-store/gen-1/predicate-10.ibk3.sri2 +0 -0
  108. package/sample-store/gen-1/predicate-10.ibk3.sri2.merkle +0 -1
  109. package/sample-store/gen-1/predicate-10.ibk3.tli1 +0 -0
  110. package/sample-store/gen-1/predicate-10.ibk3.tli1.merkle +0 -1
  111. package/sample-store/gen-1/predicate-11.ibk3 +0 -0
  112. package/sample-store/gen-1/predicate-11.ibk3.merkle +0 -0
  113. package/sample-store/gen-1/predicate-11.ibk3.oli2 +0 -0
  114. package/sample-store/gen-1/predicate-11.ibk3.oli2.merkle +0 -1
  115. package/sample-store/gen-1/predicate-11.ibk3.sri2 +0 -0
  116. package/sample-store/gen-1/predicate-11.ibk3.sri2.merkle +0 -1
  117. package/sample-store/gen-1/predicate-11.ibk3.tli1 +0 -0
  118. package/sample-store/gen-1/predicate-11.ibk3.tli1.merkle +0 -1
  119. package/sample-store/gen-1/predicate-12.ibk3 +0 -0
  120. package/sample-store/gen-1/predicate-12.ibk3.merkle +0 -1
  121. package/sample-store/gen-1/predicate-12.ibk3.oli2 +0 -0
  122. package/sample-store/gen-1/predicate-12.ibk3.oli2.merkle +0 -1
  123. package/sample-store/gen-1/predicate-12.ibk3.sri2 +0 -0
  124. package/sample-store/gen-1/predicate-12.ibk3.sri2.merkle +0 -1
  125. package/sample-store/gen-1/predicate-12.ibk3.tli1 +0 -0
  126. package/sample-store/gen-1/predicate-12.ibk3.tli1.merkle +0 -1
  127. package/sample-store/gen-1/predicate-2.ibk3 +0 -0
  128. package/sample-store/gen-1/predicate-2.ibk3.merkle +0 -1
  129. package/sample-store/gen-1/predicate-2.ibk3.oli2 +0 -0
  130. package/sample-store/gen-1/predicate-2.ibk3.oli2.merkle +0 -1
  131. package/sample-store/gen-1/predicate-2.ibk3.sri2 +0 -0
  132. package/sample-store/gen-1/predicate-2.ibk3.sri2.merkle +0 -0
  133. package/sample-store/gen-1/predicate-2.ibk3.tli1 +0 -0
  134. package/sample-store/gen-1/predicate-2.ibk3.tli1.merkle +0 -0
  135. package/sample-store/gen-1/predicate-3.ibk3 +0 -0
  136. package/sample-store/gen-1/predicate-3.ibk3.merkle +0 -1
  137. package/sample-store/gen-1/predicate-3.ibk3.oli2 +0 -0
  138. package/sample-store/gen-1/predicate-3.ibk3.oli2.merkle +0 -1
  139. package/sample-store/gen-1/predicate-3.ibk3.sri2 +0 -0
  140. package/sample-store/gen-1/predicate-3.ibk3.sri2.merkle +0 -1
  141. package/sample-store/gen-1/predicate-3.ibk3.tli1 +0 -0
  142. package/sample-store/gen-1/predicate-3.ibk3.tli1.merkle +0 -1
  143. package/sample-store/gen-1/predicate-4.ibk3 +0 -0
  144. package/sample-store/gen-1/predicate-4.ibk3.merkle +0 -0
  145. package/sample-store/gen-1/predicate-4.ibk3.oli2 +0 -0
  146. package/sample-store/gen-1/predicate-4.ibk3.oli2.merkle +0 -1
  147. package/sample-store/gen-1/predicate-4.ibk3.sri2 +0 -0
  148. package/sample-store/gen-1/predicate-4.ibk3.sri2.merkle +0 -1
  149. package/sample-store/gen-1/predicate-4.ibk3.tli1 +0 -0
  150. package/sample-store/gen-1/predicate-4.ibk3.tli1.merkle +0 -2
  151. package/sample-store/gen-1/predicate-5.ibk3 +0 -0
  152. package/sample-store/gen-1/predicate-5.ibk3.merkle +0 -1
  153. package/sample-store/gen-1/predicate-5.ibk3.oli2 +0 -0
  154. package/sample-store/gen-1/predicate-5.ibk3.oli2.merkle +0 -1
  155. package/sample-store/gen-1/predicate-5.ibk3.sri2 +0 -0
  156. package/sample-store/gen-1/predicate-5.ibk3.sri2.merkle +0 -1
  157. package/sample-store/gen-1/predicate-5.ibk3.tli1 +0 -0
  158. package/sample-store/gen-1/predicate-5.ibk3.tli1.merkle +0 -1
  159. package/sample-store/gen-1/predicate-6.ibk3 +0 -0
  160. package/sample-store/gen-1/predicate-6.ibk3.merkle +0 -1
  161. package/sample-store/gen-1/predicate-6.ibk3.oli2 +0 -0
  162. package/sample-store/gen-1/predicate-6.ibk3.oli2.merkle +0 -1
  163. package/sample-store/gen-1/predicate-6.ibk3.sri2 +0 -0
  164. package/sample-store/gen-1/predicate-6.ibk3.sri2.merkle +0 -1
  165. package/sample-store/gen-1/predicate-6.ibk3.tli1 +0 -0
  166. package/sample-store/gen-1/predicate-6.ibk3.tli1.merkle +0 -0
  167. package/sample-store/gen-1/predicate-7.ibk3 +0 -0
  168. package/sample-store/gen-1/predicate-7.ibk3.merkle +0 -0
  169. package/sample-store/gen-1/predicate-7.ibk3.oli2 +0 -0
  170. package/sample-store/gen-1/predicate-7.ibk3.oli2.merkle +0 -2
  171. package/sample-store/gen-1/predicate-7.ibk3.sri2 +0 -0
  172. package/sample-store/gen-1/predicate-7.ibk3.sri2.merkle +0 -1
  173. package/sample-store/gen-1/predicate-7.ibk3.tli1 +0 -0
  174. package/sample-store/gen-1/predicate-7.ibk3.tli1.merkle +0 -1
  175. package/sample-store/gen-1/predicate-8.ibk3 +0 -0
  176. package/sample-store/gen-1/predicate-8.ibk3.merkle +0 -1
  177. package/sample-store/gen-1/predicate-8.ibk3.oli2 +0 -0
  178. package/sample-store/gen-1/predicate-8.ibk3.oli2.merkle +0 -1
  179. package/sample-store/gen-1/predicate-8.ibk3.sri2 +0 -0
  180. package/sample-store/gen-1/predicate-8.ibk3.sri2.merkle +0 -1
  181. package/sample-store/gen-1/predicate-8.ibk3.tli1 +0 -0
  182. package/sample-store/gen-1/predicate-8.ibk3.tli1.merkle +0 -1
  183. package/sample-store/gen-1/predicate-9.ibk3 +0 -0
  184. package/sample-store/gen-1/predicate-9.ibk3.merkle +0 -1
  185. package/sample-store/gen-1/predicate-9.ibk3.oli2 +0 -0
  186. package/sample-store/gen-1/predicate-9.ibk3.oli2.merkle +0 -1
  187. package/sample-store/gen-1/predicate-9.ibk3.sri2 +0 -0
  188. package/sample-store/gen-1/predicate-9.ibk3.sri2.merkle +0 -3
  189. package/sample-store/gen-1/predicate-9.ibk3.tli1 +0 -0
  190. package/sample-store/gen-1/predicate-9.ibk3.tli1.merkle +0 -2
  191. package/select.d.ts +0 -116
  192. package/select.js +0 -492
  193. package/version.json +0 -102
  194. package/wasm.d.ts +0 -130
  195. package/wasm.js +0 -158
package/fn.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // factoidal/fn — a strictly functional dataset API.
2
2
  //
3
- // Every extracted engine operation is a value-to-value function (F*
4
- // has no mutation to expose); RDF/JS DatasetCore's add/delete is
3
+ // Every engine operation is a value-to-value function (the Lean
4
+ // library has no mutation to expose); RDF/JS DatasetCore's add/delete is
5
5
  // wrapper-side skeuomorphism on top of that. This module makes the JS
6
6
  // contract match the verified one: FnDataset is a frozen snapshot, all
7
7
  // operations are free functions that return new values, and content
@@ -25,9 +25,10 @@ const crypto = require('node:crypto');
25
25
 
26
26
  const engineApi = require('./index.js');
27
27
  const {
28
- Dataset,
28
+ DatasetCore,
29
29
  dataFactory,
30
- quadToNQuads,
30
+ quadKey,
31
+ termKey,
31
32
  quadsToNQuads,
32
33
  } = require('./rdfjs.js');
33
34
 
@@ -92,10 +93,34 @@ function arrayBackend(quads) {
92
93
  kind: 'array',
93
94
  size: quads.length,
94
95
  quads: () => quads,
96
+ engine: null,
95
97
  precomputedHash: null,
96
98
  };
97
99
  }
98
100
 
101
+ // The engine backend (0.10.0, issue 882 of danbri/factoidal): the quads are
102
+ // an engine Dataset (lib/dataset.mjs) that this module never changes. Every
103
+ // engine operation takes that Dataset itself, so no N-Quads text crosses
104
+ // between steps. The JS quad array is read once, on demand.
105
+ function engineBackend(eds) {
106
+ let quads = null;
107
+ return {
108
+ kind: 'engine',
109
+ size: eds.size,
110
+ quads: () => (quads ||= Object.freeze(eds.toArray())),
111
+ engine: eds,
112
+ precomputedHash: null,
113
+ };
114
+ }
115
+
116
+ // An FnDataset over an engine Dataset this module made and never shares.
117
+ function wrapEngine(eds) {
118
+ return new FnDataset(engineBackend(eds));
119
+ }
120
+
121
+ // ds (array-backed FnDataset) -> engine Dataset, opened once from its quads.
122
+ const ENGINE_CACHE = new WeakMap();
123
+
99
124
  // Build a de-duplicated FnDataset from any iterable of RDF/JS quads.
100
125
  // Every public constructor path (fromDataset, union, difference,
101
126
  // filter, mapQuads, query's CONSTRUCT wrapping, builder().finish())
@@ -108,7 +133,7 @@ function makeFnDataset(quadsIterable) {
108
133
  const out = [];
109
134
  for (const q of quadsIterable) {
110
135
  const frozen = dataFactory.fromQuad(q); // normalizes + (re)freezes
111
- const key = quadToNQuads(frozen);
136
+ const key = quadKey(frozen); // RDF/JS Term.equals identity, no syntax
112
137
  if (seen.has(key)) continue;
113
138
  seen.add(key);
114
139
  out.push(frozen);
@@ -147,14 +172,15 @@ class FnDataset {
147
172
  toNQuads() {
148
173
  let cached = NQUADS_CACHE.get(this);
149
174
  if (cached === undefined) {
150
- cached = quadsToNQuads(this.toArray());
175
+ cached = this._backend.engine ? this._backend.engine.toNQuads() : quadsToNQuads(this.toArray());
151
176
  NQUADS_CACHE.set(this, cached);
152
177
  }
153
178
  return cached;
154
179
  }
155
180
 
156
- /** Read-only quad-pattern match (RDF/JS DatasetCore shape), no engine call. */
181
+ /** Read-only quad-pattern match (RDF/JS DatasetCore shape); the engine's indexes for an engine-backed dataset. */
157
182
  match(subject, predicate, object, graph) {
183
+ if (this._backend.engine) return wrapEngine(this._backend.engine.match(subject, predicate, object, graph));
158
184
  return makeFnDataset(this.toArray().filter((q) =>
159
185
  (!subject || subject.equals(q.subject)) &&
160
186
  (!predicate || predicate.equals(q.predicate)) &&
@@ -170,18 +196,31 @@ const EMPTY = new FnDataset(arrayBackend(Object.freeze([])));
170
196
  // Interop with the mutable RDF/JS layer.
171
197
  // ---------------------------------------------------------------------
172
198
 
173
- /** Snapshot a (possibly mutable) RDF/JS Dataset into an FnDataset. */
199
+ /** Snapshot a Dataset (the engine's, or an RDF/JS DatasetCore) into an FnDataset. */
174
200
  function fromDataset(dataset) {
175
- if (!(dataset instanceof Dataset)) {
176
- throw new TypeError('fromDataset: expected an RDF/JS Dataset');
201
+ if (dataset instanceof engineApi.Dataset) return wrapEngine(dataset.clone());
202
+ if (!(dataset instanceof DatasetCore)) {
203
+ throw new TypeError('fromDataset: expected a Dataset or an RDF/JS DatasetCore');
177
204
  }
178
205
  return makeFnDataset(dataset);
179
206
  }
180
207
 
181
- /** Materialize an FnDataset into a fresh, independently-mutable Dataset. */
208
+ // The engine Dataset of an FnDataset: its own, or (for one built from JS
209
+ // quads) one opened from its quads once and kept.
210
+ async function engineOf(ds) {
211
+ if (ds._backend.engine) return ds._backend.engine;
212
+ let eds = ENGINE_CACHE.get(ds);
213
+ if (!eds) {
214
+ eds = await engineApi.fromQuads(ds.toArray());
215
+ ENGINE_CACHE.set(ds, eds);
216
+ }
217
+ return eds;
218
+ }
219
+
220
+ /** Materialize an FnDataset into a fresh, independently-mutable RDF/JS DatasetCore. */
182
221
  function toDataset(ds) {
183
222
  assertFnDataset(ds, 'toDataset');
184
- return new Dataset(ds.toArray());
223
+ return new DatasetCore(ds.toArray());
185
224
  }
186
225
 
187
226
  // ---------------------------------------------------------------------
@@ -247,7 +286,7 @@ async function fromChunks(chunks) {
247
286
 
248
287
  /** Parse one RDF document into an FnDataset. Mirrors index.js's parse(). */
249
288
  async function parse(text, options) {
250
- return fromDataset(await engineApi.parse(text, options));
289
+ return wrapEngine(await engineApi.parse(text, options));
251
290
  }
252
291
 
253
292
  /** Set union, first-seen order (a's quads, then b's not already present). */
@@ -259,8 +298,8 @@ function union(a, b) {
259
298
  /** Quads in a that are not in b. */
260
299
  function difference(a, b) {
261
300
  assertFnDataset(a, 'difference'); assertFnDataset(b, 'difference');
262
- const bKeys = new Set(b.toArray().map(quadToNQuads));
263
- return makeFnDataset(a.toArray().filter((q) => !bKeys.has(quadToNQuads(q))));
301
+ const bKeys = new Set(b.toArray().map(quadKey));
302
+ return makeFnDataset(a.toArray().filter((q) => !bKeys.has(quadKey(q))));
264
303
  }
265
304
 
266
305
  /** Keep quads matching quadPred(quad) => boolean. */
@@ -291,31 +330,22 @@ function mapQuads(ds, f) {
291
330
 
292
331
  /**
293
332
  * Run a SPARQL 1.1 query. SELECT -> Bindings[]; ASK -> boolean;
294
- * CONSTRUCT -> FnDataset. Delegates entirely to index.js's query() —
295
- * same capability gating (CONSTRUCT needs the npm-entry bundle; its
296
- * absence throws the existing "pending npm-entry build" Error).
333
+ * CONSTRUCT and DESCRIBE -> FnDataset. Delegates entirely to index.js's
334
+ * query().
297
335
  */
298
336
  async function query(ds, sparql, options) {
299
337
  assertFnDataset(ds, 'query');
300
- const result = await engineApi.query(toDataset(ds), sparql, options);
301
- return result instanceof Dataset ? fromDataset(result) : result;
338
+ const result = await engineApi.query((await engineOf(ds)), sparql, options);
339
+ return result instanceof engineApi.Dataset ? wrapEngine(result) : result;
302
340
  }
303
341
 
304
342
  /**
305
343
  * Materialize an entailment closure as a new FnDataset.
306
344
  *
307
- * Reuses query()'s existing entailment support rather than adding new
308
- * engine plumbing — but *not* via CONSTRUCT: the npm-entry ABI's
309
- * queryDataset has no entailment parameter (entailment closure stays
310
- * on the CLI path, per lib/api.js), and the CLI path does not support
311
- * CONSTRUCT at all, so "CONSTRUCT ... WHERE ... { entail }" is not
312
- * reachable through the existing API today. Instead this runs
313
- * `SELECT ?s ?p ?o WHERE { ?s ?p ?o }` with the entailment option
314
- * (exactly the combination test/api.test.js's "query: entail RDFS
315
- * infers subclass instances" already exercises) and repackages each
316
- * solution row as a quad — pure JS reshaping of already-materialized
317
- * bindings, not new RDF/SPARQL semantics, so it works with the CLI
318
- * bundle alone (no npm-entry bundle required).
345
+ * Reuses query()'s entailment support: it runs
346
+ * `SELECT ?s ?p ?o WHERE { ?s ?p ?o }` with the entailment option (the
347
+ * engine closes the default graph under the regime, then answers the
348
+ * query; op queryRaw) and repackages each solution row as a quad.
319
349
  *
320
350
  * Scope limitation (documented, not silent): like a bare
321
351
  * `WHERE { ?s ?p ?o }` in SPARQL generally, this closes over the
@@ -324,71 +354,32 @@ async function query(ds, sparql, options) {
324
354
  * per-graph closure semantics that the underlying query() does not
325
355
  * define today.
326
356
  */
327
- // Case-insensitive regime aliases ('rdfs', 'owl-rl', 'owlrl', 'owl_rl')
328
- // normalized to the engine's exact-case ENTAIL_VALUES spelling ('RDFS',
329
- // 'OWL-RL'); anything else (including already-correct casing, or a
330
- // genuinely invalid value) passes through unchanged so engineApi.query's
331
- // own validation reports the honest error rather than this function
332
- // guessing at what the caller meant.
333
- const ENTAIL_REGIME_ALIASES = {
334
- none: 'none', rdfs: 'RDFS', 'owl-rl': 'OWL-RL', owlrl: 'OWL-RL', owl_rl: 'OWL-RL',
335
- };
336
-
337
- function normalizeEntailRegime(regime) {
338
- const key = String(regime == null ? 'none' : regime).toLowerCase();
339
- return ENTAIL_REGIME_ALIASES[key] || regime;
340
- }
341
-
342
- // x-ikl-* is NOT IMPLEMENTED. It is not withheld by policy.
343
- //
344
- // CORRECTION 2026-08-26: an earlier version of this comment said the
345
- // family was withheld by owner decision, citing the direction-B ruling
346
- // of https://github.com/danbri/factoidal/issues/618. That ruling was
347
- // about the IKL-to-RDF projection, not about this regime family, and
348
- // attributing it here misstated a decision the owner did not make.
349
- //
350
- // The x-ikl-* family is the OWNER'S design
351
- // (https://github.com/danbri/factoidal/issues/581). Its Lean dispatch
352
- // was deleted on 2026-08-26 as collateral of the projection purge
353
- // (https://github.com/danbri/factoidal/issues/626), not as its target.
354
- // The SEMANTICS survived: Unified/ClBridge.lean's asserted_merge_sound
355
- // is this regime's soundness statement -- lifting asserted named-graph
356
- // content into the default graph -- and it carries no naming scheme.
357
- // Restoring the family is a dispatch branch plus flipping this guard.
358
- //
359
- // The owner's own statement of what IKL does not supply, 2026-08-26:
360
- // no profiles, no entailment procedures, no mapping from RDF datasets.
361
- // Checked the same day against the IKL GUIDE and Hayes 2009: correct.
362
- //
363
- // engineApi.query() (lib/api.js) already rejects this, but
364
- // normalizeEntailRegime() above passes any unrecognised string through
365
- // UNCHANGED before it gets there — check explicitly here too, so this
366
- // function's own contract states the rule rather than depending on a
367
- // downstream check someone could relax without noticing this call
368
- // site. Case-insensitive, any suffix; see test/select.test.js.
369
- function rejectIklRegime(regime, who) {
370
- if (regime != null && /^x-ikl/i.test(String(regime))) {
371
- throw new TypeError(
372
- `${who}: entail '${regime}' is not implemented. The x-ikl-* ` +
373
- 'entailment regimes are the owner\'s design ' +
374
- '(danbri/factoidal#581); the Lean engine\'s dispatch for them was ' +
375
- 'deleted on 2026-08-26 as collateral of the IKL-to-RDF projection ' +
376
- 'purge (danbri/factoidal#626). This is not a policy exclusion.');
357
+ // The regime names, their case-insensitive aliases and the x-ikl-* refusal
358
+ // are the engine's tables (op engineTables): no host copy
359
+ // (https://github.com/danbri/factoidal/issues/894 item 5). A name with no
360
+ // alias passes through unchanged and engineApi.query reports it.
361
+ async function regimeOf(regime, who) {
362
+ const t = await engineApi.engineTables();
363
+ const r = regime == null ? 'none' : String(regime);
364
+ for (const [prefix, message] of Object.entries(t.refusedRegimePrefixes)) {
365
+ if (r.toLowerCase().startsWith(prefix)) {
366
+ throw new TypeError(message.replace('WHO', who).replace('REGIME', r));
367
+ }
377
368
  }
369
+ return t.entailAliases[r.toLowerCase()] || regime;
378
370
  }
379
371
 
380
372
  async function entail(ds, regime) {
381
373
  assertFnDataset(ds, 'entail');
382
- rejectIklRegime(regime, 'entail');
383
- const rows = await engineApi.query(
384
- toDataset(ds), 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }',
385
- { entail: normalizeEntailRegime(regime) });
374
+ const entailRegime = await regimeOf(regime, 'entail');
375
+ const rows = await engineApi.query((await engineOf(ds)), 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }',
376
+ { entail: entailRegime });
386
377
  return makeFnDataset(
387
378
  rows.map((row) => dataFactory.quad(row.get('s'), row.get('p'), row.get('o'))));
388
379
  }
389
380
 
390
381
  /**
391
- * SHACL Core validation. Needs the npm-entry engine bundle. Neither
382
+ * SHACL Core validation. Neither
392
383
  * argument is mutated or consumed -- both stay valid FnDatasets after
393
384
  * the call, same as every other op in this module.
394
385
  *
@@ -401,13 +392,13 @@ async function entail(ds, regime) {
401
392
  async function validate(ds, shapes) {
402
393
  assertFnDataset(ds, 'validate');
403
394
  assertFnDataset(shapes, 'validate');
404
- const r = await engineApi.shaclValidate(toDataset(ds), toDataset(shapes));
405
- return { conforms: r.conforms, report: fromDataset(r.report) };
395
+ const r = await engineApi.shaclValidate((await engineOf(ds)), (await engineOf(shapes)));
396
+ return { conforms: r.conforms, report: wrapEngine(r.report) };
406
397
  }
407
398
 
408
399
  /**
409
400
  * ShEx (Shape Expressions) validation of one focus node against one
410
- * shape. Needs the npm-entry engine bundle.
401
+ * shape.
411
402
  *
412
403
  * @param {FnDataset} ds the data graph
413
404
  * @param {string} schema ShExJ (JSON Schema form), as text
@@ -420,14 +411,13 @@ async function validate(ds, shapes) {
420
411
  */
421
412
  async function shex(ds, schema, focus, shape) {
422
413
  assertFnDataset(ds, 'shex');
423
- return engineApi.shexValidate(toDataset(ds), schema, focus, shape);
414
+ return engineApi.shexValidate((await engineOf(ds)), schema, focus, shape);
424
415
  }
425
416
 
426
417
  /**
427
418
  * Evaluate an RML mapping graph against one logical source's raw
428
- * data, materializing the generated triples as a new FnDataset. Needs
429
- * the npm-entry engine bundle. Scope cut (documented, not silent):
430
- * every triples map in `mapping` reads the SAME `source` -- joins
419
+ * data, materializing the generated triples as a new FnDataset. Every
420
+ * triples map in `mapping` reads the SAME `source` -- joins
431
421
  * across two different logical sources are not reachable through this
432
422
  * one-source entry point (see engineApi.rmlMap's doc comment).
433
423
  *
@@ -438,13 +428,13 @@ async function shex(ds, schema, focus, shape) {
438
428
  */
439
429
  async function fromMapping(mapping, source, kind) {
440
430
  assertFnDataset(mapping, 'fromMapping');
441
- return fromDataset(await engineApi.rmlMap(toDataset(mapping), source, kind));
431
+ return wrapEngine(await engineApi.rmlMap((await engineOf(mapping)), source, kind));
442
432
  }
443
433
 
444
434
  /**
445
435
  * CSVW csv2rdf conversion (w3.org/TR/csv2rdf): convert raw tabular
446
436
  * data plus an optional CSVW metadata document into a new FnDataset.
447
- * Needs the npm-entry engine bundle. Unlike fromMapping there is no
437
+ * Unlike fromMapping there is no
448
438
  * FnDataset input -- both arguments are raw text (CSVW's metadata
449
439
  * format is JSON, not RDF). Scope cut (documented, not silent --
450
440
  * mirrors fromMapping's one-source cut): every table in a multi-table
@@ -461,14 +451,13 @@ async function fromMapping(mapping, source, kind) {
461
451
  * @returns {Promise<FnDataset>}
462
452
  */
463
453
  async function fromCsvw(csv, metadata, options) {
464
- return fromDataset(await engineApi.csvwToRdf(csv, metadata, options));
454
+ return wrapEngine(await engineApi.csvwToRdf(csv, metadata, options));
465
455
  }
466
456
 
467
457
  /**
468
458
  * RIF Core forward-chaining saturation, materialized as a new
469
459
  * FnDataset (input triples + derived triples, default graph only --
470
- * RIF Core has no named-graph notion). Needs the npm-entry engine
471
- * bundle.
460
+ * RIF Core has no named-graph notion).
472
461
  *
473
462
  * @param {FnDataset} ds the premise graph
474
463
  * @param {string} rules a RIF Core XML rule document
@@ -476,7 +465,7 @@ async function fromCsvw(csv, metadata, options) {
476
465
  */
477
466
  async function rif(ds, rules) {
478
467
  assertFnDataset(ds, 'rif');
479
- return fromDataset(await engineApi.rifEval(toDataset(ds), rules));
468
+ return wrapEngine(await engineApi.rifEval((await engineOf(ds)), rules));
480
469
  }
481
470
 
482
471
  /**
@@ -489,8 +478,7 @@ async function rif(ds, rules) {
489
478
  * Gutierrez, "Simple and Efficient Minimal RDFS", J. Web Semantics
490
479
  * 7(3), 2009). Mirrors engineApi.coreRdfsClosure's `{ok, ntriples}`
491
480
  * result, with `ntriples` parsed into an FnDataset via
492
- * Dataset.fromNQuads — pure JS, no extra engine round-trip. Needs the
493
- * npm-entry engine bundle. `rhoDfClosure` is kept below as a
481
+ * the engine Dataset of the closure. `rhoDfClosure` is kept below as a
494
482
  * literature-name alias.
495
483
  * @param {FnDataset} ds
496
484
  * @param {{format?: string}} [options]
@@ -498,17 +486,15 @@ async function rif(ds, rules) {
498
486
  */
499
487
  async function coreRdfsClosure(ds, options) {
500
488
  assertFnDataset(ds, 'coreRdfsClosure');
501
- const r = await engineApi.coreRdfsClosure(toDataset(ds), options);
502
- return { ok: r.ok, dataset: fromDataset(Dataset.fromNQuads(r.ntriples)) };
489
+ const r = await engineApi.coreRdfsClosure((await engineOf(ds)), options);
490
+ return { ok: true, dataset: wrapEngine(r) };
503
491
  }
504
492
  /** Literature-name alias for coreRdfsClosure (ρdf; see above). */
505
493
  const rhoDfClosure = coreRdfsClosure;
506
494
 
507
495
  /**
508
- * Decidable core-RDFS fragment check (`is_rho_df_frag`, tied by an F*
509
- * lemma to the prop the regime theorems quantify over): does the
510
- * certified coreRdfsClosure guarantee apply to `ds`? Needs the
511
- * npm-entry engine bundle. `rhoDfFragmentCheck` is kept below as a
496
+ * Decidable core-RDFS fragment check (L4Factoidal/RDFS, `isRhoDfFrag`):
497
+ * is `ds` in the core-RDFS fragment coreRdfsClosure is defined for? `rhoDfFragmentCheck` is kept below as a
512
498
  * literature-name alias.
513
499
  * @param {FnDataset} ds
514
500
  * @param {{format?: string}} [options]
@@ -516,7 +502,7 @@ const rhoDfClosure = coreRdfsClosure;
516
502
  */
517
503
  async function coreRdfsCheck(ds, options) {
518
504
  assertFnDataset(ds, 'coreRdfsCheck');
519
- return engineApi.coreRdfsCheck(toDataset(ds), options);
505
+ return engineApi.coreRdfsCheck((await engineOf(ds)), options);
520
506
  }
521
507
  /** Literature-name alias for coreRdfsCheck (ρdf; see above). */
522
508
  const rhoDfFragmentCheck = coreRdfsCheck;
@@ -529,19 +515,17 @@ const rhoDfFragmentCheck = coreRdfsCheck;
529
515
  * Allemang & Hendler 2008; "RDFS++", AllegroGraph). Every OWL row
530
516
  * carries a proved licensing + truth lemma; no chain-level
531
517
  * completeness claim (theorem registry) — weaker than
532
- * coreRdfsClosure's decides-iff guarantee. Needs the npm-entry engine
533
- * bundle.
518
+ * coreRdfsClosure's decides-iff guarantee.
534
519
  * @param {FnDataset} ds
535
520
  * @param {{format?: string}} [options]
536
- * @returns {Promise<{ok: boolean, dataset: FnDataset, rounds: number}>}
521
+ * @returns {Promise<{ok: boolean, dataset: FnDataset}>}
537
522
  */
538
523
  async function rdfsPlusClosure(ds, options) {
539
524
  assertFnDataset(ds, 'rdfsPlusClosure');
540
- const r = await engineApi.rdfsPlusClosure(toDataset(ds), options);
525
+ const r = await engineApi.rdfsPlusClosure((await engineOf(ds)), options);
541
526
  return {
542
- ok: r.ok,
543
- dataset: fromDataset(Dataset.fromNQuads(r.ntriples)),
544
- rounds: r.rounds,
527
+ ok: true,
528
+ dataset: wrapEngine(r),
545
529
  };
546
530
  }
547
531
 
@@ -551,7 +535,7 @@ async function rdfsPlusClosure(ds, options) {
551
535
  * individual the model-construction reasoner proves is a member of an
552
536
  * OWL class expression (someValuesFrom / hasValue / unionOf /
553
537
  * intersectionOf, and the named class an equivalentClass restriction
554
- * defines). Needs the npm-entry engine bundle. Default graph only.
538
+ * defines). Default graph only.
555
539
  *
556
540
  * @param {FnDataset} ds the ontology + ABox graph
557
541
  * @returns {Promise<{dataset: FnDataset, addedCount: number}>} dataset
@@ -560,31 +544,29 @@ async function rdfsPlusClosure(ds, options) {
560
544
  */
561
545
  async function tableauMaterialise(ds) {
562
546
  assertFnDataset(ds, 'tableauMaterialise');
563
- const r = await engineApi.tableauMaterialise(toDataset(ds));
564
- return { dataset: fromDataset(r.dataset), addedCount: r.addedCount };
547
+ const r = await engineApi.tableauMaterialise((await engineOf(ds)));
548
+ return { dataset: wrapEngine(r.dataset), addedCount: r.addedCount };
565
549
  }
566
550
 
567
551
  /**
568
552
  * OWL DL inconsistency verdict (bin/owl-runner's DL pipeline: OWL-RL
569
553
  * closure -> tableau materialise -> OWL-RL closure -> is_inconsistent).
570
554
  * `rlAlone` is the plain OWL-RL verdict on the same input, so a caller
571
- * can see the cases the tableau adds. Needs the npm-entry engine
572
- * bundle. Default graph only.
555
+ * can see the cases the tableau adds. Default graph only.
573
556
  *
574
557
  * @param {FnDataset} ds the ontology + ABox graph
575
558
  * @returns {Promise<{inconsistent: boolean, rlAlone: boolean}>}
576
559
  */
577
560
  async function tableauDlInconsistent(ds) {
578
561
  assertFnDataset(ds, 'tableauDlInconsistent');
579
- return engineApi.tableauDlInconsistent(toDataset(ds));
562
+ return engineApi.tableauDlInconsistent((await engineOf(ds)));
580
563
  }
581
564
 
582
565
  /**
583
566
  * OWL DL consistency verdict via the verified clash-detecting tableau
584
567
  * (formal/fstar/Tableau.Refute.fst's `tableau_consistent` over the
585
568
  * OWL-RL closure -- the pure verified chain bin/owl-runner runs under
586
- * `--regime dl`, minus its native-only z3 oracle). Needs the npm-entry
587
- * bundle. Default graph only.
569
+ * `--regime dl`, minus its native-only z3 oracle). Default graph only.
588
570
  *
589
571
  * `consistent` is three-valued: `false` (a clash on every tableau
590
572
  * branch), `true` (a model was constructed), or `null` -- the refuter
@@ -597,7 +579,7 @@ async function tableauDlInconsistent(ds) {
597
579
  * @returns {Promise<{consistent: boolean|null, reason?: string}>}
598
580
  */
599
581
  async function owlIsConsistent(ontology, options) {
600
- const data = ontology instanceof FnDataset ? toDataset(ontology) : ontology;
582
+ const data = ontology instanceof FnDataset ? (await engineOf(ontology)) : ontology;
601
583
  return engineApi.owlIsConsistent(data, options);
602
584
  }
603
585
 
@@ -605,7 +587,7 @@ async function owlIsConsistent(ontology, options) {
605
587
  * OWL entailment check: does `premise` entail `conclusion`? Verified
606
588
  * two-path dispatch (`via: "closure"` for the OWL-RL closure path,
607
589
  * `via: "refutation"` for negate-and-refute), mirroring bin/owl-runner.
608
- * Needs the npm-entry bundle. Default graph only. `entailed` is
590
+ * Default graph only. `entailed` is
609
591
  * three-valued (`true` / `false` / `null` budget-out, `reason` names the
610
592
  * cap).
611
593
  *
@@ -615,20 +597,20 @@ async function owlIsConsistent(ontology, options) {
615
597
  * @returns {Promise<{entailed: boolean|null, via: 'closure'|'refutation', reason?: string}>}
616
598
  */
617
599
  async function owlEntails(premise, conclusion, options) {
618
- const p = premise instanceof FnDataset ? toDataset(premise) : premise;
619
- const c = conclusion instanceof FnDataset ? toDataset(conclusion) : conclusion;
600
+ const p = premise instanceof FnDataset ? (await engineOf(premise)) : premise;
601
+ const c = conclusion instanceof FnDataset ? (await engineOf(conclusion)) : conclusion;
620
602
  return engineApi.owlEntails(p, c, options);
621
603
  }
622
604
 
623
605
  /**
624
- * RDFC-1.0 canonicalization: canonical N-Quads text. Needs the
625
- * npm-entry bundle (same gating as index.js's canonicalize()).
606
+ * RDFC-1.0 canonicalization: canonical N-Quads text (index.js's
607
+ * canonicalize()).
626
608
  */
627
609
  async function canonicalize(ds) {
628
610
  assertFnDataset(ds, 'canonicalize');
629
611
  let cached = CANON_CACHE.get(ds);
630
612
  if (cached === undefined) {
631
- const p = engineApi.canonicalize(toDataset(ds)).then((text) => {
613
+ const p = engineApi.canonicalize((await engineOf(ds))).then((text) => {
632
614
  CANON_CACHE.set(ds, text); // replace the in-flight promise
633
615
  return text;
634
616
  });
@@ -677,111 +659,34 @@ function peekHash(ds) {
677
659
  return typeof c === 'string' ? c : null;
678
660
  }
679
661
 
680
- function hasBlankNode(ds) {
681
- for (const q of ds) {
682
- if (q.subject.termType === 'BlankNode') return true;
683
- if (q.object.termType === 'BlankNode') return true;
684
- if (q.graph.termType === 'BlankNode') return true;
685
- }
686
- return false;
687
- }
688
-
689
662
  /**
690
- * Structural equality, cheapest-correct-path first (see the design
691
- * doc's cost model section for the full argument):
692
- *
693
- * 1. Different sizes -> not equal, O(1).
694
- * 2. Both sides already have a memoized hash -> compare those, O(1).
695
- * 3. Exact quad-set match (same terms, same labels) -> equal, O(n).
696
- * This is sound regardless of blank nodes: identical tokens can
697
- * never be a false positive.
698
- * 4. No blank nodes anywhere -> the step-3 negative is authoritative
699
- * (ground quads have no relabeling to hide behind) -> not equal.
700
- * 5. Otherwise (blank nodes present, step 3 was inconclusive) ->
701
- * the only sound test left is RDFC-1.0 canonical-hash equality,
702
- * which is exactly the O(n log n) canonicalize() cost this module
703
- * tries to avoid paying twice.
663
+ * Dataset isomorphism (RDF 1.1 Concepts 3.6 and 4, blank nodes inside RDF
664
+ * 1.2 triple terms included), decided by the engine
665
+ * (Dataset.isomorphicOutcome, op datasetIsomorphic). The same FnDataset is
666
+ * equal to itself without a call.
704
667
  */
705
668
  async function equals(a, b) {
706
669
  assertFnDataset(a, 'equals'); assertFnDataset(b, 'equals');
707
670
  if (a === b) return true;
708
- if (a.size !== b.size) return false;
709
- const ha = peekHash(a);
710
- const hb = peekHash(b);
711
- if (ha !== null && hb !== null) return ha === hb;
712
- const aKeys = new Set(a.toArray().map(quadToNQuads));
713
- const bTokens = b.toArray().map(quadToNQuads);
714
- const exact = bTokens.length === aKeys.size &&
715
- bTokens.every((t) => aKeys.has(t));
716
- if (exact) return true;
717
- if (!hasBlankNode(a) && !hasBlankNode(b)) return false;
718
- const [h1, h2] = await Promise.all([hash(a), hash(b)]);
719
- return h1 === h2;
720
- }
721
-
722
- /**
723
- * Open a COTTAS/Parquet artifact's raw bytes as a queryable, read-only
724
- * store (docs/designissues/2026-07-06-inmemory-bytes-store.md, browser
725
- * call site). Needs the npm-entry engine bundle. Unlike every other
726
- * constructor in this module, the returned object is NOT an FnDataset:
727
- * the whole point of the design is that rows decode lazily as a query
728
- * touches them, never materializing the corpus into heap FnDataset
729
- * quads (measured 64-161 B/quad vs. an FnDataset/heap Dataset's
730
- * ~877 B/quad for the same data, in the design doc's native numbers).
731
- *
732
- * @param {string|Uint8Array|ArrayBuffer} bytes whole `.cottas` file contents
733
- * @returns {Promise<{handle: string,
734
- * query: (sparql: string) => Promise<Array<Map<string,object>>|boolean|FnDataset>,
735
- * close: () => Promise<void>}>}
736
- * query() divergences from fn.query() (documented, not silent): no
737
- * entail option, no write/--delta-log overlay (read-only), and a
738
- * query shape the backend executor can't push down rejects instead
739
- * of silently falling back to a full materialize (see
740
- * engineApi.queryCottas's doc comment). CONSTRUCT still returns an
741
- * FnDataset (materialized once for that query only).
742
- */
743
- async function openCottas(bytes) {
744
- const handle = await engineApi.openCottas(bytes);
745
- let closed = false;
746
- return {
747
- handle,
748
- async query(sparql) {
749
- if (closed) throw new Error('openCottas store: query() called after close()');
750
- const result = await engineApi.queryCottas(handle, sparql);
751
- return result instanceof Dataset ? fromDataset(result) : result;
752
- },
753
- async close() {
754
- if (closed) return;
755
- closed = true;
756
- await engineApi.closeCottas(handle);
757
- },
758
- };
671
+ return engineApi.isomorphic(await engineOf(a), await engineOf(b));
759
672
  }
760
673
 
761
674
  /**
762
- * Serialize an FnDataset to COTTAS/Parquet bytes via the native writer
763
- * (the same pure `Tot` F* function `factoidal compact --native-writer`
764
- * uses). Needs the npm-entry engine bundle. Round-trips through
765
- * openCottas(): feeding the result straight back into openCottas()
766
- * reproduces the same queryable store.
767
- *
768
- * @param {FnDataset} ds
769
- * @returns {Promise<Uint8Array>}
770
- */
771
- async function toCottas(ds) {
772
- assertFnDataset(ds, 'toCottas');
773
- return engineApi.toCottas(toDataset(ds));
774
- }
775
-
776
- /**
777
- * Enumerate named graphs (default graph excluded), first-seen order.
778
- * Reuses index.js's graphs() enumeration; wraps each per-graph
779
- * Dataset back into an FnDataset.
675
+ * Enumerate named graphs (default graph excluded), first-seen order. An
676
+ * engine-backed dataset asks the engine (op datasetGraphNames); an array of
677
+ * JS quads groups by RDF/JS Term.equals identity, so an IRI and a blank node
678
+ * with the same string are two graphs.
780
679
  */
781
680
  function graphs(ds) {
782
681
  assertFnDataset(ds, 'graphs');
783
- return engineApi.graphs(toDataset(ds))
784
- .map(([iri, graphDataset]) => [iri, fromDataset(graphDataset)]);
682
+ if (ds._backend.engine) {
683
+ return engineApi.graphs(ds._backend.engine).map(([name, g]) => [name, wrapEngine(g)]);
684
+ }
685
+ const seen = new Map();
686
+ for (const q of ds) {
687
+ if (q.graph.termType !== 'DefaultGraph' && !seen.has(termKey(q.graph))) seen.set(termKey(q.graph), q.graph);
688
+ }
689
+ return [...seen.values()].map((g) => [g, ds.match(null, null, null, g)]);
785
690
  }
786
691
 
787
692
  // ---------------------------------------------------------------------
@@ -860,7 +765,7 @@ function pipe(...fns) {
860
765
  // -----------------------------------------------------------------
861
766
  // Typed engine functions (#74). Re-exported unchanged from the JS
862
767
  // engine api — each is already a pure, value-in / value-out function
863
- // over one F*-extracted engine (XSLT, MathML, XForms, JSON Schema,
768
+ // over one engine op (XSLT, MathML, XForms, JSON Schema,
864
769
  // Schematron, TOAN CAS, matrix algebra), so they belong in the
865
770
  // functional surface as-is. See index.d.ts / fn.d.ts for signatures.
866
771
  // -----------------------------------------------------------------
@@ -875,12 +780,6 @@ const {
875
780
  toanSimplify,
876
781
  toanDiff,
877
782
  toanSubst,
878
- matrixDeterminant,
879
- matrixScalarProduct,
880
- matrixVectorProduct,
881
- matrixOuterProduct,
882
- sigmoidPoints,
883
- sigmoidFormulaMathml,
884
783
  vcSha256Hex,
885
784
  vcEd25519SecretToPublic,
886
785
  vcEd25519Sign,
@@ -921,8 +820,6 @@ module.exports = {
921
820
  canonicalize,
922
821
  hash,
923
822
  equals,
924
- openCottas,
925
- toCottas,
926
823
  graphs,
927
824
  cell,
928
825
  derive,
@@ -938,12 +835,6 @@ module.exports = {
938
835
  toanSimplify,
939
836
  toanDiff,
940
837
  toanSubst,
941
- matrixDeterminant,
942
- matrixScalarProduct,
943
- matrixVectorProduct,
944
- matrixOuterProduct,
945
- sigmoidPoints,
946
- sigmoidFormulaMathml,
947
838
  vcSha256Hex,
948
839
  vcEd25519SecretToPublic,
949
840
  vcEd25519Sign,