2011-09-18 155 views
0

所以我有幾次返回true的謂詞。謂詞返回。 Prolog

% true returns several times and i need to press ';' 
?- get_all_transformed_moves. 
true ; 
true ; 
true. 

是否swi prolog有一些方法可以幫助我運行此謂詞而不鍵入';'?

% Wished version 
?- get_all_transformed_moves. 
true. 

回答

2

考慮以下幾點:

likes(prolog). 
likes(haskell). 
likes(erlang). 

likes_something:- 
    likes(_Something). 

如果現在你問:

?- likes_something. 

你會得到

true ; 
true ; 
true. 

出現這種情況是因爲序言發現三種方式來滿足likes_something/0謂詞(包括prolog,haskell和erlang),所以它回答三次。

這不完全是一個問題;隨時可以按,prolog將停止嘗試找到答案(當有很多結果時,這非常方便)。

同樣的事情發生在你的謂詞上:有三種解決方案,並按下;你強迫序言找到他們。因爲Rocha建議你可以使用findall/3。例如,你可以寫:

likes_something:- 
    findall(X, likes(X), _). 

,這將只返回一個yes

但是,它並沒有提供比以前的版本的詳細信息;相反,它隱藏了這樣的事實,即有三種解決方案和浪費時間試圖找到更多,而答案不會改變。 出於這個原因,我認爲你應該使用的findall/3,如果你真的想看到結果:

likes_all(L):- 
    findall(X,likes(X),L). 
當然

,你是否需要看到的結果或不取決於你的決定(或者更確切地說,這個問題你正在試圖解決:p)

另一種選擇是使用切:!/0 例如:

likes_something:- 
    likes(_Something), 
    !. 

這將prolo停止克從尋找更多的解決方案,你會得到一個真實的。但是請注意,剪切可能會非常棘手。

總而言之: 如果你想讓序言搜索所有的答案(如果你決定把它們放在一個列表中或者你的謂詞有副作用或者你只是想要它):findall/3

,如果你不希望有以尋找更多的答案選項:(!/ 0)使用切割

否則只是按enter鍵代替;

0

可以使用的findall/3謂詞:

的findall(對象,目標,列表)。 產生一個列表滿足目標Goal的所有對象Object。通常,Object只是一個變量,在這種情況下,查詢可以被讀爲:給我一個包含滿足Goal的Object的所有實例的列表。

我想這就是你想要的。

0

如果您希望謂詞最多成功一次,那麼您可以使用SWI提供的一次/ 1。

在您的例子:

?- once(get_all_transformed_moves). 
true.