有没有一种方法可以只对Prolog中包含字母和整数的对列表中的整数求和? [英] Is there a way to sum only the integers in a list of pairs that contain a letter and an integer in Prolog?

查看:110
本文介绍了有没有一种方法可以只对Prolog中包含字母和整数的对列表中的整数求和?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难弄清楚如何找到像这样的成对列表中的整数之和:

I'm having trouble figuring out how to find the sum of the integers that are in a list of pairs like so:

[[a, 1], [b, 2], [c, 3], [d, 4]]

我尝试了类似的方法,因为它让人想起常规的求和函数:

I tried something like this, since it is reminiscent of a regular sum function:

sum([], 0).
sum([[_,Head]|[_,Tail]], Sum) :-
    sum([_,Tail], Sum2),
    Sum is Head+Sum2.

正在通话:

sum([[a, 1], [b, 2], [c, 3], [d, 4]], Total),
write('Sum = '), write(Total).

但这不起作用.当它应该打印出总和时,它会打印出false,这是10.

But that doesn't work. It prints out false, when it should print out the sum, which would be 10 here.

推荐答案

每当您期望成功的目标失败时,将其视为学习的机会(逻辑赚取的简写=赚取逻辑).毕竟,这就是Prolog,它的意思是逻辑编程.那么程序中的逻辑在哪里?

Whenever a goal fails that you expect to succeed, see this as an opportunity to learn (short form for logic earn = earn logic). After all, this is Prolog which was meant to mean Programming in Logic. So where is the logic in your program?

目前,您的程序失败了,但是您希望它能够成功.罪魁祸首在哪里?让我们概括您的程序,以使生成的程序仍然失败,但要小得多.有两种简单的方法可以概括程序:

For the moment your program fails, but you expected it to succeed. Where is the culprit? Let's generalize your program such that the resulting program still fails, but is much smaller. There are two easy ways to generalize a program:

  • 删除目标(通过添加前缀*)

删除条款(用_/*term*/

我们可以很盲目的做到这一点.无需了解您的程序.只需重新检查目标仍然失败即可.这是我第一次尝试时想到的:

We can do this pretty blindly. No need to understand your program. Just recheck that the goal still fails. Here is what I came up with on my first try:


:- op(950, fy, *).
* _G_0. % ignore the argument _G_0

sum([], _/*0*/).
sum([_/*[_,Head]*/|[_,Tail]], Sum) :-
    * sum([_,Tail], Sum2),
    * Sum is Head+Sum2.

?- sum([_/*[a, 1]*/, _/*[b, 2]*/, _/*[c, 3]*/, _/*[d, 4]*/], Total).
false.                            % gnah - still fails

一个问题必须存在于其余可见部分.太难弄清楚了吗?让Prolog通过查询最普遍的查询:

One problem has to be in the remaining visible part. Too difficult to figure out? Let Prolog explain it to you by querying the most general query:

| ?- sum(Xs, Sum).
   Xs = []
;  Xs = [_A,_B,_C].

因此,只能有两个长度的列表:空列表和包含三个元素的列表.请注意,我们目前有谓词的通用版本.因此,不能保证我们会找到两种长度的解决方案.但是,我们可以100%确保所有其他长度都没有解决方案.

So only two lengths of lists are possible: The empty list and a list with three elements. Note that we have currently a generalized version of the predicate. So there is no guarantee that we will find solutions for both lengths. However, we can be 100% sure that for all other lengths there will be no solution.

让我们回到原始程序并询问最普遍的查询:

Let's get back at the original program and ask the most general query:

?- sum(Os, Total).
   Os = [], Total = 0
;  false.

哦,不,只有一个解决方案.甚至没有sum([_|_], Total)的单一解决方案.

Oh no, there is a single solution only. And not even a single solution for sum([_|_], Total).

所以让我们再次概括该程序,但现在针对这个失败的目标:

So let's generalize the program again but now with respect to this failing goal:


sum([], _/*0*/).
sum([_/*[_,Head]*/|[_,Tail|_/*[]*/]], Sum) :-
    sum([_,Tail], Sum2),
    * Sum is Head+Sum2.

?- Os = [_|_], sum(Os, Total).
false.

在这一部分中,必须有另一个错误.实际上,目标sum([_,Tail], Sum2)是罪魁祸首:它是关于一列恰好两个元素的列表,但是该规则至少要包含三个

In this part there must be a further error. And in fact, the goal sum([_,Tail], Sum2) is the culprit: It is about a list of exactly two elements, but the rule wants at least three

有关实际的修补程序,请参见其他答案.

For the actual fixes, see the other answers.

此方法适用于纯单调的程序,例如您的程序.

This method works for pure, monotonic programs such as yours.

这篇关于有没有一种方法可以只对Prolog中包含字母和整数的对列表中的整数求和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆