Development¶
This page covers the development environment, the test suite, coverage, and the day-to-day workflow. Benchmarks have their own page: Benchmarks.
Environment¶
The flake defines outputs for x86_64-linux and aarch64-darwin (Apple
Silicon). On either system, enter the reproducible development environment
with:
Other platforms have no flake outputs
On platforms outside the two supported systems (e.g. Intel Mac, Windows), the flake does not expose a development shell, package, check, or app. Load the local checkout with ASDF instead (see Getting Started) and rely on CI for Nix verification.
Running examples¶
sbcl --non-interactive \
--eval '(require :asdf)' \
--eval '(asdf:load-asd (truename "cl-prolog-kit.asd"))' \
--eval '(asdf:load-system :cl-prolog-kit/examples)'
Run this from the repository root. Loading cl-prolog-kit/examples loads the
library first and then executes all three example files. The example files are
not standalone scripts, so invoking them directly with sbcl --script does not
load the cl-prolog-kit package. See Examples for a
walkthrough.
Testing¶
cl-prolog-kit's regression suites are the cl-prolog-kit/test and
cl-prolog-kit/callgraph/test ASDF systems. They depend on
cl-weave and cover isolated table
cases, per-query cases, fixtures, generated relational properties, and the
callgraph analysis API.
The Nix runner is self-contained and is the authoritative path on supported
systems (x86_64-linux, aarch64-darwin):
nix run . # cl-weave regression suite, via the cl-weave CLI
sbcl --script run-tests.lisp # requires cl-weave on CL_SOURCE_REGISTRY
nix flake check # full verification suite
nix fmt # format Nix sources (treefmt)
Pass any cl-weave CLI options after --; for example, to produce a JSON result:
Unsupported platforms
On platforms outside the two supported systems (e.g. Intel Mac,
Windows), ensure cl-weave is discoverable through ASDF and run the
suite directly with sbcl --script run-tests.lisp, then rely on CI for
the Nix nix flake check path.
What nix flake check runs¶
checks.default— both cl-weave regression suites, run throughrun-tests.lispunder a plain SBCL with the compiled-in default dynamic space.checks.paredit-lint— a structural parse gate over every tracked.lisp/.asdfile, failing if any is not a balanced S-expression document.checks.examples— loads every shipped example through ASDF (Examples).checks.docs— builds the MkDocs site with--strictand fails if it does not produce a validindex.html.checks.formatting— checks every Nix file againstnixfmt, via treefmt.nix fmtfixes what it reports.checks.package— buildspackages.default, so the package README.md advertises (nix run github:nerima-lisp/cl-prolog-kit) is actually realised, not merely evaluated.checks.app-test— runsapps.test, the cl-weave CLI wrapper (a distinct code path fromchecks.default: it sets a 4096 MB dynamic space).checks.coverage— buildspackages.coverageand asserts it produced a report; it does not gate on a coverage percentage.
Coverage¶
packages.coverage runs both regression suites under sb-cover, instrumenting
cl-prolog-kit, cl-prolog-kit/weave, and cl-prolog-kit/callgraph (not the cl-weave
harness driving them), and writes an HTML report. The report helper generates
its runner from flake.nix, so it does not read the source-tree
run-coverage.lisp:
Outside Nix, run-coverage.lisp remains the direct SBCL entry point. With
cl-weave discoverable through CL_SOURCE_REGISTRY:
This is a visibility tool, not an enforced gate: checks.coverage fails only
if the report fails to build, not if coverage drops.
Query test helpers¶
Load the cl-prolog-kit/weave ASDF system to use the public query test helpers:
deftest-queries creates an independent cl-weave case and a fresh rulebase for
every query. A leading case label is optional; without one, the printed query is
used.
(cl-prolog-kit/weave:deftest-queries family-queries ((make-family-rulebase))
("keeps proof order" (parent alice ?child) :ordered
(((?child . bob)) ((?child . carol))))
((parent alice ?child) :set
(((?child . carol)) ((?child . bob))))
((parent alice ?child) :first ((?child . bob)))
((parent alice bob) :succeeds)
((parent bob alice) :fails)
((parent alice bob) :signals cl-prolog-kit:invalid-max-depth-error
:max-depth :invalid))
Assertion kinds:
:ordered— compares the full solution sequence, order included.:set— ignores only the order of complete solutions; it still compares the structure within each solution withequal.:first— compares the first solution's bindings.:succeeds/:fails— assert provability without inspecting bindings.:signals— asserts a condition is raised, optionally of a given type.
Query options (such as :max-depth) follow the expected value or assertion
kind.
Use assert-query inside an existing cl-weave case when a table is not needed:
(cl-weave:it "finds Alice's first child"
(cl-prolog-kit/weave:assert-query (make-family-rulebase)
(parent alice ?child) :first ((?child . bob))))
Track new files before trusting nix flake check¶
Git-backed flake input selection drops untracked files before this
repository's own source filter runs. A new docs page, example, or test file
that exists only in a dirty worktree is therefore absent from every Nix build,
and nix flake check will pass without ever seeing it — or fail with a
confusing "file does not exist" from inside the sandbox.
Structural refactors¶
nix develop puts paredit on
PATH. Prefer it over hand-editing parentheses for renames, moves, and other
structural changes to Lisp sources:
paredit inspect check --file src/engine.lisp
paredit refactor rename-function --from old-name --to new-name --output json src/*.lisp
Run a plan or preview command without --write first, review the JSON, then
re-run with --write. checks.paredit-lint fails the build if any tracked
.lisp or .asd file stops being a balanced S-expression document.
Benchmarks at a glance¶
sbcl --script benchmarks/performance.lisp # in-process micro-benchmarks
ITERATIONS=5000 benchmarks/external-comparison.sh # cross-engine comparison
These are diagnostic tools, not part of nix flake check. See
Benchmarks.
Documentation¶
The site is built with Material for MkDocs.
The config lives in docs/mkdocs.yml and content in docs/src/.
--strict promotes broken links and unlisted pages to build failures, matching
the Nix build and the checks.docs gate. The published site deploys to
GitHub Pages from .github/workflows/docs.yml on every push to main that
touches docs/, flake.nix, flake.lock, or the workflow itself.
Design constraints¶
- no runtime dependencies, SBCL-tested, ANSI-leaning core
- a single canonical public API surface
Releasing¶
Release mechanics — the tag/:version guard and writing the GitHub Release
description, which is this project's only canonical release history — follow
the org-wide
RELEASE_STANDARD.md.
A change is releasable when nix flake check is green and, if the public
surface moved, the matching pages were updated in the same change:
API,
Conditions and Errors, and
Compatibility.