Simple nth1 predicate in Prolog

With SWI Prolog, there is a predicate that finds the nth item in a list called nth1. I want to implement my own version of the predicate, but SWI is so complicated if you look at the list code (nth1). Is there an easier way to do this?

Thanks:).

+4
source share
3 answers

SWI code is a bit complicated because the predicate can be used to generate a variable from the index:

?- nth1(Idx,[a,b,c],X). Idx = 1, X = a ; Idx = 2, X = b ; Idx = 3, X = c ; false. 

If you do not want this behavior, nth1/3 can be easily implemented from the point of view of nth0 :

 nth1(Idx,List,X) :- Idx0 is Idx-1, nth0(Idx0,List,X). 

Edit : You can also do without nth0 just a few lines of code:

 nth1(1,[X|_],X) :- !. nth1(Idx,[_|List],X) :- Idx > 1, Idx1 is Idx-1, nth1(Idx1,List,X). 
+2
source

Consider the use of finite-region constraints for general (reversible) integer arithmetic:

 :- use_module(library(clpfd)). nth1(1, [E|_], E). nth1(N, [_|Xs], E) :- N #> 1, N #= N1 + 1, nth1(N1, Xs, E). 
+4
source

I did not want to be contradictory or force someone else to do my job; I just need some advice, sorry for the ambiguity.

I implemented it myself, but could you guys suggest improvements or better ways to do this? What I often do in Prolog is to write a predicate with a counter or a set of counters and get a predicate with fewer arguments to invoke sentences with extra arguments. This often ends up creating quite a lot of code. Anyway, here I just made my implementation:

 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 ). 

Any comments? Thanks :). Using:

 ?- item_at(3,[a,b,c,d,e],Item). Item = c ; 
+2
source

All Articles