listsum(L, S) 成功当且仅当 L 是必须从 1 开始的连续整数列表,并且 S 是该列表的总和
我正在为即将到来的序言考试而学习,一个我无法弄清楚的练习需要我编写以下谓词:
listsum(L, S) 成功当且仅当 L 是必须从 1 开始的连续整数列表,并且 S 是该列表的总和。
重要的是,当给定 S 时,它能够生成列表。允许使用 numlist/3、is/2 和数学运算符。
例如:
?- listsum(L, 6).
L = [1,2,3]
; false.
?- listsum(L, 7).
false.
?- listsum([2,3], 5).
false.
?- listsum([2,4], 6).
false.
你会如何写这个谓词?
编辑:非常感谢大家!
I'm studying for my upcoming prolog exam and one exercise which I can't figure out needs me to write the following predicate:
listsum(L, S) succeeds iff L is a list of consecutive integers which must start at 1 and S is the sum of that list.
It's important that it's able to generate the list when S is given. numlist/3, is/2 and mathematical operators are allowed to be used.
For example:
?- listsum(L, 6).
L = [1,2,3]
; false.
?- listsum(L, 7).
false.
?- listsum([2,3], 5).
false.
?- listsum([2,4], 6).
false.
How would you write this predicate?
Edit: Thank you so much to all of you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果允许使用库 clpfd,另一个可能的解决方案如下:
一些示例:
If it is allowed to use library clpfd, another possible solution is as follows:
Some examples:
由于前 n 个自然数的总和< /a> 是
s = n(n+1) / 2
我们可以使用有趣的内置 length/2,并编写涵盖大多数要求的关系:
当然是问题是在某些情况下,当通过 length/2 生成列表时,它不会终止。
这会在回溯时发生,例如因为我们明确要求它,或者因为我们导致 length/2 之后的某些调用失败,可能传递了错误的总和。
解决这个问题并不容易,但是在需要的地方进行实例化检查,我们得到了正确的解决方案:
Since the sum of the first n natural numbers is
s = n(n+1) / 2
we could use the interesting builtin length/2, and write the relation likethat covers most of requirements:
The problem of course is that it will not terminate, under some conditions, when generating the list by means of length/2.
This will happen on backtracking, for instance because we explicitly require it, or because we cause some of the calls following length/2 to fail, maybe passing a wrong sum.
It's not easy to solve the problem, but pushing the instantiation check where needed we get a proper solution:
假设您可以使用 numlist/3 和数学运算符,并假设您不能使用 clp(FD) ,那么您可以将问题一分为二,一个用于基本总和,另一个用于计算总和计算总和:
Given you can use
numlist/3
and mathematical operators and assuming you cannot useclp(FD)
then you may split the problem in two, one for ground sums and other which will compute sums:虽然不优雅,但如果提供了 nonvar 参数,这将生成并明智地终止:
导致 swi-prolog:
Whilst inelegant, this will generate, and will also terminate sensibly if nonvar arguments are provided:
Result in swi-prolog: