0

I am new to PROLOG and am trying some simple exercises to familiarize myself with it. However I am stuck in making an addition of 2x2matrix with another, more specifically lists within lists.

This is my code, the output using SWI-Prolog is False, and I have no idea why. Any help is appreciated!

matrixAdd([X],[Y],[S]) :- S is X + Y.
matrixAdd([[H|A],[I|B]],[[J|C],[K|D]],[[S1|Sum1],[S2|Sum2]]) :-
    S1 = H + J,
    S2 = I + K,
    matrixAdd([A,B],[C,D],[Sum1,Sum2]).
Logan
  • 267
  • 3
  • 8
  • 18
  • 1
    You cleverly used `S is X + Y` in your base case, but forgot about it in the second clause: there you have `S1 = H + J`. –  Apr 26 '16 at 17:15
  • @Boris Could you elaborate please? – Logan Apr 26 '16 at 17:20

2 Answers2

1

Elaborating:

?- A = 2 + 3.
A = 2+3.

?- A = 2 + 3, A == 5.
false.

?- A = 2 + 3, A = 5.
false.

?- A is 2 + 3, A =:= 10/2.
A = 5.

?- A is 2 + 3, A = 10/2.
false.

Figure out why you get each of these answers.

Furthermore, think about how you want to represent your matrix. Does it need to be a nested list? For example, it could be something like matrix(dim(2,2), [1,2,3,4]). Then, adding two matrices would be as easy as:

matrix_sum(matrix(D, V1), matrix(D, V2), matrix(D, Sum)) :-
    maplist(add, V1, V2, Sum).

add(X, Y, Sum) :-
    Sum is X + Y.

(You could get fancy and use a constraint library for the add operation. For example, with library(clpr) you could write {Sum = X+Y} and use the same predicate for addition and for subtraction.)

This uses unification in the head to make sure that the two matrices have the same dimensions, while the maplist take care of V1 and V2 being the same length.

Or you prefer a list of lists. Then, figure out the general predicate that adds lists of lists together (see the other answer!). Now you have a weird mix where you kind of know the magnitude of one dimension in advance, but still attempt to traverse the other dimension. As your code is at the moment, it is your base case that always fails. It should be:

matrixAdd([[],[]],[[],[]],[[],[]]).

(so many lists!) and without any body. Try replacing it in your original code and see what happens.

0

You first need to know the following:

  • There is a difference between = and is/2
  • Check your list syntax [Head|Tail] is different from [Element1,Element2]
  • Unification of [X] will only work when you pass a list with exactly 1 element. Just like [[A,B],[C,D]] will only match a 2 by 2 matrix. (Note that the elements A,B,.. could be lists as well in that case)

For you hardcode solution, fixing all these issues should work, but I want to leave that to you for now.

matrixAddHardcode([[A1,A2],[A3,A4]],[[B1,B2],[B3,B4]],[[S1,S2],[S3,S4]]) :- S1 is A1 + B1, S2 is A2 + B2, S3 is A3 + B3, S4 is A4 + B4.

Solution for any X by Y

matrixAddFix([],[],[]). matrixAddFix([L1|T1],[L2|T2],[S1|TS]) :- listSum(L1,L2,S1), matrixAddFix(T1,T2,TS). listSum([],[],[]). listSum([H1|T1],[H2|T2],[S1|TS]) :- S1 is H1+H2, listSum(T1,T2,TS).

Community
  • 1
  • 1
Sam Segers
  • 1,951
  • 2
  • 22
  • 28