EyeDual combines ISO Prolog and W3C RDF 1.2 to turn portable rules and linked data into answers and inspectable proofs.
Playground · The Art of EyeDual
Install the published CLI globally:
npm install --global eyedual
eyedual --version
printf 'works(stdin, true) :- ok = ok.\n' | eyedual --goal 'works(stdin, true)' -
EyeDual has no build step. From a source checkout, install its RDF parser dependencies and run the CLI directly with Node.js 18 or newer:
npm install
node bin/eyedual.js examples/ancestor.pl
node bin/eyedual.js --proof examples/socrates.pl
node bin/eyedual.js --warnings test/conformance/warnings/negation/unstratified_mutual.pl
printf 'works(stdin, true) :- ok = ok.\n' | node bin/eyedual.js --goal 'works(stdin, true)' -
Most checked examples contain an ISO-safe host comment such as
%% goal: enigma1225(8, _). When no --goal option is supplied, the CLI runs
those commented goals in source order. An explicit --goal always overrides
the comments, so scripts can select a different query without editing the
program.
For one-off local CLI use from the checkout, npm can run the package bin without a manual symlink:
npm exec --yes --package=. -- eyedual --version
npm exec --yes --package=. -- eyedual examples/ancestor.pl
To install the checkout’s eyedual command on your PATH, use npm’s package link:
npm link
eyedual --version
For local browser use, run python3 -m http.server from the checkout and open
http://localhost:8000/playground.html. Do not open playground.html directly as a
file: URL: module workers require HTTP(S). Each run uses the dedicated
src/playground-worker.js module, which creates the same EyeDual library registry used by the CLI and JavaScript API. Predicates such as append/3 and
member/2 therefore work without a browser option. The playground supports the
in-memory reasoner; filesystem predicates and include/1 remain Node-only.
After replacing playground files in an already-open tab, perform one hard refresh
to terminate the previous worker and discard its cached module graph.
The example corpus now contains 200 runnable examples. Three useful search
stress cases exercise the EyeDual library, which is loaded by
default in the CLI, JavaScript API, and browser playground. Their exact checked
answers live beside the other goldens under examples/output/:
node bin/eyedual.js examples/lee.pl
node bin/eyedual.js examples/n-queens.pl
node bin/eyedual.js examples/donald-gerald-robert.pl
lee.pl performs Lee wavefront routing around rectangular
obstacles and reconstructs one path (golden).
n-queens.pl uses selection and diagonal pruning to
enumerate all 92 solutions of the eight-queen puzzle
(golden). The milestone 200th example,
donald-gerald-robert.pl, solves a
pandigital cryptarithm whose naive search space is 10!, or 3,628,800 digit
assignments. Carry propagation and a shrinking digit domain reduce it to one
checked solution (golden).
import { run, Program, Solver } from 'eyedual';
const result = run(`
% Run with: eyedual --goal 'answer(X0)' program.pl
answer(ok) :- ok = ok.
`);
console.log(result.stdout);
run returns captured stdout, numeric solver stats, and a nullable
haltCode when halt/0 or halt/1 terminates the processor.
The default runtime includes EyeDual’s ISO/IEC 13211-1:1995 core profile plus
49 EyeDual library predicates implemented in src/library.js, covering strings,
lists, aggregation, dates, and arithmetic. The ISO profile itself has
115 registered predicate indicators across 94 names.
This is broad standards coverage, not a formal certification claim. EyeDual
retains documented host conventions—most visibly host-supplied goals, automatic tabling,
explicit integrity checks, and a distinct double-quoted string scalar—and exhaustive
standard error/option combinations remain part of the conformance work.
Library predicates such as append/3, member/2, and select/3 are available
without a CLI flag or JavaScript registry option.
Advanced embedders and the ISO conformance suite can still select the isolated
core registry explicitly with createDefaultRegistry() or
getDefaultRegistry(). createEyeDualRegistry() creates the complete 164-entry
registry: 115 ISO indicators and 49 EyeDual library indicators. Normal applications can rely on the default and do not need to
install either explicitly.
ISO streams are solver-owned and shared by nested goals. JavaScript callers can provide standard input and capture standard output:
const result = run(source, {
ioOptions: {
input: "term(from_input).\n",
write: (text) => process.stdout.write(text),
},
});
false/0 is the ISO built-in predicate that always fails. It is a protected
static procedure: source clauses headed by false and declarations that make
false/0 dynamic raise permission_error(modify, static_procedure). Model
domain integrity conditions as ordinary predicates such as invalid_state/2,
and have the host query them explicitly before trusting downstream decisions.
The spacecraft battery example combines sensor telemetry, the physical relation
P = I²R, engineering limits, redundant measurements, and causal rules to
derive a diagnosis and safety action:
node bin/eyedual.js examples/spacecraft-battery-diagnosis.pl
node bin/eyedual.js -p examples/spacecraft-battery-diagnosis.pl
The normal output reports computed metrics, a thermal-runaway precursor, and an
isolate_and_cool action. With -p, every conclusion carries machine-readable
evidence back to telemetry facts, arithmetic operations, threshold comparisons,
and the independent temperature channel.
The name EyeDual reflects the two standards at its foundation: ISO Prolog for executable rules and W3C RDF for linked data.
Its default execution is automatically hybrid: ordinary goals use indexed depth-first resolution, while recursive helper predicate groups are detected and tabled automatically.
Clause selection combines compact type-aware any-argument scalar indexes with demand-driven multi-argument indexes. SWI-Prolog-inspired quality checks avoid building indexes for small, weakly selective, or variable-heavy clause groups.
The runtime boundary is intentionally visible in the source tree:
src/iso.js contains the isolated ISO processor registry, while
src/library.js composes that core with host conveniences and
the small profile-guided accelerator set. The complete EyeDual library is implemented directly in the browser-safe
src/library.js, and the
playground executes requests through the dedicated
src/playground-worker.js. Normal CLI, API, solver,
proof, and playground execution uses the default EyeDual registry; advanced
embedders can still request the ISO-only registry. Every path uses the same
parser, terms, solver, streams, and proof machinery.
The tools convert standard RDF files to ordinary EyeDual rdf/4 facts, run
EyeDual rules, and serialize query answers as RDF 1.2 N-Quads:
node tools/rdf-to-eyedual.mjs --rules rules.pl data.ttl -o program.pl
node bin/eyedual.js program.pl > derived.pl
node tools/eyedual-to-rdf.mjs derived.pl -o derived.nq
The input format is detected from the filename. Supported inputs include RDF
1.2 Turtle, TriG, N-Triples, N-Quads and RDF/XML, as well as JSON-LD, RDFa,
Microdata, Notation3 and SHACL Compact Syntax. For stdin, provide the format;
use --base when relative IRIs need an explicit base:
node tools/rdf-to-eyedual.mjs --format turtle --base https://example/ -
RDF IRIs, scoped blank nodes, literals, directional language strings, nested
triple terms, named graphs and the default graph all have lossless EyeDual term
encodings. The
RDF 1.2 chapter
in The Art of EyeDual covers the mapping and --include-source behavior.
Every release must pass the complete test suite. The current 684-file conformance corpus includes 279 focused ISO cases covering the success, failure, mode, and error behavior derived from ISO/IEC 13211-1 clauses 7 and
conformance-report.md is the authoritative source for
current category totals.
The example runner compares 200 answer goldens and 55 proof goldens
byte-for-byte; the extracted-book runner keeps executable displays synchronized with the book. The
dedicated seven-case playground suite executes the exact production module-worker
request path, checks that the EyeDual library is present across repeated browser
runs, verifies serializable success and parse-error messages, and crawls the served
ES-module graph for missing assets, incorrect MIME types, and static Node-only
imports.npm test
npm run test:conformance
node test/run-conformance-report.mjs
# release preparation writes conformance-report.md via the preversion script
npm run test:examples
npm run test:regression
npm run test:playground