0
votes

I am new to prolog and I'm trying to create a specific matrix. What I already have:

  • a matrix filled with all 0-s
  • a list of pairs of number, for expl. [1-1, 2-3, 2-4]

What I want to do is replace the 0-s to 1-s in the matrix in the positions that are indicated by the pairs of numbers. I already have a predicate that given the matrix and row and column number, does the switch from 0 to 1, but I am stuck while iterating through the list of pairs. I am trying to do this:

%replace(Mx, RowId, ColumnId, Value, ResultMx)
%generateMx(Mx, ListOfPairs, ResMx)
generateMx(_, [], _).
generateMx(Mx, [I-J|Tail], Res) :-
    generateMx(Mx, Tail, Res1),
    replace(Res1, I, J, 1, Res).

But for some reason it's giving weird results.

I also tried:

generateMx(Mx, [], Res) :- Res is Mx.
generateMx(Mx, [I-J|Tail], Res) :-
    replace(Mx, I, J, 1, Res1),
    (Tail == []) -> Res is Res1 ; generateMx(Res1, Tail, Res2).

For this I get an error, but I at least see that it's trying to compare the correct result matrix with some value in as is condition. I guess it doesn't stop iterating when it supposed to?

Could someone help figuring out my mistake and how I should do this?

1

1 Answers

0
votes

generateMx(_, [], _). is wrong. If you want to constrain input and output to be the same, you should explicitly say so: generateMx(X, [], X). or as generateMx(X, [], Y) :- X = Y.. Both are equivalent but the first is more idiomatic.

By using _ in both places you are saying generateMx to succeed for any input with any output as long as the list of pairs is empty. This will succeed when it should not.

?- generateMx([[0, 0], [0, 0]], [], [[1, 1], [1, 1]]).
true 

As for the second part:

  • I do not know how your matrix is being represented, but is/2 can only be used for arithmetic. It is not a generic equality operator. You should use =.
  • -> precedence is wrong. If you write A, B -> C; D you actually mean (A, B) -> C; D
  • If you are checking for an empty Tail, the first clause is a bit redundant. Your first answer has a better approach.
generateMx(Mx, [I-J|Tail], Res) :-
    replace(Mx, I, J, 1, Res1),
    ( Tail == [] -> Res = Res1 ; generateMx(Res1, Tail, Res) ).