Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use タクティクを紹介する #1257

Merged
merged 2 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion LeanByExample/Tactic/Exists.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

`exists` タクティクは、「~を満たす `x` が存在する」という命題を示すために、証拠になる `x` を具体的に示します。

ゴールが `⊢ ∃ x, P x` のとき、`x : X` がローカルコンテキストにあれば、`exists x` によりゴールが `P x` に変わります。同時に、`P x` が自明な場合は証明が終了します。-/
ゴールが `⊢ ∃ x, P x` のとき、`x : X` がローカルコンテキストにあれば、`exists x` によりゴールが `P x` に変わります。同時に、`P x` が自明な場合は証明が終了します。-/
import Lean --#

example : ∃ x : Nat, 3 * x + 1 = 7 := by
exists 2

/- 上位互換にあたるタクティクに [`use`](./Use.md) タクティクがあります。 -/

/- ## 舞台裏
なお Lean での存在量化の定義は次のようになっています。-/
--#--
Expand Down
64 changes: 64 additions & 0 deletions LeanByExample/Tactic/Use.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/- # use

`use` タクティクは、「~を満たす `x` が存在する」という命題を示すために、証拠になる `x` を具体的に示します。

ゴールが `⊢ ∃ x, P x` のとき、`x : X` がローカルコンテキストにあれば、`use x` によりゴールが `⊢ P x` に変わります。同時に、`P x` が自明な場合は証明が終了します。
-/
import Mathlib.Tactic.Use
import Mathlib.Tactic.Linarith

#guard_msgs (drop warning) in --#
example {α : Type} (P : α → Prop) (x : α) : ∃ y, P y := by
use x
-- ゴールが `P x` に変わる
guard_target =ₛ P x

sorry

/- ## exists との違い
これだけの説明だと [`exists`](./Exists.md) タクティクと同じに見えますが、`use` タクティクには `exists` より優れている点があります。

### discharger が指定できる
`use` は、証拠を与えた後にゴールを閉じるために使うタクティク(`discharger` と呼ばれます)を指定することができます。
-/

example (x : Rat) (h : 3 * x + 6 > 6) : ∃ (y : Rat), y > 0 := by
exists x
linarith

example (x : Rat) (h : 3 * x + 6 > 6) : ∃ (y : Rat), y > 0 := by
-- `discharger` として `linarith` を指定することができる
use (discharger := linarith) x

/- ### Exists 以外の構造体にも使用できる
`exists` は、ゴールの型が `Exists` であるという想定をしているため、フィールドの数が3以上であるような構造体に対して使うとエラーになります。
-/

/-- 例示のための構造体。フィールドの数が `Exists` より多い -/
structure Foo where
x : Int
pos : x > 0
sq : x ^ 2 = 9

/-- `Foo` の項を具体的に与える例 -/
example : Foo := ⟨3, by simp, by simp⟩

/--
error: invalid constructor ⟨...⟩, insufficient number of arguments, constructs 'Foo.mk' has #3 explicit fields, but only #2 provided
-/
#guard_msgs in
example : Foo := by
exists 3

/- しかし、`use` タクティクであれば対応することができます。 -/

example : Foo := by
-- 最初のフィールドを `3` で埋めるように指示する
use 3

-- 残りのフィールドは `simp` で証明することができる
all_goals simp

example : Foo := by
-- `discharger` を指定するバージョン
use (discharger := simp) 3
1 change: 1 addition & 0 deletions booksrc/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
- [trivial: 基本的なタクティクを試す](./Tactic/Trivial.md)
- [try: 失敗をエラーにしない](./Tactic/Try.md)
- [unfold: 定義に展開](./Tactic/Unfold.md)
- [use: 存在∃を示す](./Tactic/Use.md)
- [with_reducible: 透過度指定](./Tactic/WithReducible.md)
- [wlog: 一般性を失わずに特殊化](./Tactic/Wlog.md)
- [zify: 整数にキャストする](./Tactic/Zify.md)
Loading