0

I would like to get this result:

?- numberMatrixLines(1,[[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1]],X).
X = [machinePenalty(1,[1,1,1,1,1,1,1,1]),
     machinePenalty(2 [1,1,1,1,1,1,1,1]),
     machinePenalty(3,[1,1,1,1,1,1,1,1])]

I try the following code:

numberMatrixLines(X,[],ResultMatrix):-
   writeln('should end here'),
   reverse(ResultMatrix,ResultMatrixTemp),
   initWith(ResultMatrixTemp,ResultMatrix),
   !.
numberMatrixLines(X,[H|T],ResultMatrix):-
   append_in_front(machinePenalty(X,H),ResultMatrix,ResultMatrixTemp),
   writeln(ResultMatrixTemp),
   incr(X,X1),
   numberMatrixLines(X1,T,ResultMatrixTemp).            

incr(X, X1) :-
    X1 is X+1.                

append_in_front(X,[],[X]).
append_in_front(X,L1,[X|L1]).

The result is correct when numberMatrixLines(X,[],ResultMatrix) is reached. HOWEVER, the predicate won't stop there and return X , as it's supposed to.

What can be done to make it stop in that line?

false
  • 10,264
  • 13
  • 101
  • 209
Mandy
  • 145
  • 6
  • 1
    No need for the `append_in_front/3` predicate. `append_in_front(X,T,L)` is the same as `L = [X|T]`. – Paulo Moura Apr 04 '19 at 22:32
  • Also `incr/2` is almost `succ/2`, except `succ/2` works in both directions. – Daniel Lyons Apr 04 '19 at 22:33
  • 1
    Without seeing the code for `initWith/3` it's hard to say, but if that predicate fails, then the whole thing will fail. The cut does not look useful to me, since if the first clause matched, the second clause wouldn't match because lists cannot be both empty and have a head and tail. I think you are hoping the cut will work like a quick return. It doesn't do that, it simply commits Prolog to the choices it has already made. In other words, cuts don't do anything to your call stack, they do something to your redo stack. – Daniel Lyons Apr 04 '19 at 22:35

1 Answers1

1

A straight-forward solution would be (I moved the input list to the first argument to take advantage of Prolog first-argument indexing to avoid spurious choice-points and the need of cuts):

% number_matrix_lines(+list, +integer, -list)
number_matrix_lines([], _, []).
number_matrix_lines([Line| Lines], I, [machine_penalty(I,Line)| NumberLines]) :-
    J is I + 1,
    number_matrix_lines(Lines, J, NumberLines).

Sample call:

| ?- number_matrix_lines([[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1]], 1, NumberLines).

NumberLines = [machine_penalty(1,[1,1,1,1,1,1,1,1]), machine_penalty(2,[1,1,1,1,1,1,1,1]), machine_penalty(3,[1,1,1,1,1,1,1,1])]
yes

P.S. Note that Prolog coding guidelines advise using underscores in predicate names instead of CamelCase.

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33