请考虑以下代码:
:- module(my_export, [create/2]).
create(Predicate, Id) :-
assertz(Predicate),
export(Id).
假设谓词和标识符匹配,我希望新断言的谓词在模块外可用。但是,我得到了这个输出:
?- create(c(A,B) :- A > B, c/2).
true.
?- c(1,2).
Correct to: "my_export:c(1,2)"?
为什么谓词不会导出?这样做的正确方法是什么?
答案 0 :(得分:4)
您必须使用use_module/1
导入模块。
例如,如果是sample_module.pl
:
:- module(my_export, [create/2]).
create(Predicate, Id) :-
assertz(Predicate),
export(Id).
然后这个输入和输出是真的(仔细观察发生了什么):
?- create(tmp(A,B) :- A > B, tmp/2).
ERROR: toplevel: Undefined procedure: create/2 (DWIM could not correct goal)
?- consult('c:\\Prolog\\pl\\bin\\sample_module.pl').
% c:\Prolog\pl\bin\sample_module.pl compiled into my_export 0.00 sec, 2 clauses
true.
?- create(tmp(A,B) :- A > B, tmp/2).
true.
?- tmp(1,2).
Correct to: "my_export:tmp(1,2)"? yes
false.
?- use_module('c:\\Prolog\\pl\\bin\\sample_module.pl').
true.
?- tmp(1,2).
false.
?- tmp(5,4).
true.
现在,当你"编译缓冲区"在SWI-Prolog中,真正发生的是consult/1
。您需要手动导入模块。
答案 1 :(得分:1)
正如Grzegorz解释的那样,只要模块最初导入,您的代码就会按原样运行。例如:
?- [user].
:- module(my_export, [create/2]).
|:
|: create(Predicate, Id) :-
|: assertz(Predicate),
|: export(Id).
|: % user://1 compiled into my_export 0.00 sec, 2 clauses
true.
?- module_property(my_export, P).
P = class(user) ;
P = file('user://1') ;
P = line_count(10) ;
P = exports([create/2]) ;
false.
?- my_export:create(c(A,B) :- A > B, c/2).
true.
?- module_property(my_export, P).
P = class(user) ;
P = file('user://1') ;
P = line_count(10) ;
P = exports([c/2, create/2]) ;
false.
?- create(tmp(A,B) :- A > B, tmp/2).
true.
?- module_property(my_export, P).
P = class(user) ;
P = file('user://1') ;
P = line_count(10) ;
P = exports([tmp/2, c/2, create/2]) ;
false.
但请注意,export/1
通常是指令,而不是谓词。支持模块系统的其他Prolog方言可能存在可移植性问题。