3

I am studying on Ivan Bratko book: "Programming for Artificial Intelligence" for an universitary exame and using SWI Prolog and I have some doubts about an example show on this book regarding the assert and retract predicates.

It simply present the following code that declare some facts as dynamic:

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

Then in the Prolog shell use the assert rule to define a new rule into the database:

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

Ok, so the new rule seems to be added to my database.

Now I try to perform this query and it fail:

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

On the book say that the output should be this one:

A = ann
B = tom

and it sound good and rational because I have consult the previous program where say that specify who is fast and who is slow and later I have add the faster rule asserting it...

Why don't work? maybe it depends by the Prolog implementation (SWI-Prolog)?

4

1 回答 1

4

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

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

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

然后尝试查询:

?- faster(X,Y).

您可能会认为这会失败,因为 ( 还) 不存在fast/1or的事实slow/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.
于 2013-04-15T13:04:13.497 回答