TL;DR
- 命題 と が同値であるとは、 と がともに成り立つことで、Lean では
↔で表す。 - 同値を示すときは
constructorで 2 つのゴールに分け、仮定にある同値はrwで書き換えに使う。
内容
同値の表し方
命題 と が同値であるとは、 と がともに成り立つことを指す。Lean では同値を ↔ で表す。なお、Lean では同値な命題を基本的に区別しない。これを命題外延性と呼ぶ。
constructor タクティク
ゴールが のときは、 と の 2 つのゴールを示せばよい。このためのタクティクが constructor である。· は、ゴールが複数あるときに、それぞれのゴールの証明を見やすく分けるための記法である。
example (P Q : Prop) (h1 : P → Q) (h2 : Q → P) : P ↔ Q := by
constructor
· apply h1
· apply h2タクティク結合子 <;>
constructor を使うと、続けて intro を使うことが多い。
example (P Q : Prop) (hq : Q) : (Q → P) ↔ P := by
constructor
-- (Q → P) → P を証明する
case mp =>
intro h
exact h hq
-- P → Q → P を証明する
case mpr =>
intro hp hq
exact hpこのような場合は、タクティク結合子 <;> を使うと記述量を減らせる。<;> は、直前のタクティクで生まれたすべてのゴールに、後ろのタクティクを適用する。
example (P Q : Prop) (hq : Q) : (Q → P) ↔ P := by
constructor <;> intro h
case mp =>
exact h hq
case mpr =>
intro hq
exact hrw タクティク
仮定に同値が含まれるときは、rw を使って同値なものに書き換えられる。たとえば h : P ↔ Q が仮定にあれば、rw [h] で を に書き換えられる。
example (P Q : Prop) (h : P ↔ Q) (hq : Q) : P := by
-- P ↔ Q が仮定にあるので、P の代わりに Q を示す
rw [h]
exact hq逆に を に書き換えるときは、← を付けて rw [← h] と書く。
example (P Q : Prop) (h : P ↔ Q) (hp : P) : Q := by
rw [← h]
exact hp