diff --git a/packages/CLPBN/clpbn.yap b/packages/CLPBN/clpbn.yap index 55458e9ff..2decbd55a 100644 --- a/packages/CLPBN/clpbn.yap +++ b/packages/CLPBN/clpbn.yap @@ -238,11 +238,19 @@ clpbn_marginalise(V, Dist) :- % called by top-level % or by call_residue/2 % -project_attributes(GVars, _AVars0) :- +project_attributes(GVars0, _AVars0) :- use_parfactors(on), clpbn_flag(solver, Solver), Solver \= fove, !, - generate_network(GVars, GKeys, Keys, Factors, Evidence), - call_ground_solver(Solver, GVars, GKeys, Keys, Factors, Evidence). + generate_network(GVars0, GKeys, Keys, Factors, Evidence), + b_setval(clpbn_query_variables, f(GVars0,Evidence)), + simplify_query(GVars0, GVars), + ( GKeys = [] + -> + GVars0 = [V|_], + clpbn_display:put_atts(V, [posterior([],[],[],[])]) + ; + call_ground_solver(Solver, GVars, GKeys, Keys, Factors, Evidence) + ). project_attributes(GVars, AVars) :- suppress_attribute_display(false), AVars = [_|_], @@ -262,6 +270,20 @@ project_attributes(GVars, AVars) :- ). project_attributes(_, _). +% +% check for query variables with evidence +% +simplify_query([V|GVars0], GVars) :- + get_atts(V, [evidence(_)]), !, + simplify_query(GVars0, GVars). +simplify_query([V|GVars0], GVars) :- + get_atts(V, [key(K)]), + pfl:evidence(K, _), !, + simplify_query(GVars0, GVars). +simplify_query([V|GVars0], [V|GVars]) :- + simplify_query(GVars0, GVars). +simplify_query([], []). + match([], _Keys). match([V|GVars], Keys) :- clpbn:get_atts(V,[key(GKey)]), @@ -279,13 +301,7 @@ get_clpbn_vars([V|GVars],[V|CLPBNGVars]) :- get_clpbn_vars(GVars,CLPBNGVars). get_clpbn_vars([_|GVars],CLPBNGVars) :- get_clpbn_vars(GVars,CLPBNGVars). - get_clpbn_vars([],[]). -get_clpbn_vars([V|GVars],[V|CLPBNGVars]) :- - get_atts(V, [key(_)]), !, - get_clpbn_vars(GVars,CLPBNGVars). -get_clpbn_vars([_|GVars],CLPBNGVars) :- - get_clpbn_vars(GVars,CLPBNGVars). simplify_query_vars(LVs0, LVs) :- sort(LVs0,LVs1), @@ -305,6 +321,7 @@ get_rid_of_ev_vars([V|LVs0],[V|LVs]) :- % do nothing if we don't have query variables to compute. +write_out(_, [], _, _) :- !. write_out(graphs, _, AVars, _) :- clpbn2graph(AVars). write_out(ve, GVars, AVars, DiffVars) :- @@ -651,21 +668,14 @@ variabilise_last([Arg], Arg, [V], V). variabilise_last([Arg1,Arg2|Args], Arg, Arg1.NArgs, V) :- variabilise_last(Arg2.Args, Arg, NArgs, V). -match_probability([], Goal, C, V, Prob) :- - /* there is evidence, so values are nil and V is bound */ - nonvar(V), !, - goal_to_key(Goal, Skolem), - pfl:skolem(Skolem, Domain), - member(C, Domain), - ( C == V -> Prob = 1.0 ; Prob = 0.0 ). match_probability(VPs, Goal, C, V, Prob) :- match_probabilities(VPs, Goal, C, V, Prob). match_probabilities([p(V0=C)=Prob|_], _, C, V, Prob) :- V0 == V, !. -match_probabilies([_|Probs], G, C, V, Prob) :- - match_probability(Probs, G, C, V, Prob). +match_probabilities([_|Probs], G, C, V, Prob) :- + match_probabilities(Probs, G, C, V, Prob). goal_to_key(_:Goal, Skolem) :- goal_to_key(Goal, Skolem). diff --git a/packages/CLPBN/clpbn/display.yap b/packages/CLPBN/clpbn/display.yap index 0e96a2e7b..b8c9575c6 100644 --- a/packages/CLPBN/clpbn/display.yap +++ b/packages/CLPBN/clpbn/display.yap @@ -10,6 +10,8 @@ :- use_module(library(clpbn), [use_parfactors/1]). +:- use_module(library(maplist)). + :- attribute posterior/4. @@ -21,15 +23,42 @@ attribute_goal(V, G) :- get_atts(V, [posterior(Vs,Vals,Ps,AllDiffs)]), massage_out(Vs, Vals, Ps, G, AllDiffs, V). -massage_out([], Ev, _, V=Ev, _, V) :- !. -massage_out(Vs, [D], [P], p(CEqs)=P, AllDiffs, _) :- !, +massage_out([], _Ev, _, Out, _, _V) :- !, + out_query_evidence(Out). +massage_out(Vs, [D], [P], O, AllDiffs, _) :- !, gen_eqs(Vs,D,Eqs), - add_alldiffs(AllDiffs,Eqs,CEqs). + add_alldiffs(AllDiffs,Eqs,CEqs), + out_query_evidence(Out), + ( Out = true -> O = (p(CEqs)=P) ; O = (p(CEqs)=P, Out) ). massage_out(Vs, [D|Ds], [P|Ps], (p(CEqs)=P,G) , AllDiffs, V) :- gen_eqs(Vs,D,Eqs), add_alldiffs(AllDiffs,Eqs,CEqs), massage_out(Vs, Ds, Ps, G, AllDiffs, V). +out_query_evidence(Out) :- + catch(b_getval(clpbn_query_variables, f(QVs,Evidence)), _, fail), !, + foldl( process_qv(Evidence), QVs, [], OL), + list_to_conj(OL, Out). +out_query_evidence(true). + +process_qv(Evidence, V, L0, LF) :- + clpbn:get_atts(V,[key(K)]), + member(K=Ev, Evidence), !, + pfl:skolem(K,Dom), + foldl2( add_goal(V,Ev), Dom, 0, _, L0, LF ). +process_qv(_Ev, _V, L, L). + +list_to_conj([], true). +list_to_conj([O], O) :- !. +list_to_conj([O|OL], (O,Out)) :- + list_to_conj(OL, Out). + +add_goal(V, Ev, DVal, Ev, I, L, [(p(V=DVal) = 1.0)|L]) :- !, + I is Ev+1. +add_goal(V, _Ev, DVal, I0, I, L, [(p(V=DVal) = 0.0)|L]) :- !, + I is I0+1. + + gen_eqs([V], [D], (V=D)) :- !. gen_eqs([V], D, (V=D)) :- !. gen_eqs([V|Vs], [D|Ds], ((V=D),Eqs)) :-