2015-11-19 88 views
1

我有以下事實:交易所參數

make(product_A, product_Z, product_Y). 
    make(P, X, Y) :- make(P, Y, X). 

我想,以確保從正在取得PRODUCT_A半產品(即product_Z和product_Y)爲真而不管它們的位置放一個問題。

所以我想這個查詢:

make(product_A, product_Y, product_Z). 

這一個:

make(product_A, product_Z, product_Y). 

應該由序言視爲等同(下同) - 即使我沒放在這兩種情況下作爲Prolog數據庫的事實。換句話說,我希望參數(product_Z和product_Y)在查詢中可交換。

但是當我把代碼放在開頭時,Prolog似乎重複了一個無限循環。

那麼我該如何做到這一點?

回答

6

無限推導的原因是有可能將參數翻轉回來(只要你喜歡)。您可以爲翻轉謂詞引入一個新名稱:

cmake(A,B,C) :- make(A,B,C). 
cmake(A,B,C) :- make(A,C,B). 

與一次解決方案相反,您保持邏輯上的純粹。儘管翻轉參數有效,但對於兩個以上的依賴關係,您按指數規律放大搜索空間(因爲您需要覆蓋n個參數的所有排列)。作爲替代,您可以傳遞一個排序的依賴關係列表作爲第二個參數。然後,您對輸入進行一次排序並進行查找。

+0

謝謝。因此,一個列表需要排序,因爲確保參數順序,然後我應該按字母順序創建所有事實? – forsberg

2

你需要一個once添加到您的規則,就像這樣:

make(A, B, C) :- once(make(A, C, B)).

這樣,就停止處理事實並不會在一個無限循環。