Prolog program capable of finding three consecutive and repetitive values

Viewed 80

as the title, says, I need to write a program that finds three equal and consecutive values from a List, eg:

find([o,o,a,b,b,b,c,c], X)
X = [b,b,b].

My day to day is functional programming, but I'm struggling a bit with what my program is doing because it never output concrete results (eg: outputs X = [_7714,_7720,_7726])

The program I did is the following:

find(_List, X) :-
    length(X, Size),
    Size = 3,
    format('X = ~w', [X]).

find([Equal, Equal|Tail], X) :-
    is_list(X),
    append([Equal, Equal], X, Y),
    find([Equal|Tail], Y).

find([Equal, Equal|Tail], _X) :-
    append([Equal, Equal], [], Y),
    find([Equal|Tail], Y).

find([_Equal, Diferent|Tail], _X) :-
    find([Diferent|Tail], []).

What Am I missing here or what Am I confusing in prolog theory. For me, my program makes sense, I can't really understand where the code is being executed in each step (even using trace.).

Any help is totally appreciated! Thanks in advance!

3 Answers
triple(X) --> [X,X,X].

... --> [] | [_], ... .

find(Xs, X) :-
   phrase(( ..., triple(X), ... ), Xs).

find2(Xs, X) :-
   phrase(( ..., [X,X,X], ... ), Xs).

Note that a name like find/2 does not fit nicely into a descriptive mindset as it suggests an operationalizing viewpoint which will hamper your understanding of Prolog. So instead of issuing commands like "find that sequence", simply describing what is, is often preferable.

Partial answer only. Using the de facto standard append/3 predicate:

| ?- append(_Suffix, [X,X,X|_Prefix], [o,o,a,b,b,b,c,c]).

X = b ? ;

no

But going from here to a list with the repeated element should be easy.

How about this:

You have three identical elements X at the front of a list if you have a list that looks like this; here the second parameter is the "output":

find([X,X,X|_],X).         % We have three identical elements X
                           % reflected in "output" X in a list of more than 3
                           % elements .

                           % or

find([X,X,X],X).           % We have three identical elements X
                           % reflected in "output" X in a list of exactly 3
                           % elements .

                           % or

find([_|Xs],X) :-          % We have three identical elements X in a list if
   find(Xs,X).             % we have three identical elements X in the rest

And so:

?- find([o,o,a,b,b,b,c,c], X).
X = b ;     <- I found b but maybe there are more
false.      <- Nah, actually not
Related