Prolog 如何在不剪切的情况下从列表中删除第一个匹配元素

Prolog 如何在不剪切的情况下从列表中删除第一个匹配元素,prolog,Prolog,我试图在不使用回溯的情况下从列表中删除第一个匹配项,基本上是元素的第一次出现,然后停止回溯,不再提供更多的解决方案 我有一个非常有效的方法: % delete an item from a list, only one, no back tracking, using cut delete_one( X, [X|Tail], Tail ) :- !. delete_one( X, [Y|Tail], [Y|Tail1] ) :- delete_one(X,Tail,Tail1). 这很有效。我

我试图在不使用回溯的情况下从列表中删除第一个匹配项,基本上是元素的第一次出现,然后停止回溯,不再提供更多的解决方案

我有一个非常有效的方法:

% delete an item from a list, only one, no back tracking, using cut
delete_one( X, [X|Tail], Tail ) :- !.
delete_one( X, [Y|Tail], [Y|Tail1] ) :- delete_one(X,Tail,Tail1).
这很有效。我的问题是在不使用cut的情况下实现相同的目标,而是使用
not
谓词。这就是我尝试过的:

% the same as above without using cut
delete_one_no_cut(X,[X|Tail],Tail).
delete_one_no_cut(X,[Y|Tail],[Y,Tail1]) :-
  not(X==Y),
  delete_one_no_cut(X,Tail,Tail1).

它不起作用。你能帮我吗?

操作顺序。大多数递归问题有1或2个终止特殊情况和一个一般递归情况。您有两种特殊情况:

x_list_list2(X,[X|T],T).
x_list_list2(X,[H|T],[H|New]):-
    dif(X,H),
    x_list_list2(X,T,New).
  • 一旦你找到一个空列表,你就完成了
  • 一旦你在列表的最前面找到一个匹配的词,你就完成了
还有一种常见的递归情况:

  • 列表的标题与提供的值不匹配
诀窍在于评估的顺序。试着这样做:

delete_first( _ , []    , []     ) .
delete_first( X , [H|T] , [H|T1] ) :- X \= H , delete_first(X, T, T1 ) .
delete_first( X , [X|T] , T      ) .

操作顺序。大多数递归问题有1或2个终止特殊情况和一个一般递归情况。您有两种特殊情况:

  • 一旦你找到一个空列表,你就完成了
  • 一旦你在列表的最前面找到一个匹配的词,你就完成了
还有一种常见的递归情况:

  • 列表的标题与提供的值不匹配
诀窍在于评估的顺序。试着这样做:

delete_first( _ , []    , []     ) .
delete_first( X , [H|T] , [H|T1] ) :- X \= H , delete_first(X, T, T1 ) .
delete_first( X , [X|T] , T      ) .

注意第二类的第三个参数中的
。它应该是
[Y | Tail1]
。另外,不要使用
not/1
而使用
\+/1
或直接使用
X\=Y
(或
dif/2
)注意第二类第三个参数中的
。它应该是
[Y | Tail1]
。另外,与使用
not/1
相反,使用
\+/1
或直接使用
X\=Y
(或
dif/2
)为什么要在我的版本上使用此版本?我的版本考虑了空列表。如果源列表为空或未找到匹配项,则您的操作将失败。此外,您的解决方案使用的是
dif/2
,这不是标准的ISO prolog。请求使用的是
not
/1,而
A\=B
在语义上与
not(A=B)
相同,而
dif/2
则不是。好吧,我认为如果找不到,失败是有意义的,您的
delete_first(X,[1,2],Y),X=2失败。
这可能是一个问题,取决于使用情况<代码>非/1和
\=
实现有一个缺口,我想。为什么你要使用这个版本而不是我的版本?我的版本考虑到了空列表。如果源列表为空或未找到匹配项,则您的操作将失败。此外,您的解决方案使用的是
dif/2
,这不是标准的ISO prolog。请求使用的是
not
/1,而
A\=B
在语义上与
not(A=B)
相同,而
dif/2
则不是。好吧,我认为如果找不到,失败是有意义的,您的
delete_first(X,[1,2],Y),X=2失败。
这可能是一个问题,取决于使用情况<代码>非/1和
\=
我认为实现有一个缺口。