Prolog 使用forall/2扩展序言子句

Prolog 使用forall/2扩展序言子句,prolog,metaprogramming,swi-prolog,Prolog,Metaprogramming,Swi Prolog,我用它来转换编译器中的一些Prolog子句。我需要将每个子句的开头替换为其主体,但是clause/2有时不能按照最初编写的方式扩展子句 这里,子句/2将演示(A,B)扩展为\+(调用(A),\+call(B)),而不是扩展其原始定义: :- use_module(prolog_to_minizinc). :- initialization(main). main :- writeln(forall(A,B)), clause(demo(A,B),Clause)

我用它来转换编译器中的一些Prolog子句。我需要将每个子句的开头替换为其主体,但是
clause/2
有时不能按照最初编写的方式扩展子句

这里,
子句/2
演示(A,B)
扩展为
\+(调用(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加载
库(应用宏)
。此库为
forall/2
和其他谓词提供扩展代码。查找如何加载
库(apply_macros)
并非易事,因为在
~/.config/swi prolog/init.pl
文件中将
verbose_autoload
标志设置为
true
,不会打印启动时自动加载的所有库。在我的笔记本电脑上,使用当前的devel-git版本的SWI-Prolog(
8.1.21-82-ge6e1d5376-DIRTY
):

文件
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.

这是一个糟糕的解决方法,但它可能会对您有所帮助。

请注意,
forall/2
谓词可以而且通常被定义为
forall(a,B):-\+(call(a),\+call(B))
…但是在这里,我希望
demo(a,B)
被扩展为
forall(a,B)
。如果您不发布正在使用的术语扩展代码,很难给出建议。@PauloMoura它是编译器的一部分。这个编译器使用
子句/2、
扩展子句,但是我需要在不修改定义的情况下扩展每个子句。我期望
子句(demo(A,B),子句)
子句
forall(A,B)
统一起来,但它没有按照我的预期工作。在SWI prolog 8.1.19中,如果不将prolog\u加载到minizing模块,则会使
forall(_7212,_7214)forall(_7212,_7214)正确。
清单(demo)
还显示了未扩展的代码。
?- [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.