【问题标题】:Writing Prolog Code which returns list of integer sums from a given number编写 Prolog 代码,返回给定数字的整数和列表
【发布时间】:2016-03-07 05:43:09
【问题描述】:

我正在尝试编写一个 Prolog 谓词,它可以使用 DCG 将给定的非负整数分解为每个可能的总和。

例如:

?- s(3, L, []).
L = [3] ? ;
L = [2,1] ? ;
L = [1,2] ? ;
L = [1,1,1] ? ;
false.

我首先编写了一个谓词,它接受一个数字 N 并返回 L = [1,2,3,...,N]

mkList(N, L) :-
   m(0, N, L).

m(X, X, []).
m(Y, L, [H|T]) :-
   H is Y+1,
   m(H, L, T).

但是,我不确定如何继续。

s(Input) -->
   { mkList(Input, InputList) },
   { member(X, InputList) },
   [X].

这就是我要使用的,它开始我逐个遍历列表。但是,我不确定我应该在哪里添加一条规则来找出XInput 之间的区别。

【问题讨论】:

  • 您展示的内容不是使用 DCG。您是否阅读过 DCG 文档?此外,您所说的标准是“非负整数”,这意味着s(3, L, []) 的有效解决方案应包括[0,3][0,0,3] 等。我假设您的意思是正整数
  • 总和应该由正整数组成,是的,这不是我所说的非负数。我没有阅读文档,我只是从在线书籍'Learn Prolog Now'中学习
  • 考虑以下两个非常相关的答案:stackoverflow.com/a/29289431/4609915stackoverflow.com/a/29305045/4609915。一种使用clpfd,另一种使用普通的Prolog。 HTH!
  • @lurker。 IMO 问题stackoverflow.com/q/29270479/4609915 基本相同,然而它的名字很烂:难怪为什么这个 user127992 没有找到它。这里的正确行为是什么?重命名旧问题?让新问题指向旧问题?将新问题标记为重复(OP 永远不会找到的问题)? 困惑你有什么建议?

标签: list prolog dcg


【解决方案1】:

最好的方法是像 Prolog 一样思考,即递归。是的,你有递归。它甚至可能是正确的,但我没有遵循它。

这样的想法应该可行:

mkList(Number,List) :-
 pick a number between 1 and number.  It'll be your first addend.
 subtract it from number to get the remainder.
 make a recursive call to handle the remainder.
 patch together List based on the first addend and the list from the recursive call.

显然我们需要在 Number 小于 1 时停止。

这不使用 DCG,但在我的一生中,我看不出 DCG 与这里有什么关系。

【讨论】:

  • 谢谢,这很有帮助。但是我想找到一种使用 DCG 的方法。我开始的方式现在已被编辑到帖子中。
【解决方案2】:

基本情况很简单:

all_sum(N) --> [N].

现在,如果我们提供一个 M between 1 和 N,我们可以递归调用,然后取其余的 R(注意它必须 > 0)

all_sum(N) --> {...},[M],all_sum(R).

请使用上面的提示填充点。 你会得到

?- phrase(all_sum(3),L).
L = [3] ;
L = [1, 2] ;
L = [1, 1, 1] ;
L = [2, 1] ;
false.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    相关资源
    最近更新 更多