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 ]