2016-11-28 69 views
1

我有一個謂詞next實質上是從列表中刪除數字,試圖減少列表的整體大小。刪除重複在回溯

因此,例如,我有一個列表:

[3,2,1] 

接下來會從列表中刪除某些值,所以它會返回類似這樣

[3,2] or [3,1] or [3] or [2,1] etc 

我運行一個腳本找到所有可能的動作:

findall(T, next([2,3], T), U). 

問題是重複值的列表,如:

L = [1,1,1,1]. 

通話

findall(T, next([1,1,1,1], T), U). 

將統一U[[1,1,1], [1,1,1], [1,1,1], [1,1,1]]

有沒有辦法讓Prolog的理解,它是相同的輸出多次回國?

next([_ | T], T). 
next([H | Tin], [H | Tout]) :- 
    next(Tin, Tout). 

回答

1

這似乎是一個作品setof/3

setof(T, next([1,1,1,1], T), U) 

---編輯---

的OP說

這並做到這一點,但它是一個有點哈克修補程序,我正在尋找在下一個謂詞的變化

我不認爲這是一個很好的解決方案下面,我懷疑這是更好地利用setof/3與原next/2但是......

next(Lin, LLout) :- 
    nextH(Lin, [], LLout). 

nextH([], _, []). 
nextH([H | Tin], Pre, LLout1) :- 
    append(Pre, Tin, L), 
    append(Pre, [H], Pre0), 
    nextH(Tin, Pre0, LLout0), 
    (member(L, LLout0) 
    -> LLout1 = LLout0 
    ; LLout1 = [L | LLout0]). 

--- EDIT 2 ---

的OP問

你怎麼會在接下來的謂語用SETOF?

如果使用原來的next/2謂詞產生單打名單(但我記得nextH,「下一個幫手」)

nextH([_ | T], T). 
nextH([H | Tin], [H | Tout]) :- 
    nextH(Tin, Tout). 

next/2謂詞返回的唯一列表成爲一個簡單的列表(使用setof/3

next(Lin, LLout) :- 
    setof(Lout, nextH(Lin, Lout), LLout). 
+0

該做到的,但它是一個有點哈克修復,我期待在未來謂詞 – user3667111

+0

的改變@ user3667111 - 如果你要求改變它,你應該告訴我們你的'下一個/ 2' – max66

+0

當然,我已經添加到編輯 – user3667111