使用SWI Prolog,有一个谓词可以在名为nth1的列表中找到第n个项目。我想实现我自己的谓词版本,但如果你查看列表(第1个)代码,SWI是如此复杂。有没有更简单的方法呢?
谢谢你:)。
答案 0 :(得分:4)
考虑将有限域约束用于一般(可逆)整数运算:
:- use_module(library(clpfd)).
nth1(1, [E|_], E).
nth1(N, [_|Xs], E) :-
N #> 1,
N #= N1 + 1,
nth1(N1, Xs, E).
答案 1 :(得分:2)
SWI代码有点复杂,因为谓词可用于从变量索引生成:
?- nth1(Idx,[a,b,c],X).
Idx = 1,
X = a ;
Idx = 2,
X = b ;
Idx = 3,
X = c ;
false.
如果您不想要这种行为,可以nth1/3
轻松实现nth0
:
nth1(Idx,List,X) :-
Idx0 is Idx-1,
nth0(Idx0,List,X).
修改:只需几行代码就可以不用nth0
:
nth1(1,[X|_],X) :- !.
nth1(Idx,[_|List],X) :-
Idx > 1,
Idx1 is Idx-1,
nth1(Idx1,List,X).
答案 2 :(得分:2)
我并不是说要相互矛盾或让别人去做我的工作;我只是想要一些建议,抱歉没有更清楚。
我现在已经实现了它,但你们可能会建议改进或更好的方法吗?我经常发现自己在Prolog中所做的是编写一个带有一个计数器或一组计数器的谓词,并获得一个带有较少参数的谓词来调用具有额外参数的子句。这往往会产生相当多的代码。无论如何,这是我刚才的实施:
item_at( N, L, Item ) :-
item_at( N, 0, L, Item ).
item_at( N, Count, [H|_], Item ) :-
CountNew is Count + 1,
CountNew = N,
Item = H.
item_at( N, Count, [_|T], Item ) :-
CountNew is Count + 1,
item_at( N, CountNew, T, Item ).
有何评论?谢谢 :)。用法:
?- item_at(3,[a,b,c,d,e],Item).
Item = c ;