Reputation: 63
Im new to Prolog and was looking for some assistance. What i am trying to do is basically get a list L consisting of elements that repeat at least twice in a given list L'
Example L'=[1,2,1,3,4,3,2] => L=[1,2,3].
So far I am able to compute the occurrence of every consecutive variables
% pack(L1,L2) :- the list L2 is obtained from the list L1 by packing
% repeated occurrences of elements into separate sublists.
% (list,list) (+,?)
pack([],[]).
pack([X|Xs],[Z|Zs]) :- transfer(X,Xs,Ys,Z), pack(Ys,Zs).
% transfer(X,Xs,Ys,Z) Ys is the list that remains from the list Xs
% when all leading copies of X are removed and transfered to Z
transfer(X,[],[],[X]).
transfer(X,[Y|Ys],[Y|Ys],[X]) :- X \= Y.
transfer(X,[X|Xs],Ys,[X|Zs]) :- transfer(X,Xs,Ys,Zs).
% encode(L1,L2) :- the list L2 is obtained from the list L1 by run-length
% encoding. Consecutive duplicates of elements are encoded as terms [N,E],
% where N is the number of duplicates of the element E.
% (list,list) (+,?)
encode(L1,L2) :- pack(L1,L), transform(L,L2).
transform([],[]).
transform([[X|Xs]|Ys],[[N,X]|Zs]) :- length([X|Xs],N), transform(Ys,Zs).
which will return the following list of touples
?- encode([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
X = [[4,a],[1,b],[2,c],[2,a],[1,d][4,e]]
But there still remains the problem of building a list that will contain distinct elements that repeat at least twice.
If anyone can help me or point me in the general direction that would be great.
Thanks in advance
Upvotes: 0
Views: 679
Reputation: 60014
You could write a procedure:
% E it's the list of are elements from L that repeat at least twice
elements_that_repeat_at_least_twice(L, E) :-
elements_that_repeat_at_least_twice(L, [], E).
elements_that_repeat_at_least_twice([H|Ls], Dupl, E) :-
...
In elements_that_repeat_at_least_twice the added list Dupl will keep each element you verify it's present multiple times. Examine each element of L, using [H|Ls]. Use memberchk/2 to verify if H is in L: then it's at least duplicate. If it's not yet in Dupl, add to it, and recurse. Remember to write the recursion base case (stop at empty list []).
Now I see you have added some code: then I complete suggestion:
elements_that_repeat_at_least_twice([], Dupl, Dupl).
elements_that_repeat_at_least_twice([H|Ls], Dupl, E) :-
( memberchk(H, Ls)
-> ( \+ memberchk(H, Dupl)
-> Dupl1 = [H|Dupl]
; Dupl1 = Dupl
)
; Dupl1 = Dupl
),
elements_that_repeat_at_least_twice(Ls, Dupl1, E).
Remember to reverse the list of duplicates when done.
Upvotes: 0