颠倒一个明显不真实的假设并不能证明是错误的

时间:2015-01-06 20:44:04

标签: coq inversion

我试图证明一个微不足道的引理,这是我在另一个角度发现自己的情况的再创造。

Lemma Sn_neq_n: forall n, S n <> n.

证据看起来很简单:

Proof. unfold not. intros.

现在我的目标状态显示:

n : nat
H : S n = n
===================
 False

很明显S n无法与n统一,所以我应该能够反驳这个假设:

inversion H.

但是我的状态现在显示:

,而不是解决目标
n : nat
H : S n = n
H0 : S n = n
===================
 False    

咦?我现在只是在无限循环中。我可以inversion H0我只得到H1等等。

我能够通过归纳证明这个引理:

unfold not. intros. induction n.
Case "n = 0". inversion H.
Case "n > 0". inversion H. apply IHn. apply H1.

但这有点愚蠢,因为可以想象的是统一算法,它允许反思性平等首先有意义,不应该能够S nn统一。

这里发生了什么?

1 个答案:

答案 0 :(得分:4)

要了解为什么inversion无法单独解决这一目标,我们需要更详细地了解它的作用。

当你颠倒(共)归纳类型的假设时,粗略地说,Coq所做的就是尽可能多地使用模式匹配提取信息(记住Coq策略是总是在引擎盖下制作证明条款)。因此,当通过反演证明1 <> 0时,Coq将产生一个如下所示的术语:

Definition one_neq_zero (p : 1 = 0) : False :=
  match p in _ = n return match n with
                          | 0 => False
                          | _ => True
                          end
  with
  | eq_refl => I (* "I" is the only constructor of the True proposition *)
  end.

return语句中的match注释对于此工作至关重要。这里发生的事情基本上如下:

  • 我们需要匹配相等证明p才能使用它。
  • 为了能够在证明模式匹配时谈论该等式的右侧,我们必须在匹配中添加一个返回注释。
  • 不幸的是,这个返回注释不能直接提到0。相反,它需要适用于泛型 n,即使我们知道该元素实际上是0 。这只是因为模式匹配在Coq。
  • 中的工作方式
  • 在返回注释上,我们对Coq发出了一个“技巧”:我们说我们会在我们真正关心的情况下返回False(即n = 0),但是说我们将在其他分支上返回其他内容。
  • 要对match进行类型检查,每个分支必须返回return子句中出现的类型,但在替换变量的实际值之后受in条款约束。
  • 在我们的例子中,只有一个构造函数用于相等类型eq_refl。在这里,我们知道n = 1。在我们的返回类型中用1代替n,我们获得了True,因此我们必须返回True类型的内容,我们这样做。
  • 最后,由于p的右侧为0,Coq了解整个匹配的类型为False,因此整个定义类型检查。

最后一步只能起作用,因为0是构造函数,因此Coq能够简化返回类型的匹配,以实现我们正在返回正确的东西。 在尝试反转S n = n时失败:由于n是变量,因此无法简化整个匹配。

我们可以尝试翻转相等并反转n = S n,以便Coq可以稍微简化返回类型。不幸的是,由于类似的原因,这也不起作用。例如,如果您尝试使用in _ = m return match m with 0 => True | _ => False end对匹配进行注释,则在eq_refl内我们将不得不返回match n with 0 => True | _ => False end类型的内容,而我们无法返回。

最后我要提一下,Coq中的统一算法不能像你提到的那样“消极地”使用,因为理论只定义了可证明的东西,而不是可辩驳。特别是,当我们证明一个否定的命题,如S n <> n时,类型检查器总是测试某些统一问题是否有解决方案,而不是测试他们是否有 no 解决方案。例如,假设n = m是一件非常好的事情,并且不会导致任何矛盾,即使nm 是统一的。另请注意,如果nat被声明为 co-inductive 类型,则S n = n 是一个矛盾的假设,而且两个就是在这种情况下我们无法在n上进行归纳。