|
| 1 | +/- |
| 2 | +Copyright (c) 2018 Johan Commelin. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Johan Commelin, Simon Hudon |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module data.list.tfae |
| 7 | +! leanprover-community/mathlib commit 5a3e819569b0f12cbec59d740a2613018e7b8eec |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Data.List.Basic |
| 12 | +import Mathlib.Init.Data.List.Basic |
| 13 | + |
| 14 | +/-! |
| 15 | +# The Following Are Equivalent |
| 16 | +
|
| 17 | +This file allows to state that all propositions in a list are equivalent. It is used by |
| 18 | +`Mathlib.Tactic.Tfae`. |
| 19 | +`TFAE l` means `∀ x ∈ l, ∀ y ∈ l, x ↔ y`. This is equivalent to `pairwise (↔) l`. |
| 20 | +-/ |
| 21 | + |
| 22 | + |
| 23 | +namespace List |
| 24 | + |
| 25 | +/-- TFAE: The Following (propositions) Are Equivalent. |
| 26 | +
|
| 27 | +The `tfae_have` and `tfae_finish` tactics can be useful in proofs with `TFAE` goals. |
| 28 | +-/ |
| 29 | +def TFAE (l : List Prop) : Prop := |
| 30 | + ∀ x ∈ l, ∀ y ∈ l, x ↔ y |
| 31 | +#align list.tfae List.TFAE |
| 32 | + |
| 33 | +theorem tfae_nil : TFAE [] := |
| 34 | + forall_mem_nil _ |
| 35 | +#align list.tfae_nil List.tfae_nil |
| 36 | + |
| 37 | +theorem tfae_singleton (p) : TFAE [p] := by simp [TFAE, -eq_iff_iff] |
| 38 | +#align list.tfae_singleton List.tfae_singleton |
| 39 | + |
| 40 | +theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l := |
| 41 | + ⟨fun H => ⟨H a (by simp) b (Mem.tail a h), |
| 42 | + fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩, |
| 43 | + by |
| 44 | + rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩) |
| 45 | + · rfl |
| 46 | + · exact ab.trans (H _ h _ hq) |
| 47 | + · exact (ab.trans (H _ h _ hp)).symm |
| 48 | + · exact H _ hp _ hq⟩ |
| 49 | +#align list.tfae_cons_of_mem List.tfae_cons_of_mem |
| 50 | + |
| 51 | +theorem tfae_cons_cons {a b} {l : List Prop} : TFAE (a :: b :: l) ↔ (a ↔ b) ∧ TFAE (b :: l) := |
| 52 | + tfae_cons_of_mem (Mem.head _) |
| 53 | +#align list.tfae_cons_cons List.tfae_cons_cons |
| 54 | + |
| 55 | +theorem tfae_of_forall (b : Prop) (l : List Prop) (h : ∀ a ∈ l, a ↔ b) : TFAE l := |
| 56 | + fun _a₁ h₁ _a₂ h₂ => (h _ h₁).trans (h _ h₂).symm |
| 57 | +#align list.tfae_of_forall List.tfae_of_forall |
| 58 | + |
| 59 | +theorem tfae_of_cycle {a b} {l : List Prop} : |
| 60 | + List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := |
| 61 | + by |
| 62 | + induction' l with c l IH generalizing a b <;> |
| 63 | + simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at * |
| 64 | + · intro a b |
| 65 | + exact Iff.intro a b |
| 66 | + rintro ⟨ab, ⟨bc, ch⟩⟩ la |
| 67 | + have := IH ⟨bc, ch⟩ (ab ∘ la) |
| 68 | + exact ⟨⟨ab, la ∘ (this.2 c (Mem.head _) _ (ilast'_mem _ _)).1 ∘ bc⟩, this⟩ |
| 69 | +#align list.tfae_of_cycle List.tfae_of_cycle |
| 70 | + |
| 71 | +theorem TFAE.out {l} (h : TFAE l) (n₁ n₂) {a b} (h₁ : List.get? l n₁ = some a := by rfl) |
| 72 | + (h₂ : List.get? l n₂ = some b := by rfl) : a ↔ b := |
| 73 | + h _ (List.get?_mem h₁) _ (List.get?_mem h₂) |
| 74 | +#align list.tfae.out List.TFAE.out |
| 75 | + |
| 76 | +end List |
0 commit comments