27
28:- module(scasp_comp_duals,
29 [ comp_duals/0,
30 comp_duals3/2,
31 define_forall/3
32 ]).
43:- use_module(library(lists)). 44:- use_module(common). 45:- use_module(program). 46:- use_module(variables). 47:- use_module(options). 48
49:- create_prolog_flag(scasp_plain_dual, false, []).
57:- det(comp_duals/0). 58
59comp_duals :-
60 debug(scasp(compile), 'Computing dual rules...', []),
61 defined_predicates(Preds),
62 maplist(comp_dual, Preds).
63
64scasp_builtin('call_1').
65scasp_builtin('findall_3').
71comp_dual('_false_0') :- 72 !.
73comp_dual(X) :-
74 scasp_builtin(X), 75 !.
76comp_dual(X) :-
77 findall(R, (defined_rule(X, H, B, _), c_rule(R, H, B)), Rs), 78 comp_duals3(X, Rs).
90:- det(comp_duals3/2). 91
92comp_duals3(P, []) :-
93 !, 94 predicate(H, P, []), 95 outer_dual_head(H, Hd),
96 c_rule(Rd, Hd, []),
97 assert_rule(dual(Rd)).
98comp_duals3(P, R) :- 99 predicate(H, P, []), 100 outer_dual_head(H, Hd),
101 comp_dual(Hd, R, Db, 1),
102 c_rule(Rd, Hd, Db),
103 assert_rule(dual(Rd)).
117comp_dual(_, [], [], _) :-
118 !.
119comp_dual(Hn, [X|T], [Dg|Db], C) :-
120 c_rule(X, H, B),
121 122 predicate(H, _, A1),
123 predicate(Hn, F, A2),
124 replace_prefix(F, n_, n__, F2), 125 create_unique_functor(F2, C, F3),
126 abstract_structures(A1, A3, 0, G),
127 append(G, B, B2),
128 prep_args(A3, A2, [], A4, [], 0, G2), 129 append(G2, B2, B3), 130 predicate(Dh, F3, A4), 131 body_vars(Dh, B2, Bv),
132 predicate(Dg, F3, A2), 133 comp_dual2(Dh, B3, Bv), 134 C2 is C + 1,
135 !,
136 comp_dual(Hn, T, Db, C2).
152comp_dual2(Hn, Bg, []) :-
153 !, 154 comp_dual3(Hn, Bg, []).
155comp_dual2(Hn, Bg, Bv) :-
156 Hn =.. [F|A1],
157 append(A1, Bv, A2),
158 length(A2, Arity),
159 split_functor(F, Base0, _), 160 atomic_list_concat([Base0, '_vh', Arity], Base),
161 join_functor(F2, Base, Arity),
162 Hn2 =.. [F2|A2], 163 define_forall(Hn2, G, Bv), 164 comp_dual3(Hn2, Bg, []), 165 c_rule(Rd, Hn, [G]), 166 assert_rule(dual(Rd)).
181comp_dual3(_, [], _) :-
182 !.
183comp_dual3(Hn, [X|T], U) :-
184 X = builtin_1(_), 185 !,
186 ( current_prolog_flag(scasp_plain_dual, true)
187 -> U2 = [X]
188 ; append(U, [X], U2)
189 ),
190 comp_dual3(Hn, T, U2).
191comp_dual3(Hn, [X|T], U) :-
192 dual_goal(X, X2),
193 ( current_prolog_flag(scasp_plain_dual, true)
194 -> Db = [X2]
195 ; append(U, [X2], Db) 196 ),
197 c_rule(Rd, Hn, Db), 198 assert_rule(dual(Rd)),
199 append(U, [X], U2),
200 comp_dual3(Hn, T, U2).
210dual_goal(#=(A, B), #<>(A,B)).
211dual_goal(#<>(A, B), #=(A,B)).
212dual_goal(#>(A, B), #=<(A,B)).
213dual_goal(#<(A, B), #>=(A,B)).
214dual_goal(#>=(A, B), #<(A,B)).
215dual_goal(#=<(A, B), #>(A,B)).
217dual_goal(#=(A, B), #<>(A,B)).
218dual_goal(#<>(A, B), #=(A,B)).
219dual_goal(#>(A, B), #=<(A,B)).
220dual_goal(#<(A, B), #>=(A,B)).
221dual_goal(#>=(A, B), #<(A,B)).
222dual_goal(#=<(A, B), #>(A,B)).
223
224dual_goal(=\=(A, B), =:=(A,B)).
225dual_goal(=:=(A, B), =\=(A,B)).
226dual_goal(<(A, B), >=(A,B)).
227dual_goal(>(A, B), =<(A,B)).
228dual_goal(=<(A, B), >(A,B)).
229dual_goal(>=(A, B), <(A,B)).
230dual_goal(@<(A, B), @>=(A,B)).
231dual_goal(@>(A, B), @=<(A,B)).
232dual_goal(@=<(A, B), @>(A,B)).
233dual_goal(@>=(A, B), @<(A,B)).
235dual_goal(=(A, B), \=(A,B)).
236dual_goal(\=(A, B), =(A,B)).
238dual_goal(is(A, B), not(is(A,B))). 239dual_goal(not(X), X) :-
240 predicate(X, _, _),
241 !.
242dual_goal(X, not(X)) :-
243 predicate(X, _, _),
244 !.
256define_forall(G, G, []) :-
257 !.
258define_forall(Gi, forall(X, G2), [X|T]) :-
259 define_forall(Gi, G2, T).
269outer_dual_head(H, D) :-
270 predicate(H, P, _Args),
271 negate_functor(P, Pd),
272 split_functor(Pd, _, A), 273 var_list(A, Ad), 274 predicate(D, Pd, Ad).
288abstract_structures([], [], _, []).
289abstract_structures([X|T], [$Y|T2], C, [G|Gt]) :-
290 compound(X),
291 \+ is_var(X),
292 !,
293 atom_concat('_Z', C, Y),
294 C1 is C + 1,
295 G = ($Y = X),
296 abstract_structures(T, T2, C1, Gt).
297abstract_structures([X|T], [X|T2], C, G) :-
298 abstract_structures(T, T2, C, G).
321:- det(prep_args/7). 322
323prep_args([], _, Ai, Ao, _, _, []) :-
324 reverse(Ai, Ao). 325prep_args([X|T], [Y|T2], Ai, Ao, Vs, C, [G|Gt]) :-
326 is_var(X),
327 memberchk(X, Vs), 328 !,
329 G = (Y=X), 330 prep_args(T, T2, [Y|Ai], Ao, Vs, C, Gt).
331prep_args([X|T], [_|T2], Ai, Ao, Vs, C, G) :-
332 is_var(X),
333 !,
334 prep_args(T, T2, [X|Ai], Ao, [X|Vs], C, G).
335prep_args([X|T], [Y|T2], Ai, Ao, Vs, C, Go) :-
336 X =.. [F|X2], 337 !,
338 prep_args2(X2, X3, Vs, Vs2, C, C2, Gs),
339 Xo =.. [F|X3],
340 G = (Y=Xo), 341 !,
342 prep_args(T, T2, [Y|Ai], Ao, Vs2, C2, Gt),
343 append([G|Gs], Gt, Go).
344prep_args([X|T], [Y|T2], Ai, Ao, Vs, C, [G|Gt]) :-
345 G = (Y=X), 346 prep_args(T, T2, [Y|Ai], Ao, Vs, C, Gt).
363:- det(prep_args2/7). 364
365prep_args2([], [], Vs, Vs, C, C, []).
366prep_args2([X|T], [Y|T2], Vsi, Vso, Ci, Co, [G|Gt]) :-
367 is_var(X),
368 !,
369 ( memberchk(X, Vsi) 370 -> Vs1 = Vsi
371 ; Vs1 = [X|Vsi]
372 ),
373 atom_concat('_Y', Ci, Y),
374 C1 is Ci + 1,
375 G = (Y=X), 376 prep_args2(T, T2, Vs1, Vso, C1, Co, Gt).
377prep_args2([X|T], [Y|T2], Vsi, Vso, Ci, Co, Go) :-
378 X =.. [F|X2], 379 !,
380 atom_concat('_Y', Ci, Y),
381 C1 is Ci + 1,
382 prep_args2(X2, X3, Vsi, Vs1, C1, C2, Gs),
383 Xo =.. [F|X3],
384 G = (Y=Xo), 385 prep_args2(T, T2, Vs1, Vso, C2, Co, Gt),
386 append([G|Gs], Gt, Go).
387prep_args2([X|T], [Y|T2], Vsi, Vso, Ci, Co, [G|Gt]) :-
388 389 atom_concat('_Y', Ci, Y),
390 C1 is Ci + 1,
391 G = (Y=X), 392 prep_args2(T, T2, Vsi, Vso, C1, Co, Gt)
Dual rule computation
Computation of dual rules (rules for the negation of a literal).