Back Original

Kb – Prolog Knowledge Base

A local-first, hyper-relational knowledge base with content-addressable storage (CAS). Built as a Master's thesis prototype.

screenshot

  • Hyper-relational graph: Knowledge is stored as statement(Subject, Predicate, Object, Properties). Subjects and objects can themselves be statements (reification), enabling claims about claims.
  • Content-addressable storage: Files are staged, SHA-256 hashed, and committed atomically alongside their graph metadata. Deduplication is automatic.
  • Time-travel: Updates create new statement versions linked via replaces_id. pl history walks the version chain.
  • Prolog-first: Trealla Prolog is the main runtime. SQLite and Raylib are accessed via C shared libraries loaded through FFI.
  • Interactive GUI: A Raylib-based graph viewer with image previews, a query bar, and node search.

Dependencies: Clang, X11 (Linux) or Xcode CLT (macOS). Trealla Prolog, Raylib, raygui, and SQLite are included as submodules.

git clone --recurse-submodules <repo-url>
cd kb
make

This builds libcas.so, libgui.so, and libsqlite3.so in the project root. Raylib is compiled from source during make.

To build Trealla from source:

cd vendor/trealla && make

Then ensure tpl is on your $PATH.

# Load a context into memory and open a REPL
tpl -l main.pl -- pl load concept(mathematics)

# Assert a new statement
tpl -l main.pl -- pl assert \
  "statement(concept(mathematics), foundation_of, concept(logic), [])"

# Full-text search
tpl -l main.pl -- pl search mathematics

# View version history of a term
tpl -l main.pl -- pl history concept(mathematics)

# Ingest a file into CAS
tpl -l main.pl -- cas add document.pdf

# List CAS objects
tpl -l main.pl -- cas list

# Launch the GUI
tpl -l main.pl -- gui

# Check database consistency
tpl -l main.pl -- pl verify

# Run garbage collection
tpl -l main.pl -- pl gc
main.pl             CLI router and REPL
prolog/
  sync.pl           2-phase commit: marshal Prolog terms ↔ SQLite
  cas.pl            FFI bindings to libcas.so
  db.pl             SQLite queries
  gui.pl            Raylib frontend (yield-loop pattern)
  ontology.pl       In-memory knowledge graph
src/
  cas.c / cas.h     CAS: stage, SHA-256 hash, commit atomically, verify
  gui.c / gui.h     Raylib renderer and input handler
  graph.c / graph.h Graph layout
  util.c / util.h   SHA-256, MD5
sql/
  schema.sql        SQLite schema (WAL mode, FTS5, reification)
vendor/             Trealla, Raylib, raygui, SQLite (submodules)

Every piece of knowledge is a statement/4 term:

statement(Subject, Predicate, Object, Properties)

Subject and Object are Prolog terms or integer IDs pointing to other rows in the statement table, enabling arbitrary nesting. The SQLite schema mirrors this with ANY-typed columns and a replaces_id foreign key for versioning.

Example:

% Alice claims (with certainty 0.9) that Bob likes pizza
statement(
  person(alice),
  claims,
  statement(person(bob), likes, food(pizza), []),
  [certainty(0.9)]
)

Context loading uses bidirectional recursive CTEs to pull only the subgraph reachable from a seed term into Prolog's in-memory working set.

A kb.nix shell is provided for reproducible builds:

GPL-3.0 — see LICENSE.md.