Hello I am trying to make a program in Prolog that given a list it counts the occurrences of each successive element in the list as follows:
count(1,[1,1,1,2,2,2
Here's another try of doing run-length encoding, based on clpfd!
:- use_module(library(clpfd)).
Based on if_/3 and (=)/3, we define list_rle/2:
list_rle([],[]).
list_rle([X|Xs],[N*X|Ps]) :-
list_count_prev_runs(Xs,N,X,Ps).
list_count_prev_runs(Es,N,X,Ps) :-
N #> 0,
N #= N0+1,
list_count_prev_runs_(Es,N0,X,Ps).
list_count_prev_runs_([],0,_,[]).
list_count_prev_runs_([E|Es],N,X,Ps0) :-
if_(X=E,
list_count_prev_runs(Es,N,X,Ps0),
(N = 0, Ps0 = [M*E|Ps], list_count_prev_runs(Es,M,E,Ps))).
Sample queries:
encode/decode #1
?- list_rle([a,a,b,c,c,c,d,e,e],Ys). Ys = [2*a,1*b,3*c,1*d,2*e]. ?- list_rle(Xs,[2*a,1*b,3*c,1*d,2*e]). Xs = [a,a,b,c,c,c,d,e,e] ; false.
encode/decode #2
?- dif(A,B),dif(B,C),dif(C,D),dif(D,E), list_rle([A,A,B,C,C,C,D,E,E],Ys). Ys = [2*A,1*B,3*C,1*D,2*E], dif(A,B), dif(B,C), dif(C,D), dif(D,E). ?- list_rle(Xs,[2*A,1*B,3*C,1*D,2*E]). Xs = [A,A,B,C,C,C,D,E,E], dif(A,B), dif(B,C), dif(C,D), dif(D,E) ; false.
How about something a little more general?
?- list_rle([A,B,C,D],Xs). Xs = [4*A ], A=B , B=C , C=D ; Xs = [3*A, 1*D], A=B , B=C , dif(C,D) ; Xs = [2*A, 2*C ], A=B , dif(B,C), C=D ; Xs = [2*A, 1*C,1*D], A=B , dif(B,C), dif(C,D) ; Xs = [1*A,3*B ], dif(A,B), B=C , C=D ; Xs = [1*A,2*B, 1*D], dif(A,B), B=C , dif(C,D) ; Xs = [1*A,1*B,2*C ], dif(A,B), dif(B,C), C=D ; Xs = [1*A,1*B,1*C,1*D], dif(A,B), dif(B,C), dif(C,D).