Coq QArith除以零是零,为什么?

时间:2015-03-26 15:42:14

标签: coq divide-by-zero rational-numbers

我注意到在Coq的有理数定义中,零的倒数被定义为零。 (通常,除以零没有明确定义/合法/允许。)

Require Import QArith.
Lemma inv_zero_is_zero: (/ 0) == 0. 
Proof. unfold Qeq. reflexivity. Qed.

为什么会这样?

它可能会导致有理数的计算出现问题,还是安全?

1 个答案:

答案 0 :(得分:15)

简短的回答是:是的,绝对安全。

当我们说除零没有明确定义时,我们实际意味着零没有乘法逆。特别是,我们不能有一个函数来计算零的乘法逆。然而,可能写入计算所有其他元素的乘法逆的函数,并且当这样的逆不存在时返回一些任意值(例如,对于零)。这正是这个功能正在做的事情。

在任何地方定义这个逆运算符意味着我们将能够定义用它计算的其他函数,而不必明确地争论它的参数与零不同,使得它更方便使用。实际上,想象一下,如果我们使这个函数返回option而不是当我们将它传递给零时失败,那将是多么痛苦:我们必须使我们的整个代码成为monadic,使其更难理解和推理。如果编写一个需要证明其参数非零的函数,我们会遇到类似的问题。

那么,有什么收获?好吧,当试图证明关于使用逆运算符的函数的任何事情时,我们将不得不添加明确的假设,说我们正在传递一个不同于零的参数,或者认为它的论证永远不会为零。关于这个函数的引理然后获得额外的前提条件,例如

forall q, q <> 0 -> q * (/ q) = 1

许多其他库的结构都是这样的,参见例如,MathComp的代数库中field axioms的定义。

某些情况下,我们希望将某些函数所需的其他前置条件内部化为类型级约束。这就是我们使用长度索引向量和安全get函数时所做的事情,这些函数只能在边界内的数字上调用。那么我们如何在设计库时决定使用哪一个,即是否使用具有大量额外信息的丰富类型并防止对某些函数的伪调用(如在长度索引的情况下)或者将此信息保留并要求它作为明确的引理(如在乘法逆情况下)?嗯,这里没有明确的答案,一个人真的需要单独分析每个案例,并决定哪个案例对那个案例更好。