PRISM

Sato’s PRISM is a Probabilistic Logic Programming system that shares its underlying semantics with ProbLog, but is different in that it (a) requires programs to satisfy certain modelling assumptions that allow for more efficient inference, (b) does not use stochastic memoization, and (c) requires special treatment for negation. On this page, we translate some examples included in the PRISM distribution to ProbLog.

Coins

% model part from the direction.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog, with arbitrary probabilities added 0.6::msw(coin,head); 0.4::msw(coin,tail). % ProbLog does not support if-then-else with ->, so we untangle direction(left) :- msw(coin,head). direction(right) :- msw(coin,tail). query(direction(_)).
% model part from the dcoin.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog % as coins are used repeatedly, ProbLog needs extra identifier 0.5::msw(coin(1),ID,head); 0.5::msw(coin(1),ID,tail). 0.7::msw(coin(2),ID,head); 0.3::msw(coin(2),ID,tail). dcoin(N,Rs) :- % Rs is a list with length N of outcomes dcoin(N,coin(1),Rs). % from two Bernoulli trials processes. dcoin(N,Coin,[R|Rs]) :- N > 0, msw(Coin,N,R), % replace N by some constant here to see the difference ( R == head, NextCoin = coin(2) ; R == tail, NextCoin = coin(1) ), N1 is N-1, dcoin(N1,NextCoin,Rs). dcoin(0,_,[]). query(dcoin(4,_)).
% model part from the agree.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog 0.8::msw(coin(a),heads); 0.2::msw(coin(a),tails). 0.1::msw(coin(b),heads); 0.9::msw(coin(b),tails). failure :- not(success). % failure is defined as not(success). success :- agree(_). % success <=> exist([X],agree(X)) agree(A):- % flip two coins and msw(coin(a),A), % output the result only when msw(coin(b),B), % both outcomes agree. A=B. query(msw(_,_)). evidence(success).

Bloodtype

% model part from the bloodABO.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog % in contrast to PRISM, ProbLog memoizes random variables, so we need to add an ID to this switch 0.5::msw(gene,ID,a); 0.2::msw(gene,ID,b); 0.3::msw(gene,ID,o). % ProbLog does not support if-then-else with ->, so we untangle % clauses 2 and 3 overlap with the first, but unlike PRISM ProbLog does not require them to be mutex bloodtype(X) :- genotype(X,X). bloodtype(Y) :- genotype(o,Y). bloodtype(X) :- genotype(X,o). bloodtype(ab) :- genotype(X,Y), X \= Y, X \= o, Y \= o. % tell ProbLog not to reuse X as Y by adding different extra arguments genotype(X,Y) :- msw(gene,1,X),msw(gene,2,Y). query(bloodtype(_)).
% model part from the bloodAaBb.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog, with arbitrary probabilities added 0.2::msw(locus1,'A'); 0.8::msw(locus1,a). 0.7::msw(locus2,'B'); 0.3::msw(locus2,b). % ProbLog does not support if-then-else with ->, so we untangle bloodtype(o) :- genotype(locus1,a,a), genotype(locus2,b,b). bloodtype(a) :- genotype(locus1,'A',_Y1), genotype(locus2,b,b). bloodtype(a) :- genotype(locus1,_,'A'), genotype(locus2,b,b). bloodtype(b) :- genotype(locus1,a,a), genotype(locus2,'B',_). bloodtype(b) :- genotype(locus1,a,a), genotype(locus2,_,'B'). bloodtype(ab) :- \+ bloodtype(o), \+ bloodtype(a), \+ bloodtype(b). genotype(L,X,Y) :- msw(L,X),msw(L,Y). query(bloodtype(_)).

Bayesian Network

% model part from the alarm.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog % switches defining CPTs 0.1::msw(fi,yes); 0.9::msw(fi,no). 0.15::msw(ta,yes); 0.85::msw(ta,no). 0.95::msw(sm(yes),yes); 0.05::msw(sm(yes),no). 0.05::msw(sm(no),yes); 0.95::msw(sm(no),no). 0.5::msw(al(yes,yes),yes); 0.5::msw(al(yes,yes),no). 0.9::msw(al(yes,no),yes); 0.1::msw(al(yes,no),no). 0.85::msw(al(no,yes),yes); 0.15::msw(al(no,yes),no). 0.05::msw(al(no,no),yes); 0.95::msw(al(no,no),no). 0.88::msw(le(yes),yes); 0.12::msw(le(yes),no). 0.01::msw(le(no),yes); 0.99::msw(le(no),no). 0.75::msw(re(yes),yes); 0.25::msw(re(yes),no). 0.1::msw(re(no),yes); 0.9::msw(re(no),no). % unchanged from PRISM world(Fi,Ta,Al,Sm,Le,Re) :- %% Define a distribution for world/5 such that e.g. %% P(Fire=yes,Tapering=yes,Smoke=no,Alarm=no,Leaving=no,Report=no) %% = P(world(yes,yes,no,no,no,no)) msw(fi,Fi), % P(Fire) msw(ta,Ta), % P(Tampering) msw(sm(Fi),Sm), % CPT P(Smoke | Fire) msw(al(Fi,Ta),Al), % CPT P(Alarm | Fire,Tampering) msw(le(Al),Le), % CPT P(Leaving | Alarm) msw(re(Le),Re). % CPT P(Report | Leaving) world(Sm,Re):- %% Define marginal distribution for `Smoke' and `Report' world(_,_,_,Sm,_,Re). query(world(_,_)).

HMM

% model part from the hmm.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog, with arbitrary probabilities added 0.5::msw(init,s0); 0.5::msw(init,s1). % state initialization % ProbLog needs extra argument to avoid reusing previous values 0.7::msw(out(X),Y,a); 0.3::msw(out(X),Y,b). % symbol emission 0.4::msw(tr(X),Y,s0); 0.6::msw(tr(X),Y,s1). % state transition hmm(L):- % To observe a string L: str_length(N), % Get the string length as N msw(init,S), % Choose an initial state randomly hmm(1,N,S,L). % Start stochastic transition (loop) % ProbLog does not support cut (!) to stop at basecase, so we add check to recursive clause instead hmm(T,N,_,[]):- T>N. % Stop the loop hmm(T,N,S,[Ob|Y]) :- % Loop: current state is S, current time is T T =< N, msw(out(S),T,Ob), % Output Ob at the state S using T to avoid reuse msw(tr(S),T,Next), % Transit from S to Next using T to avoid reuse T1 is T+1, % Count up time hmm(T1,N,Next,Y). % Go next (recursion) str_length(4). % String length query(hmm(_)).

German

% model part from the german.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog 0.2::msw(det,[m,nom,der]); 0.8::msw(det,[f,nom,die]). 0.6::msw(n,[m,nom,mann]); 0.4::msw(n,[f,nom,frau]). % in contrast to PRISM, ProbLog does not depend on compiling negation away, % and we therefore can directly use the parsing program to define failure failure :- not(success). % failure :- not(exist([X],np(X))). success :- np(_). np(L) :- np(L,[]). np(L1,L3):- det(Gen,Case,L1,L2), n(Gen,Case,L2,L3). det(Gen,Case,[Wd|L2],L2):- msw(det,R),R = [Gen,Case,Wd]. n(Gen,Case,[Wd|L3],L3):- msw(n,R), R = [Gen,Case,Wd]. query(np(_)). query(failure).

Constrained HMM (Dieting Professor)

% model part from the chmm.psm example in Sato's PRISM distribution http://rjida.meijo-u.ac.jp/prism/ % adapted to ProbLog % add time argument to avoid reuse 0.7::msw(tr(s0),T,s0); 0.3::msw(tr(s0),T,s1). 0.7::msw(tr(s1),T,s1); 0.3::msw(tr(s1),T,s0). 0.4::msw(lunch(s0),T,p) ; 0.6::msw(lunch(s0),T,s). % pizza:900, sandwich:400 0.5::msw(lunch(s1),T,h) ; 0.5::msw(lunch(s1),T,s). % hanburger:400, sandwich:500 failure:- not(success). success:- success(_). success(L):- chmm(L,s0,0,3). failure(L):- not(success(L)). chmm(L,S,C,N):- N>0, msw(tr(S),N,S2), msw(lunch(S),N,D), ( S == s0, ( D = p, C2 is C+900 ; D = s, C2 is C+400 ) ; S == s1, ( D = h, C2 is C+400 ; D = s, C2 is C+500 ) ), L=[D|L2], N2 is N-1, chmm(L2,S2,C2,N2). chmm([],_,C,0):- C < 2000. % given that the total number of calories in 3 days is below 2000, what was the choice of menu? query(success(_)). evidence(failure,false).