kanren
Logic Programming in Python
Examples
kanren enables the expression of relations and the search for values which satisfy them. The following code is the "Hello, world!" of logic programming. It asks for 1 number, x, such that x == 5
>>> from kanren import run, eq, membero, var, conde
>>> x = var()
>>> run(1, x, eq(x, 5))
(5,)
Multiple variables and multiple goals can be used simultaneously. The
following code asks for a number x such that x == z and z == 3
>>> z = var()
>>> run(1, x, eq(x, z),
eq(z, 3))
(3,)
kanren uses unification, an advanced form of pattern matching, to match within expression trees.
The following code asks for a number, x, such that (1, 2) == (1, x) holds.
>>> run(1, x, eq((1, 2), (1, x)))
(2,)
The above examples use eq, a goal constructor to state that two expressions
are equal. Other goal constructors exist such as membero(item, coll) which
states that item is a member of coll, a collection.
The following example uses membero twice to ask for 2 values of x,
such that x is a member of (1, 2, 3) and that x is a member of (2, 3, 4).
>>> run(2, x, membero(x, (1, 2, 3)), # x is a member of (1, 2, 3)
membero(x, (2, 3, 4))) # x is a member of (2, 3, 4)
(2, 3)
Logic Variables
As in the above examples, z = var() creates a logic variable. You may also, optionally, pass a token name for a variable to aid in debugging:
>>> z = var('test')
>>> z
~test
Lastly, you may also use vars() with an integer parameter to create multiple logic variables at once:
>>> a, b, c = vars(3)
>>> a
~_1
>>> b
~_2
>>> c
~_3
Representing Knowledge
kanren stores data as facts that state relationships between terms.
The following code creates a parent relationship and uses it to state facts about who is a parent of whom within the Simpsons family.
>>> from kanren import Relation, facts
>>> parent = Relation()
>>> facts(parent, ("Homer", "Bart"),
... ("Homer", "Lisa"),
... ("Abe", "Homer"))
>>> run(1, x, parent(x, "Bart"))
('Homer',)
>>> run(2, x, parent("Homer", x))
('Lisa', 'Bart')
We can use intermediate variables for more complex queries. Who is Bart's grandfather?
>>> y = var()
>>> run(1, x, parent(x, y),
parent(y, 'Bart'))
('Abe',)
We can express the grandfather relationship separately. In this example we use conde, a goal constructor for logical and and or.
>>> def grandparent(x, z):
... y = var()
... return conde((parent(x, y), parent(y, z)))
>>> run(1, x, grandparent(x, 'Bart'))
('Abe,')
Data Structures
kanren depends on functions, tuples, dicts, and generators. There are almost no new data structures/classes in kanren so it should be simple to integrate into preexisting code.
Extending kanren to other Types
kanren uses Multiple Dispatch and the unification library to support pattern matching on user defined types. Also see unification (wikipedia). Types which can be unified can be used for logic programming. See the project examples for how to extend the collection of unifiable types to your use case.
Install
With pip or easy_install
pip install kanren
From source
git clone git@github.com:logpy/logpy.git
cd logpy
python setup.py install
Run tests with tox
tox
Dependencies
kanren supports 3.5+.
It is pure Python and requires no dependencies beyond the standard
library, toolz,
multipledispatch, and
unification.
It is, in short, a light weight dependency.
Author
License
New BSD license. See LICENSE.txt
Motivation
Logic programming is a general programming paradigm. This implementation however came about specifically to serve as an algorithmic core for Computer Algebra Systems in Python and for the automated generation and optimization of numeric software. Domain specific languages, code generation, and compilers have recently been a hot topic in the Scientific Python community. kanren aims to be a low-level core for these projects.
References
- Logic Programming on wikipedia
- miniKanren, a Scheme library for relational programming on which this library is based. More information can be found in the thesis of William Byrd.
- core.logic a popular implementation of miniKanren in Clojure.
Metadata
Release files for kanren 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| kanren-0.3.0.tar.gz | 28.5 kB | Without provenance | Details for kanren-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| kanren-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for kanren-0.3.0-py3-none-any.whl |
Total release size: 46.4 kB
Release files / kanren-0.3.0.tar.gz
| Download URL | kanren-0.3.0.tar.gz |
|---|---|
| Size | 28.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c3b8b2c599dc5946b2ba63cf960aa74bb12421b80cbb68397ab5d00394539f0
|
|
BLAKE2b-256 checksum How to use checksums |
8cf00beacd82a099cf5d126c6af498add382da3a6fcd6d7e9ec894cb8c668df8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / kanren-0.3.0-py3-none-any.whl
| Download URL | kanren-0.3.0-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c811f34556a2cbce0c874613991be934932b61ab2b25770548952aff34e9781f
|
|
BLAKE2b-256 checksum How to use checksums |
e04b51286ddc63031b65441ccb2174050d66388b38851b452e300f1fdbfef3f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Security for kanren 0.3.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.