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

Coq QArith除以零就是零,为什么?,coq,divide-by-zero,rational-numbers,Coq,Divide By Zero,Rational Numbers,我注意到在Coq对有理数的定义中,零的倒数被定义为零。(通常情况下,被零除的定义不明确/不合法/不允许。) 为什么会这样 它会导致理性计算中的问题吗?或者它是安全的吗?简单的回答是:是的,它是绝对安全的 当我们说被零除并没有很好的定义时,我们实际上的意思是零没有乘法逆。特别是,我们不能有一个计算零的乘法逆的函数。但是,可以编写一个函数来计算所有其他元素的乘法逆,并在不存在此类逆时返回一些任意值(例如,对于零)。这正是这个函数所做的 在任何地方都定义这个逆运算符意味着我们可以定义用它计算的其他函数

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

为什么会这样


它会导致理性计算中的问题吗?或者它是安全的吗?

简单的回答是:是的,它是绝对安全的

当我们说被零除并没有很好的定义时,我们实际上的意思是零没有乘法逆。特别是,我们不能有一个计算零的乘法逆的函数。但是,可以编写一个函数来计算所有其他元素的乘法逆,并在不存在此类逆时返回一些任意值(例如,对于零)。这正是这个函数所做的

在任何地方都定义这个逆运算符意味着我们可以定义用它计算的其他函数,而不必明确地证明它的参数不同于零,这使得它的使用更加方便。事实上,想象一下,如果我们让这个函数返回一个
选项,而当我们将其传递为零时失败,那将是多么痛苦的一件事:我们将不得不使整个代码成为一元代码,这将使我们更难理解和推理。如果编写一个需要证明其参数非零的函数,我们也会遇到类似的问题

那么,有什么问题吗?当我们试图证明一个使用逆算子的函数时,我们必须加上明确的假设,说我们传递给它一个不同于零的参数,或者说它的参数永远不能为零。关于这个函数的引理得到了附加的前提条件,例如

forall q, q <> 0 -> q * (/ q) = 1
forall q,q 0->q*(/q)=1
许多其他库都是这样构造的,参见MathComp代数库中的定义

在某些情况下,我们希望将某些函数所需的附加先决条件内部化为类型级约束。例如,当我们使用长度索引向量和安全的
get
函数时,我们就是这样做的,该函数只能对边界内的数字调用。那么,在设计库时,我们如何决定选择哪一种类型,即是使用具有大量额外信息的富类型并防止对某些函数的虚假调用(如在长度索引的情况下),还是忽略这些信息并要求将其作为显式引理(如在乘法逆情况下)?嗯,这里没有明确的答案,我们确实需要对每一个案例进行单独分析,并决定哪一个方案更适合那个特定的案例

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