Section 3.6显示以下内容:
example : ¬(p → q) → p ∧ ¬q
让我们用¬
来重写→
表达式:
example : ((p → q) → false) → p ∧ (q → false)
在这一点上,很明显我们将拥有类型(p → q) → false
的参数:
example : ((p → q) → false) → p ∧ (q → false) :=
(assume hpqf : (p → q) → false,
...)
文本提到,这将需要经典推理。因此,假设我们必须使用em
。
example : ((p → q) → false) → p ∧ (q → false) :=
(assume hpqf : (p → q) → false,
or.elim (em p)
(assume hp : p,
and.intro
hp
(assume hq : q, hpqf (λ hp' : p, hq)))
(assume hpf : p → false,
and.intro
-- Need to return a value of type p here.
-- Or a false (and use with false.elim).
(assume hq : q, hpqf (λ hp : p, hq))))
如评论中所述,我们需要类型为p
或false
的值。目前尚不清楚如何获得这些。
让我们尝试另一种方法。
example : ((p → q) → false) → p ∧ (q → false) :=
(assume hpqf : (p → q) → false,
or.elim (em q)
(assume hq : q,
false.elim (hpqf (λ hp : p, hq)))
(assume hqf : q → false,
or.elim (em p)
(assume hp : p, and.intro hp hqf)
(assume hpf : p → false,
-- and.intro ...
-- Here we have no access to p or q. It seems we'd need to generate false?
)))
类似的情况。让我们先从and.intro
开始,然后在其“分支”中使用em
:
example : ((p → q) → false) → p ∧ (q → false) :=
(assume hpqf : (p → q) → false,
and.intro
or.elim (em p)
(assume hp : p, hp)
(assume hpf : p → false,
-- Need to generate a 'p' here.
-- Or a false.
)
or.elim (em q)
(assume hq : q,
(λ hq': q, hpqf (assume hp : p, hq)))
(assume hqf : q → false, hqf))
相似的结果。
我应该使用完全不同的方法吗?第3.5节提到了by_cases
和by_contradiction
;其中一个有用吗?
谢谢您的建议!
更新
以下是基于凯文方法的答案:
example : ((p → q) → false) → p ∧ (q → false) :=
(assume hpqf : (p → q) → false,
by_cases
(assume hp : p,
by_cases
(assume hq : q, and.intro hp (λ hq' : q, hpqf (λ hp' : p, hq)))
(assume hqf : q → false, and.intro hp hqf))
(assume hpf : p → false,
by_cases
(assume hq : q, false.elim (hpqf (λ hp : p, hq)))
(assume hqf : q → false,
false.elim (hpqf (λ hp : p, false.elim (hpf hp))))))
答案 0 :(得分:1)
by_cases
使您可以访问“按事实证明表”。换句话说,我们只需在四种情况下检查¬(p → q) → p ∧ ¬q
为真,p
为真,q
为真,而p
为假,则可以证明q
。 ..)。
variables (p q : Prop)
open classical
example : ¬(p → q) → p ∧ ¬q :=
λ h, by_cases
(assume hp : p,
by_cases
(assume hq : q, _)
(assume hnq : ¬ q, _)
)
(assume hnp : ¬ p,
by_cases
( assume hq : q, _)
(assume hnq : ¬ q, _)
)
在这里,我没有填写四个_
参数,但是将光标放在每个参数上将向您显示本地上下文。我不想填写它们,因为这种超级冗长的术语模式使我发疯。
在战术模式(在第5章中介绍)中,您可以像这样完整地说明它:
import tactic.interactive
variables (p q : Prop)
open classical
example : ¬(p → q) → p ∧ ¬q :=
begin
intro hnpq,
classical,
by_cases hp : p; by_cases hq : q; split;
-- 8 goals (replace previous semicolon by a comma to see this)
try {assumption}, -- four left
{ intro h, apply hnpq, intro h', assumption},
{ exfalso, apply hnpq, intro h, assumption},
{ intro h, apply hnpq, intro h', assumption},
{ exfalso, apply hnpq, intro h', exfalso, apply hp, assumption}
end
但实际上我只是这样做:
import tactic.tauto
variables (p q : Prop)
example : ¬(p → q) → p ∧ ¬q := by tauto!
您可以try all this online,而无需安装精益软件。