eyeprolog 1.6.39 → 1.6.40

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.
@@ -0,0 +1,14 @@
1
+ condition('C1', resolution, ok, 2).
2
+ condition('C2', well_founded, ok, 3).
3
+ condition('C3', justification, ok, 3).
4
+ condition('C4', coverage, ok, 3).
5
+ condition('C5', re_decision, ok, 1).
6
+ condition('C6', boundary_consistency, ok, 0).
7
+ condition('C7', relevance, ok, 4).
8
+ steps(3).
9
+ verified(2).
10
+ recomputed(1).
11
+ composed(0).
12
+ trusted(0).
13
+ claims(1).
14
+ verdict(checked).
@@ -0,0 +1,14 @@
1
+ condition('C1', resolution, ok, 2).
2
+ condition('C2', well_founded, ok, 2).
3
+ condition('C3', justification, ok, 2).
4
+ condition('C4', coverage, ok, 2).
5
+ condition('C5', re_decision, ok, 0).
6
+ condition('C6', boundary_consistency, ok, 0).
7
+ condition('C7', relevance, ok, 3).
8
+ steps(2).
9
+ verified(2).
10
+ recomputed(0).
11
+ composed(0).
12
+ trusted(0).
13
+ claims(1).
14
+ verdict(checked).
@@ -81,6 +81,8 @@ check of that proof. Each deck links to the source and opens the example in the
81
81
  - [Delayed disequality with dif/2](https://eyereasoner.github.io/eyeprolog/examples/deck/dif-constraints) — How do you say "these must differ" before you know what they are?
82
82
  - [Delfour: a privacy-preserving shopping insight](https://eyereasoner.github.io/eyeprolog/examples/deck/delfour) — Can a store scanner give diabetes-aware advice without ever learning about the diabetes?
83
83
  - [Deontic logic](https://eyereasoner.github.io/eyeprolog/examples/deck/deontic-logic) — Which duties were broken, which were repaired, and does someone need to review it?
84
+ - [Dependency depth: 10,000 predicates](https://eyereasoner.github.io/eyeprolog/examples/deck/dependency-depth-10000) — Can dependency analysis follow a deep chain without exhausting the JavaScript stack?
85
+ - [Dependency preparation: 5,000 predicates](https://eyereasoner.github.io/eyeprolog/examples/deck/dependency-preparation-5000) — How quickly can the engine prepare thousands of distinct predicates?
84
86
  - [Dijkstra with findall and sort](https://eyereasoner.github.io/eyeprolog/examples/deck/dijkstra-findall-sort) — What is the cheapest route, found the way Dijkstra would?
85
87
  - [Dining philosophers](https://eyereasoner.github.io/eyeprolog/examples/deck/dining-philosophers) — Who eats when, and with which forks?
86
88
  - [DONALD + GERALD = ROBERT](https://eyereasoner.github.io/eyeprolog/examples/deck/donald-gerald-robert) — Which digit does each letter stand for?
@@ -0,0 +1,107 @@
1
+ # Dependency depth: 10,000 predicates
2
+
3
+ ## Can dependency analysis follow a deep chain without exhausting the JavaScript stack?
4
+
5
+ A dependency graph can be deep even when its clauses are simple. This
6
+ example has 10,000 distinct predicates and 9,999 edges in one chain.
7
+ Dependency analysis uses an explicit traversal stack, so the graph's depth
8
+ does not consume one JavaScript call frame per predicate.
9
+
10
+ [Run it in the playground](https://eyereasoner.github.io/eyeprolog/playground#example=dependency-depth-10000) ·
11
+ [Source](../dependency-depth-10000.pl) ·
12
+ [Answer](../output/dependency-depth-10000.pl) ·
13
+ [Proof](../proof/dependency-depth-10000.pl) ·
14
+ [Check](../check/dependency-depth-10000.pl)
15
+
16
+ ---
17
+
18
+ # The question
19
+
20
+ Can the engine prepare and analyze the whole chain, including propagation
21
+ of a cut from its final predicate back to every caller?
22
+ The declared query asks `chain9998(ready)` to keep the resulting proof small.
23
+
24
+ ---
25
+
26
+ # The rules
27
+
28
+ ```prolog
29
+ chain0(X) :- chain1(X).
30
+ chain1(X) :- chain2(X).
31
+ % ... one clause per predicate ...
32
+ chain9998(X) :- chain9999(X).
33
+ chain9999(ready) :- !.
34
+ ```
35
+
36
+ There are no cycles. Each predicate can reach the terminal cut, including
37
+ `chain0/1`, which is 9,999 edges away. The graph is also stratified: there is
38
+ no negative cycle.
39
+
40
+ ---
41
+
42
+ # The answer
43
+
44
+ Run from the repository root:
45
+
46
+ ```sh
47
+ node bin/eyeprolog.js examples/dependency-depth-10000.pl
48
+ ```
49
+
50
+ ```text
51
+ chain9998(ready).
52
+ ```
53
+
54
+ ---
55
+
56
+ # The reason
57
+
58
+ ```text
59
+ step(chain9998(ready), rule(9999), ['X' = ready], [chain9999(ready)]).
60
+ step(chain9999(ready), rule(10000), [], "!").
61
+ step(!, builtin, [], []).
62
+ ```
63
+
64
+ Two rule applications and the cut establish the answer. This short proof
65
+ keeps the example inexpensive to prove and check during `npm test`.
66
+
67
+ ---
68
+
69
+ # The check
70
+
71
+ ```sh
72
+ node bin/eyeprolog.js --check-proof examples/proof/dependency-depth-10000.pl examples/dependency-depth-10000.pl
73
+ ```
74
+
75
+ The packaged report records `steps(3)`, `verified(2)`, `recomputed(1)`,
76
+ `trusted(0)`, and `verdict(checked)`. It checks the query's derivation.
77
+ The white-box regression checks the complete dependency graph separately.
78
+
79
+ ---
80
+
81
+ # Analyze the full graph
82
+
83
+ Run this from the repository root with the ordinary Node stack setting:
84
+
85
+ ```sh
86
+ node --input-type=module <<'JS'
87
+ import assert from 'node:assert/strict';
88
+ import fs from 'node:fs';
89
+ import { Program } from './src/index.js';
90
+ const source = fs.readFileSync('examples/dependency-depth-10000.pl', 'utf8');
91
+ const program = Program.parse(source);
92
+ assert.equal(program.groups.size, 10000);
93
+ assert.equal(program.isStratifiedNegation(), true);
94
+ assert.equal(program.negationDependencies.length, 9999);
95
+ for (let i = 0; i < 10000; i++) {
96
+ const group = program.findGroup(`chain${i}`, 1);
97
+ assert.equal(group.recursive, false);
98
+ assert.equal(group.cutReachable, true);
99
+ }
100
+ console.log('10,000 predicates analyzed; terminal cut reaches every caller.');
101
+ JS
102
+ ```
103
+
104
+ This exercises preparation and negation analysis across the full depth.
105
+ The result establishes graph-analysis depth, rather than a bound on the
106
+ depth of arbitrary Prolog execution. For preparation timing, see
107
+ [the 5,000-predicate example](dependency-preparation-5000.md).
@@ -0,0 +1,106 @@
1
+ # Dependency preparation: 5,000 predicates
2
+
3
+ ## How quickly can the engine prepare thousands of distinct predicates?
4
+
5
+ Generated programs can contain thousands of predicate names. Before answering
6
+ any query, EyeProlog prepares their dependency graph and execution plans.
7
+ This example gives that work a reproducible input: 5,000 predicates connected
8
+ by 4,999 dependency edges.
9
+
10
+ [Run it in the playground](https://eyereasoner.github.io/eyeprolog/playground#example=dependency-preparation-5000) ·
11
+ [Source](../dependency-preparation-5000.pl) ·
12
+ [Answer](../output/dependency-preparation-5000.pl) ·
13
+ [Proof](../proof/dependency-preparation-5000.pl) ·
14
+ [Check](../check/dependency-preparation-5000.pl)
15
+
16
+ ---
17
+
18
+ # The question
19
+
20
+ How much preparation does a long chain of distinct predicates require?
21
+ The declared query asks only `chain4998(ready)`. Loading the source prepares
22
+ the entire graph; answering this query needs only its final edge.
23
+
24
+ ---
25
+
26
+ # The rules
27
+
28
+ ```prolog
29
+ chain0(X) :- chain1(X).
30
+ chain1(X) :- chain2(X).
31
+ % ... one clause per predicate ...
32
+ chain4998(X) :- chain4999(X).
33
+ chain4999(ready).
34
+ ```
35
+
36
+ Each name introduces a separate graph vertex. The engine identifies the
37
+ components once and propagates planning properties over the graph. None of
38
+ these predicates is recursive, and none reaches a cut.
39
+
40
+ ---
41
+
42
+ # The answer
43
+
44
+ Run from the repository root:
45
+
46
+ ```sh
47
+ node bin/eyeprolog.js examples/dependency-preparation-5000.pl
48
+ ```
49
+
50
+ ```text
51
+ chain4998(ready).
52
+ ```
53
+
54
+ ---
55
+
56
+ # The reason
57
+
58
+ ```text
59
+ step(chain4998(ready), rule(4999), ['X' = ready], [chain4999(ready)]).
60
+ step(chain4999(ready), fact(5000), [], []).
61
+ ```
62
+
63
+ The proof has two steps. Keeping the query short lets this example exercise
64
+ preparation without adding a 5,000-step proof to every test run.
65
+
66
+ ---
67
+
68
+ # The check
69
+
70
+ ```sh
71
+ node bin/eyeprolog.js --check-proof examples/proof/dependency-preparation-5000.pl examples/dependency-preparation-5000.pl
72
+ ```
73
+
74
+ The packaged report records `steps(2)`, `verified(2)`, `trusted(0)`, and
75
+ `verdict(checked)`. It checks the answer's two inferences. The white-box
76
+ regression separately checks all 5,000 predicate plans and all 4,999 graph
77
+ edges, including negation stratification.
78
+
79
+ ---
80
+
81
+ # Time preparation
82
+
83
+ Run this from the repository root. Source reading and module startup happen
84
+ outside the timed region. Three warm-ups precede nine measured parses;
85
+ the printed value is their median. Use the same Node version and machine
86
+ when comparing releases. Timing is an observation, not a test threshold.
87
+
88
+ ```sh
89
+ node --input-type=module <<'JS'
90
+ import fs from 'node:fs';
91
+ import { Program } from './src/index.js';
92
+ const source = fs.readFileSync('examples/dependency-preparation-5000.pl', 'utf8');
93
+ for (let i = 0; i < 3; i++) Program.parse(source);
94
+ const samples = [];
95
+ for (let i = 0; i < 9; i++) {
96
+ const start = performance.now();
97
+ const program = Program.parse(source);
98
+ samples.push(performance.now() - start);
99
+ if (program.groups.size !== 5000) throw new Error('wrong predicate count');
100
+ }
101
+ samples.sort((a, b) => a - b);
102
+ console.log(`Median preparation: ${samples[4].toFixed(1)} ms`);
103
+ JS
104
+ ```
105
+
106
+ Continue with [the 10,000-predicate depth example](dependency-depth-10000.md).