A Notation3 (N3) reasoner in JavaScript.
eyeling is:
eyeling.js, no external deps)=>) + backward (<=) chaining over Horn-style rulesreasonStream)Try it here:
#...).BigInt support is fine)npm i eyeling
Run on a file:
npx eyeling examples/socrates.n3
(Or install globally: npm i -g eyeling and run eyeling ....)
const { reason } = require("eyeling");
const input = `
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix : <http://example.org/socrates#>.
:Socrates a :Human.
:Human rdfs:subClassOf :Mortal.
{ ?S a ?A. ?A rdfs:subClassOf ?B } => { ?S a ?B }.
`;
const output = reason({ proofComments: false }, input);
console.log(output);
ESM:
import eyeling from "eyeling";
const output = eyeling.reason({ proofComments: false }, input);
console.log(output);
Streaming (browser/worker, direct eyeling.js):
const { closureN3 } = eyeling.reasonStream(input, {
proof: false,
onDerived: ({ triple }) => console.log(triple),
});
Note: the API currently shells out to the bundled eyeling.js CLI under the hood (simple + robust).
From a repo checkout:
npm test
Or run individual suites:
npm run test:api
npm run test:examples
npm run test:package
npm run test:packlist
test:api runs an independent JS API test suite (does not rely on examples/).test:examples runs the examples in the examples directory and compares against the golden outputs in examples/output.test:package does a “real consumer” smoke test: npm pack → install tarball into a temp project → run API + CLI + examples.test:packlist sanity-checks what will be published in the npm tarball (and the CLI shebang/bin wiring).Usage: eyeling [options] <file.n3>
Options:
-a, --ast Print parsed AST as JSON and exit.
-e, --enforce-https Rewrite http:// IRIs to https:// for log dereferencing builtins.
-h, --help Show this help and exit.
-p, --proof-comments Enable proof explanations.
-r, --strings Print log:outputString strings (ordered by key) instead of N3 output.
-s, --super-restricted Disable all builtins except => and <=.
-t, --stream Stream derived triples as soon as they are derived.
-v, --version Print version and exit.
By default, eyeling:
# comments (can be disabled)For each newly derived triple, eyeling prints:
The proof comments are compact “local justifications” per derived triple (not a single exported global proof tree).
{ P } => { C } .{ H } <= { B } . and for built-ins.Forward rule premises are proved using:
The CLI prints only newly derived forward facts.
eyeling includes a few key performance mechanisms:
eyeling follows the usual N3 intuition:
_:b1, _:b2, … within a run)_:sk_0, _:sk_1, …)Equal facts up to renaming of Skolem IDs are treated as duplicates and are not re-added.
eyeling understands the log:implies / log:impliedBy idiom.
Top level:
{ P } log:implies { C } . becomes a forward rule { P } => { C } .{ H } log:impliedBy { B } . becomes a backward rule { H } <= { B } .During reasoning:
log:implies / log:impliedBy triple with formula subject/object is turned into a new live forward/backward rule.Rules whose conclusion is false are treated as hard failures:
:stone :color :black .
:stone :color :white .
{ ?X :color :black . ?X :color :white . } => false.
As soon as the premise is provable, eyeling exits with status code 2.
eyeling’s parser targets (nearly) the full Notation3 Language grammar from the W3C N3 Community Group spec.
In practice this means: it’s a Turtle superset that also accepts quoted formulas, rules, paths, and the N3 “syntax shorthand”
operators (=, =>, <=) described in the spec.
Commonly used N3/Turtle features:
@prefix / @base, and SPARQL-style PREFIX / BASE); and ,?x)[], and [ :p :o; :q :r ])( ... ){ ... }=>, <=)^^) and language tags ("..."@en)<- and keyword forms like is ... of)! and ^)# line commentseyeling implements the builtins described in eyeling-builtins.
MIT (see LICENSE).