List Prolog从列表中删除元素

List Prolog从列表中删除元素,list,prolog,List,Prolog,我有以下事实来删除列表中所有出现的元素。虽然输出是正确的,但元素只是被替换为空白 remover( _, [], []). remover( R, [R|T], [T2]) :- remover( R, T, T2). remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2). 调用remover时,输出为: remover(3,[1,2,3,4,3],Res) Res = [1, 2, [4, []]] 我还有以下事实,仅删除第一次出

我有以下事实来删除列表中所有出现的元素。虽然输出是正确的,但元素只是被替换为空白

remover( _, [], []).
remover( R, [R|T], [T2]) :- remover( R, T, T2).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).
调用remover时,输出为:

remover(3,[1,2,3,4,3],Res)
Res = [1, 2, [4, []]]
我还有以下事实,仅删除第一次出现,但输出与上面相同

remover_primeira( _, [], []).
remover_primeira( R, [R|T], [T2]) :-remover_primeira( R, T, T2),!.
remover_primeira( R, [H|T], [H|T2]) :- H \= R, remover_primeira( R, T, T2).

我做错了什么?

您不应该在第二个子句中将T2包装在单例列表中,它应该是:

remover( _, [], []).
remover( R, [R|T], T2) :- remover( R, T, T2).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).
如果您只需要删除第一个引用,那么您不应该从找到该元素的那一刻起重复:

remover( _, [], []).
remover( R, [R|T], T).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).
在第二个子句中,不应将T2包装在单例列表中,它应该是:

remover( _, [], []).
remover( R, [R|T], T2) :- remover( R, T, T2).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).
如果您只需要删除第一个引用,那么您不应该从找到该元素的那一刻起重复:

remover( _, [], []).
remover( R, [R|T], T).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).

@WillemVanOnsem的解决方案源自操作代码,在将要删除的元素与列表中的元素进行比较时使用术语统一。另一种方法是使用术语相等。该解决方案适用于地面条件。但如果条款不成立,可能会导致意外的结果。例如:

| ?- remover(a(_), [a(1), b(2), a(3), b(4)], List).

List = [b(2),a(3),b(4)] ? ;
no
考虑以下remover/3谓词的替代定义:

remover(_, [], []).
remover(R, [H|T], T2) :- \+ H \= R, remover(R, T, T2).
remover(R, [H|T], [H|T2]) :- H \= R, remover(R, T, T2).
使用此解决方案,上面的查询给出:

| ?- remover(a(_), [a(1), b(2), a(3), b(4)], List).         

List = [b(2),b(4)] ? ;
no

确保对谓词的语义有清晰的理解

由@WillemVanOnsem提出的解决方案源自操作代码,在将要删除的元素与列表元素进行比较时使用术语统一。另一种方法是使用术语相等。该解决方案适用于地面条件。但如果条款不成立,可能会导致意外的结果。例如:

| ?- remover(a(_), [a(1), b(2), a(3), b(4)], List).

List = [b(2),a(3),b(4)] ? ;
no
考虑以下remover/3谓词的替代定义:

remover(_, [], []).
remover(R, [H|T], T2) :- \+ H \= R, remover(R, T, T2).
remover(R, [H|T], [H|T2]) :- H \= R, remover(R, T, T2).
使用此解决方案,上面的查询给出:

| ?- remover(a(_), [a(1), b(2), a(3), b(4)], List).         

List = [b(2),b(4)] ? ;
no

确保对谓词的语义有清晰的理解

如果只删除第一次发生的事件,该怎么办?我做错了什么?@FábioPires:那么你不应该在喜欢元素的情况下再次出现。非常感谢你。我发现Prolog中的递归很难理解,那么只删除第一次出现的递归呢?我做错了什么?@FábioPires:那么你不应该在喜欢元素的情况下再次出现。非常感谢你。我发现Prolog中的递归很难理解