Your remaining problem is in your vecTimesMatrix predicate:
vecTimesMatrix([],[[]],[]).
vecTimesMatrix([List], [MH|Mtail],[N]):-
getDotProd(List, MH, N),
vecTimesMatrix(List, Mtail, N).
Issues:
- In the second clause, the first argument is given as
[List] which would imply a list of a single element (List). Subsequent calls to getDotProd and vecTimesMatrix in the clause indicate that this should simply be List.
- In the second clause, the third argument is shown simply as a list of one argument:
[N]. So the third argument never "builds" a list. Additionally, the recursive call to vecTimesMatrix has N as its third argument, and that argument had already been instantiated by the prior query to getDotProd as the dot product of the vector List and the vectory MH. Logically, the recursive call should be saying that the vector product of List with Mtail is the tail of the final product.
- The base case assumes that the first argument reduces to
[], but this is not so. List always remains as-is throughout the recursive process. So instead of [] you should have _ (it will keep its value, but you don't care about it in the base case).
- The base case has as a second argument
[[]], but that's not the correct form for an empty list. That's actually a list consisting of one element, that element being the empty list. In reality, even though the second argument is a "list of lists", the empty list is still [].
Putting it all together (and renaming predicates per de facto conventions using underscores rather than camel case):
get_dot_prod([], [], 0.0). % Dot product of empty vectors is 0.0
% (Dot prod of vectors of unequal length
% is not defined and will fail)
get_dot_prod([H1|T1], [H2|T2], N) :- % N is dot product of [H1|T1] [H2|T2] if...
get_dot_prod(T1, T2, N1), % N1 is dot product of T1 T2, and
N is N1 + (H1 * H2). % N is N1 + (H1*H2) [evaluated]
vec_times_matrix(_, [], []). % Product of any vector with
% empty matrix is empty
vec_times_matrix(List, [MH|Mtail], [N|Ntail]):-
% [N|Ntail] is List x [MH|Mtail] if...
get_dot_prod(List, MH, N), % N is dot product of List and MH, and
vec_times_matrix(List, Mtail, Ntail). % Ntail is List x Mtail
This will yield:
| ?- vec_times_matrix([1,2],[[1,0],[0,1]], M).
M = [1.0,2.0] ? a
no
| ?- vec_times_matrix([1,2],[[1,0],[0,1],[1,1]], M).
M = [1.0,2.0,3.0] ? a
(1 ms) no
I added the comments in the code above to illustrate, in a simple way, how to think of the prolog predicate logic, which aids in defining them. As was pointed out already, the prolog "predicate" doesn't act as a "function". It describes a logical relation between entities which will either succeed or fail.
Once you learn to think how prolog thinks (relationally), you'll find it more enjoyable. :)
N is getDotProd..., where you meangetDotProd(List, MH, N). The other is that your two rules forgetDotProddo not have the same arity: first one has four parameters and the second has three. - Daniel Lyons