Вот еще один, он использует карту вместо добавления. Dot-продукты производятся для продуктов, не имеющих номера. Это также детерминистично.
Множитель:
amul([], _Other_Row,[]).
amul([X|Xs],Other_Row,[Row_Out|Rest_Out]) :-
maplist(mul(X),Other_Row, Row_Out),
amul(Xs,Other_Row, Rest_Out).
Предикат продукта:
mul(X,Y, Prod) :-
( number(X), number(Y)
-> Prod is X * Y
; true
-> Prod = dot(X,Y)
).
[1,3,5] X [2,4,6]
?- amul([1,3,5], [2,4,6],Prod).
Prod = [[2, 4, 6], [6, 12, 18], [10, 20, 30]].
[a, b, c] X [1,2,3,4]
?- amul([a,b,c],[1,2,3,4],Prod).
Prod = [[dot(a, 1), dot(a, 2), dot(a, 3), dot(a, 4)],
[dot(b, 1), dot(b, 2), dot(b, 3), dot(b, 4)],
[dot(c, 1), dot(c, 2), dot(c, 3), dot(c, 4)]].