Skip to main content

A Prolog-style logic programming DSL embedded in Python

Project description

clausal

A Prolog-style logic programming DSL embedded in Python. Write relational logic programs using .clausal source files or directly in Python, with full constraint solving, tabling, DCGs, and a rich standard library.

Features

  • .clausal source files — import logic modules with Python's standard import system
  • Prolog-style predicates — Horn clauses, unification, backtracking search
  • Constraint solving — CLP(FD) for integers, CLP(B) for booleans, dif/2 disequality
  • SLG tabling — memoised subgoal calls for termination on cyclic structures
  • DCGs — Definite Clause Grammars with >> syntax and phrase/2,3
  • Well-Founded Semantics — negation-as-failure with \+ / tabled predicates
  • Module system-import_from/2, -import_module/1, qualified calls
  • Meta-predicatesfindall/3, bagof/3, setof/3, forall/2, call/N
  • Higher-ordermaplist/2,3, foldl/4, include/3, exclude/3
  • Python interop++expr escape, lambda goal closures, f-string support
  • SciPy integration — wrappers for scipy.special, scipy.linalg, scipy.optimize, scipy.interpolate, scipy.signal
  • Regexmatch/2,3, search/2,3, replace/4, split/3 with auto-binding goal expansion
  • Term expansion — macro system for source-level term rewriting
  • C extensions — fast logic variables, trail-based backtracking, trampoline (no WAM)

Installation

pip install clausal

Requires Python ≥ 3.13 and a C compiler for the extension modules.

Quick start

Python API

from clausal import query, solve, once, Var
from clausal.import_hook import LogicModule

# Load a .clausal module
import clausal.examples.family  # if you have one

Writing .clausal files

# family.clausal
parent(tom, bob) <-
parent(tom, liz) <-
parent(bob, ann) <-
parent(bob, pat) <-

grandparent(X_, Z_) <- (parent(X_, Y_), parent(Y_, Z_))
# Python
import family   # .clausal files load via the import hook

from clausal import query
results = list(query(family.grandparent(Var(), Var())))
# → [(tom, ann), (tom, pat)]

Constraints (CLP(FD))

# queens.clausal
-import_from(clpfd, [in_, all_different, label])

queens(N_, QS_) <- (
    length(QS_, N_),
    QS_ in_ 1..N_,
    safe(QS_),
    label(QS_)
)

Arithmetic & builtins

fib(0, 0) <-
fib(1, 1) <-
fib(N_, F_) <- (
    N_ > 1,
    N1_ is N_ - 1,
    N2_ is N_ - 2,
    fib(N1_, F1_),
    fib(N2_, F2_),
    F_ is F1_ + F2_
)

DCGs

sentence >> (noun_phrase, verb_phrase)
noun_phrase >> ([the], noun)
verb_phrase >> ([runs])
noun >> ([cat])
noun >> ([dog])
from clausal import once
result = once(phrase(sentence, [the, cat, runs]))

Testing

.clausal files can include inline tests as test/1 clauses:

test("fib(5) = 5") <- fib(5, 5)

Standalone runner:

python -m clausal.testing clausal/examples/           # all .clausal files
python -m clausal.testing clausal/examples/hanoi.clausal  # single file
python -m clausal.testing -v clausal/examples/        # verbose

Via pytest (.clausal tests collected automatically):

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

Logic variables and backtracking

The C extension clausal.logic.variables provides Prolog-style logic variables and trail-based backtracking without a Warren Abstract Machine.

from clausal.logic.variables import Var, Trail, unify, is_var

trail = Trail()
X = Var()
Y = Var()

unify(X, 42, trail)
assert X.value == 42

mark = trail.mark()
unify(Y, "temporary", trail)
trail.undo(mark)
assert is_var(Y)   # Y is unbound again

See docs/ for full documentation.

Requirements

  • Python ≥ 3.13
  • greenlet
  • pyyaml ≥ 6.0
  • C compiler (for building from source)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clausal-0.3.0.tar.gz (574.4 kB view details)

Uploaded Source

File details

Details for the file clausal-0.3.0.tar.gz.

File metadata

  • Download URL: clausal-0.3.0.tar.gz
  • Upload date:
  • Size: 574.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for clausal-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8c14dd3726eb12be0d7c0b2a8d54ba8744bc344e9d86083b823d145024355f3f
MD5 44bd95a4fa29a439bb4dc40b20877fdf
BLAKE2b-256 6b578e13ff1caf153750c9a893dba729c59ae87e481d961df93700c314f1272d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page