Skip to content

Commit a73d2b5

Browse files
authored
Merge pull request #530 from lean-ja/Seasawher/issue341
refactor: `rcases` を `cases` から独立させる
2 parents dc49d4f + bf00d03 commit a73d2b5

File tree

6 files changed

+61
-43
lines changed

6 files changed

+61
-43
lines changed

Examples/Tactic/Cases.lean

+11-40
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
55
たとえば、ローカルコンテキストに `h : P ∨ Q` があるときに `cases h` とすると、仮定に `P` を付け加えたゴール `case inl` と、仮定に `Q` を付け加えたゴール `case inr` を生成します。
66
7-
補足すると、`inl` と `inr` はそれぞれ `left injection` と `right injection` からその名前があり、`Or` 型のコンストラクタです。-/
7+
上位互換にあたるタクティクに [`rcases`](./RCases.md) があります。
8+
-/
89

910
-- `P`, `Q`, `R` を命題とする
1011
variable (P Q R : Prop)
@@ -40,8 +41,7 @@ example : P ∨ Q → (P → R) → (Q → R) → R := by
4041
| inr hQ =>
4142
exact hQR hQ
4243

43-
/-!
44-
## 補足
44+
/- ## 舞台裏
4545
4646
`cases` は、実際には論理和に限らず帰納型をコンストラクタに分解することができるタクティクです。
4747
論理和を分解することができるのも、`Or` が帰納型として定義されているからです。
@@ -57,52 +57,23 @@ Or.inr : ∀ {a b : Prop}, b → a ∨ b
5757
-/
5858
#guard_msgs in #print Or
5959

60+
-- Or のコンストラクタ
6061
#check (Or.inl : P → P ∨ Q)
6162
#check (Or.inr : Q → P ∨ Q)
6263

63-
end Cases --#
64-
65-
/-! ## rcases
66-
67-
`rcases` は `cases` をパターンに従って再帰的(recursive)に適用します。`cases` の上位互換という立ち位置です。-/
68-
69-
example : P ∨ Q → (P → R) → (Q → R) → R := by
70-
intro h hPR hQR
71-
72-
-- 場合分けをする
73-
rcases h with hP | hQ
74-
· apply hPR hP
75-
· apply hQR hQ
76-
77-
-- 論理積 ∧ に対しても使える
78-
example : P ∧ Q → Q ∧ P := by
79-
-- `h: P ∧ Q` と仮定する
80-
intro h
81-
82-
-- `h: P ∧ Q` を `hP: P` と `hQ: Q` に分解する
83-
rcases h with ⟨hP, hQ⟩
84-
85-
-- `Q ∧ P` を証明する
86-
exact ⟨hQ, hP⟩
87-
88-
/- `rcases` は一般には `⟨x₁, x₂, ...⟩ | ⟨y₁, y₂, ...⟩ | ...` という記法で帰納型の分解が可能です。-/
89-
64+
-- 帰納型として定義した例示のための型
9065
inductive Sample where
9166
| foo (x y : Nat) : Sample
9267
| bar (z : String) : Sample
9368

9469
example (s : Sample) : True := by
95-
rcases s with ⟨x, y⟩ | ⟨z⟩
96-
97-
case foo =>
98-
-- `x`, `y` が取り出せている
99-
guard_hyp x : Nat
100-
guard_hyp y : Nat
70+
-- cases で場合分けを実行できる
71+
cases s
10172

73+
case foo x y =>
10274
trivial
10375

104-
case bar =>
105-
-- `z` が取り出せている
106-
guard_hyp z : String
107-
76+
case bar z =>
10877
trivial
78+
79+
end Cases --#

Examples/Tactic/Intro.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ example (hPR : P → R) (hQR : Q → R) : P ∨ Q → R := by
5353
| Or.inr hQ =>
5454
exact hQR hQ
5555

56-
/- `rcases` を使って分解することも一般的です。-/
56+
/- [`rcases`](./RCases.md) を使って分解することも一般的です。-/
5757

5858
example (hPR : P → R) (hQR : Q → R) : P ∨ Q → R := by
5959
intro h

Examples/Tactic/Obtain.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ example (h : ∃ e : X, P e) : True := by
2929
trivial
3030

3131
/-
32-
`obtain` に与えることのできるパターンは `rcases` に与えられるパターンと同様で、一般の帰納型を分解することができます。
32+
`obtain` に与えることのできるパターンは [`rcases`](./RCases.md) に与えられるパターンと同様で、一般の帰納型を分解することができます。
3333
-/
3434

3535
inductive Sample where

Examples/Tactic/RCases.lean

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/- # rcases
2+
3+
`rcases` は [`cases`](./Cases.md) をパターンに従って再帰的(recursive)に適用します。`cases` の上位互換という立ち位置です。-/
4+
5+
variable (P Q R : Prop)
6+
7+
example : P ∨ Q → (P → R) → (Q → R) → R := by
8+
intro h hPR hQR
9+
10+
-- 場合分けをする
11+
rcases h with hP | hQ
12+
· apply hPR hP
13+
· apply hQR hQ
14+
15+
-- 論理積 ∧ に対しても使える
16+
example : P ∧ Q → Q ∧ P := by
17+
-- `h: P ∧ Q` と仮定する
18+
intro h
19+
20+
-- `h: P ∧ Q` を `hP: P` と `hQ: Q` に分解する
21+
rcases h with ⟨hP, hQ⟩
22+
23+
-- `Q ∧ P` を証明する
24+
exact ⟨hQ, hP⟩
25+
26+
/- `rcases` は一般には `⟨x₁, x₂, ...⟩ | ⟨y₁, y₂, ...⟩ | ...` という記法で帰納型の分解が可能です。-/
27+
28+
inductive Sample where
29+
| foo (x y : Nat) : Sample
30+
| bar (z : String) : Sample
31+
32+
example (s : Sample) : True := by
33+
rcases s with ⟨x, y⟩ | ⟨z⟩
34+
35+
case foo =>
36+
-- `x`, `y` が取り出せている
37+
guard_hyp x : Nat
38+
guard_hyp y : Nat
39+
40+
trivial
41+
42+
case bar =>
43+
-- `z` が取り出せている
44+
guard_hyp z : String
45+
46+
trivial

Examples/Term/Type/Prop.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ theorem proof_irrel (P : Prop) (h1 h2 : P) : h1 = h2 := rfl
1515
/-- info: 'Proposition.proof_irrel' does not depend on any axioms -/
1616
#guard_msgs in #print axioms proof_irrel
1717

18-
/- 証明無関係の重要な帰結のひとつに、「命題から値を取り出すことができるのは、証明の中だけ」というものがあります。たとえば次のように、証明の中であれば命題を [`cases`](../../Tactic/Cases.md) や `rcases` で分解して値を取り出すことができます。-/
18+
/- 証明無関係の重要な帰結のひとつに、「命題から値を取り出すことができるのは、証明の中だけ」というものがあります。たとえば次のように、証明の中であれば命題を [`cases`](../../Tactic/Cases.md) や [`rcases`](../../Tactic/RCases.md) で分解して値を取り出すことができます。-/
1919

2020
-- 同じ存在命題の2通りの証明
2121
-- 2乗すると1になる整数を2通り与えた

src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
- [positivity: 正値性を示す](./Tactic/Positivity.md)
109109
- [push_neg: ドモルガン](./Tactic/PushNeg.md)
110110
- [qify: 有理数にキャストする](./Tactic/Qify.md)
111+
- [rcases: パターン分解](./Tactic/RCases.md)
111112
- [refine: 穴埋め推論](./Tactic/Refine.md)
112113
- [rel: 不等式を使う](./Tactic/Rel.md)
113114
- [rename_i: 死んだ変数に名前を付ける](./Tactic/RenameI.md)

0 commit comments

Comments
 (0)