eyeron

Working on eyeron

eyeron is a Rust reasoner for Notation3 (N3). It derives conclusions from facts and rules, writes N3 proofs, and checks those proofs; it runs as a command-line program, a Rust library, and a browser application. It is an N3 reasoner only. Describe what it implements as it currently is, distinguish demonstrated behavior from design goals, and keep error messages specific and user-facing text direct.

Repository map

Commands

cargo build --release
./target/release/eyeron examples/socrates.n3
./target/release/eyeron -p examples/socrates.n3      # proof
./target/release/eyeron -c examples/dog-license.n3   # prove and check
./target/release/eyeron --check-proof proof.n3 program.n3
./target/release/eyeron -a examples/socrates.n3      # parsed AST
cargo test --release --test regressions
cargo test --release --test examples
./scripts/test-all
cargo clippy --release --all-targets
cargo playground
git diff --check

./scripts/test-all uses the optimized test-fast profile, enables incremental builds, and checks two example proofs concurrently (EYERON_TEST_JOBS overrides the worker count). It runs every suite with --no-fail-fast and ends with one line, Tests: N run; P% OK; Ts total, naming any suite that ended without a result. cargo playground needs wasm-pack. cargo deny check needs a one-time cargo install --locked cargo-deny; CI runs it on every push. EYERON_W3C_RDF_REFRESH=1 refreshes the local W3C mirror; the suite is local-only otherwise.

Large examples such as deep-taxonomy-100000 and kaprekar-6174 produce very large proofs. Redirect full output to a temporary file and inspect focused parts rather than flooding the terminal.

Language and examples

Implementation and verification

Match the surrounding Rust: its naming, comment density, and doc comments that say why. Prefer small, direct changes over new machinery, and fix the code that produces a wrong result rather than patching its output.

Proof checking must stay sound: a forged proof must never report checked. The conditions C1–C9 are defined in SPEC.md Section 9; proof checking does not require compatibility with sibling engines. Matching against a recorded step is one-way, so only the rule’s variables bind. An existential witness must be a fresh blank node tied to one firing, and its introduction assumes no fact already satisfied its piece: an unsatisfied obligation that evidence independent of the firing contradicts (C6). Built-ins are re-decided with closed arguments, including tests on quoted graphs; only those that read outside the proof, and tests over the current graph, are obligations, and the latter must not be contradicted by the proof’s own evidence (C6). Query answers are output, never premises, and a proof claims exactly what the run outputs. For every new check, add a forged proof to tests/proof_validation.rs and confirm that all packaged proofs still check.

eyeron is expected to run about as fast as its JavaScript sibling eyeling; a gap of several times is a defect. After engine changes, run EYERON_TEST_JOBS=1 ./scripts/test-all --release once on a quiet machine, and look per example as well as at the total: one slow example can hide behind an otherwise faster suite. Do not time anything while other builds or agents share the machine. Profile before optimizing; valgrind’s callgrind works where perf is unavailable. Hand-rolled hashers need final mixing, because hash tables pick buckets from the low bits.

eyeron, eyeling, eyeleng, and eyeprolog are one family; a behavior fixed in one usually belongs in the others. When eyeron and eyeling disagree, find out which one is right before changing either.

Run focused tests while working, then ./scripts/test-all and clippy before finishing code changes. Add a regression test for each behavior change, in the style of the file it joins. Documentation describes the current behavior, not how it came to be; documentation-only edits need a review and git diff --check.

Versions and releases

Commit directly to main. Do not use closing keywords such as Fixes #N in commit messages; issues are closed by hand. Follow the user’s instructions about committing, pushing, and releasing.

Cargo.toml is the version source; never bump it by hand. Releases are cut with the release script after the suite has passed:

./release patch "<release message>"
./release minor "<release message>"
./release major "<release message>"

The script switches to main, pulls with --ff-only, bumps the version with cargo set-version (cargo-edit), rebuilds pkg/ with cargo playground so the wasm build reports the new version, stages every change, commits, creates an annotated v* tag, and pushes the branch and tag. Review the working tree first because it stages everything. A push to main deploys GitHub Pages and runs CI; a v* tag creates the GitHub release from the tag’s message and publishes the crate through .github/workflows/publish-crates.yml. See the guide for its one-time crates.io authentication setup and existing-tag dispatch.