Christophe De Troyer
Christophe De Troyer

Reputation: 2922

Prolog print array fails

I'm fairly new to Prolog, and I'm having the following issue:

I represent a two-dimensional array as follows:

[[ROW1], [ROW2],..]

I wrote a predicate to print out the two dimensional array as follows:

valueAt(1, [BEGIN | _], BEGIN).
valueAt(POSITION, [FIRST | REST], VAL) :- NPOS is POSITION - 1,
                                          valueAt(NPOS, REST, VAL). 

printRowValues([], _).
printRowValues(ROW, STARTIDX) :- valueAt(STARTIDX, ROW, VALUE),
                                 print(VALUE), print(' '),
                                 NEXTIDX is STARTIDX + 1,
                                 printRowValues(ROW, NEXTIDX).

printContainer(CONTAINER) :- printRows(CONTAINER, 1).

printRows([]).
printRows([ROW | REST]) :- printRowValues(ROW, 1),
                           printRows(REST).

This prints the first row and then just gives false. I don't really see my problem here..

PS: The function printRowValues uses the index because I used it to test my valueAt function. I know I can write the printrow function much simpler (see below) but that's not the point. I'm missing some Prolog knowledge here.

Simpler version that makes the entire thing work:

printRow([]).
printRow([HEAD | REST]) :- print(HEAD), print(' '),
                           printRow(REST).  

Sample query:

[debug] [1] 41 ?- printRows([[1, 1, 1], [2, 2, 2], [3, 3, 3]]).
1 1 1 
false

Upvotes: 2

Views: 774

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726599

The problem with your implementation is that the first (base) clause of the printRowValues is never reached, because the second clause does not reduce the list to make it shorter. It is the same list that is always passed, so Prolog interpreter never reaches the base clause.

You can fix this by changing the base clause to use len/1 predicate:

printRowValues(List, N) :- N is 1 + len(List).

This will terminate once N reaches the length of the list plus one (you need plus one because your indexes are one-based).

Upvotes: 1

Related Questions