Skip to main content

Relational programming in Python

Project description

kanren

Build Status Coverage Status PyPI

Logic/relational programming in Python with miniKanren.

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.

Examples

kanren enables one to express sophisticated relations—in the form of goals—and generate values that satisfy the relations. The following code is the "Hello, world!" of logic programming; it asks for values of the logic variable x such that x == 5:

>>> from kanren import run, eq, membero, var, lall
>>> x = var()
>>> run(1, x, eq(x, 5))
(5,)

Multiple logic variables and goals can be used simultaneously. The following code asks for one list containing the values of x and z such that x == z and z == 3:

>>> z = var()
>>> run(1, [x, z], eq(x, z),
                   eq(z, 3))
([3, 4],)

kanren uses unification to match forms within expression trees. The following code asks for values of x such that (1, 2) == (1, x):

>>> run(1, x, eq((1, 2), (1, x)))
(2,)

The above examples use eq: a goal constructor that creates a goal for unification between two objects. Other goal constructors, such as membero(item, coll), express more sophisticated relations and are often constructed from simpler ones like eq. More specifically, membero states that item is a member of the collection coll.

The following example uses membero to ask for all values of x, such that x is a member of (1, 2, 3) and x is a member of (2, 3, 4).

>>> run(0, 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)

The examples above made implicit use of the goal constructors lall and lany, which represent goal conjunction and disjunction, respectively. Many useful relations can be expressed with lall, lany, and eq alone, but in kanren it's also easy to leverage the host language and explicitly create any relation expressible in Python.

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. For instance, who is Bart's grandfather?

>>> grandparent_lv, parent_lv = var(), var()
>>> run(1, grandparent_lv, parent(grandparent_lv, parent_lv),
                           parent(parent_lv, 'Bart'))
('Abe',)

We can express the grandfather relationship as a distinct relation by creating a goal constructor:

>>> def grandparent(x, z):
...     y = var()
...     return lall(parent(x, y), parent(y, z))

>>> run(1, x, grandparent(x, 'Bart'))
('Abe,')

Constraints

kanren provides a fully functional constraint system that allows one to restrict unification and object types:

>>> from kanren.constraints import neq, isinstanceo

>>> run(0, x,
...     neq(x, 1),  # Not "equal" to 1
...     neq(x, 3),  # Not "equal" to 3
...     membero(x, (1, 2, 3)))
(2,)

>>> from numbers import Integral
>>> run(0, x,
...     isinstanceo(x, Integral),  # `x` must be of type `Integral`
...     membero(x, (1.1, 2, 3.2, 4)))
(2, 4)

Graph Relations

kanren comes with support for relational graph operations suitable for basic symbolic algebra operations. See the examples in doc/graphs.md.

Extending kanren

kanren uses multipledispatch and the logical-unification library to support pattern matching on user defined types. Essentially, types that can be unified can be used with most kanren goals. See the logical-unification project's examples for demonstrations of how arbitrary types can be made unifiable.

Installation

Using pip:

pip install miniKanren

To install from source:

git clone git@github.com:pythological/kanren.git
cd kanren
pip install -r requirements.txt

Tests can be run with the provided Makefile:

make check

About

This project is a fork of logpy.

References

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

miniKanren-0.4.0.tar.gz (40.1 kB view details)

Uploaded Source

Built Distribution

miniKanren-0.4.0-py3-none-any.whl (26.2 kB view details)

Uploaded Python 3

File details

Details for the file miniKanren-0.4.0.tar.gz.

File metadata

  • Download URL: miniKanren-0.4.0.tar.gz
  • Upload date:
  • Size: 40.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.1.0.post20200127 requests-toolbelt/0.9.1 tqdm/4.42.0 CPython/3.7.6

File hashes

Hashes for miniKanren-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d28d35e4f306a300b29bcbb8ec7259fa5dfbb6f0d8008a7080caae20c07257b6
MD5 1df8b4145842e9bcfe6123b4057b33fe
BLAKE2b-256 d58a5a15688c1dfa6124c21b17e6d0c8b9370cf022e981e15ca23a8412449572

See more details on using hashes here.

File details

Details for the file miniKanren-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: miniKanren-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 26.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.1.0.post20200127 requests-toolbelt/0.9.1 tqdm/4.42.0 CPython/3.7.6

File hashes

Hashes for miniKanren-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eed15a3becb32ef78d15212790749c07b2d1d343db1ba26fde3c5834d985749d
MD5 54120cd9ec66ae94767fdb7d6d76813d
BLAKE2b-256 e61efe305fa97f99170fb09c366e9f08e78fb985a6b5871625063dde05f50f4c

See more details on using hashes here.

Supported by

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