#prolog
#пролог
Вопрос:
Я пытался оценить все последовательные 3 элемента списка, сравнить их, а затем извлечь средний элемент в другой список.
Пример:
У меня был такой список:[[1,2],[2,2],[2,3],[2,4]]
оценка #1: [1,2],[2,2],[2,3], потому что (2> 1 и 3> 2) для первого и 3-го элемента, поэтому будет взят средний элемент.
оценка #2: [2,2],[2,3],[2,4], потому что !(2> 2), поэтому средний элемент [2,3] не будет принят.
Однако я не смог указать, почему моя функция завершается с ошибкой, на последнем шаге для моей Tracker
переменной.
findMirror([],_).
findMirror([[X1,Y1],[X2,Y2]|[[X3,Y3]|T]],Tracker) :-
write([X1,Y1]),
write([X2,Y2]),
write([X3,Y3]),
write(" "),
findMirror([[X2,Y2]|[[X3,Y3]|T]],[[X2,Y2]|Tracker]).
Если я не включаю Tracker
, он работает нормально:
?- findMirror([[1,2],[3,4],[5,6],[7,8],[9,10]]).
[1,2][3,4][5,6] [3,4][5,6][7,8] [5,6][7,8][9,10]
с Tracker
:
?- findMirror([[1,2],[2,2],[2,3],[4,4]],M). [1,2][2,2][2,3] [2,2][2,3][4,4]
false.
чего я пытаюсь достичь:
?- findMirror([[1,2],[2,2],[2,3],[4,4]],M).
M = [[2,2],[2,3]].
Комментарии:
1. Где вы проверяете X1 < X2 и X2 <X3 в вашем предикате?
Ответ №1:
Вы неправильно используете синтаксис списков, который предлагает Prolog, а DRY (не повторяйтесь) и факторизация являются ключевыми, как и в любом другом языке, для обеспечения качества кода…
findMirror([],[]).
findMirror([A,B,C|T],Tracker) :-
( shouldKeepMiddle(A,C)
-> Tracker=[B|Tracker1]
; Tracker=Tracker1
),
findMirror(T,Tracker1).
shouldKeepMiddle([X1,Y1],[X3,Y3]) :- etc etc
Обратите внимание, что Tracker=[B|Tracker1]
это не присваивание, оно может быть также написано как [B|Tracker1]=Tracker
.