如何导出动态创建的谓词?

时间:2014-04-27 05:20:32

标签: prolog swi-prolog

请考虑以下代码:

:- 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)"? 

为什么谓词不会导出?这样做的正确方法是什么?

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方言可能存在可移植性问题。