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(library(debug)). 45:- use_module(common). 46:- use_module(program). 47:- use_module(variables). 48:- use_module(options). 49
50:- create_prolog_flag(scasp_plain_dual, false, []).
58:- det(comp_duals/0). 59
60comp_duals :-
61 debug(scasp(compile), 'Computing dual rules...', []),
62 defined_predicates(Preds),
63 maplist(comp_dual, Preds).
64
65scasp_builtin('call_1').
66scasp_builtin('findall_3').
67scasp_builtin('inf_2').
68scasp_builtin('sup_2').
74comp_dual('_false_0') :- 75 !.
76comp_dual(X) :-
77 scasp_builtin(X), 78 !.
79comp_dual(X) :-
80 findall(R, (defined_rule(X, H, B, _), c_rule(R, H, B)), Rs), 81 comp_duals3(X, Rs).
93:- det(comp_duals3/2). 94
95comp_duals3(P, []) :-
96 !, 97 predicate(H, P, []), 98 outer_dual_head(H, Hd),
99 c_rule(Rd, Hd, []),
100 assert_rule(dual(Rd)).
101comp_duals3(P, R) :- 102 predicate(H, P, []), 103 outer_dual_head(H, Hd),
104 comp_dual(Hd, R, Db, 1),
105 c_rule(Rd, Hd, Db),
106 assert_rule(dual(Rd)).
120comp_dual(_, [], [], _) :-
121 !.
122comp_dual(Hn, [X|T], [Dg|Db], C) :-
123 c_rule(X, H, B),
124 125 predicate(H, _, A1),
126 predicate(Hn, F, A2),
127 replace_prefix(F, n_, n__, F2), 128 create_unique_functor(F2, C, F3),
129 abstract_structures(A1, A3, 0, G),
130 append(G, B, B2),
131 prep_args(A3, A2, [], A4, [], 0, G2), 132 append(G2, B2, B3), 133 predicate(Dh, F3, A4), 134 body_vars(Dh, B2, Bv),
135 predicate(Dg, F3, A2), 136 comp_dual2(Dh, B3, Bv), 137 C2 is C + 1,
138 !,
139 comp_dual(Hn, T, Db, C2).
155comp_dual2(Hn, Bg, []) :-
156 !, 157 comp_dual3(Hn, Bg, []).
158comp_dual2(Hn, Bg, Bv) :-
159 Hn =.. [F|A1],
160 append(A1, Bv, A2),
161 length(A2, Arity),
162 split_functor(F, Base0, _), 163 atomic_list_concat([Base0, '_vh', Arity], Base),
164 join_functor(F2, Base, Arity),
165 Hn2 =.. [F2|A2], 166 define_forall(Hn2, G, Bv), 167 comp_dual3(Hn2, Bg, []), 168 c_rule(Rd, Hn, [G]), 169 assert_rule(dual(Rd)).
184comp_dual3(_, [], _) :-
185 !.
186comp_dual3(Hn, [X|T], U) :-
187 X = builtin_1(_), 188 !,
189 ( current_prolog_flag(scasp_plain_dual, true)
190 -> U2 = [X]
191 ; append(U, [X], U2)
192 ),
193 comp_dual3(Hn, T, U2).
194comp_dual3(Hn, [X|T], U) :-
195 dual_goal(X, X2),
196 ( current_prolog_flag(scasp_plain_dual, true)
197 -> Db = [X2]
198 ; append(U, [X2], Db) 199 ),
200 c_rule(Rd, Hn, Db), 201 assert_rule(dual(Rd)),
202 append(U, [X], U2),
203 comp_dual3(Hn, T, U2).
213dual_goal(#=(A, B), #<>(A,B)).
214dual_goal(#<>(A, B), #=(A,B)).
215dual_goal(#>(A, B), #=<(A,B)).
216dual_goal(#<(A, B), #>=(A,B)).
217dual_goal(#>=(A, B), #<(A,B)).
218dual_goal(#=<(A, B), #>(A,B)).
220dual_goal(#=(A, B), #<>(A,B)).
221dual_goal(#<>(A, B), #=(A,B)).
222dual_goal(#>(A, B), #=<(A,B)).
223dual_goal(#<(A, B), #>=(A,B)).
224dual_goal(#>=(A, B), #<(A,B)).
225dual_goal(#=<(A, B), #>(A,B)).
226
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)).
234dual_goal(@>(A, B), @=<(A,B)).
235dual_goal(@=<(A, B), @>(A,B)).
236dual_goal(@>=(A, B), @<(A,B)).
238dual_goal(=(A, B), \=(A,B)).
239dual_goal(\=(A, B), =(A,B)).
241dual_goal(is(A, B), not(is(A,B))). 242dual_goal(not(X), X) :-
243 predicate(X, _, _),
244 !.
245dual_goal(X, not(X)) :-
246 predicate(X, _, _),
247 !.
259define_forall(G, G, []) :-
260 !.
261define_forall(Gi, forall(X, G2), [X|T]) :-
262 define_forall(Gi, G2, T).
272outer_dual_head(H, D) :-
273 predicate(H, P, _Args),
274 negate_functor(P, Pd),
275 split_functor(Pd, _, A), 276 var_list(A, Ad), 277 predicate(D, Pd, Ad).
291abstract_structures([], [], _, []).
292abstract_structures([X|T], [$Y|T2], C, [G|Gt]) :-
293 compound(X),
294 \+ is_var(X),
295 !,
296 atom_concat('_Z', C, Y),
297 C1 is C + 1,
298 G = ($Y = X),
299 abstract_structures(T, T2, C1, Gt).
300abstract_structures([X|T], [X|T2], C, G) :-
301 abstract_structures(T, T2, C, G).
324:- det(prep_args/7). 325
326prep_args([], _, Ai, Ao, _, _, []) :-
327 reverse(Ai, Ao). 328prep_args([X|T], [Y|T2], Ai, Ao, Vs, C, [G|Gt]) :-
329 is_var(X),
330 memberchk(X, Vs), 331 !,
332 G = (Y=X), 333 prep_args(T, T2, [Y|Ai], Ao, Vs, C, Gt).
334prep_args([X|T], [_|T2], Ai, Ao, Vs, C, G) :-
335 is_var(X),
336 !,
337 prep_args(T, T2, [X|Ai], Ao, [X|Vs], C, G).
338prep_args([X|T], [Y|T2], Ai, Ao, Vs, C, Go) :-
339 X =.. [F|X2], 340 !,
341 prep_args2(X2, X3, Vs, Vs2, C, C2, Gs),
342 Xo =.. [F|X3],
343 G = (Y=Xo), 344 !,
345 prep_args(T, T2, [Y|Ai], Ao, Vs2, C2, Gt),
346 append([G|Gs], Gt, Go).
347prep_args([X|T], [Y|T2], Ai, Ao, Vs, C, [G|Gt]) :-
348 G = (Y=X), 349 prep_args(T, T2, [Y|Ai], Ao, Vs, C, Gt).
366:- det(prep_args2/7). 367
368prep_args2([], [], Vs, Vs, C, C, []).
369prep_args2([X|T], [Y|T2], Vsi, Vso, Ci, Co, [G|Gt]) :-
370 is_var(X),
371 !,
372 ( memberchk(X, Vsi) 373 -> Vs1 = Vsi
374 ; Vs1 = [X|Vsi]
375 ),
376 atom_concat('_Y', Ci, Y),
377 C1 is Ci + 1,
378 G = (Y=X), 379 prep_args2(T, T2, Vs1, Vso, C1, Co, Gt).
380prep_args2([X|T], [Y|T2], Vsi, Vso, Ci, Co, Go) :-
381 X =.. [F|X2], 382 !,
383 atom_concat('_Y', Ci, Y),
384 C1 is Ci + 1,
385 prep_args2(X2, X3, Vsi, Vs1, C1, C2, Gs),
386 Xo =.. [F|X3],
387 G = (Y=Xo), 388 prep_args2(T, T2, Vs1, Vso, C2, Co, Gt),
389 append([G|Gs], Gt, Go).
390prep_args2([X|T], [Y|T2], Vsi, Vso, Ci, Co, [G|Gt]) :-
391 392 atom_concat('_Y', Ci, Y),
393 C1 is Ci + 1,
394 G = (Y=X), 395 prep_args2(T, T2, Vsi, Vso, C1, Co, Gt)
Dual rule computation
Computation of dual rules (rules for the negation of a literal).