2015-11-26 179 views
1

我是新來的Prolog,我試圖理解它。只填充一個列表,只發生多個列表元素

我開始用一些簡單的程序,這應該:

  • 檢查元素是否包含在列表的其餘部分
    • 如果FALSE什麼都不做
    • 如果真把它添加到第二個列表。 (只有一個字符應該添加到第二個列表中)。

與預期結果的一些例子:

?- occ([a,b,c,a,a,b,e,f,g], Y). 
Y = [a,b]. 

?- occ([a,a,a,a,a], Y). 
Y = [a]. 

?- occ([a,b,c,d,e,f,g], Y). 
Y = []. 

這是我寫的代碼,但我有一些問題(它總是返回true)。

occ([],[]). 
occ([],_Y). 
occ([X|Xs],[X|Y]) :- 
    occ(Xs,Y), 
    member(X,Xs), 
    not(member(X,Y)), 
    !. 
occ([_X|_Xs],_Y). 

我嘗試使用調試器,我發現not(member(X,Y))總是false並在綁定區段只有XXs永不Y。任何意見非常感謝!謝謝。

UPDATE

我想我解決了這個問題,下面的代碼:

occ([],[]). 
occ([X|Xs],[X|Y]) :- 
    occ(Xs,Y), 
    member(X,Xs), 
    not(member(X,Y)), 
    !. 
occ([_X|_Xs],[]). 

但我真的不知道爲什麼現在的工作......在3個occ我改變_Y[] .. 但爲什麼它會改變結果?

+1

你的謂詞總是返回true,因爲你有兩個子句一起接受任何列表參數併成功。如果第一個參數是空列表'[]',則無論第二個參數是什麼,'occ([],_Y).'總是會成功。如果第一個參數是至少一個元素的列表,並且不管第二個參數是什麼,那麼'occ([_ X | _Y],_Y).'將始終成功。你想要做的就是確保每個條款都是有意義的,只要表達一個關於它的論點的有效規則即可。 – lurker

+0

我試着更改我的代碼,但是我無法實現我期待的內容......請你幫我多一點嗎?我想我錯過了一些東西。 – Marcx

+0

如果你用最新的變化來編輯你的問題,知道你現在的想法在哪裏,它可能會有所幫助。 – lurker

回答

2

在這個答案中我們使用tpartition/4結合if_/3(=)/3

我們定義list_duplicateset/2這樣的:

 
list_duplicateset([], []). 
list_duplicateset([E|Xs0], Ys0) :- 
    tpartition (= (E), Xs0, Es, Xs), 
    if_ (Es  = [], 
     Ys0 = Ys, 
     Ys0 = [E|Ys]), 
    list_duplicateset(Xs, Ys). 

首先,我們運行從this answer to a similar question抽取的樣本查詢:

?- list_duplicateset([1,2,2,3,4,5,7,6,7], Xs). 
Xs = [2,7]. 

接下來,讓我們運行的OP給了疑問:

?- list_duplicateset([a,b,c,a,a,b,e,f,g], Xs). 
Xs = [a, b]. 

?- list_duplicateset([a,a,a,a,a], Xs). 
Xs = [a]. 

?- list_duplicateset([a,b,c,d,e,f,g], Xs). 
Xs = []. 

請注意,上面列出的所有查詢都是 給出預期的答案,確定性地成功

相關問題