Prolog:您如何在两个列表之间进行迭代(嵌套循环)?

时间:2018-10-09 04:24:51

标签: list prolog

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

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

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

因此输出应为:

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

1 个答案:

答案 0 :(得分:5)

使用Prolog的主要优点是,您可以委托这样的循环到Prolog 引擎。您不必显式地编写它们。

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

我们可以说:

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

所以,在Prolog中:

one_from_each(As, Bs, [A,B]) :-
    member(A, As),
    member(B, Bs).

示例查询:

?- one_from_each([hi,hello],[bye,later], X).
X = [hi, bye] ;
X = [hi, later] ;
X = [hello, bye] ;
X = [hello, later].

它也可以在其他方向上起作用

?- one_from_each(As, Bs, [hi,bye]).
As = [hi|_4656],
Bs = [bye|_4662] ;
As = [hi|_4656],
Bs = [_4660, bye|_4668] ;
As = [hi|_4656],
Bs = [_4660, _4666, bye|_4674] .

因此,整个问题都被误导了。在Prolog中进行编码时,请始终提出以下问题:如何制定应保留的内容?有了这样的表述之后,您就可以继续寻找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) -->
    [[L,R]],
    one_from_each_(Rs, L).

示例:

?- phrase(one_from_each([hi,hello],[bye,later]), Ls).
Ls = [[hi, bye], [hi, later], [hello, bye], [hello, later]].

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

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