Skip to content

Clausal

Beta

Clausal is in early beta. The API, syntax, and module interfaces are all subject to change. The developer experience has not been widely tested beyond the author's own use. Expect rough edges — bug reports and feedback are very welcome.

Logic programming embedded in Python.

Clausal brings Prolog-style logic programming to Python — not as a front-end to an external engine, but as a genuine part of the Python runtime. Python code and logic code call into each other freely, share the same objects, and run on the same VM.

import clausal
from fibonacci import fib

for solution in clausal.query(fib(10, N)):
    print(solution[N])  # 55

Why Clausal?

  • Pure Python syntax — all clausal code is valid Python. No separate parser, no foreign syntax to learn.
  • Deep integration — predicates are Python classes, logic variables are Python objects, backtracking uses Python generators.
  • Full-featured — tabling, CLP(FD), DCGs, EDCGs, modules, term expansion, goal expansion, reified if-then-else.
  • Fast — C extension for unification/trails, first-argument indexing, groundness-keyed dispatch, tail recursion optimization, bytecode caching.

Quick taste

A .clausal file defines predicates using Python syntax with a trailing comma:

# skip
# fibonacci.clausal

-table(fib/2),

fib(0, 0),
fib(1, 1),
fib(N, F) <- (
    N > 1,
    N1 := N - 1,
    N2 := N - 2,
    fib(N1, F1),
    fib(N2, F2),
    F := F1 + F2
)

Call it from Python:

import clausal
from fibonacci import fib

results = list(clausal.query(fib(10, F)))
# F binds to 55

Interactive example — Sudoku in IPython

Start IPython with the integration enabled:

CLAUSAL_IPYTHON=True ipython

Then solve a Sudoku puzzle interactively:

In [1]: from clausal.examples.sudoku import *

In [2]: *(ROWS is [
   ...:   [1, _, _, 8, _, 4, _, _, _],
   ...:   [_, 2, _, _, _, _, 4, 5, 6],
   ...:   [_, _, 3, 2, _, 5, _, _, _],
   ...:   [_, _, _, 4, _, _, 8, _, 5],
   ...:   [7, 8, 9, _, 5, _, _, _, _],
   ...:   [_, _, _, _, _, 6, 2, _, 3],
   ...:   [8, _, 1, _, _, _, 7, _, _],
   ...:   [_, _, _, 1, 2, 3, _, 8, _],
   ...:   [2, _, 5, _, _, _, _, _, 9],
   ...: ], Solve(ROWS))
Out[2]: ROWS is [
  [1, 5, 6, 8, 9, 4, 3, 2, 7],
  [9, 2, 8, 7, 3, 1, 4, 5, 6],
  [4, 7, 3, 2, 6, 5, 9, 1, 8],
  [3, 6, 2, 4, 1, 7, 8, 9, 5],
  [7, 8, 9, 3, 5, 2, 6, 4, 1],
  [5, 1, 4, 9, 8, 6, 2, 7, 3],
  [8, 3, 1, 5, 4, 9, 7, 6, 2],
  [6, 9, 7, 1, 2, 3, 5, 8, 4],
  [2, 4, 5, 6, 7, 8, 1, 3, 9]
]
No more solutions.

Uppercase names (ROWS) are automatically allocated as logic variables. The *(...) form is the IPython query syntax — see IPython / Jupyter REPL for the full feature set.


What's inside

Section What you'll find
Syntax The trailing-comma convention, escape operators, logic variables, clause syntax
Predicates How to define predicates in .clausal files
Builtins Complete index of built-in predicates
Dicts & Sets DictTerm, SetTerm, __unify__ protocol
Constraints Dif/2, CLP(FD) finite-domain constraints, and CLP(R) real-domain constraints
CLP(R) Interval arithmetic, non-linear propagation, and bisection labeling over the reals
Tabling SLG resolution and well-founded semantics
Lambdas Goal closures for higher-order logic programming
If-Then-Else Reified branching (no cut, no committed choice)
Import System .clausal file loading, module directives, qualified calls
Architecture Layer stack, execution model, why not a WAM
Python Integration Query API, ++() escape, Python interop
IPython / Jupyter REPL Interactive queries, *(goals) syntax, solution browsing
Standard Library Modules
Physical Units n(Unit) sugar, dimensional arithmetic, AttVar constraints
Regex Pattern matching, group extraction, auto-binding
Symbolic Math SymPy integration — calculus, algebra, number theory
YAML YAML parsing and generation
Date/Time Date, time, and datetime predicates
Logging Structured logging predicates
UUID UUID generation and inspection
Graphs Graph traversal, pathfinding, connectivity, MST
SQLite SQLite database predicates
spaCy NLP NLP pipeline — tokenisation, NER, POS, similarity
scipy.special Special mathematical functions — gamma, Bessel, elliptic, hypergeometric, orthogonal polynomials
scipy.linalg Linear algebra — solvers, decompositions, matrix functions, factorisations
scipy.optimize Optimisation — minimisation, root finding, curve fitting, linear programming
scipy.integrate Numerical integration — quadrature, ODE solvers, sampled-data methods
scipy.interpolate Interpolation — splines, PCHIP, Akima, regular grids, radial basis functions
scipy.stats Statistics — descriptive stats, hypothesis tests, distributions
scipy.fft Discrete Fourier transforms — FFT, inverse FFT, helper functions
scipy.ndimage N-dimensional image processing — filters, morphology, transforms, measurements
scipy.spatial Spatial algorithms — distance functions, KD-tree, ConvexHull, Delaunay, Rotation
Testing Writing test predicates, running the test suite
DCGs Definite Clause Grammars for parsing
Exceptions throw/catch, structured error terms
CLP(B) Boolean constraint programming
Meta-Interpreter Specialization Partial deduction — specialize MIs to remove interpretation overhead
Prolog Translation Bidirectional clausal ↔ Prolog translation