findall/3 在其结果列表中创建新的、不相关的变量 [英] findall/3 creates new, unrelated variables in its resulting list

查看:37
本文介绍了findall/3 在其结果列表中创建新的、不相关的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

?- permutation([A,B,C],Z).
Z = [A, B, C] ;
Z = [A, C, B] ;
Z = [B, A, C] ;
Z = [B, C, A] ;
Z = [C, A, B] ;
Z = [C, B, A] ;
false.

有道理.我可以处理 [A,B,C] 的排列,并且该排列包含与 [A,B,C] 中相同的元素,所以我所做的一切这些元素将适用于我的原始列表.

Makes sense. I can work on a permutation of [A,B,C] and that permutation contains the same elements as in [A,B,C], so everything I do to those elements will apply to my original list.

现在:

?- findall(X, permutation([A,B,C], X), Z).
Z = [[_G1577, _G1580, _G1583], [_G1565, _G1568, _G1571], [_G1553, _G1556, _G1559], [_G1541, _G1544, _G1547], [_G1529, _G1532, _G1535], [_G1517, _G1520, _G1523]].

为什么??为什么 findall/3 给我的列表包含完全不相关的变量,而不是 A,B,C?Z 中的列表甚至没有相互关联,所以我得到的结果实际上只是 6 个长度为 3 的随机列表,这完全不是我查询的.

Why?? Why is findall/3 giving me lists which contain completely unrelated variables, instead of A,B,C? The lists in Z are not even related to each other, so really the result I get is just 6 random lists of length 3, which is totally not what I queried.

通过这种行为,我们会得到如下荒谬的结果:

With this behavior we get ridiculous results like this:

?- findall(X, permutation([A,B,C],X), Z), A = 1.
A = 1,
Z = [[_G1669, _G1672, _G1675], [_G1657, _G1660, _G1663], [_G1645, _G1648, _G1651], [_G1633, _G1636, _G1639], [_G1621, _G1624, _G1627], [_G1609, _G1612, _G1615]].

从逻辑的角度来看,这毫无意义.

Which makes no sense from a logical standpoint.

我了解 findall/3 并不是真正的关系型、纯逻辑谓词,但我不明白这如何证明此处显示的行为是合理的.

I understand that findall/3 is not really a relational, pure logic predicate but I don't see how this justifies the behavior shown here.

因此我的问题是:

  • 为什么为谓词选择这种行为?

  • Why was this behavior chosen for the predicate?

是否存在这种行为实际上比我想要的行为更可取的情况?

Are there common situations where this behavior is actually preferable to the one I want?

如何使用我想要的行为实现 findall/3 版本?

How to implement a version of findall/3 with the behavior I want?

推荐答案

为什么为谓词选择这种行为?

Why was this behavior chosen for the predicate?

findall/3 是一个高度原始的内置谓词,它相对容易实现并且没有解决您感兴趣的所有细节.至少它是可重入的 - 因此可以递归使用.

findall/3 is a highly primitive built-in predicate that is relatively easy to implement and that does not address all the nitty-gritty details you are interested in. At least it is reentrant - thus can be used recursively.

过去,DEC10 Prolog 没有记录 findall/3.也就是说,在 1978 年和 1984 年都没有.然而,1984 年的版本确实提供了 setof/3,它在内部使用了一个类似 findall 的谓词.在 ISO-Prolog(没有 findall/3)中实现它是相对棘手的,因为你必须处理错误和嵌套.许多实现依赖于实现特定的原语.

Historically, DEC10 Prolog did not document findall/3. That is, neither in 1978 nor 1984. The 1984 version did however provide setof/3 which internally uses a findall-like predicate. Implementing it in ISO-Prolog (without findall/3) is relatively tricky since you have to handle errors and nesting. Many implementations rely on implementation specific primitives.

是否存在这种行为实际上比我想要的行为更可取的常见情况?

Are there common situations where this behavior is actually preferable to the one I want?

如果没有解决方案,Findall 会成功,而 setof/3bagof/3 都会失败.这可能是偏爱它的一个原因.至少有一些比需要的结构更复杂的结构,这些结构很可能是基于 findall 构建的.

Findall succeeds if there is no solution whereas both setof/3 and bagof/3 simply fail. This might be a reason to prefer it. At least some more sophisticated constructs than those are needed which are most probably built based on findall.

在存在约束的情况下它会变得非常混乱.事实上,它是如此混乱,以至于截至目前,我仍然不知道在这种情况下可以以合理的方式处理 clpfd 约束的实现.想想:

It gets pretty messy in the presence of constraints. In fact, it is so messy, that as of the current point in time I am still unaware of an implementation that would deal in a reasonable manner with clpfd-constraints in this very situation. Think of:

?- findall(A, (A in 1..3 ; A in 5..7), As).

在这里,SWI 复制约束,而 SICStus 不会复制它们,因此您可以将其用作更复杂实现的构建块.

Here, SWI copies constraints, where SICStus does not copy them permitting you thus to use it as building-block for a more sophisticated implementation.

如何使用我想要的行为实现 findall/3 版本?

How to implement a version of findall/3 with the behavior I want?

首先,考虑 setof/3bagof/3(此处).也许你已经对它们感到满意了——只要不涉及任何限制......

First, consider setof/3 and bagof/3 (here). Maybe you are happy with them already - as long as no constraints are involved...

这篇关于findall/3 在其结果列表中创建新的、不相关的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆