【问题标题】:Prolog: How do you iterate between two lists (nest for-loop)?Prolog:如何在两个列表之间进行迭代(嵌套 for 循环)?
【发布时间】:2018-10-09 04:24:51
【问题描述】:

我这周刚开始学习 Prolog,所以我不确定在 Prolog 中是否可以使用 for 循环。 我在 Prolog 中有两个列表

stringList([hi,hello],[bye,later],X).

如何创建一个新的解决方案列表,每个列表一个元素?

所以输出应该是:

X = [hi,bye]
X = [hi,later]
X = [hello,bye]
X = [hello,later]

【问题讨论】:

  • 一些 Prolog 扩展允许“for”循环,但 for 循环本身非常“非声明性”。在声明式系统中,您通常应该考虑应该做什么,而不是如何

标签: list prolog


【解决方案1】:

使用 Prolog 的一个主要优势是您可以这样的循环委托给 Prolog 引擎。您不必明确地编写它们。

例如,在您的情况下,请以这种方式思考问题:关于X持有(或应该持有)什么?

我们可以说:

  1. X 是一个包含两个元素的列表,例如 [A,B]
  2. A 是第一个参数表示的列表的成员。
  3. B 是由第二个参数表示的列表的成员。

所以,在 Prolog 中:

one_from_each(As, Bs, [A,B]) :- 成员(A,作为), 成员(B,Bs)。

示例查询:

?- one_from_each([hi,hello],[bye,later], X)。 X = [嗨,再见]; X = [嗨,稍后] ; X = [你好,再见] ; X = [你好,稍后]。

它也适用于其他方向

?- one_from_each(As, Bs, [hi,bye])。 作为 = [hi|_4656], Bs = [再见|_4662]; 作为 = [hi|_4656], Bs = [_4660,再见|_4668]; 作为 = [hi|_4656], Bs = [_4660,_4666,再见|_4674]。

因此,整个问题有些误导。在 Prolog 中编码时,总是会问:我如何制定应该hold 的内容?一旦有了这样的公式,就可以将解决方案的搜索留给 Prolog 引擎!

如果你想要,你可以更明确。例如:

one_from_each([], _) --> []。 one_from_each([L|Ls], Rs) --> one_from_each_(Rs, L), one_from_each(Ls,Rs)。 one_from_each_([], _) --> []。 one_from_each_([R|Rs], L) --> [[左,右]], one_from_each_(Rs,L)。

例子:

?- 短语(one_from_each([hi,hello],[bye,later]), Ls)。 Ls = [[嗨,再见],[嗨,稍后],[你好,再见],[你好,稍后]]。

这有时称为空间表示,因为现在不再在回溯(时间表示)中找到解决方案,而是明确表示。

由此可见,“循环”对应于递归定义。

【讨论】:

  • 谢谢!后续问题:是否有一种简单的方法可以从原始列表中删除子列表。例如,如果 X = [嗨,稍后]。如何将其从列表中删除,以便我的下一个答案是 X = [hello,bye]?当我的列表变得庞大时,这将成为一个更大的问题。
  • 我认为这是值得自己提出的问题!请提出单独的问题进行讨论。
  • 好的。我添加了这个问题。我认为它需要递归,但这是我不太擅长的领域:stackoverflow.com/questions/52769929/…
猜你喜欢
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2022-06-22
  • 1970-01-01
相关资源
最近更新 更多