精益定理证明的4.4节显示如下:
(∃ x, p x) ↔ ¬ (∀ x, ¬ p x) := sorry
在这里,我将重点介绍从右到左的情况:
¬ (∀ x, ¬ p x) → (∃ x, p x)
我们知道我们将有一个类型为¬ (∀ x, ¬ p x)
的参数,所以让我们开始:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
_
)
在这一点上,如果我们尝试将exists.intro
与x
一起使用:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
exists.intro x _)
由于x
是未知标识符,我们将收到错误消息。
但是,作为这组练习的一部分,我们得到了:
variables a : α
因此,我们尝试将exists.intro
与之配合使用:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
exists.intro a _)
我们没有p a
,所以让我们尝试通过em
使用经典逻辑:
or.elim
的第一子句以简单的方式处理:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
or.elim (em (p a))
(λ hpa : p a, exists.intro a hpa)
(λ hnpa : ¬ p a, _))
由于我们有一个从(∀ x, ¬ p x)
到false
(即hnAxnpx
)的函数,因此,我们尝试构建类型为(∀ x, ¬ p x)
的值。然后我们可以调用hnAxnpx
并使用false.elim
。
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
or.elim (em (p a))
(λ hpa : p a, exists.intro a hpa)
(λ hnpa : ¬ p a, false.elim (hnAxnpx (λ a, _))))
在这一点上,我们似乎是如此接近!我们被告知我们需要一个¬p a
下划线所在的位置。看来hnpa
就是这样一个值。因此,我们尝试一下:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
or.elim (em (p a))
(λ hpa : p a, exists.intro a hpa)
(λ hnpa : ¬ p a, false.elim (hnAxnpx (λ a, hnpa))))
但是,随之而来的是以下错误:
type mismatch at application
hnAxnpx (λ (a : α), hnpa)
term
λ (a : α), hnpa
has type
α → ¬p a
but is expected to have type
∀ (x : α), ¬p x
我应该继续上面说明的方法吗?还是应该考虑采用完全不同的方法?
更新
这是另一种方法:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
false.elim (hnAxnpx
(λ x,
(λ hpx : p x, _)))) -- Here we'll need a false.
但是,到那时,我还不清楚如何在下划线处获得false
值。
更新
leanprover zulip组provided the following very helpful hints上的马里奥·卡内罗(Mario Carneiro)关于这最后一种方法:
请勿在您使用的地方使用
false.elim
;那丢掉了 我们试图证明(∃ x, p x)
并导致 无法解决的状态改为在此处使用by_contradiction,这还为您提供了 假设
¬ (∃ x, p x)
通过此建议,我们得到:
example : ¬ (∀ x, ¬ p x) → (∃ x, p x) :=
(assume hnAxnpx : ¬ (∀ x, ¬ p x),
by_contradiction
(λ hnExpx : ¬ (∃ x, p x),
(hnAxnpx
(λ x, (λ hpx,
hnExpx (exists.intro x hpx))))))
似乎有效。