2

我的问题:给定一个列表

L = [x1,...,xn]

编写一个convert(L,X)转换L为整数的 Prolog 程序

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? >>>

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

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

请帮我解决一下这个。谢谢你。

4

2 回答 2

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.
于 2012-11-30T12:35:34.343 回答
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 ) .
于 2014-05-20T20:18:42.770 回答