1:- module(scasp_stack,
2 [ justification_tree/3, 3 print_justification_tree/1, 4 print_justification_tree/2, 5 unqualify_justitication_tree/3 6 ]). 7:- use_module(predicates). 8:- use_module(common). 9:- use_module(modules). 10:- use_module(output). 11
12:- autoload(library(apply), [maplist/3]). 13:- autoload(library(lists), [reverse/2, append/3]). 14:- autoload(library(option),
15 [option/2, merge_options/3, option/3, select_option/3]). 16
17:- meta_predicate
18 justification_tree(:, -, +),
19 print_justification_tree(:),
20 print_justification_tree(:, +). 21
22:- multifile
23 justification_tree_hook/2. 24
55
56:- det(justification_tree/3). 57
58justification_tree(M:Stack, M:JustificationTree, Options) :-
59 reverse(Stack, RevStack),
60 stack_tree([query|RevStack], Trees),
61 filter_tree(Trees, M, [JustificationTree], Options).
62
75
76stack_tree(Stack, Tree) :-
77 stack_tree(Stack, Tree, [], []).
78
79stack_tree([], Children0, Children, []) =>
80 Children = Children0.
81stack_tree([[]|Stack], Children0, Children, [T0/T|Parents]) =>
82 Children = Children0,
83 stack_tree(Stack, T0, T, Parents).
84stack_tree([H|Stack], Tree, T, Parents) =>
85 Tree = [H-Children|T0],
86 stack_tree(Stack, Children, [], [T0/T|Parents]).
87
88
97
98filter_tree([],_,[], _) :- !.
99filter_tree([goal_origin(_,_)-[_,goal_origin(Abd, O)-_]|Cs],
100 M,
101 [goal_origin(abduced(Atom), O)-[]|Fs], Options) :-
102 abduction_justification(Abd, Atom),
103 !,
104 filter_tree(Cs, M, Fs, Options).
105filter_tree([proved(Abd)-[]|Cs],
106 M,
107 [proved(Atom)-[]|Fs], Options) :-
108 abduction_justification(Abd, Atom),
109 !,
110 filter_tree(Cs, M, Fs, Options).
111filter_tree([goal_origin(Term0,O)-Children|Cs], M, Tree, Options) :-
112 filter_pos(Term0, Options),
113 raise_negation(Term0, Term),
114 selected(Term, M), !,
115 filter_tree(Children, M, FChildren, Options),
116 Tree = [goal_origin(Term, O)-FChildren|Fs],
117 filter_tree(Cs, M, Fs, Options).
118filter_tree([Term0-Children|Cs], M, Tree, Options) :-
119 filter_pos(Term0, Options),
120 raise_negation(Term0, Term),
121 selected(Term, M), !,
122 filter_tree(Children, M, FChildren, Options),
123 ( Term == o_nmr_check, FChildren == []
124 -> Tree = Fs
125 ; Tree = [Term-FChildren|Fs]
126 ),
127 filter_tree(Cs, M, Fs, Options).
128filter_tree([_-Childs|Cs], M, FilterChildren, Options) :-
129 append(Childs, Cs, AllCs),
130 filter_tree(AllCs, M, FilterChildren, Options).
131
136
137filter_pos(not(GC), _Options), is_global_constraint(GC) =>
138 true.
139filter_pos(not(_), Options) =>
140 \+ option(pos(true), Options).
141filter_pos(_, _) =>
142 true.
143
144selected(query, _) => true.
145selected(proved(_), _) => true.
146selected(chs(_), _) => true.
147selected(assume(_), _) => true.
148selected(not(-Goal), _) =>
149 \+ aux_predicate(Goal).
150selected(not(Goal), _) =>
151 \+ aux_predicate(Goal).
152selected(-(Goal), M) =>
153 selected(Goal, M).
154selected(findall(_,_,_), _) => true.
155selected(is(_,_), _) => true.
156selected(_>_, _) => true.
157selected(_>=_, _) => true.
158selected(_<_, _) => true.
159selected(_=<_, _) => true.
160selected(Goal, M) =>
161 ( aux_predicate(Goal)
162 -> fail
163 ; ( current_predicate(M:pr_user_predicate/1)
164 -> user_predicate(M:Goal)
165 ; true
166 )
167 -> true
168 ; is_global_constraint(Goal)
169 ).
170
171aux_predicate(-(o_,_)) :- !. 172aux_predicate(A) :-
173 functor(A, Name, _Arity),
174 sub_atom(Name, 0, _, _, o_),
175 \+ is_global_constraint(Name).
176
177is_global_constraint(o_nmr_check) :-
178 !.
179is_global_constraint(Atom) :-
180 atom(Atom),
181 atom_concat(o_chk_, NA, Atom),
182 atom_number(NA, _).
183
184
185abduction_justification(Abd, Atom) :-
186 Abd =.. [F, Atom],
187 abduction_justification_(F).
188
189abduction_justification_(F) :-
190 sub_atom(F, _, _, 0, 'abducible$'),
191 !.
192abduction_justification_(abducible).
193
194
211
212print_justification_tree(Tree) :-
213 print_justification_tree(Tree, []).
214
215:- det(print_justification_tree/2). 216
217print_justification_tree(Tree, Options) :-
218 justification_tree_hook(Tree, Options),
219 !.
220print_justification_tree(M:Tree, Options) :-
221 merge_options(Options, [depth(0),module(M)], Options1),
222 plain_output(Tree, Options1),
223 ( option(full_stop(true), Options, true)
224 -> format(".~n", [])
225 ; true
226 ).
227
229
230plain_output(goal_origin(Term, _)-Children, Options) :-
231 !,
232 plain_output(Term-Children, Options).
233plain_output(Term-[], Options) :-
234 !,
235 option(depth(D), Options),
236 Indent is D*3,
237 nl_indent(Indent),
238 term(Term, Options).
239plain_output(Term-Children, Options) :-
240 !,
241 select_option(depth(D), Options, Options1),
242 option(indent(Width), Options1, 3),
243 Indent is D*Width,
244 connector(implies, Conn, Options),
245 nl_indent(Indent), term(Term, Options), format(" ~w",[Conn]),
246 D1 is D+1,
247 plain_output_children(Children, [depth(D1)|Options1]).
248
249nl_indent(Indent) :-
250 format('~N~t~*|', [Indent]).
251
252plain_output_children([A,B|Rs], Options) :-
253 !,
254 plain_output(A, Options),
255 connector(and, Conn, Options),
256 format("~w",[Conn]),
257 plain_output_children([B|Rs], Options).
258plain_output_children([A], Options) :-
259 !,
260 plain_output(A, Options).
261
265
266term(proved(Term), Options) =>
267 term1(proved, Term, Options).
268term(assume(Term), Options) =>
269 term1(assume, Term, Options).
270term(chs(Term), Options) =>
271 term1(chs, Term, Options).
272term(Term, Options) =>
273 print_model_term(Term, Options).
274
275term1(Functor, Arg, Options) :-
276 print_connector(Functor, Options),
277 format('(', []),
278 print_model_term(Arg, Options),
279 format(')', []).
280
285
286:- det(unqualify_justitication_tree/3). 287
288unqualify_justitication_tree(_:Tree0, Module, Tree) :-
289 is_list(Tree0),
290 !,
291 maplist(unqualify_just(Module), Tree0, Tree).
292unqualify_justitication_tree(_:Tree0, Module, Tree) :-
293 unqualify_just(Module, Tree0, Tree).
294
295unqualify_just(M, Node0-Children0, Node-Children) :-
296 unqualify_model_term(M, Node0, Node),
297 maplist(unqualify_just(M), Children0, Children)