:- module(_,[mmultiply/3],[assertions,regtypes,nativeprops]).

:- entry mmultiply(_A,_B,_C)
         : ( nlilist(_A), nlilist(_B), var(_C) ).

:- pred mmultiply(_A,_B,_C)
         : ( nlilist(_A), nlilist(_B), var(_C) ).

mmultiply(A, B, C) :- mmultiply_(A, B, C).

:- pred mmultiply_(_A,_B,_C)
         : ( nlilist(_A), nlilist(_B), var(_C) )
        => ( nlilist(_C) ).

mmultiply_([],_1,[]).
mmultiply_([V0|Rest],V1,[Result|Others]) :-
        mmultiply_(Rest,V1,Others),
        multiply(V1,V0,Result).

:- pred multiply(_A,_1,_B)
         : ( nlilist(_A), nlist(_1) )
        => ( nlist(_B) ).

multiply([],_1,[]).
multiply([V0|Rest],V1,[Result|Others]) :-
        multiply(Rest,V1,Others),
        vmul(V0,V1,Result).

:- pred vmul(_A,_B,Result)
         : ( nlist(_A), nlist(_B) )
        => ( num(Result) ).

vmul([],[],0).
vmul([H1|T1],[H2|T2],Result) :-
        vmul(T1,T2,Newresult),
        Product is H1*H2,
        Result is Product+Newresult.

:- prop nlilist/1+regtype.

nlilist([]).
nlilist([X|Xs]) :-
        nlist(X),
        nlilist(Xs).

:- prop nlist/1+regtype.

nlist([]).
nlist([X|Xs]) :-
        num(X),
        nlist(Xs).
