List prolog-检查给定列表是否与模式匹配并替换某些元素
我遇到以下prolog代码的问题:List prolog-检查给定列表是否与模式匹配并替换某些元素,list,prolog,List,Prolog,我遇到以下prolog代码的问题: valid(X, Y) :- append([E1 | T2], [E1 | T3], X1), append([E1|T1], X1, X), append([E2 | T2], [E2 | T3], Y1), append([E2|T1], Y1, Y), E2 is E1 + 1. 我想做的是:对于给定的列表X,检查它是否匹配模式[E1,…,E1,…,E1,…];如果是,则将所有E1替换为E1+1。 ..部分中可以有任意数量的元
valid(X, Y) :-
append([E1 | T2], [E1 | T3], X1), append([E1|T1], X1, X),
append([E2 | T2], [E2 | T3], Y1), append([E2|T1], Y1, Y),
E2 is E1 + 1.
我想做的是:对于给定的列表X,检查它是否匹配模式[E1,…,E1,…,E1,…]
;如果是,则将所有E1
替换为E1+1
。
..
部分中可以有任意数量的元素,即T1
,T2
和T3
可以是任意长度
例如,我的预期输出是:
?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.
?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.
?- valid([1,5,6,7,8], Y).
false.
但现在我得到的实际输出是:
?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
ERROR: Out of global stack
?- valid([1,5,6,7,8], Y).
ERROR: Out of global stack
问题是,prolog将尝试尝试无限长的T1
、T2
和T3
,因此从不停止。因此,当我的输入列表X
与模式不匹配时,它会一直运行,直到内存空间不足
有没有办法修复我的代码,使其在找到所有可能的答案(可能不止一个)或X与模式不匹配时停止
谢谢
Append/3
谓词不是稳定的,因此它在开始时会计算其参数。因此,您需要在前面移动计算X的规则,如下所示:
valid(X, Y) :-
append([E1|T1], X1, X),append([E1 | T2], [E1 | T3], X1),
append([E2|T1], Y1, Y),append([E2 | T2], [E2 | T3], Y1),
E2 is E1 + 1.
由于对X求值,第一次追加不会导致尝试无限长的长度,第二次追加也是如此
一些例子:
?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.
?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.
?- valid([1,5,6,7,8], Y).
false.
?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.
?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.
?- valid([1,5,6,7,8], Y).
false.
?- valid(X, [2, 5, 2, 6, 7, 2, 8]).
X = [1, 5, 1, 6, 7, 1, 8] ;
false.
我更喜欢用一些简单的递归和E1的计数(并在输出列表中替换为E2)来解决这个问题,因为追加可能有点棘手
例如:
:- use_module(library(clpfd)).
valid([H|T], [H2|T2]):- H2 #= H+1 ,valid(H,T,T2,1).
valid(_,[],[],3).
valid(H,[H|T1],[H2|T2],Count):- H2 #= H+1, Count1 #= Count+1,valid(H,T1,T2,Count1).
valid(H,[H1|T1],[H1|T2],Count):- dif(H1,H), valid(H,T1,T2,Count).
还有一些例子:
?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.
?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.
?- valid([1,5,6,7,8], Y).
false.
?- valid([1,5,1,6,7,1,8], Y).
Y = [2, 5, 2, 6, 7, 2, 8] ;
false.
?- valid([1,5,6,1,7,1], Y).
Y = [2, 5, 6, 2, 7, 2] ;
false.
?- valid([1,5,6,7,8], Y).
false.
?- valid(X, [2, 5, 2, 6, 7, 2, 8]).
X = [1, 5, 1, 6, 7, 1, 8] ;
false.
使用CLPFD库可以使谓词更具关系性,因此正如您在上面的最后一个示例中所看到的那样,您可以进行如下查询:有效(X、[2,5,2,6,7,2,8])。
而之前不能(使用以前的解决方案)
以下是另一种替代方法:
new(H,H,R):- R is H+1.
new(H,N,N):- dif(N,H).
valid([H|T], Y):- findall(X1, (member(X1,[H|T]),X1 = H) , L),
length(L,3), maplist(new(H),[H|T],Y).
很乐意帮忙!!!,我已经尝试过用递归求解,并编辑了我的答案,希望能有所帮助!!。