{{ message }}
/ logicpy Public

Prolog Implementation in Python

# evertheylen/logicpy

Switch branches/tags
Nothing to show

## Files

Failed to load latest commit information.
Type
Name
Commit time

# Prolog implementation in Python

Wanted: Better name

While following the course "Declarative Languages" at KULeuven I got inspired to make a Prolog implementation in Python, while relying on Python's parser. This is the result:

```from logicpy import *
u, n = Universe().and_namespace()

n.parent[_.alice, _.bob] = True
n.parent[_.alice, _.charlie] = True
n.sibling[_.A, _.B] = n.parent(_.X, _.A) & n.parent(_.X, _.B) & (_.A != _.B)

u.simple_query(n.sibling(_.X, _.Y))
# returns [{'X': Atom('bob'), 'Y': Atom('charlie')},
#          {'X': Atom('charlie'), 'Y': Atom('bob')}]```

There is also a kind of shell, which has some tricks so you can write your queries more naturally. Use it through `u.interactive()`:

``````? parent(alice, Child)
{Child = bob};
{Child = charlie};
?
``````

More examples can be found in the tests (`logicpy/tests.py`). There you will find more features:

• Evaluation of expressions (mainly math): I pulled a C++ for this and used the bitshift operators: `_.X << _.A * 2` will unify `X` with double of `A`, as long as `A` is instantiated.
• Cuts: Just use `cut`
• Comparisons: As you would expect.

## Why use it?

It has, obviously, perfect integration with Python. There are three main ways to integrate your functionality, which are best described using their return value.

### My function doesn't return anything useful, it only performs some work.

Use the `@runnable` decorator. Arguments given to your function will be evaluated. Used as a predicate, it will always succeed. Example:

``````@runnable

# Can be used as:
n.generate_intro[_.Name] = add_article("Intro " + _.Name, "Hello, I am " + _.Name + ", happy to be here.")
``````

### My function returns a Boolean

Use the `@provable` decorator. This works almost exactly like `@runnable`, but depending on the truthiness of the return value it will succeed or fail.

### My function returns some valuable result

Use the `@evaluated` decorator. Again, the arguments itself are evaluated. Example:

``````@evaluated
def max_(x, y):
return max(x, y)

# Can be used as:
Y << max_(X+5, 8)
``````

### Want more control? (Debugging, multiple results, ...)

Apart from those techniques, you can also subclass from `MonoArg` or `MultiArg` (or `Structure` if you really want), and implement the `prove(result, debugger)` method. Yield all results that you find ok. This gives you the most control, but requires more knowledge about the inner workings of this library.

## Why not use it?

I didn't add any metaprogramming, since this would logically be Python's job. There is no 'standard library'. There are still going to be a lot of bugs. This project contains more lines of Python than the total amount of lines of Prolog I have written in my life, so some things might behave unexpectedly (but I wouldn't know currently). It's more of a proof-of-concept.

However, the biggest disadvantage might be performance. It's pretty slow.

## How does it work?

• Lots of generators for a Prolog-like runtime (works pretty well, see the backtracking implementation in `logicpy/builtin.py`!)
• Some little hacky tricks to provide the interface (these are somewhat more brittle)

Prolog Implementation in Python

## Releases

No releases published

## Packages 0

No packages published