【问题标题】:Some problems asserting a new rule in SWI-Prolog在 SWI-Prolog 中断言新规则的一些问题
【发布时间】:2013-04-06 21:10:40
【问题描述】:

我正在学习 Ivan Bratko 的书:“人工智能编程”,用于大学考试并使用 SWI Prolog,我对本书中关于 assert 的示例显示有些疑问>retract 谓词。

它只是呈现以下代码,将一些事实声明为动态:

:-dynamic fast(ann).
:-dynamic slow(tom).
:-dynamic slow(pat).

然后在 Prolog shell 中使用 assert 规则将新规则定义到数据库中:

[debug] 59 ?- assert((faster(X,Y) :- fast(X), slow(Y))).
true.

好的,新规则似乎已添加到我的数据库中。

现在我尝试执行此查询,但失败了:

[debug] 64 ?- faster(X,Y).
false.

书上说输出应该是这个:

A = ann
B = tom

这听起来很好也很合理,因为我参考了之前的程序,其中说指定谁快谁慢,后来我添加了更快的规则来断言它......

为什么不工作?也许这取决于 Prolog 实现(SWI-Prolog)?

【问题讨论】:

  • 您对dynamic 指令的使用应仅指示谓词及其参数数量,例如:- dynamic fast/1:-dynamic slow/1。为这些动态谓词断言事实是一个单独的(运行时)步骤。
  • 好的,需要澄清一下
  • 有趣的旁注:断言的事物仅在程序执行期间存在于内存中。我正在玩弄它,当我尝试在单独的运行中收回我用assertz 定义的事实时,它失败了,因为没有可收回的东西。要永久添加到知识库,您需要一个带有 append 的输出流。

标签: prolog


【解决方案1】:

Prolog 中的dynamic 指令在编译程序中很有用(通常在要编译的源文件中使用)。如果您使用assert 或等效机制在交互式 shell 中创建事实(或规则),那么 SWI-Prolog 将假定这些谓词是动态的。

但是,如果您想在为谓词定义任何事实之前通过规则中的子句引用谓词,则dynamic 指令很有用。也就是说,假设我们首先这样做:

?- assert((faster(X,Y) :- fast(X), slow(Y))).
true.

然后尝试查询:

?- faster(X,Y).

您可能认为这会失败,因为fast/1slow/1 不存在(目前)事实。但实际上 SWI-Prolog 会(按设计)抛出错误异常:

ERROR: faster/2: Undefined procedure: fast/1

为了防止这种情况,我们应该在用户输入模式下添加动态指令:

?- [user].
|: :-dynamic fast/1, slow/1.
|: (type Ctrl-z to exit user entry mode)
% user://1 compiled 0.00 sec, 1 clauses

现在我们将得到预期的失败行为(假设之前断言的规则):

?- faster(X,Y).
false.

您可以使用相同的模式来创建您的事实:

?- [user].
|: fast(ann).
|: slow(tom).
|: slow(pat).
|: (type Ctrl-z to exit user entry mode)
% user://2 compiled 0.00 sec, 4 clauses
true.

现在faster 查询以两种不同的方式成功:

?- faster(X,Y).
X = ann,
Y = tom ;
X = ann,
Y = pat.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 2019-07-06
    • 1970-01-01
    相关资源
    最近更新 更多