Prolog -替换列表元素



所以我有一个程序,它有一个谓词,用给定的新元素替换列表中某个元素的第一次出现,并产生一个新列表。我是这样做的:

    changeFst(OldE,[OldE|T],NewE,[NewE|T]):-!.
    changeFst(OldE,[_|T],NewE,_):- changeFst(OldE,T,NewE,_),!.
例如如果你给

(2(1、2、3、4、2],10 X) 应该还给你 X =[1、10、3、4、2)

现在我正在制作更改最后出现的部分(在示例中它将返回X=[1,2,3,4,10])。这是我的代码:

    changeLast(OldE,OldL,NewE,NewL):-
       reverse(OldE,X), 
       changeFst(OldE,X,NewE,NewL),
       !.

所以这实际上很好但问题是它返回的是反向的列表(在上面的例子中它返回的是[10,4,3,2,1]而不是[1,2,3,4,10])

我怎样才能再次反转以正确显示我的答案?

你对changeFst/4的定义在许多方面是不正确的,比如changeFst(o,[o,o],n,[m,y,s,t,e,r,y]).成功了,但显然它应该失败。原因是你对cuts的用法不正确。如果您想学习Prolog,请首先坚持学习纯声明性子集。这意味着没有伤口,也没有副作用。

这是一个不依赖于剪切的定义:

changeFst(Old,[Old|Olds],New,[New|Olds]).
changeFst(Old,[E|Olds],New,[E|News]):-
   dif(Old, E),
   changeFst(Old,Olds,New,News).

这种纯关系的一个优点是,我们可以使用最一般的查询来查看我们得到的答案:

?- changeFst(Old, Olds, New, News).
   Olds = [Old|_A], News = [New|_A]
;  Olds = [_A,Old|_B], News = [_A,New|_B], dif(Old,_A)
;  Olds = [_A,_B,Old|_C], News = [_A,_B,New|_C],
   dif(Old,_A), dif(Old,_B)
;  Olds = [_A,_B,_C,Old|_D], News = [_A,_B,_C,New|_D],
   dif(Old,_A), dif(Old,_B), dif(Old,_C)
; ... .

你注意到答案总是包含Olds a 部分列表吗?如:第一个答案中的Olds = [Old|_A]。这可能有点太笼统了,毕竟这意味着现在甚至非列表也被接受了:

?- changeFst(o,[o|nonlist], New, News).
   News = [New|nonlist]
;  false.

所以你可能想确保OldsNews总是列表。

但是我想说明的是,我想告诉你的是,在纯关系中,你可以看到很多东西,这些东西是被截断的程序无法直接显示的。

如果我们在它:如何处理空列表?当前版本表明changeFst/4应该失败。不确定你想要什么,但如果你想要它成功,首先添加一个事实changeFst(_,[],_,[]).

如果您的Prolog不支持dif/2 (Prolog -dif),请参阅此答案。

按照@false:

的建议,使用if_/3(=)/3来保持纯净和高效。
changeFst(Old,Olds,New,News) :-
   list_change_first_(Olds,News,Old,New).
list_change_first_([],[],_,_).
list_change_first_([X|Xs],[Y|Ys],Old,New) :-
   if_(X = Old, (Y = New, Ys = Xs),
                (Y = X,   list_change_first_(Xs,Ys,Old,New))).
示例查询:

?- changeFst(2,[1,2,3,4,2],10,Xs).
Xs = [1,10,3,4,2].                         % succeeds deterministically
?- changeFst(o,[o,o],n,[m,y,s,t,e,r,y]).
false.                                     % expected result
?- changeFst(Old,Olds,New,News).
Olds = [],             News = []                                       ;
Olds = [Old|_A],       News = [New|_A]                                 ;
Olds = [_A],           News = [_A],           dif(_A,Old)              ;
Olds = [_A,Old|_B],    News = [_A,New|_B],    dif(_A,Old)              ;
Olds = [_A,_B],        News = [_A,_B],        dif(_A,Old), dif(_B,Old) ;
Olds = [_A,_B,Old|_C], News = [_A,_B,New|_C], dif(_A,Old), dif(_B,Old) % and so on...

相关内容

  • 没有找到相关文章

最新更新