Пролог-мудрый, у вас есть несколько проблем. Во-первых, ваш предикат работает только при создании экземпляров обоих аргументов, что разочаровывает Prolog. Еще один ваш стиль - head/2
ничего не добавляет к [H|T]
. Я также считаю, что этот алгоритм в корне ошибочен. Я не думаю, что вы можете быть уверены, что в хвосте списка нет последовательности длинной длины, не сохраняя неизменной копии угадываемой длины. Другими словами, второе, что указывает @Zakum, я не думаю, что для этого будет простое решение.
Так я бы подошел к проблеме. Первый вспомогательный предикат для получения максимального из двух значений:
max(X, Y, X) :- X >= Y.
max(X, Y, Y) :- Y > X.
Сейчас большая часть работы sequence_length/2
делает делегирована петлю, для базового случая пустого списка, за исключением:
sequence_length([], 0).
sequence_length([X|Xs], Length) :-
once(sequence_length_loop(X, Xs, 1, Length)).
звонок в once/1
гарантирует, что мы получим только один ответ. Это предотвратит использование предиката с использованием списков с последовательностями, одновременно делая предикат детерминированным, что вам и нужно. (Он имеет тот же эффект, что и красиво вырезанный).
базовый случай Loop в: скопировать аккумулятор для выходного параметра:
sequence_length_loop(_, [], Length, Length).
Индуктивный случай # 1: у нас есть еще один экземпляр того же значения. Увеличьте аккумулятор и повторите попытку.
sequence_length_loop(X, [X|Xs], Acc, Length) :-
succ(Acc, Acc1),
sequence_length_loop(X, Xs, Acc1, Length).
Индуктивный корпус №2: у нас другое значение. Вычислить длину последовательности оставшейся части списка; если он больше нашего аккумулятора, используйте это; в противном случае используйте аккумулятор.
sequence_length_loop(X, [Y|Xs], Acc, Length) :-
X \= Y,
sequence_length([Y|Xs], LengthRemaining),
max(Acc, LengthRemaining, Length).
Вот как я подхожу к этой проблеме. Я не знаю, будет ли это полезно для вас или нет, но я надеюсь, что вы сможете что-то извлечь из этого.
Спасибо! это очень полезно. – URL87
@ Daniel_Lyons: Я был бы рад, если вы мне что-нибудь объясните, , как вы сказали, 'once' гарантировать, что мы получаем только 1 ответ, но если мы опустим это' once' и останемся с - 'sequence_length_loop (X, Xs, 1, Length) ', что может быть проверено больше проверок, чтобы получить больше результатов? здесь мы просто отправляем в 'sequence_length_loop' только созданные экземпляры' (X, Xs, 1, Length) '... – URL87
@ URL87 Мы получаем ложную точку выбора без' once', как и в оригинале. Я выбрал «один раз» здесь, потому что я нахожу его более аккуратным, чем введение сокращения после каждого из других целей, и он передает цель более четко, чем разрез после цели цикла. –