eyelog

Eyelog Handbook

This handbook is the practical companion to the Eyelog language specification. For the normative Prolog-like language definition, including lexical syntax, terms, clauses, goals, Herbrand semantics, built-ins, memoization declarations, triple/3, and conformance boundaries, read SPEC.md.

This document focuses on using the current implementation: running examples, using the browser playground, writing maintainable example files, testing, performance, and release workflow.

Contents

1. Running Eyelog

Build only the native command-line executable:

make cli

Run an example:

bin/eyelog examples/ancestor.pl

Ask a direct query:

bin/eyelog --query 'triple(pat, ancestor, X)' examples/ancestor.pl

The command-line usage is:

usage: eyelog [--version] [--query GOAL] [file-or-url.pl|- ...]

Inputs are parsed into one program before solving, so facts and rules can be split across files:

bin/eyelog facts.pl rules.pl

Use - to read one input from standard input:

printf 'triple(stdin, works, true).\n' | bin/eyelog -

For interactive standard input, terminate the program with end-of-file after the final period. On Linux, macOS, and WSL this is normally Ctrl-D on an empty line:

triple(a, b, c).
<Enter>
<Ctrl-D>

Native builds can also load http:// or https:// inputs by invoking curl or wget:

bin/eyelog https://raw.githubusercontent.com/eyereasoner/eyelog/refs/heads/main/examples/ancestor.pl

Without --query, the executable asks for the public output relation:

triple(S, P, O)

and prints distinct answers as Prolog facts. The language-level convention for triple/3 is specified in SPEC.md. The formal least-model reading is specified in SPEC.md.

2. Browser playground

Build the WebAssembly assets:

make browser

Serve the repository over HTTP:

make serve

Then open:

http://localhost:8000/playground.html

Opening the playground directly as a file:// URL usually fails because browsers block module workers or .wasm loading from local files.

The playground:

Readable URL-based share links use the ?url=... form:

https://eyereasoner.github.io/eyelog/playground?url=https://raw.githubusercontent.com/eyereasoner/eyelog/refs/heads/main/examples/matrix.pl

Edited inline programs use compact hash links. On insecure HTTP origins where the modern Clipboard API is unavailable, the playground falls back to textarea copy and then to a manual copy prompt.

After changing C source, the Makefile, or browser build settings, rebuild stale browser assets with:

make clean browser

The generated dist/browser/ files are local build products and should not be committed.

3. Writing example programs

Most examples use this structure:

  1. input data as facts;
  2. helper predicates for computation or search;
  3. concise triple/3 rules as the public report layer.

For example:

parent(pat, jan).
parent(jan, emma).

ancestor(X, Y) :- parent(X, Y).
ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).

triple(X, ancestor, Y) :- ancestor(X, Y).

Keep the public output small and explanatory. For calculation examples, prefer reporting the final result plus a few reason/status triples rather than every intermediate value.

Use helper predicates for internal state and use triple/3 for the visible result:

score(case1, 0.92).
threshold(case1, 0.80).

triple(case1, status, accepted) :-
  score(case1, Score),
  threshold(case1, Threshold),
  gt(Score, Threshold).

triple(case1, reason, "score exceeds threshold") :-
  score(case1, Score),
  threshold(case1, Threshold),
  gt(Score, Threshold).

For exact language rules, Herbrand semantics, built-in modes, list syntax, quoted atoms, strings, numbers, and conformance details, use SPEC.md as the source of truth.

4. Example catalog

The repository contains examples across several styles and domains. Each example name links to its source file.

Core logic and graph reasoning

Data, RDF-shaped output, and formula data

Search and puzzles

Arithmetic and mathematics

Science, technology, and engineering

Representative applied scenarios

Other demonstrations

5. Golden outputs and tests

Each example that is part of the regression suite has a matching golden output file under examples/output/.

Run all tests:

make test

The test runner:

When adding or changing an example:

  1. keep the default triple/3 output concise;
  2. run the example manually;
  3. write or update examples/output/<name>.pl;
  4. add one or two targeted checks to test/run.sh if the example has an important invariant;
  5. run make test.

Example update loop:

bin/eyelog examples/my-example.pl > examples/output/my-example.pl
make test

6. Development and release

Common build commands:

make cli       # native executable only
make browser   # WebAssembly playground assets
make           # CLI and browser assets
make all       # same as make
make clean
make test

The default make / make all target builds both native and browser assets. That requires a C compiler and Emscripten’s emcc. Use make cli when you only need the native executable.

For releases, update VERSION; the build embeds that value in bin/eyelog --version and the playground displays it in the UI.

The release helper is typically invoked with a short sentence:

./mkeyelog "Minor release: support multiple CLI inputs, stdin, and file-or-URL loading."

GitHub Pages builds the browser playground through the repository workflow. The workflow installs Emscripten before building browser assets.

7. Performance notes

Eyelog is a compact top-down Horn-clause engine. The following habits keep examples practical:

The implementation indexes user clauses by predicate and by bound scalar arguments. This helps all predicates, not just triple/3, especially when a goal has a bound atom/string/number argument.

The browser build has stricter call-stack limits than native execution. Several examples use native built-ins and iterative internals to reduce WebAssembly stack pressure, but deeply recursive search can still be more demanding in the browser than on the command line.

8. Current implementation limits

The language profile is intentionally smaller than ISO Prolog; see SPEC.md for the normative conformance boundary.

Current practical limits include:

Use SPEC.md for language-level guarantees and this handbook for repository workflow and practical examples.