以下两个命题很容易证明。
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.
答案 0 :(得分:8)
由于Coq如何处理其Universe Prop
,Set
和Type
,重写策略不起作用。有一种包含概念允许人们使用Prop
,就好像它是Set
或Type
一样。这就是为什么你被允许首先编写nat = False
的原因,因为只允许相同类型的事物之间存在相等性。问题在于,对于Coq,False : Prop
与False : 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.
当您使用策略编写证明时,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).
两个命题都可以在Coq中证明。在Coq的基础理论中,唯一可以表明nat
和bool
等简单类型不同的方法是基数参数。因此,nat <> bool
因为bool
只有两个元素,而nat
只有两个元素。因此,通过显示bool
有两个元素,可以重写等式nat = bool
以找出nat
也应该有两个元素,然后利用它来获得矛盾。类似的论点会显示nat <> True
。