2014-10-09 58 views
1
r1(X,Z) :- backwards(X,Z). 

r1_10(X,Z) :- 
    r1(X,Z), 

我有這段代碼。這個想法是,如果r1滿足10次,r1_10會被滿足。我對Prolog很陌生,我不確定如何真正地正確地循環。我在考慮只是強制同一行10次,但我需要能夠做到像r1_30這樣的事情,所以這將是很多代碼沒有理由。試圖制定一個目標,如果另一個目標在Prolog中運行10次,則滿足

謝謝!

編輯: 這個答案有很多幫助,但只是爲了澄清我的問題。基本上,我有目標r1,它調用了我的反向/ 2謂詞,這簡直讓我反思了這個列表。我有兩種向後/ 2謂詞,其中一種包括累加器,另一種不是。 r1_10只是一個目標,最終會告訴我,使用累加器的那個速度更快,更好。目標r1_10僅僅是一個運行目標r1 10次的方法。我很確定我不需要不同的結果,我只需要知道r1完成10次後它會成功。希望這可以幫助!

回答

2

目前尚不清楚「滿意10倍」是什麼意思。你的意思是r1/2謂詞將有10個解決方案嗎?一個例子是目標member(X, [1,2,3,4,5,6,7,8,9,0]),其在回溯時將連續實例化變量X到每個列表元素。如果是這樣,一種解決方案可能是使用標準的findall/3謂詞來計算目標的所有解決方案的列表,然後計算列表的長度。例如:

r1_10(X,Z) :- 
    findall(_, r1(X,Z), Solutions), 
    length(Solutions, 10). 

該斷言可以通過使用附加的參數來傳遞的解決方案,以檢查的數量很容易地推廣。它也可以通過使用另一個參數來通過目標本身來推廣。另一方面,如果你想簡單地調用一個目標N次,你可以定義一個需要一個目標和一個計數器的謂詞。例如:

call_n_times(N, Goal) :- 
    between(1, N, _), % generate, on backtracking, all numbers in the interval [1,N] 
    once(Goal), 
    fail. 
call_n_times(_, _). 

但是,此定義假定目標永遠不會失敗(或引發錯誤)。從你的問題來看,如果目標不能滿足N次,應該會發生什麼。在這種情況下,呼叫者是否應該失敗?如果是這樣,你將需要一個不同的定義。例如(再次假設目標從未失敗或引發錯誤):

call_n_times(0, _) :- !. % green cut just to avoid a spurious choice-point 
call_n_times(N, Goal) :- 
    N > 0, 
    once(Goal), 
    M is N - 1, 
    call_n_times(M, Goal). 

但是這個定義仍然可能會有問題。例如,如果你傳遞一個非地面目標,即有變量的目標,並且調用該目標,則會以阻止其在下一步中成功的方式實例化其所有變量的一部分。爲了避免這種潛在的問題的一種方法是使用下面的緊湊型定義:

call_n_times(N, Goal) :- 
    forall(between(1,N,_), Goal). 

forall/2between/3是事實上的標準謂詞。對於第一個參數的每個解決方案,第二個參數爲true(因此實現生成和測試循環)時,forall/2謂詞爲true。

我們可以使用一些更多細節,包括你想要完成什麼,包括你想要重複的目標的性質。

相關問題