删除列表中项目的所有实例:Prolog

时间:2016-02-21 04:04:58

标签: prolog

removeAll(X, [ X | T], [ H1 | T1 ] ):-
      ( member ( X , T )
        -> removeAll ( X , T , [ H1 | T1 ] )
        ;[ H1 | T1 ] is T
      ).
removeAll ( X , [ H | T ] , L ):-
removeAll ( X , T , L2 ), append ( [ H ] , L2 , L ).

如果我通过“removeAll(2,[1,1,2],L)。”,
它给出错误“ERROR: is/2: Type error: 'evaluable' expected, found '[]' (an empty_list)”。

如果我传递“removeAll(1,[1,1,2],L).”,则返回false。

真的很困惑。我哪里错了?

2 个答案:

答案 0 :(得分:2)

首先,您必须考虑源列表为空的情况:

removeAll(_, [], []).

这也是停止条件。因为您正在构建递归谓词,删除目标列表头部中与特定元素匹配的每个元素,直到列表为空

第二个子句,如果元素是List的Head,则不要将它复制到Result列表,并继续使用Tail进行递归调用。

removeAll(X, [X|T], L):- removeAll(X, T, L), !.

第三个子句,将列表头部的元素复制到Result列表,然后继续使用Tail进行递归调用。

removeAll(X, [H|T], [H|L]):- removeAll(X, T, L ).

你的谓词:

removeAll(_, [], []).
removeAll(X, [X|T], L):- removeAll(X, T, L), !.
removeAll(X, [H|T], [H|L]):- removeAll(X, T, L ).

答案 1 :(得分:1)

保持安全,站在的一边!

根据 tfilter/3dif/3,我们可以像这样定义removeAll/3

removeAll(X, Es, Xs) :-
   tfilter(dif(X), Es, Xs).

OP给出的查询的一些变体:

?-        removeAll(1, [1,1,2], Xs).
Xs = [2].

?- X = 1, removeAll(X, [1,1,2], Xs).
X = 1, Xs = [2].

?-        removeAll(X, [1,1,2], Xs), X = 1.
   X = 1, Xs = [2]
;  false.

?- X = 1, removeAll(X, [1,1,2], Xs), X = 1.
X = 1, Xs = [2].

更多查询显示更专业和更通用的用途:

?- removeAll(a, [a,b,c], [a,b,c]).
false.                               % as expected

?- removeAll(X, [a,b,c], Xs).
   Xs = [  b,c],     X=a
;  Xs = [a,  c],               X=b
;  Xs = [a,b  ],                         X=c
;  Xs = [a,b,c], dif(X,a), dif(X,b), dif(X,c).