John Z
John Z

Reputation: 89

Prolog recursively iterate a list fail

I was trying to evaluate every consecutive 3 elements of a list, compare them then extract the middle element into another list.

Ex:

I had list like this:[[1,2],[2,2],[2,3],[2,4]]

eval #1: [1,2],[2,2],[2,3], because (2>1 & 3>2) for the first and 3rd element, so middle element will be taken.

eval #2: [2,2],[2,3],[2,4], because !(2>2), so middle element [2,3] will not be taken.

However, I couldn't finger out why my function fails, at the last step for my Tracker variable.

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

If I don't include Tracker, it runs fine:

?- 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]

with Tracker:

?- findMirror([[1,2],[2,2],[2,3],[4,4]],M).                                                                                                                                          [1,2][2,2][2,3] [2,2][2,3][4,4] 
false.

what I am trying to achieve:

?- findMirror([[1,2],[2,2],[2,3],[4,4]],M).
  M = [[2,2],[2,3]].

Upvotes: 0

Views: 43

Answers (1)

CapelliC
CapelliC

Reputation: 60004

You're not using appropriately the syntax of lists that Prolog offers, and DRY (don't repeat yourself) and factorization are keys as in any other language for code quality...

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

Note that Tracker=[B|Tracker1] is not an assignment, it can be as well written like [B|Tracker1]=Tracker.

Upvotes: 2

Related Questions