Ошибка рекурсивной итерации списка в Prolog

#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 .