Skip to main content

Clausal Prolog

Prolog in Python for Neurosymbolic AI

Documentation: clausal.pl · start with the Tutorial.

Neural networks are good at perception, language and pattern-matching, but are slow, resource-hungry, unreliable and need to be constrained. Symbolic AI is good at rules, reasoning and guarantees but can't deal with the real world. Clausal Prolog puts both in one Python process: a neural network can call symbolic logic that in turn calls neural predicates, nested as deeply as you like, with no serialisation, IPC or second runtime in between. Combining the two gives systems that are:

  • Explainable: conclusions come from rules you can read and a derivation you can trace, not only from weights.
  • Reliable: hard constraints such as regulations, safety rules and business policy hold exactly, every time, rather than approximately.
  • Data-efficient: knowledge you can state as a rule doesn't have to be learned from examples.
  • Correctable: change a rule and the behaviour changes, with no retraining.

Clausal Prolog is a Prolog implemented in Python that aims for ISO Prolog conformity. Logic programs go in .clausal files, written in Clausal Prolog: ISO syntax without cut or committed choice, which guarantees properties of programs that let you realise The Power of Prolog. Existing ISO Prolog goes in .pl files. The seam (.seam) is a Python-syntax surface for the adapters that give controlled access* to the whole Python ecosystem. All three import with Python's standard import system, and the import rules preserve each surface's guarantees. The engine includes constraint solving, tabling, DCGs and a large standard library.

*Python seam adaptors assume the Python programmer takes full responsibility for correctness (in the Pythonic way).

The package is clausal: pip install clausal, import clausal.

Three source surfaces

Extension Surface Syntax Use it for
.clausal Clausal Prolog ISO Prolog, without cut Your logic programs. The default choice.
.pl ISO Prolog Regular ISO Prolog, cut included External Prolog code, for Prolog systems such as Scryer or Trealla
.seam Seam Python syntax The boundary with Python: ++ escapes, hosted Python, adapters

All three are importable modules once clausal is imported. In one directory, name.seam beats name.clausal, which beats name.pl.

Changed in 1.0 (the extension flip). .clausal used to be the Python-syntax seam language. It is now Clausal Prolog, and seam source is named .seam. A seam file still named .clausal fails to load with a Prolog syntax error. To migrate, run git mv name.clausal name.seam for each one. Move it rather than copying it: a name.clausal left beside name.seam is a different module, written in Prolog. See CHANGELOG.md.

Features

  • Clausal Prolog: ISO syntax, ISO builtin names and error terms, "…" as a string, and modules with module/2, use_module/1,2 and end_module/1
  • Purity by design: no cut, -> or *->; use dif/2, if_/3 from library(reif), constraints and first-argument indexing instead
  • Constraint solving: CLP(Z) for integers, CLP(B), CLP(Q), CLP(R) and dif/2
  • SLG tabling and well-founded semantics for negation over tabled predicates
  • DCGs: --> grammar rules with phrase/2,3
  • Regular ISO Prolog alongside: .pl files, run in the Scryer or Trealla embeddings, or imported directly (experimental)
  • Python interop through the seam: library(...) facades over the engine's Python modules (library(json), library(datetime), …), Python-free .seam modules, and allowlisted Python bridges
  • ISO direction: ISO builtin names, ISO error terms and ISO modules; where ISO is silent, Scryer Prolog's behaviour
  • C extensions: logic variables, trail-based backtracking and a trampoline, with no WAM

Installation

pip install clausal

Requires Python ≥ 3.13 and a C compiler (pip uses it automatically when building from source).

Quick start

A Clausal Prolog module

% family.clausal
:- module(family, [grandparent/2, fib/2, path/2]).
:- use_module(library(clpz)).

parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).

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

% CLP(Z) arithmetic: fib/2 runs in both directions.
fib(0, 0).
fib(1, 1).
fib(N, F) :-
    N #> 1,
    N1 #= N - 1, N2 #= N - 2,
    F #>= N1, F #= F1 + F2,
    fib(N1, F1), fib(N2, F2).

% Tabling terminates on the cycle.
:- table(path/2).
edge(1, 2).
edge(2, 3).
edge(3, 1).
path(X, Y) :- edge(X, Y).
path(X, Y) :- edge(X, Z), path(Z, Y).

test("tom's grandchildren") :- grandparent(tom, ann), grandparent(tom, pat).
test("fib(10) = 55") :- fib(10, 55).
test("which fib is 55?") :- once(fib(N, 55)), N == 10.
test("path reaches the whole cycle") :- findall(Y, path(1, Y), Ys), msort(Ys, [1, 2, 3]).
test("tom has no grandparent", fail) :- grandparent(_, tom).

:- end_module(family).

A Clausal Prolog module file must end with :- end_module(Name)..

Running it

clausal family.clausal -g "grandparent(tom, X)"   # X = ann.  X = pat.
clausal --test family.clausal                      # runs the test clauses

clausal FILE on its own runs the program's main/0. See docs/cli.md.

Querying it from Python

Python asks the questions from a .seam file, with a goal in for position after --:

# app.seam
-import_from(family, [grandparent, fib])
-private([tom])

for GRANDCHILD in --grandparent(tom, GRANDCHILD):
    print(GRANDCHILD)               # ann, then pat

for N in --fib(N, 55):
    print(N)                        # 10
    break
python -c "import clausal, app"     # import clausal installs the import hook

See Python Integration for more ways to query.

Constraints, DCGs and reified conditions

% puzzles.clausal
:- module(puzzles, [greeting//0, send_more/1, classify/2]).
:- use_module(library(clpz)).
:- use_module(library(reif)).

greeting --> [hello], name.
name --> [world].
name --> [prolog].

send_more([S,E,N,D,M,O,R,Y]) :-
    Vars = [S,E,N,D,M,O,R,Y],
    Vars ins 0..9, all_different(Vars),
    S #\= 0, M #\= 0,
    1000*S + 100*E + 10*N + D + 1000*M + 100*O + 10*R + E #=
        10000*M + 1000*O + 100*N + 10*E + Y,
    label(Vars).

% if_/3 instead of (Cond -> Then ; Else): it stays correct when X is unbound.
classify(X, R) :- if_(X = a, R = yes, R = no).

test("dcg") :- phrase(greeting, [hello, prolog]).
test("send more money") :- send_more([9,5,6,7,1,0,8,2]).
test("if_") :- classify(a, yes), classify(b, no).
test("dif") :- dif(X, a), X = b.

:- end_module(puzzles).

What Clausal Prolog restricts

Clausal Prolog is ISO Prolog with a few deliberate rules. Each one is enforced when the file loads:

  • Cut-free. ! and -> are refused, and *-> is not an operator. Use dif/2, if_/3, once/1, constraints or first-argument indexing.
  • Modules close. A module file must end with :- end_module(Name).. A file can opt out with :- set_prolog_flag(require_end_module, false)..
  • One-way dependency on ISO Prolog. A .clausal module may not import a .pl module, which may use cut. It is refused with permission_error(access, prolog_module, M). A .pl module may import a .clausal one.
  • Python only through the seam. A .clausal file reaches Python through engine-shipped library(...) facades (for example :- use_module(library(datetime), [date_add/3]).), through Python-free .seam modules, or through .seam modules listed under [tool.clausal] python_bridges in the importing project's pyproject.toml. Anything else is refused with permission_error(import, python_bridge, M).

See docs/importing_prolog.md for the full rules.

ISO Prolog .pl files

A .pl file is regular, external ISO Prolog: it is not restricted to the cut-free subset, and that is why a .clausal module may not import one. To run full ISO Prolog, cut included, alongside Clausal Prolog, use the Scryer or Trealla embeddings.

Importing a .pl file straight into the engine (put it on sys.path and import it) is experimental and outside the 1.0 compatibility promise. That in-process loader does not run cut yet: a .pl file that uses ! or -> fails to load there. CLAUSAL_PL_FRONTEND selects its front end (translator by default, or native, the ISO reader that .clausal files always use).

The seam: .seam files

Code that must call Python lives in .seam files. These use the older Python-syntax surface, with the ++expr escape, hosted Python statements and adapters over Python libraries. A .clausal module imports a .seam module like any other (subject to the Python-bridge rules). Keep .seam modules small and write your logic in Clausal Prolog. clausal-fmt and clausal-rewrite work on .seam files only. See docs/clausal_prolog.md for how the two surfaces differ.

Testing

A module carries its tests inline as test/1 clauses, or as test/2 with the option fail for a goal that must have no solution:

test("fib(5) = 5") :- fib(5, 5).
test("no grandparent", fail) :- grandparent(_, tom).

Standalone runner:

python -m clausal.testing path/to/dir/              # every .seam, .clausal and .pl file
python -m clausal.testing family.clausal            # a single file
python -m clausal.testing -v clausal/examples/      # verbose

Via pytest: test clauses in .seam, .clausal and .pl files are collected automatically.

python -m pytest tests/ clausal/examples/ -q

Requirements

  • Python ≥ 3.13 (no other runtime dependencies)
  • C compiler (for building from source)

Optional packages (YAML, spaCy, SciPy, PyTorch, the Scryer and Trealla embeddings, and more) live in packages/ and are not on PyPI yet. Install one from the repository, for example:

pip install "clausal-yaml @ git+https://github.com/neurosymbolica/clausal-prolog#subdirectory=packages/clausal-yaml"

License

MIT

Metadata

Release files for clausal 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for clausal 1.0.0
File Size Uploaded
clausal-1.0.0.tar.gz 3.7 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for clausal 1.0.0
File
clausal-1.0.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details
clausal-1.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 Details
clausal-1.0.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.5+ x86-64, Linux glibc 2.28+ x86-64 Details
clausal-1.0.0-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details
clausal-1.0.0-cp314-cp314-macosx_10_15_x86_64.whl CPython 3.14 CPython 3.14 macOS 10.15+ x86-64 Details
clausal-1.0.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
clausal-1.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 Details
clausal-1.0.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.5+ x86-64, Linux glibc 2.28+ x86-64 Details
clausal-1.0.0-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
clausal-1.0.0-cp313-cp313-macosx_10_13_x86_64.whl CPython 3.13 CPython 3.13 macOS 10.13+ x86-64 Details

Total release size: 30.0 MB

Release files / clausal-1.0.0.tar.gz

Download URL clausal-1.0.0.tar.gz
Size 3.7 MB
Tags Source
SHA-256 checksum
How to use checksums
cc59f9e0d3000be8dcffca1fe948477718403c13c08084b62b92cc754c8774eb
BLAKE2b-256 checksum
How to use checksums
5e9ba30226d94636a14c470d30a9df201dbafe90c89e2fa47b7a8e8c44bce82d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp314-cp314-win_amd64.whl

Download URL clausal-1.0.0-cp314-cp314-win_amd64.whl
Size 2.4 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
e6f30f7b5c209e02814131cb9eb65cc0de9d2278cc21af1753d4f82087fff50a
BLAKE2b-256 checksum
How to use checksums
01a294db5f07c11ae9e3c9ff4003ba7525142cb618f313bca81bc24d8f24a2d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL clausal-1.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 3.0 MB
Tags CPython 3.14 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
ef2ee466cd0ee68dda17f6e5db96da5b6d429b10e8456ea3ff69e91daafcf4f7
BLAKE2b-256 checksum
How to use checksums
0d9d0b6febab26bc3cc7500efc11a4a1b999f0f9ad62e7fb5a4733df607f4d0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL clausal-1.0.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 2.9 MB
Tags CPython 3.14 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64
SHA-256 checksum
How to use checksums
b4cdac2fa9208b5feebee3049e1c3c82e11b1485a49845dfbd34705aed38bac6
BLAKE2b-256 checksum
How to use checksums
33723ea1ffeea2e1455d6c8a9ccadb4098faff90c12097b0b1a6c6603dc2f20d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp314-cp314-macosx_11_0_arm64.whl

Download URL clausal-1.0.0-cp314-cp314-macosx_11_0_arm64.whl
Size 2.4 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
80f4f52af16fc7ebb6e7769cc6fbeabda883becff8283dbbd487b91bd4b107f8
BLAKE2b-256 checksum
How to use checksums
bf556d30c5cba409259ef85fb5d881f4e75c7dfd4a753239ddebe5dde4810a71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp314-cp314-macosx_10_15_x86_64.whl

Download URL clausal-1.0.0-cp314-cp314-macosx_10_15_x86_64.whl
Size 2.4 MB
Tags CPython 3.14 macOS 10.15+ x86-64
SHA-256 checksum
How to use checksums
41bd86316c1093c9046ab4fed27ff55f2b03ecda8f27fc6553cec84475cdbe70
BLAKE2b-256 checksum
How to use checksums
eb297a5fc5ab3401f42b992b2b47c85d10274d4ce6c94bc3c0bceff554c8ddfb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp313-cp313-win_amd64.whl

Download URL clausal-1.0.0-cp313-cp313-win_amd64.whl
Size 2.4 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
c37e6192297881c12ce571ac0a3237a544be1aaa70d27ad3ba5655fbe6996085
BLAKE2b-256 checksum
How to use checksums
ac2e3a16e165ac17f70bcfc37fb0b87ba70b937e7038a5e1a765957c811a2a0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL clausal-1.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 3.0 MB
Tags CPython 3.13 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
43c875b9592b0643ef145f57249c7fda08644053b162dfb93257433bbb9c7daa
BLAKE2b-256 checksum
How to use checksums
ff72ad5215300deeef57aa0677a78b3b0ce1c9e51e46f6db4f4ae9ff7e4b2f06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL clausal-1.0.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 2.9 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64
SHA-256 checksum
How to use checksums
f2f4cc5d683cb9ad0ec310433b8461d1b47c35f957b8adcd29283c454d1a355a
BLAKE2b-256 checksum
How to use checksums
3d5662863f360dd6e1b672ce6c00a2a786016f6dec31da765b0136a8f750cb84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp313-cp313-macosx_11_0_arm64.whl

Download URL clausal-1.0.0-cp313-cp313-macosx_11_0_arm64.whl
Size 2.4 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a505bdcfbde52933eafd8626725eec643f7d720985aaef3bd569f8be88517952
BLAKE2b-256 checksum
How to use checksums
3d40438a3573270bb3e4f4734d4ce2a542b832f9bf54b690ed7b1938c2e5b262
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / clausal-1.0.0-cp313-cp313-macosx_10_13_x86_64.whl

Download URL clausal-1.0.0-cp313-cp313-macosx_10_13_x86_64.whl
Size 2.4 MB
Tags CPython 3.13 macOS 10.13+ x86-64
SHA-256 checksum
How to use checksums
6cf7c17be181be7c316e39f5425b8e4c4033cfc837d4d4d9d00b53ed9874d6d8
BLAKE2b-256 checksum
How to use checksums
529c89fd7963c2d1fc0a0d0078afa5dfcf84e66aac245b8d14bf7b293e408234
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

11 release files

0.4.0

1 release file

0.3.1

1 release file

0.3.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page