Reputation: 3
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).
Upvotes: 0
Views: 1651
Reputation: 18726
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.
Upvotes: 1
Reputation: 3
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).
Upvotes: 0