deriva 0.0.13 → 0.0.15

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/docs/guide.md CHANGED
@@ -416,6 +416,7 @@ Use `holds/2` when you want to match the member term directly, for example `name
416
416
  | [`hamming-code.pl`](../examples/hamming-code.pl) | Corrects a single-bit Hamming word. | [`output/hamming-code.pl`](../examples/output/hamming-code.pl) |
417
417
  | [`hanoi.pl`](../examples/hanoi.pl) | Derives the Towers of Hanoi moves. | [`output/hanoi.pl`](../examples/output/hanoi.pl) |
418
418
  | [`heat-loss.pl`](../examples/heat-loss.pl) | Computes conductive heat loss. | [`output/heat-loss.pl`](../examples/output/heat-loss.pl) |
419
+ | [`herbrand-semantics.pl`](../examples/herbrand-semantics.pl) | Shows how unique names and free constructors make symbolic identity predictable. | [`output/herbrand-semantics.pl`](../examples/output/herbrand-semantics.pl) |
419
420
  | [`herbrand-witnesses.pl`](../examples/herbrand-witnesses.pl) | Represents existential-style consequences as stable Herbrand witness terms. | [`output/herbrand-witnesses.pl`](../examples/output/herbrand-witnesses.pl) |
420
421
  | [`heron-theorem.pl`](../examples/heron-theorem.pl) | Computes triangle area by Heron's theorem. | [`output/heron-theorem.pl`](../examples/output/heron-theorem.pl) |
421
422
  | [`ideal-gas-law.pl`](../examples/ideal-gas-law.pl) | Applies the ideal gas law. | [`output/ideal-gas-law.pl`](../examples/output/ideal-gas-law.pl) |
@@ -29,11 +29,12 @@
29
29
  - [7.2 Failure](#72-failure)
30
30
  - [7.3 Finite search expectation](#73-finite-search-expectation)
31
31
  - [8. Logical reading: Herbrand semantics](#8-logical-reading-herbrand-semantics)
32
- - [8.1 Variables and quantification](#81-variables-and-quantification)
33
- - [8.2 Equality, identity, and unification](#82-equality-identity-and-unification)
34
- - [8.3 Goal-directed execution versus model-theoretic meaning](#83-goal-directed-execution-versus-model-theoretic-meaning)
35
- - [8.4 Built-ins and operational extensions](#84-built-ins-and-operational-extensions)
36
- - [8.5 Stratified negation](#85-stratified-negation)
32
+ - [8.1 Why use a Herbrand interpretation?](#81-why-use-a-herbrand-interpretation)
33
+ - [8.2 Variables and quantification](#82-variables-and-quantification)
34
+ - [8.3 Equality, identity, and unification](#83-equality-identity-and-unification)
35
+ - [8.4 Goal-directed execution versus model-theoretic meaning](#84-goal-directed-execution-versus-model-theoretic-meaning)
36
+ - [8.5 Built-ins and operational extensions](#85-built-ins-and-operational-extensions)
37
+ - [8.6 Stratified negation](#86-stratified-negation)
37
38
  - [9. Standard built-in predicates](#9-standard-built-in-predicates)
38
39
  - [9.1 Equality and unification](#91-equality-and-unification)
39
40
  - [9.2 Arithmetic](#92-arithmetic)
@@ -413,7 +414,59 @@ is read universally over Herbrand terms: for every substitution of `X`, `Y`, and
413
414
 
414
415
  Equivalently, the least Herbrand model is obtained by repeatedly applying the immediate-consequence operation: start with the source facts, add every ground rule head whose ground body is already true, and continue to the least fixed point. This definition is mathematical; an implementation does not have to compute the model bottom-up.
415
416
 
416
- ### 8.1 Variables and quantification
417
+ ### 8.1 Why use a Herbrand interpretation?
418
+
419
+ Herbrand semantics is not an alternative to model theory: a Herbrand
420
+ interpretation is a particular kind of Tarskian structure. Deriva chooses this
421
+ restricted structure because programs manipulate symbolic terms directly and
422
+ need their identity to be predictable without a separate set of domain axioms.
423
+
424
+ Consider this program:
425
+
426
+ ```deriva
427
+ materialize(different, 2).
428
+
429
+ different(alice, bob) :-
430
+ neq(alice, bob).
431
+
432
+ different(ticket(alice), ticket(bob)) :-
433
+ neq(ticket(alice), ticket(bob)).
434
+ ```
435
+
436
+ It produces:
437
+
438
+ ```deriva
439
+ different(alice, bob).
440
+ different(ticket(alice), ticket(bob)).
441
+ ```
442
+
443
+ The complete runnable example, normal output, and proof output are available as
444
+ [`examples/herbrand-semantics.pl`](../examples/herbrand-semantics.pl),
445
+ [`examples/output/herbrand-semantics.pl`](../examples/output/herbrand-semantics.pl),
446
+ and [`examples/proof/herbrand-semantics.pl`](../examples/proof/herbrand-semantics.pl).
447
+
448
+ In an unrestricted Tarskian interpretation, the constants `alice` and `bob`
449
+ may denote the same domain element unless a distinctness axiom says otherwise.
450
+ Even if they denote different elements, the function denoted by `ticket` need
451
+ not be injective, so `ticket(alice)` and `ticket(bob)` may still denote the same
452
+ element. A conventional first-order theory must add unique-name and free-
453
+ constructor axioms to rule out those interpretations.
454
+
455
+ In the Herbrand universe, `alice` and `bob` are different because they are
456
+ different ground terms. Compound terms are free constructors, so
457
+ `ticket(alice)` and `ticket(bob)` are also different. This makes unification,
458
+ read-back, generated witness terms, and proof explanations agree on identity by
459
+ construction. The program can therefore treat syntax as inspectable data
460
+ without first defining an external domain and an interpretation function.
461
+
462
+ This choice does not claim that differently named terms must denote different
463
+ entities in every application. When two names refer to the same real-world
464
+ entity, a Deriva program should represent that relationship explicitly, for
465
+ example with `same_as/2`, or normalize both names to one canonical term. The
466
+ Herbrand layer keeps the representation unambiguous; application rules state
467
+ the intended real-world equivalences.
468
+
469
+ ### 8.2 Variables and quantification
417
470
 
418
471
  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
472
 
@@ -429,19 +482,19 @@ registration(Student, Course, registration_of(Student, Course)) :-
429
482
 
430
483
  These rules may derive `parent_of(alice)` or `registration_of(alice, logic)` as ordinary visible Herbrand terms. The witness is deterministic: the same functor and inputs produce the same term, while different inputs produce different terms by normal syntactic identity. This is the practical executable form of existential-style consequences in Deriva; it does not introduce hidden blank nodes or special quantifier syntax.
431
484
 
432
- ### 8.2 Equality, identity, and unification
485
+ ### 8.3 Equality, identity, and unification
433
486
 
434
487
  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
488
 
436
489
  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
490
 
438
- ### 8.3 Goal-directed execution versus model-theoretic meaning
491
+ ### 8.4 Goal-directed execution versus model-theoretic meaning
439
492
 
440
493
  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
494
 
442
495
  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
496
 
444
- ### 8.4 Built-ins and operational extensions
497
+ ### 8.5 Built-ins and operational extensions
445
498
 
446
499
  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
500
 
@@ -449,7 +502,7 @@ Arithmetic and string built-ins do not introduce a separate semantic universe. T
449
502
 
450
503
  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
504
 
452
- ### 8.5 Stratified negation
505
+ ### 8.6 Stratified negation
453
506
 
454
507
  Portable programs using user-defined predicates under `not/1` SHOULD be **stratified**. A program is stratified when no predicate depends negatively on itself, either directly or through a cycle of other predicate dependencies. In a stratified program, predicates can be assigned strata so that positive dependencies stay in the same or a lower stratum and negative dependencies point strictly to a lower stratum.
455
508
 
@@ -0,0 +1,16 @@
1
+ % Herbrand terms denote themselves: distinct names and constructor applications
2
+ % remain distinct without extra unique-name or free-constructor axioms.
3
+
4
+ % Output declaration: materialize/2 selects the relation written to this
5
+ % example's golden output.
6
+ materialize(different, 2).
7
+
8
+ % Under unrestricted Tarskian semantics, alice and bob could denote the same
9
+ % element. In Deriva's Herbrand universe, their different syntax is enough.
10
+ different(alice, bob) :-
11
+ neq(alice, bob).
12
+
13
+ % A general Tarskian function need not be injective. Herbrand compound terms
14
+ % are free constructors, so different arguments produce different terms.
15
+ different(ticket(alice), ticket(bob)) :-
16
+ neq(ticket(alice), ticket(bob)).
@@ -0,0 +1,2 @@
1
+ different(alice, bob).
2
+ different(ticket(alice), ticket(bob)).
@@ -0,0 +1,30 @@
1
+ different(alice, bob).
2
+ why(
3
+ different(alice, bob),
4
+ proof(
5
+ goal(different(alice, bob)),
6
+ by(rule("herbrand-semantics.pl", clause(2))),
7
+ uses([
8
+ proof(
9
+ goal(neq(alice, bob)),
10
+ by(builtin(neq, 2))
11
+ )
12
+ ])
13
+ )
14
+ ).
15
+
16
+ different(ticket(alice), ticket(bob)).
17
+ why(
18
+ different(ticket(alice), ticket(bob)),
19
+ proof(
20
+ goal(different(ticket(alice), ticket(bob))),
21
+ by(rule("herbrand-semantics.pl", clause(3))),
22
+ uses([
23
+ proof(
24
+ goal(neq(ticket(alice), ticket(bob))),
25
+ by(builtin(neq, 2))
26
+ )
27
+ ])
28
+ )
29
+ ).
30
+
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.0.13",
6
+ "version": "0.0.15",
7
7
  "description": "Deriva turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/playground.html CHANGED
@@ -526,6 +526,7 @@
526
526
  "hamming-code",
527
527
  "hanoi",
528
528
  "heat-loss",
529
+ "herbrand-semantics",
529
530
  "herbrand-witnesses",
530
531
  "heron-theorem",
531
532
  "ideal-gas-law",
@@ -38,6 +38,7 @@ const proofExamples = [
38
38
  'graph-reachability.pl',
39
39
  'greatest-lower-bound-uniqueness.pl',
40
40
  'group-inverse-uniqueness.pl',
41
+ 'herbrand-semantics.pl',
41
42
  'list-collection.pl',
42
43
  'proof-contrapositive.pl',
43
44
  'reusable-builtins.pl',