1

我正在尝试预先计算一些东西并将结果保存为程序开头的事实:(简化代码)

:- dynamic cost/2.
%recipe(Id,Cost)
recipe(1,20).
recipe(2,40).

assert_all :- recipe(Id,Cost), assert(cost(Id,Cost)).

但是当我在 SICStus Prolog 中查阅文件时,只有第一个结果 cost(1,20) 被断言:

| ?- assert_all.
yes
| ?- cost(Id,Cost).
Id = 1,
Cost = 20 ? ;
no
| ?

但是,当我直接在 SICStus prolog 控制台中输入 assert_all 的右侧时,两个 cost/2 事实都在那里。

| ?- recipe(Id,Cost), assert(cost(Id,Cost)).
Id = 1,
Cost = 20 ? ;
Id = 2,
Cost = 40 ? ;
no
| ?- cost(Id,Cost).                         
Id = 1,
Cost = 20 ? ;
Id = 2,
Cost = 40 ? ;
no

我发现这种行为非常令人困惑,这是怎么回事?

4

1 回答 1

2

fail/0在您的原始子句中放入 a并添加另一个刚刚成功的子句:

assert_all:- 
  recipe(Id,Cost), 
  assert(cost(Id,Cost)),
  fail.
assert_all.

发生的事情是,您编写的程序断言了食谱的第一个成本并留下了选择点。在回溯时,它最终会断言其他事实(如果它回溯,当您通过按下;Sicstus 控制台要求更多替代方案时会发生这种情况)。

这个答案的失败驱动循环只是回溯每个解决方案recipe/2并断言其成本。然后第二个子句就成功了。

于 2016-05-17T19:45:55.427 回答