p.enthalabs

GitHub - mat-mgm/kb-prolog: A hyper-relational knowledge base with content-addressable storage, built on Prolog, SQLite, and C.

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

![Image 1: screenshot](https://github.com/mat-mgm/kb-prolog/blob/main/screenshot.png)

What it is

[](https://github.com/mat-mgm/kb-prolog#what-it-is)

- **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.

Build

[](https://github.com/mat-mgm/kb-prolog#build) **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`.

Usage

[](https://github.com/mat-mgm/kb-prolog#usage)

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

Architecture

[](https://github.com/mat-mgm/kb-prolog#architecture)

``` 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) ```

Data model

[](https://github.com/mat-mgm/kb-prolog#data-model) 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.

Nix

[](https://github.com/mat-mgm/kb-prolog#nix) A `kb.nix` shell is provided for reproducible builds:

nix-shell kb.nix

License

[](https://github.com/mat-mgm/kb-prolog#license) GPL-3.0 — see LICENSE.md.