使用 Prolog 的一个主要优势是您可以将这样的循环委托给 Prolog 引擎。您不必明确地编写它们。
例如,在您的情况下,请以这种方式思考问题:关于X,持有(或应该持有)什么?
我们可以说:
-
X 是一个包含两个元素的列表,例如 [A,B]。
-
A 是第一个参数表示的列表的成员。
-
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 = [[嗨,再见],[嗨,稍后],[你好,再见],[你好,稍后]]。
这有时称为空间表示,因为现在不再在回溯(时间表示)中找到解决方案,而是明确表示。
由此可见,“循环”对应于递归定义。