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。
真的很困惑。我哪里错了?
答案 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)
保持安全,站在logical-purity的一边!
根据meta-predicate tfilter/3
和dif/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).