Prolog程序转换(L,X)将列表L转换为整数:x1 + x2 * 10 ^ 1 + ... + xn * 10 ^(n-1)

时间:2012-11-30 11:00:50

标签: recursion lambda prolog swi-prolog

我的问题:给出一个列表

L = [x1,...,xn]

编写一个将convert(L,X)转换为整数

的Prolog程序L
x1*10^0 + x2*10^1 + ... + xn*10^(n-1)

将结果存储在X

例如

?- convert( [1,2,3,4] , Res ).
Res = 4321.

我试图解决这个问题,但是我正在尝试使用内置的电源功能时出现语法错误。这就是我到目前为止所做的:

convert([],Res) .
convert(L1,Res) :- conv( L1 , Res , C ) .

conv( [] , Res , C ) .
conv( [H|Ys] , Res , C ):-
  C1 is C-1 ,
  N is (H*(10**C)) ,
  conv(Ys,Res2,C1) ,
  Res is N + Res2 .

我收到此错误:

******* syntax error
>>>   conv ( [ H | Ys ] , Res , C ) :- C1 is C - 1 , N is ( H * ( 10  <--- HERE? >>>

所以有人可以告诉我如何摆脱这个错误?

另外,有什么方法我会在语法上出错吗?

请帮我解决这个问题。谢谢。

2 个答案:

答案 0 :(得分:3)

当您使用SWI-Prolog时,这有效:

:- use_module(library(lambda)).

convert(L,Res) :-
    reverse(L, LR),
    foldl(\X^Y^Z^(Z is Y * 10 + X), LR, 0, Res).

代码:

convert([],Res) . <== Here Res is a free variable
convert(L1,Res) :-conv(L1,Res,C). <== here C is free

conv([],Res,C). <== Here Res anc C are free

这不起作用;你可以尝试

conv([],0).
conv([H|Ys],Res):-
  conv(Ys,Res2),
  Res is Res2 * 10 + H.

答案 1 :(得分:0)

原始海报在正确的轨道上。但是,这样做不会使用library(lambda)

convert( Xs , R ) :-        % to sum a list of values, scaling each by their corresponding power of 10,
  convert( Xs , 1 , 0 , R ) % just invoke the worker predicate, seeding the power accumulator with 10^0 (1)
  .                         % and the result accumulator with zero (0).

convert( []     , _ , R , R ) .   % when we exhaust the source list, we're done: unify the result R with the result accumulator
convert( [X|Xs] , P , T , R ) :-  % otherwise...
  T1 is T + X*P ,                 % - increment the result accumulator by the current list item, scaled by the current power of 10,
  P1 is P*10 ,                    % - bump up to the next power of 10, and
  convert(Xs,P1,T1,R)             % - recurse down.
  .                               %

也可以使用Prolog的内置取幂(但它既不简单也不快):

convert( Xs , R ) :-
  convert(Xs,0,0,R)
  .

convert( []     , _ , R , R ) .
convert( [X|Xs] , N , T , R ) :-
  T1 is T + X * 10**N ,
  N1 is N+1 ,
  convert1(Xs,N1,T1,R)
  .

最简单,最优雅的方式(至少在SWI,Quintus或Sicstus中)将使用library(aggregate)并写下单行:

convert( Xs , R ) :- aggregate( sum(X*10**N) , nth0(N,Xs,X) , R ) .