我不知道如何阻止它进入循环

时间:2017-09-26 19:13:02

标签: prolog

问题是要创建一个replace/4谓词,将第一个列表中的某个元素(X)替换为Y之类的另一个元素(x),最后将它存储到最后一个参数中,一个新列表。我知道我的基本情况(?)显然有问题,但我似乎无法弄明白。当我跟踪这段代码时,它开始正常,但在第一个列表为空之后,它开始添加匿名变量。请怜悯,我是Prolog的新手。

replace([], _, _, []).
replace([H|T], X, Y, N):-
  H = X,
  append(N, [Y], NL),
  replace(T, X, Y, NL).
replace([H|T], X, Y, N):-
  H \= X,
  append(N, [H], NL),
  replace(T, X, Y, NL).

1 个答案:

答案 0 :(得分:3)

没有append/3的简单更有效的解决方案是:

replace([], _, _, []).
replace([X|T], X, Y, [Y|T1]):-replace(T, X, Y, T1).
replace([H|T], X, Y, [H|T1]):-dif(X,H), replace(T, X, Y, T1).

请注意,使用谓词dif/2代替\=运算符要好得多(它有更多关系行为:只需测试dif(X,Y).X\=Y. X,Y不绑定变量看差异)。

示例:

?- replace([2,4,5,7,8,2,3,4],2,12,L).
L = [12, 4, 5, 7, 8, 12, 3, 4] ;
false.

另一种解决方案是使用DCG:

replace([],_,_) -->[].
replace([X|T],X,Y) --> [Y],replace(T,X,Y).
replace([H|T],X,Y) --> [H],{dif(H,X)},replace(T,X,Y).

final_replace(In_L,X,Y,Out_L):- phrase(replace(In_L,X,Y),Out_L).

示例:

?- final_replace([2,4,5,7,8,2,3,4],2,12,L).
L = [12, 4, 5, 7, 8, 12, 3, 4] ;
false.