2016-03-08 63 views
2
  1. 寫謂詞allDistinct/1,其參數爲(符號)的列表,並且成功,如果列表中的所有符號是不同的。序言:覈對重複列表中的

    notin(A,[]). 
    
    notin(A,[B|C]) :- A\=B, notin(A,C). 
    
    allDistinct([]). 
    
    allDistinct([_]). 
    
    allDistinct([A|B]) :- notin(A,B), 
    
    allDistinct(B). 
    
+3

'allDistinct(B)'說* *任何列表都是不同的!並且...請指出您需要幫助。你還沒有問過問題。 – lurker

+0

除了縮進,allDistinct(B)調用我不明白爲什麼這個代碼不應該工作。子句allDistinct([_])似乎也是多餘的。 –

回答

4

謂語sort/2排序,並從列表中刪除重複項。您可以使用它,比較與舊的新的排序列表長度(length/2謂語),如果他們不同,有一些重複值。

+1

直向,s(X)。但**也確保足夠的實例**! – repeat

4

上一sketch by @whd跟進,我們可以繼續這樣的:

下面我們使用SICStus Prolog的4.3.2:

 
:-use_module (library (lists)). 

allDistinct(Es) :- 
    ( ground (Es) 
    ->sort (Es, Fs), 
     same_length (Es, Fs) 
    ; throw (error (instantiation_error , 
        instantiation_error (allDistinct(Es),1))) 
    ). 

示例查詢:

 
| ?- allDistinct([1,2,3]). 
yes 
| ?- allDistinct([1,2,3.0]). 
yes 
| ?- allDistinct([1,2,3.0,2]). 
no 
| ?- allDistinct([1,2,3.0,X]). 
! Instantiation error in argument 1 of user:allDistinct/1 
! goal: allDistinct([1,2,3.0,_197]) 
0

這這些問題之一有相當多的替代合理解決方案。假設公共庫謂詞可以使用,這裏是另一個問題:

all_distinct(List) :- 
    \+ (
     select(Element, List, Tail), 
     select(Element, Tail, _) 
    ). 

這種解決方案的性能優點是,它就停止掃描列表作爲它找到一個重複元件。但是,它比基於標準sort/2謂詞解決方案快?不清楚sort/2是在大多數的Prolog系統的高度優化的謂詞。另外,我們沒有忘記,除非我們確信所有列表元素綁定,我們應該是安全的,並檢查它(見@Repeat答案)。