Reputation: 31850
I'm using clause/2
to transform some Prolog clauses in a compiler. I need to replace the head of each clause with its body, but clause/2
sometimes doesn't expand the clause in the way that it was originally written.
Here, clause/2
expands demo(A,B)
to \+ (call(A),\+call(B))
, instead of expanding its original definition:
:- use_module(prolog_to_minizinc).
:- initialization(main).
main :-
writeln(forall(A,B)),
clause(demo(A,B),Clause),
writeln(Clause).
demo(A,B) :-
forall(A,B).
Is there another way to expand clauses, without modifying clauses that include forall/2
?
Upvotes: 1
Views: 121
Reputation: 18683
The unwanted expansion of the forall/2
goal is due to SWI-Prolog loading library(apply_macros)
at startup. This library provides the expansion code for forall/2
and other predicates. Finding how library(apply_macros)
is loaded is not trivial as setting the verbose_autoload
flag to true
in the ~/.config/swi-prolog/init.pl
file doesn't print all libraries that are being auto-loaded at startup. On my laptop, using the current devel git version of SWI-Prolog (8.1.21-82-ge6e1d5376-DIRTY
):
?- current_module(apply_macros).
true.
?- module_property(apply_macros, P).
P = class(library) ;
P = file('/Users/pmoura/lib/swipl/library/apply_macros.pl') ;
P = line_count(36) ;
P = exports([expand_phrase/2, expand_phrase/4]) .
?- source_file_property('/Users/pmoura/lib/swipl/library/apply_macros.pl', P).
P = modified(1547476368.0) ;
P = source(file) ;
P = module(apply_macros) ;
P = load_context(nb_set, '/Users/pmoura/lib/swipl/library/nb_set.pl':45, [imports([])]) ;
P = load_count(1) ;
P = number_of_clauses(52).
?- source_file_property('/Users/pmoura/lib/swipl/library/nb_set.pl', P).
P = modified(1547476368.0) ;
P = source(file) ;
P = module(nb_set) ;
P = load_context(solution_sequences, '/Users/pmoura/lib/swipl/library/solution_sequences.pl':46, []) ;
P = load_count(1) ;
P = number_of_clauses(13).
?- source_file_property('/Users/pmoura/lib/swipl/library/solution_sequences.pl', P).
P = modified(1574086719.0) ;
P = source(file) ;
P = module(solution_sequences) ;
P = load_context(editline, '/Users/pmoura/lib/swipl/library/editline.pl':59, []) ;
P = load_count(1) ;
P = number_of_clauses(49).
The file editline.pl
provides the default convenient command-line history and other services. But if you switch to readline
by adding to your ~/.config/swi-prolog/init.pl
file the directive:
:- set_prolog_flag(readline, readline).
Then you get:
?- [user].
|: a(A,B) :- forall(A,B).
|: % user://1 compiled 0.00 sec, 1 clauses
true.
?- listing(a/2).
% autoloading user:listing/1 from /Users/pmoura/lib/swipl/library/listing
a(A, B) :-
forall(A, B).
true.
This is a poor workaround but it may help you.
Upvotes: 2