Skip to content

Commit 987029c

Browse files
committed
feat: port Data.List.TFAE (#1354)
Co-authored-by: zeramorphic <50671761+zeramorphic@users.noreply.github.com>
1 parent 19e17ae commit 987029c

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ import Mathlib.Data.List.Nodup
245245
import Mathlib.Data.List.Pairwise
246246
import Mathlib.Data.List.Perm
247247
import Mathlib.Data.List.Range
248+
import Mathlib.Data.List.TFAE
248249
import Mathlib.Data.Multiset.Basic
249250
import Mathlib.Data.Multiset.Nodup
250251
import Mathlib.Data.Nat.Basic

Mathlib/Data/List/TFAE.lean

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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

Comments
 (0)