简体   繁体   English

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

[英]How to prove “~(nat = False)”, “~(nat = bool)” and “~(nat = True)” in coq

The following two propositions are easy to prove. 以下两个命题很容易证明。

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.

But when I tried to prove a slightly different proposition ~(nat = False) , I found the rewrite tactic doesn't work. 但是当我试图证明一个稍微不同的命题~(nat = False) ,我发现重写策略不起作用。 It reports 它报道

Error: Refiner was given an argument "fun x : Set => x" of type "Set -> Set" instead of "Set -> Prop". 错误:Refiner被赋予了一个参数“fun x:Set => x”,类型为“Set - > Set”而不是“Set - > Prop”。

So I tried to write a lemma. 所以我试着写一个引理。

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*)

All works fine until now. 一切正常,直到现在。 But when I tried to Qed it, it reported 但当我试图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".

The following are another two propositions that make me stuck. 以下是另外两个让我陷入困境的命题。

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

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

My questions are: 我的问题是:

 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. The rewrite tactic doesn't work due to how Coq handles its universes, Prop , Set and Type . 由于Coq处理其Universe, PropSetType ,重写策略不起作用。 There is a notion of subsumption which allows one to use a Prop as if it were a Set or a Type . 有一种包含概念允许人们使用Prop ,就像它是SetType This is why you were allowed to write nat = False in the first place, since equality is only allowed between things of the same type. 这就是为什么你被允许首先编写nat = False ,因为只允许在相同类型的事物之间进行相等。 The problem is that, for Coq, False : Prop is different from False : Set . 问题在于,对于Coq, False : PropFalse : Set不同。 not is defined with False : Prop , which means that that rewrite will produce a mismatch, which explains the error message you got. notFalse : Prop定义False : Prop ,这意味着重写会产生不匹配,这解释了你得到的错误信息。

    Here are similar approaches that would work. 以下是可行的类似方法。 Notice the explicit coercion to Set . 注意显式强制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. When you write a proof using tactics, Coq is essentially building a proof term internally, but isn't really typechecking it. 当你使用策略编写证明时,Coq实际上是在内部构建一个证明术语,但实际上并没有对它进行类比检查。 In this sense, it is a little bit like metaprogramming. 从这个意义上讲,它有点像元编程。 Once you hit Qed , the term that was built by the tactic is sent to the typechecker to make sure it is OK. 一旦你击中Qed ,由策略构建的术语将发送给类型检查器,以确保它没问题。 Most of the times, tactics produce proofs that are correct, but every once in a while one finds proofs that are not accepted, and your case is an example of that. 大多数时候,策略会产生正确的证据,但每隔一段时间就会发现一些不被接受的证据,而你的案例就是一个例子。

    The error message that was printed was not very clear, but one can get a better sense of what's happening by using the command Set Printing All , which causes Coq to print all terms and statements without notations and showing implicit arguments. 打印的错误消息不是很清楚,但可以通过使用命令Set Printing All更好地了解正在发生的事情,这会导致Coq打印所有不带符号的术语和语句并显示隐式参数。 This is what your error message becomes when doing that: 执行此操作时,这是您的错误消息:

     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 ab : Type, @eq Type ab -> 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". *) 

    There, we can see that the problem is that there is again a universe mismatch: one equality is in Type , while the other is in Set . 在那里,我们可以看到问题是宇宙不再存在不匹配:一个等式在Type ,而另一个在Set There are several ways one can fix this; 有几种方法可以解决这个问题; the easiest is probably to change your first theorem to: 最简单的可能是将你的第一个定理改为:

     Lemma Type_eq_prod : forall (a : Set) (b : Set), a = b -> (a -> b). 
  3. Both propositions are provable in Coq. 两个命题都可以在Coq中证明。 In the base theory of Coq, the only way one can show that simple types such as nat and bool are different is by cardinality arguments. 在Coq的基础理论中,唯一可以证明natbool等简单类型不同的方法是基数论证。 Thus, nat <> bool because bool has only two elements, whereas nat has more than that. 因此, nat <> bool因为bool只有两个元素,而nat有更多。 Thus, by showing that bool has two elements, one can rewrite the equality nat = bool to find out that nat should also have two elements, and then exploit that to get a contradiction. 因此,通过显示bool有两个元素,可以重写等式nat = bool以找出nat也应该有两个元素,然后利用它来获得矛盾。 A similar argument would show that nat <> True . 类似的参数会显示nat <> True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM