List 替换嵌套列表中的一个或多个元素

List 替换嵌套列表中的一个或多个元素,list,replace,prolog,List,Replace,Prolog,我正努力做到这一点: 给定OldList,如果项目满足目标,则更换任何项目(oldNew);如果不是,请不要更换该项目 返回一个带有替换项的NewList,替换项的结构(即嵌套)与OldList相同 对于特殊情况OldList=[a,b,c]我可以使用它(参见我的代码),但我想编写一个谓词,它可以泛化列表长度和嵌套列表,例如OldList=[a,[b,c,[d,e]]] 提前谢谢! /JC 编辑1: 让它可以处理任意长度的列表;但我仍然不知道如何处理嵌套列表 replace2(OldList,

我正努力做到这一点:

给定
OldList
,如果项目满足目标,则更换任何项目
(oldNew)
;如果不是,请不要更换该项目

返回一个带有替换项的
NewList
,替换项的结构(即嵌套)与
OldList
相同

对于特殊情况
OldList=[a,b,c]
我可以使用它(参见我的代码),但我想编写一个谓词,它可以泛化列表长度和嵌套列表,例如
OldList=[a,[b,c,[d,e]]]

提前谢谢! /JC

编辑1:

让它可以处理任意长度的列表;但我仍然不知道如何处理嵌套列表

replace2(OldList, NewList):-
    [H | T] = OldList,
    oldNew(H, NewHead),
    NewList = [NewHead | T].
replace2(OldList, NewList):-
    [H | T] = OldList,
    replace2(T, NewTail),
    NewList = [H | NewTail].

通常,模式匹配在头部是明确的。代码更清晰:

replace2([], []).
replace2([H|T], [Ht|Tt]) :-
  (  oldNew(H, Ht)
  -> true
  ;  is_list(H)
  -> replace2(H, Ht)
  ;  H = Ht
  ),
  replace2(T, Tt).
在SWI Prolog库中,并允许稍短的代码:

replace2(L, T) :- maplist([H,Ht]>>
  (  oldNew(H, Ht)
  -> true
  ;  is_list(H)
  -> replace2(H, Ht)
  ;  H = Ht
  ), L, T).
可以看到,括号内的析取已从以前的定义中复制和粘贴。这是一个lambda应用程序

?- replace2([aa, car, apple, fruit, any, [aa, car, apple, banana, any]], T).
T = [aa, ferrari, apple, banana, any, [aa, ferrari, apple|...]].

很好地使用了
apply
yall
?- replace2([aa, car, apple, fruit, any, [aa, car, apple, banana, any]], T).
T = [aa, ferrari, apple, banana, any, [aa, ferrari, apple|...]].