[英]What does `true = false` mean in Coq?
[I am not sure this is appropriate for stack overflow, but there are many other Coq questions here so perhaps someone can help.] [我不确定这是否适合堆栈溢出,但这里还有许多其他 Coq 问题,所以也许有人可以提供帮助。]
I am working through the following from http://www.cis.upenn.edu/~bcpierce/sf/Basics.html#lab28 (just below where Case is introduced).我正在通过http://www.cis.upenn.edu/~bcpierce/sf/Basics.html#lab28 (就在 Case 介绍的下方)中完成以下工作。 Note that I am a complete beginner at this, and am working at home - I am not a student.
请注意,我在这方面是一个完整的初学者,并且正在家里工作 - 我不是学生。
Theorem andb_true_elim1 : forall b c : bool,
andb b c = true -> b = true.
Proof.
intros b c H.
destruct b.
Case "b = true".
reflexivity.
Case "b = false".
rewrite <- H. reflexivity.
Qed.
and I am looking at what the rewrite does:我正在研究重写的作用:
Case := "b = false" : String.string
c : bool
H : andb false c = true
============================
false = true
then rewrite <- H.
is applied:然后
rewrite <- H.
被应用:
Case := "b = false" : String.string
c : bool
H : andb false c = true
============================
false = andb false c
and it's clear how the proof will succeed.很明显证明将如何成功。
I can see how in terms of manipulating symbols in a mechanical way I am arriving at a proof.我可以看到如何以机械方式操纵符号来获得证明。 That's fine.
没关系。 But I am disturbed by the "meaning".
但我对“意义”感到不安。 In particular, how can I have
false = true
in the middle of a proof?特别是,我怎么能在证明中间有
false = true
?
It seems like I am making some kind of argument with contradictions, but I am not sure what.似乎我正在提出某种矛盾的论点,但我不确定是什么。 I feel like I have been blindly following rules and have somehow arrived at a point where I am typing nonsense.
我觉得我一直在盲目地遵守规则,不知何故到了我打字胡说八道的地步。
What am I doing above?我在上面做什么?
I hope the question is clear.我希望这个问题很清楚。
Generally, when you do a case analysis in a theorem prover, a lot of the cases boil down to "cannot happen".通常,当您在定理证明器中进行案例分析时,很多案例归结为“不可能发生”。 For example, if you are proving some fact about the integers, you may need to do a case analysis of whether the integer
i
is positive, zero, or negative.例如,如果您要证明有关整数的一些事实,您可能需要对整数
i
是正数、零还是负数进行案例分析。 But there may be other hypotheses lying around in your context, or perhaps some part of your goal, that is contradictory with one of the cases.但是,在您的上下文中,或者您的目标的某些部分,可能还有其他假设与其中一种情况相矛盾。 You may know from a previous assertion, for example, that
i
can never be negative.例如,您可能从之前的断言中知道,
i
永远不会是否定的。
However Coq is not that smart.然而,Coq 并不那么聪明。 So you still have to go through the mechanics of actually showing that the two contradictory hypotheses can be glued together into a proof of absurdity and hence a proof of your theorem.
因此,您仍然必须通过实际证明这两个相互矛盾的假设可以粘合在一起成为荒谬证明,从而证明您的定理的机制。
Think about it like in a computer program:把它想象成一个计算机程序:
switch (k) {
case X:
/* do stuff */
break;
case Y:
/* do other stuff */
break;
default:
assert(false, "can't ever happen");
}
The false = true
goal is the "can't ever happen". false = true
目标是“永远不会发生”。 But you can't just assert your way out in Coq.但是你不能只是在 Coq 中断言你的出路。 You actually have to put down a proof term.
你实际上必须写下一个证明术语。
So above, you have to prove the absurd goal false = true
.所以上面,你必须证明荒谬的目标
false = true
。 And the only thing you have to work with is the hyothesis H: andb false c = true
.您唯一需要处理的是假设
H: andb false c = true
andb H: andb false c = true
。 A moment's thought will show you that actually this is an absurd hypothesis (because andb false y
reduces to false for any y
and hence cannot possibly be true).稍加思考就会告诉你,这实际上是一个荒谬的假设(因为对于任何
y
, andb false y
减少为 false,因此不可能为真)。 So you bang on the goal with the only thing at your disposal (namely H
) and your new goal is false = andb false c
.所以你用唯一可以使用的东西(即
H
) false = andb false c
目标,你的新目标是false = andb false c
。
So you apply an absurd hypothesis trying to achive an absurd goal.所以你应用一个荒谬的假设来试图实现一个荒谬的目标。 And lo and behold you end up with something you can actually show by reflexivity.
瞧,你最终得到了一些你可以通过反身性来展示的东西。 Qed.
Qed。
UPDATE Formally, here's what's going on.更新正式,这是发生了什么。
Recall that every inductive definition in Coq comes with an induction principle.回想一下 Coq 中的每个归纳定义都带有一个归纳原则。 Here are the types of the induction principles for equality and the
False
proposition (as opposed to the term false
of type bool
):以下是等式和
False
命题的归纳原则的类型(与bool
类型的术语false
相对):
Check eq_ind.
eq_ind
: forall (A : Type) (x : A) (P : A -> Prop),
P x -> forall y : A, x = y -> P y
Check False_ind.
False_ind
: forall P : Prop, False -> P
That induction principle for False
says that if you give me a proof of False
, I can give you a proof of any proposition P
. False
归纳原理说,如果你给我一个False
的证明,我可以给你任何命题P
的证明。
The induction principle for eq
is more complicated. eq
的归纳原理比较复杂。 Let's consider it confined to bool
.让我们考虑它仅限于
bool
。 And specifically to false
.并专门为
false
。 It says:它说:
Check eq_ind false.
eq_ind false
: forall P : bool -> Prop, P false -> forall y : bool, false = y -> P y
So if you start with some proposition P(b)
that depends on a boolean b
, and you have a proof of P(false)
, then for any other boolean y
that is equal to false
, you have a proof of P(y)
.因此,如果您从某个依赖于布尔值
b
命题P(b)
开始,并且您有P(false)
的证明,那么对于任何其他等于false
布尔值y
,您就有了P(y)
的证明.
This doesn't sound terribly exiciting, but we can apply it to any proposition P
that we want.这听起来并不特别令人兴奋,但我们可以将它应用于我们想要的任何命题
P
And we want a particularly nasty one.我们想要一个特别讨厌的。
Check eq_ind false (fun b : bool => if b then False else True).
eq_ind false (fun b : bool => if b then False else True)
: (fun b : bool => if b then False else True) false ->
forall y : bool,
false = y -> (fun b : bool => if b then False else True) y
Simplifying a bit, what this says is True -> forall y : bool, false = y -> (if y then False else True)
.稍微简化一下,这就是
True -> forall y : bool, false = y -> (if y then False else True)
。
So this wants a proof of True
and then some boolean y
that we get to pick.所以这需要一个
True
的证明,然后是一些我们可以选择的布尔值y
。 So let's do that.所以让我们这样做。
Check eq_ind false (fun b : bool => if b then False else True) I true.
eq_ind false (fun b : bool => if b then False else True) I true
: false = true -> (fun b : bool => if b then False else True) true
And here we are: false = true -> False
.我们在这里:
false = true -> False
。
Combining with what we know about the induction principle for False
, we have: if you give me a proof of false = true
, I can prove any proposition.结合我们对
False
归纳原理的了解,我们有:如果你给我一个false = true
证明,我可以证明任何命题。
So back to andb_true_elim1
.所以回到
andb_true_elim1
。 We have a hypothesis H
that is false = true
.我们有一个假设
H
是false = true
。 And we want to prove some kind of goal.我们想证明某种目标。 As I've shown above, there exists a proof term that turns proofs of
false = true
into proofs of anything you want.正如我上面所展示的,存在一个证明项,可以将
false = true
证明转换为您想要的任何证明。 So in particular H
is a proof of false = true
, so you can now prove any goal you want.所以特别是
H
是false = true
的证明,所以你现在可以证明你想要的任何目标。
The tactics are basically machinery that builds the proof term.策略基本上是构建证明项的机器。
true = false
is a statement equating two different boolean values. true = false
是一个等于两个不同布尔值的语句。 Since those values are different this statement is clearly not provable (in the empty context).由于这些值不同,此陈述显然无法证明(在空上下文中)。
Considering your proof: you arrive at the stage where the goal is false = true
, so clearly you won't be able to prove it... but the thing is that your context (assumptions) are also contradictory.考虑你的证明:你到达了目标为
false = true
的阶段,很明显你无法证明它......但问题是你的上下文(假设)也是矛盾的。 This often happens for instance when you do case-analysis and one of the cases is contradictory with your other assumptions.例如,当您进行案例分析并且其中一个案例与您的其他假设相矛盾时,经常会发生这种情况。
I realize this is old, but I want to clarify some of the intuition behind Lambdageek's answer (in case someone finds this)我意识到这很旧,但我想澄清 Lambdageek 答案背后的一些直觉(以防有人发现这一点)
I noticed that the key point seems to be that we define a function F:bool->Prop
with different values at each point (ie. true => True
and false => False
).我注意到关键点似乎是我们定义了一个函数
F:bool->Prop
在每个点都有不同的值(即true => True
和false => False
)。 However it can easily be shown from the induction principle for equality eq_ind
the intuitive idea (this is in fact the " Leibniz " way of defining equality) that然而,可以很容易地从等式的归纳原理
eq_ind
直观的想法(这实际上是定义等式的“莱布尼茨”方式)表明
forall P:bool -> Prop, forall x,y:bool, (x = y) -> (P x) -> (P y),
But this would mean that from true=false
and I:True
, we can conclude False
.但这意味着从
true=false
和I:True
,我们可以得出结论False
。
Another fundamental property we are using here is the ability to define F
, which is given by the recursion principle for bool, bool_rect
:我们在这里使用的另一个基本属性是定义
F
的能力,它由 bool 的递归原则bool_rect
:
forall P:bool -> Type, P true -> P false -> (forall b:bool, P b)
by choosing P := (fun b:bool => Prop)
, then we get通过选择
P := (fun b:bool => Prop)
,我们得到
(bool_rect P) : Prop -> Prop -> (bool -> Prop),
where we input True
and False
to get our function F
.我们输入
True
和False
来得到我们的函数F
。
If we put this all together, we would get如果我们把这一切放在一起,我们会得到
(eq_ind true (bool_rect (fun b => Prop) True False) I false) : true = false -> False
It is also worth pointing out that Coq takes induction/recursion principles like eq_ind
or bool_rect
as axioms that define the identity and boolean types.还值得指出的是,Coq 将
eq_ind
或bool_rect
等归纳/递归原则作为定义身份和布尔类型的公理。
The normal, human, way of proving this is to say that since the hypothesis is not matched in this case, we do not need to prove the sequel.证明这一点的正常人类方法是说,由于在这种情况下假设不匹配,因此我们不需要证明续集。 And in Coq, there is a way for expressing that.
在 Coq 中,有一种表达方式。 This is through a tactic named
inversion
.这是通过一种名为
inversion
的策略。
Here is an example:下面是一个例子:
Theorem absurd_implies_absurd :
true = false -> 1 = 2.
Proof.
intros H.
inversion H.
Qed.
The first step let H
be the hypothesis true = false
, and therefore the goal to prove is 1 = 2
.第一步让
H
成为假设true = false
,因此要证明的目标是1 = 2
。
The inversion H
step will automatically prove the goal! inversion H
步将自动证明目标! Exactly what we wanted, magic!正是我们想要的,魔法!
To understand this magic, we turn to the documentation of what inversion
means.为了理解这种魔法,我们转向了
inversion
意味着什么的文档。
To a beginner (like me), the official documentation for inversion is terse and cryptic to read,here is a much better explanation of it.对于初学者(像我一样),反演的官方文档简洁而晦涩难懂,这里有一个更好的解释。 Search for the keyword inversion on the page and you will find this:
在页面上搜索关键词倒置,你会发现这个:
If c
and d
are different constructors, then the hypothesis H
is contradictory.如果
c
和d
是不同的构造函数,则假设H
是矛盾的。 That is, a false assumption has crept into the context, and this means that any goal whatsoever is provable!也就是说,错误的假设已经进入上下文,这意味着任何目标都是可证明的! In this case, inversion H marks the current goal as completed and pops it off the goal stack.
在这种情况下,反转 H 将当前目标标记为已完成并将其从目标堆栈中弹出。
This expresses exactly what we wanted.这正是我们想要的。 The only issue is that this is ahead of the book's plan.
唯一的问题是这超出了本书的计划。 Of course, rewriting
true
to false
will work.当然,将
true
重写为false
会起作用。 The issue is not that it doesn't work, the issue is that it is just not what we wanted.问题不在于它不起作用,问题在于它不是我们想要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.