attribute
attribute
は,属性(attribute)を付与するためのコマンドです.
次の例では,命題に simp
属性を付与しています.これは simp
タクティクで利用される命題を増やすことを意味します.
theorem foo {P Q : Prop} : (P → Q) ∧ P ↔ Q ∧ P := by
constructor <;> intro h
· obtain ⟨hPQ, hP⟩ := h
constructor <;> repeat apply_assumption
· obtain ⟨hP, hQ⟩ := h
constructor <;> intros
all_goals assumption
-- `simp` では示せない
example {P Q : Prop} : (P → Q) ∧ P ↔ Q ∧ P := by
simp
show P → P ∨ Q
intro (h : P)
left
assumption
-- `attribute` で属性を付与
attribute [simp] foo
-- `simp` で示せるようになった
example {P Q : Prop} : (P → Q) ∧ P ↔ Q ∧ P := by
simp
属性によっては与えた属性を削除することもできます.削除するには -
を属性の頭に付けます.
-- `simp` 属性を削除
attribute [-simp] foo
-- 再び示せなくなった
example {P Q : Prop} : (P → Q) ∧ P ↔ Q ∧ P := by
simp
show P → P ∨ Q
intro (h : P)
left
assumption
attribute
コマンドを使用すると定義の後から属性を付与することができますが,定義した直後に属性を付与する場合はタグと呼ばれる @[..]
という書き方が使えます.
@[simp]
theorem bar {P Q : Prop} : (P → Q) ∧ P ↔ Q ∧ P := by
constructor <;> intro h
· obtain ⟨hPQ, hP⟩ := h
constructor <;> repeat apply_assumption
· obtain ⟨hP, hQ⟩ := h
constructor <;> intros
all_goals assumption
example {P Q : Prop} : (P → Q) ∧ P ↔ Q ∧ P := by
simp
属性のスコープを制限する
特定の section
でのみ付与した属性を有効にするには,local
で属性名を修飾します.
example (P Q : Prop) : ((P ∨ Q) ∧ ¬ Q) ↔ (P ∧ ¬ Q) := by
-- simp だけでは証明が終わらない
try simp
show ¬Q → Q → P
intro hnQ hQ
contradiction
section
-- 補題
theorem or_and_neg (P Q : Prop) : ((P ∨ Q) ∧ ¬ Q) ↔ (P ∧ ¬ Q) := by
constructor <;> intro h
· obtain ⟨hPQ, hnQ⟩ := h
rcases hPQ with hP | hQ
· exact ⟨hP, hnQ⟩
· contradiction
· obtain ⟨hP, hnQ⟩ := h
exact ⟨by left; assumption, hnQ⟩
-- local に simp 補題を登録
attribute [local simp] or_and_neg
-- simp で証明ができる
example (P Q : Prop) : ((P ∨ Q) ∧ ¬ Q) ↔ (P ∧ ¬ Q) := by simp
end
variable (P Q : Prop)
-- section を抜けると simp 補題が利用できない
#check_failure (by simp : ((P ∨ Q) ∧ ¬ Q) ↔ (P ∧ ¬ Q))