eyelang 0.1.5 → 0.1.7
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 +22 -13
- package/docs/language-reference.md +1 -3
- package/examples/collatz-1000.pl +45 -0
- package/examples/output/collatz-1000.pl +1000 -0
- package/index.d.ts +167 -29
- package/package.json +1 -1
- package/test/run-regression.mjs +219 -38
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
|
|
@@ -238,7 +248,7 @@ The playground has matching `--stats` and `--proof` checkboxes, so browser runs
|
|
|
238
248
|
|
|
239
249
|
### Builtins
|
|
240
250
|
|
|
241
|
-
Eyelang builtins are registered by name and arity in small modules under [`src/builtins`](../src/builtins). This keeps the runtime portable to Node.js and the browser while giving each builtin family a clear boundary. Built-ins are called as ordinary Eyelang predicates. See the [Eyelang language reference](
|
|
251
|
+
Eyelang builtins are registered by name and arity in small modules under [`src/builtins`](../src/builtins). This keeps the runtime portable to Node.js and the browser while giving each builtin family a clear boundary. Built-ins are called as ordinary Eyelang predicates. See the [Eyelang language reference](language-reference.md#9-standard-built-in-predicates) for the portable profile. The bundled implementation currently registers 80 name/arity entries across 78 predicate names:
|
|
242
252
|
|
|
243
253
|
| Family | Count | Built-ins |
|
|
244
254
|
|---|---:|---|
|
|
@@ -289,8 +299,6 @@ Use `holds/2` when you want to match the member term directly, for example `name
|
|
|
289
299
|
|
|
290
300
|
`matches/3` can create context data from named regular-expression captures, which is useful when text logs or messages need to become facts before later rules inspect them with `holds/2` or `holds/3`. See [`observability-log-correlation.pl`](../examples/observability-log-correlation.pl) for a complete log-correlation example.
|
|
291
301
|
|
|
292
|
-
The N3 counterpart of the context schema audit lives at [`examples/context-schema-audit.n3`](../examples/context-schema-audit.n3) with golden output in [`examples/output/context-schema-audit.md`](../examples/output/context-schema-audit.md).
|
|
293
|
-
|
|
294
302
|
|
|
295
303
|
## Example catalog
|
|
296
304
|
|
|
@@ -321,6 +329,7 @@ The repository includes examples for recursion, graph reachability, finite searc
|
|
|
321
329
|
| [`canary-release.pl`](../examples/canary-release.pl) | Decides canary rollout or rollback. | [`output/canary-release.pl`](../examples/output/canary-release.pl) |
|
|
322
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) |
|
|
323
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) |
|
|
324
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) |
|
|
325
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) |
|
|
326
335
|
| [`complex.pl`](../examples/complex.pl) | Performs arithmetic on complex pairs. | [`output/complex.pl`](../examples/output/complex.pl) |
|
|
@@ -467,8 +476,8 @@ The conformance suite lives in [`test/conformance/`](../test/conformance/) as on
|
|
|
467
476
|
Common commands:
|
|
468
477
|
|
|
469
478
|
```sh
|
|
470
|
-
npm run test:eyelang #
|
|
471
|
-
npm
|
|
479
|
+
npm run test:eyelang # alias for npm test
|
|
480
|
+
npm test # full conformance, regression/API/white-box, examples, and proof examples
|
|
472
481
|
node test/run-conformance.mjs
|
|
473
482
|
node test/run-regression.mjs
|
|
474
483
|
node test/run-examples.mjs
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
- [9.6 Strings and atom constants](#96-strings-and-atom-constants)
|
|
40
40
|
- [9.7 Lists](#97-lists)
|
|
41
41
|
- [9.8 Aggregation and ordering](#98-aggregation-and-ordering)
|
|
42
|
-
- [9.9 Context
|
|
42
|
+
- [9.9 Context and term inspection](#99-context-and-term-inspection)
|
|
43
43
|
- [9.10 Search control](#910-search-control)
|
|
44
44
|
- [10. Implementation-specific built-ins](#10-implementation-specific-built-ins)
|
|
45
45
|
- [11. Declarations](#11-declarations)
|
|
@@ -475,8 +475,6 @@ The first goal can yield `holds((name(alice, "Alice"), knows(alice, bob)), name(
|
|
|
475
475
|
|
|
476
476
|
`holds/3` is the appropriate form for schema-style introspection because it exposes the predicate name and all arguments without assuming a fixed arity. For example, a single rule can inspect `heartbeat`, `source(sensor17)`, `temperature(sensor17, 38)`, and `signature(sensor17, sha256, Hash, Time)` as `heartbeat/0`, `source/1`, `temperature/2`, and `signature/4`; see [`context-schema-audit.pl`](../examples/context-schema-audit.pl).
|
|
477
477
|
|
|
478
|
-
The N3 example [`context-schema-audit.n3`](../examples/context-schema-audit.n3) shows the same idea in quoted graph form: members are encoded as predicates with RDF-list argument objects, then `log:includes` and `list:length` expose `Name + Arity` for schema checking.
|
|
479
|
-
|
|
480
478
|
### 9.10 Search control
|
|
481
479
|
|
|
482
480
|
| Built-in | Meaning |
|
|
@@ -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).
|