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

标签 module prolog swi-prolog

SWI Prolog manual ,我发现了以下评论:

For example, assume an application that can reason about multiple worlds. It is attractive to store the data of a particular world in a module, so we extract information from a world simply by invoking goals in this world.

这实际上很好地描述了我要实现的目标。但是我遇到了一个问题。虽然我确实想为许多不同的世界建模,但我也想在所有这些世界中分享一些东西。所以我的想法是为每个世界中真实的事物创建一个 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)).

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

最佳答案

Prolog 模块没有为“多世界”设计模式提供好的解决方案。值得注意的是,使谓词成为元谓词(或模块透明或多文件)将是一个有问题的 hack。但是这种模式对于 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.

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

假设代码保存在 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”快捷方式。

关于module - Prolog:调用谓词时考虑动态模块中的子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67810114/

相关文章:

prolog - SWI-Prolog:当 "Non-module file"已加载到某些模块时,无权加载源)

prolog - 如何关闭 Prolog 中的 "true"和 "false"输出?

angular - "p-menu"不是已知元素

python - python有没有C/C++之类的double import?

javascript - NodeJS计划支持导入/导出es6(es2015)模块

debugging - gprolog : Getting a stacktrace after an exception

prolog - 二叉树 T 的叶节点中的值列表

prolog - 将 OSM 数据转换为 Prolog 事实?

android - 在模块(android 库)中使用改造 2.4.0 时出现 NoClassDefFoundError

http - swi 序言 8.0.2 : gziped http