I am working on a project that is mainly based on logic programming. I have predifined related rules and facts that the program uses to calculate probabilities then these probabilities are appended to the data and fed into a further machine learning model. The program to calculate the probabilities can be easily defined in prolog as follows for example:
has_lot_work(daniel, 8). %number of lets say urgent tasks
has_lot_work(david, 3).
stress(X, P) :- has_lot_work(X, P2), P is P2 / 100.
to_smoke(X, Prob) :- stress(X, P1), friends(Y, X), influences(Y, X, P2), smokes(Y), Prob is P1 + P2.
to_have_asthma(X, 0.3) :- smokes(X). %30 percent of current smokers get asthma
to_have_asthma(X, Prob) :- to_smoke(X, P2), Prob is P2 * 0.25. %25 percent of smokers-to-be will get asthma
friends(X, Y) :- friend(X, Y).
friends(X, Y) :- friend(Y, X).
influences(X, Y, 0.4) :- friends(X, Y). %friends influence each other by 40 percent
friend(peter, david).
friend(peter, rebecca).
friend(daniel, rebecca).
smokes(peter).
smokes(rebecca).
In the example, I am interested in calculation the probability of someone to smoke (to_smoke(Who, Prob)) and to get asthma (to_have_asthma(Who, Prob)). I use python to get and clean the data and for the ML model afterwards, so I wanted to apply this logic in python as well. But couldn't find a way to do this logic calculations and I couldn't find a proper way to connect python with prolog without errors and problems.
I tried to develop something that uses prolog's syntax, approach and backtracking in python to solve the issue. I wrote pytholog library. I am sharing the answers to get comments and if there are better ways to do it.
In pytholog I initiate a knowledge base and I query it.
import pytholog as pl
friends_kb = pl.KnowledgeBase("friends")
friends_kb([
"has_lot_work(daniel, 8)",
"has_lot_work(david, 3)",
"stress(X, P) :- has_lot_work(X, P2), P is P2 / 100",
"to_smoke(X, Prob) :- stress(X, P1), friends(Y, X), influences(Y, X, P2), smokes(Y), Prob is P1 + P2",
"to_have_asthma(X, 0.3) :- smokes(X)",
"to_have_asthma(X, Prob) :- to_smoke(X, P2), Prob is P2 * 0.25",
"friends(X, Y) :- friend(X, Y)",
"friends(X, Y) :- friend(Y, X)",
"influences(X, Y, 0.4) :- friends(X, Y)",
"friend(peter, david)",
"friend(peter, rebecca)",
"friend(daniel, rebecca)",
"smokes(peter)",
"smokes(rebecca)"
])
print(friends_kb.query(pl.Expr("to_smoke(Who, P)")))
# [{'Who': 'daniel', 'P': 0.48000000000000004}, {'Who': 'david', 'P': 0.43000000000000005}]
print(friends_kb.query(pl.Expr("to_have_asthma(Who, P)")))
# [{'Who': 'peter', 'P': '0.3'}, {'Who': 'rebecca', 'P': '0.3'}, {'Who': 'daniel', 'P': 0.12000000000000001}, {'Who': 'david', 'P': 0.10750000000000001}]
You have a few choices but as AFAIK there is no built-in methods or predicates for Python so you need to access it as a library as such.
One popular way is to use miniKanren. I have not used this, but just looking at its syntax is enough to make me run away in horror.
Another approach is to find an interface between Python and Prolog and one popular one is between Python and SWI-Prolog, e.g pyswip. There are many of these so you will have to hunt and check to find which one works best for your needs. Again I have not used these.
If you do go with this choice to use a library to connect to SWI-Prolog, I do know that those questions pop up from time to time at the SWI-Prolog forum.
This is one I would chose as you get access to a full feature Prolog with cut, backtracking, tabling, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With