deriva 0.0.12 → 0.0.13

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
@@ -1,7 +1,7 @@
1
1
  # Deriva
2
2
 
3
3
  <p align="left">
4
- <img src="docs/assets/deriva-logo.png" alt="Deriva logo" width="50">
4
+ <img src="docs/assets/deriva-logo.png" alt="Deriva logo" width="70">
5
5
  </p>
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/deriva.svg)](https://www.npmjs.com/package/deriva)
@@ -1,4 +1,4 @@
1
- # Conformance Deriva report
1
+ # Deriva conformance report
2
2
 
3
3
  This report summarizes the file-based conformance corpus under `test/conformance/`.
4
4
 
package/docs/guide.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  This guide introduces Deriva, a small Horn-clause language and engine whose source syntax is Prolog-like but deliberately its own compact language for facts, rules, goals, answers, and proofs. Deriva works over ordinary terms, lists, arithmetic, strings, and finite search. Run it with the `deriva` CLI, or use `node bin/deriva.js` when working directly from a source checkout.
4
4
 
5
+ This documentation uses **Deriva** for the project, language, and engine, and
6
+ `deriva` for the npm package and CLI command.
7
+
5
8
  Programs write relations directly, for example `ancestor(pat, emma)` or `status(case1, accepted)`. Web identifiers can be written as ordinary quoted atoms that include angle brackets, for example `'<https://schema.org/name>'`, when a program needs explicit IRI-shaped names without prefix declarations. Deriva output is ordinary Deriva syntax: by default, the CLI materializes selected answer facts and prints those facts only. Pass `--proof` (or `-p`) when you also want each answer followed by a `why/2` explanation fact that records the proof. Programs may add `materialize/2` declarations such as `materialize(answer, 2).` to focus output on selected predicates.
6
9
 
7
10
  Execution is automatically hybrid. Ordinary predicates use indexed
@@ -15,7 +18,7 @@ For the normative language definition, including lexical syntax, terms, clauses,
15
18
  ## Contents
16
19
 
17
20
  1. [Quick start](#quick-start)
18
- 2. [Running deriva](#running-deriva)
21
+ 2. [Running the `deriva` CLI](#running-the-deriva-cli)
19
22
  3. [Default output](#default-output)
20
23
  4. [Writing programs](#writing-programs)
21
24
  5. [Aggregation helpers](#aggregation-helpers)
@@ -61,7 +64,7 @@ deriva --version
61
64
 
62
65
  `npm install -g .` is another local-checkout option if you want npm to install the package globally instead of linking it. Avoid hand-written `/usr/local/bin` symlinks unless you really need one; npm already reads the `bin` entry in `package.json` and creates the correct executable shim.
63
66
 
64
- ## Running deriva
67
+ ## Running the `deriva` CLI
65
68
 
66
69
  The commands in this section use `deriva` for readability. In a source checkout where you have not run `npm link` or `npm install -g .`, replace `deriva` with `node bin/deriva.js`, or run the command through `npm exec --yes --package=. -- deriva`.
67
70
 
@@ -72,7 +75,7 @@ deriva --version
72
75
  deriva -v
73
76
  ```
74
77
 
75
- Run a program and let deriva print derived binary facts:
78
+ Run a program and let Deriva print derived binary facts:
76
79
 
77
80
  ```sh
78
81
  deriva examples/ancestor.pl
@@ -85,7 +88,7 @@ deriva --proof examples/ancestor.pl
85
88
  deriva -p examples/ancestor.pl
86
89
  ```
87
90
 
88
- deriva-readable explanations are opt-in proof output. Each `why/2` fact contains a nested abstract proof term, and a blank line separates consecutive explanations. Using deriva syntax for explanations keeps them in the same language as the answers themselves: they are readable by humans, parseable by deriva, easy to test, and can be transformed or explained further like any other deriva data. For example:
91
+ Deriva-readable explanations are opt-in proof output. Each `why/2` fact contains a nested abstract proof term, and a blank line separates consecutive explanations. Using Deriva syntax for explanations keeps them in the same language as the answers themselves: they are readable by humans, parseable by Deriva, easy to test, and can be transformed or explained further like any other Deriva data. For example:
89
92
 
90
93
  ```deriva
91
94
  type(socrates, mortal).
@@ -106,7 +109,7 @@ why(
106
109
 
107
110
  ```
108
111
 
109
- The explanation output can itself be read as deriva input; for example, another program can materialize `why/2` facts such as `why(type(socrates, mortal), Proof)`. `--proof` adds only these explanation facts; it does not change the answers found by the solver.
112
+ The explanation output can itself be read as Deriva input; for example, another program can materialize `why/2` facts such as `why(type(socrates, mortal), Proof)`. `--proof` adds only these explanation facts; it does not change the answers found by the solver.
110
113
 
111
114
  ### Explanation cookbook
112
115
 
@@ -181,7 +184,7 @@ ancestor(X, Y) :- parent(X, Y).
181
184
  ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).
182
185
  ```
183
186
 
184
- By default, deriva asks for new ground consequences of selected output predicates, suppresses duplicates, excludes source facts, sorts the result, and prints Prolog facts:
187
+ By default, Deriva asks for new ground consequences of selected output predicates, suppresses duplicates, excludes source facts, sorts the result, and prints Prolog facts:
185
188
 
186
189
  ```deriva
187
190
  ancestor(jan, emma).
@@ -213,7 +216,7 @@ answer(case1, accepted).
213
216
 
214
217
  ## Writing programs
215
218
 
216
- A good deriva program normally has three layers:
219
+ A good Deriva program normally has three layers:
217
220
 
218
221
  1. source facts;
219
222
  2. helper predicates for calculation or search;
@@ -306,7 +309,7 @@ best_cycle(Cycle, Cost) :-
306
309
 
307
310
  ## Context data
308
311
 
309
- Comma terms can be data as well as conjunctions. deriva provides two context utilities:
312
+ Comma terms can be data as well as conjunctions. Deriva provides two context utilities:
310
313
 
311
314
  ```deriva
312
315
  holds((name(alice, "Alice"), knows(alice, bob)), name(S, O)).
@@ -513,13 +516,13 @@ for f in examples/proof/*.pl; do
513
516
  done
514
517
  ```
515
518
 
516
- Run the full deriva suite:
519
+ Run the full Deriva suite:
517
520
 
518
521
  ```sh
519
522
  npm run test:deriva
520
523
  ```
521
524
 
522
- The deriva corpus runner runs in this order: Conformance, Regression/API/White-box, Examples. Each section prints its own subtotal, followed by a suite-specific grand total. The suite checks the conformance cases derived from the language reference, supplemental regression/API/white-box checks, and every runnable example against its golden output.
525
+ The Deriva corpus runner runs in this order: Conformance, Regression/API/White-box, Examples. Each section prints its own subtotal, followed by a suite-specific grand total. The suite checks the conformance cases derived from the language reference, supplemental regression/API/white-box checks, and every runnable example against its golden output.
523
526
 
524
527
  Run only one internal suite when you are iterating:
525
528
 
@@ -537,7 +540,7 @@ node test/run-conformance-report.mjs
537
540
 
538
541
  Release preparation runs the same report and writes [`conformance-report.md`](../conformance-report.md), so each published package carries a current conformance summary.
539
542
 
540
- The conformance suite lives in [`test/conformance/`](../test/conformance/) as a file-based deriva corpus. Positive cases pair `cases/<name>.pl` with exact expected stdout under `expected/<name>.pl`; negative cases pair `errors/<name>.pl` with exact expected error text under `expected-errors/<name>.txt`; warning cases pair `warnings/<name>.pl` with exact `--warnings` stdout and stderr files under `expected-warnings/`; proof cases pair `proofs/<name>.pl` with exact `--proof` output under `expected-proofs/`. Cases may be grouped in category directories such as `arithmetic/`, `strings/`, `lists/`, `terms/`, `atoms/`, `variables/`, `negation/`, and `syntax/`, so another implementation can reuse the same corpus as an executable language contract. The suite covers the standard language surface from the language reference, including reusable built-ins, standard errors, standard warnings, and the machine-readable `why/2` proof-output contract. The regression suite lives in [`test/run-regression.mjs`](../test/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
543
+ The conformance suite lives in [`test/conformance/`](../test/conformance/) as a file-based Deriva corpus. Positive cases pair `cases/<name>.pl` with exact expected stdout under `expected/<name>.pl`; negative cases pair `errors/<name>.pl` with exact expected error text under `expected-errors/<name>.txt`; warning cases pair `warnings/<name>.pl` with exact `--warnings` stdout and stderr files under `expected-warnings/`; proof cases pair `proofs/<name>.pl` with exact `--proof` output under `expected-proofs/`. Cases may be grouped in category directories such as `arithmetic/`, `strings/`, `lists/`, `terms/`, `atoms/`, `variables/`, `negation/`, and `syntax/`, so another implementation can reuse the same corpus as an executable language contract. The suite covers the standard language surface from the language reference, including reusable built-ins, standard errors, standard warnings, and the machine-readable `why/2` proof-output contract. The regression suite lives in [`test/run-regression.mjs`](../test/run-regression.mjs) and covers CLI regressions, the public JavaScript API, and white-box invariants for parser, unification, and indexing behavior.
541
544
 
542
545
  ## Development and release
543
546
 
@@ -570,7 +573,7 @@ The `preversion` script reruns the full test suite and refreshes [`conformance-r
570
573
 
571
574
  ## Relationship to Eyeling
572
575
 
573
- [Eyeling](https://github.com/eyereasoner/eyeling) and deriva share the same goal of small, inspectable rule-based reasoning in JavaScript, but they make different language and implementation trade-offs.
576
+ [Eyeling](https://github.com/eyereasoner/eyeling) and Deriva share the same goal of small, inspectable rule-based reasoning in JavaScript, but they make different language and implementation trade-offs.
574
577
 
575
578
  Eyeling is the RDF/Notation3 member of the family. It reads N3-style triples, quoted formulas, forward rules written with `=>`, backward rules written with `<=`, RDF terms, RDF-JS data, and RDF-oriented streams. That makes it the better fit when data interchange with RDF/N3 tools is the main requirement.
576
579
 
@@ -581,13 +584,13 @@ A useful rule of thumb:
581
584
  | Use case | Prefer | Why |
582
585
  | --- | --- | --- |
583
586
  | RDF/N3 data, triples, prefixes, graph terms, RDF-JS, RDF message streams | Eyeling | The surface language and APIs are RDF/Notation3-native. |
584
- | Compact relational rules over ordinary terms, lists, arithmetic, and finite search | deriva | The syntax is shorter for non-RDF relation programs and output is ordinary facts. |
587
+ | Compact relational rules over ordinary terms, lists, arithmetic, and finite search | Deriva | The syntax is shorter for non-RDF relation programs and output is ordinary facts. |
585
588
  | Human-auditable derivations | Either | Both can emit proof explanations when requested. |
586
- | Large generated Horn-clause workloads | deriva | The engine specializes in predicate/arity indexing, scalar argument indexes, fast fact paths, and materialized output goals. |
589
+ | Large generated Horn-clause workloads | Deriva | The engine specializes in predicate/arity indexing, scalar argument indexes, fast fact paths, and materialized output goals. |
587
590
 
588
- On local smoke benchmarks, deriva is substantially faster on large generated Horn-clause and recursion-heavy workloads. These numbers are 5-run medians with stdout redirected to `/dev/null`, using Node.js `v22.16.0`, deriva from this checkout, and Eyeling package version `1.34.6` with its default output mode. The ratio is `Eyeling median / deriva median`, so larger numbers mean deriva was faster.
591
+ On local smoke benchmarks, Deriva is substantially faster on large generated Horn-clause and recursion-heavy workloads. These numbers are 5-run medians with stdout redirected to `/dev/null`, using Node.js `v22.16.0`, Deriva from this checkout, and Eyeling package version `1.34.6` with its default output mode. The ratio is `Eyeling median / Deriva median`, so larger numbers mean Deriva was faster.
589
592
 
590
- | Example | deriva median | Eyeling median | Ratio |
593
+ | Example | Deriva median | Eyeling median | Ratio |
591
594
  | --- | ---: | ---: | ---: |
592
595
  | `fundamental-theorem-arithmetic` | `0.16 sec` | `2.00 sec` | `12.66x` |
593
596
  | `deep-taxonomy-100000` | `1.69 sec` | `4.72 sec` | `2.79x` |
@@ -597,13 +600,13 @@ On local smoke benchmarks, deriva is substantially faster on large generated Hor
597
600
 
598
601
  Treat these as smoke comparisons rather than a formal benchmark: hardware, Node.js version, package version, CLI startup, and output mode all matter.
599
602
 
600
- The projects are therefore complementary rather than replacements for each other: Eyeling optimizes for Semantic Web interoperability and N3 expressiveness; deriva optimizes for a small standard-looking relational rule language and fast finite goal-directed execution.
603
+ The projects are therefore complementary rather than replacements for each other: Eyeling optimizes for Semantic Web interoperability and N3 expressiveness; Deriva optimizes for a small standard-looking relational rule language and fast finite goal-directed execution.
601
604
 
602
605
  ## Performance notes
603
606
 
604
607
  Use `-s` or `--stats` for a quick sanity check while optimizing solver changes. It prints counters such as `solve_goals_calls`, `unify_calls`, `deterministic_rule_expansions`, `candidate_lists_selected`, `clause_candidates_considered`, `clauses_tried`, `max_depth`, and `max_solver_call_depth` to stderr, leaving normal output stable for golden-file tests. The `max_solver_call_depth` counter is especially useful for browser regressions, where the VM call stack can be tighter than a command-line run. Use `-w` or `--warnings` separately when you want portability diagnostics without enabling stricter parsing.
605
608
 
606
- deriva hashes predicate groups by name and arity, then indexes clauses by scalar argument values. It also builds two-argument composite indexes for scalar pairs and probes those composite indexes without per-lookup heap allocation. This helps both large generated programs with many predicates and selective queries such as:
609
+ Deriva hashes predicate groups by name and arity, then indexes clauses by scalar argument values. It also builds two-argument composite indexes for scalar pairs and probes those composite indexes without per-lookup heap allocation. This helps both large generated programs with many predicates and selective queries such as:
607
610
 
608
611
  ```deriva
609
612
  edge(g1, a, X).
@@ -611,7 +614,7 @@ path(a, Y).
611
614
  status(Case, accepted).
612
615
  ```
613
616
 
614
- Ground facts use a fast path that avoids freshening and copying a rule body. Recursive-predicate detection uses an explicit work stack, which keeps large predicate chains safer in the browser. deriva automatically tables positive recursive groups, including dependencies reached through supported meta-goals and directly materialized relations. Cyclic calls iterate to an answer fixed point before replay. Recursive components containing a negative dependency retain guarded ordinary resolution because positive fixed-point tabling is not a semantics for unstratified negation. The engine also infers common structurally decreasing input positions; calls with an unbound structural input and fully open calls retain ordinary resolution rather than trying to materialize a potentially infinite relation. Authors do not need a search-control declaration.
617
+ Ground facts use a fast path that avoids freshening and copying a rule body. Recursive-predicate detection uses an explicit work stack, which keeps large predicate chains safer in the browser. Deriva automatically tables positive recursive groups, including dependencies reached through supported meta-goals and directly materialized relations. Cyclic calls iterate to an answer fixed point before replay. Recursive components containing a negative dependency retain guarded ordinary resolution because positive fixed-point tabling is not a semantics for unstratified negation. The engine also infers common structurally decreasing input positions; calls with an unbound structural input and fully open calls retain ordinary resolution rather than trying to materialize a potentially infinite relation. Authors do not need a search-control declaration.
615
618
 
616
619
  Predicates can also carry advisory mode and determinism declarations for documentation and host tooling:
617
620
 
@@ -50,7 +50,7 @@
50
50
  - [11.1 Automatic hybrid reasoning](#111-automatic-hybrid-reasoning)
51
51
  - [11.2 Default-output materialization](#112-default-output-materialization)
52
52
  - [11.3 Advisory modes and determinism](#113-advisory-modes-and-determinism)
53
- - [12. deriva Sockets](#12-deriva-sockets)
53
+ - [12. Deriva Sockets](#12-deriva-sockets)
54
54
  - [12.1 Socket vocabulary](#121-socket-vocabulary)
55
55
  - [12.2 Socket example](#122-socket-example)
56
56
  - [12.3 Sockets and AI agents](#123-sockets-and-ai-agents)
@@ -67,7 +67,7 @@
67
67
 
68
68
  ## Abstract
69
69
 
70
- Deriva is a compact definite-clause language whose surface syntax is Prolog-like term and clause syntax with deliberate deriva choices for rule-based programs over ordinary terms, lists, arithmetic, strings, and finite search. A Deriva program is a finite sequence of facts and Horn clauses. The underlying declarative semantics of the pure language is **Herbrand semantics**: constants, compound terms, and lists denote themselves, and predicates denote sets of ground atomic formulas over those terms. Evaluation is goal-directed: goals are solved by unification against facts, rules, and a fixed set of built-in predicates.
70
+ Deriva is a compact definite-clause language whose surface syntax is Prolog-like term and clause syntax with deliberate Deriva choices for rule-based programs over ordinary terms, lists, arithmetic, strings, and finite search. A Deriva program is a finite sequence of facts and Horn clauses. The underlying declarative semantics of the pure language is **Herbrand semantics**: constants, compound terms, and lists denote themselves, and predicates denote sets of ground atomic formulas over those terms. Evaluation is goal-directed: goals are solved by unification against facts, rules, and a fixed set of built-in predicates.
71
71
 
72
72
  Deriva is intentionally smaller than ISO Prolog. It supports compact Horn-clause reasoning, list processing, arithmetic examples, finite search, and context data, without operators, cut, modules, dynamic predicates, DCGs, zero-arity compound syntax, or a complete ISO standard library.
73
73
 
@@ -89,7 +89,7 @@ A **goal** is an atomic formula, a built-in call, or a comma conjunction.
89
89
 
90
90
  A **source fact** is a fact written directly in the input program. A **new derivation** is a ground consequence found through at least one rule and not merely repeated from the source facts.
91
91
 
92
- The **Herbrand universe** of a program is the set of all ground deriva terms constructible from the constants and functors in the program, together with the built-in list constructors `[]` and `./2` where lists are used. The **Herbrand base** is the set of all ground atomic formulas whose predicate symbols occur in the program and whose arguments are terms from the Herbrand universe.
92
+ The **Herbrand universe** of a program is the set of all ground Deriva terms constructible from the constants and functors in the program, together with the built-in list constructors `[]` and `./2` where lists are used. The **Herbrand base** is the set of all ground atomic formulas whose predicate symbols occur in the program and whose arguments are terms from the Herbrand universe.
93
93
 
94
94
  ## 2. Design goals
95
95
 
@@ -329,7 +329,7 @@ pair(3, nested(atom, [x, y]))
329
329
 
330
330
  The same concrete syntax is used for atomic formulas when the compound appears as a fact, rule head, or goal. In `parent(pat, jan).`, `parent/2` is a predicate symbol and the whole expression is an atomic formula. In `value(x, parent(pat, jan)).`, the inner `parent(pat, jan)` is ordinary compound data.
331
331
 
332
- The functor or predicate name is fixed syntactically and is written as an atom constant. deriva does not support variables in predicate or functor position.
332
+ The functor or predicate name is fixed syntactically and is written as an atom constant. Deriva does not support variables in predicate or functor position.
333
333
 
334
334
  ### 5.4 Lists
335
335
 
@@ -375,7 +375,7 @@ Clauses with the same predicate name and arity define one predicate group. Predi
375
375
 
376
376
  ## 7. Goals and proof search
377
377
 
378
- Goals are solved left-to-right. For a user-defined atomic-formula goal, deriva selects candidate clauses by predicate name, arity, and available indexes. A candidate clause is freshened, its head is unified with the goal, and then its body is solved.
378
+ Goals are solved left-to-right. For a user-defined atomic-formula goal, Deriva selects candidate clauses by predicate name, arity, and available indexes. A candidate clause is freshened, its head is unified with the goal, and then its body is solved.
379
379
 
380
380
  A conjunction goal succeeds when all conjunct goals succeed in order. An answer is printed as the resolved answer term followed by a period.
381
381
 
@@ -385,11 +385,11 @@ Unification follows the ordinary first-order term structure used by the language
385
385
 
386
386
  ### 7.2 Failure
387
387
 
388
- A goal fails when no built-in case or user clause can prove it. deriva has no exception term language; parse errors and resource failures are implementation errors reported to the host.
388
+ A goal fails when no built-in case or user clause can prove it. Deriva has no exception term language; parse errors and resource failures are implementation errors reported to the host.
389
389
 
390
390
  ### 7.3 Finite search expectation
391
391
 
392
- Programs and selected output goals SHOULD be written so the relevant search space is finite. deriva includes recursion guards and tabling support, but it is not required to terminate for arbitrary recursive logic programs.
392
+ Programs and selected output goals SHOULD be written so the relevant search space is finite. Deriva includes recursion guards and tabling support, but it is not required to terminate for arbitrary recursive logic programs.
393
393
 
394
394
  ## 8. Logical reading: Herbrand semantics
395
395
 
@@ -415,9 +415,9 @@ Equivalently, the least Herbrand model is obtained by repeatedly applying the im
415
415
 
416
416
  ### 8.1 Variables and quantification
417
417
 
418
- Variables do not range over external objects, records, pointers, or host-language values. In the logical reading, variables range over Herbrand terms. A rule is implicitly universally quantified over its variables. A selected goal is existential in the usual logic-programming sense: deriva searches for substitutions of its variables by Herbrand terms that make the goal true with respect to the program.
418
+ Variables do not range over external objects, records, pointers, or host-language values. In the logical reading, variables range over Herbrand terms. A rule is implicitly universally quantified over its variables. A selected goal is existential in the usual logic-programming sense: Deriva searches for substitutions of its variables by Herbrand terms that make the goal true with respect to the program.
419
419
 
420
- deriva has no blank nodes and no existential variables in rule heads. Existential-style consequences SHOULD be represented by explicit Herbrand witness terms written directly in rule heads:
420
+ Deriva has no blank nodes and no existential variables in rule heads. Existential-style consequences SHOULD be represented by explicit Herbrand witness terms written directly in rule heads:
421
421
 
422
422
  ```deriva
423
423
  has_parent(Child, parent_of(Child)) :-
@@ -433,11 +433,11 @@ These rules may derive `parent_of(alice)` or `registration_of(alice, logic)` as
433
433
 
434
434
  Because the domain is Herbrand, equality in the pure language is syntactic identity of terms after substitution. Two distinct atom constants are distinct. Two compound terms are equal only when they have the same functor, the same arity, and pairwise equal arguments. Lists follow the same rule through their `[]` and `./2` representation.
435
435
 
436
- Operationally, deriva uses first-order unification to find substitutions. The implementation does not perform an occurs check, so cyclic terms are not part of the portable Herbrand reading even if a particular implementation can temporarily construct recursive bindings internally. Portable programs SHOULD avoid relying on occurs-check-sensitive cases such as `eq(X, f(X))`.
436
+ Operationally, Deriva uses first-order unification to find substitutions. The implementation does not perform an occurs check, so cyclic terms are not part of the portable Herbrand reading even if a particular implementation can temporarily construct recursive bindings internally. Portable programs SHOULD avoid relying on occurs-check-sensitive cases such as `eq(X, f(X))`.
437
437
 
438
438
  ### 8.3 Goal-directed execution versus model-theoretic meaning
439
439
 
440
- deriva's CLI and library evaluator are goal-directed. They try to prove requested goals by resolving them against facts, rules, and built-ins, using clause order, goal order, indexing, tabling, and deterministic built-in execution. This operational strategy is intended to enumerate answers that are true in the least Herbrand model for the pure Horn-clause fragment, but it is not a complete bottom-up model enumerator. Non-terminating recursion or infinite generators can prevent an answer from being found even when the answer belongs to the least Herbrand model.
440
+ Deriva's CLI and library evaluator are goal-directed. They try to prove requested goals by resolving them against facts, rules, and built-ins, using clause order, goal order, indexing, tabling, and deterministic built-in execution. This operational strategy is intended to enumerate answers that are true in the least Herbrand model for the pure Horn-clause fragment, but it is not a complete bottom-up model enumerator. Non-terminating recursion or infinite generators can prevent an answer from being found even when the answer belongs to the least Herbrand model.
441
441
 
442
442
  Default CLI output is also a host behavior, not a separate semantics. It asks broad materialization goals, suppresses duplicates, excludes source facts, keeps ground answers, and prints selected consequences. Embedders can still access the goal-directed solver directly through the implementation API.
443
443
 
@@ -445,7 +445,7 @@ Default CLI output is also a host behavior, not a separate semantics. It asks br
445
445
 
446
446
  Built-ins are specified relations or operations added to the Herbrand core. A built-in call in a goal has the syntax of an atomic formula, but its success relation is specified procedurally here rather than by source clauses. Some built-ins, such as `eq/2`, `append/3`, `member/2`, and `length/2`, can be understood as relations over Herbrand terms. Others, such as arithmetic, string matching, date/time predicates, aggregation, `once/1`, and negation-as-failure, are operational extensions whose behavior is defined by this specification rather than by pure least-Herbrand-model semantics alone.
447
447
 
448
- Arithmetic and string built-ins do not introduce a separate semantic universe. They inspect the lexical values of already represented Herbrand constants and, when they succeed, bind output arguments to deriva terms such as numbers, strings, or atom constants. For example, `add(2, 3, X)` may bind `X` to the number term `5`; it does not mean that variables range over host-language numbers outside the Herbrand universe.
448
+ Arithmetic and string built-ins do not introduce a separate semantic universe. They inspect the lexical values of already represented Herbrand constants and, when they succeed, bind output arguments to Deriva terms such as numbers, strings, or atom constants. For example, `add(2, 3, X)` may bind `X` to the number term `5`; it does not mean that variables range over host-language numbers outside the Herbrand universe.
449
449
 
450
450
  Negation-as-failure `not(Goal)` is especially operational: it succeeds when the current goal-directed search finds no solution for `Goal`. It is not classical negation and should not be read as adding negative facts to the Herbrand model. Programs using negation SHOULD keep the negated goal sufficiently ground and finite.
451
451
 
@@ -544,7 +544,7 @@ Comparisons interpret numeric-looking terms numerically. Other scalar terms are
544
544
  | `lowercase(Text, Out)`, `uppercase(Text, Out)`, `trim(Text, Out)` | Text normalization helpers. |
545
545
  | `number_string(Number, String)` | Converts a number to a string or parses a numeric string into a number. |
546
546
  | `atom_string(Atom, String)` | Converts between atom constants and strings. |
547
- | `term_string(Term, String)` | Renders a ground term as its deriva source string. |
547
+ | `term_string(Term, String)` | Renders a ground term as its Deriva source string. |
548
548
 
549
549
  ### 9.7 Lists
550
550
 
@@ -616,15 +616,15 @@ The first goal can yield `holds((name(alice, "Alice"), knows(alice, bob)), name(
616
616
 
617
617
  ## 10. Implementation-specific built-ins
618
618
 
619
- Implementations MAY provide additional built-ins beyond the standard predicates listed above. Such built-ins are **implementation-specific built-ins**. They are useful for embedding deriva in particular host environments, exposing efficient finite-domain solvers, or providing domain-specific relations for applications.
619
+ Implementations MAY provide additional built-ins beyond the standard predicates listed above. Such built-ins are **implementation-specific built-ins**. They are useful for embedding Deriva in particular host environments, exposing efficient finite-domain solvers, or providing domain-specific relations for applications.
620
620
 
621
- Implementation-specific built-ins are not required for conformance to this specification. A portable deriva program SHOULD NOT depend on one unless the target implementation explicitly documents it.
621
+ Implementation-specific built-ins are not required for conformance to this specification. A portable Deriva program SHOULD NOT depend on one unless the target implementation explicitly documents it.
622
622
 
623
623
  An implementation-specific built-in SHOULD obey the same surface-language discipline as standard built-ins:
624
624
 
625
625
  - it is called using ordinary atomic-formula syntax, for example `some_extension(A, B)`;
626
- - its arguments and results are deriva terms from the Herbrand universe;
627
- - it succeeds, fails, and binds variables as a relation over deriva terms;
626
+ - its arguments and results are Deriva terms from the Herbrand universe;
627
+ - it succeeds, fails, and binds variables as a relation over Deriva terms;
628
628
  - it SHOULD document its intended modes, especially which arguments must be ground before it runs deterministically;
629
629
  - it MUST NOT change the meaning of ordinary facts, rules, unification, or standard built-ins.
630
630
 
@@ -638,7 +638,7 @@ Declarations are written as ordinary facts, but the host treats them specially.
638
638
 
639
639
  ### 11.1 Automatic hybrid reasoning
640
640
 
641
- deriva automatically combines ordinary goal-directed resolution with tabled
641
+ Deriva automatically combines ordinary goal-directed resolution with tabled
642
642
  resolution. Predicate dependency cycles are detected when a program is loaded,
643
643
  including dependencies inside conjunctions, negation, `once/1`, `forall/2`, and
644
644
  aggregation goals. Positive recursive predicate groups, including directly
@@ -702,9 +702,9 @@ The example documents the common checking/generation mode where the list is supp
702
702
 
703
703
  ## 12. Deriva Sockets
704
704
 
705
- A **deriva Socket** is a declared semantic opening in a deriva program where facts, rules, tools, datasets, or agents can plug in knowledge through an explicit contract while preserving deriva-readable reasoning and explanations.
705
+ A **Deriva Socket** is a declared semantic opening in a Deriva program where facts, rules, tools, datasets, or agents can plug in knowledge through an explicit contract while preserving Deriva-readable reasoning and explanations.
706
706
 
707
- The term follows the ordinary socket pattern: a socket defines a place where a matching provider can connect. In deriva, the matching part is knowledge. A socket identifies what shape of knowledge a program expects; a plug identifies which provider supplies it. This separates reasoning logic from knowledge providers and makes composition boundaries visible as deriva data.
707
+ The term follows the ordinary socket pattern: a socket defines a place where a matching provider can connect. In Deriva, the matching part is knowledge. A socket identifies what shape of knowledge a program expects; a plug identifies which provider supplies it. This separates reasoning logic from knowledge providers and makes composition boundaries visible as Deriva data.
708
708
 
709
709
  In this specification, sockets are a portable **programming pattern** expressed with ordinary facts. The core solver does not give `socket/2`, `plug/2`, `provides/1`, or `requires/1` special proof-search behavior unless a host explicitly documents such an extension. Because they are ordinary facts, socket declarations remain readable, inspectable, explainable, and safe to ignore by hosts that do not validate them.
710
710
 
@@ -719,7 +719,7 @@ provides(Signature).
719
719
  requires(Signature).
720
720
  ```
721
721
 
722
- `Name` and `Provider` are ordinary deriva terms, usually atom constants. `Contract` is an ordinary deriva term that describes the expected or offered knowledge. A portable signature form is:
722
+ `Name` and `Provider` are ordinary Deriva terms, usually atom constants. `Contract` is an ordinary Deriva term that describes the expected or offered knowledge. A portable signature form is:
723
723
 
724
724
  ```deriva
725
725
  predicate(Predicatename, Arity)
@@ -755,21 +755,21 @@ ancestor(X, Z) :-
755
755
  ancestor(Y, Z).
756
756
  ```
757
757
 
758
- The `ancestor/2` rules do not depend on a particular storage mechanism for `parent/2`. In a small test, the provider may be the same file. In an embedded host, it may be a database adapter, a document extractor, a remote service, or another deriva module. The socket facts make that boundary explicit without changing the logical meaning of the rules.
758
+ The `ancestor/2` rules do not depend on a particular storage mechanism for `parent/2`. In a small test, the provider may be the same file. In an embedded host, it may be a database adapter, a document extractor, a remote service, or another Deriva module. The socket facts make that boundary explicit without changing the logical meaning of the rules.
759
759
 
760
- When deriva derives `ancestor(pat, emma)`, the answer explanation can still refer to the source clauses that were actually used, for example facts for `parent/2` and rules for `ancestor/2`. The socket facts add an inspectable description of where such knowledge is intended to enter.
760
+ When Deriva derives `ancestor(pat, emma)`, the answer explanation can still refer to the source clauses that were actually used, for example facts for `parent/2` and rules for `ancestor/2`. The socket facts add an inspectable description of where such knowledge is intended to enter.
761
761
 
762
762
  ### 12.3 Sockets and AI agents
763
763
 
764
- deriva Sockets are especially useful for AI-facing systems. An AI agent can extract or propose candidate claims, but those claims should enter a reasoning program as explicit deriva facts or rules through a declared socket rather than as opaque text. deriva can then check the claims against other facts and rules, derive consequences, and optionally return ordinary `why/2` explanations.
764
+ Deriva Sockets are especially useful for AI-facing systems. An AI agent can extract or propose candidate claims, but those claims should enter a reasoning program as explicit Deriva facts or rules through a declared socket rather than as opaque text. Deriva can then check the claims against other facts and rules, derive consequences, and optionally return ordinary `why/2` explanations.
765
765
 
766
- This gives a clear division of labor: AI can help generate, translate, and connect knowledge; deriva can represent, check, and explain the reasoning; sockets define the boundary between them.
766
+ This gives a clear division of labor: AI can help generate, translate, and connect knowledge; Deriva can represent, check, and explain the reasoning; sockets define the boundary between them.
767
767
 
768
768
  ## 13. Output and read-back profile
769
769
 
770
770
  Normal answer output prints one resolved answer term followed by a period. Strings are double-quoted; atom constants are quoted when needed; lists use list syntax; compound terms use functor notation. Host interfaces MAY provide an option such as `--proof` to add `why/2` explanation facts; this option MUST NOT change the answers found. Host interfaces MAY also provide a non-fatal warning option such as `--warnings` for portability diagnostics such as unstratified negation; this option MUST NOT change the answers found.
771
771
 
772
- Output SHOULD be accepted as deriva input when it contains only supported term syntax. Explanations are ordinary deriva facts, so answer output can be read back and processed by deriva.
772
+ Output SHOULD be accepted as Deriva input when it contains only supported term syntax. Explanations are ordinary Deriva facts, so answer output can be read back and processed by Deriva.
773
773
 
774
774
  Default host output behavior is:
775
775
 
@@ -783,11 +783,11 @@ Default host output behavior is:
783
783
 
784
784
  ### 13.1 Explanation output
785
785
 
786
- When proof output is enabled, each answer SHOULD be followed by a machine-readable `why/2` fact. Explanation output is ordinary deriva syntax whose second argument is a nested abstract proof term such as `proof(goal(G), by(Method), bindings(Bindings), uses(Proofs))`; implementations SHOULD print `goal(...)` and `by(...)` on separate lines for readability. A proof term preserves the answer goal, derivation method, relevant bindings, and nested uses while omitting proof IDs. User clauses SHOULD be referenced explicitly as `fact(Filename, clause(N))` or `rule(Filename, clause(N))`, where `N` is the 1-based clause number within that source. Built-ins SHOULD be referenced as `builtin(Name, Arity)` because they do not come from source clauses. Explanation output is outside the logical semantics of the input program and MUST NOT change the set of answers.
786
+ When proof output is enabled, each answer SHOULD be followed by a machine-readable `why/2` fact. Explanation output is ordinary Deriva syntax whose second argument is a nested abstract proof term such as `proof(goal(G), by(Method), bindings(Bindings), uses(Proofs))`; implementations SHOULD print `goal(...)` and `by(...)` on separate lines for readability. A proof term preserves the answer goal, derivation method, relevant bindings, and nested uses while omitting proof IDs. User clauses SHOULD be referenced explicitly as `fact(Filename, clause(N))` or `rule(Filename, clause(N))`, where `N` is the 1-based clause number within that source. Built-ins SHOULD be referenced as `builtin(Name, Arity)` because they do not come from source clauses. Explanation output is outside the logical semantics of the input program and MUST NOT change the set of answers.
787
787
 
788
788
  ## 14. Conformance
789
789
 
790
- A conforming deriva implementation supports the standard language described above as one conformance surface rather than as separate core and extension profiles. This includes:
790
+ A conforming Deriva implementation supports the standard language described above as one conformance surface rather than as separate core and extension profiles. This includes:
791
791
 
792
792
  - lexical syntax described above;
793
793
  - facts and definite clauses;
@@ -804,11 +804,11 @@ A conforming deriva implementation supports the standard language described abov
804
804
 
805
805
  Browser execution, package layout, CLI URL loading, and any implementation-specific built-ins described in host documentation are outside this conformance surface unless separately standardized.
806
806
 
807
- Conformance cases live in the repository under `test/conformance/`. They are run by `npm test` before the example suite, and can be run alone with `node test/run-conformance.mjs`. Positive cases have input programs under `test/conformance/cases/` and exact expected standard-output files under `test/conformance/expected/`; both use `.pl` so expected output remains deriva-readable. Expected-error cases live under `test/conformance/errors/` with exact messages under `test/conformance/expected-errors/`. Expected-warning cases live under `test/conformance/warnings/` with exact `--warnings` stdout and stderr files under `test/conformance/expected-warnings/`. Proof cases live under `test/conformance/proofs/` with exact explanation output under `test/conformance/expected-proofs/`. The corpus is grouped by language area, including arithmetic, strings, lists, terms, atoms, variables, negation, declarations, materialization, rules, syntax, and errors.
807
+ Conformance cases live in the repository under `test/conformance/`. They are run by `npm test` before the example suite, and can be run alone with `node test/run-conformance.mjs`. Positive cases have input programs under `test/conformance/cases/` and exact expected standard-output files under `test/conformance/expected/`; both use `.pl` so expected output remains Deriva-readable. Expected-error cases live under `test/conformance/errors/` with exact messages under `test/conformance/expected-errors/`. Expected-warning cases live under `test/conformance/warnings/` with exact `--warnings` stdout and stderr files under `test/conformance/expected-warnings/`. Proof cases live under `test/conformance/proofs/` with exact explanation output under `test/conformance/expected-proofs/`. The corpus is grouped by language area, including arithmetic, strings, lists, terms, atoms, variables, negation, declarations, materialization, rules, syntax, and errors.
808
808
 
809
809
  ## 15. Relationship to ISO Prolog
810
810
 
811
- deriva source is intended to be familiar to Prolog readers and uses ISO Prolog-compatible variable and quoted-atom spelling, but deriva is not ISO Prolog. Notable differences include:
811
+ Deriva source is intended to be familiar to Prolog readers and uses ISO Prolog-compatible variable and quoted-atom spelling, but Deriva is not ISO Prolog. Notable differences include:
812
812
  - no operators or operator declarations;
813
813
  - no zero-arity compound syntax such as `nil()`;
814
814
  - no cut;
@@ -819,7 +819,7 @@ deriva source is intended to be familiar to Prolog readers and uses ISO Prolog-c
819
819
  - no variables in functor or predicate position;
820
820
  - no occurs check in unification.
821
821
 
822
- Programs intended to be portable to deriva SHOULD use uppercase or underscore variables, avoid ISO-specific features that deriva does not implement, and keep terms explicit. Atom names that are not plain lowercase-starting names or graphic atom tokens SHOULD be written as quoted atoms, for example `'a-b'` or `'<abc>'`.
822
+ Programs intended to be portable to Deriva SHOULD use uppercase or underscore variables, avoid ISO-specific features that Deriva does not implement, and keep terms explicit. Atom names that are not plain lowercase-starting names or graphic atom tokens SHOULD be written as quoted atoms, for example `'a-b'` or `'<abc>'`.
823
823
 
824
824
  ## 16. Examples
825
825
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.0.12",
6
+ "version": "0.0.13",
7
7
  "description": "Deriva turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
@@ -1,5 +1,5 @@
1
1
  // Numeric builtins for integer-preserving arithmetic, floating point functions, comparisons, and ranges.
2
- // The code keeps BigInt paths where possible so large deriva integers remain exact.
2
+ // The code keeps BigInt paths where possible so large Deriva integers remain exact.
3
3
  import { compareIntegerText, deref, isDecimalInteger, lexicalValue, numberTerm, numberTextFromDouble, parseFiniteNumber, unify } from '../term.js';
4
4
 
5
5
  const unaryNames = ['neg', 'abs', 'sin', 'cos', 'tan', 'asin', 'acos', 'sqrt', 'floor', 'ceiling', 'trunc', 'rounded', 'exp', 'log'];
@@ -200,7 +200,7 @@ function nextDown(value) {
200
200
  function logCompat(input) {
201
201
  const value = Math.log(input);
202
202
  // V8 and glibc libm differ by one ulp for a few values reached by the
203
- // Newton-Raphson example. Align this pure-JS port with the native deriva
203
+ // Newton-Raphson example. Align this pure-JS port with the native Deriva
204
204
  // reference while leaving ordinary log(1), log(2), log(10), and log(e) alone.
205
205
  if (input > 2.5 && input < 2.7182818 && value > 0.95 && value < 1.0) return nextUp(value);
206
206
  if (input > 2.7182818 && input < 2.718281828459 && value > 0.999999999999 && value < 1.0) return nextDown(value);
@@ -1,4 +1,4 @@
1
- // Term-inspection builtins for reusable meta-programming over deriva terms.
1
+ // Term-inspection builtins for reusable meta-programming over Deriva terms.
2
2
  import { atom, compound, deref, listFromItems, lexicalValue, numberTerm, properListItems, stringTerm, unify } from '../term.js';
3
3
 
4
4
  export const termBuiltins = {
package/src/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- // Command-line interface for deriva.
1
+ // Command-line interface for Deriva.
2
2
  // It loads programs from files, URLs, or stdin, then materializes derived output predicates.
3
3
  import fs from 'node:fs/promises';
4
4
  import path from 'node:path';
package/src/explain.js CHANGED
@@ -1,6 +1,6 @@
1
- // deriva proof output helpers.
1
+ // Deriva proof output helpers.
2
2
  // The explanation printer replays a successful goal against the program and emits
3
- // ordinary deriva facts with nested proof terms. Explanations are therefore both
3
+ // ordinary Deriva facts with nested proof terms. Explanations are therefore both
4
4
  // human-readable and machine-readable.
5
5
  import { COMPOUND, Env, Term, VAR, deref, flattenConjunction, freshTerm, termToString, unify, variantTerms } from './term.js';
6
6
  import { selectClauseCandidates } from './program.js';
package/src/parser.js CHANGED
@@ -1,4 +1,4 @@
1
- // Tokenizer and recursive-descent parser for the deriva source language.
1
+ // Tokenizer and recursive-descent parser for the Deriva source language.
2
2
  // It preserves the compact Prolog-like syntax while producing Term objects for the solver.
3
3
  import { atom, compound, cons, emptyList, numberTerm, stringTerm, variable } from './term.js';
4
4
 
package/src/solver.js CHANGED
@@ -1,4 +1,4 @@
1
- // Depth-first deriva solver with builtin dispatch, memoization, and guarded recursion handling.
1
+ // Depth-first Deriva solver with builtin dispatch, memoization, and guarded recursion handling.
2
2
  // Most semantic decisions still flow through unification; optimizations only select candidates earlier.
3
3
  import { COMPOUND, Env, compound, copyResolved, flattenConjunction, freshTerm, termIsGround, termToString, unify, variantTerms } from './term.js';
4
4
  import { createDefaultRegistry } from './builtins/registry.js';
@@ -113,7 +113,7 @@ export class Solver {
113
113
  continue;
114
114
  }
115
115
 
116
- // deriva normally solves left-to-right, but ready deterministic builtins can
116
+ // Deriva normally solves left-to-right, but ready deterministic builtins can
117
117
  // be run early as pure filters. Stop at internal sentinels so rule-body
118
118
  // active guards are released before the caller's remaining goals are seen.
119
119
  const selectedIndex = selectReadyDeterministicBuiltin(goals, env, this.registry);
@@ -9,7 +9,7 @@ All conformance files live under topic directories such as `arithmetic/`, `lists
9
9
  A normal positive case consists of:
10
10
 
11
11
  - `conformance/cases/<name>.pl` — input program;
12
- - `conformance/expected/<name>.pl` — exact expected standard output, stored as deriva-readable facts.
12
+ - `conformance/expected/<name>.pl` — exact expected standard output, stored as Deriva-readable facts.
13
13
 
14
14
  Expected-error cases consist of:
15
15
 
@@ -63,9 +63,9 @@ The runner executes normal materialized programs in-process through the public J
63
63
 
64
64
  ## Scope
65
65
 
66
- The conformance corpus is a single deriva suite. It covers the standard language described by the language reference: lexical syntax, facts, definite clauses, first-order terms, lists, conjunction, structured unification, left-to-right goal-directed proof search, materialized output, read-back printing, standard built-ins, declarations, warnings, errors, proof output, and standard host behavior.
66
+ The conformance corpus is a single Deriva suite. It covers the standard language described by the language reference: lexical syntax, facts, definite clauses, first-order terms, lists, conjunction, structured unification, left-to-right goal-directed proof search, materialized output, read-back printing, standard built-ins, declarations, warnings, errors, proof output, and standard host behavior.
67
67
 
68
- The suite deliberately does not separate `core` and `extension` profiles. Reusable built-ins such as arithmetic, strings, lists, aggregation, context terms, term inspection, and search control are part of the standard deriva conformance surface. Implementation-specific built-ins may still exist in downstream hosts, but they should have their own tests outside this corpus unless they are standardized.
68
+ The suite deliberately does not separate `core` and `extension` profiles. Reusable built-ins such as arithmetic, strings, lists, aggregation, context terms, term inspection, and search control are part of the standard Deriva conformance surface. Implementation-specific built-ins may still exist in downstream hosts, but they should have their own tests outside this corpus unless they are standardized.
69
69
 
70
70
  ## Updating expected output
71
71
 
@@ -56,7 +56,7 @@ export function buildConformanceReport() {
56
56
 
57
57
  export function formatConformanceReport(report = buildConformanceReport()) {
58
58
  const lines = [
59
- '# Conformance Deriva report',
59
+ '# Deriva conformance report',
60
60
  '',
61
61
  'This report summarizes the file-based conformance corpus under `test/conformance/`.',
62
62
  '',
@@ -358,7 +358,7 @@ function documentationSyncCases() {
358
358
  run: () => assertArrayEqual(findBrokenDocLinks(), [], 'broken documentation links'),
359
359
  },
360
360
  {
361
- name: 'documentation uses deriva source style',
361
+ name: 'documentation uses Deriva source style',
362
362
  run: () => assertArrayEqual(documentationSourceStyleIssues(), [], 'documentation source style'),
363
363
  },
364
364
  {