Count numbers in list - list

I have a problem with calculating the occurences of the given number in list. For instance, if we have a list like L = [4,5,6,4,3,4,2,4,5,6,7,4] and I want to count how many 4s is in the list, then the answer is 5.
I tried to implement this in prolog, but gprolog shows me only no as an answer:
count_occ([], 0).
count_occ([H|T], L) :- count_occ(T, N), H =:= 4, L is N + 1.
And I do not know why.

I took a stab at this. I made it extra verbose so it's easy to follow along:
% count_occurences(+List, +DesiredElement, -NumOccurences)
count_occurences([], _, 0).
count_occurences([H|T], DesiredElement, NumOccurences) :-
H =\= DesiredElement,
count_occurences(T, DesiredElement, NumOccurences).
count_occurences([H|T], DesiredElement, NumOccurences) :-
H =:= DesiredElement,
count_occurences(T, DesiredElement, N),
NumOccurences is N + 1.
Using a conditional expression, the last 2 predicates can be combined into one:
% count_occurences(+List, +DesiredElement, -NumOccurences)
count_occurences([], _, 0).
count_occurences([H|T], DesiredElement, NumOccurences) :-
count_occurences(T, DesiredElement, N),
(H =:= DesiredElement -> /* if H is DesiredElement */
NumOccurences is N + 1; /* "then" */
NumOccurences is N /* "else" */
).

I think the problem is that you do not provide a clause Prolog can take when H is not 4. This one is however easy: you simply perform a recursive call:
count_occ([H|T],N) :-
H \= 4,
count_occ(T,N).
Or a full implementation:
count_occ([],0).
count_occ([4|T],N1) :-
count_occ(T,N),
N1 is N+1.
count_occ([H|T],N) :-
H \= 4,
count_occ(T,N).

Related

Prime numbers Prolog

I have written Prolog code to (try) find prime numbers between 0 and N. I am however unable to filter out composite numbers.
Any advice would be great.
check(N, 2) :-
N mod 2 =:= 0.
plist(N, List) :-
X>1,
findall(Z, between(1, N, Z), L1),
list(L1, 2, List).
list([], _, []).
list([H | Tail1], 2, [H | Tail2]) :-
\+ divide(H, 2),
list(Tail1, 2, Tail2).
list([H | Tail1], 2, List) :-
divide(H, 2),
list(Tail1, 2, List).
Start coding a predicate is_prime(N) :- .... without any optimization, just looping from 2 to N-1 (of course, you can stop at square root of N, but it's not so important right now...).
You can test it at the command line, ?- is_prime(13). should give true, ?- is_prime(21). should give false...
Then you have done:
plist(N, List) :-
findall(Z, (between(1, N, Z), is_prime(Z)), List).

DCG and inversion of a list in Prolog

I'm trying to count the numer of inversions in a list. A predicate inversion(+L,-N) unifies N to the number of inversions in that list. A inversion is defined as X > Y and X appears before Y in the list (unless X or Y is 0). For example:
?- inversions([1,2,3,4,0,5,6,7,8],N).
N = 0.
?- inversions([1,2,3,0,4,6,8,5,7],N).
N = 3.
For what I'm using this for, the list will always have exacly 9 elements, and always containing the numbers 0-8 uniquely.
I'm quite new to Prolog and I'm trying to do this as concise and as elegant as possible; It seems like DCG will probably help a lot. I read into the official definition and some tutorial sites, but still don't quit understand what it is. Any help would be greatly appreciated.
Here is another solution that doesn't leave choice points using if_/3:
inversions([],0).
inversions([H|T], N):-
if_( H = 0,
inversions(T,N),
( find_inv(T,H,N1),inversions(T, N2), N #= N1+N2 )
).
find_inv([],_,0).
find_inv([H1|T],H,N1):-
if_( H1=0,
find_inv(T,H,N1),
if_( H#>H1,
(find_inv(T,H,N2),N1 #= N2+1),
find_inv(T,H,N1)
)
).
#>(X, Y, T) :-
( integer(X),
integer(Y)
-> ( X > Y
-> T = true
; T = false
)
; X #> Y,
T = true
; X #=< Y,
T = false
).
I'm not so sure a DCG would be helpful here. Although we're processing a sequence, there's a lot of examination of the entire list at each point when looking at each element.
Here's a CLPFD approach which implements the "naive" algorithm for inversions, so it's transparent and simple, but not as efficient as it could be (it's O(n^2)). There's a more efficient algorithm (O(n log n)) involving a divide and conquer approach, which I show further below.
:- use_module(library(clpfd)).
inversions(L, C) :-
L ins 0..9,
all_distinct(L),
count_inv(L, C).
% Count inversions
count_inv([], 0).
count_inv([X|T], C) :-
count_inv(X, T, C1), % Count inversions for current element
C #= C1 + C2, % Add inversion count for the rest of the list
count_inv(T, C2). % Count inversions for the rest of the list
count_inv(_, [], 0).
count_inv(X, [Y|T], C) :-
( X #> Y, X #> 0, Y #> 0
-> C #= C1 + 1, % Valid inversion, count it
count_inv(X, T, C1)
; count_inv(X, T, C)
).
?- inversions([1,2,3,4,0,5,6,7,8],N).
N = 0 ;
false.
?- inversions([1,2,3,0,4,6,8,5,7],N).
N = 3 ;
false.
?- inversions([0,2,X],1).
X = 1 ;
false.
It does leave a choice point, as you can see, which I haven't sorted out yet.
Here's the O(n log n) solution, which is using the sort/merge algorithm.
inversion([], [], 0).
inversion([X], [X], 0).
inversion([HU1, HU2|U], [HS1, HS2|S], C) :- % Ensure list args have at least 2 elements
split([HU1, HU2|U], L, R),
inversion(L, SL, C1),
inversion(R, SR, C2),
merge(SL, SR, [HS1, HS2|S], C3),
C #= C1 + C2 + C3.
% Split list into left and right halves
split(List, Left, Right) :-
split(List, List, Left, Right).
split(Es, [], [], Es).
split(Es, [_], [], Es).
split([E|Es], [_,_|T], [E|Ls], Right) :-
split(Es, T, Ls, Right).
% merge( LS, RS, M )
merge([], RS, RS, 0).
merge(LS, [], LS, 0).
merge([L|LS], [R|RS], [L|T], C) :-
L #=< R,
merge(LS, [R|RS], T, C).
merge([L|LS], [R|RS], [R|T], C) :-
L #> R, R #> 0 #<==> D, C #= C1+D,
merge([L|LS], RS, T, C1).
You can ignore the second argument, which is the sorted list (just a side effect if all you want is the count of inversions).
Here is another possibility to define the relation. First, #</3 and #\=/3 can be defined like so:
:- use_module(library(clpfd)).
bool_t(1,true).
bool_t(0,false).
#<(X,Y,Truth) :- X #< Y #<==> B, bool_t(B,Truth).
#\=(X,Y,Truth) :- X #\= Y #<==> B, bool_t(B,Truth).
Based on that, if_/3 and (',')/3 a predicate inv_t/3 can be defined, that yields true in the case of an inversion and false otherwise, according to the definition given by the OP:
inv_t(X,Y,T) :-
if_(((Y#<X,Y#\=0),X#\=0),T=true,T=false).
And subsequently the actual relation can be described like so:
list_inversions(L,I) :-
list_inversions_(L,I,0).
list_inversions_([],I,I).
list_inversions_([X|Xs],I,Acc0) :-
list_x_invs_(Xs,X,I0,0),
Acc1 #= Acc0+I0,
list_inversions_(Xs,I,Acc1).
list_x_invs_([],_X,I,I).
list_x_invs_([Y|Ys],X,I,Acc0) :-
if_(inv_t(X,Y),Acc1#=Acc0+1,Acc1#=Acc0),
list_x_invs_(Ys,X,I,Acc1).
Thus the example queries given by the OP succeed deterministically:
?- list_inversions([1,2,3,4,0,5,6,7,8],N).
N = 0.
?- list_inversions([1,2,3,0,4,6,8,5,7],N).
N = 3.
Such application-specific constraints can often be built using reified constraints (constraints whose truth value is reflected into a 0/1 variable). This leads to a relatively natural formulation, where B is 1 iff the condition you want to count is satisfied:
:- lib(ic).
inversions(Xs, N) :-
( fromto(Xs, [X|Ys], Ys, [_]), foreach(NX,NXs) do
( foreach(Y,Ys), param(X), foreach(B,Bs) do
B #= (X#\=0 and Y#\=0 and X#>Y)
),
NX #= sum(Bs) % number of Ys that are smaller than X
),
N #= sum(NXs).
This code is for ECLiPSe.
Using clpfd et automaton/8 we can write
:- use_module(library(clpfd)).
inversions(Vs, N) :-
Vs ins 0..sup,
variables_signature(Vs, Sigs),
automaton(Sigs, _, Sigs,
[source(s),sink(i),sink(s)],
[arc(s,0,s), arc(s,1,s,[C+1]), arc(s,1,i,[C+1]),
arc(i,0,i)],
[C], [0], [N]),
labeling([ff],Vs).
variables_signature([], []).
variables_signature([V|Vs], Sigs) :-
variables_signature_(Vs, V, Sigs1),
variables_signature(Vs, Sigs2),
append(Sigs1, Sigs2, Sigs).
variables_signature_([], _, []).
variables_signature_([0|Vs], Prev, Sigs) :-
variables_signature_(Vs,Prev,Sigs).
variables_signature_([V|Vs], Prev, [S|Sigs]) :-
V #\= 0,
% Prev #=< V #<==> S #= 0,
% modified after **false** remark
Prev #> V #<==> S,
variables_signature_(Vs,Prev,Sigs).
examples :
?- inversions([1,2,3,0,4,6,8,5,7],N).
N = 3 ;
false.
?- inversions([1,2,3,0,4,5,6,7,8],N).
N = 0 ;
false.
?- inversions([0,2,X],1).
X = 1.
in SWI-Prolog, with libraries aggregate and lists:
inversions(L,N) :-
aggregate_all(count, (nth1(P,L,X),nth1(Q,L,Y),X\=0,Y\=0,X>Y,P<Q), N).
both libraries are autoloaded, no need to explicitly include them.
If you want something more general, you can see the example in library(clpfd), under the automaton section, for some useful ideas. But I would try to rewrite your specification in simpler terms, using element/3 instead of nth1/3.
edit
after #false comment, I tried some variation on disequality operators, but none I've tried have been able to solve the problematic query. Then I tried again with the original idea, to put to good use element/3. Here is the result:
:- use_module(library(clpfd)).
inversions(L) :-
L ins 0..8,
element(P,L,X),
element(Q,L,Y),
X #\= 0, Y #\= 0, X #> Y, P #< Q,
label([P,Q]).
inversions(L,N) :-
aggregate(count, inversions(L), N) ; N = 0.
The last line label([P,Q]) it's key to proper reification: now we can determine the X value.
?- inversions([0,2,X],1).
X = 1.

Prolog - get middle element of List

I would like to get the middle element of a list in Prolog.
The predicates middle([1,2,3],M) and middle([1,2,3,4],M) should both return 2 as a result.
And I am allowed to use the predicate deleteLast.
I know that there are similar posts that solve that question but I have not found one that just uses deleteLast.
Even the syntax is not correct - however this is my solution so far:
middle([], _).
middle([X|XTail|Y], E) :-
1 is mod(list_length([X|XTail|Y], 2)),
middle([XTail], E).
middle([X|XTail|Y], E) :-
0 is mod(list_length([X|XTail|Y], 2)),
middle([X|XTail], E).
middle([X], X).
Question: Is that partly correct or am I completely on the wrong path ?
Sorry, the attempted solution you have is completely on the wrong path.
It doesn't use deleteLast/2 as you stated you require
You are using list_length/2 as if it were an arithmetic function, which it is not. It's a predicate.
You have a term with invalid syntax and unknown semantics, [X|XTail|Y]
In Prolog, you just need to think about it in terms of the rules. Here's an approach using deleteLast/2:
middle([X], X). % `X` is the middle of the single element list `[X]`
middle([X,_], X). % `X` is the middle of the two-element list `[X,_]`
% X is the middle of the list `[H|T]` if X is the middle of the list TWithoutLast
% where TWithoutLast is T with its last element removed
%
middle([H|T], X) :-
deleteLast(T, TWithoutLast),
middle(TWithoutLast, X).
I assume deleteLast/2 is well-behaved and just fails if T is empty.
You can also do this with same_length/2 and append/3, but, alas, doesn't use deleteLast/2:
middle(L, M) :-
same_length(L1, L2),
append(L1, [M|L2], L).
middle(L, M) :-
same_length(L1, L2),
append(L1, [M,_|L2], L).
So much unnecessary work, and unnecessary code. length/2 is very efficient, and a true relation. Its second argument is guaranteed to be a non-negative integer. So:
middle(List, Middle) :-
List = [_|_], % at least one element
length(List, Len),
divmod(Len, 2, Q, R), % if not available do in two separate steps
N is Q + R,
nth1(N, List, Middle).
And you are about ready:
?- middle(L, M), numbervars(L).
L = [A],
M = A ;
L = [A, B],
M = A ;
L = [A, B, C],
M = B ;
L = [A, B, C, D],
M = B ;
L = [A, B, C, D, E],
M = C ;
L = [A, B, C, D, E, F],
M = C .
I understand that this doesn't solve your problem (the answer by #lurker does) but it answers your question. :-(
Here is my attempt:
middle(L,M):- append(L1,L2,L),length(L1,N),length(L2,N), reverse(L1,[M|_]).
middle(L,M):- append(L1,L2,L),length(L1,N),length(L2,N1), N is N1+1 ,
reverse(L1,[M|_]).
Example:
?- middle([1,2,3],M).
M = 2 ;
false.
?- middle([1,2,3,4],M).
M = 2 ;
false.
In your implementation the problem is that by writing for example:
list_length([X|XTail|Y], 2)
The above does not give you as X the first element and as Y the last so I think it has some major problems...
As well pointed out by lurker you could write the above solution in one clause without using reverse/2:
middle(L, M) :- append(L1, [M|T], L), length(L1, N), length([M|T], N1),
(N1 is N + 1 ; N1 is N + 2).
Also to make the solution more relational (also see mat's comment below) you could use CLPFD library and replace is/2 with #= like:
middle(L, M) :- append(L1, [M|T], L), length(L1, N), length([M|T], N1),
(N1 #= N + 1 ; N1 #= N + 2).
Another interesting solution is to consider this predicate for splitting a list in half:
half(List, Left, Right) :-
half(List, List, Left, Right).
half(L, [], [], L).
half(L, [_], [], L).
half([H|T], [_,_|T2], [H|Left], Right) :-
half(T, T2, Left, Right).
This predicate divides an even list into two equal halves, or an odd list into two pieces where the right half has one more element than the left. It does so by reducing the original list, via the second argument, by two elements, each recursive call, while at the same time reducing the original list by one element each recursive call via the first argument. When it recurses down to the second argument being zero or one elements in length, then the first argument represents the half that's left, which is the right-hand list.
Example results for half/3 are:
| ?- half([a,b,c], L, R).
L = [a]
R = [b,c] ? a
(1 ms) no
| ?- half([a,b,c,d], L, R).
L = [a,b]
R = [c,d] ? a
no
| ?-
We can't quite use this to easily find the middle element because, in the even case, we want the last element of the left hand list. If we could bias the right-hand list by an extra element, we could then pick off the head of the right-hand half as the "middle" element. We can accomplish this using the deleteLast/2 here:
middle([X], X).
middle(List, Middle) :-
deleteLast(List, ListWithoutLast),
half(ListWithoutLast, _, [Middle|_]).
The head of the right half list of the original list, with the last element deleted, is the "middle" element. We can also simply half/3 and combine it with middle/2 since we don't really need everything half/3 does (e.g., we don't need the left-hand list, or the tail of the right hand list):
middle([X], X).
middle(List, Middle) :-
deleteLast(List, ListWithoutLast),
middle(ListWithoutLast, ListWithoutLast, Middle).
middle([M|_], [], M).
middle([M|_], [_], M).
middle([_|T], [_,_|T2], Right) :-
middle(T, T2, Right).
Another approach would be to modify half/3 to bias the splitting of the original list in half toward the right-hand half, which eliminates the need for using deleteLast/2.
modified_half(List, Left, Right) :-
modified_half(List, List, Left, Right).
modified_half(L, [_], [], L).
modified_half(L, [_,_], [], L).
modified_half([H|T], [_,_,X|T2], [H|Left], Right) :-
modified_half(T, [X|T2], Left, Right).
This will bias the right hand list to have an extra element at the "expense" of the left:
| ?- modified_half([a,b,c,d,e], L, R).
L = [a,b]
R = [c,d,e] ? a
no
| ?- modified_half([a,b,c,d,e,f], L, R).
L = [a,b]
R = [c,d,e,f] ? a
no
| ?-
Now we can see that the middle element, per the original definition, is just the head of the right hand list. We can create a new definition for middle/2 using the above. As we did before with half/3, we can ignore everything but the head in the right half, and we can eliminate the left half since we don't need it, and create a consolidated middle/2 predicate:
middle(List, Middle) :-
middle(List, List, Middle).
middle([M|_], [_,_], M).
middle([M|_], [_], M).
middle([_|T], [_,_,X|T2], Middle) :-
middle(T, [X|T2], Middle).
This reduces the original list down one element at a time (first argument) and two elements at a time (second argument) until the second argument is reduced to one or two elements. It then considers the head first argument to be the middle element:
This gives:
| ?- middle([a,b,c], M).
M = b ? ;
no
| ?- middle([a,b,c,d], M).
M = b ? ;
no
| ?- middle(L, M).
L = [M,_] ? ;
L = [M] ? ;
L = [_,M,_,_] ? ;
L = [_,M,_] ? ;
L = [_,_,M,_,_,_] ? ;
L = [_,_,M,_,_] ? ;
L = [_,_,_,M,_,_,_,_] ?
...

List of factorials in Prolog

I'm having trouble solving the following exercise...
A factorial can be described in Prolog as:
factorial(0, 1).
factorial(N, F) :-
N1 is N - 1,
factorial(N1, F1),
F is N * F1.
I need to expand this code in order to return a list of all previous factorials until N. But it returns only the first factorial (1), and then the error: ERROR: Out of local stack. Here is my code:
insertList(H, L, [H|L]) :-
!.
factorial(0, 1, [1]).
factorial(N, F, L) :-
N1 is N - 1,
factorial(N1, F1, L),
F is N * F1,
insertList(F, L, [F|L]).
list_factorial(X, L) :-
factorial(X, F, L).
What am I doing wrong?
Here's an implementation in pure prolog with clpfd:
:- use_module(library(clpfd)).
list_factorial([1], 0).
list_factorial(Zs0, N) :-
length(Zs0, N),
N #> 0,
list_n_fac(Zs0, 1, 1).
list_n_fac([], _, _).
list_n_fac([Z1|Zs], N0, Z0) :-
Z1 #= Z0 * N0,
N1 #= N0 + 1,
list_n_fac(Zs, N1, Z1).
Sample query:
?- list_factorial(Zs, 8).
Zs = [1,2,6,24,120,720,5040,40320].
Here's the most general query:
?- list_factorial(Zs, N).
( N = 0, Zs = [1]
; N = 1, Zs = [1]
; N = 2, Zs = [1,2]
; N = 3, Zs = [1,2,6]
; N = 4, Zs = [1,2,6,24]
; N = 5, Zs = [1,2,6,24,120]
...
the minimal correction, indicating the main problem
insertList(H, L, [H|L]):- !.
factorial(0, 1, [1]).
factorial(N, F, Fs):- N1 is N-1, factorial(N1, F1, L), F is N * F1, insertList(F, L, Fs).
list_factorial(X, L):- factorial(X, F, L).
but it will loop if you request backtracking after the first solution is returned. You could add the test #false suggested... otherwise, another definition could be
factorials(N, L) :-
N > 0 -> L = [F,G|Fs], M is N-1, factorials(M, [G|Fs]), F is G*N ; L = [1].
Another solution is:
factorial(0,1) :- !.
factorial(N,F) :-
N>0, N1 is N - 1, factorial(N1,F1), F is N * F1.
list_factorial(N,L) :-
N>1, !, N2 is N-1, list_factorial(N2,L2), factorial(N,F), append(L2,[F],L).
list_factorial(N,[F]) :- factorial(N,F).
I changed your factorial with the test if N is greater than 0, because you can't do the factorial of negative number and with a cut to get only one solution.
You made me install SWI-prolog haha.
list_fact(N,M,A):- A is N * M.
list_fact(N,M,A):- N1 is N + 1, M1 is N * M, list_fact(N1,M1,A).
Call as
list_fact(1,1,A).
It's quite simple. The first rule calculates the next factorial as N * M.
The second rule makes a recursive call where N = N + 1 and M = the previous factorial calculated in rule 1.

Count only numbers in list of numbers and letters

I'm new to Prolog and I can't seem to get the answer to this on my own.
What I want is, that Prolog counts ever Number in a list, NOT every element. So for example:
getnumbers([1, 2, c, h, 4], X).
Should give me:
X=3
getnumbers([], 0).
getnumbers([_ | T], N) :- getnumbers(T, N1), N is N1+1.
Is what I've got, but it obviously gives me every element in a list. I don't know how and where to put a "only count numbers".
As usual, when you work with lists (and SWI-Prolog), you can use module lambda.pl found there : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
:- use_module(library(lambda)).
getnumbers(L, N) :-
foldl(\X^Y^Z^(number(X)
-> Z is Y+1
; Z = Y),
L, 0, N).
Consider using the built-in predicates (for example in SWI-Prolog), and checking their implementations if you are interested in how to do it yourself:
include(number, List, Ns), length(Ns, N)
Stay logically pure, it's easy: Use the meta-predicate
tcount/3 in tandem with the reified type test predicate number_t/2 (short for number_truth/2):
number_t(X,Truth) :- number(X), !, Truth = true.
number_t(X,Truth) :- nonvar(X), !, Truth = false.
number_t(X,true) :- freeze(X, number(X)).
number_t(X,false) :- freeze(X,\+number(X)).
Let's run the query the OP suggested:
?- tcount(number_t,[1,2,c,h,4],N).
N = 3. % succeeds deterministically
Note that this is monotone: delaying variable binding is always logically sound. Consider:
?- tcount(number_t,[A,B,C,D,E],N), A=1, B=2, C=c, D=h, E=4.
N = 3, A = 1, B = 2, C = c, D = h, E = 4 ; % succeeds, but leaves choice point
false.
At last, let us peek at some of the answers of the following quite general query:
?- tcount(number_t,[A,B,C],N).
N = 3, freeze(A, number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 2, freeze(A, number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 1, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 0, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)).
of course, you must check the type of an element to see if it satisfies the condition.
number/1 it's the predicate you're looking for.
See also if/then/else construct, to use in the recursive clause.
This uses Prolog's natural pattern matching with number/1, and an additional clause (3 below) to handle cases that are not numbers.
% 1 - base recursion
getnumbers([], 0).
% 2 - will pass ONLY if H is a number
getnumbers([H | T], N) :-
number(H),
getnumbers(T, N1),
N is N1+1.
% 3 - if got here, H CANNOT be a number, ignore head, N is unchanged, recurse tail
getnumbers([_ | T], N) :-
getnumbers(T, N).
A common prolog idiom with this sort of problem is to first define your predicate for public consumption, and have it invoke a 'worker' predicate. Often it will use some sort of accumulator. For your problem, the public consumption predicate is something like:
count_numbers( Xs , N ) :-
count_numbers_in_list( Xs , 0 , N ) .
count_numbers_in_list( [] , N , N ) .
count_numbers_in_list( [X|Xs] , T , N ) :-
number(X) ,
T1 is T+1 ,
count_numbers_in_list( Xs , T1 , N )
.
You'll want to structure the recursive bit so that it is tail recursive as well, meaning that the recursive call depends on nothing but data in the argument list. This allows the compiler to reuse the existing stack frame on each call, so the predicate becomes, in effect, iterative instead of recursive. A properly tail-recursive predicate can process a list of infinite length; one that is not will allocate a new stack frame on every recursion and eventually blow its stack. The above count_numbers_in_list/3 is tail recursive. This is not:
getnumbers([H | T], N) :-
number(H),
getnumbers(T, N1),
N is N1+1.