问题标签 [partial-ordering]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
822 浏览

python - 为什么 Python 不提供 __le__ 和 __ge__ 的默认实现?

以下比较关系(=、≠、<、>、≤ 和 ≥)之间的数学关系始终有效,因此在 Python 中默认实现(除了 2 个联合关系,这似乎是任意的,这也是本文的原因):

  • 2互补关系:“=和≠互为互补”;
  • 6个逆向关系*:“=是自身的逆向关系”、“≠是自身的逆向关系”、“<和>是彼此的逆向关系”、“≤和≥是彼此的逆向关系”;
  • 2个并集关系:“≤是<和=的并集,”≥是>和=的并集。

以下比较关系之间的关系仅对总订单functools.total_ordering有效,因此在 Python 中默认不实现(但用户可以通过 Python 标准库提供的类装饰器方便地实现它们):

  • 4种互补关系:“<和≥互为补”,">和≤互为补”。

为什么Python只缺少上面的2个联合关系(“≤是联合<和=”,“≥是>和=”的联合)?

它应该提供一个__le__关于and 的默认实现,以及一个关于__lt__and的默认实现,就像这些(但可能在 C 中为了性能,比如):__eq____ge____gt____eq____ne__

2 个联合关系始终有效,因此这些默认实现将使用户不​​必一直提供它们(如这里)。

这是Python 文档的段落,其中明确指出默认情况下当前未实现 2 个联合关系(粗体强调我的):

默认情况下,__ne__()委托__eq__()并反转结果,除非它是NotImplemented. 比较运算符之间没有其他隐含关系,例如,真值(x<y or x==y)不隐含x<=y


* 逆向关系通过NotImplemented协议在 Python 中实现。

0 投票
2 回答
71 浏览

haskell - 通过散列实现排序

我有一组相对较大的代数数据类型,我无法自动派生EqOrd因为数据类型中的单个字段被认为是元数据,不应该考虑相等和排序。例如,数据类型可能如下所示:

在这种情况下,每个 Int 都是元数据。

所以我所做Eq的只是通过比较构造函数来手动实现。但这Ord变得疯狂,因为如果我有n构造函数,我必须实现n^2比较函数。所以目前我的工作是手动实现Hashable,这需要我为每个构造函数实现一个哈希函数。然后在我的Ord实例中进行哈希比较。

这显然有一些问题,因为compare (hash x) (hash y) == EQ -> x == y不成立,因为两个不同的值可以共享相同的散列。然而,这可以通过首先手动检查是否相等来处理,如果是这种情况,总是说左边比右边小。

但是,现在对于它持有的任何类型的某些值,您都拥有它a < b && b < a。我不确定在 HaskellOrd实例中是否允许。所以基本上我的问题是这样实施 Ord 是否可行?我需要的原因Ord是因为许多库需要Ord. 例如图形库和地图库。

这是一个完整的例子:

0 投票
1 回答
41 浏览

c++ - C++ which template would be call if both template function match the argument list

I know that the second template function would be called, but i dont know the rules for template function matching.

0 投票
1 回答
53 浏览

c++ - 会员和自由经营者的消歧规则

我有一个看起来像这样的程序:

在这种情况下,函数 2 将被调用。但是当我将函数 1 修改为自由函数而不是成员函数时

现在将调用函数 1,即使在这两种情况下函数 1 基本相同。这背后的原因是什么?GCC 根据 ISO C++ 标准抱怨歧义,但没有说明确切的原因并且无论如何编译都很好。这种情况对于操作员来说是独一无二的,因为无论他们是否是成员,它们都可以以相同的方式被调用。

0 投票
1 回答
284 浏览

rust - 为什么 BinaryHeap 需要 Ord?

我使用标准BinaryHeap作为算法的一部分,我需要检索最大的对象(通过一些最大的定义)。两个非等价元素可能都同样大(因此它们在二进制堆中的相对顺序无关紧要) - 例如,我可能只对多字段结构的单个字段进行排序感兴趣。

因此,让我的类型实现OrdEq. PartialOrd相反,我可能应该PartialEq只实施。但是,唉,BinaryHeap要求它的元素是Ord!为什么会这样,使用BinaryHeap这种类型的最惯用的方法是什么?

(顺便说一句,在 C++ 中,在这种情况下,我会相当容易地编写自定义比较器类型,并在比较器类型上模板化优先级队列。所以我不认为我想做的在数学或算法上是错误的。)

0 投票
2 回答
292 浏览

c++ - 模板参数推导过程的细节是什么

考虑上面的例子,标准规定类模板部分特化应该比它的主类模板更特化。

在类模板部分特化的参数列表中,适用以下限制:

专业化应比主模板更专业化。

为了确定哪个更专业,将对其应用以下规则:

对于两个类模板部分特化,如果根据函数模板的排序规则,对两个函数模板进行以下重写,则第一个函数模板比​​第二个函数模板更特化:

  • 两个函数模板中的每一个都具有与相应的偏特化相同的模板参数。
  • 每个函数模板都有一个函数形参,其类型是类模板特化,其中模板实参是部分特化的 simple-template-id 的 template-argument-list 中的每个模板实参的函数模板的对应模板形参.

对于主类模板,重写后的函数模板是这样的:

类模板偏特化的重写函数模板是这样的:

根据“在部分排序期间推导模板参数”的规则:

用于确定排序的类型取决于完成部分排序的上下文:

  • 在函数调用的上下文中,使用的类型是函数调用具有参数的那些函数参数类型。
  • 在调用转换函数的上下文中,使用转换函数模板的返回类型。
  • 在其他上下文中,使用函数模板的函数类型

上面从参数模板中指定的每个类型和参数模板中的相应类型都用作 P 和 A 的类型。如果特定 P 不包含参与模板参数推导的模板参数,则该 P 不用于确定订购。

既不是function call,也不call to a conversion function是这个上下文。所以子弹3有效。这意味着,取void(Test<T>)为 P 和取void(Test<T&&>)为 A,反之亦然。

对于这对 P/A,就是temp.deduct.type#10中提到的情况,即

将 P 的相应参数类型列表 ([dcl.fct]) 的每个参数类型 P i与 A 的相应参数类型列表的相应参数类型 A i进行比较。

模板参数可以在几种不同的上下文中推导出来,但在每种情况下,都会将根据模板参数指定的类型(称为 P)与实际类型(称为 A)进行比较,并尝试查找模板参数值(类型参数的类型,非类型参数的值,或模板参数的模板)将使 P 在替换推导值(称为推导 A)后与 A 兼容。

在这里,我们在每个函数类型中只有一个参数。所以比较一下Test<T>Test<T&&>反之亦然,这个过程在temp.deduct.type#9中提到。

但是我在这里争论的是,标准中没有相关规则说明比较过程的细节是什么。换句话说,为什么我们可以TT&&(T would be T&&) 推导出来,但反过来不行。如果我错过了有关细节的相关规则,请指出。如果标准中确实没有这样的细节描述,那么模板参数推演过程细节的相关技术在哪里可以找到呢?

0 投票
1 回答
40 浏览

string - 如何在线性时间内获取字符串元素之间的顺序关系?

我有一个字符串,我想在线性时间内获取字符串元素之间的顺序关系。

比如字符串“abc”,有3个偏序关系,分别是ab、bc、ac

0 投票
1 回答
90 浏览

c++ - 是否对参与偏序的类型执行实例化

最近,我发现GCC偏序时的行为发生了变化,具体情况如下:

结果是,Clang打印#2(任何版本Clang都打印了一致的结果)。但是,GCC具有不同的行为。旧版本的GCC打印#2,相反,最新的GCC抱怨候选函数不明确。让我们看看标准对部分排序的看法。
temp.deduct.partial#2

推演过程使用转换后的类型作为参数模板,将另一个模板的原始类型作为参数模板。对于偏序比较中涉及的每种类型,此过程执行两次:一次使用转换后的模板 1 作为参数模板,模板 2 作为参数模板,再次使用转换后的模板 2 作为参数模板和模板 1作为参数模板。

#1因此,我们可以分别得到候选和的两组 P/A 对#2。一个是变换#1后的A,原来#2的P。另一个是原来#1的P,变换后#2的A。所以这两组将给出如下:

T可以推导出来UniqueB。对于第一组,规则说:

如果特定 P 不包含参与模板参数推导的模板参数,则该 P 不用于确定排序。

所以,我们先把它们放在一边,稍后再考虑

对于非演绎的上下文,它的值可以从别处获得。

然而,在某些情况下,该值不参与类型推导,而是使用在其他地方推导或明确指定的模板参数的值。如果模板参数仅在非推导上下文中使用且未明确指定,则模板参数推导失败。

因此,我们可以忽略对typename unknow_context<U>::type/ int,并考虑U/ UniqueAU可以推导出来UniqueA

如果给定类型的推导成功,则参数模板中的类型被认为至少与参数模板中的类型一样特化。

#b中,我们得到#2至少与 一样专业的结果#1

问题在#a set. 第二对没有问题,可以说第二部分#1至少和第二部分一样专业#2

但是,函数模板 F 是否比函数模板 G 更专业的规则定义为:

函数模板 F 至少与函数模板 G 一样特化,如果对于用于确定排序的每一对类型,来自 F 的类型至少与来自 G 的类型一样特化。如果 F 位于至少和 G 一样专业,而 G 至少不像 F 那样专业

因此,我们注意 pair int / typename unknow_context<UniqueA>::type,尽管规则说“P 不用于确定排序”。但是,标准中的重要说明说:

[ 注意:在 [temp.deduct.call] 和 [temp.deduct.partial] 下,如果 P 不包含出现在推导上下文中的模板参数,则不进行推导,因此P 和 A 不必具有相同的形式。——尾注]

所以,就目前而言,从P/A set #a,#1起码还是和#2(演绎成功)一样专业。所以,我认为最新的GCC应该是正确的(模棱两可,两者都不比另一个更专业)。

问题一:

哪个编译器是正确的?

问题2:

是否在部分排序期间执行特化的实例化?该标准似乎没有指定是否将执行实例化。

都选择了#2。我担心其中的P/A pair特殊之处,即:

是否typename unknow_context<UniqueA>::type会计算到UniqueA?似乎所有编译器都将typename unknow_context<UniqueA>::type其视为唯一类型,而不是将其计算为UniqueA.

0 投票
0 回答
152 浏览

haskell - Haskell:如何将部分顺序应用于子字符串函数?

我已经实现了类 POrd 和一个子字符串函数,它接受 2 个字符串并确定第一个字符串是否是第二个输入字符串的子字符串。

现在我想将 POrd 类应用到 substring 函数中,以便子字符串可以部分排序。

但是我被困在如何正确地将偏序类(POrd)应用到子字符串函数上。

0 投票
0 回答
40 浏览

r - 如何在R中自定义Hasse图?

研究论文的偏序哈斯图。希望从 hasseDiagram 包中自定义 hasse() 函数的输出,但不确定如何。我已经看了一下引擎盖,但不清楚我可以在哪里设置参数来驱动:

  1. 标签颜色
  2. 箭头大小和形状

有任何想法吗?

例子:

在此处输入图像描述