禁用"纠正:" SWI-Prolog模块的选项

时间:2016-02-16 06:40:50

标签: prolog swi-prolog

因此,根据文档,未包含在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可见。周期。

2 个答案:

答案 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并未作为模块实现。该指令仅用作包的加载机制。