Программа Prolog, способная находить три последовательных и повторяющихся значения

#prolog

#пролог

Вопрос:

как говорится в названии, мне нужно написать программу, которая находит три равных и последовательных значения из списка, например:

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

Моя повседневная работа — функциональное программирование, но я немного борюсь с тем, что делает моя программа, потому что она никогда не выдает конкретные результаты (например: выходные X = [_7714,_7720,_7726] данные)

Программа, которую я сделал, следующая:

 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], []).
  

Чего мне здесь не хватает или что я путаю в теории prolog. Для меня моя программа имеет смысл, я не могу понять, где выполняется код на каждом шаге (даже с использованием trace. ).

Любая помощь полностью приветствуется! Заранее спасибо!

Ответ №1:

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

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

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

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

Обратите внимание, что имя like find/2 плохо вписывается в описательный образ мышления, поскольку оно предполагает операционализирующую точку зрения, которая затруднит ваше понимание Prolog. Поэтому вместо выдачи команд типа «найти эту последовательность» часто предпочтительнее просто описать, что есть.

Ответ №2:

Только частичный ответ. Использование стандартного append/3 предиката де-факто:

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

X = b ? ;

no
  

Но переход отсюда к списку с повторяющимся элементом должен быть простым.

Комментарии:

1. Здравствуйте, я ценю быстрый ответ, но я действительно не понял помощи в этом ответе 😞

Ответ №3:

Как насчет этого:

У вас есть три идентичных элемента X в начале списка, если у вас есть список, который выглядит следующим образом; здесь вторым параметром является «вывод»:

 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
  

И так:

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

Комментарии:

1. find([X,X,X],X). не требуется. _ может быть []

2. @MaxB Ошибка .. да!