用 forall/2 扩展 Prolog 子句
Expanding Prolog clauses with forall/2
我正在使用 clause/2
来转换编译器中的一些 Prolog 子句。我需要用正文替换每个子句的头部,但 clause/2
有时不会按照最初编写的方式扩展子句。
这里,clause/2
将demo(A,B)
扩展为\+ (call(A),\+call(B))
,而不是扩展其原始定义:
:- 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).
是否有另一种方法来扩展子句,而不修改包含 forall/2
的子句?
forall/2
目标的意外扩展是由于 SWI-Prolog 在启动时加载 library(apply_macros)
。这个库提供了 forall/2
和其他谓词的扩展代码。查找 library(apply_macros)
的加载方式并非易事,因为在 ~/.config/swi-prolog/init.pl
文件中将 verbose_autoload
标志设置为 true
不会打印所有在启动时自动加载的库。在我的笔记本电脑上,使用当前开发的 git 版本的 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).
文件editline.pl
提供默认方便的命令行历史记录和其他服务。但是,如果您通过将指令添加到 ~/.config/swi-prolog/init.pl
文件来切换到 readline
:
:- set_prolog_flag(readline, readline).
然后你得到:
?- [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.
这是一个糟糕的解决方法,但它可能对您有所帮助。
我正在使用 clause/2
来转换编译器中的一些 Prolog 子句。我需要用正文替换每个子句的头部,但 clause/2
有时不会按照最初编写的方式扩展子句。
这里,clause/2
将demo(A,B)
扩展为\+ (call(A),\+call(B))
,而不是扩展其原始定义:
:- 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).
是否有另一种方法来扩展子句,而不修改包含 forall/2
的子句?
forall/2
目标的意外扩展是由于 SWI-Prolog 在启动时加载 library(apply_macros)
。这个库提供了 forall/2
和其他谓词的扩展代码。查找 library(apply_macros)
的加载方式并非易事,因为在 ~/.config/swi-prolog/init.pl
文件中将 verbose_autoload
标志设置为 true
不会打印所有在启动时自动加载的库。在我的笔记本电脑上,使用当前开发的 git 版本的 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).
文件editline.pl
提供默认方便的命令行历史记录和其他服务。但是,如果您通过将指令添加到 ~/.config/swi-prolog/init.pl
文件来切换到 readline
:
:- set_prolog_flag(readline, readline).
然后你得到:
?- [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.
这是一个糟糕的解决方法,但它可能对您有所帮助。