如何在coq中证明“〜(nat = False)”,“〜(nat = bool)”和“〜(nat = True)”

时间:2014-10-24 14:32:20

标签: functional-programming logic coq dependent-type type-theory

以下两个命题很容易证明。

Theorem nat_eq_nat : nat = nat.
Proof.
  trivial.
Qed.

Theorem True_neq_False : ~(True = False).
Proof.
  unfold not.
  intros.
  symmetry in H.
  rewrite H.
  trivial.
Qed.

但是当我试图证明一个稍微不同的命题~(nat = False)时,我发现重写策略不起作用。它报告

  

错误:Refiner被赋予了一个参数“fun x:Set => x”,类型为“Set”    - >设置“而不是”Set - >丙”。

所以我试着写一个引理。

Lemma Type_eq_prod : forall (a : Type) (b : Type), a = b -> (a -> b).
Proof.
  intros.
  rewrite <- H.
  trivial.
Qed.

Theorem nat_neq_False : ~(nat = False).
Proof.
  unfold not.
  intros.
  apply (Type_eq_prod nat False) in H.
  inversion H.
  apply 0. (*no subgoals left*)

到目前为止一切正常。但当我试图Qed时,它报告了

Error: Illegal application (Type Error): 
The term "Type_eq_prod" of type "forall a b : Type, a = b -> a -> b"
cannot be applied to the terms
 "nat" : "Set"
 "False" : "Prop"
 "H" : "nat = False"
 "0" : "nat"
The 3rd term has type "nat = False" which should be coercible to
 "nat = False".

以下是另外两个让我陷入困境的命题。

Theorem nat_neq_bool : ~(nat = bool).
Proof.
  unfold not.
  intros.
Abort.

Theorem nat_neq_true : ~(nat = True).
Proof.
  unfold not.
  intros.
Abort.

我的问题是:

 1.Why the rewrite tactic doesn't work with proposition ~(nat = False).
 2.Why can't I Qed it when there is no subgoals.
 3.How to prove the aborted propositions above or is it possible to prove or prove the negates of them in coq.

1 个答案:

答案 0 :(得分:8)

  1. 由于Coq如何处理其Universe PropSetType,重写策略不起作用。有一种包含概念允许人们使用Prop,就好像它是SetType一样。这就是为什么你被允许首先编写nat = False的原因,因为只允许相同类型的事物之间存在相等性。问题在于,对于Coq,False : PropFalse : Set不同。 not定义为False : Prop,这意味着重写会产生不匹配,这会解释您收到的错误消息。

    以下是可行的类似方法。注意明确强制Set

    Lemma nat_neq_False_2 : (nat = False) -> (False : Set).
    Proof.
      intros H.
      rewrite <- H.
      apply 0.
    Qed.
    
    Lemma nat_neq_False_3 : ~(nat = False).
    Proof.
      intros H.
      destruct (nat_neq_False_2 H).
    Qed.
    
  2. 当您使用策略编写证明时,Coq基本上是在内部构建一个证明术语,但并不是真的要检查它。从这个意义上讲,它有点像元编程。点击Qed后,策略构建的术语将发送给类型检查程序以确保其正常。大多数时候,策略会产生正确的证据,但每隔一段时间就会找到不被接受的证据,而你的案例就是一个例子。

    打印的错误消息不是很清楚,但可以通过使用命令Set Printing All更好地了解发生的情况,这会导致Coq打印所有不带符号的条款和语句显示隐含的参数。这是您在执行此操作时出现的错误消息:

    Set Printing All.
    
    Lemma Type_eq_prod : forall (a : Type) (b : Type), a = b -> (a -> b).
    Proof.
      intros.
      rewrite <- H.
      trivial.
    Qed.
    
    Theorem nat_neq_False : ~(nat = False).
    Proof.
      unfold not.
      intros.
      apply (Type_eq_prod nat False) in H.
      inversion H.
      apply 0. (*no subgoals left*)
    Qed.
    
    
    (* Error: Illegal application (Type Error):  *)
    (* The term "Type_eq_prod" of type "forall a b : Type, @eq Type a b -> a -> b" *)
    (* cannot be applied to the terms *)
    (*  "nat" : "Set" *)
    (*  "False" : "Prop" *)
    (*  "H" : "@eq Set nat False" *)
    (*  "O" : "nat" *)
    (* The 3rd term has type "@eq Set nat False" which should be coercible to *)
    (*  "@eq Type nat False". *)
    

    在那里,我们可以看到问题是宇宙再次出现不匹配:一个平等在Type,而另一个在Set。有几种方法可以解决这个问题;最简单的可能是将你的第一个定理改为:

    Lemma Type_eq_prod : forall (a : Set) (b : Set), a = b -> (a -> b).
    
  3. 两个命题都可以在Coq中证明。在Coq的基础理论中,唯一可以表明natbool等简单类型不同的方法是基数参数。因此,nat <> bool因为bool只有两个元素,而nat只有两个元素。因此,通过显示bool有两个元素,可以重写等式nat = bool以找出nat也应该有两个元素,然后利用它来获得矛盾。类似的论点会显示nat <> True