2010-03-31 29 views
1

我是Prolog的新手,我試圖創建一個函數,它只是從列表中刪除一個元素的所有實例。下面的代碼是我到目前爲止有:在序言中創建一個'刪除成員'函數

remove([H|T], E, L2) :- (\+ ([H|T] == []) -> 
    (H == E 
     -> remove(T, E, L2) 
     ; append(L2, H, L2), remove(T, E, L2) 
    ) 
    ; append(L2, []) 
). 

當我運行該代碼:

remove([1,2,3,4,5], 3, L2). 

我得到一個錯誤:

ERROR: Out of global stack 

可能有人點我,爲什麼我我有這個問題嗎?

回答

3

本聲明

[H|T] == [] 

因爲一個空列表永遠不能等同於含有至少一個列表永遠是真實的一個元素。

+0

你是對的。然而,在每次迭代中,我傳遞一個較少的元素(尾部),這意味着最終,列表將沒有元素,遞歸應該停止。 至少這個想法... – screenshot345 2010-04-01 00:27:47

+0

你似乎來自不同的背景(命令式編程?),因此對Prolog的工作原理有一個基本的誤解。我建議你看一下列表處理謂詞的源代碼,比如member/2,append/3等。基本思想是列表是不可變的,並且刪除意味着將所有需要的元素從一個列表複製到另一個列表並忽略不需要的。即使T = [],[H | T] = []也不會成立,那麼你只有[H] = [],這不成立。 – Kaarel 2010-04-01 00:43:50

1

你需要的是一個SWI的斷言:

?- subtract([1,1,2,3,1],[1,2],R). 
R = [3]. 

?- listing(subtract). 
lists:subtract([], _, []) :- !. 
lists:subtract([A|C], B, D) :- 
     memberchk(A, B), !, 
     subtract(C, B, D). 
lists:subtract([A|B], C, [A|D]) :- 
     subtract(B, C, D). 

true. 
相關問題