Вопрос

Consider the following code:

:- module(my_export, [create/2]).

create(Predicate, Id) :-
    assertz(Predicate),
    export(Id).

Assuming that the predicated and the identifier match, I'd expect the newly asserted predicate to be available outside the module. However, I get this output:

?- create(c(A,B) :- A > B, c/2).
true.

?- c(1,2).
Correct to: "my_export:c(1,2)"? 

How come the predicate isn't exported? What is the correct way to do this?

Это было полезно?

Решение

You have to import module by using use_module/1.

For example, if this is sample_module.pl:

:- module(my_export, [create/2]).

create(Predicate, Id) :-
    assertz(Predicate),
    export(Id).

Then this input and output is true (observe closely what's going on):

?- 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.

Now, when you "compile buffer" in SWI-Prolog what really happens is consult/1. You need to import your module manually.

Другие советы

Your code work as-is, as long as the module is initially imported, as Grzegorz explained. For example:

?- [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.

Note, however, that export/1 is usually a directive, not a predicate. There might be portability issues to other Prolog dialects supporting a module system.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top