%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % four aProbLog example programs corresponding to the four inference settings, all using the ProbLog graph % (comment out all but one of the four cases to run) % $Id: aProbLog_examples.pl 6460 2011-07-27 14:09:46Z bernd $ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- use_module('../aproblog'). :- use_module(library(lists)). %%%% % shared background knowledge %%%% % definition of acyclic path using list of visited nodes path(X,Y) :- path(X,Y,[X],_). path(X,X,A,A). path(X,Y,A,R) :- X\==Y, edge(X,Z), absent(Z,A), path(Z,Y,[Z|A],R). % using directed edges in both directions edge(X,Y) :- dir_edge(Y,X). edge(X,Y) :- dir_edge(X,Y). % checking whether node hasn't been visited before absent(_,[]). absent(X,[Y|Z]):-X \= Y, absent(X,Z). %/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% case 1: disjoint & neutral sums, bottleneck semiring %%% % ?- aproblog_label(path(1,6),L). % L = 7 :- set_aproblog_flag(disjoint_sum,true). :- set_aproblog_flag(neutral_sum,true). semiring_zero(-inf). semiring_one(inf). label_negated(_W,N) :- semiring_one(N). semiring_addition(A,B,C) :- C is max(A, B). semiring_multiplication(A,B,C) :- C is min(A,B). 9::dir_edge(1,2). 8::dir_edge(2,3). 6::dir_edge(3,4). 7::dir_edge(1,6). 5::dir_edge(2,6). 4::dir_edge(6,5). 7::dir_edge(5,3). 2::dir_edge(5,4). %%% end case 1 %%% %*/ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% case 2: disjoint & non-neutral sums, most likely interpretation semiring %%% % ?- aproblog_label(path(1,6),L). % L = 0.0508032-[[e16],not[e54],[e53],not[e65],[e34],[e23],[e26],[e12]] :- set_aproblog_flag(disjoint_sum,true). :- set_aproblog_flag(neutral_sum,false). % fact labels of form prob-[variable] with a unique "variable" for each fact % "practical" approach % - resolves ties by taking first interpretation % - uses arbitrary list order instead of some canonical representation semiring_zero(0-[]). semiring_one(1-[]). label_negated(W-[A],WW-[not(A)]) :- WW is 1-W. semiring_addition(A-L,B-LL,C-LLL) :- C is max(A, B), ( C =:= A -> LLL = L ; LLL = LL ). semiring_multiplication(A-L,B-LL,C-LLL) :- C is A*B, append(L,LL,LLL). 0.9-[[e12]]::dir_edge(1,2). 0.8-[[e23]]::dir_edge(2,3). 0.6-[[e34]]::dir_edge(3,4). 0.7-[[e16]]::dir_edge(1,6). 0.5-[[e26]]::dir_edge(2,6). 0.4-[[e65]]::dir_edge(6,5). 0.7-[[e53]]::dir_edge(5,3). 0.2-[[e54]]::dir_edge(5,4). %%% end case 2 %%% */ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% case 3: non-disjoint & neutral sums, gradient semiring %%% % ?- aproblog_label(path(1,6),L). % L = (0.8667952,[0.185328,0.039744,0.00259200000000001,0.444016,0.2064096,0.079488,0.038016,0.00777600000000005]) :- set_aproblog_flag(disjoint_sum,false). :- set_aproblog_flag(neutral_sum,true). % vector version for parallel computation: first argument is probability, second argument is an ordered list of gradients w.r.t. the different facts (0/1) % as length varies, zero/one are still non-vector, thus different cases needed in definitions below semiring_zero((0,0)). semiring_one((1,0)). % inverting base cases and lists label_negated((P,0),(P2,0)) :- !, P2 is 1-P. label_negated((P,1),(P2,-1)) :- !, P2 is 1-P. label_negated((P,[]),(P2,[])) :- !, P2 is 1-P. label_negated((P,[0|R]),(P2,[0|R2])) :- !, label_negated((P,R),(P2,R2)). label_negated((P,[1|R]),(P2,[-1|R2])) :- label_negated((P,R),(P2,R2)). % addition is per element on lists % both are lists semiring_addition((A1,[FA|RA]),(B1,[FB|RB]),(C1,Res)) :- !, C1 is A1 + B1, sum_lists_per_el([FA|RA],[FB|RB],Res). % one is a neutral element semiring_addition((A1,[FA|RA]),(B1,B2),(C1,Res)) :- !, C1 is A1 + B1, sum_lists_per_el_constant([FA|RA],B2,Res). semiring_addition((A1,A2),(B1,[FB|RB]),(C1,Res)) :- !, C1 is A1 + B1, sum_lists_per_el_constant([FB|RB],A2,Res). % both are neutral elements semiring_addition((A1,A2),(B1,B2),(C1,C2)) :- C1 is A1 + B1, C2 is A2 + B2. sum_lists_per_el([],[],[]). sum_lists_per_el([F|R],[FF|RR],[FFF|RRR]) :- FFF is F+FF, sum_lists_per_el(R,RR,RRR). sum_lists_per_el_constant([],_,[]). sum_lists_per_el_constant([F|R],C,[FFF|RRR]) :- FFF is F+C, sum_lists_per_el_constant(R,C,RRR). % similar for multiplication, but need to pass on probabilities as well for product rule semiring_multiplication((A1,[FA|RA]),(B1,[FB|RB]),(C1,Res)) :- !, C1 is A1 * B1, mult_lists_per_el([FA|RA],[FB|RB],A1,B1,Res). semiring_multiplication((A1,[FA|RA]),(B1,B2),(C1,Res)) :- !, C1 is A1 * B1, mult_lists_per_el_constant([FA|RA],B2,A1,B1,Res). semiring_multiplication((A1,A2),(B1,[FB|RB]),(C1,Res)) :- !, C1 is A1 * B1, mult_lists_per_el_constant([FB|RB],A2,B1,A1,Res). semiring_multiplication((A1,A2),(B1,B2),(C1,C2)) :- C1 is A1*B1, C2 is A1*B2 + A2*B1. mult_lists_per_el([],[],_,_,[]). mult_lists_per_el([F|R],[FF|RR],P,PP,[FFF|RRR]) :- FFF is PP*F+FF*P, mult_lists_per_el(R,RR,P,PP,RRR). mult_lists_per_el_constant([],_,_,_,[]). mult_lists_per_el_constant([F|R],C,P,PP,[FFF|RRR]) :- FFF is F*PP+P*C, mult_lists_per_el_constant(R,C,P,PP,RRR). (0.9,[1,0,0,0,0,0,0,0])::dir_edge(1,2). (0.8,[0,1,0,0,0,0,0,0])::dir_edge(2,3). (0.6,[0,0,1,0,0,0,0,0])::dir_edge(3,4). (0.7,[0,0,0,1,0,0,0,0])::dir_edge(1,6). (0.5,[0,0,0,0,1,0,0,0])::dir_edge(2,6). (0.4,[0,0,0,0,0,1,0,0])::dir_edge(6,5). (0.7,[0,0,0,0,0,0,1,0])::dir_edge(5,3). (0.2,[0,0,0,0,0,0,0,1])::dir_edge(5,4). %%% end case 3 %%% */ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% case 4: non-disjoint & non-neutral sums, expectation semiring %%% % ?- aproblog_label(path(1,6),L). % L = (0.8667952,4.357428) :- set_aproblog_flag(disjoint_sum,false). :- set_aproblog_flag(neutral_sum,false). % fact labels are tuples of (probability, probability*value) % NB: this assumes that negative facts have value (and thus expected value) 0 semiring_zero((0,0)). semiring_one((1,0)). label_negated((P,_),(Q,0)) :- Q is 1-P. semiring_addition((A1,A2),(B1,B2),(C1,C2)) :- C1 is A1+B1, C2 is A2+B2. semiring_multiplication((A1,A2),(B1,B2),(C1,C2)) :- C1 is A1*B1, C2 is A1*B2+B1*A2. % positive edges have value 1 (0.9,0.9*1)::dir_edge(1,2). (0.8,0.8*1)::dir_edge(2,3). (0.6,0.6*1)::dir_edge(3,4). (0.7,0.7*1)::dir_edge(1,6). (0.5,0.5*1)::dir_edge(2,6). (0.4,0.4*1)::dir_edge(6,5). (0.7,0.7*1)::dir_edge(5,3). (0.2,0.2*1)::dir_edge(5,4). %%% end case 4 %%% */