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 togetDotProd
andvecTimesMatrix
in the clause indicate that this should simply beList
. - 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 tovecTimesMatrix
hasN
as its third argument, and that argument had already been instantiated by the prior query togetDotProd
as the dot product of the vectorList
and the vectoryMH
. Logically, the recursive call should be saying that the vector product ofList
withMtail
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. :)