eyelang 0.1.6 → 0.1.8
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 +19 -5
- package/docs/guide.md +30 -9
- package/examples/collatz-1000.pl +45 -0
- package/examples/output/collatz-1000.pl +1000 -0
- package/package.json +1 -1
- package/test/run-regression.mjs +54 -3
package/README.md
CHANGED
|
@@ -9,12 +9,26 @@ It grew out of logic-language experiments in the EYE/N3 reasoning tradition, but
|
|
|
9
9
|
|
|
10
10
|
## Install and run
|
|
11
11
|
|
|
12
|
+
Eyelang has no runtime npm dependencies and no build step. From a source checkout, run the CLI directly with Node.js 18 or newer:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
node bin/eyelang.js examples/ancestor.pl
|
|
16
|
+
node bin/eyelang.js --proof examples/socrates.pl
|
|
17
|
+
printf 'works(stdin, true) :- eq(ok, ok).\n' | node bin/eyelang.js -
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For one-off local CLI use from the checkout, npm can run the package bin without a manual symlink:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm exec -- eyelang --version
|
|
24
|
+
npm exec -- eyelang examples/ancestor.pl
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To install the checkout's `eyelang` command on your `PATH`, use npm's package link:
|
|
28
|
+
|
|
12
29
|
```bash
|
|
13
|
-
npm
|
|
14
|
-
eyelang
|
|
15
|
-
eyelang --proof examples/socrates.pl
|
|
16
|
-
printf 'works(stdin, true) :- eq(ok, ok).
|
|
17
|
-
' | eyelang -
|
|
30
|
+
npm link
|
|
31
|
+
eyelang --version
|
|
18
32
|
```
|
|
19
33
|
|
|
20
34
|
## JavaScript API
|
package/docs/guide.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Eyelang Guide
|
|
2
2
|
|
|
3
|
-
This guide introduces Eyelang, a small Horn-clause language and engine whose source syntax is a deliberate subset of ordinary Prolog syntax for rules, goals, answers, and proofs. Eyelang works over ordinary terms, lists, arithmetic, strings, and finite search. Run it with the `eyelang` CLI, or use `node
|
|
3
|
+
This guide introduces Eyelang, a small Horn-clause language and engine whose source syntax is a deliberate subset of ordinary Prolog syntax for rules, goals, answers, and proofs. Eyelang works over ordinary terms, lists, arithmetic, strings, and finite search. Run it with the `eyelang` CLI, or use `node bin/eyelang.js` when working directly from a source checkout.
|
|
4
4
|
|
|
5
5
|
Programs write relations directly, for example `ancestor(pat, emma)` or `status(case1, accepted)`. Eyelang output is ordinary Eyelang 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(Name, Arity).` declarations to focus output on selected predicates.
|
|
6
6
|
|
|
@@ -24,25 +24,35 @@ For the normative language definition, including lexical syntax, terms, clauses,
|
|
|
24
24
|
|
|
25
25
|
## Quick start
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Eyelang has no runtime npm dependencies and no build step. From a source checkout, run the CLI entry point directly with Node.js 18 or newer:
|
|
28
28
|
|
|
29
29
|
```sh
|
|
30
|
-
|
|
30
|
+
node bin/eyelang.js --version
|
|
31
|
+
node bin/eyelang.js examples/ancestor.pl
|
|
32
|
+
node bin/eyelang.js facts.pl rules.pl
|
|
33
|
+
printf 'works(stdin, true) :- eq(ok, ok).\n' | node bin/eyelang.js -
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
You can also use npm's local package-bin runner from the checkout:
|
|
34
37
|
|
|
35
38
|
```sh
|
|
39
|
+
npm exec -- eyelang --version
|
|
40
|
+
npm exec -- eyelang examples/ancestor.pl
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
To make the `eyelang` command available on your `PATH` while developing this checkout, prefer npm's package link instead of a manual symlink:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npm link
|
|
36
47
|
eyelang --version
|
|
37
|
-
eyelang examples/ancestor.pl
|
|
38
|
-
eyelang facts.pl rules.pl
|
|
39
|
-
printf 'works(stdin, true) :- eq(ok, ok).\n' | eyelang -
|
|
40
48
|
```
|
|
41
49
|
|
|
42
|
-
|
|
50
|
+
`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.
|
|
43
51
|
|
|
44
52
|
## Running eyelang
|
|
45
53
|
|
|
54
|
+
The commands in this section use `eyelang` for readability. In a source checkout where you have not run `npm link` or `npm install -g .`, replace `eyelang` with `node bin/eyelang.js`, or run the command through `npm exec -- eyelang`.
|
|
55
|
+
|
|
46
56
|
Show the package version:
|
|
47
57
|
|
|
48
58
|
```sh
|
|
@@ -319,6 +329,7 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
319
329
|
| [`canary-release.pl`](../examples/canary-release.pl) | Decides canary rollout or rollback. | [`output/canary-release.pl`](../examples/output/canary-release.pl) |
|
|
320
330
|
| [`cat-koko.pl`](../examples/cat-koko.pl) | Demonstrates named existential witnesses from a Cat Koko rule pattern. | [`output/cat-koko.pl`](../examples/output/cat-koko.pl) |
|
|
321
331
|
| [`clinical-trial-screening.pl`](../examples/clinical-trial-screening.pl) | Screens candidates for a trial. | [`output/clinical-trial-screening.pl`](../examples/output/clinical-trial-screening.pl) |
|
|
332
|
+
| [`collatz-1000.pl`](../examples/collatz-1000.pl) | Materializes Collatz trajectories for starts 1000 down to 1. | [`output/collatz-1000.pl`](../examples/output/collatz-1000.pl) |
|
|
322
333
|
| [`combinatorics-findall-sort.pl`](../examples/combinatorics-findall-sort.pl) | Collects and sorts finite combinations. | [`output/combinatorics-findall-sort.pl`](../examples/output/combinatorics-findall-sort.pl) |
|
|
323
334
|
| [`competitive-enzyme-kinetics.pl`](../examples/competitive-enzyme-kinetics.pl) | Computes inhibited enzyme reaction rates. | [`output/competitive-enzyme-kinetics.pl`](../examples/output/competitive-enzyme-kinetics.pl) |
|
|
324
335
|
| [`complex.pl`](../examples/complex.pl) | Performs arithmetic on complex pairs. | [`output/complex.pl`](../examples/output/complex.pl) |
|
|
@@ -504,7 +515,17 @@ A useful rule of thumb:
|
|
|
504
515
|
| Human-auditable derivations | Either | Both can emit proof explanations when requested. |
|
|
505
516
|
| Large generated Horn-clause workloads | eyelang | The engine specializes in predicate/arity indexing, scalar argument indexes, fast fact paths, and materialized output goals. |
|
|
506
517
|
|
|
507
|
-
|
|
518
|
+
On local smoke benchmarks, eyelang 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`, eyelang from this checkout, and Eyeling package version `1.34.6` with its default output mode. The ratio is `Eyeling median / eyelang median`, so larger numbers mean eyelang was faster.
|
|
519
|
+
|
|
520
|
+
| Example | eyelang median | Eyeling median | Ratio |
|
|
521
|
+
| --- | ---: | ---: | ---: |
|
|
522
|
+
| `fundamental-theorem-arithmetic` | `0.16 sec` | `2.00 sec` | `12.66x` |
|
|
523
|
+
| `deep-taxonomy-100000` | `1.69 sec` | `4.72 sec` | `2.79x` |
|
|
524
|
+
| `path-discovery` | `0.53 sec` | `1.62 sec` | `3.07x` |
|
|
525
|
+
| `fibonacci` | `0.15 sec` | `5.76 sec` | `38.40x` |
|
|
526
|
+
| `collatz-1000` | `0.71 sec` | `6.99 sec` | `9.85x` |
|
|
527
|
+
|
|
528
|
+
Treat these as smoke comparisons rather than a formal benchmark: hardware, Node.js version, package version, CLI startup, and output mode all matter.
|
|
508
529
|
|
|
509
530
|
The projects are therefore complementary rather than replacements for each other: Eyeling optimizes for Semantic Web interoperability and N3 expressiveness; eyelang optimizes for a small standard-looking relational rule language and fast finite goal-directed execution.
|
|
510
531
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
% Collatz conjecture suite translated from Eyeling's examples/collatz-1000.n3.
|
|
2
|
+
% It enumerates starts N = 1000, 999, ..., 1 by deriving N = 1000 - N0
|
|
3
|
+
% from a repeat relation, then materializes each full trajectory.
|
|
4
|
+
%
|
|
5
|
+
% Source N3:
|
|
6
|
+
% https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/collatz-1000.n3
|
|
7
|
+
|
|
8
|
+
% Output declarations: materialize/2 selects the relations written to this example's golden output.
|
|
9
|
+
% memoize/2 caches shared suffix trajectories so the 1000 starts do not recompute
|
|
10
|
+
% the same Collatz tails hundreds of times.
|
|
11
|
+
materialize(collatzTrajectory, 2).
|
|
12
|
+
memoize(collatz, 2).
|
|
13
|
+
|
|
14
|
+
% Program structure: facts set up the scenario, and rules derive the materialized conclusions.
|
|
15
|
+
% The N3 source defines repeat/2 recursively; this Eyelang version uses the
|
|
16
|
+
% equivalent bounded generator so the 1000-case regression remains stack-safe.
|
|
17
|
+
|
|
18
|
+
% Query / materialization of the test suite.
|
|
19
|
+
% Generate N in {1000..1} and ask the backward-defined collatz/2 predicate
|
|
20
|
+
% for the full trajectory list M.
|
|
21
|
+
collatzTrajectory(N, M) :-
|
|
22
|
+
repeat(1000, N0),
|
|
23
|
+
sub(1000, N0, N),
|
|
24
|
+
collatz(N, M).
|
|
25
|
+
|
|
26
|
+
% Range generator.
|
|
27
|
+
% repeat(N, I) enumerates all integers I in the half-open interval [0..N-1].
|
|
28
|
+
repeat(N, I) :-
|
|
29
|
+
sub(N, 1, Last),
|
|
30
|
+
between(0, Last, I).
|
|
31
|
+
|
|
32
|
+
% Backward Collatz relation.
|
|
33
|
+
% collatz(N, M) relates a start value N to its full trajectory list M.
|
|
34
|
+
collatz(1, [1]).
|
|
35
|
+
collatz(N, [N|J]) :-
|
|
36
|
+
gt(N, 1),
|
|
37
|
+
mod(N, 2, 0),
|
|
38
|
+
div(N, 2, N1),
|
|
39
|
+
collatz(N1, J).
|
|
40
|
+
collatz(N, [N|J]) :-
|
|
41
|
+
gt(N, 1),
|
|
42
|
+
mod(N, 2, 1),
|
|
43
|
+
mul(3, N, T),
|
|
44
|
+
add(T, 1, N1),
|
|
45
|
+
collatz(N1, J).
|