Don';我不理解Coq中假设`(存在x:x,~px)`的“破坏”策略

Don';我不理解Coq中假设`(存在x:x,~px)`的“破坏”策略,coq,coq-tactic,Coq,Coq Tactic,我是Coq的新手,尝试着从中学习。在“Coq中的逻辑”一章中,有一个练习not\u exists\u dist,我通过猜测完成了该练习,但不理解: Theorem not_exists_dist : excluded_middle → ∀ (X:Type) (P : X → Prop), ¬ (∃ x, ¬ P x) → (∀ x, P x). Proof. intros em X P H x. destruct (em (P x)) as [T | F]. - ap

我是Coq的新手,尝试着从中学习。在“Coq中的逻辑”一章中,有一个练习
not\u exists\u dist
,我通过猜测完成了该练习,但不理解:

Theorem not_exists_dist :
  excluded_middle →
  ∀ (X:Type) (P : X → Prop),
    ¬ (∃ x, ¬ P x) → (∀ x, P x).
Proof.
  intros em X P H x.
  destruct (em (P x)) as [T | F].
  - apply T.
  - destruct H.              (* <-- This step *)
    exists x.
    apply F.
Qed.
之后呢

em: excluded_middle
X: Type
P: X -> Prop
x: X
F: ~ P x
--------------------------------------
(1/1)
exists x0 : X, ~ P x0

虽然我理解假设中的
p/\code>和
p\/Q
上的
destruct
,但我不理解它是如何在
p->False
上工作的。通常,
destruct t
适用于
t
是归纳类型
I
的居住者,为可能用于生成
t
I
的每个可能构造函数提供一个目标。如您所述,这里的
H
具有类型
P->False
,这不是归纳类型,而是
False
。所以发生的是:
destruct
为您提供了与
P
假设
H
相对应的第一个目标。将
H
应用于该目标会导致一个类型为
False
的术语,这是一种归纳类型,
destruct
在该术语上正常工作,因为
False
没有构造器,所以目标为零。归纳类型的许多策略都是这样工作的,假设形式为
P1->…->Pn->I
,其中
I
是归纳类型:它们为
P1
Pn
,然后对
I
进行工作,让我先做另一个证明,尝试给出一些直觉。 考虑:

Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B. 
Proof.
  intros. (*eval up to here*)
Admitted.
您将在
*目标*
中看到:

1 subgoal (ID 77)
  
  A, B, C : Prop
  H : A
  H0 : C
  H1 : A ∨ B → B ∨ C → A ∧ B
  ============================
  A ∧ B
好的,我们需要显示
A/\B
。我们可以使用
split
来分解和分离,因此我们需要显示
A
B
A
很容易被假设遵循,
B
是我们没有的东西。因此,我们现在的校对脚本可能如下所示:

Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B. 
Proof.
  intros. split; try assumption. (*eval up to here*)
Admitted.
目标:

1 subgoal (ID 80)
  
  A, B, C : Prop
  H : A
  H0 : C
  H1 : A ∨ B → B ∨ C → A ∧ B
  ============================
  B
我们能够到达
B
的唯一方法是以某种方式使用H1。让我们看看
destructh1
对我们的目标有什么作用:

3 subgoals (ID 86)
  
  A, B, C : Prop
  H : A
  H0 : C
  ============================
  A ∨ B

subgoal 2 (ID 87) is:
 B ∨ C
subgoal 3 (ID 93) is:
 B
我们有额外的子目标!为了解构H1,我们需要为
A\/B
B\/C
提供它的证明,否则我们不能解构
A/\B

为了完整性:(没有
拆分;尝试假设
速记)

另一种查看方式是:H1是一个函数,它将
a\/B
B\/C
作为输入<代码>析构函数
对其输出起作用。为了破坏这样一个函数的结果,您需要给它一个适当的输入。 然后,
destruct
在不引入额外目标的情况下执行案例分析。 我们也可以在验证脚本中执行此操作,然后再进行
销毁
ing:

Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B. 
Proof.
  intros. split.
  - assumption.
  - specialize (H1 (or_introl H) (or_intror H0)).
    destruct H1.
    assumption.
Qed.
从证明术语的角度来看,
a/\B
destruct
match a/\B with conj H1 H2=>(*构造一个以您的目标为其类型的术语*)end
相同。 我们可以用相应的
refine
来替换校对脚本中的
destruct
,该脚本正好做到:

Goal forall A B C : Prop, A -> C -> (A \/ B -> B \/ C -> A /\ B) -> A /\ B. 
Proof.
  intros. unfold not in H0. split.
  - assumption.
  - specialize (H1 (or_introl H) (or_intror H0)).
    refine (match H1 with conj Ha Hb => _ end).
    exact Hb.
Qed.

回到你的证据上来。你在销毁之前的目标

em: excluded_middle
X: Type
P: X -> Prop
H: ~ (exists x : X, ~ P x)
x: X
F: ~ P x
--------------------------------------
(1/1)
P x
应用
不在H中展开策略后,您会看到:

em: excluded_middle
X: Type
P: X -> Prop
H: (exists x : X, P x -> ⊥) -> ⊥
x: X
F: ~ P x
--------------------------------------
(1/1)
P x
现在回想一下⊥: 它是一个不能被构造的命题,也就是说,它没有构造函数。 如果你有⊥ 作为一种假设,您可以进行分解,您基本上可以查看
匹配的类型⊥ 使用end
,可以是任何内容

事实上,我们可以用它证明任何目标:

Goal (forall (A : Prop), A) <-> False.  (* <- note that this is different from *)
Proof.                                  (*    forall (A : Prop), A <-> False   *)
  split; intros.
  - specialize (H False). assumption.
  - refine (match H with end).
Qed.
无论如何,
destruct
在您的假设下,
H
将为您的目标提供证明,如果您能够显示
存在x:x,~px->⊥


除了
destruct
,您还可以执行
exfalso。应用H.
实现同样的效果。

谢谢,现在我知道
p->Q
上的析构函数实际上是
Q
上的析构函数,并将
p
作为子目标添加。如果
Q
False
像这里一样,原始目标从exfalso开始消失,因此只剩下子目标
P
有待证明。谢谢你的详细解释,我从你的答案中学到了一些新东西:-)。如果理解正确,
P->Q
上的
destruct
告诉coq我想
Q
上的
destruct
,coq将
P
作为子目标添加为预目标。
em: excluded_middle
X: Type
P: X -> Prop
H: (exists x : X, P x -> ⊥) -> ⊥
x: X
F: ~ P x
--------------------------------------
(1/1)
P x
Goal (forall (A : Prop), A) <-> False.  (* <- note that this is different from *)
Proof.                                  (*    forall (A : Prop), A <-> False   *)
  split; intros.
  - specialize (H False). assumption.
  - refine (match H with end).
Qed.
(λ (A B C : Prop) (H : A) (H0 : C) (H1 : A ∨ B → B ∨ C → A ∧ B),
   conj H (let H2 : A ∧ B := H1 (or_introl H) (or_intror H0) in match H2 with
                                                                | conj _ Hb => Hb
                                                                end))