/usr/share/Yap/problog/grounder.yap is in yap 6.2.2-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | %%% -*- Mode: Prolog; -*-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% $Date: 2011-11-28 14:41:26 +0100 (Mon, 28 Nov 2011) $
% $Revision: 6764 $
%
% Main author of this file:
% Bernd Gutmann
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
:- module(grounder, [grounder_reset/0,
grounder_compute_reachable_atoms/3,
grounder_reachable_atom/1,
grounder_ground_term_with_reachable_atoms/2,
grounder_completion_for_atom/3
]).
:- style_check(all).
:- yap_flag(unknown,error).
:- use_module('../problog',[probabilistic_fact/3]).
:- use_module(termhandling).
%========================================================================
%=
%========================================================================
:- multifile user:myclause/3.
user:myclause(_InterpretationID,Head,Body) :-
current_predicate(user:myclause/2),
user:myclause(Head,Body).
%========================================================================
%= reset the internal state, that is, forget all reachable atoms
%========================================================================
grounder_reset :-
eraseall(reachable).
%========================================================================
%= grounder_reachable_atom(-Atom)
%========================================================================
grounder_reachable_atom(Atom) :-
recorded(reachable,Atom,_Key).
%========================================================================
%= grounder_compute_reachable_atoms(+A,+ID,-Success)
%= A is a ground atom
%= ID is an interpretation ID
%= Success is "true" if there is a proof for A, otherwise "false"
%=
%= The predicate always succeeds exactly once
%=
%= This is basically a vanilla meta-interpreter, that follows all
%= paths in the SLD tree and records which atoms can be reached
%= while proving A.
%= the only "speciality" is that the negation of a probilistic
%= fact always succeeds
%=
%= the reachable atoms are stored in the internal database
%= under the key "reachable"
%========================================================================
grounder_compute_reachable_atoms(A,ID,Success) :-
bb_put(dep_proven,false),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
( % go over all proofs for A in interpretation ID
tabled_meta_interpreter(A,ID),
bb_put(dep_proven,true),
fail; % go to next proof
true
),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bb_delete(dep_proven,Success).
%========================================================================
%= tabled_meta_interpreter(+E, +ID)
%= E is a valid Prolog expression
%= ID is an interpretation ID
%=
%= the predicate succeeds if there is a proof for E
%= upon backtracking all possible proofs are generated
%= the atoms visited while proving E are added to the internal database
%= using the key "reachable"
%=
%= if a ground atom is revisited, it is not proven again
%========================================================================
tabled_meta_interpreter((X,Y),ID) :-
!,
tabled_meta_interpreter(X,ID),
tabled_meta_interpreter(Y,ID).
tabled_meta_interpreter((X;Y),ID) :-
!,
(
tabled_meta_interpreter(X,ID);
tabled_meta_interpreter(Y,ID)
).
tabled_meta_interpreter(\+ X,ID) :-
!,
(
probabilistic_fact(_, X, _)
->
tabled_meta_interpreter(X,ID) % prob. facts can be true/false
;
\+ tabled_meta_interpreter(X,ID)
).
tabled_meta_interpreter(X,_) :-
predicate_property(X,built_in),
!,
call(X).
tabled_meta_interpreter( Atom,ID ) :-
ground(Atom),
!,
(
recorded(reachable,Atom,_) % did we see this atom before?
->
true % nothing to do
;
% nope, we have to continue proving
recorda(reachable,Atom,_),
tabled_meta_interpreter_aux_ground_atom(Atom,ID)
).
tabled_meta_interpreter(Atom,ID) :-
% at this point we know, Atom is non-ground
% hence we need to be carefull not to ignore any path in the SLD tree
%
% we can ignore probabilistic facts and only look for myclauses
% since in ProbLog the requirement is that non-ground facts have to be
% ground at query time
current_predicate(user:myclause/3),
user:myclause(ID,Atom,Body),
tabled_meta_interpreter(Body,ID),
% check whether Atom got grounded now,
% if not, complain and give up
(
ground(Atom)
->
recorda(reachable,Atom,_)
;
format(user_error,'Error at running the meta interpreter.~n',[]),
format(user_error,'The clauses defined by myclause/2 have to be written in a way such that~n',[]),
format(user_error,'each atom in the body of a clause gets fully grounded when it is called.~n',[]),
format(user_error,' This is not the case for the atom ~w~3n',[Atom]),
throw(meta_interpreter_error(Atom))
).
% note, that on backtracking all alternative proofs will
% be followed as well
%========================================================================
%= tabled_meta_interpreter_aux_ground_atom(+E, +ID)
%= E is a valid Prolog expression
%= ID is an interpretation ID
%=
%= the predicate succeeds if there is a proof for E
%= upon backtracking all possible proofs are generated
%= the atoms visited while proving E are added to the internal database
%= using the key "reachable"
%=
%= if a ground atom is revisited, it is not proven again
%=
%= DON'T call this predicate directly, it is a helper predicate for
%= tabled_meta_interpreter/2
%========================================================================
tabled_meta_interpreter_aux_ground_atom(Atom,_ID) :-
probabilistic_fact(_, Atom, _),
!.
% probabilistic facts and background knowledge must not have
% an atom in common. hence we can savely put that cut above.
tabled_meta_interpreter_aux_ground_atom(Atom,ID) :-
current_predicate(user:myclause/3),
user:myclause(ID,Atom,Body),
% find a suitable clause and continue proving
% on backtracking we will try all suitable clauses
tabled_meta_interpreter(Body,ID).
%========================================================================
%= grounder_ground_term_with_reachable_atoms(+T1,-T2)
%= T1 is a (possible non-ground) term
%= T2 is ground term
%=
%= generates on backtracking all possible ground instances of T1
%= where atoms are grounded with reachable atoms that have
%= been found before by grounder_compute_reachable_atoms/3
%========================================================================
grounder_ground_term_with_reachable_atoms( (X,Y), (X2,Y2)) :-
!,
grounder_ground_term_with_reachable_atoms(X,X2),
grounder_ground_term_with_reachable_atoms(Y,Y2).
grounder_ground_term_with_reachable_atoms( (X;Y), (X2;Y2)) :-
!,
grounder_ground_term_with_reachable_atoms(X,X2),
grounder_ground_term_with_reachable_atoms(Y,Y2).
grounder_ground_term_with_reachable_atoms( \+X, \+X2) :-
!,
grounder_ground_term_with_reachable_atoms(X,X2).
grounder_ground_term_with_reachable_atoms( false, false) :-
!.
grounder_ground_term_with_reachable_atoms(X, true) :-
predicate_property(X,built_in),
!,
call(X).
grounder_ground_term_with_reachable_atoms(X,'$atom'(X)) :-
!,
recorded(reachable,X,_).
%========================================================================
%= grounder_completion_for_atom(+A,+ID,-X)
%= A is
%= X is
%= ID is
%=
%=
%=
%=
%========================================================================
grounder_completion_for_atom(Head,InterpretationID,'$atom'(Head)<=>Disjunction) :-
% find all clauses
findall(Body2,(
user:myclause(InterpretationID,Head,Body),
grounder_ground_term_with_reachable_atoms(Body,Body2)
),Bodies),
Bodies\==[],
list_to_disjunction(Bodies,Disjunction).
|