SWI-Prolog Capability Atlas

This folder is a systematic capability survey of SWI-Prolog — the dialect embedded in-process by orchestrata as its governance/policy brain — swept from the official swi-prolog.org documentation on 2026-07-29. Each of the ten topic pages was written against the actual manual sections and package documents (the exact URLs read are cited in each page's ## Sources section), not from folklore or secondhand blog posts. Every page follows the same contract:

  1. Full predicate reference — every major predicate/directive of the subsystem with its signature, determinism, and semantics explained in full sentences.
  2. Runnable examples — complete SWI-Prolog code blocks taken or adapted from the manual, long enough to paste into swipl and run.
  3. A mermaid diagram of the subsystem's architecture or data flow.
  4. ## Pitfalls and gotchas — the real caveats the manual documents (and a few it only implies), because these subsystems fail in non-obvious ways.
  5. ## How orchestrata can leverage this — 3–6 concrete proposals grounded in the real codebase: named rule files (governance.pl, kg_relevance.pl, test_schedule.pl, …), named Python seams (core/prolog_adapter.py, governance/prolog_gate.py, orchestrator/prolog_worker.py), and named infrastructure (the redis-queue container at 10.53.1.10, the Memgraph orchgraph cluster at 10.53.1.160).

The cross-project consolidation of all those leverage sections — deduplicated, ranked, with code sketches — lives in the companion capstone page: Prolog Leverage Roadmap for orchestrata.

Why this folder exists

Orchestrata already runs SWI-Prolog in production: 22 rule files consulted through the janus bridge cover governance gating, intent NL parsing, symbolic knowledge-graph reasoning, and CLP(FD) test scheduling. But the live-analysis audit that preceded this sweep found the project uses a narrow slice of what the runtime ships: no plunit, no Prolog-side threads, no library(redis), no semweb, no engines, no persistency, tabling only in the KG tier, CLP(FD) only in one file, DCGs only in one grammar. Each topic page documents one of those unused (or under-used) subsystems end-to-end so that future design work can reach for the right primitive with the manual semantics already digested.

The topic pages

Page What it gives you
Redis from Prolog — library(redis) SWI's native Redis client: named lazy-connecting servers with auto-reconnect (redis_server/3), commands as callable terms with typed reply mapping and as Type coercions, pipelining, PUB/SUB via library(broadcast), and full consumer-group streams in library(redis_streams).
Threads, Message Queues and Concurrency Native preemptive OS threads sharing only the heap (thread_create/3, thread_join/2), term-copying message queues with unification-based selective receive, thread_wait/2 condition-variable semantics over the dynamic DB, signals, library(thread) high-level parallelism (concurrent_maplist, concurrent_forall, first_solution/3), and library(thread_pool).
Unit Testing with plunit The complete plunit contract: begin_tests/end_tests units as sub-modules, the full test/2 option catalogue (true/fail/throws/error/all/set, forall, setup/cleanup, blocked/fixme, nondet), run_tests and CI wiring, .plt companion files, and library(prolog_coverage).
Janus — the Python-Prolog Bridge Both directions of the bridge orchestrata lives on: query_once/query/apply_once/cmd/consult from Python (with the truth-value and iterator-close contracts), py_call/py_iter/py_module from Prolog, data conversion rules, GIL/engine threading model, and error translation.
Tabling (SLG Resolution) and Memoization :- table in all its modes: variant vs subsumptive, answer subsumption (lattice, po, min/max/sum/first/last), incremental tabling with its dependency graph, monotonic tabling, shared tables across threads, well-founded semantics with tnot/1, and restraints (max_answers, tripwires) for bounded rationality.
Constraint Solving — CLP(FD), CLP(B), dif/2 Integer constraints as true relations (#=, in/ins, labeling/2 with branch-and-bound min/max), global constraints (all_distinct, global_cardinality, cumulative/2), reification, Boolean SAT via CLP(B) (taut/2, sat_count/2), and sound disequality with dif/2.
Graphs in Prolog — semweb/RDF, ugraphs, assoc The C-indexed RDF triple store (rdf/3-4, rdf_reachable, typed rdf11 literals, named graphs, transactions/snapshots, the SPARQL client, crash-safe journal persistency) plus pure in-memory graph algorithms (library(ugraphs): top_sort, transpose, reachable, layers) and AVL maps (library(assoc)).
DCGs and Text Processing How -->/2 translates to difference-list clauses, phrase/2-3 vs call_dcg/3, pushback/semicontext notation, library(dcg/basics) and library(dcg/high_order) (sequence//3, optional//2), and reversible parse/generate grammars.
Engines, Coroutining and Attributed Variables Engines as ~20 KB suspendable Prolog VMs pulled with engine_next/2 (not bound to OS threads), the engine_post/engine_fetch/engine_yield stateful-agent protocol, freeze/2, when/2, frozen/2 diagnostics, and the attributed-variable hooks under all SWI constraint solvers.
Modules, Dynamic Predicates and Persistent State The module system (use_module/2 with except/renaming, reexport facades, meta_predicate/1 specifiers), dynamic/1 and the ISO logical update view under concurrency, library(persistency) journaled facts, library(settings) typed config, and term_expansion/goal_expansion compile-time hooks.

How the subsystems compose

The pages are written to stand alone, but the subsystems are not islands — SWI-Prolog's power for a system like orchestrata comes from how they stack:

Overview diagram

Diagram prolog-index-1

Solid arrows are data paths; dashed annotations mark where orchestrata stands today (USED / UNUSED / PROPOSED). The asymmetry is the whole story: the janus membrane and the tabling/DCG/CLP islands behind it are production-proven, while the entire right-hand column of I/O and lifecycle machinery (redis, semweb, persistency, plunit, threads, engines) is dark.

Orchestrata touchpoint summary

A condensed map of where each subsystem meets the codebase — the leverage roadmap page expands every row into a concrete build item:

Subsystem Status in orchestrata Key touchpoints
janus Production, exclusive bridge core/prolog_adapter.py (ground-facts doctrine, engine pinning), orchestrator/prolog_worker.py (PrologWorker/PrologProxy singletons), governance/prolog_client.py (the one blessed loader)
Tabling Production (KG tier only) kg_relevance.pl:48-54, knowledge.pl:32,53 incremental tables over per-refinement facts; tools/codebase_db.pl tabled closures; governance corpus untabled; constitutional.pl:133 warns against tabling assess_harm/3 instead of restructuring it
CLP(FD) Production (one file) test_schedule.pl best_schedule_pairs/4 driven by core/threading/test_scheduler.py; documented crux: conflicting modules forced onto the same worker
DCG Production (one grammar) intent_grammar.pl + generated intent_lexicon.gen.pl (CI drift check via scripts/gen_intent_lexicon.py), routing.pl parity-tested against INTENT_VOLK_MAPPING
plunit Absent Zero .plt files; only hits are the vendored janus self-test and an orphaned runner (rtm/scripts/run_plunit_tests.py) pointing at a directory that does not exist
Threads/queues Absent (Prolog-side) All concurrency is Python threads with janus per-thread engine pinning (~3.4x measured); no thread_create in any project .pl
library(redis) Absent Redis is the project's hot store (Postman queues, audit queues db 15, receipts) but is Python-only today
semweb/RDF Absent KG reasoning is hand-rolled ground facts projected from the Memgraph orchgraph cluster; no rdf/3, no named graphs, no journal persistency
Engines Absent No suspendable computations; deny provenance re-runs the whole proof through explain.pl
persistency/settings Absent Every fact rebuilt per process; thresholds are magic numbers in resources.pl/completion.pl; no hot-reload of consulted rules (consult-once globals throughout)

Facts worth remembering

Datapoints from the sweep that repeatedly change design decisions — each is documented in full on its topic page:

Reading order

For a first pass, read in dependency order rather than table order:

  1. janus — the membrane everything crosses; understand the truth-value dict, the iterator-close hazard, and why assertz is ground-facts-only.
  2. modules-dynamic-state — modules, dynamic/1, and the logical update view; prerequisites for reading any rule file critically.
  3. tabling — the most consequential single capability for the governance corpus (incremental tables = gate decisions as trie lookups).
  4. plunit — because nothing else should ship untested.
  5. Then in any order: threads, redis, clpfd, dcg, semweb-graphs, engines-coroutines.
  6. Finish with the leverage roadmap, which turns the ten ## How orchestrata can leverage this sections into one ranked, deduplicated build plan.

Provenance and maintenance

Sources

The seed table-of-contents pages for the sweep (each topic page cites its own deeper URLs):