2

假设我有一个名为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

我该如何解决这个错误?

4

1 回答 1

3

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

:- module(foo).

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

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

您应该只需要在加载要扩展的文件之前加载此模块的定义。

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

于 2013-10-16T15:57:39.553 回答