【问题标题】:Prolog: Doubling the value of each element in a list of lists and returning a single listProlog:将列表列表中每个元素的值加倍并返回单个列表
【发布时间】:2010-09-26 22:33:58
【问题描述】:

我需要编写一组子句,它们接受一个整数列表并返回一个所有元素都加倍的列表。

例如:

?- double([[1,2],[3]], X).
Yes
X = [2,4,6]

我有一组名为 mega_append 的子句,它们从列表列表中返回单个列表。

例如:

?- mega_append([[1,2],[3]], X).
Yes
X = [1,2,3]

这是我的进度(m_a 是 mega_append 的缩写):

double([],[]).
double(List,[H1|T1]) :-
    m_a(List,[H2|T2]),
    H1 is 2 * H2,
    double(T2, T1).

我将尝试解释我认为它是如何工作的。我将第一个列表展平并将其拆分为头部和尾部(H2 和 T2)。我将第二个列表分成头部和尾部(H1 和 T1)。我检查以确保 H1(加倍值)等于 H2(原始值)的 2 倍。如果是,那么我检查列表的其余部分。最终,如果它们都正确匹配,我应该留下两个空列表,它们应该匹配第一个子句并返回是。

当只有一个值时有效(例如:double([[1]], X))。谁能提供任何关于我做错了什么的见解?我的逻辑或代码不正确吗?

【问题讨论】:

  • 如果 mega_append 得到一个列表而不是列表列表会怎样?前任。 ?- mega_append([2,3], X).

标签: prolog


【解决方案1】:

您的问题是 T2 是单个列表,因此递归调用后的 List 不是列表列表。

要解决这个问题,您可以首先使用 mega_append 来展平列表,然后使用辅助谓词来处理展平的列表。 IE。双倍看起来像这样:

double([],[]).
double(List,X) :-
    m_a(List,FList),
    double_aux(List, FList).

编辑: 这是一种只使用一个子句的方法,因为您想查看一个子句。 我建议使用辅助谓词。

double([],[]).
double([[]],[]).
double(List,[H1|T1]) :-
    mega_append(List,[H2|T2]),
    H1 is 2 * H2,
    double([T2], T1).

【讨论】:

  • 谢谢。我能够使用这种方法弄清楚。不过,我仍然相信存在一种仅使用一组子句的方法。
  • 通常有一个flatten/2 过程可以完成您的m_a/2 所做的工作。
  • 确实有。我用一个例子编辑了我的帖子,但是使用辅助谓词的 imo 比那个例子更好。 (可能有一些我看不到的好方法。)
  • @rvirding:它的工作原理不一样。如果您在原始代码中将 m_a 替换为 flatten,您会说它有效。 IE。 flatten(L1,L2),当 L1 平坦时,L1 = L2。
  • 很高兴您提到flatten/2,因为这绝对是值得了解的事情。同时,这是作业,我怀疑mega_append 被设计为flatten 的功能较弱的版本,以特别防止OP 的第一次尝试。即使使用flatten,我也会创建一个谓词来解决扁平列表的问题,然后使用该版本解决更一般的情况。你知道,问题分解。最初我也尝试将所有内容都放在一个谓词中,但有时最好将问题分解。
【解决方案2】:

使用,我们像这样定义 nonterminal double//1

:- use_module(library(clpfd)).

double([])     --> [].
double([D|Ds]) --> {DD #= D*2}, [DD], double(Ds).

让我们运行一些查询——使用phrase/2apply:foldl/4,非终结符double//1

:- 使用模块(库(应用))。 ?- 短语(foldl(double,[[1,2],[3]]),Xs)。 Xs = [2,4,6]。 ?- 短语(foldl(double,[[A,B],[C]]),[2,4,6]) . A = 1,B = 2,C = 3。

想要更多使用phrase/[2,3] 的示例吗? 阅读this SICStus Prolog manual 页面!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-06
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    相关资源
    最近更新 更多