因此,根据文档,未包含在module
指令中的谓词不应该在定义它们的源文件之外可见。
让我们说有这个文件animals.pro:
:- module(animals, [mammal/1]).
mammal(rhino).
mammal(whale).
insect(fly).
insect(mantis).
我这样做......
:- use_module(animals).
insect(X).
它提示我:
Correct to: "animals:insect(X)"?
如何禁用此类提示?我根本不希望insect
可见。周期。
答案 0 :(得分:4)
在对SWI-Prolog源代码进行前瞻性研究之后,我不认为有一种直接的方法可以禁用"更正:"从顶级查询时提示。我可能弄错了。
但是,如果您尝试查询"私有"则会弹出提示。谓词直接。如果从另一个谓词调用它,你就不会看到任何内容,你将得到你期望的异常:
?- use_module(animals).
true.
?- assertz(( foo(X) :- insect(X) )).
true.
?- foo(X).
ERROR: foo/1: Undefined procedure: insect/1
Exception: (8) insect(_G1431) ? abort
% Execution Aborted
?- insect(X).
Correct to: "animals:insect(X)"? no
ERROR: residue_vars/2: Undefined procedure: insect/1
Exception: (7) insect(_G3328) ? abort
% Execution Aborted
正如我在上面的评论中所说,你总是可以通过明确地对模块进行限定来从模块中获取私有谓词。继续上面的例子:
?- assertz(( bar(X) :- animals:insect(X) )).
true.
?- bar(X).
X = fly ;
X = mantis.
您当然可以自己阅读documentation on modules。
至于为什么会这样:嗯,这是一个设计决定我想。如果我没记错的话,Python会做同样的事情 - 如果调用者知道要查找什么,你就无法隐藏实现。您是否打算将此用于"隐藏实现",Java-OOP样式?
答案 1 :(得分:1)
使用Logtalk而不是模块。您不仅可以使用SWI-Prolog运行它,还可以使用11个Prolog系统运行它。 Logtalk强制执行封装,防止调用非公共谓词。如果您的帖子中的模块保存在class UserManager(models.Manager):
...
def create(self, username, email, secret_id=None):
user = User(username=username, email=email)
user.save()
user_profile = UserProfile(
user=user,
secret_id=secret_id
)
user_profile.save()
return user
文件中,您可以进行快速实验(在SWI-Prolog中):
animals.pl
在这个快速实验中,Logtalk简单地将您的?- pack_install(logtalk).
true.
?- use_module(library(logtalk)).
true.
?- {animals}.
% [ /Users/pmoura/Desktop/animals.pl loaded ]
% (0 warnings)
true.
?- animals::insect(X).
ERROR: predicate_declaration `insect/1' does not exist
...
模块编译为Logtalk对象。为了正确使用,并利用所有Logtalk功能(例如接口/协议),通常很容易将现有模块转换为对象。在你的情况下:
animals
Logtalk源文件的默认扩展名为:- object(animals)
:- public(mammal/1).
mammal(rhino).
mammal(whale).
insect(fly).
insect(mantis).
:- end_object.
。如果您将对象版本保存在.lgt
文件中,则可以使用animals.lgt
的{{1}}快捷方式以相同的方式加载它。
您仍然可以将模块与对象一起使用,包括从对象调用模块谓词以及在必要时从模块向对象发送消息。
P.S。尽管使用了上面的{}/1
指令,但Logtalk并未作为模块实现。该指令仅用作包的加载机制。