eyelang 1.5.0 → 1.5.2
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 +5 -4
- package/bin/eyelang +0 -0
- package/examples/derived-backward-rule.pl +27 -0
- package/examples/output/derived-backward-rule.pl +3 -0
- package/package.json +1 -1
- package/playground.html +1 -0
- package/src/cli.js +2 -2
- package/test/run-regression.js +24 -1
package/README.md
CHANGED
|
@@ -239,10 +239,10 @@ Predicate names and atom constants use the same lexical form. Namespace-like nam
|
|
|
239
239
|
|
|
240
240
|
The CLI is output-oriented and uses `materialize/2` to decide what to print. Embedders can still use the JavaScript API and `Solver` directly for arbitrary goals and arities.
|
|
241
241
|
|
|
242
|
-
Add `--stats` when you want lightweight solver counters on stderr without changing stdout:
|
|
242
|
+
Add `-s` or `--stats` when you want lightweight solver counters on stderr without changing stdout:
|
|
243
243
|
|
|
244
244
|
```sh
|
|
245
|
-
bin/eyelang
|
|
245
|
+
bin/eyelang -s examples/sudoku.pl
|
|
246
246
|
```
|
|
247
247
|
|
|
248
248
|
The playground has matching `--stats` and `--proof` checkboxes, so browser runs can show the same counters or explanations like the CLI.
|
|
@@ -362,6 +362,7 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
362
362
|
| [`delfour.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/delfour.pl) | Derives shopping and authorization recommendations. | [`output/delfour.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/delfour.pl) |
|
|
363
363
|
| [`dense-hamiltonian-cycle.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/dense-hamiltonian-cycle.pl) | Searches a dense Hamiltonian cycle with aggregate minimization. | [`output/dense-hamiltonian-cycle.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/dense-hamiltonian-cycle.pl) |
|
|
364
364
|
| [`deontic-logic.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/deontic-logic.pl) | Reports obligations, prohibitions, and violations. | [`output/deontic-logic.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/deontic-logic.pl) |
|
|
365
|
+
| [`derived-backward-rule.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/derived-backward-rule.pl) | Derives an inverse-property backward rule from rule data. | [`output/derived-backward-rule.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/derived-backward-rule.pl) |
|
|
365
366
|
| [`derived-rule.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/derived-rule.pl) | Derives conclusions from rule data. | [`output/derived-rule.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/derived-rule.pl) |
|
|
366
367
|
| [`diamond-property.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/diamond-property.pl) | Checks the diamond property of a relation. | [`output/diamond-property.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/diamond-property.pl) |
|
|
367
368
|
| [`dijkstra-findall-sort.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/dijkstra-findall-sort.pl) | Finds shortest paths using collected candidates. | [`output/dijkstra-findall-sort.pl`](https://github.com/eyereasoner/eyelang/blob/main/examples/output/dijkstra-findall-sort.pl) |
|
|
@@ -500,7 +501,7 @@ node bin/eyelang --help
|
|
|
500
501
|
Useful profiling smoke test:
|
|
501
502
|
|
|
502
503
|
```sh
|
|
503
|
-
bin/eyelang
|
|
504
|
+
bin/eyelang -s examples/sudoku.pl > /dev/null
|
|
504
505
|
```
|
|
505
506
|
|
|
506
507
|
For a release:
|
|
@@ -513,7 +514,7 @@ For a release:
|
|
|
513
514
|
|
|
514
515
|
## Performance notes
|
|
515
516
|
|
|
516
|
-
Use `--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.
|
|
517
|
+
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.
|
|
517
518
|
|
|
518
519
|
eyelang 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:
|
|
519
520
|
|
package/bin/eyelang
CHANGED
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
% Derived backward rule example adapted from Eyeling derived-backward-rule.n3.
|
|
2
|
+
%
|
|
3
|
+
% Eyeling source shape:
|
|
4
|
+
% parentOf invOf childOf.
|
|
5
|
+
% alice parentOf bob.
|
|
6
|
+
% { ?p invOf ?q. } => { { ?x ?q ?y. } <= { ?y ?p ?x. }. }.
|
|
7
|
+
% { ?x childOf ?y. } => { ?x hasParent ?y. }.
|
|
8
|
+
%
|
|
9
|
+
% The generated backward rule is represented as quoted formula data in
|
|
10
|
+
% log_impliedBy/2, then mirrored as an ordinary eyelang rule so the generated
|
|
11
|
+
% childOf relation can feed the ordinary hasParent rule.
|
|
12
|
+
|
|
13
|
+
materialize(log_impliedBy, 2).
|
|
14
|
+
materialize(childOf, 2).
|
|
15
|
+
materialize(hasParent, 2).
|
|
16
|
+
|
|
17
|
+
invOf(parentOf, childOf).
|
|
18
|
+
parentOf(alice, bob).
|
|
19
|
+
|
|
20
|
+
log_impliedBy(childOf(var(x), var(y)), parentOf(var(y), var(x))) :-
|
|
21
|
+
invOf(parentOf, childOf).
|
|
22
|
+
|
|
23
|
+
childOf(X, Y) :-
|
|
24
|
+
log_impliedBy(childOf(var(x), var(y)), parentOf(var(y), var(x))),
|
|
25
|
+
parentOf(Y, X).
|
|
26
|
+
|
|
27
|
+
hasParent(X, Y) :- childOf(X, Y).
|
package/package.json
CHANGED
package/playground.html
CHANGED
package/src/cli.js
CHANGED
|
@@ -34,7 +34,7 @@ export async function main(argv) {
|
|
|
34
34
|
return;
|
|
35
35
|
} else if (!endOptions && (arg === '--proof' || arg === '-p')) {
|
|
36
36
|
options.proof = true;
|
|
37
|
-
} else if (!endOptions && arg === '--stats') {
|
|
37
|
+
} else if (!endOptions && (arg === '--stats' || arg === '-s')) {
|
|
38
38
|
options.stats = true;
|
|
39
39
|
} else if (!endOptions && arg.startsWith('-') && arg !== '-') {
|
|
40
40
|
throw new Error(`unknown option: ${arg}`);
|
|
@@ -142,7 +142,7 @@ Input:
|
|
|
142
142
|
Options:
|
|
143
143
|
-h, --help Show this help text and exit.
|
|
144
144
|
-p, --proof Enable proof explanations.
|
|
145
|
-
|
|
145
|
+
-s, --stats Print solver statistics to stderr after execution.
|
|
146
146
|
-v, --version Show the package version and exit.
|
|
147
147
|
-- Stop option parsing; following arguments are treated as files.
|
|
148
148
|
`);
|
package/test/run-regression.js
CHANGED
|
@@ -171,7 +171,8 @@ why(
|
|
|
171
171
|
const result = runCli([]);
|
|
172
172
|
assertEqual(result.status, 0, 'exit status');
|
|
173
173
|
assertIncludes(result.stdout, 'Usage:\n eyelang [options] [file-or-url.pl|- ...]', 'stdout');
|
|
174
|
-
assertIncludes(result.stdout, '--proof', 'stdout');
|
|
174
|
+
assertIncludes(result.stdout, '-p, --proof', 'stdout');
|
|
175
|
+
assertIncludes(result.stdout, '-s, --stats', 'stdout');
|
|
175
176
|
assertEqual(result.stderr, '', 'stderr');
|
|
176
177
|
},
|
|
177
178
|
},
|
|
@@ -225,6 +226,28 @@ why(
|
|
|
225
226
|
},
|
|
226
227
|
|
|
227
228
|
|
|
229
|
+
{
|
|
230
|
+
name: '--stats prints solver statistics to stderr',
|
|
231
|
+
run: () => {
|
|
232
|
+
const result = runCli(['--stats', '-'], { input: 'p(a, b).\nq(X, Y) :- p(X, Y).\n' });
|
|
233
|
+
assertEqual(result.status, 0, 'exit status');
|
|
234
|
+
assertEqual(result.stdout, 'q(a, b).\n', 'stdout');
|
|
235
|
+
assertIncludes(result.stderr, 'eyelang stats:\n', 'stderr');
|
|
236
|
+
assertIncludes(result.stderr, ' solve_goals_calls:', 'stderr');
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: '-s prints solver statistics to stderr',
|
|
241
|
+
run: () => {
|
|
242
|
+
const result = runCli(['-s', '-'], { input: 'p(a, b).\nq(X, Y) :- p(X, Y).\n' });
|
|
243
|
+
assertEqual(result.status, 0, 'exit status');
|
|
244
|
+
assertEqual(result.stdout, 'q(a, b).\n', 'stdout');
|
|
245
|
+
assertIncludes(result.stderr, 'eyelang stats:\n', 'stderr');
|
|
246
|
+
assertIncludes(result.stderr, ' solve_goals_calls:', 'stderr');
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
|
|
228
251
|
{
|
|
229
252
|
name: 'double dash permits option-shaped file names',
|
|
230
253
|
run: () => {
|