【问题标题】:SWI Prolog scalar multiplying with accumulatorsSWI Prolog 标量与累加器相乘
【发布时间】:2014-03-30 21:28:15
【问题描述】:

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

编写一个 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,但我所有的尝试都失败了。

谢谢

【问题讨论】:

  • 这不是您问题的答案,所以我将其作为评论发布:基于maplist 的解决方案可能看起来像scalar_mult(N, L, R) :- maplist(mul(N), L, R). mul(X, Y, R) :- R is X * Y.

标签: list prolog reverse accumulator


【解决方案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 来处理它。

【讨论】:

    【解决方案2】:

    实际上使用 reverse/2 有效:

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

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

    【讨论】:

    • 谢谢。你能向我解释一下那里发生了什么吗?我用 reverse(T,List2) 和 reverse(List2,T) 都试过了,它们都有效。这是为什么?使用 reverse(List2, T) 是不是更合乎逻辑,因为 T 将是反向列表?
    • @user3281466,在最纯粹的情况下,prolog 中的谓词是描述参数之间关系的“关系”,而不是具有输入和输出的函数。 reverse/2 是那些纯粹的关系序言谓词之一,它说“一个列表是另一个列表的相反”,你给它哪个并不重要,另一个将是相反的。所以reverse(T, List2)reverse(List2, T) 都可以工作。并非所有谓词都是纯粹的关系。 prolog 文档指出每个谓词的参数行为(使用+-? 指标)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多