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

3
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。
真的很困惑。我做错了什么?

1
你知道吗:通过消除语法错误,你可以改善你的问题!在开括号之前可能没有任何空格字符:member ( X , T ) 最好改为 member(X, T) - repeat
2个回答

9

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

removeAll(_, [], []).

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

第二个子句,如果元素是列表的头部,则不将其复制到结果列表中,并继续使用尾部进行递归调用。

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

第三条款,将列表Head中的元素复制到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 ).

好的。谢谢。明白了。 - Yogesh kumar
1
[tag:prolog-cut] 破坏了你的代码。目标 removeAll(a,[a,b,c],[a,b,c]) 成功,它应该失败 - repeat

1

保持安全,坚持一边!

基于 tfilter/3dif/3,我们可以这样定义removeAll/3

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

一些由原帖提供的查询变体:
?-        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.                               % 如预期所示
?- 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).

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接