Skip to content

Repository files navigation

Eyeleng

Eyeleng is a JavaScript implementation of SPARQL 1.2 RL (SRL), following the W3C Recommendation-track specification at https://www.w3.org/TR/sparql-rl/.

Status: SPARQL 1.2 RL is currently a W3C Working Draft. Eyeleng tracks the current specification and may change as the specification advances.

Features

  • SPARQL 1.2 RL rule sets using .srl and media type application/sparql-rl.
  • srl: namespace http://www.w3.org/ns/sparql-rl#.
  • RDF 1.2 data input through rdf-parse 5.x.
  • Open/closed dependency analysis and stratification.
  • Run-once handling for rules containing SET or blank nodes in the head.
  • Local rule-set imports through IMPORTS.
  • Forward and hybrid evaluation.
  • CLI, JavaScript API, browser bundle, examples, and W3C conformance harness.

Graph model

Eyeleng distinguishes the two graphs used by SPARQL 1.2 RL:

  • base graph — external RDF supplied by the caller, for example with --data; WHERE DATA and NOT DATA match this graph only;
  • inference graph — starts with triples from SRL DATA { ... } blocks and grows with rule conclusions.

Normal rule bodies participate in rule evaluation over the available data, while ground-data clauses remain pinned to the base graph.

FOR clause

Eyeleng recognizes the current FOR ?var IN iri grammar production. Because the current abstract syntax and evaluation model do not define execution semantics for it, a rule using FOR produces a well-formedness/evaluation diagnostic rather than non-standard behavior.

Install and build

npm install
npm run build
npm test

The build produces the standalone CLI (eyeleng.js) and browser bundle.

CLI

Run a rule set containing its own DATA facts:

node eyeleng.js examples/family.srl

Use an RDF 1.2 document as the immutable base graph:

node eyeleng.js --data facts.ttl rules.srl

--data may be repeated. rdf-parse determines the RDF concrete syntax from the filename/content type and parses it in RDF 1.2 mode.

Important options:

--data FILE             Add an RDF 1.2 document to the immutable base graph (repeatable)
--all                   Print base graph plus inference graph
--json                  Print JSON instead of compact triples/bindings
--prove                 Print proof explanations
--stats                 Print iteration and triple counts to stderr
--check                 Parse, check well-formedness, and stratify only
--strict                Treat warnings as errors
--deps                  Print open/closed rule dependencies during --check
--query TEXT            Run a raw SRL body pattern
--query-file FILE       Read a raw SRL body pattern from a file
--query-mode MODE       Use auto, forward, or backward query planning (default auto)
--hybrid                Opt into Eyeleng's hybrid forward/backward optimization
--max-iterations N      Stop after N fixpoint iterations within a stratum
--no-imports            Reject rule sets containing IMPORTS
--rdf-messages          Treat --data input as an RDF Message Log
--include-message-facts Include payload facts while parsing RDF Message Logs
--version               Print version

Run node eyeleng.js --help for the complete list.

JavaScript API

SRL parsing and evaluation are synchronous when all data is embedded in the rule set:

const { run } = require('./src/index.js');

const result = run(`
PREFIX : <http://example/>
DATA { :alice :parentOf :bob . }
RULE { ?y :childOf ?x } WHERE { ?x :parentOf ?y }
`);

console.log(result.inferred);

For an external RDF base graph, parse RDF asynchronously through rdf-parse and pass the resulting triples to the rule engine:

const fs = require('node:fs');
const {
  parseRdfDocument,
  runAsync,
} = require('./src/index.js');

const rdfSource = fs.readFileSync('facts.ttl', 'utf8');
const { triples } = await parseRdfDocument(rdfSource, {
  filename: 'facts.ttl',
  baseIRI: 'file:///absolute/path/facts.ttl',
});

const rules = fs.readFileSync('rules.srl', 'utf8');
const result = await runAsync(rules, { baseGraph: triples });
console.log(result.inferred);

Imports

IMPORTS incorporates SPARQL-RL rule sets. The embedding application may provide an import resolver; the CLI resolves local file: imports.

RDF data is supplied separately as the base graph with --data or baseGraph. Unsupported, unresolved, or non-SRL imports are rejected.

RDF Message Logs

RDF Message Logs are supported as an ancillary base-data input:

node eyeleng.js --data examples/rdf-messages.trig examples/rdf-messages.srl

Use --rdf-messages to force message-log interpretation when no version announcement is present. --include-message-facts also exposes payload facts while parsing the log.

Message logs are data inputs, not importable rule sets.

Conformance tests

Run the SPARQL 1.2 RL W3C test harness with:

npm run w3c:sparql-rl
npm run w3c:sparql-rl:json
npm run w3c:sparql-rl:earl

The harness covers syntax, well-formedness, stratification, and evaluation tests from the W3C SPARQL-RL test suite.

Project layout

src/parser.js              SPARQL 1.2 RL concrete syntax
src/analyze.js             well-formedness, open/closed dependencies, stratification
src/assignments.js         run-once classification
src/engine.js              forward/hybrid evaluation and graph separation
src/rdf.js                 RDF 1.2 -> internal terms via rdf-parse
src/api.js                 public API, imports, RDF Message Log support
src/sparqlRlManifest.js    W3C SPARQL-RL test harness
src/cli.js                 command-line interface
examples/*.srl             executable SPARQL 1.2 RL examples
test/                      local tests plus W3C harness entry point

Architecture

Eyeleng owns rule-language parsing, well-formedness checks, dependency and stratification analysis, and evaluation. RDF 1.2 document parsing is delegated to rdf-parse and converted from RDF/JS terms in src/rdf.js.

About

EYE Logic Engine Next Generation - a JavaScript implementation of SPARQL 1.2 RL (SRL).

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages