27
28:- module(scasp_program,
29 [ defined_rule/4,
30 defined_query/2,
31 defined_predicates/1,
32 defined_nmr_check/1,
33 defined_directive/1,
34 reserved_prefix/1,
35 has_prefix/2,
36 replace_prefix/4, 37 non_printable/1, 38 assert_program/1,
39 assert_rule/1,
40 assert_nmr_check/1,
41 destroy_program/0
42 ]).
54:- use_module(library(lists)). 55:- use_module(library(apply)). 56:- use_module(library(debug)). 57
58:- use_module(common). 59:- use_module(variables).
99
100:- thread_local
101 defined_rule/4, 102 defined_query/2, 103 defined_predicates/1, 104 defined_nmr_check/1,
105 defined_directive/1.
117program(p(Rules, Directives, Query), Rules, Directives, Query).
131query(c(Q, Nmr_check, N), Q, Nmr_check, N).
147reserved_prefix('c'). 148reserved_prefix('n'). 149reserved_prefix('d').
160has_prefix(F, C) :-
161 sub_atom(F, 1, _, _, '_'),
162 sub_atom(F, 0, 1, _, C),
163 reserved_prefix(C).
167replace_prefix(F0, P0, P, F) :-
168 string_concat(P0, B, F0),
169 atom_concat(P, B, F).
176non_printable(Name) :-
177 sub_atom(Name, 0, _, _, '_'),
178 !.
179non_printable(Name) :-
180 sub_atom(Name, 1, _, _, '__'),
181 !.
204:- det(assert_program/1). 205
206assert_program(Stmts) :-
207 debug(scasp(compile), 'Converting program to internal format...', []),
208 format_program(Stmts, Program),
209 get_predicates(Program, Predicates),
210 assert_predicates(Predicates),
211 assert_program_struct(Program),
212 maplist(handle_classical_negation, Predicates).
225format_program([], P) :-
226 !, 227 predicate(G, '_false_0', []),
228 query(Q, [not(G)], _, 1),
229 program(P, [], [], Q).
230format_program(X, P) :-
231 predicate(G, '_false_0', []),
232 AScount = 1,
233 query(Q2, [not(G)], _, AScount),
234 sort_by_type(X, R, D, Q2, Q),
235 program(P, R, D, Q).
250:- det(sort_by_type/5). 251
252sort_by_type([source(Ref, X)|T], [source(Ref, X)|R], D, Ci, Co) :-
253 c_rule(X, _, _),
254 !,
255 sort_by_type(T, R, D, Ci, Co).
256sort_by_type([source(_, X)|T], R, D, _, Co) :-
257 X = c(N, Q),
258 query(C, Q, _, N),
259 !,
260 sort_by_type(T, R, D, C, Co).
261sort_by_type([source(_, (:-(Directive)))|T], R, [Directive|D], C, Co) :-
262 !,
263 sort_by_type(T, R, D, C, Co).
264sort_by_type([], [], [], C, C).
279:- det(rule_predicates/2). 280
281get_predicates(P, Ps) :-
282 program(P, R, _, Q),
283 query(Q, Qs, _, _),
284 rules_predicates(['_false_0'-Qs|R], Ps).
285
286rules_predicates(Rules, Preds) :-
287 maplist(rule_predicates, Rules, Preds0),
288 append(Preds0, Preds1),
289 list_to_set(Preds1, Preds).
290
291rule_predicates(source(_, R), Preds) :-
292 !,
293 rule_predicates(R, Preds).
294rule_predicates(R, Preds) :-
295 c_rule(R, H, B),
296 atom_predicate(H, F),
297 convlist(atom_predicate, B, FB),
298 list_to_set([F|FB], Preds).
299
300atom_predicate(not(X), P) :-
301 atom_predicate(X, P).
302atom_predicate(X, F) :-
303 predicate(X, F, _).
315handle_classical_negation(X) :-
316 has_prefix(X, 'c'), 317 atom_concat(c_, Xn, X), 318 defined_predicates(P),
319 memberchk(Xn, P), 320 !,
321 split_functor(X, _, N), 322 var_list(N, A), 323 X2 =.. [X|A],
324 Xn2 =.. [Xn|A],
325 predicate(H, '_false_0', []), 326 c_rule(R, H, [X2, Xn2]),
327 assert_rule(neg(R)).
328handle_classical_negation(_).
336assert_program_struct(P) :-
337 program(P, R, D, Q),
338 maplist(assert_rule, R),
339 maplist(assert_directive, D),
340 assert_query(Q).
348:- det(assert_rule/1). 349
350assert_rule(Rule) :-
351 rule_origin(Rule, Origin, R),
352 assert_rule_(R, Origin).
353
354assert_rule_(Rule, Origin) :-
355 c_rule(Rule, H2, B),
356 predicate(H2, H, _), 357 assertz(defined_rule(H, H2, B, Origin)).
358
359rule_origin(source(Ref, Rule), Ref, Rule).
360rule_origin(neg(Rule), generated(neg), Rule).
361rule_origin(nmr(Rule), generated(nmr), Rule).
362rule_origin(dual(Rule), generated(dual), Rule).
371assert_directive(D) :-
372 assertz(defined_directive(D)).
380assert_query(Q) :-
381 query(Q, Qs, _, N),
382 assertz(defined_query(Qs, N)).
390assert_nmr_check(NMR) :-
391 c_rule(R, '_nmr_check_0', NMR),
392 assert_rule(nmr(R)),
393 assertz(defined_nmr_check(['_nmr_check_0'])).
401assert_predicates(Ps) :-
402 assertz(defined_predicates(Ps)).
409destroy_program :-
410 retractall(defined_rule(_, _, _, _)),
411 retractall(defined_query(_, _)),
412 retractall(defined_predicates(_)),
413 retractall(defined_nmr_check(_)),
414 retractall(defined_directive(_))
Input program access
Allow access to input program rules and query by asserting them and exporting the resulting dynamic predicates.