List 序言:如何在两个列表之间迭代(嵌套循环)?

List 序言:如何在两个列表之间迭代(嵌套循环)?,list,prolog,List,Prolog,本周我刚开始学习Prolog,所以我不确定在Prolog中是否可以使用for循环。 我在Prolog中有两个列表 stringList([hi,hello],[bye,later],X). 如何创建一个新的解决方案列表,每个列表包含一个元素 因此,输出应为: X = [hi,bye] X = [hi,later] X = [hello,bye] X = [hello,later] 使用Prolog的一个主要优点是,您可以将此类循环委托给Prolog引擎。您不必显式地编写它们 例如,在您的案例

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

stringList([hi,hello],[bye,later],X).
如何创建一个新的解决方案列表,每个列表包含一个元素

因此,输出应为:

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

使用Prolog的一个主要优点是,您可以将此类循环委托给Prolog引擎。您不必显式地编写它们

例如,在您的案例中,以这种方式思考问题:关于
X
,什么适用(或应该适用)

我们可以说:

  • X
    是一个包含两个元素的列表,例如
    [a,B]
  • A
    是由第一个参数表示的列表的成员
  • B
    是由第二个参数表示的列表的成员
  • 因此,在序言中:

    one_from_each(As, Bs, [A,B]) :- member(A, As), member(B, Bs). 每个(As,Bs,[A,B])中的一个:- 成员(A,As), 成员(B,Bs)。 示例查询:

    ?- one_from_each([hi,hello],[bye,later], X). X = [hi, bye] ; X = [hi, later] ; X = [hello, bye] ; X = [hello, later]. -每人一张([嗨,你好],[稍后再见],X)。 X=[你好,再见]; X=[你好,稍后]; X=[你好,再见]; X=[你好,稍后]。 并且它在其他方向也起作用

    ?- 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] . -每人一份(As,Bs,[你好,再见])。 As=[hi | U 4656], Bs=[再见| 4662]; As=[hi | U 4656], Bs=[_4660,再见|u 4668]; As=[hi | U 4656], Bs=[_4660,_4666,再见|u 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). 每个([],[u]->[]中各有一个。 每一个中的一个([L|Ls],Rs)--> 每个(Rs,L)中各有一个, 每个(Ls、Rs)一个。 每一个中的一个([],-->[])。 每个人一个([R|Rs],L)-> [L,R]], 一人一人(Rs,L)。 例如:

    ?- phrase(one_from_each([hi,hello],[bye,later]), Ls). Ls = [[hi, bye], [hi, later], [hello, bye], [hello, later]]. -短语(每个短语中有一个短语([你好,你好],[再见,稍后]),Ls)。 Ls=[[你好,再见],[你好,稍后],[你好,再见],[你好,稍后]]。 这有时被称为空间表示,因为解决方案现在不再在回溯(时间表示)中找到,而是显式表示


    从这里,您可以看到“循环”对应于递归定义。

    一些Prolog扩展允许“for”-循环,但for循环本身非常“非声明性”。在声明式系统中,您通常应该考虑应该做什么,而不是如何做。谢谢!后续问题:有没有一种简单的方法可以从原始列表中删除子列表中的某个元素。例如,如果X=[hi,later]。我如何将其从列表中删除,以便我的下一个答案是X=[你好,再见]?当我的单子越来越大的时候,这是一个更大的问题。我认为这是非常值得提出自己的问题!请另外提一个问题来讨论。好的。我补充了这个问题。我认为这需要递归,但这是我并不擅长的领域: