List 列表替换中的Prolog元素

List 列表替换中的Prolog元素,list,replace,prolog,List,Replace,Prolog,嗨,我想知道你是否能帮我解决这个问题 从Prolog编程:编写Prolog脚本,用另一个给定元素替换列表中的任何给定元素。例如: replace( 3, a,[1,2,3,4,3,5], [1,2,a,4,a,5])=true 非常感谢在Prolog中,大多数列表处理都是先处理头部,然后递归处理列表的其余部分。当然,您不能忘记基本情况,它是一个空列表 用空列表中的任何内容替换任何内容将再次导致空列表。如果列表的标题与要替换的元素相同,请替换它,否则请保持原样。在这两种情况下,递归地处理列表的其

嗨,我想知道你是否能帮我解决这个问题

从Prolog编程:编写Prolog脚本,用另一个给定元素替换列表中的任何给定元素。例如:

replace( 3, a,[1,2,3,4,3,5], [1,2,a,4,a,5])=true

非常感谢在Prolog中,大多数列表处理都是先处理头部,然后递归处理列表的其余部分。当然,您不能忘记基本情况,它是一个空列表

用空列表中的任何内容替换任何内容将再次导致空列表。如果列表的标题与要替换的元素相同,请替换它,否则请保持原样。在这两种情况下,递归地处理列表的其余部分。从英文翻译成序言:

replace(_, _, [], []).
replace(O, R, [O|T], [R|T2]) :- replace(O, R, T, T2).
replace(O, R, [H|T], [H|T2]) :- H \= O, replace(O, R, T, T2).
不过,人们通常会安排3个。arg将成为第一个。严格地说,上面并没有替换列表中的任何内容,它只是说明了第四个参数是否与第三个参数类似,但用Y'代替X'

replace(E,S,[],[]).
replace(E,S,[E|T1],[S|T2]):-replace(E,S,T1,T2).
replace(E,S,[H|T1],[H|T2]):-E\=H, replace(E,S,T1,T2).
这个想法很简单,如果元素匹配,就对其进行更改,如果不匹配,就继续执行直到空为止。

到目前为止,在其他答案中给出的所有实现在逻辑上都是不合理的,当与非基本术语一起使用时。考虑原始查询和一个小的变型:

domains
I=integer*
K=integer*
Z=integer
A=integer
predicates
nondeterm  rep(I,Z,A,K)
clauses
rep([],_,_,[]).
rep([Z|T1],Z,A,[A|T2]):- rep(T1,Z,A,T2).
rep([H|T1],Z,A,[H|T2]) :- rep(T1,Z,A,T2).
goal
rep([1,2,3],2,4,X).
?- replace(3,three,[1,2,3],Xs).
Xs = [1,2,three] ;                 % OK: correct
false

?- A=3, replace(A,B,[1,2,3],Xs).   % OK: correct
Xs = [1,2,B], A = 3 ;
false
它起作用了!让我们问一些非常类似的问题:

?- replace(A,B,[1,2,3],Xs).        % FAIL: should succeed more than once...
Xs = [B,2,3], A = 1 ;              %       ... but the other solutions are missing 
false

?- replace(A,B,[1,2,3],Xs), A=3.   % FAIL: this query _should_ succeed ...
false                              %       ... it does not!

发生什么事了?把责任归咎于元逻辑内置的
(!)/0
(\=)/2
,它们很难正确使用,并且常常使代码脆弱、不纯净、逻辑不健全

为了保持逻辑的可靠性,坚持逻辑的纯洁性并尽可能避免元逻辑的“特征”!幸运的是,大多数Prolog实现支持
dif/2
,作为
(\=)/2
的逻辑替代方案。让我们使用它:

% code by @svick, modified to use dif/2 instead of (\=)/2
replaceP(_, _, [], []).
replaceP(O, R, [O|T], [R|T2]) :- replaceP(O, R, T, T2).
replaceP(O, R, [H|T], [H|T2]) :- dif(H,O), replaceP(O, R, T, T2).
让我们再次运行上述查询,这次使用改进的
replacepp/4

?- replaceP(3,three,[1,2,3],Xs).
Xs = [1,2,three] ;                 % OK: correct, like before
false

?- replaceP(A,B,[1,2,3],Xs).       % OK: four solutions, not just one
Xs = [B,2,3], A = 1 ;         
Xs = [1,B,3], A = 2 ;
Xs = [1,2,B], A = 3 ;
Xs = [1,2,3], dif(A,1),dif(A,2),dif(A,3) ;
false

?- replaceP(A,B,[1,2,3],Xs), A=3.  % OK (succeeds now)
Xs = [1,2,B], A = 3 ;                 
false
?- A=3, replaceP(A,B,[1,2,3],Xs).  % OK (same as before)
Xs = [1,2,B], A = 3 ;
false

我还没有试过什么,我不知道该怎么做。
?- replaceP(3,three,[1,2,3],Xs).
Xs = [1,2,three] ;                 % OK: correct, like before
false

?- replaceP(A,B,[1,2,3],Xs).       % OK: four solutions, not just one
Xs = [B,2,3], A = 1 ;         
Xs = [1,B,3], A = 2 ;
Xs = [1,2,B], A = 3 ;
Xs = [1,2,3], dif(A,1),dif(A,2),dif(A,3) ;
false

?- replaceP(A,B,[1,2,3],Xs), A=3.  % OK (succeeds now)
Xs = [1,2,B], A = 3 ;                 
false
?- A=3, replaceP(A,B,[1,2,3],Xs).  % OK (same as before)
Xs = [1,2,B], A = 3 ;
false