如何使用模块覆盖用户谓词

时间:2013-10-16 14:36:28

标签: prolog swi-prolog

假设我有一个名为foo的模块(在foo.pl中定义)。例如,此模块执行term_expansion

:- module(foo,[term_expansion/2]).

term_expansion(A,A) :-
    print A.

当然,真正的代码会使用更复杂的术语。

现在我想在一个文件中导入这个库,比如test.pl

:- use_module(foo).
fact(a).

但是,当使用swi-prolog时,我收到以下错误:

ERROR: Cannot import foo:term_expansion/2 into module user: name clash

如何解决此错误?

1 个答案:

答案 0 :(得分:3)

术语扩展谓词通常(它们不是标准的)声明为多文件(可能是动态)谓词。在SWI-Prolog的特定情况下,术语扩展机制已经定义并调用了伪模块term_expansion/2user谓词的定义。因此,一种可能的解决方案是改为编写:

:- module(foo).

:- multifile(user:term_expansion/2).
:- dynamic(user:term_expansion/2).

user:term_expansion(A,A) :-
    print(A).

在加载要进行术语扩展的文件之前,您只需要加载此模块的定义。

关于为什么term_expansion/2谓词默认情况下未声明为多文件的后续问题。我可以对你的问题给出两种不同的解释。我会解决这两个问题。 (1)为什么需要重复multifile/1指令? ISO Prolog标准意味着多文件谓词应该在包含它的子句的所有文件中声明为多文件(我说暗示而不是指定标准谈论“Prolog文本”而不​​是文件)。实际上,SWI-Prolog在这里相当自由,但重复这些指令是好的做法,而且当其他系统在这方面更密切地遵循标准时。 (2)为什么术语扩展谓词必须首先被声明为多文件(和动态)?这取决于实施。例如。在术语扩展机制的Logtalk实现中,它们既不是多文件也不是动态的。