First N Fibonacci Numbers in Prolog - prolog

I want to generate the 1st N fibonacci numbers in Prolog. That means whenever I will give N = 5, it should print : 0,1,1,2,3, But whenever I run it suppose with N =5 then it gives output as : 1,2,1,3,1,2,5.
Below is my program:
fib(0,0).
fib(1,1).
fib(F,N) :-
N>1,
N1 is N-1,
N2 is N-2,
fib(F1,N1),
fib(F2,N2),
F is F1+F2,
format('~w, ',[F]).

Just so we're all on the same page, this is what happens when running your code with N = 5:
?- fib(Fib, 5).
1, 2, 1, 3, 1, 2, 5,
Fib = 5 ;
false.
You are trying to print results rather than computing a data structure (a list) of the results. This is almost always not the way to go in Prolog.
(As an aside, the usual order of arguments in Prolog is "inputs" first, then "outputs". I believe most Prolog programmers would expect this predicate to be fib(N, Fib) rather than fib(Fib, N). We'll continue with your version, but it is confusing!)
One of the problems with printing intermediate results is that it can be difficult to understand which results are printed, and in which order. We can change your printing goal to be a bit more explicit about that is going on:
format('computed fib(~w, ~w)~n',[F, N]).
This gives:
?- fib(Fib, 5).
computed fib(1, 2)
computed fib(2, 3)
computed fib(1, 2)
computed fib(3, 4)
computed fib(1, 2)
computed fib(2, 3)
computed fib(5, 5)
Fib = 5 ;
false.
As you can see, this "naive" Fibonacci computation computes intermediate results several times, which is why you get more outputs than you expected. For example (in functional notation), computing fib(4) will compute fib(2) and fib(3), but computing fib(5) will also compute fib(3) separately.
If you remove the printing, your predicate does work correctly, for example:
?- fib(Fib, 4).
Fib = 3 .
?- fib(Fib, 5).
Fib = 5 .
?- fib(Fib, 6).
Fib = 8 .
?- fib(Fib, 7).
Fib = 13 .
There are several ways of getting the results into a list if you really want. For example, using some predicates from the SWI-Prolog library:
?- numlist(1, 20, Ns), maplist(fib, Fibs, Ns).
Ns = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Fibs = [1, 1, 2, 3, 5, 8, 13, 21, 34|...] ;
false.
There are several problems with this: Do you really want a list? Prolog's backtracking for computing results one after the other is often superior to computing a list of results "all at once". More importantly, this naive Fibonacci implementation is very very inefficient. The above goal takes over a second on my machine.

From "Approach 3" on this answer, completely reviewed here:
At
rosettacode.org,
under Fibonacci/Prolog, the following quite interesting solution is
given. It uses a "lazy list", which is an open list (a list where the
termination (the "fin") is not [] but an unbound variable), where a
"frozen goal" is attached to the list-terminating unbound variable using
the predicate
freeze/2.
The frozen goal is run (a "coroutine") whenever the value of that
unbound variable is needed.
Proceed "bottom-up" with a "lazy list" as cache. The "lazy list"
is an open list that has a frozen goal to compute the next list
entry on its "fin".
Retrieving a member of the list using nth0(N,Cache,F) causes unification of the unbound "fin" with a new listbox [|]. This
thaws the goal on the "fin", which then computes the next
Fibonacci number, unifies it with arg1 of the listbox and then
sets up a new frozen goal on arg2 of the listbox, the
% new "fin" of the lazy list.
It is not directly evident why this works with nth0/3, so a replacement predicate retrieve/3 which also prints debugging messages has been provided.
Example:
?- debug(fib_bll).
?- fib_bottomup_lazylist_cache(10,F,Cache).
% At this point, the cache just contains [0,1|_]: [0,1|_28196]
% At K = 0, N = 10, No unfreeze at this point
% At K = 1, N = 10, No unfreeze at this point
% At K = 2, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 0, FB = 1, FIN has been unified to [1|_28628]
% At K = 3, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 1, FB = 1, FIN has been unified to [2|_28910]
% At K = 4, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 1, FB = 2, FIN has been unified to [3|_29192]
% At K = 5, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 2, FB = 3, FIN has been unified to [5|_29474]
% At K = 6, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 3, FB = 5, FIN has been unified to [8|_29756]
% At K = 7, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 5, FB = 8, FIN has been unified to [13|_30038]
% At K = 8, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 8, FB = 13, FIN has been unified to [21|_30320]
% At K = 9, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 13, FB = 21, FIN has been unified to [34|_30602]
% At K = 10, N = 10, Will call unification with a listbox that will unfreeze the goal
% Unfrozen: FA = 21, FB = 34, FIN has been unified to [55|_30884]
% Unfrozen: FA = 21, FB = 34, FIN has been unified to [55|_30884]
% F = 55,
% Cache = [0,1,1,2,3,5,8,13,21,34,55|_31458],
% freeze(_31458,fibonacci_algorithms:bll_frozen(34,55,_31458)).
Note that for call to retrieve/3, where K==N, the same debug
message is issued twice. This is because
retrieve_3(K,N,[_|More],F) is attempted first, leading to
thawing, but then a rollback is issued due to K<N, and the
frozen goal is reinstated. The second clause
retrieve_3(N,N,[F|_],F) is then attempted, leading to the same
thawing. Side-effects in Prolog: interesting.
This approach allows you to widen the cache on request, too.
For example,
This approach allows you to widen the cache on request, too. For
example, if I want fib(10) first, but then also fib(13) I can just reuse the cache, lengthening it:
?-
fibb_bottomup_lazylist_cache(10,Fib10,Cache),nth0(13,Cache,Fib13).
Fib10 = 55,
Cache = [0,1,1,2,3,5,8,13,21,34,55,89,144,233|_55906],
Fib13 = 233,
freeze(_55906,fibonacci_algorithms:bll_frozen(144,233,_55906)).
Note the residual goal being printed out.
% Carve the constants fib(0) and fib(1) out of the code.
const(fib0,0).
const(fib1,1).
% :- debug(fib_bll). % Uncomment to allow debugging printout
fib_bottomup_lazylist_cache(N,F,Cache) :-
const(fib0,F0),
const(fib1,F1),
Cache=[F0,F1|Fin],
freeze(
Fin,
bll_frozen(F0,F1,Fin)),
debug(fib_bll,"At this point, the cache just contains [0,1|_]: ~q",Cache),
% nth0(N,Cache,F).
retrieve(N,Cache,F).
bll_frozen(FA,FB,FIN) :-
FC is FA + FB,
FIN=[FC|NewFIN],
debug(fib_bll,"Unfrozen: FA = ~d, FB = ~d, FIN has been unified to ~q",[FA,FB,FIN]),
freeze(
NewFIN,
bll_frozen(FB,FC,NewFIN)).
% A replacement for nth0/3 to show what's going on
retrieve(N,Cache,F) :-
retrieve_2(0,N,Cache,F).
retrieve_2(K,N,Cache,F) :-
(var(Cache)
-> debug(fib_bll,"At K = ~d, N = ~d, Will call unification with a listbox that will unfreeze the goal",[K,N])
; debug(fib_bll,"At K = ~d, N = ~d, No unfreeze at this point",[K,N])),
retrieve_3(K,N,Cache,F).
retrieve_3(K,N,[_|More],F) :-
K < N,
!,
Kp is K+1,
retrieve_2(Kp,N,More,F).
retrieve_3(N,N,[F|_],F).

Related

Prolog: generate solution according to the original list

I am a beginner in Prolog, and I've searched a lot but cannot solve the problem. The question is giving me a list given the head of the list, such as [20,_,_,_].
The length of the list is unknown. For example, it could be [30,_,_,_,_,_].
the _ is the distinct factor, which only consists of the digit from 1 to 9. For example, [20,_,_,_] could generate [1,4,5] and its combination.
The list could be filled with a number first. For example, [20,_,4,_]. The output would be still [1,4,5] and [5,4,1].
What I've tried is to rip off the head of the list, and try to generate the rest of the elements back to the original list, but I failed, and cannot understand the debugger and its trace information.
removeHead([Head|Tail],Tail).
get_head_element([],_).
get_head_element([Head|Rest],Head).
divide(1,[],_).
divide(Number,[Head|List],Result):-
0 is mod(Number,Head),
Quotient is Number/Head,
divide(Quotient,List,Result).
solve_multiply(Row,RestRow):-
get_head_element(Row, Goal),
removeHead(Row,RestRow),
all_distinct(RestRow),
RestRow ins 1..9,
divide(Goal,RestRow,RestRow).
Any hint of resource that I can keep approaching this question? Thanks.
EDIT:
I think it another way that the elements multiplied in the list would be the same at the head, so I wrote a multiply predicate.
%% multiply(+List,-Result)
%
% for calling the multiply(+List,+PrevResult,+Result) with accumulator set to 1
multiply(List,Result):-
multiply(List,1,Result).
%% multiply(+List,+PrevResult,+Result)
%
% multiply each element in the list
multiply([Element|RestList],PrevResult,Result):-
NextResult is PrevResult * Element,
multiply(RestList,NextResult, Result).
%% multiply([], -Result, -Result).
%
% multiply predicate stops when all the elements have been multiplied
multiply([], Result, Result).
%% solve_multiply(+Row,-RestRow)
solve_multiply(Row,RestRow):-
get_head_element(Row, Goal),
removeHead(Row,RestRow),
RestRow ins 1..9,
multiply(RestRow,Goal), % get the Arguments not sufficiently instantiated message
all_distinct(RestRow).
The simplest way to find the solution is to:
Compare the multiplied elements to the head element.
Use the constraint provided by clpfd.
Therefore, the code should be:
multiply(List,Result):-
multiply(List,1,Result).
multiply([Element|RestList],PrevResult,Result):-
NextResult #= PrevResult * Element, % constraint that works for both side ?X #= ?Y
multiply(RestList,NextResult, Result). % tail recursion
multiply([], Result, Result).
solve_multiply(Row,RestRow):-
get_head_element(Row, Goal),
removeHead(Row,RestRow),
RestRow ins 1..9,
multiply(RestRow,Goal),
all_distinct(RestRow).
When calling the solve_multiply([20,_,_,_],X), labeling([],X). The result is:
X = [1, 4, 5] ;
X = [1, 5, 4] ;
X = [4, 1, 5] ;
X = [4, 5, 1] ;
X = [5, 1, 4] ;
X = [5, 4, 1] ;
false.
When calling the solve_multiply([20,_,1,_],X), labeling([],X). The result is:
X = [4, 1, 5] ;
X = [5, 1, 4].

Find all natural divisors of a number (with Prolog)

I want to create a predicate divisors(X,[Y]) which is true if
X>1 and Y is the list of all divisors of X starting with X and going down to 1.
What my code right now looks like:
divisors(1,[1]).
divisors(X,[Y,Z|Ys]) :-
X>0,
Y is X,
Y>Z,
divides(X,[Z|Ys]).
divides(X,[Y,Z|Ys]) :-
Y>Z,
0 is X mod Y,
divides(X,[Z|Ys]).
divides(X,[1]).
But there are several problems with it:
prolog returns an error if asked for the list (e.g. ?-divisors(10,X).)
?- divisors(X,[Y]). Where [Y] is an incomplete list of divisors is true...
Edit by Guy Coder
This answer is by the OP and was posted in a comment below.
Moving here so others can see it.
divisors(X,R) :-
X > 1,
divisors(X,1,[],R).
divisors(X,D,R,R):-
D>X.
divisors(N,D0,R0,R) :-
divisors_0(N,D0,R0,R1),
D is D0 + 1,
divisors(N,D,R1,R).
divisors_0(N,D,R0,[D|R0]) :-
divides(N,D).
divisors_0(N,D,R0,R0).
divides(N,D) :-
0 is N mod D.
Op also noted some errors in this version:
It doesn't terminate if I ask a wrong statement like (10,[1,2,3]).
It throws an error if I ask a statement like (X, [10,5,2,1]). (-> Arguments are not sufficiently initialized.)
While the answer by William is nice and probably faster here is answer closer to what you were writing.
divides(N,D) :-
0 is N mod D.
divisors_0(N,D,R0,[D|R0]) :-
divides(N,D).
divisors_0(N,D,R0,R0) :-
\+ divides(N,D).
divisors(_,0,R,R).
divisors(N,D0,R0,R) :-
divisors_0(N,D0,R0,R1),
D is D0 - 1,
divisors(N,D,R1,R).
divisors(X,R) :-
X > 1,
divisors(X,X,[],R), !.
Example:
?- between(1,15,N), divisors(N,Rs).
N = 2,
Rs = [1, 2] ;
N = 3,
Rs = [1, 3] ;
N = 4,
Rs = [1, 2, 4] ;
N = 5,
Rs = [1, 5] ;
N = 6,
Rs = [1, 2, 3, 6] ;
N = 7,
Rs = [1, 7] ;
N = 8,
Rs = [1, 2, 4, 8] ;
N = 9,
Rs = [1, 3, 9] ;
N = 10,
Rs = [1, 2, 5, 10] ;
N = 11,
Rs = [1, 11] ;
N = 12,
Rs = [1, 2, 3, 4, 6, 12] ;
N = 13,
Rs = [1, 13] ;
N = 14,
Rs = [1, 2, 7, 14] ;
N = 15,
Rs = [1, 3, 5, 15].
Edit
OP modified their code, see update in question and had some errors.
This version resolves those errors.
divisors(X,R) :-
(
var(X)
->
false
;
(
var(R)
->
X > 1,
divisors(X,1,[],R)
;
divisors_2(X,R), !
)
).
divisors_2(_,[]).
divisors_2(X,[H|T]) :-
divides(X,H),
divisors_2(X,T).
divisors(X,D,R,R):-
D>X.
divisors(N,D0,R0,R) :-
divisors_0(N,D0,R0,R1),
D is D0 + 1,
divisors(N,D,R1,R).
divisors_0(N,D,R0,[D|R0]) :-
divides(N,D).
divisors_0(_,_,R0,R0).
divides(N,D) :-
0 is N mod D.
The first error: It doesn't terminate if I ask a wrong statement like divisors(10,[1,2,3]).
is fixed by adding to divisors/2
(
var(R)
->
X > 1,
divisors(X,1,[],R)
;
divisors_2(X,R), !
)
and
divisors_2(_,[]).
divisors_2(X,[H|T]) :-
divides(X,H),
divisors_2(X,T).
which just processes the list of denominators instead of generating a list.
The second error: It throws an error if I ask a statement like divisors(X, [10,5,2,1]). (-> Arguments are not sufficiently initialized.)
is resolved by further adding to divisor/2
divisors(X,R) :-
(
var(X)
->
false
;
(
var(R)
->
X > 1,
divisors(X,1,[],R)
;
divisors_2(X,R), !
)
).
which checks if the first parameter X is a variable and if so just returns false. The other option would be to generate an infinite list of answers. While possible it wasn't requested.
In Prolog, it is quite common to use backtracking and propose multiple solutions to the same query. Instead of constructing a list of dividers, we thus can construct a predicate that unifies the second parameter with all divisors. For example:
divisor(N, D) :-
between(1, N, D),
0 is N mod D.
This then yields:
?- divisor(12, N).
N = 1 ;
N = 2 ;
N = 3 ;
N = 4 ;
N = 6 ;
N = 12.
The above algorithm is an O(n) algorithm: we scan for divisors linear with the value of the item for which we want to obtain the divisors. We can easily improve this to O(√n) by scanning up to √n, and each time yield both the divisor (of course in case it is a divisor), and the co-divisor, like:
emitco(D, _, D).
emitco(D, C, C) :-
dif(D, C).
divisor(N, R) :-
UB is floor(sqrt(N)),
between(1, UB, D),
0 is N mod D,
C is N / D,
emitco(D, C, R).
This still yield the correct answers, but the order is like a convergent alternating sequence:
?- divisor(12, N).
N = 1 ;
N = 12 ;
N = 2 ;
N = 6 ;
N = 3 ;
N = 4.
?- divisor(16, N).
N = 1 ;
N = 16 ;
N = 2 ;
N = 8 ;
N = 4 ;
false.
We can obtain a list of the divisors by using a findall/3 [swi-doc] or setof/3 [swi-doc]. The setof/3 will even sort the divisors, so we can implement divisors/2 in terms of divisor/2:
divisors(N, Ds) :-
setof(D, divisor(N, D), Ds).
For example:
?- divisors(2, N).
N = [1, 2].
?- divisors(3, N).
N = [1, 3].
?- divisors(5, N).
N = [1, 5].
?- divisors(12, N).
N = [1, 2, 3, 4, 6, 12].
?- divisors(15, N).
N = [1, 3, 5, 15].
We can use reverse/2 to reverse that result.

To compare the Equality and Print the Equal value

I want to compare 2 values X and C1 as you can see in code, X is reversed value of C if both values are equal then it should print the compared value please tell me how to do this. It is to print Palindrome Numbers like... 1,11,22,33,44,55,66,77,88,99,101....
go(N):-
write(0),nl,
go(0,N).
go(_,0):- !.
go(A,C):-
A1 is A,
C1 is A1 + 1,
/* write(C1),nl,*/
rev(C1,X),
/* write(X),nl,*/
/* To compare the Value of X and C1 and print if compared value is true*/
NewC is C-1,
go(C1,NewC).
rev(Q,E):-
name(Q, Q1),
reverse(Q1,E1),
name(E,E1).
Describing palindrome numbers is actually a nice task for CLP(FD) and DCGs. First let's describe what the digits of a palindrome number look like:
:- use_module(library(clpfd)).
palindromedigits(Digits) :- % Digits are palindrome digits if
Digits ins 0..9, % they are between 0 and 9
Digits = [H|_], % and the first digit...
H #\= 0, % ... is different from 0
phrase(palindrome, Digits). % and they form a palindrome
palindrome --> % a palindrome is
[]. % an empty list
palindrome --> % or
[_]. % a list with a single element
palindrome --> % or
[A], % an element A
palindrome, % followed by a palindrome
[A]. % followed by an element A
To test if a number is a palindrome, you could turn it into a list of digits and palindromedigits/1 has to hold for that list. To generate such numbers, you could use length/2 to describe lists of all possible lengths, palindromedigits/1 again has to hold for those lists and the digits have to be multiplied by their respective powers of ten and summed up. Since leading zeros are excluded by palindromedigits/1, you'd have to add a fact for 0, if you want to include it in the palindrome numbers. That might look something like this:
palindromenumber(0). % 0 is a palindromenumber
palindromenumber(PN) :- % rule for testing numbers
number(PN), % succeeds if PN is a number
number_codes(PN,C), % C is a list of codes corresponding to the digits
maplist(plus(48),Digits,C), % codes and digits are off by 48
palindromedigits(Digits). % Digits is a palindrome
palindromenumber(PN) :- % rule for generating numbers
var(PN), % succeeds if PN is a variable
length(Digits,_), % Digits is a list of length 0,1,2,...
palindromedigits(Digits), % Digits is a palindrome
digits_number_(Digits,PN,1,0), % Digits correspond to the number PN
label(Digits). % labels the list Digits with actual numbers
Note that the codes corresponding to the digits are off by 48, hence the goal with maplist/3, e.g.:
?- number_codes(123,C), maplist(plus(48),Digits,C).
C = [49, 50, 51], % <- the codes
Digits = [1, 2, 3]. % <- the actual digits
The predicate digits_number_/4 is fairly straight forward. It is called with 1 as the initial power of ten and 0 as the initial accumulator for the number. The digits are multiplied with the power of ten corresponding to their position in the number and subsequently added to the accumulator. If the list of digits is empty, the accumulator holds the number corresponding to the list of digits.
digits_number_([],PN,_,PN).
digits_number_([D|Ds],PN,P,Acc) :-
Acc1 #= Acc + D*B,
P10 #= P*10,
digits_number_(Ds,PN,P10,Acc1).
Note that it doesn't matter that the digits are multiplied with the powers in reverse order, because it's a palindrome number.
Now you can query for palindrome numbers:
?- palindromenumber(PN).
PN = 0 ;
PN = 1 ;
PN = 2 ;
.
.
.
PN = 33 ;
PN = 44 ;
PN = 55 ;
.
.
.
PN = 666 ;
PN = 676 ;
PN = 686 ;
.
.
.
PN = 7667 ;
PN = 7777 ;
PN = 7887
.
.
.
Or you can test if a number is a palindrome:
?- palindromenumber(121).
true ;
false.
?- palindromenumber(123).
false.
?- palindromenumber(12321).
true ;
false.
EDIT
To address the question in your comment, you can do that by describing a relation between such a sequence and it's length. So you'll have a predicate with arity two instead of arity one. Let's give it a nice descriptive name, say firstN_palindromicnumbers/2. The actual realation is described by a predicate with an additional argument that holds the current candidate to be examined. Since you want to start the sequence with 1, that will be the argument firstN_palindromicnumbers_/3 will be called with:
firstN_palindromicnumbers(N,PNs) :-
firstN_palindromicnumbers_(N,PNs,1). % sequence starts with 1
The argument that holds the candidates will be increased by 1 through the recursions, while the first argument, N, will be decreased every time a candidate turns out to be an actual palindromic number. So the predicate eventually ends up with N being 0, an empty list and a candidate we don't care for. That will be the base case. Otherwise the head of the list is the smallest palindromic number in the (remainder of the) sequence. You can reuse the goals number_codes/2 and maplist/3 from above to describe a list of digits corresponding to the current candidate and the DCG palindrome//0 to state that the digits have to be a palindrome. The other goals from the predicate palindromedigits/1 won't be needed, since the candidates will be 1,2,3,..., thus consisting of (at least one) digit(s) from 0 to 9 without leading zeros. You can express this in Prolog like so:
firstN_palindromicnumbers_(0,[],_C). % base case
firstN_palindromicnumbers_(N1,[C0|PNs],C0) :- % case: C0 is a palindrome
N1 #> 0, % sequence is not of desired length yet
number_codes(C0,Codes),
maplist(plus(48),Digits,Codes),
phrase(palindrome, Digits), % digits form a palindrome
N0 #= N1-1, % sequence of length N1-1 has to be described yet
C1 #= C0+1, % C1 is the next candidate
firstN_palindromicnumbers_(N0,PNs,C1). % PNs is the rest of the sequence
firstN_palindromicnumbers_(N1,PNs,C0) :- % case: C0 ain't a palindrome
N1 #> 0, % sequence is not of desired length yet
number_codes(C0,Codes),
maplist(plus(48),Digits,Codes),
\+ phrase(palindrome, Digits), % digits don't form a palindrome
C1 #= C0+1, % C1 is the next candidate
firstN_palindromicnumbers_(N1,PNs,C1). % PNs is the rest of the sequence
Now you can query the predicate for a sequence of palindromic numbers of given length (Note that with SWI-Prolog you might have to hit w to see the entire list):
?- firstN_palindromicnumbers(15,PNs).
PNs = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] [write] % <- hit the w key
PNs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66] ;
false.
?- firstN_palindromicnumbers(25,PNs).
PNs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161] ;
false.
You can also use the predicate to check if a given list is the sequence of the first N palindrommic numbers:
?- firstN_palindromicnumbers(N,[1,2,3,4,5]).
N = 5 ;
false.
?- firstN_palindromicnumbers(N,[0|_]).
false.
?- firstN_palindromicnumbers(N,[1,2,3,4,11]).
false.
And the most general query yields the expected answers as well:
?- firstN_palindromicnumbers(N,PNs).
N = 0,
PNs = [] ;
N = 1,
PNs = [1] ;
N = 2,
PNs = [1, 2] ;
N = 3,
PNs = [1, 2, 3] ;
.
.
.

Prolog lists with lengths of constrained length [duplicate]

This question already has answers here:
Using a constrained variable with `length/2`
(4 answers)
Closed 5 years ago.
I'm using the clpfd library
?- use_module(library(clpfd)).
true.
Then I attempt to generate all 3 lists of length K with 1 <= K <= 3.
?- K in 1 .. 3, length(C, K).
K = 1,
C = [_1302] ;
K = 2,
C = [_1302, _1308] ;
K = 3,
C = [_1302, _1308, _1314] ;
ERROR: Out of global stack
I would expect the query to terminate after K = 3. For example, the following does terminate.
?- between(1, 3, K), length(X, K).
K = 1,
X = [_3618] ;
K = 2,
X = [_3618, _3624] ;
K = 3,
X = [_3618, _3624, _3630].
Why does one terminate and the other does not?
K in 1..3 simply asserts that K is somewhere between 1 and 3, without binding particular value. What you need is indomain(K) predicate, which backtracks over all values in K's domain:
K in 1..3, indomain(K), length(C, K).
Out of stack in your example happens for the following reason: length(C, K) without any of its arguments bound generates lists of different lengths, starting with 0, then 1, 2, 3, ...
Each time it generates a solution it tries bind a particular value to K, that is 0, 1, 2, ...
Now, because there are constraints applied to K, any attempts to bind a value greater than 3 will fail, meaning that length(C, K) will continue trying to find alternative solutions, that is, it will keep generating lists of length 4, 5, 6, ... and so on, all of which will be discarded. This process will continue until you exhaust your stack.

SWI-Prolog Delete items that have pair occurrences

I need a solution that deletes elements that have pairs of occurrences from list.
I did it in haskell, but i don't have any ideas how to interpretate it in Prolog.
For example [1,2,2,2,4,4,5,6,6,6,6] -> [1,2,2,2,5]
Code in Haskell :
import Data.List
count e list = length $ filter (==e) list
isnotEven = (== 1) . (`mod` 2)
removeUnique :: [Int] -> [Int]
removeUnique list = filter (\x -> isnotEven (count x list) ) list
The following follows your Haskell code.
You need library(reif) for SICStus|SWI.
:- use_module(reif).
oddcount_t(List, E, T) :- % reified: last argument is truth value
tfilter(=(E), List, Eqs),
length(Eqs, Nr),
M is Nr mod 2,
=(M, 1, T).
removeevenocc(List, RList) :-
tfilter(oddcount_t(List), List, RList).
?- removeevenocc([1,2,2,2,4,4,5,6,6,6,6], R).
R = [1,2,2,2,5].
?- removeevenocc([1,X], R).
X = 1, R = []
; R = [1, X],
dif(X, 1).
Note the last question. Here, the list was not entirely given: The second element is left unknown. Therefore, Prolog produces answers for all possible values of X! Either X is 1, then the resulting list is empty, or X is not 1, then the list remains the same.
this snippet uses some of the libraries (aggregate,lists,yall) available, as well as some builtins, like setof/3, and (=:=)/2:
?- L=[1,2,2,2,4,4,5,6,6,6,6],
| setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds),
| foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = [1, 2, 2, 2, 4, 4, 5, 6, 6|...],
Ds = [4, 6],
R = [1, 2, 2, 2, 5].
edit
to account for setof/3 behaviour (my bug: setof/3 fails if there are no solutions), a possible correction:
?- L=[1],
(setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds);Ds=[]),
foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = R, R = [1],
Ds = [].
Now there is a choice point left, the correct syntax could be
?- L=[1],
(setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds)->true;Ds=[]),
foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = R, R = [1],
Ds = [].

Resources