SWI Prolog标量乘以累加器

时间:2014-02-27 12:36:41

标签: list prolog reverse accumulator

所以我一直在研究以下问题:

  

写一个3位谓词scalarMult,其第一个参数是   整数,其第二个参数是整数列表,其第三个参数   参数是标量乘以第二个参数的结果   首先。例如,查询

?-  scalarMult(3,[2,7,4],Result). 
     

应该产生

Result = [6,21,12] 
     

借助累加器和包装谓词来执行此操作。

这就是我所做的:

scalarMult(I, List1, List2):- scalarMult1(I, List1, [], List2).

scalarMult1(I,[], A, A).
scalarMult1(I,[H|T], A, Result):- H1 is H*I, scalarMult1(I,T,[H1|A],Result).

唯一的问题是它将新元素放在累加器的头部,所以我最终得到一个反向列表(所以对于上面的例子,我会得到Result = [12,21,6] )。有什么方法可以解决这个问题吗?我尝试在我的代码中使用reverse但是我的所有尝试都失败了。

由于

2 个答案:

答案 0 :(得分:2)

使用reverse / 2工作,实际上:

scalarMult(I, List1, List2):- scalarMult1(I, List1, [], T), reverse(T, List2).

但我认为使用累加器(这里真的没用)的要求可能是为了验证你的列表处理水平。

答案 1 :(得分:1)

注意到Carlo关于使用累加器用于教学目的的说法,scalar_multiplication/3谓词的直接定义不需要累加器(从scalarMult/3重命名;驼峰案例不被认为是好的编程Prolog中的风格):

% first exchange argument orders to take advantage of the first-argument
% indexing that is provided in most Prolog implementations
scalar_multiplication(Scalar, Numbers, ScaledNumbers) :-
    scalar_multiplication_(Numbers, Scalar, ScaledNumbers).

% base case; either input list was empty or we finished traversing the list
scalar_multiplication_([], _, []).

% recursive case
scalar_multiplication_([Number| Numbers], Scalar, [ScaledNumber| ScaledNumbers]) :-
    ScaledNumber is Number * Scalar,
    scalar_multiplication_(Numbers, Scalar, ScaledNumbers).

这是处理列表的常见模式的实例。很常见,几个Prolog实现提供了二阶谓词(或元谓词),通常命名为map/3maplist/3来处理它。