eyeprolog 1.6.35 → 1.6.36

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.6.35",
6
+ "version": "1.6.36",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
@@ -26,6 +26,17 @@ them. Robert Kowalski summed this up as “algorithm = logic + control”. Most
26
26
  the craft of Prolog lies in keeping the logic fixed while improving the
27
27
  control.
28
28
 
29
+ The title acknowledges a debt. Leon Sterling and Ehud Shapiro's *The Art of
30
+ Prolog* (1986) taught a generation to read a logic program first as a
31
+ definition and only then as a computation, to build programs from small,
32
+ well-understood relations, and to treat accumulators, generate-and-test,
33
+ grammars, and interpreters as a craft with principles of its own. This book
34
+ follows the same plan. It begins with logic programs as relations and the
35
+ search that computes them (Parts I–III), turns to constructing, transforming,
36
+ and applying programs (Parts IV–VII), and then covers the practical ISO language
37
+ and its reference (Parts VIII–IX), ending with laboratories (Part X). Every
38
+ chapter ends with exercises, and every Part closes with a historical note.
39
+
29
40
  ## Getting started
30
41
 
31
42
  EyeProlog requires Node.js 18 or newer. Check with:
@@ -262,9 +273,16 @@ into later rules.
262
273
  Facts are statements, not commands. Their order can affect the order of
263
274
  answers, but a fact never means “do this now”.
264
275
 
265
- **Exercise.** Add `grandparent/2` using two calls to `parent/2`. Query all
266
- grandparents, then only those of `diego`. Predict which output changes after
267
- adding `parent(diego, elena).`
276
+ **Exercises.**
277
+
278
+ 1. Add `grandparent/2` using two calls to `parent/2`. Query all grandparents,
279
+ then only those of `diego`.
280
+ 2. Predict which answers change after adding `parent(diego, elena).`, then run
281
+ both versions and compare.
282
+ 3. Define `sibling/2` from `parent/2` so that nobody is their own sibling.
283
+ Which built-in from Chapter 2 does the definition need?
284
+ 4. Write `child/2` and `parent/2` as two independent fact tables instead of a
285
+ rule. Which facts can now disagree, and why does the rule rule that out?
268
286
 
269
287
  ## 2. Terms, variables, and substitution
270
288
 
@@ -336,10 +354,17 @@ route(a, d, path([a, b, d], cost(9))).
336
354
  The outer `measurement(...)` is a statement; the nested `sample(...)` is data.
337
355
  The syntax is the same, and position decides the role.
338
356
 
339
- **Checkpoint.** Without running anything, decide whether each pair unifies:
340
- `point(X, X)` with `point(red, red)`, `point(X, X)` with `point(red, blue)`,
341
- and `[Head | Tail]` with `[a, b, c]`. Then check with `=/2`. Write
342
- `diagonal/1`, which succeeds for `point(X, X)`.
357
+ **Exercises.**
358
+
359
+ 1. Without running anything, decide whether each pair unifies:
360
+ `point(X, X)` with `point(red, red)`, `point(X, X)` with `point(red, blue)`,
361
+ and `[Head | Tail]` with `[a, b, c]`. Then check each with `=/2`.
362
+ 2. Write `diagonal/1`, which succeeds for `point(X, X)`, and query it with
363
+ `point(2, 2)` and `point(2, 3)`.
364
+ 3. Give the most general unifier of `reading(S, V, unit(U))` and
365
+ `reading(temp, 91, unit(celsius))`, then of `f(X, g(X))` and `f(a, Y)`.
366
+ 4. Represent a calendar date as a compound term and write `same_month/2` for
367
+ two dates. Which arguments of the term does the unification compare?
343
368
 
344
369
  ## 3. Rules and their two readings
345
370
 
@@ -529,9 +554,19 @@ and per-group `negationStratum`, request the analysis with `analyzeNegation`,
529
554
  reject unstratified programs with `strictNegation`, or call
530
555
  `program.assertStratifiedNegation()`.
531
556
 
532
- **Checkpoint.** Take one rule from this chapter. Read it once as a sentence
533
- about all of its ground instances and once as a sequence of subquestions, and
534
- say which body goal first binds each variable.
557
+ **Exercises.**
558
+
559
+ 1. Read `eligible/1` once as a sentence about all of its ground instances and
560
+ once as a sequence of subquestions, and say which body goal first binds
561
+ each variable. Then move `Years >= 18` to the front and predict what
562
+ happens.
563
+ 2. Write the least Herbrand model of the `can_enter/1` clauses for
564
+ `staff(ann)`, `visitor(bob)`, `visitor(cy)`, and `escorted(bob)`.
565
+ 3. Extend `different/2` to compare `pair(a, b)` and `pair(b, a)`, and explain
566
+ in Herbrand terms why they denote different objects.
567
+ 4. Write a three-predicate program whose negative dependencies are
568
+ stratified, then add one clause that breaks the stratification and run it
569
+ with `--warnings`.
535
570
 
536
571
  ## 4. Recursion: describing reachability
537
572
 
@@ -599,9 +634,17 @@ cyclic graph. Table the finite relation; bound the witness relation, for
599
634
  example by keeping a list of visited vertices and requiring
600
635
  `\+ member(Next, Visited)` so that only simple paths are built.
601
636
 
602
- **Checkpoint.** For the family in Chapter 1, predict every `ancestor/2` answer.
603
- For one indirect answer, name the clauses used and say what moves closer to a
604
- known fact at each step.
637
+ **Exercises.**
638
+
639
+ 1. For the family in Chapter 1, predict every `ancestor/2` answer (there are
640
+ six). For one indirect answer, name the clauses used and say what moves
641
+ closer to a known fact at each step.
642
+ 2. Write `edge/2` facts for a three-vertex cycle and query a tabled
643
+ `reach/2`. Remove the `table` declaration and explain what changes.
644
+ 3. Give `path/3` a visited list so that it returns only simple paths, and
645
+ check that it terminates on the cyclic graph from exercise 2.
646
+ 4. State the termination argument for `ancestor/2` over a finite acyclic
647
+ `parent/2` relation, without tabling.
605
648
 
606
649
  ## 5. Lists as relations
607
650
 
@@ -645,8 +688,36 @@ The `lists` library provides the standard relations, including `member/2`,
645
688
  not yet known; a relation that needs a proper list may enumerate possible tails
646
689
  or raise an instantiation error, so bind the tail first.
647
690
 
648
- **Checkpoint.** Trace `joins([a], [b, c], Whole)` by hand. Then bind `Whole` to
649
- `[a, b, c]`, leave the first two arguments open, and predict every split.
691
+ **Exercises.**
692
+
693
+ 1. Trace `joins([a], [b, c], Whole)` by hand. Then bind `Whole` to
694
+ `[a, b, c]`, leave the first two arguments open, and predict every split.
695
+ 2. Use `joins/3` to define `last_item/2` and `prefix_of/2` without writing any
696
+ new recursion.
697
+ 3. Write `length_of/2` with an accumulator in the style of `reverse_acc/2`, and
698
+ say which argument must be bound for it to terminate.
699
+ 4. Define `contains_item/2` for a list that may contain duplicates. How many
700
+ answers does `contains_item(a, [a, b, a])` give, and why?
701
+
702
+ ### Historical note: clauses become a programming medium
703
+
704
+ The ingredients of Part I were assembled across several traditions.
705
+ First-order logic supplied variables, substitution, and quantified formulas.
706
+ Herbrand's 1930 thesis made ground terms and ground instances central to proof
707
+ theory. Robinson's 1965 resolution principle gave automated deduction a
708
+ uniform, machine-oriented inference rule whose practical force came from
709
+ unification.
710
+
711
+ Prolog emerged when these ideas met a natural-language project in Marseille in
712
+ the early 1970s. Colmerauer and Roussel stress that the project did not begin
713
+ as an abstract attempt to invent a programming language: the need to analyze
714
+ French drove the development of executable clauses and their control.
715
+ Kowalski's procedural interpretation of Horn clauses, worked out in Edinburgh
716
+ at the same time, explained why a set of logical sentences could be run as a
717
+ program. Lists then became more than containers. They represented sentences,
718
+ syntax trees, proof states, and sequences of goals, and the two-clause list
719
+ program condensed a much older mathematical pattern, definition by
720
+ constructors and structural induction, into executable form.
650
721
 
651
722
  # Part II — Search
652
723
 
@@ -713,8 +784,16 @@ factorial(N, F) :-
713
784
  `factorial(5, F)` gives `F = 120`; `factorial(N, 120)` raises an error at
714
785
  `N > 0`. Record the intended mode in tests and comments.
715
786
 
716
- **Checkpoint.** In `square/2`, which goal binds `N`? What happens if you swap
717
- the two body goals?
787
+ **Exercises.**
788
+
789
+ 1. In `square/2`, which goal binds `N`? Swap the two body goals and run the
790
+ query; explain the instantiation error.
791
+ 2. Write `cube_below/2` that enumerates the cubes of the integers from 1 to a
792
+ given bound.
793
+ 3. Define `triangle_number(N, T)` for `T = 1 + 2 + ... + N` by recursion, then
794
+ by a closed formula with `is/2`, and compare them for `N` from 0 to 10.
795
+ 4. Explain why `factorial(N, 120)` cannot run backwards, and write a separate
796
+ relation that finds `N` by bounded generation.
718
797
 
719
798
  ## 7. Failure, negation, and quantification
720
799
 
@@ -789,9 +868,16 @@ goal of `wfs_truth/2` must be ground, as must direct calls to `tnot/1`, and in
789
868
  WFS rules every variable in the head or under `tnot/1` must occur in a positive
790
869
  body literal. Strict ISO mode has no `tnot/1`; `\+/1` is unchanged.
791
870
 
792
- **Checkpoint.** In the three-position game, change `move(b, c)` to
793
- `move(c, b)` and predict the truth value of each `win/1` atom before running
794
- `wfs_truth/2`.
871
+ **Exercises.**
872
+
873
+ 1. With `user(ann)`, `user(bob)`, and `blocked(bob)`, run `allowed(U)`, then
874
+ swap the two body goals and explain why the answer disappears.
875
+ 2. Write `all_tests_pass/1` for a suite in which one test has no `passed/1`
876
+ fact, and name the closed-world assumption the answer depends on.
877
+ 3. In the three-position game, change `move(b, c)` to `move(c, b)` and predict
878
+ the truth value of each `win/1` atom before running `wfs_truth/2`.
879
+ 4. Rewrite `allowed/1` for open data, where a missing `blocked/1` fact means
880
+ "unknown", using an explicit status relation.
795
881
 
796
882
  ## 8. Collecting and choosing answers
797
883
 
@@ -844,8 +930,16 @@ Keep candidate generation (`route/4`) separate from choice (`best_route/4`).
844
930
  The candidates can then be listed, counted, tested, and optimized by different
845
931
  queries without rewriting the search.
846
932
 
847
- **Checkpoint.** With no `route/4` facts at all, predict the result of
848
- `findall/3`, `countall/2`, `sumall/3`, and `aggregate_min/5` over it.
933
+ **Exercises.**
934
+
935
+ 1. With no `route/4` facts at all, predict the result of `findall/3`,
936
+ `countall/2`, `sumall/3`, and `aggregate_min/5` over it.
937
+ 2. Give two `edge/3` facts with the same cost from one node and compare
938
+ `outgoing_costs/2` with the sorted set of costs.
939
+ 3. Change the key of `best_route/4` so that ties are broken by the route with
940
+ fewer stops before term order.
941
+ 4. Write `cheapest_per_origin/2` that returns one best route for every origin.
942
+ Which variable must be bound before the aggregate runs?
849
943
 
850
944
  ## 9. Structured data, text, and contexts
851
945
 
@@ -902,6 +996,16 @@ never becomes a fact of the program. It stays data inside one message, and
902
996
  <img src="book-assets/context-data-boundary.svg" alt="Raw text becomes structured members inside one message context, which ordinary term traversal inspects without asserting those members globally.">
903
997
  <figcaption>Normalize text into structure at the boundary; inspecting a member inside one context does not make it a fact.</figcaption>
904
998
  </figure>
999
+ **Exercises.**
1000
+
1001
+ 1. Use `functor/3`, `arg/3`, and `=../2` to take `reading(temp, 91)` apart, and
1002
+ to build `reading(humidity, 40)` from its name and arguments.
1003
+ 2. Extend `normalized/2` to remove punctuation before splitting, and test it on
1004
+ two inputs that should normalize to the same words.
1005
+ 3. Add a second message to the `hot_event/1` program and query `hot_event(Id)`.
1006
+ Confirm that `severity(high)` is still not a fact of the program.
1007
+ 4. Write `context_value(Context, Name, Value)` for members of the form
1008
+ `Name(Value)`, using `context_member/2` and `=../2`.
905
1009
 
906
1010
  ## 10. From puzzles to models
907
1011
 
@@ -959,8 +1063,39 @@ The visited list makes the search finite: no state is entered twice on one
959
1063
  path. EyeProlog is at its best when the answer has a small witness such as a
960
1064
  path, schedule, or proof; numerical kernels belong in the host.
961
1065
 
962
- **Checkpoint.** Remove `(A \= C)` from `coloring/3` and predict the number of
963
- answers before running it. (There are twelve; account for the six new ones.)
1066
+ **Exercises.**
1067
+
1068
+ 1. Remove `(A \= C)` from `coloring/3` and predict the number of answers
1069
+ before running it. (There are twelve; account for the six new ones.)
1070
+ 2. Move all three tests to the end of `coloring/3` and compare the work
1071
+ reported by `--stats` with the original.
1072
+ 3. Color the four regions of a map in which one region touches the other
1073
+ three, using `color/1` and as few tests as possible.
1074
+ 4. Write `transition/3` facts for a two-jug water puzzle and use `plan/4` to
1075
+ find a sequence of moves. What makes the search finite?
1076
+
1077
+ ### Historical note: control, databases, and finite failure
1078
+
1079
+ Early Prolog made a decisive engineering choice: clauses would be tried in
1080
+ textual order and subgoals selected left to right. That choice made logic
1081
+ executable, and it also made control visible. A logically symmetric
1082
+ conjunction could behave asymmetrically when one order supplied a value and
1083
+ another asked arithmetic to run too soon.
1084
+
1085
+ The meeting of logic programming and database research in the 1970s sharpened
1086
+ questions about finite relations, closed-world reasoning, and query
1087
+ evaluation. Keith Clark's 1978 account did not identify failure with
1088
+ unrestricted logical negation; it related negation as failure to a completed
1089
+ database reading. Later work on stratification by Apt, Blair, and Walker
1090
+ disciplined negative dependencies, and the well-founded semantics gave
1091
+ recursion through negation a three-valued meaning. Aggregation continued the
1092
+ database lineage: a set of solutions could itself become data, provided the
1093
+ nested search was finite.
1094
+
1095
+ These distinctions explain EyeProlog's conservative treatment. Negation and
1096
+ aggregation are powerful because they expose a bounded subcomputation. Their
1097
+ safety comes not from punctuation but from an argument about scope and
1098
+ termination.
964
1099
 
965
1100
  # Part III — Trustworthy reasoning
966
1101
 
@@ -1057,8 +1192,16 @@ not hold.
1057
1192
  A proof is also a design review: detours point at overgrown helpers, and a
1058
1193
  premise hidden inside a computed value should become a fact.
1059
1194
 
1060
- **Checkpoint.** Edit `socrates.why.pl` so that the first step binds `'X'` to
1061
- `plato`, and run the check again. Which condition fails?
1195
+ **Exercises.**
1196
+
1197
+ 1. Run `--proof` on `examples/socrates.pl` and read each `step/4` downward
1198
+ from the claim, naming the clause it cites.
1199
+ 2. Save the proof as `socrates.why.pl`, edit the first step so that it binds
1200
+ `'X'` to `plato`, and run `--check-proof` again. Which condition fails?
1201
+ 3. Write a program in which the same goal is used twice in one body, and
1202
+ confirm that the proof records one step for it.
1203
+ 4. Add a `\+` goal to a rule and find the `absent` step in its proof. Why is it
1204
+ reported as a trusted boundary?
1062
1205
 
1063
1206
  ## 12. Integrity checks as ordinary predicates
1064
1207
 
@@ -1114,6 +1257,14 @@ perfectly valid answer, not invalid input. Keep four outcomes apart:
1114
1257
 
1115
1258
  `false/0` keeps its ISO meaning: a built-in that always fails. Clauses for
1116
1259
  `false` are rejected with `permission_error(modify, static_procedure)`.
1260
+ **Exercises.**
1261
+
1262
+ 1. Add `probability/2` facts, one of them above 1, and query
1263
+ `invalid_probability/2`.
1264
+ 2. Write an integrity relation for a person holding two incompatible roles at
1265
+ the same time, with arguments that identify both role records.
1266
+ 3. For a loan-approval theory, give one example of each of the four outcomes:
1267
+ no answer, an integrity answer, a resource limit, and an error.
1117
1268
 
1118
1269
  ## 13. Termination, tabling, and performance
1119
1270
 
@@ -1214,9 +1365,17 @@ Resource limits are never answers. Normal execution has no implicit depth
1214
1365
  limit; if an embedder sets `maxDepth` and a search exceeds it, EyeProlog raises
1215
1366
  `resource_error(depth_limit)` rather than quietly failing the branch.
1216
1367
 
1217
- **Checkpoint.** Classify three recursive calls: one over a shrinking list, one
1218
- over a finite cyclic graph, one that builds `s(s(...))` terms without bound.
1219
- Which terminate without tabling, which with it, and which with neither?
1368
+ **Exercises.**
1369
+
1370
+ 1. Classify three recursive calls: one over a shrinking list, one over a
1371
+ finite cyclic graph, one that builds `s(s(...))` terms without bound. Which
1372
+ terminate without tabling, which with it, and which with neither?
1373
+ 2. Run the untabled `reach/2` on a two-vertex cycle under a depth limit, then
1374
+ add `:- table reach/2.` and compare the outcomes.
1375
+ 3. Write a forward rule `Conclusion :+ Premise` that derives `ancestor/2` from
1376
+ `parent/2` facts, and run it without a goal.
1377
+ 4. Compare `--stats` for `reach(a, Z)` and `reach(Z, a)` on the same tabled
1378
+ graph, and explain the difference.
1220
1379
 
1221
1380
  ## 14. Knowledge engineering
1222
1381
 
@@ -1264,8 +1423,16 @@ The same layering works for most theories:
1264
1423
  Prefer positive concepts, negate only across a closed boundary, and keep
1265
1424
  confidence and provenance as data, not rule order.
1266
1425
 
1267
- **Checkpoint.** Which facts in the battery example can a proof *not*
1268
- authenticate? (Hint: where do the numbers come from?)
1426
+ **Exercises.**
1427
+
1428
+ 1. Which facts in the battery example can a proof *not* authenticate? (Hint:
1429
+ where do the numbers come from?)
1430
+ 2. Add a `cooling_failed/1` fact and a second policy rule for `action/2`, and
1431
+ check that the physics predicates did not change.
1432
+ 3. Run `examples/spacecraft-battery-diagnosis.pl` with `--proof` and sort its
1433
+ steps into the five layers listed in this chapter.
1434
+ 4. Lay out the layers for a small theory of your own: source facts, helpers,
1435
+ decisions, integrity relations, and outputs.
1269
1436
 
1270
1437
  ## 15. Explicit data boundaries
1271
1438
 
@@ -1325,9 +1492,15 @@ number. General text must go through a term constructor or serializer, never
1325
1492
  straight into source. The resource options cap the work an untrusted input can
1326
1493
  cause.
1327
1494
 
1328
- **Checkpoint.** For one record your application receives, write down what the
1329
- host validates, the term it builds, the goal it asks, and the limit that bounds
1330
- the work.
1495
+ **Exercises.**
1496
+
1497
+ 1. For one record your application receives, write down what the host
1498
+ validates, the term it builds, the goal it asks, and the limit that bounds
1499
+ the work.
1500
+ 2. Change `allowedSensors` so that a sensor name could contain a quote, and
1501
+ explain why string interpolation is then unsafe.
1502
+ 3. Extend the host to accept a list of readings and ask one goal per reading.
1503
+ Which of the four claims gains a new owner?
1331
1504
 
1332
1505
  ## 16. Embedding EyeProlog
1333
1506
 
@@ -1557,6 +1730,37 @@ point is dropped as soon as nothing is left. Mode-sensitive extensions can also
1557
1730
  supply `ready`, `fallbackWhenNotReady`, and `shouldUse` metadata, which affect
1558
1731
  dispatch and early filtering and are therefore part of the extension's
1559
1732
  contract.
1733
+ **Exercises.**
1734
+
1735
+ 1. Run the `run()` example and print `result.stats`. Then set
1736
+ `solutionLimit: 1` on a goal with several answers and explain why the limit
1737
+ is not a proof of absence.
1738
+ 2. Use `proofCertificate` and `verifyProof` on `q(a)`, then edit the program
1739
+ so that `p(a)` is missing and verify the old certificate again.
1740
+ 3. Add a host relation `host_time/1` to the registry with
1741
+ `createEyePrologRegistry()`, and decide whether it may be marked
1742
+ `deterministic`.
1743
+
1744
+ ### Historical note: from answers to accountable inference
1745
+
1746
+ The least-model semantics of van Emden and Kowalski (1976) connected definite
1747
+ programs to a mathematical fixed point: keep adding supported ground
1748
+ consequences until nothing new appears. Tabled logic programming, developed in
1749
+ systems such as XSB and described by Chen and Warren, turned that fixed point
1750
+ into a goal-directed technique that shares recursive calls and accumulates
1751
+ their answers. EyeProlog's explicit tabling is far smaller than those systems,
1752
+ but inherits their central insight: remembering a recursive question can change
1753
+ termination without changing what the relation says. For finite Datalog with
1754
+ recursion through `tnot/1`, it uses the alternating-fixed-point account of the
1755
+ well-founded semantics, so a negative cycle may remain undefined instead of
1756
+ being collapsed into negation as failure.
1757
+
1758
+ In parallel, deductive databases asked where facts come from and how derived
1759
+ claims keep their provenance. The lesson is architectural. A proof procedure
1760
+ can attest that a conclusion follows from the supplied clauses. It cannot
1761
+ authenticate a database, calibrate a sensor, or authorize a request. Systems
1762
+ became more trustworthy when those boundaries were named rather than left
1763
+ implicit.
1560
1764
 
1561
1765
  # Part IV — The craft of logic programming
1562
1766
 
@@ -1655,9 +1859,16 @@ selected goal, the clauses that match it, the bindings each produces, and the
1655
1859
  calls that repeat. The sketch usually shows a generator that is too broad or a
1656
1860
  test placed too late.
1657
1861
 
1658
- **Checkpoint.** Swap two body goals in a rule of your own. Before running it,
1659
- predict whether the answer set, termination, first answer, or proof shape
1660
- changes.
1862
+ **Exercises.**
1863
+
1864
+ 1. Swap two body goals in a rule of your own. Before running it, predict
1865
+ whether the answer set, termination, first answer, or proof shape changes.
1866
+ 2. Run both `adult/1` clauses with `Person` unbound and explain the
1867
+ difference.
1868
+ 3. Rewrite `bad_member/2` so that it terminates, and state the measure that
1869
+ decreases.
1870
+ 4. Write the intended modes of `append/3` that terminate, and give one call
1871
+ that does not.
1661
1872
 
1662
1873
  ## 18. Constructing a program
1663
1874
 
@@ -1755,8 +1966,16 @@ concept has no stable meaning yet. Add one representative query per layer as
1755
1966
  you go, so a silent failure in normalization shows up before the final
1756
1967
  decision predicate does.
1757
1968
 
1758
- **Checkpoint.** For a domain of your own, write three positive ground
1759
- examples, one near miss, and the intended query mode before writing any rule.
1969
+ **Exercises.**
1970
+
1971
+ 1. For a domain of your own, write three positive ground examples, one near
1972
+ miss, and the intended query mode before writing any rule.
1973
+ 2. Write `suffix/2` from examples, as `prefix/2` was written, starting with the
1974
+ smallest positive case.
1975
+ 3. Split a rule of your own into generate and test parts, as in
1976
+ `compatible_pair/2`, and compare the proofs.
1977
+ 4. Choose a representation for a timetable and justify it by the questions it
1978
+ must answer.
1760
1979
 
1761
1980
  ## 19. Correctness and termination
1762
1981
 
@@ -1824,8 +2043,16 @@ A failed eligibility query may be a legitimate "no". A successful
1824
2043
  `invalid_limits/3` query means the host should stop deciding until the data is
1825
2044
  repaired.
1826
2045
 
1827
- **Checkpoint.** For one recursive relation of your own, state its invariant and
1828
- its termination measure in one sentence each.
2046
+ **Exercises.**
2047
+
2048
+ 1. For one recursive relation of your own, state its invariant and its
2049
+ termination measure in one sentence each.
2050
+ 2. Prove by induction that `prefix/2` returns only prefixes, then that it finds
2051
+ every prefix of a proper list.
2052
+ 3. Move the subtraction in `factorial/2` after the recursive call and show
2053
+ which of the three claims fails.
2054
+ 4. Write an integrity relation in the style of `invalid_limits/3` for a range
2055
+ whose lower bound exceeds its upper bound.
1829
2056
 
1830
2057
  ## 20. Improving a program
1831
2058
 
@@ -1887,9 +2114,36 @@ Finally, resist generality nobody needs. A predicate that supports three modes
1887
2114
  can be harder to terminate, explain, and index than two simple predicates with
1888
2115
  clear contracts. Generalize when the second real use appears.
1889
2116
 
1890
- **Checkpoint.** Make exactly one control change to a program and classify each
1891
- difference in answers, proofs, and `--stats` as intended, harmless but
1892
- observable, or a regression.
2117
+ **Exercises.**
2118
+
2119
+ 1. Make exactly one control change to a program and classify each difference
2120
+ in answers, proofs, and `--stats` as intended, harmless but observable, or a
2121
+ regression.
2122
+ 2. Replace `connected/2` by a tabled reachability relation and compare the
2123
+ number of answers and the work on a graph with many paths.
2124
+ 3. Find a predicate of your own named like `step2/3` and replace it with a
2125
+ helper that adds vocabulary, as `within_thermal_limits/1` does.
2126
+ 4. Hoist one invariant computation out of a recursion, then check that the
2127
+ answers and the first proof are unchanged.
2128
+
2129
+ ### Historical note: logic plus control
2130
+
2131
+ Kowalski's 1979 formulation "algorithm = logic + control" gave a durable name
2132
+ to the dual reading developed in this Part. The logic component states what is
2133
+ known; control determines how it is used. The slogan did not claim that control
2134
+ was unimportant. It argued that control can often be improved while meaning
2135
+ stays fixed, and that programs are easier to reason about when the two are
2136
+ kept apart.
2137
+
2138
+ The craft tradition of Prolog grew around this tension. Goal ordering,
2139
+ accumulators, generate-and-test, and changes of representation were never
2140
+ mere interpreter tricks; at their best they were transformations justified by
2141
+ invariants and modes. Sterling and Shapiro made construction and improvement
2142
+ central to *The Art of Prolog*, showing that declarative clarity and
2143
+ procedural competence mature together. Later work on the verification of logic
2144
+ programs, collected in Apt's *From Logic Programming to Prolog* (1997), gave
2145
+ the same intuition a formal footing: partial correctness, completeness, and
2146
+ termination are separate obligations, each with its own proof method.
1893
2147
 
1894
2148
  # Part V — Advanced relational design
1895
2149
 
@@ -2005,12 +2259,14 @@ usually locate the problem.
2005
2259
 
2006
2260
  **Exercises.**
2007
2261
 
2008
- 1. Draw the and–or tree for `ancestor(byron, Who)`, then add a second parent
2009
- of `clara` and mark where it branches.
2010
- 2. Write a cyclic `edge/2` graph, table `path/2`, and compare its answers with
2011
- the table rounds reported by `--stats`.
2012
- 3. Write a recursive rule whose call grows a list each step and explain why
2013
- tabling does not make it finite.
2262
+ 1. Draw the and–or tree for `ancestor(byron, Who)`. Then add a second parent of
2263
+ `clara` and mark where the tree gains a branch.
2264
+ 2. For `eligible/1`, keep a binding ledger for an applicant whose
2265
+ `verified/1` fact is missing, and name the choice that search resumes from.
2266
+ 3. Write a cyclic `edge/2` graph, table `path/2`, and compare its answers with
2267
+ the table counters reported by `--stats`.
2268
+ 4. Write a recursive rule whose call grows a term on every step, like
2269
+ `grows/1`, and explain why tabling cannot make it finite.
2014
2270
 
2015
2271
  ## 22. Trees, languages, and symbolic evaluation
2016
2272
 
@@ -2154,9 +2410,12 @@ first rule, expanding `X` into `add(X, number(0))`, and rewriting never stops.
2154
2410
 
2155
2411
  **Exercises.**
2156
2412
 
2157
- 1. Define `tree_size/2` and `tree_height/2`.
2158
- 2. Add adjectives to the grammar and subtraction to the evaluator.
2159
- 3. Define constant folding for `add(number(A), number(B))`.
2413
+ 1. Define `tree_size/2` and `tree_height/2` for the `tree/3` representation.
2414
+ 2. Add adjectives to the sentence grammar and subtraction to `evaluate/2`.
2415
+ 3. Extend `simplify/2` with constant folding for `add(number(A), number(B))`,
2416
+ and give a measure showing that repeated simplification terminates.
2417
+ 4. Prove by structural induction that applying `mirror/2` twice returns the
2418
+ original tree.
2160
2419
 
2161
2420
  ## 23. Transforming programs
2162
2421
 
@@ -2284,9 +2543,13 @@ drops a mode is a different program.
2284
2543
 
2285
2544
  **Exercises.**
2286
2545
 
2287
- 1. Unfold a two-clause helper and count the resulting caller clauses.
2288
- 2. Compare direct and accumulator-based list length in several modes.
2289
- 3. Find a transformation that keeps the answer set but changes the first proof
2546
+ 1. Unfold a helper with two clauses into its caller and count the resulting
2547
+ caller clauses. What did the proof lose?
2548
+ 2. Compare a direct and an accumulator-based list length in every mode you can
2549
+ call them in. Which modes does each support, and which terminate?
2550
+ 3. State the invariant of `sum_from/3` and use it to show that
2551
+ `sum_numbers/2` and `sum_numbers_acc/2` agree on ground numeric lists.
2552
+ 4. Find a transformation that keeps the answer set but changes the first proof
2290
2553
  that `once/1` selects.
2291
2554
 
2292
2555
  ## 24. Designing finite search
@@ -2396,10 +2659,12 @@ it only when that order is part of the specification.
2396
2659
 
2397
2660
  **Exercises.**
2398
2661
 
2399
- 1. Add skills and time slots to the assignment example.
2400
- 2. Make `simple_path/3` return an accumulated cost.
2401
- 3. Write a recursive first clause that starves a valid later base clause, then
2402
- repair it.
2662
+ 1. Add skills and time slots to `assignment/2`, keeping the search finite.
2663
+ 2. Make `simple_path/3` return the accumulated cost of the path as well.
2664
+ 3. Change the key in `best_plan/3` so that equal-cost plans prefer the shorter
2665
+ plan, and explain why the new key does so.
2666
+ 4. Write a recursive first clause that starves a valid later base clause, then
2667
+ repair it and explain why the repair terminates.
2403
2668
 
2404
2669
  ## 25. Case study: an auditable decision service
2405
2670
 
@@ -2532,9 +2797,36 @@ a past decision can be reconstructed under the rules that governed it.
2532
2797
 
2533
2798
  **Exercises.**
2534
2799
 
2535
- 1. Add time-bounded training using explicit dates and `difference/3` from `library(dates)`.
2536
- 2. Model `denial/3` without assuming every failed permit has the same reason.
2800
+ 1. Add a second badge for `ada` and observe that `permit(Person, Zone)` gives
2801
+ one answer with two proofs. Redesign the relation so the badge is part of
2802
+ the answer.
2803
+ 2. Add time-bounded training using explicit dates and `difference/3` from
2804
+ `library(dates)`.
2537
2805
  3. Write an integrity relation for a badge assigned to two people.
2806
+ 4. Model `denial/3` without assuming that every failed permit has the same
2807
+ reason.
2808
+
2809
+ ### Historical note: interpreters, transformation, and the art tradition
2810
+
2811
+ Logic programming became a laboratory for symbolic computation because its
2812
+ principal data (terms, clauses, substitutions, and proof trees) could be
2813
+ represented with the same structures as any other domain. Meta-interpreters
2814
+ made resolution itself a topic of programs; Pereira and Warren's definite
2815
+ clause grammars (1980) made language recognition relational; partial
2816
+ evaluation showed how a general relation could be specialized when part of its
2817
+ input was known.
2818
+
2819
+ Futamura's work in the 1970s gave partial evaluation a striking reading:
2820
+ specializing an interpreter to a source program yields a compiled program.
2821
+ Tamaki and Sato's unfold/fold transformations (1984) gave logic programs a
2822
+ calculus of meaning-preserving rewrites. EyeProlog does not build every classic
2823
+ transformation in. What it inherits is the demand that a transformation name
2824
+ its invariant and preserve a stated answer contract.
2825
+
2826
+ *The Art of Prolog* joined computation, construction, nondeterminism, grammars,
2827
+ interpreters, transformation, and applications into one sustained account of
2828
+ craft. This Part follows that breadth with EyeProlog's explicit means: syntax is
2829
+ data, state is an argument, and audit evidence remains visible.
2538
2830
 
2539
2831
  # Part VI — Mathematics made executable
2540
2832
 
@@ -2634,32 +2926,17 @@ A tabled predicate makes the connection concrete. Its table grows with each
2634
2926
  new answer until no rule adds another — a local, demand-driven fixed-point
2635
2927
  computation.
2636
2928
 
2637
- ### Where the idea came from
2638
-
2639
- The path to logic programming ran through mathematics examining its own
2640
- methods. Hilbert made formal proof and consistency mathematical subjects.
2641
- Gödel showed that sufficiently expressive consistent systems cannot prove
2642
- every arithmetical truth. Church and Turing made "effective procedure" exact
2643
- and proved that some decision problems have no algorithm. Herbrand reduced
2644
- quantified statements to ground instances, Robinson turned unification into a
2645
- uniform inference rule, and van Emden and Kowalski gave definite programs
2646
- their least-model meaning. Each step made one idea precise and exposed a new
2647
- limit; resolution, in particular, still needed control — selection order,
2648
- clause order, and eventually tabling.
2649
-
2650
2929
  **Exercises.**
2651
2930
 
2652
2931
  1. Run `triple/3` with one, two, and three arguments bound. Compare the
2653
2932
  question asked, the answers, and the amount of search.
2654
2933
  2. Keep only primitive triples by rejecting those whose sides share a divisor.
2655
- Which generators make the negation safe?
2656
- 3. In `examples/fundamental-theorem-arithmetic.pl`, separate the witness it
2657
- constructs from the property it verifies.
2658
- 4. Draw the fixed-point rounds for a four-edge graph with one cycle.
2659
-
2660
- **Checkpoint.** For one printed answer, state the existential claim its
2661
- bindings witness, the finite domain that made search possible, and what
2662
- further argument a universal theorem would need.
2934
+ Which generators must run first to make the negation safe?
2935
+ 3. Draw the fixed-point rounds of the least model for a four-edge graph with
2936
+ one cycle.
2937
+ 4. For one printed answer of `triple/3`, state the existential claim its
2938
+ bindings witness, the finite domain that made the search possible, and what
2939
+ further argument a universal theorem would need.
2663
2940
 
2664
2941
  ## 27. Recursion is induction in motion
2665
2942
 
@@ -2764,16 +3041,15 @@ it.
2764
3041
 
2765
3042
  **Exercises.**
2766
3043
 
2767
- 1. Define multiplication on Peano naturals and give its decreasing measure.
2768
- 2. Prove the strengthened `reverse_go/3` invariant on paper.
2769
- 3. Compare the termination arguments for list membership and for reachability
2770
- on a cyclic graph.
2771
- 4. In `examples/peano-calculus.pl`, find where the data constructors determine
2772
- the available induction.
2773
-
2774
- **Checkpoint.** Line up one recursive program with its induction proof — base
2775
- clause and base case, recursive call and hypothesis, head and conclusion —
2776
- then give a separate termination measure.
3044
+ 1. Define multiplication on Peano naturals using `plus/3` and give its
3045
+ decreasing measure.
3046
+ 2. Prove the strengthened `reverse_go/3` invariant by induction on the first
3047
+ argument.
3048
+ 3. Compare the termination arguments for list membership and for tabled
3049
+ reachability on a cyclic graph.
3050
+ 4. In `examples/peano-calculus.pl`, line up one recursive predicate with its
3051
+ induction proof (base clause and base case, recursive call and hypothesis,
3052
+ head and conclusion), then give a separate termination measure.
2777
3053
 
2778
3054
  ## 28. Algebra, symmetry, and representation
2779
3055
 
@@ -2894,10 +3170,8 @@ and which induction it exposes.
2894
3170
  for a zero denominator and a noncanonical zero.
2895
3171
  3. Use `examples/d3-group.pl` to check identity, inverses, and associativity.
2896
3172
  Which checks are exhaustive, and why?
2897
-
2898
- **Checkpoint.** Take a value with two possible representations. Say whether
2899
- EyeProlog treats them as structurally equal, whether the domain treats them as
2900
- equivalent, and what connects the two.
3173
+ 4. Use `integer_rectangle/3` to list the rectangles of area 36, then explain
3174
+ which argument supplies the finite direction for the inverse problem.
2901
3175
 
2902
3176
  ## 29. Search as experimental mathematics
2903
3177
 
@@ -2984,18 +3258,16 @@ conditions alongside the result.
2984
3258
 
2985
3259
  **Exercises.**
2986
3260
 
2987
- 1. Turn a familiar universal conjecture into a bounded counterexample search.
2988
- State what an empty result does and does not prove.
2989
- 2. Estimate the naive search space of `send-more-money.pl`, then identify the
2990
- constraint that removes the most branches.
3261
+ 1. Turn a familiar universal conjecture into a bounded counterexample search in
3262
+ the style of `counterexample_to_odd_square/1`. State what an empty result
3263
+ proves and what it does not.
3264
+ 2. Estimate the naive search space of `examples/send-more-money.pl`, then
3265
+ identify the constraint that removes the most branches.
2991
3266
  3. Search a three-element carrier for a noncommutative operation with an
2992
- identity.
2993
- 4. For one scientific example, list every premise that is not pure logic.
2994
-
2995
- **Checkpoint.** Label a computation as witness construction, counterexample,
2996
- exhaustive finite check, bounded evidence, or numerical model evaluation. In
2997
- one sentence each, say what its success proves and what its failure leaves
2998
- open.
3267
+ identity, and return the offending pair as a witness.
3268
+ 4. Classify one computation of your own as witness construction,
3269
+ counterexample, exhaustive finite check, bounded evidence, or numerical
3270
+ model evaluation, and say what its success and its failure establish.
2999
3271
 
3000
3272
  ## 30. What mathematics promises
3001
3273
 
@@ -3061,14 +3333,34 @@ from which version of the theory.
3061
3333
  trust.
3062
3334
  2. Write a conclusion that is valid from false premises, and explain why proof
3063
3335
  checking cannot repair it.
3064
- 3. Write a one-page trust contract for an embedded EyeProlog service: accepted
3065
- sources, model scope, numeric assumptions, resource bounds, proof
3066
- retention, and known limits.
3336
+ 3. Prefix one strong conclusion with every condition it depends on: source
3337
+ authenticity, model scope, built-in semantics, finite search, theory
3338
+ version, and derivation validity.
3339
+ 4. Write a one-page trust contract for an embedded EyeProlog service: accepted
3340
+ sources, model scope, numeric assumptions, resource bounds, proof retention,
3341
+ and known limits.
3067
3342
 
3068
- **Checkpoint.** Prefix one strong conclusion with every condition it depends
3069
- on: source authenticity, model scope, built-in semantics, finite search,
3070
- theory version, and derivation validity. If the qualified claim still
3071
- matters, the model has earned its confidence.
3343
+ ### Historical note: mathematics examines its own methods
3344
+
3345
+ The path to logic programming ran through mathematics examining its own
3346
+ methods. Hilbert's program made formal proof and consistency mathematical
3347
+ objects. Gödel established limits for sufficiently expressive effective
3348
+ axiomatic systems. Church and Turing made effective calculability precise
3349
+ enough to prove that some decision problems have no algorithm. Herbrand and
3350
+ Robinson supplied the ideas that became central to automated first-order
3351
+ deduction.
3352
+
3353
+ Logic programming belongs to this history because it operationalizes a
3354
+ restricted proof discipline. It does not erase the limit results or turn every
3355
+ existence proof into an efficient witness generator. It gives a small region
3356
+ where propositions, substitutions, proof steps, and computations can be
3357
+ inspected together.
3358
+
3359
+ The deeper inheritance is a style of honesty. Mathematics advanced by proving
3360
+ not only more statements but also where its methods fail, separating truth,
3361
+ provability, decidability, and computation. Finite bounds, mode restrictions,
3362
+ search risks, and trust boundaries belong in an account of EyeProlog for the
3363
+ same reason: limits are part of the result, not fine print.
3072
3364
 
3073
3365
  # Part VII — The reasoning laboratory
3074
3366
 
@@ -3216,13 +3508,12 @@ Keep three outcomes distinct:
3216
3508
 
3217
3509
  1. Build the domain-language test table for `ancestor/2`, including a cycle and
3218
3510
  the disputed reflexive case.
3219
- 2. Write bounded commutativity and associativity tests for a finite operation
3220
- table. Which is cheaper, and why?
3511
+ 2. Extend `bounded_double_law/0` into bounded commutativity and associativity
3512
+ tests for a finite operation table. Which is cheaper, and why?
3221
3513
  3. Write a metamorphic test for a route planner.
3222
3514
  4. Design a test that tells "no answer" apart from "invalid input".
3223
-
3224
- **Checkpoint.** Fill in the test matrix for one public relation and say which
3225
- expected outputs should be exact goldens.
3515
+ 5. Fill in the minimum test matrix for one public relation and say which
3516
+ expected outputs should be exact goldens.
3226
3517
 
3227
3518
  ## 32. Debugging by meaning, search, and proof
3228
3519
 
@@ -3356,14 +3647,13 @@ Otherwise the repository remembers the fix and forgets the reason.
3356
3647
 
3357
3648
  1. Introduce a missing join into a two-relation rule, then use the proof of a
3358
3649
  false positive to find it.
3359
- 2. Write a term-growing recursive rule and explain why tabling cannot make its
3360
- answer space finite.
3650
+ 2. Make `optimized_square/2` differ from `reference_square/2` at one point and
3651
+ show that `disagreement/2` finds it. Add the check for the other direction.
3361
3652
  3. Compare `--stats` before and after moving an invariant calculation out of a
3362
3653
  recursion.
3363
-
3364
- **Checkpoint.** Turn one defect into a regression: the smallest disputed
3365
- ground question, the expected answer, the first wrong binding or search
3366
- choice, the repaired invariant, and the test that fails if it returns.
3654
+ 4. Turn one defect into a regression: the smallest disputed ground question,
3655
+ the expected answer, the first wrong binding or search choice, the repaired
3656
+ invariant, and the test that fails if the defect returns.
3367
3657
 
3368
3658
  ## 33. A pattern catalog for reasoning
3369
3659
 
@@ -3511,9 +3801,27 @@ that. Use the smallest set of patterns the problem actually calls for.
3511
3801
  2. Refactor an opaque rule into boundary, concept, and decision layers, and
3512
3802
  compare the proofs before and after.
3513
3803
  3. Write a versioned evidence envelope for the Chapter 25 decision service.
3514
-
3515
- **Checkpoint.** For one real theory, pick the smallest set of patterns that
3516
- solves its problem and name the pressure that justifies each.
3804
+ 4. For one real theory, pick the smallest set of patterns that solves its
3805
+ problem and name the pressure that justifies each.
3806
+
3807
+ ### Historical note: executable specifications learn to remember
3808
+
3809
+ Logic programs have long stood between specification and implementation. That
3810
+ made testing both easier and subtler: a ground clause could serve as an
3811
+ example, yet a relation might have several modes and an answer set rather than
3812
+ one returned value. Shapiro's algorithmic program debugging (1983) turned this
3813
+ into a method, locating a wrong clause by asking an oracle about the intended
3814
+ meaning of the program's subgoals. Testing practice later absorbed ideas from
3815
+ theorem proving, database validation, regression testing, and property-based
3816
+ testing.
3817
+
3818
+ A repository makes this practice durable. A theory, its exact answer files,
3819
+ proof files, conformance corpus, and version tags preserve not only a program
3820
+ but expectations about its meaning. Regression tests make old decisions
3821
+ reviewable; property tests seek counterexamples; metamorphic tests state what
3822
+ must stay invariant under controlled change. Patterns complete the cycle by
3823
+ naming recurring design knowledge, so that the failure that taught a lesson
3824
+ becomes executable memory.
3517
3825
 
3518
3826
  # Part VIII — Standard Prolog in practice
3519
3827
 
@@ -3615,8 +3923,17 @@ and
3615
3923
  [`iso-integer-arithmetic.pl`](https://github.com/eyereasoner/eyeprolog/blob/main/examples/iso-integer-arithmetic.pl)
3616
3924
  run each of these side by side.
3617
3925
 
3618
- **Checkpoint.** Name one absence in a route planner that should fail and one
3619
- broken precondition that should throw.
3926
+ **Exercises.**
3927
+
3928
+ 1. Rewrite `travel_status/3` as two clauses, one for `connected` and one using
3929
+ `\+ route(From, To)`. With `route(a, b)` stated twice, count the solutions
3930
+ of each version with `findall/3` and explain the difference.
3931
+ 2. Make `require_route/2` throw `type_error(atom, From)` when `From` is not an
3932
+ atom, and show that `checked_route/3` lets that error pass outward.
3933
+ 3. Remove `Seller^` from `regional_total/2` and predict its answers for a
3934
+ region with two sellers.
3935
+ 4. In a route planner, name one absence that should fail and one broken
3936
+ precondition that should throw.
3620
3937
 
3621
3938
  ## 35. Reflective terms and atomic conversion
3622
3939
 
@@ -3658,8 +3975,15 @@ and
3658
3975
  [`iso-atomic-conversion.pl`](https://github.com/eyereasoner/eyeprolog/blob/main/examples/iso-atomic-conversion.pl),
3659
3976
  which lists every three-character sub-atom of `eyeprolog`.
3660
3977
 
3661
- **Checkpoint.** Given `pair(X, X)`, predict `term_variables/2` before and
3662
- after `copy_term/2`.
3978
+ **Exercises.**
3979
+
3980
+ 1. Given `pair(X, X)`, predict the result of `term_variables/2` before and
3981
+ after `copy_term/2`.
3982
+ 2. Write `term_size/2`, counting the nodes of a term, once with `functor/3` and
3983
+ `arg/3` and once with `=../2`.
3984
+ 3. Explain why `3 + 4 < 8` succeeds while `3 + 4 @< 8` fails.
3985
+ 4. Use `sub_atom/5` with `findall/3` to collect every three-character sub-atom
3986
+ of `eyeprolog`, and predict their number before running it.
3663
3987
 
3664
3988
  ## 36. Dynamic predicates, directives, and operators
3665
3989
 
@@ -3728,8 +4052,16 @@ See
3728
4052
  and
3729
4053
  [`iso-operators.pl`](https://github.com/eyereasoner/eyeprolog/blob/main/examples/iso-operators.pl).
3730
4054
 
3731
- **Checkpoint.** Give the clause order after one `asserta/1` and two
3732
- `assertz/1` calls.
4055
+ **Exercises.**
4056
+
4057
+ 1. Give the clause order of `task/2` after one `asserta/1` and two `assertz/1`
4058
+ calls.
4059
+ 2. Write `pop_task/1`, which retracts the first `task/2` clause and returns it,
4060
+ and show that backtracking into a later failure does not restore the task.
4061
+ 3. Declare an infix operator such as `implies` and write three facts with it.
4062
+ Use `write_canonical/1` to show the terms that were stored.
4063
+ 4. Write an embedded quad test that checks the `task/2` order produced by
4064
+ `prepare_queue/0`.
3733
4065
 
3734
4066
  ## 37. Streams and term I/O
3735
4067
 
@@ -3792,18 +4124,33 @@ it.
3792
4124
  writes a fixture under `/tmp`, reads it back and observes the end of the
3793
4125
  stream.
3794
4126
 
3795
- **Checkpoint.** Why does `write_event/2` belong outside the relation that
3796
- decides what an event means?
4127
+ **Exercises.**
4128
+
4129
+ 1. Use `write_event/2` to write two events, then read them back with `read/2`
4130
+ until `end_of_file`.
4131
+ 2. Write `f('A b', 1+2, "ab")` with `write/1`, `writeq/1`, and
4132
+ `write_canonical/1`, and say which outputs another Prolog can read back.
4133
+ 3. Open a text stream for writing and call `put_byte/2` on it. Which error is
4134
+ raised, and why is that better than guessing an encoding?
4135
+ 4. Why does `write_event/2` belong outside the relation that decides what an
4136
+ event means?
3797
4137
 
3798
4138
  ### Historical note: the practical language becomes portable
3799
4139
 
3800
- In the late 1970s and 1980s Prolog spread from Marseille into several
3801
- implementation traditions. The Edinburgh and DECsystem-10 lineage settled the
3802
- practical vocabulary of ordered control, term inspection, dynamic clauses,
3803
- operators and streams, and the differences between systems made portability a
3804
- lasting concern. ISO/IEC 13211-1:1995 gave that practice a common core, against
3805
- which later constraints, modules, tabling and coroutining could be named as
3806
- extensions.
4140
+ By the late 1970s and 1980s, Prolog had spread from Marseille into several
4141
+ implementation traditions. David H. D. Warren's DECsystem-10 Prolog compiler
4142
+ (1977), whose techniques he later distilled into the Warren Abstract Machine
4143
+ (1983), established much of the practical vocabulary in Edinburgh: ordered control,
4144
+ term inspection, dynamic clauses, operators, and streams. These facilities made
4145
+ Prolog useful far beyond theorem-proving examples, but differences between
4146
+ systems also made portability a recurring concern.
4147
+
4148
+ ISO/IEC 13211-1:1995 gave that accumulated practice a common core. It did not
4149
+ freeze the language: constraints, modules, tabling, coroutining, and other
4150
+ facilities continued to develop in implementations and in later
4151
+ standardization work. What the standard supplied was a stable, shared account
4152
+ of ordinary Prolog terms, control, state, errors, and I/O, against which
4153
+ extensions could be named.
3807
4154
 
3808
4155
  # Part IX — Reference as practice
3809
4156
 
@@ -7933,10 +8280,18 @@ filename, open with a comment stating the lesson and the model's boundary,
7933
8280
  keep its queries finite and its output small, include a positive and a
7934
8281
  boundary case, and come with its answer, proof, and check files.
7935
8282
 
7936
- **Checkpoint.** Run one example with `--proof --stats`. Which output is the
7937
- reusable logical result, which describes this particular run, and which
7938
- status does a calling process see? Change one fact and predict all three before
7939
- rerunning.
8283
+ **Exercises.**
8284
+
8285
+ 1. Run one example with `--proof --stats`. Which output is the reusable
8286
+ logical result, which describes this particular run, and which status does a
8287
+ calling process see? Change one fact and predict all three before rerunning.
8288
+ 2. Save the proof of `examples/socrates.pl` and check it with `--check-proof`.
8289
+ Delete the step for `type(socrates, man)` and check again; then restore it
8290
+ and delete the step for `type(socrates, mortal)` instead. Why does only the
8291
+ second deletion fail, and which conditions report it?
8292
+ 3. Write a three-quad test file for `ancestor/2` with one ordered answer
8293
+ sequence, one `false.` description, and one labelled quad, and run it with
8294
+ `--quads`.
7940
8295
 
7941
8296
  ## 41. Standards, limits, and implementation boundaries
7942
8297
 
@@ -8105,6 +8460,25 @@ languages and theories and are not EyeProlog specifications.
8105
8460
  - David Hilbert,
8106
8461
  [“Mathematical Problems”](https://www.gutenberg.org/ebooks/71655), Paris,
8107
8462
  1900. The problem-directed axiomatic culture behind Part VI.
8463
+ - Robert A. Kowalski, “Predicate Logic as Programming Language”, *Proceedings
8464
+ of IFIP Congress 74*, 1974, pp. 569–574. The procedural interpretation of
8465
+ Horn clauses (Part I).
8466
+ - David H. D. Warren, *An Abstract Prolog Instruction Set*, Technical Note 309,
8467
+ SRI International, 1983. The Warren Abstract Machine (Part VIII).
8468
+ - Fernando C. N. Pereira and David H. D. Warren, “Definite Clause Grammars for
8469
+ Language Analysis”, *Artificial Intelligence* 13(3), 1980, pp. 231–278
8470
+ (Chapter 22).
8471
+ - Hisao Tamaki and Taisuke Sato, “Unfold/Fold Transformation of Logic
8472
+ Programs”, *Proceedings of the Second International Logic Programming
8473
+ Conference*, 1984, pp. 127–138 (Chapter 23).
8474
+ - Ehud Y. Shapiro, *Algorithmic Program Debugging*, MIT Press, 1983
8475
+ (Chapter 32).
8476
+ - Krzysztof R. Apt, *From Logic Programming to Prolog*, Prentice Hall, 1997.
8477
+ Correctness, completeness, and termination of logic programs (Chapter 19).
8478
+ - William F. Clocksin and Christopher S. Mellish, *Programming in Prolog*,
8479
+ Springer, 1981; Ivan Bratko, *Prolog Programming for Artificial
8480
+ Intelligence*, Addison-Wesley, 1986. Teaching Prolog by construction
8481
+ (Part X).
8108
8482
  - Dörthe Arndt and Stephan Mennicke,
8109
8483
  [“Notation3 as an Existential Rule Language”](https://arxiv.org/abs/2308.07332),
8110
8484
  2023. Semantic Web rules and existential-rule reasoning.
@@ -8305,6 +8679,23 @@ variables. Tabling recognizes variant calls.
8305
8679
  **Witness.** A ground term demonstrating an existential claim: a path, an
8306
8680
  assignment, a factorization, a schedule.
8307
8681
 
8682
+ ### Historical note: manuals become specifications
8683
+
8684
+ Early Prolog programmers learned from implementation manuals, examples, and
8685
+ books whose descriptions were often inseparable from one particular system. As
8686
+ the language spread, reference writing acquired a second task: telling the
8687
+ portable language apart from implementation convention. Predicate indexes,
8688
+ precise mode and error descriptions, and standards documents became tools for
8689
+ comparing systems rather than merely operating one of them.
8690
+
8691
+ Standardization made that distinction explicit, and conformance suites such as
8692
+ Ulrich Neumerkel's ISO conformity assessment made many disagreements between
8693
+ systems executable. A mature reference therefore joins several kinds of
8694
+ evidence: normative prose, named predicates and flags, examples,
8695
+ implementation boundaries, and reproducible tests. It is not a substitute for
8696
+ programming practice; it is a map from a concrete question to the contract
8697
+ that governs it.
8698
+
8308
8699
  # Part X — Laboratories
8309
8700
 
8310
8701
  ## 43. Laboratories
@@ -8505,3 +8896,20 @@ an unbounded theorem.
8505
8896
  **Laboratories.** A finished answer is an artifact, not a paragraph: a source
8506
8897
  file, the predicted output, the actual output, and one sentence explaining any
8507
8898
  difference.
8899
+
8900
+ ### Historical note: logic programming grows through exercises
8901
+
8902
+ Logic programming has long been taught by construction. Lists, family
8903
+ relations, puzzles, grammars, interpreters, search problems, and small expert
8904
+ systems became recurring exercises because each exposes both a logical
8905
+ relation and the control needed to compute with it. Clocksin and Mellish's
8906
+ *Programming in Prolog* (1981), Bratko's *Prolog Programming for Artificial
8907
+ Intelligence* (1986), and Sterling and Shapiro's *The Art of Prolog* (1986)
8908
+ made this dual reading the core of teaching: an exercise was not finished when
8909
+ a clause parsed, but when its meaning, modes, and behavior could be explained.
8910
+
8911
+ Laboratory practice later absorbed regression testing, property-based
8912
+ checking, benchmark corpora, and reproducible command-line runs. These tools
8913
+ fit logic programming unusually well, because a small change can be examined
8914
+ at several levels at once: answers, failures, witnesses, proofs, and search.
8915
+ The laboratory is where a declarative claim becomes an executable experiment.