我在Prolog中非常新,并试图在Prolog中实现获取列表的第n个元素 这是我的代码,但它会抛出错误
element_at(X,[X|_],1).
element_at(X,[_|L],K) :-
K > 1,
K1 is K - 1,
element_at(X,L,K1).
我认为代码右侧第二行的X必须用其他东西替换,但我想不出任何东西。
答案 0 :(得分:5)
测试时不评估K. 您需要撤销订单
element_at(X,[X|_],1).
element_at(X,[_|L],K) :- element_at(X,L,K1), K is K1 + 1.
答案 1 :(得分:1)
这是一个使用累加器的尾递归版本。使用累加器,它的值在每次调用时都已实例化,因此您可以先递增,然后进行递归。
element_at(X, List, Pos) :-
element_at(X, List, 1, Pos).
element_at(X, [X|_], Pos, Pos).
element_at(X, [_|T], Acc, Pos) :-
Acc1 is Acc + 1,
element_at(X, T, Acc1, Pos).
这适用于输入的变量的各种组合,但是如果Pos
被接地并且在找到可能的解决方案之后它(以及CapelliC的非尾递归版本)将无限循环,例如:
| ?- element_at(X, L, 3).
L = [_,_,X|_] ? ;
.... loop ....
因此,检查此案例的修改可以避免:
element_at(X, List, Pos) :-
element_at(X, List, 1, Pos).
element_at(X, [X|_], Pos, Pos).
element_at(X, [_|T], Acc, Pos) :-
(nonvar(Pos) -> Acc < Pos ; true), % fail if Acc hits ground Pos
Acc1 is Acc + 1,
element_at(X, T, Acc1, Pos).
现在你得到:
| ?- element_at(X, L, 3).
L = [_,_,X|_] ? ;
no.
和
| ?- element_at(X, L, P).
L = [X|_]
P = 1 ? ;
L = [_,X|_]
P = 2 ? ;
L = [_,_,X|_]
P = 3 ? ;
L = [_,_,_,X|_]
P = 4 ? ;
...etc...