2016-05-17 55 views
1

我試圖預先計算一些東西和我的節目開始將結果保存爲事實:(簡化代碼)序言:含有斷言規則只添加了第一個結果,以事實

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

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

但只有第一結果,當我在協商的Prolog SICStus文件成本(1,20)被斷言​​:

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

然而,當我輸入直接在SICStus序言控制檯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

嘗試使用asserta在開頭保存您的結果:http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse48 –

回答

2

將一個fail/0原來的條款中,並補充說,只是成功的一個條款:

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

怎麼回事是你的程序,你寫的斷言第一成本爲配方並留下了一個選擇點。在回溯時,它最終會斷言其他事實(如果它回退,當您在Sicstus控制檯中按;要求更多替代方法時發生的情況)。

這個答案的失敗驅動循環只是回溯每個解決方案recipe/2並聲稱其成本。那麼第二條就成功了。

+0

它的工作原理,謝謝,也爲解釋! – Juraj