質問

Say I have a module named foo (defined in foo.pl). This module does term_expansion for instance:

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

term_expansion(A,A) :-
    print A.

Of course the real code does something more complicated with the terms.

Now I want to import this library in a file, say test.pl:

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

When using swi-prolog however, I get the following error:

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

How can I resove this error?

役に立ちましたか?

解決

Term-expansion predicates are usually (they are not standard) declared as multifile (and possibly dynamic) predicates. In the specific case of SWI-Prolog, the term-expansion mechanism already defines and calls definitions for the term_expansion/2 predicate in the pseudo-module user. Thus, a possible solution would be to write instead:

:- module(foo).

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

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

You should only need to load the definition of this module before loading files that you want to be term-expanded.

Regarding your follow up question about why the term_expansion/2 predicate is not declared multifile by default. I can give two different interpretations to your question. I'll address both. (1) Why do you need to repeat the multifile/1 directive? The ISO Prolog standard implies that a multifile predicate should be declared multifile in all files containing clauses for it (I say implies instead of specifies as the standard talks about "Prolog text" and not files). Actually, SWI-Prolog is quite liberal here but it's good practice to repeat the directives, moreover when other systems follow the standard more closely in this regard. (2) Why must the term-expansion predicates be declared multifile (and dynamic) in the first place? That depends on the implementation. E.g. in the Logtalk implementation of the term-expansion mechanism they are neither multifile nor dynamic.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top