Search code examples
prologdeclarative

How to translate an imperative task in prolog


I have a functor that calculate the Manhattan distance in a N-puzzle domain of a single tile:

distanzaTile(Stato, Pos, Dis) :-
  dim(D),
  nth0(Pos, Stato, Elem),
  Elem == v,
  Y is floor(abs((9 - (Pos + 1))/D)),
  X is mod(abs(9 - (Pos + 1)), D),
  Dis is X+ Y.
  !.
distanzaTile(Stato, Pos, Dis) :-
  dim(D),
  nth0(Pos, Stato, Elem),
  Y is floor(abs((Elem - (Pos + 1))/D)),
  X is mod(abs(Elem - (Pos + 1)), D),
  Dis is X+ Y.

where Stato is an array, Pos is the current position in the array taken into account, Dis is the actual result. Now, I have to cycle through all the elements of Stato and sum all the Diss. Thinking imperative I'd go for a for cycle. How to achieve something similar recursively?


Solution

  • I used Stato as input and as counter as follow:

    ricorri(_, [], _, A, A).
    ricorri(Stato, [_|T], Pos, In, Out) :-
      distanzaTile(Stato, Pos, Dis),
      Pos2 is Pos + 1,
      In2 is In + Dis,
      ricorri(Stato, T, Pos2, In2, Out).
    

    Hope it may help someone.