我试图预先计算一些东西并将结果保存为程序开头的事实:(简化代码)
:- 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
我发现这种行为非常混乱,发生了什么?
答案 0 :(得分:2)
在原始子句中放入fail/0
并添加另一个成功的子句:
assert_all:-
recipe(Id,Cost),
assert(cost(Id,Cost)),
fail.
assert_all.
正在发生的事情是,你所写的程序断言了食谱的第一个成本并留下了一个选择点。在回溯时,它最终会断言其他事实(如果它回溯,当你在Sicstus控制台中按;
要求更多替代方案时会发生这种情况。)
这个答案的失败驱动循环只是回溯了recipe/2
的每个解决方案并断言其成本。然后第二个条款就成功了。