Define predicate in prolog - list

I'm struggling with this one:
Define predicate len_NM(L,N,M) which checks if a certain list of lists L contains at least N elements with length no less than M.

The OP stated:
Define predicate len_NM(L,N,M) which checks if a certain list of lists L contains at least N elements with length no less than M.
In this answer we do not solve the original problem, but the following variation:
Define predicate len_NM(L,N,M) which checks if a certain list of lists L contains exactly N elements with length no less than M.
Similarly to this answer, we define dcg seqq1//1 to establish the relationship between a list of non-empty lists and its flattened opposite:
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
seqq1([]) --> [].
seqq1([Es|Ess]) --> {Es=[_|_]}, seq(Es), seqq1(Ess).
Sample use:
?- phrase(seqq1([[1,2],[3],[4]]),Xs).
Xs = [1,2,3,4].
Note that seqq1//1 works in "both directions":
?- phrase(seqq1(Xss),[1,2,3,4]).
Xss = [[1],[2],[3],[4]]
; Xss = [[1],[2],[3,4]]
; Xss = [[1],[2,3],[4]]
; Xss = [[1],[2,3,4]]
; Xss = [[1,2],[3],[4]]
; Xss = [[1,2],[3,4]]
; Xss = [[1,2,3],[4]]
; Xss = [[1,2,3,4]]
; false.
In this answer we use clpfd:
:- use_module(library(clpfd)).
Then, we define len_NM/4—using maplist/3,
length/2, tcount/3, and (#=<)/3:
len_NM(Xss,Ys,N,M) :-
M #>= 1,
N #>= 0,
phrase(seqq1(Xss),Ys),
maplist(length,Xss,Ls),
tcount(#=<(M),Ls,N).
Let's run some sample queries!
?- len_NM([[1,2,3],[4],[5,6],[7,8,9,10],[11,12]],_,N,L).
N = 5, L = 1 % five lists have length of at least one
; N = 4, L = 2 % four lists have length of at least two
; N = 2, L = 3 % two of at least three (e.g., [1,2,3] and [7,8,9,10])
; N = 1, L = 4 % one list has length of four (or more)
; N = 0, L in 5..sup. % no list has length of five (or more)
OK! How about this one?
?- append(Xs,_,[x,x,x,x,x,x]), % With `Xs` having at most 6 elements ...
N #>= 1, % ... `Xss` shall contain at least 1 list ...
len_NM(Xss,Xs,N,4). % ... having a length of 4 (or more).
Xs = [x,x,x,x], N = 1, Xss = [[x,x,x,x]]
; Xs = [x,x,x,x,x], N = 1, Xss = [[x],[x,x,x,x]]
; Xs = [x,x,x,x,x], N = 1, Xss = [[x,x,x,x],[x]]
; Xs = [x,x,x,x,x], N = 1, Xss = [[x,x,x,x,x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x],[x],[x,x,x,x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x],[x,x,x,x],[x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x],[x,x,x,x,x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x,x],[x,x,x,x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x,x,x,x],[x],[x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x,x,x,x],[x,x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x,x,x,x,x],[x]]
; Xs = [x,x,x,x,x,x], N = 1, Xss = [[x,x,x,x,x,x]]
; false.

Related

Prolog - How to limit variable list length

I am having trouble generating all lists that meet certain criteria.
city(new_york, 47).
city(chicago, 100).
all_unique([]).
all_unique([H|T]) :- H = [] ; (not(member(H, T)), all_unique(T)).
cities([Head|Tail]) :-
length(Tail, L),
L < 2,
city(Head, _A),
(Tail = [] ; cities(Tail)).
When I issue the query cities(L), I want it to generate all lists of cities with a maximum length of 2 and no repetition. What it does now is return all possible lists and then keep trying lists that obviously don't meet the criteria.
?- cities(L).
L = [new_york] ;
L = [chicago] ;
L = [new_york, new_york] ;
L = [new_york, chicago] ;
L = [chicago, new_york] ;
L = [chicago, chicago] ;
ERROR: Out of global stack
?-
How do I tell Prolog not to try lists that are too long or have repeated items?
Your definition of all_unique/1 is better based on prolog-dif:
all_unique([]).
all_unique([E|Es]) :-
maplist(dif(E), Es),
all_unique(Es).
Based on meta-predicate maplist/2 you can define cities/1 like this:
city_(new_york, 47).
city_(chicago, 100).
city(C) :-
city_(C, _).
cities(List) :-
length(Ref, 2),
append(List, _, Ref),
all_unique(List),
maplist(city, List).
Sample query:
?- cities(Xs).
Xs = [] ;
Xs = [new_york] ;
Xs = [chicago] ;
Xs = [new_york, chicago] ;
Xs = [chicago, new_york] ;
false. % terminates universally

List consisting of each element of another List repeated twice Prolog

I have to write a predicate: double(X,Y) to be true when Y is the list consisting of each element of X
repeated twice (e.g. double([a,b],[a,a,b,b]) is true).
I ended with sth like this:
double([],[]).
double([T],List) :- double([H|T],List).
double([H|T],List) :- count(H, List, 2).
Its working fine for lists like [a,a,b] but it shouldnt... please help.
And i need help with another predicate: repeat(X,Y,N) to be true when Y is the list consisting of each element of X
repeated N times (e.g. repeat([a,b], [a,a,a,b,b,b],3) is true).
double([],[]).
double([I|R],[I,I|RD]) :-
double(R,RD).
Here's how you could realize that "repeat" predicate you suggested in the question:
:- use_module(library(clpfd)).
Based on if_/3 and (=)/3 we define:
each_n_reps([E|Es], N) :-
aux_n_reps(Es, E, 1, N).
aux_n_reps([], _, N, N). % internal auxiliary predicate
aux_n_reps([E|Es], E0, N0, N) :-
if_(E0 = E,
( N0 #< N, N1 #= N0+1 ), % continue current run
( N0 #= N, N1 #= 1 )), % start new run
aux_n_reps(Es, E, N1, N).
Sample queries1 using SICStus Prolog 4.3.2:
?- each_n_reps(Xs, 3).
Xs = [_A,_A,_A]
; Xs = [_A,_A,_A,_B,_B,_B] , dif(_A,_B)
; Xs = [_A,_A,_A,_B,_B,_B,_C,_C,_C], dif(_A,_B), dif(_B,_C)
...
How about fair enumeration?
?- length(Xs, _), each_n_reps(Xs, N).
N = 1, Xs = [_A]
; N = 2, Xs = [_A,_A]
; N = 1, Xs = [_A,_B] , dif(_A,_B)
; N = 3, Xs = [_A,_A,_A]
; N = 1, Xs = [_A,_B,_C] , dif(_A,_B), dif(_B,_C)
; N = 4, Xs = [_A,_A,_A,_A]
; N = 2, Xs = [_A,_A,_B,_B], dif(_A,_B)
; N = 1, Xs = [_A,_B,_C,_D], dif(_A,_B), dif(_B,_C), dif(_C,_D)
...
How can [A,B,C,D,E,F] be split into runs of equal length?
?- each_n_reps([A,B,C,D,E,F], N).
N = 6, A=B , B=C , C=D , D=E , E=F
; N = 3, A=B , B=C , dif(C,D), D=E , E=F
; N = 2, A=B , dif(B,C), C=D , dif(D,E), E=F
; N = 1, dif(A,B), dif(B,C), dif(C,D), dif(D,E), dif(E,F).
Footnote 1: Answers were reformatted to improve readability.
Ok for repeat/3 i have sth like this:
repeat1([],[],0).
repeat1([A|B],[X|T],Y):- repeat1(B,T,Z), Y is 1+Z.
repeat1([A1|B],[X1|T], Z) :- A1\=A, X1\=X, repeat1(B,T,Z).

PROLOG Undefined procedure ERROR (Two parameters recursion)

count([], 0, 0).
count([X|T], M, N) :- 1 is X, count(T, MRec, NRec),
M is MRec, N is NRec+1.
count([X|T], M, N) :- 0 is X, count(T, MRec, NRec),
M is MRec+1, N is NRec.
control_number(L) :- count_digit(L, M, N), 2 is M, 3 is N.
?- control_number([1,1,0,0,1]).
ERROR: count_number/3: Undefined procedure: count/3
Hello everybody, I need help. This code must provide the count of two separate number recursively. However, I cannot provide recursion
with 2 parameters. I guess MRec and NRec is not valid in any way.
Any help will be appreciated. Thanks now...
Here is a more idiomatic rewrite:
count_digits([], 0, 0).
count_digits([1|T], M, N) :-
count_digits(T, M, NRec),
N is NRec+1.
count_digits([0|T], M, N) :-
count_digits(T, MRec, N),
M is MRec+1.
control_number(L) :-
count_digits(L, 2, 3).
This can be improved a lot by using library(clpfd). Maybe someone else will answer.
As already pointed out by #false this predicate is quite a candidate for clpfd. Besides that I added constraints (marked as % <-) to ensure that M and N are greater than 0 in the recursive cases, so Prolog does not continue to search for further solutions once those variables have been reduced to 0.
:- use_module(library(clpfd)).
count_digits([], 0, 0).
count_digits([1|T], M, N) :-
N #> 0, % <-
NRec #= N-1,
count_digits(T, M, NRec).
count_digits([0|T], M, N) :-
M #> 0, % <-
MRec #= M-1,
count_digits(T, MRec, N).
With these minor modifications you can already use count_digits/3 in several ways. For example to ask for all lists with 2 0's and 3 1's:
?- count_digits(L,2,3).
L = [1,1,1,0,0] ? ;
L = [1,1,0,1,0] ? ;
L = [1,1,0,0,1] ? ;
L = [1,0,1,1,0] ? ;
L = [1,0,1,0,1] ? ;
L = [1,0,0,1,1] ? ;
L = [0,1,1,1,0] ? ;
L = [0,1,1,0,1] ? ;
L = [0,1,0,1,1] ? ;
L = [0,0,1,1,1] ? ;
no
Or count the occurrences of 0's and 1's in a given list:
?- count_digits([1,1,0,0,1],M,N).
M = 2,
N = 3
% 1
Or even ask for the number of 0's and 1's in a list containing variables:
?- count_digits([1,0,X,Y],M,N).
M = X = Y = 1,
N = 3 ? ;
M = N = 2,
X = 1,
Y = 0 ? ;
M = N = 2,
X = 0,
Y = 1 ? ;
M = 3,
N = 1,
X = Y = 0
This is quite nice already and one might be content with the predicate as is. It certainly is fine if you intend to use it with control_number/1 as suggested by #false. However it might be worth the time to fool around a little with some other queries. For example the most general query: What lists are there with M 0's and N 1's?
?- count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,1,1],
M = 0,
N = 3 ?
...
It is only producing lists that consist of 1's exclusively. That is because the first recursive rule is the one describing the case with the 1 as the first element of the list. So the solutions are coming in an unfair order. What happens with the following query is maybe even somewhat less intuitive: What lists are there with the same (but not fixed) number of 0's and 1's:
?- count_digits(L,M,M).
L = [],
M = 0 ? ;
There is an answer and then the predicate loops. That's not exactly a desirable property. An interesting observation about this query: If one uses it on lists with fixed length the result is actually as expected:
?- length(L,_), count_digits(L,M,M).
L = [],
M = 0 ? ;
L = [1,0],
M = 1 ? ;
L = [0,1],
M = 1 ? ;
L = [1,1,0,0],
M = 2 ? ;
L = [1,0,1,0],
M = 2 ? ;
...
Applying this idea to the previous query yields a fair ordering of the results:
?- length(L,_), count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [0],
M = 1,
N = 0 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,0],
M = N = 1 ? ;
...
It certainly would be nice to get these results without having to prefix an auxiliary goal. And looking a little closer at the relation described by count_digits/3 another observation meets the eye: If there are M 0's and N 1's the length of the list is actually fixed, namely to M+N. To put these observations to work one could rename count_digits/3 to list_0s_1s/3 and redefine count_digits/3 to be the calling predicate with the following constraints:
:- use_module(library(clpfd)).
count_digits(L,M,N) :-
X #= M+N,
length(L,X), % L is of length M+N
list_0s_1s(L,M,N).
list_0s_1s([], 0, 0).
list_0s_1s([1|T], M, N) :-
N #> 0,
NRec #= N-1,
list_0s_1s(T, M, NRec).
list_0s_1s([0|T], M, N) :-
M #> 0,
MRec #= M-1,
list_0s_1s(T, MRec, N).
The first three queries above yield the same results as before but these two are now producing results in a fair order without looping:
?- count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [0],
M = 1,
N = 0 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,0],
M = N = 1 ?
...
?- count_digits(L,M,M).
L = [],
M = 0 ? ;
L = [1,0],
M = 1 ? ;
L = [0,1],
M = 1 ? ;
L = [1,1,0,0],
M = 2 ? ;
L = [1,0,1,0],
M = 2 ?
...
Two last notes on your predicate control_number/1: Firstly, if you are using is/2 make sure to use it like so:
?- M is 2.
M = 2
% 1
instead of (as used in your definition of control_number/1):
?- 2 is M.
ERROR!!
INSTANTIATION ERROR- in arithmetic: expected bound value
% 1
And secondly, if you intend to use a predicate like control_number/1 to call count_digits/3, don't put goals like M is 2 and N is 3 after the actual call of count_digits/3. That way you are asking for all solutions of count_digits(L,M,N), of which there are infinitely many, and in the subsequent goals you are then filtering out the ones that satisfy your constraints (M is 2 and N is 3). With this ordering of the goals you make sure that control_number/1 does not terminate after producing the finite number of solutions, since infinitely many solution-candidates are produced by the first goal that subsequently fail according to your constraints. Instead, place such constraints first or put them directly as arguments into the goal as posted by #false.
Accumulation parameters is the way to go (you need an auxiliary predicate in order to initialize those parameters):
count(List,C0,C1) :-
count_aux(List,C0,C1,0,0).
count_aux([],C0,C1,C0,C1).
count_aux([0|Rest],C0,C1,PartialC0,PartialC1) :-
IncC0 is PartialC0+1,
!,
count_aux(Rest,C0,C1,IncC0,PartialC1).
count_aux([1|Rest],C0,C1,PartialC0,PartialC1) :-
IncC1 is PartialC1+1,
!,
count_aux(Rest,C0,C1,PartialC0,IncC1).
count_aux([_|Rest],C0,C1,PartialC0,PartialC1) :-
count_aux(Rest,C0,C1,PartialC0,PartialC1).
Note:
You should call count/3, not count_aux/5.
Last two parameters to count_aux/5 are accumulation parameters
initialized to zero.
First clause to count_aux/5 is the base case, where accumulated
parameters are returned.
Last clause to count_aux/5 prevents predicate failure if list items
are not 0 nor 1.
Example:
?- count([1,1,0,0,0,k],A,B).
A = 3,
B = 2.

Duplicate nth value from list

Fairly new to Prolog, I'm trying to implement a recursive rule duplicate_nth(N,L1,L2) which takes a 1-based index N, a list L1 and duplicates the Nth value of L1 and returns it in a list L2.
Sample use:
?- duplicate_nth(1, [2,3,4], X).
X = [2,2,3,4]. % expected result
My current code is:
duplicate_nth(N,[H|T],L2) :-
N = 1, % Is `N` equal to 1?
append([H],[H|T],L2). % If so, prepend `H` to `[H|T]`
duplicate_nth(N,H|T,L2) :-
N > 1,
This works if N = 1. It will not, however, work if N > 1 and I am unsure of how to proceed.
No need to worry about implementing recursive predicate(s) the right way!
Simply delegate the "recursive part" to same_length/2, append/3, and length/2:
duplicate_nth(N,Xs0,Xs1) :- % index `N` is 1-based
same_length([_|Xs0],Xs1),
Suffix = [X|_],
append(Prefix,Suffix,Xs0),
length([_|Prefix],N),
append(Prefix,[X|Suffix],Xs1).
Sample query:
?- N = 1,
Xs0 = [a,b,c,d],
duplicate_nth(N,Xs0,Xs1).
N = 1, Xs0 = [a,b,c,d], Xs1 = [a,a,b,c,d] % only solution
; false.
Let's generalize above query and see the solution set grow!
?- Xs0 = [a,b,c,d],
duplicate_nth(N,Xs0,Xs1).
N = 1, Xs0 = [a,b,c,d], Xs1 = [a,a,b,c,d] % (same solution as before)
; N = 2, Xs0 = [a,b,c,d], Xs1 = [a,b,b,c,d] % (new solution)
; N = 3, Xs0 = [a,b,c,d], Xs1 = [a,b,c,c,d] % (new solution)
; N = 4, Xs0 = [a,b,c,d], Xs1 = [a,b,c,d,d] % (new solution)
; false.
Note that duplicate_nth/3 also works when used "in the other direction".
?- Xs1 = [a,b,b,c,d,d,e],
duplicate_nth(N,Xs0,Xs1).
N = 2, Xs1 = [a,b,b,c,d,d,e], Xs0 = [a,b,c,d,d,e]
; N = 5, Xs1 = [a,b,b,c,d,d,e], Xs0 = [a,b,b,c,d,e]
; false.
Last, let's run the most general query!
?- duplicate_nth(N,Xs0,Xs).
N = 1, Xs0 = [_A], Xs = [_A,_A]
; N = 1, Xs0 = [_A,_B], Xs = [_A,_A,_B]
; N = 2, Xs0 = [_A,_B], Xs = [_A,_B,_B]
; N = 1, Xs0 = [_A,_B,_C], Xs = [_A,_A,_B,_C]
; N = 2, Xs0 = [_A,_B,_C], Xs = [_A,_B,_B,_C]
; N = 3, Xs0 = [_A,_B,_C], Xs = [_A,_B,_C,_C]
; N = 1, Xs0 = [_A,_B,_C,_D], Xs = [_A,_A,_B,_C,_D]
...
Fair enumeration "out-of-the-box"? Perfect!
Nearly all functions on lists have the same structure. A base case:
function(FixedValues,List1,List2) :-
!.
Where List2 is written in function of List1 and FixedValues is a set of parameters that is grounded.
And an inductive case:
function(Values,[H|T],[H2|T2]) :-
other_function(H,H2), %transform H into H2
ValuesNext is Values-1, %or some other function
function(ValuesNext,T,T2).
The ! is a "cut" and prevents Prolog to execute other predicate definitions if the conditions of the first one are met.
Applied to this problem, try:
duplicate_nth(1,[H|T],[H,H|T]) :- %base case
!.
duplicate_nth(N,[H|T],[H|T2]) :- %inductive case
N1 is N-1,
duplicate_nth(N1,T,T2).
In most cases you need to make the program safer, since N might be out of bounds (less than or equal to zero, or larger than the length of the list.)
In that case, add:
duplicate_nth(_,[],[]).

list length, inserting element

I'm trying to write a program in Prolog, which will insert an element into a certain position, so e.g.
?- ins(a, [1,2,3,4,5], 3, X).
X = [1,2,a,3,4,5].
I have the following code:
ins(X,[H|T],P,OUT) :-
length([T3],P),
concatenate(X,[H],T),
ins(...).
The problem is that it is inserting element X in given index from back (I even know where the problem is -> the length([T3],P) which is obviously the length of the list from back not from head) . I was trying to remember how much elements did I cut off and insert X when "number of cut off elements" = P, but I can't really write that in Prolog. Any ideas?
% ins(Val,List,Pos,Res)
ins(Val,[H|List],Pos,[H|Res]):- Pos > 1, !,
Pos1 is Pos - 1, ins(Val,List,Pos1,Res).
ins(Val, List, 1, [Val|List]).
The predicate fails if Pos = 0 or Pos > length(List) + 1
Let's state what you want here. For example you could say: "I want to split my input List after Position - 1 elements so that I can insert a new element there".
A direct traduction with append/3 (DCG would be better btw):
ins(Element, List, Position, Result) :-
PrefixLength is Position - 1,
length(Prefix, PrefixLength),
append(Prefix, Suffix, List),
append(Prefix, [Element], Temp),
append(Temp, Suffix, Result).
Or you could say: "I want to go through the elements of my List Position - 1 times without touching anything and then insert Element and then not touch anything again".
This time the direct traduction would be:
ins2(Element, List, 1, [Element|List]).
ins2(Element, [Head|Tail], Position, [Head|Result]) :-
Position > 1,
NewPosition is Position - 1,
ins2(Element, Tail, NewPosition, Result).
you could too state that: "My input List is a list equal to my Result one except it hasn't my Element as Positionth element." and realize that if you use swi-prolog, a predicate solves this instantly:
ins3(Element, List, Position, Result) :-
nth1(Position, Result, Element, List).
Bottom line is: state what the problem is clearly and the solution should appear in simple terms.
TL;DR: To insert item E at position I1 into list Es0, we do not need to write recursive code.
Instead, we can delegate the work (and the worries about getting it right, too!) to versatile auxiliary predicates, all of which are part of the Prolog prologue. To define ins_/4 we write:
ins_(E, Es0, I1, Es) :-
maplist(any_thing, Es, [_|Es0]),
append(Prefix, Suffix, Es0),
length([_|Prefix], I1),
append(Prefix, [E|Suffix], Es).
any_thing(_, _). % auxiliary predicate (used above)
Note that maplist(any_thing, Es, [_|Es0]) is equivalent to same_length(Es, [_|Es0]).
Sample queries1,2,3 using GNU Prolog version 1.4.4 (64-bit):
?- ins_(X, [a,b,c,d,e], N1, Xs).
N1 = 1, Xs = [X,a,b,c,d,e]
; N1 = 2, Xs = [a,X,b,c,d,e]
; N1 = 3, Xs = [a,b,X,c,d,e]
; N1 = 4, Xs = [a,b,c,X,d,e]
; N1 = 5, Xs = [a,b,c,d,X,e]
; N1 = 6, Xs = [a,b,c,d,e,X]
; false.
?- ins_(X, [a,b,c,d,e], 3, Xs).
Xs = [a,b,X,c,d,e]
; false.
?- ins_(X, Xs0, 3, [a,b,c,d,e]).
X = c, Xs0 = [a,b,d,e]
; false.
Let's not forget about the most general query!
?- ins(X, Es0, I1, Es).
Es0 = [], I1 = 1, Es = [X]
;
Es0 = [A], I1 = 1, Es = [X,A]
; Es0 = [A], I1 = 2, Es = [A,X]
;
Es0 = [A,B], I1 = 1, Es = [X,A,B]
; Es0 = [A,B], I1 = 2, Es = [A,X,B]
; Es0 = [A,B], I1 = 3, Es = [A,B,X]
;
Es0 = [A,B,C], I1 = 1, Es = [X,A,B,C]
; Es0 = [A,B,C], I1 = 2, Es = [A,X,B,C]
; Es0 = [A,B,C], I1 = 3, Es = [A,B,X,C]
; Es0 = [A,B,C], I1 = 4, Es = [A,B,C,X]
;
Es0 = [A,B,C,D], I1 = 1, Es = [X,A,B,C,D]
; ...
Fair enumeration of all solutions, OK!
EDIT:
I repeated the most general query with ins3/4 as defined
by #m09 in his answer on SWI-Prolog 7.3.11 and SICStus Prolog 4.3.2 (both feature the library predicate nth1/4).
I was surprised to see the underlying implementations of nth1/4 exhibit different procedural semantics (w.r.t. "fair enumeration"). See for yourself!
% SICStus Prolog 4.3.2 % SWI Prolog 7.3.11
% %
?- ins3(X, Es0, I1, Es). % ?- ins3(X, Es0, I1, Es).
I1 = 1, Es0 = [], Es = [X] % I1 = 1, Es = [X|Es0]
; % ; I1 = 2, Es0 = [_A|_Z],
I1 = 1, Es0 = [_A], Es = [X,_A] % Es = [_A,X|_Z]
; I1 = 2, Es0 = [_A], Es = [_A,X] % ; I1 = 3, Es0 = [_A,_B|_Z],
; % Es = [_A,_B,X|_Z]
I1 = 1, Es0 = [_A,_B], Es = [X,_A,_B] % ; I1 = 4, Es0 = [_A,_B,_C|_Z],
; I1 = 2, Es0 = [_A,_B], Es = [_A,X,_B] % Es = [_A,_B,_C,X|_Z],
; I1 = 3, Es0 = [_A,_B], Es = [_A,_B,X] % ; I1 = 5, Es0 = [_A,_B,_C,_D|_Z],
; % Es = [_A,_B,_C,_D,X|_Z]
... % ...
Footnote 1: All sample queries shown above terminate universally.
Footnote 2: The answers given by the GNU Prolog toplevel have been pretty-printed a little.
Footnote 3: The code presented above is used as-is, no additional library predicates are required.
ins(Element,List,Nth,Result) :-
length([_|L0],Nth),
append(L0,[_|R],List),
append(L0,[Element|R],Result).