That seems complicated to me. The problem is to basically do long-form multiplication, the way that you'd do it on paper. If you first reverse the list (using the built-in reverse/2
predicate), things become much simpler:
%--------------------------------------------------------------%
% Mult/3: multiply a integer, represented as a list of digits, %
% by an integer value N, producing an integer, also %
% represented as a lsit of digits. %
%--------------------------------------------------------------%
multiply( Ds , N , Result) :-
reverse(Ds,Rs) ,
multiply( Rs , N , 0 , T ) ,
reverse( T , Result )
.
%
% the worker predicate that does all the work
%
multiply( [] , _ , C , [] ) :- % if the list is exhausted
C =< 0 % and the carry is 0,
. % we're done. C'est fini.
multiply( [] , _ , C , [C] ) :- % if the list is exhausted
C > 0 , % and the carry is 1-9, then
C < 10 % The last digit in the result is the carry
. % We're done. C'est fini.
multiply( [] , _ , C , [R|Rs] ) :- % If the list is exhausted,
C >= 10 , % and the carry is 10+,
R is C rem 10 , % the next digit in the result is the carry modulo 10
Q is C div 10 , % take the quotient
multiply( [] , _ , Q , Rs ) % and recurse down with the quotient as the carry
. %
multiply( [D|Ds] , N , C , [R|Rs] ) :- % if the list is NOT exhausted,
T is D*N + C , % compute the product for this digit
R is T rem 10 , % the next digit in the result is that product modulo 10
Q is T div 10 , % the next carry is the quotient
multiply( Ds , N , Q , Rs ) % recurse down
. $ Easy!