Prolog:包含assert的规则只会在事实中添加第一个结果

时间:2016-05-17 19:43:06

标签: prolog sicstus-prolog prolog-assert

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

:- 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的右侧时,那里都有成本/ 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

我发现这种行为非常混乱,发生了什么?

1 个答案:

答案 0 :(得分:2)

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

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

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

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