【问题标题】:How to perform long concatenation of lists in Prolog?如何在 Prolog 中执行列表的长连接?
【发布时间】:2016-11-12 02:05:06
【问题描述】:

我对使用 Prolog 语言执行长列表连接感兴趣。 目标是定义一个谓词,该谓词获取 unknown 个列表,并将它们全部连接到一个列表中(作为谓词的第二个参数给出)。

我知道我应该首先了解 Prolog 如何支持无限大小的参数,但我认为答案是使用列表,例如: [一个| [[b,c,d] | [[e,f,g] | [h,i,j,k]]]].

如果是这样,我想写谓词有点像这样:

l_conc([ ],[ ]).
l_conc([[ ]|Tail],L):-
      l_conc(Tail,L).
l_conc([[Head|L1]|Tail],[Head|L2]):-
      l_conc([L1|Tail],L2).

但是,它只会将空列表相互连接。 请在这里帮助我(关于参数表示和谓词本身):-) 谢谢!

【问题讨论】:

标签: list prolog concat


【解决方案1】:

在我回答实际问题之前,我有几个 cmets。

首先,您作为示例给出的术语[a | [[b,c,d] | [[e,f,g] | [h,i,j,k]]]] 可以在Prolog 中更紧凑地编写。您可以使用 Prolog toplevel 本身来查看该术语的实际含义:

?- Ls = [a | [[b,c,d] | [[e,f,g] | [h,i,j,k]]]]。 Ls = [a, [b, c, d], [e, f, g], h, i, j, k]

由此可见,这只是一个列表。但是,它不是列表列表,因为原子ahi不是列表 .

因此,您的示例与您的问题不符。有一些方法可以“扁平化”列表,但我只能建议不要扁平化,因为它不是纯粹的关系。原因是[X] 被认为是一个“平面”列表,但X = [a,b,c] 使[[a,b,c]] 不是平面,所以如果你使用flatten/2,你会遇到逻辑上的不一致。

我推荐的是append/2。实现它的最简单方法是使用 DCG ()。例如:

一起([])-> []。 一起([Ls|Lss])--> 列表(Ls), 一起(Lss)。 列表([])-> []。 列表([L|Ls])-> [L],列表(Ls)。

查询示例:

?- 短语(一起([[a],[b,c],[d]]),Ls)。 Ls = [a, b, c, d]。

在本例中,恰好一层的嵌套已被移除。

【讨论】:

  • 嗨,Mat,我理解示例中的不匹配,也理解您对 DCG 的解释。我不明白的是为什么我不能只使用 append/2 如果它是语言中的本机 - 它似乎完全符合我的需要......此外,我试图将 DCG 代码翻译成规则和事实代码,但它没有产生相同的结果。你能帮忙找出我应该在这里解决什么吗?新的一起([],[])。 new_together([Ls|Lss], [NewLs|NewLss]) :- new_list(Ls, NewLs), new_together(Lss, NewLss)。新列表([],[])。新列表([L|Ls],[L|NewLs]):- 新列表(Ls,NewLs)。谢谢!
  • 如果您的 Prolog 系统已经提供此谓词,您当然可以并且应该在实际程序中使用预定义的append/2。但是,如果您还不知道如何编写这样的谓词,您还应该学习如何自己编写这些谓词,以便更好地理解这些关系,并且如果您需要它们,也可以轻松实现细微的变化。看我给的DCG怎么翻译成Prolog子句,用listing/1,比如?- listing(together//1).
猜你喜欢
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多