Since there are two answers, and no one pointed out explicitly enough the reason why you get into "out of local stack" trouble (Mat says in the comment to your question that your predicates are not deterministic, but does not explain exactly why).
Two of the predicates you have defined, namely, bubblesort/3
and bubble/3
, have mutually exclusive clauses. But Prolog (at least SWI-Prolog) does not recognize that these are mutually exclusive. So, choice points are created, you don't get tail recursion optimization, and probably no garbage collection (you need to measure using your implementation of choice if you want to know how much goes where and when).
You have two different problems.
Problem 1: lists with exactly one element
This problem pops up in both predicates. In the most simple predicate possible:
foo([_]).
foo([_|T]) :-
foo(T).
And then:
?- foo([a]).
true ;
false.
This is not surprising; consider:
?- [a] = [a|[]].
true.
You can solve this by using a technique called lagging:
bar([H|T]) :-
bar_1(T, H).
bar_1([], _).
bar_1([H|T], _) :-
bar_1(T, H).
Then:
?- bar([a]).
true.
In the definition of bar_1/2
, the first argument to the first clause is the empty list; the first argument to the second clause is a non-empty list (a list with at least one element, and a tail). Prolog does not create choice points when all clauses are obviously exclusive. What obvious means will depend on the implementation, but usually, when the first arguments to all clauses are all terms with different functors, then no choice points are created.
Try the following (you might get different results, but the message is the same):
?- functor([], Name, Arity).
Name = [],
Arity = 0.
?- functor([_|_], Name, Arity).
Name = '[|]',
Arity = 2.
See this question and the answer by Mat to see how you can use this to make your program deterministic.
Mat, in his answer, uses this approach, if I see correctly.
Problem 2: constraints (conditions) in the body of the clauses
This is the problem with the second and third clause of bubble/3
. In the textbook "correct" example of choosing the minimum of two elements:
min(A, B, B) :- B @< A.
min(A, B, A) :- A @=< B.
Then:
?- min(1,2,1).
true.
but:
?- min(2,1,1).
true ;
false.
You can solve this in two ways: either by doing what Mat is doing, which is, using compare/3
, which succeeds deterministically; or, by doing what CapelliC is doing, which is, using an if-then-else.
Mat:
min_m(A, B, Min) :-
compare(Order, A, B),
min_order(Order, A, B, Min).
min_order(<, A, _, A).
min_order(=, A, _, A).
min_order(>, _, B, B).
And Carlo:
min_c(A, B, Min) :-
( B @< A
-> Min = B
; Min = A
).
I know there will always be at least as many opinions as heads, but both are fine, depending on what you are doing.
PS
You could use the built in length/2
to generate a list, and re-write your generate_list/3
like this:
generate_list(Limit, Len, List) :-
length(List, Len),
random_pos_ints(List, Limit).
random_pos_ints([], _).
random_pos_ints([H|T], Limit) :-
random(0, Limit, H),
random_pos_ints(T, Limit).
The helper random_pos_ints/2
is a trivial predicate that can be expressed in terms of maplist
:
generate_list(Limit, Len, List) :-
length(List, Len),
maplist(random(0, Limit), List).