带列表的Prolog程序

带列表的Prolog程序,prolog,turbo-prolog,Prolog,Turbo Prolog,我必须在turbo prolog中作为家庭作业解决以下问题:“确定列表中以数字表示的数字与给定数字的乘积,例如:[1 9 3 5 9]*2-->[3 8 7 1 9 8]” 我解决这个问题的思路是首先计算产品,然后将其数字放入列表中。只是我无法真正理解最后一部分。这是我目前的源代码: 领域 list=integer* 谓词 length(list,integer) powerten(integer,integer) product(integer,list,integer) /*

我必须在turbo prolog中作为家庭作业解决以下问题:“确定列表中以数字表示的数字与给定数字的乘积,例如:[1 9 3 5 9]*2-->[3 8 7 1 9 8]”

我解决这个问题的思路是首先计算产品,然后将其数字放入列表中。只是我无法真正理解最后一部分。这是我目前的源代码:

领域

list=integer*
谓词

    length(list,integer)

powerten(integer,integer)

product(integer,list,integer) /* this predicate computes the product */

    /* the product,powerten and length are taken care of */


addDigit(integer,list) /* this predicate should decompose the number in its digits and put them in the list */


productList(integer,list,list)
条款

     length([],0).

     length([_|T],L):-

            length(T,L1),

            L=L1+1.

powerten(0,1):-!.

powerten(L,N):-
    L1=L-1,
    powerten(L1,N1),
    N=N1*10.

product(_,[],0):-!.

product(NR,[H|T],RESULT ):-
    length([H|T],LEN),
    L2=LEN-1,

    powerten(L2,N),
    product(NR,T,R1),
    RESULT=R1+H*N*NR.




addDigit(0,[]):-!.


addDigit(NR,[NR|_]):-

    NR>0,
    DIGIT = NR MOD 10,
    NR1=NR DIV 10,
    addDigit(NR1,_).        


productList(NR,L1,L2):-

     /* this is the "main" predicate . Its arguments are NR - the first factor, L1- the 
         initial list, whose digits make the second factor, L2 - the result list which            
          contains  the digits of he result */

            product(NR,L1,RESULT),

            addDigit(RESULT,L2).
正如您所看到的,在addDigit谓词出现之前,一切都很好。我就是找不到办法把产品的数字加到最终的列表中。有人能帮我解决吗?
谢谢。

addDigit对我来说似乎是错误的:您只使用第一个,而未指定尾部!试一试

addDigit(NR,[DIGIT|Ns]):-
    NR>0,
    DIGIT = NR MOD 10,
    NR1 = NR DIV 10,
    addDigit(NR1, Ns).

这对我来说似乎很复杂。问题是基本上要做长形乘法,就像你在纸上做的那样。如果首先反转列表(使用内置的
reverse/2
谓词),事情会变得简单得多:

%--------------------------------------------------------------%
% 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!
%---------------------------------------------------------------%
%Mult/3:将整数相乘,表示为数字列表,%
%通过整数值N,生成一个整数,也是%
%表示为数字的lsit。%
%--------------------------------------------------------------%
乘法(Ds,N,结果):-
反向(Ds、Rs),
乘(Rs,N,0,T),
反向(T,结果)
.
%
%完成所有工作的worker谓词
%
乘法([],uC,[]):-%
C=<0%,进位为0,
.                                    %   我们结束了。好的。
如果列表已用尽,则乘法([],u,C,[C]):-%
C>0%,进位为1-9,则
C<10%结果中的最后一位是进位
.                                    %   我们结束了。好的。
乘法([],[uUc,[R | Rs]):-%如果列表已用尽,
C>=10%,进位为10+,
R是C rem 10%,结果中的下一个数字是进位模10
Q是C除以10%,取商
乘以([]、Q、Rs)%并以商作为进位向下递归
.                                    %
乘法([D | Ds],N,C,[R | Rs]):-%如果列表未用尽,
T是D*N+C,计算此数字的乘积
R是T rem 10%,结果中的下一个数字是乘积模10
Q是T除以10%,下一个进位是商
乘法(Ds,N,Q,Rs)%向下递归
.                                    $ 容易的!

谢谢,这确实比我尝试的解决方案简单得多