2014-03-18 73 views
0

因此,作爲我工作的一部分,我的代碼需要將所有解決方案打印到查詢中,但不使用findall/3謂詞。我已經做了一些閱讀,並且有一些方法可以將解決方案添加到列表中等等。我試圖自己做這件事,但沒有成功;因此我希望有人能夠展示如何在不使用findall的情況下打印所有解決方案。SWI-Prolog:收集沒有findall的所有解決方案

程序代碼如下:

solutions(Q, 100):- 
     Q = [X, Y, S], 
     between(2,50,X), 
     between(2,50,Y), 
     S is X+Y, 
     Y > X, 
     S =< 50. 

的Q和100在那裏,因爲它需要的程序的其他部分,從而忽略了現在。當我使用?- solutions(Q, 100)查詢時,我得到結果[2,3,5][2,4,6][2,5,7]等,但顯然我需要按;才能獲得每個新結果。我需要顯示所有這些,而不需要按;並且不使用findall。

+0

你是否被允許使用'assert'? –

+0

http://stackoverflow.com/questions/7647758/prolog-findall-implementation –

回答

0

一個基於斷言的解決方案(這實際上是如何findall在Prolog的教科書開始實施):假設solution/2找到的每個單一的解決辦法,按你的代碼。現在我們使用失敗驅動循環,正如Paulo所建議的那樣,使用assert/1緩存解決方案來構建解決方案列表。

solutions(_, N) :- 
    solution(Q, N), 
    (cache(Qs) -> retractall(cache(_)) ; Qs = []), 
    assert(cache([Q|Qs])), 
    fail. 
solutions(Qs, _) :- 
    retract(cache(Qs)). 
+0

非常感謝這完美的作品! =] – Elviii

1

您可以使用故障驅動循環。嘗試:

?- solutions(Q, 100), write(Q), nl, fail. 
+0

可能的重複雖然這確實工作正常,但他們嚴格保持對解決方案(Q,100)的查詢。所以,不幸的是我不能這樣做= [ – Elviii

+0

@Elviii所以,只需在您的'解決方案'代碼的末尾添加'write(Q),nl,fail.'。 –

+0

我也做不到。他們用來標記這項工作的方法是通過使用另一個程序來檢查我正在做他們想讓我做什麼。這不允許故障驅動循環。有更多的四處張望,發現累加器可能是一種選擇。你認爲這會是最好的嗎?謝謝! – Elviii

相關問題