Module Prolog:在调用谓词时考虑动态模块中的子句

Module Prolog:在调用谓词时考虑动态模块中的子句,module,prolog,swi-prolog,Module,Prolog,Swi Prolog,在调查中,我发现了以下评论: 例如,假设一个应用程序可以对多个世界进行推理。将特定世界的数据存储在一个模块中是很有吸引力的,因此我们只需调用世界中的目标即可从世界中提取信息 这实际上是一个非常好的描述,我正在努力实现。然而,我遇到了一个问题。虽然我确实想为许多不同的世界建模,但也有一些东西我想在所有这些世界中分享。因此,我的想法是为每个世界都真实的事物建立一个allworlds模块,为每个我想推理的世界建立一个模块,后者从前者导入。所以我会在REPL中这样做: allworlds:asserta

在调查中,我发现了以下评论:

例如,假设一个应用程序可以对多个世界进行推理。将特定世界的数据存储在一个模块中是很有吸引力的,因此我们只需调用世界中的目标即可从世界中提取信息

这实际上是一个非常好的描述,我正在努力实现。然而,我遇到了一个问题。虽然我确实想为许多不同的世界建模,但也有一些东西我想在所有这些世界中分享。因此,我的想法是为每个世界都真实的事物建立一个
allworlds
模块,为每个我想推理的世界建立一个模块,后者从前者导入。所以我会在REPL中这样做:

allworlds:asserta(grandparent(X, Z) :- (parent(X, Y), parent(Y, Z))).
allworlds:dynamic(parent/2).
add_import_module(greece, allworlds, start).
greece:asserta(parent(kronos, zeus)).
greece:asserta(parent(zeus, ares)).

现在我想查询希腊:祖父母(kronos,X)并得到
X=ares
,但我得到的是
false
。当
allworlds:grandparent
调用
parent
时,它不会像我希望的那样调用
greece:parent
,而是
allworlds:parent
。我的研究似乎表明,我需要使
祖父母
谓词模块透明。但是调用
allworlds:module\u transparent(祖父母/2)。
并没有解决这个问题,而且它也被弃用。这就是我被困的地方。我怎样才能让它工作?这是解决方案的一部分吗?不幸的是,我无法理解它的文档。

Prolog模块不能为“多世界”设计模式提供一个好的解决方案。值得注意的是,使谓词元谓词(或模块透明或多文件)成为一个有问题的黑客。但是这种模式对于Logtalk来说并不重要,Logtalk是一种扩展Prolog的语言,可以将大多数Prolog系统用作后端编译器。针对您的问题的最小(但不是唯一)解决方案是:

:- object(allworlds).

    :- public(grandparent/2).
    grandparent(X, Z) :-
        ::parent(X, Y),
        ::parent(Y, Z).

    :- public(parent/2).

:- end_object.


:- object(greece,
    extends(allworlds)).

    parent(kronos, zeus).
    parent(zeus, ares).

:- end_object.
在这里,当公共谓词需要访问特定于世界的谓词定义时(在本例中,self是接收消息的对象/世界-
祖父母/2
),我们使用继承(各个世界继承公共知识)和消息self(
::/1
控制结构)

假设代码保存在
worlds.lgt
文件中,并且您使用SWI Prolog作为后端:

$ swilgt
...
?- {worlds}.
% [ /Users/pmoura/worlds.lgt loaded ]
% (0 warnings)
true.

?- greece::grandparent(kronos, X).
X = ares.

注意:如果在windows上运行,请在安装Logtalk后使用“开始”菜单中的“Logtalk-SWI Prolog”快捷方式。

这似乎与我不久前尝试的操作类似。看一看:嘿,保罗,谢谢你的回答。不幸的是,我的程序不是用Prolog编写的,它实际上是在JVM上运行的。它从外部获取一个世界的描述,将其转换为Prolog事实,断言那些使用JPL的事实,执行一些查询,然后再次收回它们。我只是把它当作一个逻辑引擎。Logtalk还能用吗?不幸的是,上述方法与并发性不匹配,这就是为什么我首先研究模块来分离不同的世界。对于使用Logtalk+SWI Prolog+JPL,请参见,例如,Hey Paolo,我终于开始尝试提出的解决方案,我有一个问题:是否可以在派生对象中为谓词添加额外的子句,而该派生对象已经在基本对象中定义了?例如,当我将
祖父母(kronos,hephaistos)。
添加到上面的
greece
对象时,则
greece::祖父母(kronos,ares)
不再有效。在没有显式超级调用的情况下是否可以修复此问题?您需要在派生对象中进行超级调用,以允许在本地定义之外找到继承的定义。我明白了,非常感谢!