[GOAL]
N✝ N : ℕ
γ : SL(2, ℤ)
⊢ γ ∈ Gamma N ↔ ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
[PROOFSTEP]
rw [Gamma_mem']
[GOAL]
N✝ N : ℕ
γ : SL(2, ℤ)
⊢ ↑(SpecialLinearGroup.map (Int.castRingHom (ZMod N))) γ = 1 ↔
    ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
[PROOFSTEP]
constructor
[GOAL]
case mp
N✝ N : ℕ
γ : SL(2, ℤ)
⊢ ↑(SpecialLinearGroup.map (Int.castRingHom (ZMod N))) γ = 1 →
    ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
[PROOFSTEP]
intro h
[GOAL]
case mp
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(SpecialLinearGroup.map (Int.castRingHom (ZMod N))) γ = 1
⊢ ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
[PROOFSTEP]
simp [← SL_reduction_mod_hom_val N γ, h]
[GOAL]
case mpr
N✝ N : ℕ
γ : SL(2, ℤ)
⊢ ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1 →
    ↑(SpecialLinearGroup.map (Int.castRingHom (ZMod N))) γ = 1
[PROOFSTEP]
intro h
[GOAL]
case mpr
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(SpecialLinearGroup.map (Int.castRingHom (ZMod N))) γ = 1
[PROOFSTEP]
ext i j
[GOAL]
case mpr.a
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
i j : Fin 2
⊢ ↑(↑(SpecialLinearGroup.map (Int.castRingHom (ZMod N))) γ) i j = ↑1 i j
[PROOFSTEP]
rw [SL_reduction_mod_hom_val N γ]
[GOAL]
case mpr.a
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
i j : Fin 2
⊢ ↑(↑γ i j) = ↑1 i j
[PROOFSTEP]
fin_cases i
[GOAL]
case mpr.a.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
j : Fin 2
⊢ ↑(↑γ { val := 0, isLt := (_ : 0 < 2) } j) = ↑1 { val := 0, isLt := (_ : 0 < 2) } j
[PROOFSTEP]
fin_cases j
[GOAL]
case mpr.a.tail.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
j : Fin 2
⊢ ↑(↑γ { val := 1, isLt := (_ : (fun a => a < 2) 1) } j) = ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } j
[PROOFSTEP]
fin_cases j
[GOAL]
case mpr.a.head.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }) =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }
[PROOFSTEP]
simp only [h]
[GOAL]
case mpr.a.head.tail.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }) =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
[PROOFSTEP]
simp only [h]
[GOAL]
case mpr.a.tail.head.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }) =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }
[PROOFSTEP]
simp only [h]
[GOAL]
case mpr.a.tail.head.tail.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }) =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
[PROOFSTEP]
simp only [h]
[GOAL]
case mpr.a.head.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }) =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }
case mpr.a.head.tail.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }) =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
case mpr.a.tail.head.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }) =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }
case mpr.a.tail.head.tail.head
N✝ N : ℕ
γ : SL(2, ℤ)
h : ↑(↑γ 0 0) = 1 ∧ ↑(↑γ 0 1) = 0 ∧ ↑(↑γ 1 0) = 0 ∧ ↑(↑γ 1 1) = 1
⊢ ↑(↑γ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }) =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
[PROOFSTEP]
exacts [h.1, h.2.1, h.2.2.1, h.2.2.2]
[GOAL]
N : ℕ
⊢ Gamma 1 = ⊤
[PROOFSTEP]
ext
[GOAL]
case h
N : ℕ
x✝ : SL(2, ℤ)
⊢ x✝ ∈ Gamma 1 ↔ x✝ ∈ ⊤
[PROOFSTEP]
simp
[GOAL]
N : ℕ
⊢ Gamma 0 = ⊥
[PROOFSTEP]
ext
[GOAL]
case h
N : ℕ
x✝ : SL(2, ℤ)
⊢ x✝ ∈ Gamma 0 ↔ x✝ ∈ ⊥
[PROOFSTEP]
simp only [Gamma_mem, coe_matrix_coe, Int.coe_castRingHom, map_apply, Int.cast_id, Subgroup.mem_bot]
[GOAL]
case h
N : ℕ
x✝ : SL(2, ℤ)
⊢ ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1 ↔ x✝ = 1
[PROOFSTEP]
constructor
[GOAL]
case h.mp
N : ℕ
x✝ : SL(2, ℤ)
⊢ ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1 → x✝ = 1
[PROOFSTEP]
intro h
[GOAL]
case h.mp
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ x✝ = 1
[PROOFSTEP]
ext i j
[GOAL]
case h.mp.a
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
i j : Fin 2
⊢ ↑x✝ i j = ↑1 i j
[PROOFSTEP]
fin_cases i
[GOAL]
case h.mp.a.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
j : Fin 2
⊢ ↑x✝ { val := 0, isLt := (_ : 0 < 2) } j = ↑1 { val := 0, isLt := (_ : 0 < 2) } j
[PROOFSTEP]
fin_cases j
[GOAL]
case h.mp.a.tail.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
j : Fin 2
⊢ ↑x✝ { val := 1, isLt := (_ : (fun a => a < 2) 1) } j = ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } j
[PROOFSTEP]
fin_cases j
[GOAL]
case h.mp.a.head.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) } =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }
[PROOFSTEP]
simp only [h]
[GOAL]
case h.mp.a.head.tail.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
[PROOFSTEP]
simp only [h]
[GOAL]
case h.mp.a.tail.head.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) } =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }
[PROOFSTEP]
simp only [h]
[GOAL]
case h.mp.a.tail.head.tail.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
[PROOFSTEP]
simp only [h]
[GOAL]
case h.mp.a.head.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) } =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }
case h.mp.a.head.tail.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    ↑1 { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
case h.mp.a.tail.head.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) } =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }
case h.mp.a.tail.head.tail.head
N : ℕ
x✝ : SL(2, ℤ)
h : ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
⊢ ↑x✝ { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    ↑1 { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }
[PROOFSTEP]
exacts [h.1, h.2.1, h.2.2.1, h.2.2.2]
[GOAL]
case h.mpr
N : ℕ
x✝ : SL(2, ℤ)
⊢ x✝ = 1 → ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
[PROOFSTEP]
intro h
[GOAL]
case h.mpr
N : ℕ
x✝ : SL(2, ℤ)
h : x✝ = 1
⊢ ↑(↑x✝ 0 0) = 1 ∧ ↑(↑x✝ 0 1) = 0 ∧ ↑(↑x✝ 1 0) = 0 ∧ ↑(↑x✝ 1 1) = 1
[PROOFSTEP]
simp [h]
[GOAL]
N✝ N : ℕ
⊢ ∀ {a b : SL(2, ℤ)}, a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}
[PROOFSTEP]
intro a b ha hb
[GOAL]
N✝ N : ℕ
a b : SL(2, ℤ)
ha : a ∈ {g | ↑(↑g 1 0) = 0}
hb : b ∈ {g | ↑(↑g 1 0) = 0}
⊢ a * b ∈ {g | ↑(↑g 1 0) = 0}
[PROOFSTEP]
simp only [Set.mem_setOf_eq]
[GOAL]
N✝ N : ℕ
a b : SL(2, ℤ)
ha : a ∈ {g | ↑(↑g 1 0) = 0}
hb : b ∈ {g | ↑(↑g 1 0) = 0}
⊢ ↑(↑(a * b) 1 0) = 0
[PROOFSTEP]
have h := (Matrix.two_mul_expl a.1 b.1).2.2.1
[GOAL]
N✝ N : ℕ
a b : SL(2, ℤ)
ha : a ∈ {g | ↑(↑g 1 0) = 0}
hb : b ∈ {g | ↑(↑g 1 0) = 0}
h : (↑a * ↑b) 1 0 = ↑a 1 0 * ↑b 0 0 + ↑a 1 1 * ↑b 1 0
⊢ ↑(↑(a * b) 1 0) = 0
[PROOFSTEP]
simp only [coe_matrix_coe, coe_mul, Int.coe_castRingHom, map_apply, Set.mem_setOf_eq] at *
[GOAL]
N✝ N : ℕ
a b : SL(2, ℤ)
ha : ↑(↑a 1 0) = 0
hb : ↑(↑b 1 0) = 0
h : (↑a * ↑b) 1 0 = ↑a 1 0 * ↑b 0 0 + ↑a 1 1 * ↑b 1 0
⊢ ↑((↑a * ↑b) 1 0) = 0
[PROOFSTEP]
rw [h]
[GOAL]
N✝ N : ℕ
a b : SL(2, ℤ)
ha : ↑(↑a 1 0) = 0
hb : ↑(↑b 1 0) = 0
h : (↑a * ↑b) 1 0 = ↑a 1 0 * ↑b 0 0 + ↑a 1 1 * ↑b 1 0
⊢ ↑(↑a 1 0 * ↑b 0 0 + ↑a 1 1 * ↑b 1 0) = 0
[PROOFSTEP]
simp [ha, hb]
[GOAL]
N✝ N : ℕ
⊢ 1 ∈
    { carrier := {g | ↑(↑g 1 0) = 0},
        mul_mem' :=
          (_ :
            ∀ {a b : SL(2, ℤ)},
              a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) }.carrier
[PROOFSTEP]
simp
[GOAL]
N✝ N : ℕ
⊢ ∀ {x : SL(2, ℤ)},
    x ∈
        {
              toSubsemigroup :=
                { carrier := {g | ↑(↑g 1 0) = 0},
                  mul_mem' :=
                    (_ :
                      ∀ {a b : SL(2, ℤ)},
                        a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) },
              one_mem' := (_ : ↑(OfNat.ofNat 1 1 0) = 0) }.toSubsemigroup.carrier →
      x⁻¹ ∈
        {
              toSubsemigroup :=
                { carrier := {g | ↑(↑g 1 0) = 0},
                  mul_mem' :=
                    (_ :
                      ∀ {a b : SL(2, ℤ)},
                        a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) },
              one_mem' := (_ : ↑(OfNat.ofNat 1 1 0) = 0) }.toSubsemigroup.carrier
[PROOFSTEP]
intro a ha
[GOAL]
N✝ N : ℕ
a : SL(2, ℤ)
ha :
  a ∈
    {
          toSubsemigroup :=
            { carrier := {g | ↑(↑g 1 0) = 0},
              mul_mem' :=
                (_ :
                  ∀ {a b : SL(2, ℤ)},
                    a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) },
          one_mem' := (_ : ↑(OfNat.ofNat 1 1 0) = 0) }.toSubsemigroup.carrier
⊢ a⁻¹ ∈
    {
          toSubsemigroup :=
            { carrier := {g | ↑(↑g 1 0) = 0},
              mul_mem' :=
                (_ :
                  ∀ {a b : SL(2, ℤ)},
                    a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) },
          one_mem' := (_ : ↑(OfNat.ofNat 1 1 0) = 0) }.toSubsemigroup.carrier
[PROOFSTEP]
simp only [Set.mem_setOf_eq]
[GOAL]
N✝ N : ℕ
a : SL(2, ℤ)
ha :
  a ∈
    {
          toSubsemigroup :=
            { carrier := {g | ↑(↑g 1 0) = 0},
              mul_mem' :=
                (_ :
                  ∀ {a b : SL(2, ℤ)},
                    a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) },
          one_mem' := (_ : ↑(OfNat.ofNat 1 1 0) = 0) }.toSubsemigroup.carrier
⊢ ↑(↑a⁻¹ 1 0) = 0
[PROOFSTEP]
rw [SL2_inv_expl a]
[GOAL]
N✝ N : ℕ
a : SL(2, ℤ)
ha :
  a ∈
    {
          toSubsemigroup :=
            { carrier := {g | ↑(↑g 1 0) = 0},
              mul_mem' :=
                (_ :
                  ∀ {a b : SL(2, ℤ)},
                    a ∈ {g | ↑(↑g 1 0) = 0} → b ∈ {g | ↑(↑g 1 0) = 0} → a * b ∈ {g | ↑(↑g 1 0) = 0}) },
          one_mem' := (_ : ↑(OfNat.ofNat 1 1 0) = 0) }.toSubsemigroup.carrier
⊢ ↑(↑{ val := ![![↑a 1 1, -↑a 0 1], ![-↑a 1 0, ↑a 0 0]],
            property := (_ : det ![![↑a 1 1, -↑a 0 1], ![-↑a 1 0, ↑a 0 0]] = 1) }
        1 0) =
    0
[PROOFSTEP]
simp only [cons_val_zero, cons_val_one, head_cons, coe_matrix_coe, coe_mk, Int.coe_castRingHom, map_apply, Int.cast_neg,
  neg_eq_zero, Set.mem_setOf_eq] at *
[GOAL]
N✝ N : ℕ
a : SL(2, ℤ)
ha : ↑(↑a 1 0) = 0
⊢ ↑(↑a 1 0) = 0
[PROOFSTEP]
exact ha
[GOAL]
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
⊢ ↑(det ↑↑A) = 1
[PROOFSTEP]
simp [A.1.property]
[GOAL]
N✝ N : ℕ
⊢ (fun g => ↑(↑↑g 1 1)) 1 = 1
[PROOFSTEP]
simp
[GOAL]
N✝ N : ℕ
⊢ ∀ (x y : { x // x ∈ Gamma0 N }),
    OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } (x * y) =
      OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } x *
        OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } y
[PROOFSTEP]
intro A B
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
⊢ OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } (A * B) =
    OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } A *
      OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } B
[PROOFSTEP]
have := (two_mul_expl A.1.1 B.1.1).2.2.2
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
this : (↑↑A * ↑↑B) 1 1 = ↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1
⊢ OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } (A * B) =
    OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } A *
      OneHom.toFun { toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } B
[PROOFSTEP]
simp only [Subgroup.coe_mul, coe_matrix_coe, coe_mul, Int.coe_castRingHom, map_apply] at *
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
this : (↑↑A * ↑↑B) 1 1 = ↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1
⊢ ↑((↑↑A * ↑↑B) 1 1) = ↑(↑↑A 1 1) * ↑(↑↑B 1 1)
[PROOFSTEP]
rw [this]
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
this : (↑↑A * ↑↑B) 1 1 = ↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1
⊢ ↑(↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1) = ↑(↑↑A 1 1) * ↑(↑↑B 1 1)
[PROOFSTEP]
have ha := A.property
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
this : (↑↑A * ↑↑B) 1 1 = ↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1
ha : ↑A ∈ Gamma0 N
⊢ ↑(↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1) = ↑(↑↑A 1 1) * ↑(↑↑B 1 1)
[PROOFSTEP]
simp only [Int.cast_add, Int.cast_mul, add_left_eq_self, Gamma0_mem, coe_matrix_coe, Int.coe_castRingHom,
  map_apply] at *
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
this : (↑↑A * ↑↑B) 1 1 = ↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1
ha : ↑(↑↑A 1 0) = 0
⊢ ↑(↑↑A 1 0) * ↑(↑↑B 0 1) = 0
[PROOFSTEP]
rw [ha]
[GOAL]
N✝ N : ℕ
A B : { x // x ∈ Gamma0 N }
this : (↑↑A * ↑↑B) 1 1 = ↑↑A 1 0 * ↑↑B 0 1 + ↑↑A 1 1 * ↑↑B 1 1
ha : ↑(↑↑A 1 0) = 0
⊢ 0 * ↑(↑↑B 0 1) = 0
[PROOFSTEP]
simp
[GOAL]
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
⊢ A ∈ Gamma1' N ↔ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
constructor
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
⊢ A ∈ Gamma1' N → ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
intro ha
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : A ∈ Gamma1' N
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
have hA := A.property
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : A ∈ Gamma1' N
hA : ↑A ∈ Gamma0 N
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
rw [Gamma0_mem] at hA
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : A ∈ Gamma1' N
hA : ↑(↑↑A 1 0) = 0
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
have adet := Gamma0_det N A
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : A ∈ Gamma1' N
hA : ↑(↑↑A 1 0) = 0
adet : ↑(det ↑↑A) = 1
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
rw [Matrix.det_fin_two] at adet
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : A ∈ Gamma1' N
hA : ↑(↑↑A 1 0) = 0
adet : ↑(↑↑A 0 0 * ↑↑A 1 1 - ↑↑A 0 1 * ↑↑A 1 0) = 1
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
simp only [Gamma0Map, coe_matrix_coe, Int.coe_castRingHom, map_apply, Gamma1_mem', MonoidHom.coe_mk, OneHom.coe_mk,
  Int.cast_sub, Int.cast_mul] at *
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
hA : ↑(↑↑A 1 0) = 0
ha : ↑(↑↑A 1 1) = 1
adet : ↑(↑↑A 0 0) * ↑(↑↑A 1 1) - ↑(↑↑A 0 1) * ↑(↑↑A 1 0) = 1
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
rw [hA, ha] at adet
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
hA : ↑(↑↑A 1 0) = 0
ha : ↑(↑↑A 1 1) = 1
adet : ↑(↑↑A 0 0) * 1 - ↑(↑↑A 0 1) * 0 = 1
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
simp only [mul_one, mul_zero, sub_zero] at adet
[GOAL]
case mp
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
hA : ↑(↑↑A 1 0) = 0
ha : ↑(↑↑A 1 1) = 1
adet : ↑(↑↑A 0 0) = 1
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
[PROOFSTEP]
simp only [adet, hA, ha, eq_self_iff_true, and_self_iff]
[GOAL]
case mpr
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
⊢ ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0 → A ∈ Gamma1' N
[PROOFSTEP]
intro ha
[GOAL]
case mpr
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
⊢ A ∈ Gamma1' N
[PROOFSTEP]
simp only [Gamma1_mem', Gamma0Map, MonoidHom.coe_mk, coe_matrix_coe, Int.coe_castRingHom, map_apply]
[GOAL]
case mpr
N✝ N : ℕ
A : { x // x ∈ Gamma0 N }
ha : ↑(↑↑A 0 0) = 1 ∧ ↑(↑↑A 1 1) = 1 ∧ ↑(↑↑A 1 0) = 0
⊢ ↑{ toFun := fun g => ↑(↑↑g 1 1), map_one' := (_ : ↑(OfNat.ofNat 1 1 1) = 1) } A = 1
[PROOFSTEP]
exact ha.2.1
[GOAL]
N✝ N : ℕ
A : SL(2, ℤ)
⊢ A ∈ Gamma1 N ↔ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
constructor
[GOAL]
case mp
N✝ N : ℕ
A : SL(2, ℤ)
⊢ A ∈ Gamma1 N → ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
intro ha
[GOAL]
case mp
N✝ N : ℕ
A : SL(2, ℤ)
ha : A ∈ Gamma1 N
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
simp_rw [Gamma1, Subgroup.mem_map] at ha
[GOAL]
case mp
N✝ N : ℕ
A : SL(2, ℤ)
ha : ∃ x, x ∈ ⊤ ∧ ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) x = A
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
obtain ⟨⟨x, hx⟩, hxx⟩ := ha
[GOAL]
case mp.intro.mk
N✝ N : ℕ
A : SL(2, ℤ)
x : { x // x ∈ Gamma0 N }
hx : x ∈ Gamma1' N
hxx :
  { val := x, property := hx } ∈ ⊤ ∧
    ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx } = A
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
rw [Gamma1_to_Gamma0_mem] at hx
[GOAL]
case mp.intro.mk
N✝ N : ℕ
A : SL(2, ℤ)
x : { x // x ∈ Gamma0 N }
hx✝ : x ∈ Gamma1' N
hx : ↑(↑↑x 0 0) = 1 ∧ ↑(↑↑x 1 1) = 1 ∧ ↑(↑↑x 1 0) = 0
hxx :
  { val := x, property := hx✝ } ∈ ⊤ ∧
    ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx✝ } = A
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
simp only [Subgroup.mem_top, true_and] at hxx
[GOAL]
case mp.intro.mk
N✝ N : ℕ
A : SL(2, ℤ)
x : { x // x ∈ Gamma0 N }
hx✝ : x ∈ Gamma1' N
hx : ↑(↑↑x 0 0) = 1 ∧ ↑(↑↑x 1 1) = 1 ∧ ↑(↑↑x 1 0) = 0
hxx : ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx✝ } = A
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
rw [← hxx]
[GOAL]
case mp.intro.mk
N✝ N : ℕ
A : SL(2, ℤ)
x : { x // x ∈ Gamma0 N }
hx✝ : x ∈ Gamma1' N
hx : ↑(↑↑x 0 0) = 1 ∧ ↑(↑↑x 1 1) = 1 ∧ ↑(↑↑x 1 0) = 0
hxx : ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx✝ } = A
⊢ ↑(↑(↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx✝ }) 0
          0) =
      1 ∧
    ↑(↑(↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx✝ }) 1
            1) =
        1 ∧
      ↑(↑(↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) { val := x, property := hx✝ })
            1 0) =
        0
[PROOFSTEP]
convert hx
[GOAL]
case mpr
N✝ N : ℕ
A : SL(2, ℤ)
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0 → A ∈ Gamma1 N
[PROOFSTEP]
intro ha
[GOAL]
case mpr
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
⊢ A ∈ Gamma1 N
[PROOFSTEP]
simp_rw [Gamma1, Subgroup.mem_map]
[GOAL]
case mpr
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
⊢ ∃ x, x ∈ ⊤ ∧ ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) x = A
[PROOFSTEP]
have hA : A ∈ Gamma0 N := by simp [ha.right.right, Gamma0_mem]
[GOAL]
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
⊢ A ∈ Gamma0 N
[PROOFSTEP]
simp [ha.right.right, Gamma0_mem]
[GOAL]
case mpr
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
hA : A ∈ Gamma0 N
⊢ ∃ x, x ∈ ⊤ ∧ ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) x = A
[PROOFSTEP]
have HA : (⟨A, hA⟩ : Gamma0 N) ∈ Gamma1' N :=
  by
  simp only [Gamma1_to_Gamma0_mem, Subgroup.coe_mk, coe_matrix_coe, Int.coe_castRingHom, map_apply]
  exact ha
[GOAL]
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
hA : A ∈ Gamma0 N
⊢ { val := A, property := hA } ∈ Gamma1' N
[PROOFSTEP]
simp only [Gamma1_to_Gamma0_mem, Subgroup.coe_mk, coe_matrix_coe, Int.coe_castRingHom, map_apply]
[GOAL]
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
hA : A ∈ Gamma0 N
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
exact ha
[GOAL]
case mpr
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
hA : A ∈ Gamma0 N
HA : { val := A, property := hA } ∈ Gamma1' N
⊢ ∃ x, x ∈ ⊤ ∧ ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N))) x = A
[PROOFSTEP]
refine' ⟨(⟨(⟨A, hA⟩ : Gamma0 N), HA⟩ : (Gamma1' N : Subgroup (Gamma0 N))), _⟩
[GOAL]
case mpr
N✝ N : ℕ
A : SL(2, ℤ)
ha : ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
hA : A ∈ Gamma0 N
HA : { val := A, property := hA } ∈ Gamma1' N
⊢ { val := { val := A, property := hA }, property := HA } ∈ ⊤ ∧
    ↑(MonoidHom.comp (Subgroup.subtype (Gamma0 N)) (Subgroup.subtype (Gamma1' N)))
        { val := { val := A, property := hA }, property := HA } =
      A
[PROOFSTEP]
simp
[GOAL]
N✝ N : ℕ
⊢ Gamma1 N ≤ Gamma0 N
[PROOFSTEP]
intro x HA
[GOAL]
N✝ N : ℕ
x : SL(2, ℤ)
HA : x ∈ Gamma1 N
⊢ x ∈ Gamma0 N
[PROOFSTEP]
simp only [Gamma0_mem, Gamma1_mem, coe_matrix_coe, Int.coe_castRingHom, map_apply] at *
[GOAL]
N✝ N : ℕ
x : SL(2, ℤ)
HA : ↑(↑x 0 0) = 1 ∧ ↑(↑x 1 1) = 1 ∧ ↑(↑x 1 0) = 0
⊢ ↑(↑x 1 0) = 0
[PROOFSTEP]
exact HA.2.2
[GOAL]
N : ℕ
H K : Subgroup SL(2, ℤ)
h : H ≤ K
h2 : IsCongruenceSubgroup H
⊢ IsCongruenceSubgroup K
[PROOFSTEP]
obtain ⟨N, hN⟩ := h2
[GOAL]
case intro
N✝ : ℕ
H K : Subgroup SL(2, ℤ)
h : H ≤ K
N : ℕ+
hN : Gamma ↑N ≤ H
⊢ IsCongruenceSubgroup K
[PROOFSTEP]
refine' ⟨N, le_trans hN h⟩
[GOAL]
N✝ : ℕ
N : ℕ+
⊢ Gamma ↑N ≤ Gamma ↑N
[PROOFSTEP]
simp only [le_refl]
[GOAL]
N✝ : ℕ
N : ℕ+
⊢ IsCongruenceSubgroup (Gamma1 ↑N)
[PROOFSTEP]
refine' ⟨N, _⟩
[GOAL]
N✝ : ℕ
N : ℕ+
⊢ Gamma ↑N ≤ Gamma1 ↑N
[PROOFSTEP]
intro A hA
[GOAL]
N✝ : ℕ
N : ℕ+
A : SL(2, ℤ)
hA : A ∈ Gamma ↑N
⊢ A ∈ Gamma1 ↑N
[PROOFSTEP]
simp only [Gamma1_mem, Gamma_mem] at *
[GOAL]
N✝ : ℕ
N : ℕ+
A : SL(2, ℤ)
hA : ↑(↑A 0 0) = 1 ∧ ↑(↑A 0 1) = 0 ∧ ↑(↑A 1 0) = 0 ∧ ↑(↑A 1 1) = 1
⊢ ↑(↑A 0 0) = 1 ∧ ↑(↑A 1 1) = 1 ∧ ↑(↑A 1 0) = 0
[PROOFSTEP]
simp only [hA, eq_self_iff_true, and_self_iff]
[GOAL]
N✝ N : ℕ
g : ConjAct SL(2, ℤ)
⊢ g • Gamma N = Gamma N
[PROOFSTEP]
apply Subgroup.Normal.conjAct (Gamma_normal N)
[GOAL]
N : ℕ
g : ConjAct SL(2, ℤ)
Γ : Subgroup SL(2, ℤ)
h : IsCongruenceSubgroup Γ
⊢ IsCongruenceSubgroup (g • Γ)
[PROOFSTEP]
obtain ⟨N, HN⟩ := h
[GOAL]
case intro
N✝ : ℕ
g : ConjAct SL(2, ℤ)
Γ : Subgroup SL(2, ℤ)
N : ℕ+
HN : Gamma ↑N ≤ Γ
⊢ IsCongruenceSubgroup (g • Γ)
[PROOFSTEP]
refine' ⟨N, _⟩
[GOAL]
case intro
N✝ : ℕ
g : ConjAct SL(2, ℤ)
Γ : Subgroup SL(2, ℤ)
N : ℕ+
HN : Gamma ↑N ≤ Γ
⊢ Gamma ↑N ≤ g • Γ
[PROOFSTEP]
rw [← Gamma_cong_eq_self N g, Subgroup.pointwise_smul_le_pointwise_smul_iff]
[GOAL]
case intro
N✝ : ℕ
g : ConjAct SL(2, ℤ)
Γ : Subgroup SL(2, ℤ)
N : ℕ+
HN : Gamma ↑N ≤ Γ
⊢ Gamma ↑N ≤ Γ
[PROOFSTEP]
exact HN


[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommMonoid α
s : Interval α
⊢ Option.map (fun b => NonemptyInterval.pure 1 * b) s = s
[PROOFSTEP]
simp_rw [NonemptyInterval.pure_one, one_mul, ← id_def, Option.map_id, id]
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommMonoid α
s : Interval α
⊢ Option.map (fun a => a * NonemptyInterval.pure 1) s = s
[PROOFSTEP]
simp_rw [NonemptyInterval.pure_one, mul_one, ← id_def, Option.map_id, id]
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
⊢ s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
refine' ⟨fun h => _, _⟩
[GOAL]
case refine'_1
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : s * t = 1
⊢ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
rw [ext_iff, Prod.ext_iff] at h
[GOAL]
case refine'_1
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
⊢ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
have := (mul_le_mul_iff_of_ge s.fst_le_snd t.fst_le_snd).1 (h.2.trans h.1.symm).le
[GOAL]
case refine'_1
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
refine' ⟨s.fst, t.fst, _, _, h.1⟩
[GOAL]
case refine'_1.refine'_1
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ s = pure s.fst
[PROOFSTEP]
apply NonemptyInterval.ext
[GOAL]
case refine'_1.refine'_2
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ t = pure t.fst
[PROOFSTEP]
apply NonemptyInterval.ext
[GOAL]
case refine'_1.refine'_1.h
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ s.toProd = (pure s.fst).toProd
[PROOFSTEP]
dsimp [pure]
[GOAL]
case refine'_1.refine'_2.h
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ t.toProd = (pure t.fst).toProd
[PROOFSTEP]
dsimp [pure]
[GOAL]
case refine'_1.refine'_1.h
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ s.toProd = (s.fst, s.fst)
[PROOFSTEP]
nth_rw 2 [this.1]
[GOAL]
case refine'_1.refine'_2.h
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
h : (s * t).fst = 1.fst ∧ (s * t).snd = 1.snd
this : s.fst = s.snd ∧ t.fst = t.snd
⊢ t.toProd = (t.fst, t.fst)
[PROOFSTEP]
nth_rw 2 [this.2]
[GOAL]
case refine'_2
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
⊢ (∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1) → s * t = 1
[PROOFSTEP]
rintro ⟨b, c, rfl, rfl, h⟩
[GOAL]
case refine'_2.intro.intro.intro.intro
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
b c : α
h : b * c = 1
⊢ pure b * pure c = 1
[PROOFSTEP]
rw [pure_mul_pure, h, pure_one]
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
⊢ s - t = s + -t
[PROOFSTEP]
refine NonemptyInterval.ext _ _ (Prod.ext ?_ ?_)
[GOAL]
case refine_1
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
⊢ (s - t).fst = (s + -t).fst
[PROOFSTEP]
exact sub_eq_add_neg _ _
[GOAL]
case refine_2
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
⊢ (s - t).snd = (s + -t).snd
[PROOFSTEP]
exact sub_eq_add_neg _ _
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s : NonemptyInterval α
⊢ - -s = s
[PROOFSTEP]
apply NonemptyInterval.ext
[GOAL]
case h
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s : NonemptyInterval α
⊢ (- -s).toProd = s.toProd
[PROOFSTEP]
exact neg_neg _
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
⊢ -(s + t) = -t + -s
[PROOFSTEP]
refine NonemptyInterval.ext _ _ (Prod.ext ?_ ?_)
[GOAL]
case refine_1
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
⊢ (-(s + t)).fst = (-t + -s).fst
[PROOFSTEP]
exact neg_add_rev _ _
[GOAL]
case refine_2
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
⊢ (-(s + t)).snd = (-t + -s).snd
[PROOFSTEP]
exact neg_add_rev _ _
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
s t : NonemptyInterval α
h : s + t = 0
⊢ -s = t
[PROOFSTEP]
obtain ⟨a, b, rfl, rfl, hab⟩ := NonemptyInterval.add_eq_zero_iff.1 h
[GOAL]
case intro.intro.intro.intro
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : NonemptyInterval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (NonemptyInterval α) := addCommMonoid
a b : α
hab : a + b = 0
h : pure a + pure b = 0
⊢ -pure a = pure b
[PROOFSTEP]
rw [neg_pure, neg_eq_of_add_eq_zero_right hab]
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
⊢ s / t = s * t⁻¹
[PROOFSTEP]
refine NonemptyInterval.ext _ _ (Prod.ext ?_ ?_)
[GOAL]
case refine_1
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
⊢ (s / t).fst = (s * t⁻¹).fst
[PROOFSTEP]
exact div_eq_mul_inv _ _
[GOAL]
case refine_2
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
⊢ (s / t).snd = (s * t⁻¹).snd
[PROOFSTEP]
exact div_eq_mul_inv _ _
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s : NonemptyInterval α
⊢ s⁻¹⁻¹ = s
[PROOFSTEP]
apply NonemptyInterval.ext
[GOAL]
case h
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s : NonemptyInterval α
⊢ s⁻¹⁻¹.toProd = s.toProd
[PROOFSTEP]
exact inv_inv _
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
⊢ (s * t)⁻¹ = t⁻¹ * s⁻¹
[PROOFSTEP]
refine NonemptyInterval.ext _ _ (Prod.ext ?_ ?_)
[GOAL]
case refine_1
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
⊢ (s * t)⁻¹.fst = (t⁻¹ * s⁻¹).fst
[PROOFSTEP]
exact mul_inv_rev _ _
[GOAL]
case refine_2
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
⊢ (s * t)⁻¹.snd = (t⁻¹ * s⁻¹).snd
[PROOFSTEP]
exact mul_inv_rev _ _
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
s t : NonemptyInterval α
h : s * t = 1
⊢ s⁻¹ = t
[PROOFSTEP]
obtain ⟨a, b, rfl, rfl, hab⟩ := NonemptyInterval.mul_eq_one_iff.1 h
[GOAL]
case intro.intro.intro.intro
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : NonemptyInterval α
src✝ : CommMonoid (NonemptyInterval α) := commMonoid
a b : α
hab : a * b = 1
h : pure a * pure b = 1
⊢ (pure a)⁻¹ = pure b
[PROOFSTEP]
rw [inv_pure, inv_eq_of_mul_eq_one_right hab]
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
⊢ s * t = 1 ↔ ∃ a b, s = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
cases s
[GOAL]
case none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
t : Interval α
⊢ none * t = 1 ↔ ∃ a b, none = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
simp [WithBot.none_eq_bot]
[GOAL]
case some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
t : Interval α
val✝ : NonemptyInterval α
⊢ some val✝ * t = 1 ↔ ∃ a b, some val✝ = pure a ∧ t = pure b ∧ a * b = 1
[PROOFSTEP]
cases t
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
val✝ : NonemptyInterval α
⊢ some val✝ * none = 1 ↔ ∃ a b, some val✝ = pure a ∧ none = pure b ∧ a * b = 1
[PROOFSTEP]
simp [WithBot.none_eq_bot]
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
val✝¹ val✝ : NonemptyInterval α
⊢ some val✝¹ * some val✝ = 1 ↔ ∃ a b, some val✝¹ = pure a ∧ some val✝ = pure b ∧ a * b = 1
[PROOFSTEP]
simp_rw [WithBot.some_eq_coe, ← NonemptyInterval.coe_mul_interval, ← NonemptyInterval.coe_one_interval, WithBot.coe_inj,
  NonemptyInterval.coe_eq_pure]
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
val✝¹ val✝ : NonemptyInterval α
⊢ val✝¹ * val✝ = 1 ↔ ∃ a b, val✝¹ = NonemptyInterval.pure a ∧ val✝ = NonemptyInterval.pure b ∧ a * b = 1
[PROOFSTEP]
exact NonemptyInterval.mul_eq_one_iff
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ ∀ (a b : Interval α), a - b = a + -b
[PROOFSTEP]
rintro (_ | s) (_ | t)
[GOAL]
case none.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ none - none = none + -none
[PROOFSTEP]
first
| rfl
| exact congr_arg some (sub_eq_add_neg _ _)
[GOAL]
case none.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ none - none = none + -none
[PROOFSTEP]
rfl
[GOAL]
case none.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
t : NonemptyInterval α
⊢ none - some t = none + -some t
[PROOFSTEP]
first
| rfl
| exact congr_arg some (sub_eq_add_neg _ _)
[GOAL]
case none.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
t : NonemptyInterval α
⊢ none - some t = none + -some t
[PROOFSTEP]
rfl
[GOAL]
case some.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ some s - none = some s + -none
[PROOFSTEP]
first
| rfl
| exact congr_arg some (sub_eq_add_neg _ _)
[GOAL]
case some.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ some s - none = some s + -none
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
⊢ some s - some t = some s + -some t
[PROOFSTEP]
first
| rfl
| exact congr_arg some (sub_eq_add_neg _ _)
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
⊢ some s - some t = some s + -some t
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
⊢ some s - some t = some s + -some t
[PROOFSTEP]
exact congr_arg some (sub_eq_add_neg _ _)
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ ∀ (x : Interval α), - -x = x
[PROOFSTEP]
rintro (_ | s)
[GOAL]
case none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ - -none = none
[PROOFSTEP]
first
| rfl
| exact congr_arg some (neg_neg _)
[GOAL]
case none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ - -none = none
[PROOFSTEP]
rfl
[GOAL]
case some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ - -some s = some s
[PROOFSTEP]
first
| rfl
| exact congr_arg some (neg_neg _)
[GOAL]
case some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ - -some s = some s
[PROOFSTEP]
rfl
[GOAL]
case some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ - -some s = some s
[PROOFSTEP]
exact congr_arg some (neg_neg _)
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ ∀ (a b : Interval α), -(a + b) = -b + -a
[PROOFSTEP]
rintro (_ | s) (_ | t)
[GOAL]
case none.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ -(none + none) = -none + -none
[PROOFSTEP]
first
| rfl
| exact congr_arg some (neg_add_rev _ _)
[GOAL]
case none.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ -(none + none) = -none + -none
[PROOFSTEP]
rfl
[GOAL]
case none.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
t : NonemptyInterval α
⊢ -(none + some t) = -some t + -none
[PROOFSTEP]
first
| rfl
| exact congr_arg some (neg_add_rev _ _)
[GOAL]
case none.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
t : NonemptyInterval α
⊢ -(none + some t) = -some t + -none
[PROOFSTEP]
rfl
[GOAL]
case some.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ -(some s + none) = -none + -some s
[PROOFSTEP]
first
| rfl
| exact congr_arg some (neg_add_rev _ _)
[GOAL]
case some.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
⊢ -(some s + none) = -none + -some s
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
⊢ -(some s + some t) = -some t + -some s
[PROOFSTEP]
first
| rfl
| exact congr_arg some (neg_add_rev _ _)
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
⊢ -(some s + some t) = -some t + -some s
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
⊢ -(some s + some t) = -some t + -some s
[PROOFSTEP]
exact congr_arg some (neg_add_rev _ _)
[GOAL]
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
⊢ ∀ (a b : Interval α), a + b = 0 → -a = b
[PROOFSTEP]
rintro (_ | s) (_ | t) h
[GOAL]
case none.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
h : none + none = 0
⊢ -none = none
[PROOFSTEP]
first
| cases h
| exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h)
[GOAL]
case none.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
h : none + none = 0
⊢ -none = none
[PROOFSTEP]
cases h
[GOAL]
case none.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
t : NonemptyInterval α
h : none + some t = 0
⊢ -none = some t
[PROOFSTEP]
first
| cases h
| exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h)
[GOAL]
case none.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
t : NonemptyInterval α
h : none + some t = 0
⊢ -none = some t
[PROOFSTEP]
cases h
[GOAL]
case some.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
h : some s + none = 0
⊢ -some s = none
[PROOFSTEP]
first
| cases h
| exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h)
[GOAL]
case some.none
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s : NonemptyInterval α
h : some s + none = 0
⊢ -some s = none
[PROOFSTEP]
cases h
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
h : some s + some t = 0
⊢ -some s = some t
[PROOFSTEP]
first
| cases h
| exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h)
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
h : some s + some t = 0
⊢ -some s = some t
[PROOFSTEP]
cases h
[GOAL]
case some.some
ι : Type u_1
α✝ : Type u_2
inst✝¹ : OrderedCommGroup α✝
s✝ t✝ : Interval α✝
α : Type u
inst✝ : OrderedAddCommGroup α
src✝ : AddCommMonoid (Interval α) := addCommMonoid
s t : NonemptyInterval α
h : some s + some t = 0
⊢ -some s = some t
[PROOFSTEP]
exact congr_arg some (neg_eq_of_add_eq_zero_right <| Option.some_injective _ h)
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ ∀ (a b : Interval α), a / b = a * b⁻¹
[PROOFSTEP]
rintro (_ | s) (_ | t)
[GOAL]
case none.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ none / none = none * none⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (div_eq_mul_inv _ _)
[GOAL]
case none.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ none / none = none * none⁻¹
[PROOFSTEP]
rfl
[GOAL]
case none.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
t : NonemptyInterval α
⊢ none / some t = none * (some t)⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (div_eq_mul_inv _ _)
[GOAL]
case none.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
t : NonemptyInterval α
⊢ none / some t = none * (some t)⁻¹
[PROOFSTEP]
rfl
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ some s / none = some s * none⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (div_eq_mul_inv _ _)
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ some s / none = some s * none⁻¹
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
⊢ some s / some t = some s * (some t)⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (div_eq_mul_inv _ _)
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
⊢ some s / some t = some s * (some t)⁻¹
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
⊢ some s / some t = some s * (some t)⁻¹
[PROOFSTEP]
exact congr_arg some (div_eq_mul_inv _ _)
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ ∀ (x : Interval α), x⁻¹⁻¹ = x
[PROOFSTEP]
rintro (_ | s)
[GOAL]
case none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ none⁻¹⁻¹ = none
[PROOFSTEP]
first
| rfl
| exact congr_arg some (inv_inv _)
[GOAL]
case none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ none⁻¹⁻¹ = none
[PROOFSTEP]
rfl
[GOAL]
case some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ (some s)⁻¹⁻¹ = some s
[PROOFSTEP]
first
| rfl
| exact congr_arg some (inv_inv _)
[GOAL]
case some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ (some s)⁻¹⁻¹ = some s
[PROOFSTEP]
rfl
[GOAL]
case some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ (some s)⁻¹⁻¹ = some s
[PROOFSTEP]
exact congr_arg some (inv_inv _)
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ ∀ (a b : Interval α), (a * b)⁻¹ = b⁻¹ * a⁻¹
[PROOFSTEP]
rintro (_ | s) (_ | t)
[GOAL]
case none.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ (none * none)⁻¹ = none⁻¹ * none⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (mul_inv_rev _ _)
[GOAL]
case none.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ (none * none)⁻¹ = none⁻¹ * none⁻¹
[PROOFSTEP]
rfl
[GOAL]
case none.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
t : NonemptyInterval α
⊢ (none * some t)⁻¹ = (some t)⁻¹ * none⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (mul_inv_rev _ _)
[GOAL]
case none.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
t : NonemptyInterval α
⊢ (none * some t)⁻¹ = (some t)⁻¹ * none⁻¹
[PROOFSTEP]
rfl
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ (some s * none)⁻¹ = none⁻¹ * (some s)⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (mul_inv_rev _ _)
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
⊢ (some s * none)⁻¹ = none⁻¹ * (some s)⁻¹
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
⊢ (some s * some t)⁻¹ = (some t)⁻¹ * (some s)⁻¹
[PROOFSTEP]
first
| rfl
| exact congr_arg some (mul_inv_rev _ _)
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
⊢ (some s * some t)⁻¹ = (some t)⁻¹ * (some s)⁻¹
[PROOFSTEP]
rfl
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
⊢ (some s * some t)⁻¹ = (some t)⁻¹ * (some s)⁻¹
[PROOFSTEP]
exact congr_arg some (mul_inv_rev _ _)
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
⊢ ∀ (a b : Interval α), a * b = 1 → a⁻¹ = b
[PROOFSTEP]
rintro (_ | s) (_ | t) h
[GOAL]
case none.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
h : none * none = 1
⊢ none⁻¹ = none
[PROOFSTEP]
first
| cases h
| exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h)
[GOAL]
case none.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
h : none * none = 1
⊢ none⁻¹ = none
[PROOFSTEP]
cases h
[GOAL]
case none.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
t : NonemptyInterval α
h : none * some t = 1
⊢ none⁻¹ = some t
[PROOFSTEP]
first
| cases h
| exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h)
[GOAL]
case none.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
t : NonemptyInterval α
h : none * some t = 1
⊢ none⁻¹ = some t
[PROOFSTEP]
cases h
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
h : some s * none = 1
⊢ (some s)⁻¹ = none
[PROOFSTEP]
first
| cases h
| exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h)
[GOAL]
case some.none
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s : NonemptyInterval α
h : some s * none = 1
⊢ (some s)⁻¹ = none
[PROOFSTEP]
cases h
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
h : some s * some t = 1
⊢ (some s)⁻¹ = some t
[PROOFSTEP]
first
| cases h
| exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h)
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
h : some s * some t = 1
⊢ (some s)⁻¹ = some t
[PROOFSTEP]
cases h
[GOAL]
case some.some
ι : Type u_1
α : Type u_2
inst✝ : OrderedCommGroup α
s✝ t✝ : Interval α
src✝ : CommMonoid (Interval α) := commMonoid
s t : NonemptyInterval α
h : some s * some t = 1
⊢ (some s)⁻¹ = some t
[PROOFSTEP]
exact congr_arg some (inv_eq_of_mul_eq_one_right <| Option.some_injective _ h)
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s t : NonemptyInterval α
a : α
⊢ length (s - t) = length s + length t
[PROOFSTEP]
simp [sub_eq_add_neg]
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s t : Interval α
a : α
x✝ : Interval α
⊢ length (⊥ + x✝) ≤ length ⊥ + length x✝
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s t : Interval α
a : α
x✝ : Interval α
⊢ length (x✝ + ⊥) ≤ length x✝ + length ⊥
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s t : Interval α
a : α
⊢ length (s - t) ≤ length s + length t
[PROOFSTEP]
simpa [sub_eq_add_neg] using length_add_le s (-t)
[GOAL]
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s✝ t : Interval α
a : α
f : ι → Interval α
s : Finset ι
⊢ length (∑ i in s, f i) ≤ ∑ i in s, length (f i)
[PROOFSTEP]
apply Finset.le_sum_of_subadditive
[GOAL]
case h_one
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s✝ t : Interval α
a : α
f : ι → Interval α
s : Finset ι
⊢ length 0 = 0
case h_mul
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s✝ t : Interval α
a : α
f : ι → Interval α
s : Finset ι
⊢ ∀ (x y : Interval α), length (x + y) ≤ length x + length y
[PROOFSTEP]
exact length_zero
[GOAL]
case h_mul
ι : Type u_1
α : Type u_2
inst✝ : OrderedAddCommGroup α
s✝ t : Interval α
a : α
f : ι → Interval α
s : Finset ι
⊢ ∀ (x y : Interval α), length (x + y) ≤ length x + length y
[PROOFSTEP]
exact length_add_le


[GOAL]
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c x y : RingCon R
h : (fun c => Setoid.r) x = (fun c => Setoid.r) y
⊢ x = y
[PROOFSTEP]
rcases x with ⟨⟨x, _⟩, _⟩
[GOAL]
case mk.mk
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c y : RingCon R
x : R → R → Prop
iseqv✝ : Equivalence x
add'✝ : ∀ {w x_1 y z : R}, Setoid.r w x_1 → Setoid.r y z → Setoid.r (w + y) (x_1 + z)
mul'✝ : ∀ {w x_1 y z : R}, Setoid.r w x_1 → Setoid.r y z → Setoid.r (w * y) (x_1 * z)
h :
  (fun c => Setoid.r) { toSetoid := { r := x, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ } = (fun c => Setoid.r) y
⊢ { toSetoid := { r := x, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ } = y
[PROOFSTEP]
rcases y with ⟨⟨y, _⟩, _⟩
[GOAL]
case mk.mk.mk.mk
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c : RingCon R
x : R → R → Prop
iseqv✝¹ : Equivalence x
add'✝¹ : ∀ {w x_1 y z : R}, Setoid.r w x_1 → Setoid.r y z → Setoid.r (w + y) (x_1 + z)
mul'✝¹ : ∀ {w x_1 y z : R}, Setoid.r w x_1 → Setoid.r y z → Setoid.r (w * y) (x_1 * z)
y : R → R → Prop
iseqv✝ : Equivalence y
add'✝ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w + y_1) (x + z)
mul'✝ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w * y_1) (x * z)
h :
  (fun c => Setoid.r) { toSetoid := { r := x, iseqv := iseqv✝¹ }, add' := add'✝¹, mul' := mul'✝¹ } =
    (fun c => Setoid.r) { toSetoid := { r := y, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ }
⊢ { toSetoid := { r := x, iseqv := iseqv✝¹ }, add' := add'✝¹, mul' := mul'✝¹ } =
    { toSetoid := { r := y, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ }
[PROOFSTEP]
have : x = y := h
[GOAL]
case mk.mk.mk.mk
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c : RingCon R
x : R → R → Prop
iseqv✝¹ : Equivalence x
add'✝¹ : ∀ {w x_1 y z : R}, Setoid.r w x_1 → Setoid.r y z → Setoid.r (w + y) (x_1 + z)
mul'✝¹ : ∀ {w x_1 y z : R}, Setoid.r w x_1 → Setoid.r y z → Setoid.r (w * y) (x_1 * z)
y : R → R → Prop
iseqv✝ : Equivalence y
add'✝ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w + y_1) (x + z)
mul'✝ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w * y_1) (x * z)
h :
  (fun c => Setoid.r) { toSetoid := { r := x, iseqv := iseqv✝¹ }, add' := add'✝¹, mul' := mul'✝¹ } =
    (fun c => Setoid.r) { toSetoid := { r := y, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ }
this : x = y
⊢ { toSetoid := { r := x, iseqv := iseqv✝¹ }, add' := add'✝¹, mul' := mul'✝¹ } =
    { toSetoid := { r := y, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ }
[PROOFSTEP]
subst x
[GOAL]
case mk.mk.mk.mk
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c : RingCon R
y : R → R → Prop
iseqv✝¹ : Equivalence y
add'✝¹ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w + y_1) (x + z)
mul'✝¹ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w * y_1) (x * z)
iseqv✝ : Equivalence y
add'✝ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w + y_1) (x + z)
mul'✝ : ∀ {w x y_1 z : R}, Setoid.r w x → Setoid.r y_1 z → Setoid.r (w * y_1) (x * z)
h :
  (fun c => Setoid.r) { toSetoid := { r := y, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ } =
    (fun c => Setoid.r) { toSetoid := { r := y, iseqv := iseqv✝¹ }, add' := add'✝¹, mul' := mul'✝¹ }
⊢ { toSetoid := { r := y, iseqv := iseqv✝ }, add' := add'✝, mul' := mul'✝ } =
    { toSetoid := { r := y, iseqv := iseqv✝¹ }, add' := add'✝¹, mul' := mul'✝¹ }
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c : RingCon R
d : (a b : R) → Decidable (↑c a b)
⊢ DecidableEq (RingCon.Quotient c)
[PROOFSTEP]
delta RingCon.Quotient
[GOAL]
α : Type u_1
R : Type u_2
inst✝¹ : Add R
inst✝ : Mul R
c : RingCon R
d : (a b : R) → Decidable (↑c a b)
⊢ DecidableEq (Quotient c.toSetoid)
[PROOFSTEP]
infer_instance


[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Monoid M
⊢ ∀ (b : M), 1 • b = b
[PROOFSTEP]
simp only [units_smul_def, ofConjAct_one, Units.val_one, one_mul, inv_one, mul_one, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Monoid M
⊢ ∀ (x y : ConjAct Mˣ) (b : M), (x * y) • b = x • y • b
[PROOFSTEP]
simp only [units_smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Monoid M
⊢ ∀ (x y : ConjAct Mˣ) (b : M),
    ↑(↑ofConjAct (x * y)) * b * ↑(↑ofConjAct (x * y))⁻¹ =
      ↑(↑ofConjAct x) * (↑(↑ofConjAct y) * b * ↑(↑ofConjAct y)⁻¹) * ↑(↑ofConjAct x)⁻¹
[PROOFSTEP]
simp only [map_mul, Units.val_mul, mul_assoc, mul_inv_rev, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Monoid M
⊢ ∀ (r : ConjAct Mˣ) (x y : M), r • (x * y) = r • x * r • y
[PROOFSTEP]
simp only [units_smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Monoid M
⊢ ∀ (r : ConjAct Mˣ) (x y : M),
    ↑(↑ofConjAct r) * (x * y) * ↑(↑ofConjAct r)⁻¹ =
      ↑(↑ofConjAct r) * x * ↑(↑ofConjAct r)⁻¹ * (↑(↑ofConjAct r) * y * ↑(↑ofConjAct r)⁻¹)
[PROOFSTEP]
simp only [mul_assoc, Units.inv_mul_cancel_left, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Monoid M
⊢ ∀ (r : ConjAct Mˣ), r • 1 = 1
[PROOFSTEP]
simp [units_smul_def, mul_one, Units.mul_inv, forall, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝³ : Monoid M
inst✝² : SMul α M
inst✝¹ : SMulCommClass α M M
inst✝ : IsScalarTower α M M
a : α
um : ConjAct Mˣ
m : M
⊢ a • um • m = um • a • m
[PROOFSTEP]
rw [units_smul_def, units_smul_def, mul_smul_comm, smul_mul_assoc]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Semiring R
src✝ : MulDistribMulAction (ConjAct Rˣ) R := unitsMulDistribMulAction
⊢ ∀ (a : ConjAct Rˣ), a • 0 = 0
[PROOFSTEP]
simp only [units_smul_def, mul_zero, zero_mul, forall, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Semiring R
src✝ : MulDistribMulAction (ConjAct Rˣ) R := unitsMulDistribMulAction
⊢ ∀ (a : ConjAct Rˣ) (x y : R), a • (x + y) = a • x + a • y
[PROOFSTEP]
simp only [units_smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Semiring R
src✝ : MulDistribMulAction (ConjAct Rˣ) R := unitsMulDistribMulAction
⊢ ∀ (a : ConjAct Rˣ) (x y : R),
    ↑(↑ofConjAct a) * (x + y) * ↑(↑ofConjAct a)⁻¹ =
      ↑(↑ofConjAct a) * x * ↑(↑ofConjAct a)⁻¹ + ↑(↑ofConjAct a) * y * ↑(↑ofConjAct a)⁻¹
[PROOFSTEP]
simp only [mul_add, add_mul, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : GroupWithZero G₀
⊢ ∀ (b : G₀), 1 • b = b
[PROOFSTEP]
simp only [smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : GroupWithZero G₀
⊢ ∀ (b : G₀), ↑ofConjAct 1 * b * (↑ofConjAct 1)⁻¹ = b
[PROOFSTEP]
simp only [map_one, one_mul, inv_one, mul_one, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : GroupWithZero G₀
⊢ ∀ (x y : ConjAct G₀) (b : G₀), (x * y) • b = x • y • b
[PROOFSTEP]
simp only [smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : GroupWithZero G₀
⊢ ∀ (x y : ConjAct G₀) (b : G₀),
    ↑ofConjAct (x * y) * b * (↑ofConjAct (x * y))⁻¹ =
      ↑ofConjAct x * (↑ofConjAct y * b * (↑ofConjAct y)⁻¹) * (↑ofConjAct x)⁻¹
[PROOFSTEP]
simp only [map_mul, mul_assoc, mul_inv_rev, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝³ : GroupWithZero G₀
inst✝² : SMul α G₀
inst✝¹ : SMulCommClass α G₀ G₀
inst✝ : IsScalarTower α G₀ G₀
a : α
ug : ConjAct G₀
g : G₀
⊢ a • ug • g = ug • a • g
[PROOFSTEP]
rw [smul_def, smul_def, mul_smul_comm, smul_mul_assoc]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : DivisionRing K
src✝ : MulAction (ConjAct K) K := mulAction₀
⊢ ∀ (a : ConjAct K), a • 0 = 0
[PROOFSTEP]
simp only [smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : DivisionRing K
src✝ : MulAction (ConjAct K) K := mulAction₀
⊢ ∀ (a : ConjAct K), ↑ofConjAct a * 0 * (↑ofConjAct a)⁻¹ = 0
[PROOFSTEP]
simp only [mul_zero, zero_mul, forall, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : DivisionRing K
src✝ : MulAction (ConjAct K) K := mulAction₀
⊢ ∀ (a : ConjAct K) (x y : K), a • (x + y) = a • x + a • y
[PROOFSTEP]
simp only [smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : DivisionRing K
src✝ : MulAction (ConjAct K) K := mulAction₀
⊢ ∀ (a : ConjAct K) (x y : K),
    ↑ofConjAct a * (x + y) * (↑ofConjAct a)⁻¹ =
      ↑ofConjAct a * x * (↑ofConjAct a)⁻¹ + ↑ofConjAct a * y * (↑ofConjAct a)⁻¹
[PROOFSTEP]
simp only [mul_add, add_mul, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ ∀ (b : G), 1 • b = b
[PROOFSTEP]
simp only [smul_def, ofConjAct_one, one_mul, inv_one, mul_one, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ ∀ (x y : ConjAct G) (b : G), (x * y) • b = x • y • b
[PROOFSTEP]
simp only [smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ ∀ (x y : ConjAct G) (b : G),
    ↑ofConjAct (x * y) * b * (↑ofConjAct (x * y))⁻¹ =
      ↑ofConjAct x * (↑ofConjAct y * b * (↑ofConjAct y)⁻¹) * (↑ofConjAct x)⁻¹
[PROOFSTEP]
simp only [map_mul, mul_assoc, mul_inv_rev, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ ∀ (r : ConjAct G) (x y : G), r • (x * y) = r • x * r • y
[PROOFSTEP]
simp only [smul_def]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ ∀ (r : ConjAct G) (x y : G),
    ↑ofConjAct r * (x * y) * (↑ofConjAct r)⁻¹ =
      ↑ofConjAct r * x * (↑ofConjAct r)⁻¹ * (↑ofConjAct r * y * (↑ofConjAct r)⁻¹)
[PROOFSTEP]
simp only [mul_assoc, inv_mul_cancel_left, forall_const, forall]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ ∀ (r : ConjAct G), r • 1 = 1
[PROOFSTEP]
simp only [smul_def, mul_one, mul_right_inv, forall, forall_const]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝³ : Group G
inst✝² : SMul α G
inst✝¹ : SMulCommClass α G G
inst✝ : IsScalarTower α G G
a : α
ug : ConjAct G
g : G
⊢ a • ug • g = ug • a • g
[PROOFSTEP]
rw [smul_def, smul_def, mul_smul_comm, smul_mul_assoc]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
⊢ fixedPoints (ConjAct G) G = ↑(center G)
[PROOFSTEP]
ext x
[GOAL]
case h
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
x : G
⊢ x ∈ fixedPoints (ConjAct G) G ↔ x ∈ ↑(center G)
[PROOFSTEP]
simp [mem_center_iff, smul_def, mul_inv_eq_iff_eq_mul]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
g h : G
⊢ g ∈ orbit (ConjAct G) h ↔ IsConj g h
[PROOFSTEP]
rw [isConj_comm, isConj_iff, mem_orbit_iff]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
g h : G
⊢ (∃ x, x • h = g) ↔ ∃ c, c * h * c⁻¹ = g
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝ : Group G
g h : G
⊢ Setoid.Rel (orbitRel (ConjAct G) G) g h = IsConj g h
[PROOFSTEP]
rw [orbitRel_apply, mem_orbit_conjAct]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝¹ inst✝ : Group G
g : G
⊢ orbit (ConjAct G) g = ConjClasses.carrier (ConjClasses.mk g)
[PROOFSTEP]
ext h
[GOAL]
case h
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝¹ inst✝ : Group G
g h : G
⊢ h ∈ orbit (ConjAct G) g ↔ h ∈ ConjClasses.carrier (ConjClasses.mk g)
[PROOFSTEP]
rw [ConjClasses.mem_carrier_iff_mk_eq, ConjClasses.mk_eq_mk_iff_isConj, mem_orbit_conjAct]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
g : G
h : { x // x ∈ H }
⊢ ↑(↑(MulEquiv.symm (↑MulAut.conjNormal g)) h) = g⁻¹ * ↑h * g
[PROOFSTEP]
change _ * _⁻¹⁻¹ = _
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
g : G
h : { x // x ∈ H }
⊢ ↑ofConjAct (↑(MulEquiv.toMonoidHom toConjAct) g)⁻¹ * ↑h * (↑(MulEquiv.toMonoidHom toConjAct) g)⁻¹⁻¹ = g⁻¹ * ↑h * g
[PROOFSTEP]
rw [inv_inv]
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K : Type u_6
inst✝¹ : Group G
H : Subgroup G
inst✝ : Normal H
g : G
h : { x // x ∈ H }
⊢ ↑ofConjAct (↑(MulEquiv.toMonoidHom toConjAct) g)⁻¹ * ↑h * ↑(MulEquiv.toMonoidHom toConjAct) g = g⁻¹ * ↑h * g
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K✝ : Type u_6
inst✝ : Group G
H : Subgroup G
hH : Normal H
K : Subgroup { x // x ∈ H }
h : Characteristic K
a : G
ha : a ∈ map (Subgroup.subtype H) K
b : G
⊢ b * a * b⁻¹ ∈ map (Subgroup.subtype H) K
[PROOFSTEP]
obtain ⟨a, ha, rfl⟩ := ha
[GOAL]
case intro.intro
α : Type u_1
M : Type u_2
G : Type u_3
G₀ : Type u_4
R : Type u_5
K✝ : Type u_6
inst✝ : Group G
H : Subgroup G
hH : Normal H
K : Subgroup { x // x ∈ H }
h : Characteristic K
b : G
a : { x // x ∈ H }
ha : a ∈ ↑K
⊢ b * ↑(Subgroup.subtype H) a * b⁻¹ ∈ map (Subgroup.subtype H) K
[PROOFSTEP]
exact K.apply_coe_mem_map H.subtype ⟨_, (SetLike.ext_iff.mp (h.fixed (MulAut.conjNormal b)) a).mpr ha⟩