eyeling 1.34.0 → 1.34.1

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 CHANGED
@@ -818,7 +818,7 @@ Formula-aware built-ins make Eyeling useful for meta-reasoning. `log:includes`,
818
818
 
819
819
  ### eyelang built-ins
820
820
 
821
- The eyelang engine has its own built-in registry under `lib/eyelang/builtins/`. These are separate from the N3 namespaces above and are called as ordinary eyelang predicates. See the [eyelang language reference](docs/eyelang-language-reference.md#9-standard-built-in-predicates) for the portable profile. The bundled implementation currently registers:
821
+ The eyelang engine has its own built-in registry under `lib/eyelang/builtins/`. These are separate from the N3 namespaces above and are called as ordinary eyelang predicates. See the [eyelang language reference](docs/eyelang-language-reference.md#9-standard-built-in-predicates) for the portable profile. The bundled implementation currently registers 68 name/arity entries across 66 predicate names:
822
822
 
823
823
  | Family | Built-ins |
824
824
  |---|---|
@@ -261,7 +261,7 @@ best(Cycle, Cost) :-
261
261
  weighted_hamiltonian_cycle(edge, Cities, Cycle, Cost).
262
262
  ```
263
263
 
264
- The reusable search and numeric helpers include `n_queens/2`, Hamiltonian path/cycle helpers, `bounded_path/5`, `cnf_model/3`, Quine-McCluskey helpers, number-theory helpers such as `extended_gcd/5`, and matrix helpers such as `matrix_multiply/2`. These helpers are extension builtins of this implementation; [the eyelang language reference](eyelang-language-reference.md) defines the portable core and standard builtin profile.
264
+ The reusable search and numeric helpers include `n_queens/2`, Hamiltonian path/cycle helpers, `bounded_path/5`, `cnf_model/3`, Quine-McCluskey helpers, number-theory helpers such as `extended_gcd/5`, and matrix helpers such as `matrix_multiply/2`. These helpers are extension builtins of this implementation; [the eyelang language reference](eyelang-language-reference.md) defines the portable core and standard builtin profile. The complete bundled implementation list is kept in the top-level [README built-ins section](../README.md#built-ins-1), and the regression suite checks that table against the actual runtime registry.
265
265
 
266
266
  To add a builtin, create or extend a module with `register(registry)` and call `registry.add(name, arity, handler, options)`. The default registry is assembled in [`lib/eyelang/builtins/registry.js`](../lib/eyelang/builtins/registry.js). Builtins that are only safe for specific argument modes should provide a `ready` predicate and `fallbackWhenNotReady: true`, so user-defined clauses remain visible until the builtin is applicable.
267
267
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.34.0",
3
+ "version": "1.34.1",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
@@ -196,6 +196,18 @@ why(
196
196
  assertEqual(readmeExamples.join('\n'), examples.join('\n'), 'README example catalog');
197
197
  },
198
198
  },
199
+ {
200
+ name: 'README mirrors the eyelang builtin registry',
201
+ run: () => {
202
+ const actual = registeredBuiltinNames();
203
+ const documented = readmeBuiltinNames();
204
+ assertEqual(documented.join('\n'), actual.join('\n'), 'README builtin catalog');
205
+
206
+ const { entries, names } = readmeBuiltinSummary();
207
+ assertEqual(entries, actual.length, 'README builtin entry count');
208
+ assertEqual(names, new Set(actual.map((item) => item.split('/')[0])).size, 'README builtin name count');
209
+ },
210
+ },
199
211
  {
200
212
  name: 'stdin input is accepted',
201
213
  run: () => {
@@ -499,6 +511,27 @@ function readmeCatalogExampleNames() {
499
511
  .sort();
500
512
  }
501
513
 
514
+ function registeredBuiltinNames() {
515
+ return [...createDefaultRegistry().defs.keys()].sort();
516
+ }
517
+
518
+ function readmeBuiltinNames() {
519
+ const readme = fs.readFileSync(path.join(packageRoot, 'README.md'), 'utf8');
520
+ const section = between(readme, '### eyelang built-ins', '## Custom built-ins');
521
+ return [...section.matchAll(/`([A-Za-z_][A-Za-z0-9_]*)\/(\d+)`/g)]
522
+ .map((match) => `${match[1]}/${match[2]}`)
523
+ .filter((name, index, names) => names.indexOf(name) === index)
524
+ .sort();
525
+ }
526
+
527
+ function readmeBuiltinSummary() {
528
+ const readme = fs.readFileSync(path.join(packageRoot, 'README.md'), 'utf8');
529
+ const section = between(readme, '### eyelang built-ins', '## Custom built-ins');
530
+ const match = section.match(/currently registers (\d+) name\/arity entries across (\d+) predicate names/);
531
+ if (match == null) throw new Error('README builtin summary not found');
532
+ return { entries: Number(match[1]), names: Number(match[2]) };
533
+ }
534
+
502
535
  function playgroundExampleNames() {
503
536
  const html = fs.readFileSync(path.join(root, 'playground.html'), 'utf8');
504
537
  const match = html.match(/const EXAMPLES = \[(.*?)\];/s);