Prolog:列表中的递归,包含一个一次性规则

时间:2016-02-07 19:51:34

标签: recursion prolog traveling-salesman

我很可能无法正确地说出我的搜索关键字。我试图做的是递归地评估列表中连续条目的差异,并继续将它们添加到全局计数器。挑战是最后的循环子句,如果列表是[5,4,3,2,1],谓词应该返回(5-4)+(4-3)+(3-2)+(2-1)+(1-5)=0

到目前为止我所拥有的内容如下:

circularSumOfDifferences([_],0).
circularSumOfDifferences([E1,E2|List],Sum) :-
    Diff is E1-E2,
    circularSumOfDifferences([E2|List],SoD),
    Sum is Diff+SoD.

现在我想到定义另一个谓词,在给定列表的尾部添加列表的第一个元素,并结合查询调用新列表:copyHeadToTail([5,4,3,2,1],Result),circularSumOfDifferences(Result,C).

它很难实现,但它对我来说并不是很优雅。我想知道是否有一种方法可以定义一个谓词circularSumOfDifferences(+L,-SoD),它通过列表进行递归并在最后(或开始)为一个减法运行一个语句,即。 1-5

1 个答案:

答案 0 :(得分:3)

当然,您可以编写一个可以执行此操作的谓词,但您应该注意到列表中的每个元素X在总和中出现两次,一次为X,一次为{{ 1}}。无论你给出这个谓词的数字列表,结果总是会有0。那是家庭作业吗?很有可能的是,要注意这一点而不是试图计算实际总和:

-X

如果您坚持,可以使用以下命令编写谓词:

always_zero([], 0).
always_zero([X|Xs], 0) :-
    number(X),
    always_zero(Xs, 0).

这使用辅助谓词,这在Prolog程序中很常见。实际迭代列表的辅助谓词有三个额外的参数:列表的解包头,原始的第一个元素(在列表的末尾使用),以及到目前为止的总和。