Prolog:包含断言的规则仅将第一个结果添加到事实
Prolog: a rule containing assert adds only first result to facts
我正在尝试预先计算一些东西并将结果保存为程序开头的事实:(简化代码)
:- 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 序言控制台中输入 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
我觉得这个行为很混乱,这是怎么回事?
在您的原始子句中添加一个 fail/0
并添加另一个刚刚成功的子句:
assert_all:-
recipe(Id,Cost),
assert(cost(Id,Cost)),
fail.
assert_all.
这是怎么回事,你写的程序断言了配方的第一笔费用并留下了一个选择点。在回溯时,它最终会断言其他事实(如果它回溯,这就是当您通过在 Sicstus 控制台中按 ;
来请求更多替代方案时发生的情况)。
这个答案的失败驱动循环只是回溯 recipe/2
的每个解决方案并断言其成本。那么第二个子句就成功了。
我正在尝试预先计算一些东西并将结果保存为程序开头的事实:(简化代码)
:- 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 序言控制台中输入 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
我觉得这个行为很混乱,这是怎么回事?
在您的原始子句中添加一个 fail/0
并添加另一个刚刚成功的子句:
assert_all:-
recipe(Id,Cost),
assert(cost(Id,Cost)),
fail.
assert_all.
这是怎么回事,你写的程序断言了配方的第一笔费用并留下了一个选择点。在回溯时,它最终会断言其他事实(如果它回溯,这就是当您通过在 Sicstus 控制台中按 ;
来请求更多替代方案时发生的情况)。
这个答案的失败驱动循环只是回溯 recipe/2
的每个解决方案并断言其成本。那么第二个子句就成功了。