What does the tactic destruct do in the proof below?
Question
I was reading the series Software Foundations by Benjamin Pierce. And in the Chapter Logic in the first book I came across a problem. In the proof of the theorem
Definition excluded_middle := forall P : Prop, P \/ ~ P.excluded_middle -> forall (X : Type) (P : X -> Prop), ~ (exists x : X, ~ P x) -> forall x : X, P x
And the proof of theorem can be as follows:
excluded_middle -> forall (X : Type) (P : X -> Prop), ~ (exists x : X, ~ P x) -> forall x : X, P x(forall P : Prop, P \/ ~ P) -> forall (X : Type) (P : X -> Prop), ~ (exists x : X, ~ P x) -> forall x : X, P xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: XP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H1: P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P xP xapply H1.exmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H1: P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
x: X
H2: ~ P xexists x : X, ~ P xapply H2. Qed.exmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
x: X
H2: ~ P x~ P x
What puzzled me is the destruct H in the second case. What does the tactic destruct do here? It seems different from What I've known about it before. (H here is ~ (exists x : X, ~ P x)). After using destruct H, the subgoal is tranformed from P x into exists x : X, ~ P x.
Answer
When you destruct a term of the form A -> B you get a goal for A and the goals for what destruct B would result in. not A is defined as A -> False so B is False in your case and destruct B results in no goals. So you end up with just A.
Here is a long form proof of what is going on:
excluded_middle -> forall (X : Type) (P : X -> Prop), ~ (exists x : X, ~ P x) -> forall x : X, P xexcluded_middle -> forall (X : Type) (P : X -> Prop), ~ (exists x : X, ~ P x) -> forall x : X, P x(forall P : Prop, P \/ ~ P) -> forall (X : Type) (P : X -> Prop), ~ (exists x : X, ~ P x) -> forall x : X, P xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: XP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H1: P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P xP xapply H1.exmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H1: P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P xexists x : X, ~ P xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P x
H3: exists x : X, ~ P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P x~ P xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P x
H3: exists x : X, ~ P xP xexmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
H2: ~ P x
H3: exists x : X, ~ P xP xdestruct H. Qed.exmid: forall P : Prop, P \/ ~ P
X: Type
P: X -> Prop
H: False
x: X
H2: ~ P x
H3: exists x : X, ~ P xP x
A: You can also replace destruct H with exfalso; apply H.