2012-10-24 81 views
3

我使用以下故障驅動循環列出所有內容,而不使用 分號。序言:失敗驅動循環

happiness(fred,5). 
happiness(john,3). 
happiness(grace,2). 

someGoal(X) :- 
     happiness(X,Y), write(Y), tab(4), fail. 

在查詢模式下,我得到這個預期

?- someGoal(_). 
5 3 2 

我怎樣才能插入這些數字到列表中,而不是將它們寫到屏幕? 我無法在someGoal內處理這個問題,因爲回溯似乎是隱含的。

回答

4

你是對的,回溯它是Prolog處理替代品的方式。

使用findall/3,收集使用回溯 '內部' 所有備選方案:

someGoal(X, Values) :- 
    findall(Value, happiness(X, Value), Values). 

然後?- someGoal(_, Values).將實例值= [5,3,2]

+0

謝謝,很好,拯救了我的一天。儘管嘗試了其他方法,我建立了許多prolog技能:P – Zoran

4

故障驅動的環路常將某些部件打開並且不確定,遲早會導致一些問題。特別是變量的精確量化很容易被打開。 Often, such loops can be avoided alltogether。在你的例子中,我不清楚你爲什麼有一個參數someGoal/1。至少你不使用它。因此會出現以下幾個問題:

  1. 如果沒有匹配的值,您會期望什麼?您的原始程序無法打印並且失敗。

  2. 如果存在多餘條目,您會期望什麼?你想多次打印東西嗎?

  3. 您是否堅持價值的精確順序,或者您能否想象另一個訂單?

  4. 爲什麼你有興趣看到這些值呢?大多數時候你想要看到它們與具體名稱相關聯,或者你想要它的一些總和,如總和或平均值。

鑑於我不知道這些答案,我可以爲您提供幾種解決方案。我將舉一個額外的(冗餘)事實作爲例子:

 
happiness(fred,5). 
happiness(john,3). 
happiness(john,3). 
happiness(grace,2). 

?- setof(P-H,happiness(P,H), PHs). 
PHs = [fred-5, grace-2, john-3]. 

?- setof(H,P^happiness(P,H), PHs). 
PHs = [2, 3, 5]. 

?- bagof(H,P^happiness(P,H), PHs). 
PHs = [5, 3, 3, 2]. 
+0

非常感謝您進一步澄清和案例研究。爲了便於閱讀,我的玩具示例從更復雜的示例中減少。 – Zoran