Relational/Logic Programming in Python?
Question:
I’m a longtime python developer and recently have been introduced to Prolog. I love the concept of using relationship rules for certain kinds of tasks, and would like to add this to my repertoire.
Are there any good libraries for logic programming in Python? I’ve done some searching on Google but only found the following:
jtauber’s blog series on relational_python
Would love to compare to some others…thanks!
-aj
Answers:
Perhaps you should google “Logic Programming in Python”. Pyke looks promising:
Pyke introduces a form of Logic Programming (inspired by Prolog) to
the Python community by providing a knowledge-based inference engine
(expert system) written in 100% Python.
Unlike Prolog, Pyke integrates with Python allowing you to invoke Pyke
from Python and intermingle Python statements and expressions within
your expert system rules.
You could also look at Dee, which adds relations to Python: http://www.quicksort.co.uk
A recent Prolog implementation in Python (or rather RPython) in
Pyrolog. It is still rather experimental.
Another option is Yield Prolog
You should also check PyLog:
It has a very clean and simple syntax and implementation.
LogPy is an implementation of miniKanren, a relational programming language, in Python. It follows in th tradition of core.logic
, the preeminent logic programming solution in Clojure. LogPy was designed for interoperability with pre-existing codebases.
As we are heading toward 2019, I recommend PySWIP over others recommended here. It is actively maintained and has an easy interface, unlike Pyke (9 years ago) or PyLog (6 years ago).
You can have a look at pytholog.
It is written in python totally with no interfaces with prolog and it mimics prolog’s syntax, approach and backtracking.
Simply initiate a KnowledgeBase and feed it with facts and rules then run queries.
import pytholog as pl
food_kb = pl.KnowledgeBase("food")
food_kb(["food_type(gouda, cheese)",
"food_type(ritz, cracker)",
"food_type(steak, meat)",
"food_type(sausage, meat)",
"food_type(limonade, juice)",
"food_type(cookie, dessert)",
"flavor(sweet, dessert)",
"flavor(savory, meat)",
"flavor(savory, cheese)",
"flavor(sweet, juice)",
"food_flavor(X, Y) :- food_type(X, Z), flavor(Y, Z)"])
print(food_kb.query(pl.Expr("food_flavor(What, sweet)")))
# [{'What': 'limonade'}, {'What': 'cookie'}]
print(food_kb.query(pl.Expr("flavor(sweet, dessert)")))
# ['Yes']
It also supports calculations and probabilities
battery_kb = pl.KnowledgeBase("battery")
battery_kb([
"battery(dead, P) :- voltmeter(battery_terminals, abnormal, P2), P is P2 + 0.5",
"battery(dead, P) :- electrical_problem(P), P >= 0.8",
"battery(dead, P) :- electrical_problem(P2), age(battery, old, P3), P is P2 * P3 * 0.9",
"electrical_problem(0.7)",
"age(battery, old, 0.8)",
"voltmeter(battery_terminals, abnormal, 0.3)"])
battery_kb.query(pl.Expr("battery(dead, Probability)"))
# [{'Probability': 0.8}, {'Probability': 'No'}, {'Probability': 0.504}]
It can also be used to find a path between nodes in graphs.
graph = pl.KnowledgeBase("graph")
graph([
"edge(a, b, 6)", "edge(a, c, 1)", "edge(b, e, 4)",
"edge(b, f, 3)", "edge(c, d, 3)", "edge(d, e, 8)",
"edge(e, f, 2)",
"path(X, Y, W) :- edge(X , Y, W)",
"path(X, Y, W) :- edge(X, Z, W1), path(Z, Y, W2), W is W1 + W2"])
answer, path = graph.query(pl.Expr("path(a, f, W)"), show_path = True)
print(answer)
# [{'W': 9}, {'W': 12}, {'W': 14}]
print([x for x in path if str(x) > "Z"])
# ['d', 'b', 'e', 'c']
answer, path = graph.query(pl.Expr("path(a, e, W)"), show_path = True, cut = True)
print(answer)
# [{'W': 10}]
print([x for x in path if str(x) > "Z"])
# ['b']
Another option is to use in-memory relational databases. After all, SQL is the most popular relational language, and it has a lot of similarity with Prolog.
I’m a longtime python developer and recently have been introduced to Prolog. I love the concept of using relationship rules for certain kinds of tasks, and would like to add this to my repertoire.
Are there any good libraries for logic programming in Python? I’ve done some searching on Google but only found the following:
jtauber’s blog series on relational_python
Would love to compare to some others…thanks!
-aj
Perhaps you should google “Logic Programming in Python”. Pyke looks promising:
Pyke introduces a form of Logic Programming (inspired by Prolog) to
the Python community by providing a knowledge-based inference engine
(expert system) written in 100% Python.Unlike Prolog, Pyke integrates with Python allowing you to invoke Pyke
from Python and intermingle Python statements and expressions within
your expert system rules.
You could also look at Dee, which adds relations to Python: http://www.quicksort.co.uk
A recent Prolog implementation in Python (or rather RPython) in
Pyrolog. It is still rather experimental.
Another option is Yield Prolog
You should also check PyLog:
It has a very clean and simple syntax and implementation.
LogPy is an implementation of miniKanren, a relational programming language, in Python. It follows in th tradition of core.logic
, the preeminent logic programming solution in Clojure. LogPy was designed for interoperability with pre-existing codebases.
As we are heading toward 2019, I recommend PySWIP over others recommended here. It is actively maintained and has an easy interface, unlike Pyke (9 years ago) or PyLog (6 years ago).
You can have a look at pytholog.
It is written in python totally with no interfaces with prolog and it mimics prolog’s syntax, approach and backtracking.
Simply initiate a KnowledgeBase and feed it with facts and rules then run queries.
import pytholog as pl
food_kb = pl.KnowledgeBase("food")
food_kb(["food_type(gouda, cheese)",
"food_type(ritz, cracker)",
"food_type(steak, meat)",
"food_type(sausage, meat)",
"food_type(limonade, juice)",
"food_type(cookie, dessert)",
"flavor(sweet, dessert)",
"flavor(savory, meat)",
"flavor(savory, cheese)",
"flavor(sweet, juice)",
"food_flavor(X, Y) :- food_type(X, Z), flavor(Y, Z)"])
print(food_kb.query(pl.Expr("food_flavor(What, sweet)")))
# [{'What': 'limonade'}, {'What': 'cookie'}]
print(food_kb.query(pl.Expr("flavor(sweet, dessert)")))
# ['Yes']
It also supports calculations and probabilities
battery_kb = pl.KnowledgeBase("battery")
battery_kb([
"battery(dead, P) :- voltmeter(battery_terminals, abnormal, P2), P is P2 + 0.5",
"battery(dead, P) :- electrical_problem(P), P >= 0.8",
"battery(dead, P) :- electrical_problem(P2), age(battery, old, P3), P is P2 * P3 * 0.9",
"electrical_problem(0.7)",
"age(battery, old, 0.8)",
"voltmeter(battery_terminals, abnormal, 0.3)"])
battery_kb.query(pl.Expr("battery(dead, Probability)"))
# [{'Probability': 0.8}, {'Probability': 'No'}, {'Probability': 0.504}]
It can also be used to find a path between nodes in graphs.
graph = pl.KnowledgeBase("graph")
graph([
"edge(a, b, 6)", "edge(a, c, 1)", "edge(b, e, 4)",
"edge(b, f, 3)", "edge(c, d, 3)", "edge(d, e, 8)",
"edge(e, f, 2)",
"path(X, Y, W) :- edge(X , Y, W)",
"path(X, Y, W) :- edge(X, Z, W1), path(Z, Y, W2), W is W1 + W2"])
answer, path = graph.query(pl.Expr("path(a, f, W)"), show_path = True)
print(answer)
# [{'W': 9}, {'W': 12}, {'W': 14}]
print([x for x in path if str(x) > "Z"])
# ['d', 'b', 'e', 'c']
answer, path = graph.query(pl.Expr("path(a, e, W)"), show_path = True, cut = True)
print(answer)
# [{'W': 10}]
print([x for x in path if str(x) > "Z"])
# ['b']
Another option is to use in-memory relational databases. After all, SQL is the most popular relational language, and it has a lot of similarity with Prolog.