2014-02-19 63 views
-2

我需要定義一個謂詞來檢測列表是否包含重複的元素。我無法使用findall/3或相關謂詞。我不想刪除重複項,我想知道是否存在重複或重複的元素,然後在集合中存在重複項的情況下使用Prolog輸出'yes',如果沒有重複項,則選擇'否'。我是Prolog的新手,我不知道如何在Prolog中不使用謂詞的情況下做到這一點。我需要想出一個新的(如冗餘/ 1或其他性質)。有人能幫助嗎?創建一個謂詞來檢測列表是否包含Prolog中的重複元素

+1

你可以做任何的嘗試呢?這是作業嗎? – lurker

+0

什麼樣的謂詞被認爲與'findall/3'有關?你允許使用'member/2'嗎?只需編寫一個使用'member/2'的版本,然後編寫你自己的'member/2'。這相當微不足道。 – lurker

+0

只需重新執行'findall'。問題解決了。 – nhahtdh

回答

2

一個有趣的方式:使用sort/2對列表進行排序,刪除重複項。檢查初始列表的長度是否大於排序列表的長度。

redundant(List) :- 
    sort(List, Sorted), 
    length(List, A), 
    length(Sorted, B), 
    A > B. 
+0

不,我不能使用Prolog已經內置的代碼。我想到了這樣的: 冗餘(X,X)。 冗餘([X | L]): - 紅色(X,L)。 冗餘([_ | L]): - 冗餘(L)。 red(X,[X | _])。紅(X,[_ | L]): - 紅(X,L)。 但它在Prolog中顯示錯誤。 – user3330438

+1

使用您嘗試的代碼更新問題(或創建一個新問題),並更明確地描述可以使用什麼和不能使用什麼。 –

2

你的問題有一個含糊之處:你是什麼意思的重複元素?根據(=)/2(邏輯相等),(==)/2(語法相等)還是(=:=)/2(算術相等)應該相等。

我會假設第一個。

以語法立場:

contains_duplicate(L) :- 
    phrase((..., [E], ..., [E], ...), L). 

... --> [] | [_], ... . 

現在,我們不僅可以測試一些元素的具體名單,但我們甚至可以問一般問題(我將在這裏使用GNU-Prolog的,其綜合的原因輸出):

| ?- contains_duplicate(L). 
L = [A,A] ? a 
L = [A,A,_] 
L = [A,A,_,_] 
L = [A,A,_,_,_] 
L = [A,A,_,_,_,_] 
L = [A,A,_,_,_,_,_] 
L = [A,A,_,_,_,_,_,_] 
L = [A,A,_,_,_,_,_,_,_] 
L = [A,A,_,_,_,_,_,_,_,_] ... 

所以Prolog給我們提供了前兩個元素作爲重複項的所有列表。其他可能性在哪裏?不幸的是,它們隱藏在這個無限次序的答案後面。但是,我們有運氣,我們可以做一個公平枚舉像這樣所有的答案

| ?- length(L,_),contains_duplicate(L). 
L = [A,A] ? a 
L = [A,A,_] 
L = [A,_,A] 
L = [_,A,A] 
L = [A,A,_,_] 
L = [A,_,A,_] 
L = [A,_,_,A] 
L = [_,A,A,_] 
L = [_,A,_,A] 
L = [_,_,A,A] 
L = [A,A,_,_,_] ... 
相關問題