我正在尝试在SWI Prolog中解决此问题,我的代码目前看起来像这样:
insert(L1,X,L2):-
COUNTER = 1,
NEXT = 1,
insert_plus(L1,COUNTER,NEXT,X,L2).
insert_plus([],_,_,_,[]).
insert_plus([H|T],COUNTER,NEXT,X,[H|T1]) :- % don't insert
COUNTER \= NEXT,
insert_plus(T,COUNTER+1,NEXT,X,T1).
insert_plus([H|T],COUNTER,NEXT,X,[H|[X|T]]) :- % DO insert
COUNTER = NEXT,
insert_plus(T,COUNTER+1,NEXT*2,X,T).
有人可以解释为什么这并不总是按预期工作?
?- insert([1,2,3,4,5,6,7],9,X). X = [1,9,2,3,4,5,6,7]. % BAD! expected: `X = [1,9,2,9,3,4,9,5,6,7]`
答案 0 :(得分:1)
Prolog没有评估表达,它证明了关系。因此必须明确地进行算术运算。这里
...
insert_plus(T, COUNTER+1, NEXT, X, T1).
你需要
...
SUCC is COUNTER+1,
insert_plus(T, SUCC, NEXT, X, T1).
同样的问题 - 包括COUNTER和NEXT - 出现在最后一条规则中。
答案 1 :(得分:1)
您需要更改的绝对最低要求是:
insert_plus([],_,_,_,[]). insert_plus([H|T],COUNTER,NEXT,X,[H|T1]) :- COUNTER =\= NEXT, % `(=\=)/2` arithmetic not-equal insert_plus(T,COUNTER+1,NEXT,X,T1). insert_plus([H|T],COUNTER,NEXT,X,[H|[X|T1]]) :- % use `T1`, not `T` COUNTER =:= NEXT, % `(=:=)/2` arithmetic equal insert_plus(T,COUNTER+1,NEXT*2,X,T1). % use `T1` (as above)
示例查询:
?- insert([1,2,3,4,5,6,7],9,X). X = [1,9,2,9,3,4,9,5,6,7]. % expected result
除了上述更改,我建议您注意@CapelliC给出的
in his answer关于使用内置Prolog谓词(is)/2
的算术表达式评估...
......或者更好的是,使用clpfd!