[GOAL]
G : Type u_1
H : Type u_2
inst✝ : Monoid G
⊢ ¬IsTorsion G ↔ ∃ g, ¬IsOfFinOrder g
[PROOFSTEP]
rw [IsTorsion, not_forall]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : Monoid G
tG : IsTorsion G
src✝ : Monoid G := inst✝
g : G
⊢ g⁻¹ * g = 1
[PROOFSTEP]
erw [← pow_succ', tsub_add_cancel_of_le, pow_orderOf_eq_one]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : Monoid G
tG : IsTorsion G
src✝ : Monoid G := inst✝
g : G
⊢ 1 ≤ orderOf g
[PROOFSTEP]
exact orderOf_pos' (tG g)
[GOAL]
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hf : Function.Surjective ↑f
tG : IsTorsion G
h : H
⊢ IsOfFinOrder h
[PROOFSTEP]
obtain ⟨g, hg⟩ := hf h
[GOAL]
case intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hf : Function.Surjective ↑f
tG : IsTorsion G
h : H
g : G
hg : ↑f g = h
⊢ IsOfFinOrder h
[PROOFSTEP]
rw [← hg]
[GOAL]
case intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hf : Function.Surjective ↑f
tG : IsTorsion G
h : H
g : G
hg : ↑f g = h
⊢ IsOfFinOrder (↑f g)
[PROOFSTEP]
exact f.isOfFinOrder (tG g)
[GOAL]
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hN : N = MonoidHom.ker f
tH : IsTorsion H
tN : IsTorsion { x // x ∈ N }
g : G
⊢ ∃ n, 0 < n ∧ g ^ n = 1
[PROOFSTEP]
obtain ⟨ngn, ngnpos, hngn⟩ := (isOfFinOrder_iff_pow_eq_one _).mp (tH <| f g)
[GOAL]
case intro.intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hN : N = MonoidHom.ker f
tH : IsTorsion H
tN : IsTorsion { x // x ∈ N }
g : G
ngn : ℕ
ngnpos : 0 < ngn
hngn : ↑f g ^ ngn = 1
⊢ ∃ n, 0 < n ∧ g ^ n = 1
[PROOFSTEP]
have hmem := f.mem_ker.mpr ((f.map_pow g ngn).trans hngn)
[GOAL]
case intro.intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hN : N = MonoidHom.ker f
tH : IsTorsion H
tN : IsTorsion { x // x ∈ N }
g : G
ngn : ℕ
ngnpos : 0 < ngn
hngn : ↑f g ^ ngn = 1
hmem : g ^ ngn ∈ MonoidHom.ker f
⊢ ∃ n, 0 < n ∧ g ^ n = 1
[PROOFSTEP]
lift g ^ ngn to N using hN.symm ▸ hmem with gn h
[GOAL]
case intro.intro.intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hN : N = MonoidHom.ker f
tH : IsTorsion H
tN : IsTorsion { x // x ∈ N }
g : G
ngn : ℕ
ngnpos : 0 < ngn
hngn : ↑f g ^ ngn = 1
gn : { x // x ∈ N }
h : ↑gn = g ^ ngn
hmem✝ hmem : ↑gn ∈ MonoidHom.ker f
⊢ ∃ n, 0 < n ∧ g ^ n = 1
[PROOFSTEP]
obtain ⟨nn, nnpos, hnn⟩ := (isOfFinOrder_iff_pow_eq_one _).mp (tN gn)
[GOAL]
case intro.intro.intro.intro.intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hN : N = MonoidHom.ker f
tH : IsTorsion H
tN : IsTorsion { x // x ∈ N }
g : G
ngn : ℕ
ngnpos : 0 < ngn
hngn : ↑f g ^ ngn = 1
gn : { x // x ∈ N }
h : ↑gn = g ^ ngn
hmem✝ hmem : ↑gn ∈ MonoidHom.ker f
nn : ℕ
nnpos : 0 < nn
hnn : gn ^ nn = 1
⊢ ∃ n, 0 < n ∧ g ^ n = 1
[PROOFSTEP]
exact ⟨ngn * nn, mul_pos ngnpos nnpos, by rw [pow_mul, ← h, ← Subgroup.coe_pow, hnn, Subgroup.coe_one]⟩
[GOAL]
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
f : G →* H
hN : N = MonoidHom.ker f
tH : IsTorsion H
tN : IsTorsion { x // x ∈ N }
g : G
ngn : ℕ
ngnpos : 0 < ngn
hngn : ↑f g ^ ngn = 1
gn : { x // x ∈ N }
h : ↑gn = g ^ ngn
hmem✝ hmem : ↑gn ∈ MonoidHom.ker f
nn : ℕ
nnpos : 0 < nn
hnn : gn ^ nn = 1
⊢ g ^ (ngn * nn) = 1
[PROOFSTEP]
rw [pow_mul, ← h, ← Subgroup.coe_pow, hnn, Subgroup.coe_one]
[GOAL]
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
h : ExponentExists G
g : G
⊢ IsOfFinOrder g
[PROOFSTEP]
obtain ⟨n, npos, hn⟩ := h
[GOAL]
case intro.intro
G : Type u_1
H : Type u_2
inst✝¹ : Group G
N : Subgroup G
inst✝ : Group H
g : G
n : ℕ
npos : 0 < n
hn : ∀ (g : G), g ^ n = 1
⊢ IsOfFinOrder g
[PROOFSTEP]
exact (isOfFinOrder_iff_pow_eq_one g).mpr ⟨n, npos, hn g⟩
[GOAL]
G : Type u_1
H : Type u_2
R : Type u_3
M : Type u_4
inst✝² : AddCommMonoid M
inst✝¹ : Semiring R
inst✝ : Module R M
tR : IsTorsion R
f : M
⊢ ∃ n, 0 < n ∧ n • f = 0
[PROOFSTEP]
obtain ⟨n, npos, hn⟩ := (isOfFinAddOrder_iff_nsmul_eq_zero _).mp (tR 1)
[GOAL]
case intro.intro
G : Type u_1
H : Type u_2
R : Type u_3
M : Type u_4
inst✝² : AddCommMonoid M
inst✝¹ : Semiring R
inst✝ : Module R M
tR : IsTorsion R
f : M
n : ℕ
npos : 0 < n
hn : n • 1 = 0
⊢ ∃ n, 0 < n ∧ n • f = 0
[PROOFSTEP]
exact ⟨n, npos, by simp only [nsmul_eq_smul_cast R _ f, ← nsmul_one, hn, zero_smul]⟩
[GOAL]
G : Type u_1
H : Type u_2
R : Type u_3
M : Type u_4
inst✝² : AddCommMonoid M
inst✝¹ : Semiring R
inst✝ : Module R M
tR : IsTorsion R
f : M
n : ℕ
npos : 0 < n
hn : n • 1 = 0
⊢ n • f = 0
[PROOFSTEP]
simp only [nsmul_eq_smul_cast R _ f, ← nsmul_one, hn, zero_smul]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
x✝ : { x // x ∈ torsion G }
x : G
n : ℕ
npos : n > 0
hn : Function.IsPeriodicPt ((fun x x_1 => x * x_1) x) n 1
⊢ ↑(((fun x x_1 => x * x_1)
            { val := x, property := (_ : ∃ n, n > 0 ∧ Function.IsPeriodicPt ((fun x x_1 => x * x_1) x) n 1) })^[n]
        1) =
    ↑1
[PROOFSTEP]
dsimp
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
x✝ : { x // x ∈ torsion G }
x : G
n : ℕ
npos : n > 0
hn : Function.IsPeriodicPt ((fun x x_1 => x * x_1) x) n 1
⊢ ↑((fun x_1 => { val := x, property := (_ : ∃ n, n > 0 ∧ Function.IsPeriodicPt (fun x_2 => x * x_2) n 1) } * x_1)^[n]
        1) =
    1
[PROOFSTEP]
rw [mul_left_iterate]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
x✝ : { x // x ∈ torsion G }
x : G
n : ℕ
npos : n > 0
hn : Function.IsPeriodicPt ((fun x x_1 => x * x_1) x) n 1
⊢ ↑((fun x_1 => { val := x, property := (_ : ∃ n, n > 0 ∧ Function.IsPeriodicPt (fun x_2 => x * x_2) n 1) } ^ n * x_1)
        1) =
    1
[PROOFSTEP]
change _ * 1 = 1
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
x✝ : { x // x ∈ torsion G }
x : G
n : ℕ
npos : n > 0
hn : Function.IsPeriodicPt ((fun x x_1 => x * x_1) x) n 1
⊢ ↑({ val := x, property := (_ : ∃ n, n > 0 ∧ Function.IsPeriodicPt (fun x_1 => x * x_1) n 1) } ^ n) * 1 = 1
[PROOFSTEP]
rw [_root_.mul_one, SubmonoidClass.coe_pow, Subtype.coe_mk, (isPeriodicPt_mul_iff_pow_eq_one _).mp hn]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
a✝ b✝ : G
hg₁ : a✝ ∈ {g | ∃ n, orderOf g = p ^ n}
hg₂ : b✝ ∈ {g | ∃ n, orderOf g = p ^ n}
⊢ ∃ m, (a✝ * b✝) ^ p ^ m = 1
[PROOFSTEP]
obtain ⟨m, hm⟩ := exists_orderOf_eq_prime_pow_iff.mp hg₁
[GOAL]
case intro
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
a✝ b✝ : G
hg₁ : a✝ ∈ {g | ∃ n, orderOf g = p ^ n}
hg₂ : b✝ ∈ {g | ∃ n, orderOf g = p ^ n}
m : ℕ
hm : a✝ ^ p ^ m = 1
⊢ ∃ m, (a✝ * b✝) ^ p ^ m = 1
[PROOFSTEP]
obtain ⟨n, hn⟩ := exists_orderOf_eq_prime_pow_iff.mp hg₂
[GOAL]
case intro.intro
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
a✝ b✝ : G
hg₁ : a✝ ∈ {g | ∃ n, orderOf g = p ^ n}
hg₂ : b✝ ∈ {g | ∃ n, orderOf g = p ^ n}
m : ℕ
hm : a✝ ^ p ^ m = 1
n : ℕ
hn : b✝ ^ p ^ n = 1
⊢ ∃ m, (a✝ * b✝) ^ p ^ m = 1
[PROOFSTEP]
exact ⟨m + n, by rw [mul_pow, pow_add, pow_mul, hm, one_pow, Monoid.one_mul, mul_comm, pow_mul, hn, one_pow]⟩
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
a✝ b✝ : G
hg₁ : a✝ ∈ {g | ∃ n, orderOf g = p ^ n}
hg₂ : b✝ ∈ {g | ∃ n, orderOf g = p ^ n}
m : ℕ
hm : a✝ ^ p ^ m = 1
n : ℕ
hn : b✝ ^ p ^ n = 1
⊢ (a✝ * b✝) ^ p ^ (m + n) = 1
[PROOFSTEP]
rw [mul_pow, pow_add, pow_mul, hm, one_pow, Monoid.one_mul, mul_comm, pow_mul, hn, one_pow]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
⊢ orderOf 1 = p ^ 0
[PROOFSTEP]
rw [pow_zero, orderOf_one]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
g : { x // x ∈ primaryComponent G p }
⊢ ∃ n, orderOf g = p ^ n
[PROOFSTEP]
simpa [primaryComponent] using g.property
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
p' : ℕ
hp' : Fact (Nat.Prime p')
hne : p ≠ p'
⊢ ∀ {x : G}, x ∈ primaryComponent G p → x ∈ primaryComponent G p' → x = 1
[PROOFSTEP]
rintro g ⟨_ | n, hn⟩ ⟨n', hn'⟩
[GOAL]
case intro.zero.intro
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
p' : ℕ
hp' : Fact (Nat.Prime p')
hne : p ≠ p'
g : G
hn : orderOf g = p ^ Nat.zero
n' : ℕ
hn' : orderOf g = p' ^ n'
⊢ g = 1
[PROOFSTEP]
rwa [pow_zero, orderOf_eq_one_iff] at hn
[GOAL]
case intro.succ.intro
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
p : ℕ
hp : Fact (Nat.Prime p)
p' : ℕ
hp' : Fact (Nat.Prime p')
hne : p ≠ p'
g : G
n : ℕ
hn : orderOf g = p ^ Nat.succ n
n' : ℕ
hn' : orderOf g = p' ^ n'
⊢ g = 1
[PROOFSTEP]
exact absurd (eq_of_prime_pow_eq hp.out.prime hp'.out.prime n.succ_pos (hn.symm.trans hn')) hne
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
tG : IsTorsion G
⊢ torsion G = ⊤
[PROOFSTEP]
ext
[GOAL]
case h
G : Type u_1
H : Type u_2
inst✝ : CommMonoid G
tG : IsTorsion G
x✝ : G
⊢ x✝ ∈ torsion G ↔ x✝ ∈ ⊤
[PROOFSTEP]
tauto
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : Monoid G
⊢ ¬IsTorsionFree G ↔ ∃ g, g ≠ 1 ∧ IsOfFinOrder g
[PROOFSTEP]
simp_rw [IsTorsionFree, Ne.def, not_forall, Classical.not_not, exists_prop]
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : Group G
hN : Nontrivial G
tG : IsTorsion G
⊢ ∃ g, g ≠ 1 ∧ IsOfFinOrder g
[PROOFSTEP]
obtain ⟨x, hx⟩ := (nontrivial_iff_exists_ne (1 : G)).mp hN
[GOAL]
case intro
G : Type u_1
H : Type u_2
inst✝ : Group G
hN : Nontrivial G
tG : IsTorsion G
x : G
hx : x ≠ 1
⊢ ∃ g, g ≠ 1 ∧ IsOfFinOrder g
[PROOFSTEP]
exact ⟨x, hx, tG x⟩
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : Group G
hN : Nontrivial G
tfG : IsTorsionFree G
⊢ ∃ g, ¬IsOfFinOrder g
[PROOFSTEP]
obtain ⟨x, hx⟩ := (nontrivial_iff_exists_ne (1 : G)).mp hN
[GOAL]
case intro
G : Type u_1
H : Type u_2
inst✝ : Group G
hN : Nontrivial G
tfG : IsTorsionFree G
x : G
hx : x ≠ 1
⊢ ∃ g, ¬IsOfFinOrder g
[PROOFSTEP]
exact ⟨x, (tfG x) hx⟩
[GOAL]
G : Type u_1
H✝ : Type u_2
inst✝ : Group G
tG : IsTorsionFree G
H : Subgroup G
h : { x // x ∈ H }
hne : h ≠ 1
⊢ ↑h ≠ 1
[PROOFSTEP]
norm_cast
[GOAL]
G : Type u_1
H : Type u_2
inst✝ : CommGroup G
g : G ⧸ torsion G
hne : g ≠ 1
hfin : IsOfFinOrder g
⊢ g = 1
[PROOFSTEP]
induction' g using QuotientGroup.induction_on' with g
[GOAL]
case H
G : Type u_1
H : Type u_2
inst✝ : CommGroup G
g✝ : G ⧸ torsion G
hne✝ : g✝ ≠ 1
hfin✝ : IsOfFinOrder g✝
g : G
hne : ↑g ≠ 1
hfin : IsOfFinOrder ↑g
⊢ ↑g = 1
[PROOFSTEP]
obtain ⟨m, mpos, hm⟩ := (isOfFinOrder_iff_pow_eq_one _).mp hfin
[GOAL]
case H.intro.intro
G : Type u_1
H : Type u_2
inst✝ : CommGroup G
g✝ : G ⧸ torsion G
hne✝ : g✝ ≠ 1
hfin✝ : IsOfFinOrder g✝
g : G
hne : ↑g ≠ 1
hfin : IsOfFinOrder ↑g
m : ℕ
mpos : 0 < m
hm : ↑g ^ m = 1
⊢ ↑g = 1
[PROOFSTEP]
obtain ⟨n, npos, hn⟩ := (isOfFinOrder_iff_pow_eq_one _).mp ((QuotientGroup.eq_one_iff _).mp hm)
[GOAL]
case H.intro.intro.intro.intro
G : Type u_1
H : Type u_2
inst✝ : CommGroup G
g✝ : G ⧸ torsion G
hne✝ : g✝ ≠ 1
hfin✝ : IsOfFinOrder g✝
g : G
hne : ↑g ≠ 1
hfin : IsOfFinOrder ↑g
m : ℕ
mpos : 0 < m
hm : ↑g ^ m = 1
n : ℕ
npos : 0 < n
hn : (fun x => x ^ m) g ^ n = 1
⊢ ↑g = 1
[PROOFSTEP]
exact
  (QuotientGroup.eq_one_iff g).mpr
    ((isOfFinOrder_iff_pow_eq_one _).mpr ⟨m * n, mul_pos mpos npos, (pow_mul g m n).symm ▸ hn⟩)


[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S : B
l : List M
hl : ∀ (x : M), x ∈ l → x ∈ S
⊢ List.prod l ∈ S
[PROOFSTEP]
lift l to List S using hl
[GOAL]
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S : B
l : List { x // x ∈ S }
⊢ List.prod (List.map Subtype.val l) ∈ S
[PROOFSTEP]
rw [← coe_list_prod]
[GOAL]
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S : B
l : List { x // x ∈ S }
⊢ ↑(List.prod l) ∈ S
[PROOFSTEP]
exact l.prod.coe_prop
[GOAL]
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : Monoid M✝
inst✝⁴ : SetLike B M✝
inst✝³ : SubmonoidClass B M✝
S : B
M : Type u_4
inst✝² : CommMonoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
m : Multiset M
hm : ∀ (a : M), a ∈ m → a ∈ S
⊢ Multiset.prod m ∈ S
[PROOFSTEP]
lift m to Multiset S using hm
[GOAL]
case intro
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : Monoid M✝
inst✝⁴ : SetLike B M✝
inst✝³ : SubmonoidClass B M✝
S : B
M : Type u_4
inst✝² : CommMonoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
m : Multiset { x // x ∈ S }
⊢ Multiset.prod (Multiset.map Subtype.val m) ∈ S
[PROOFSTEP]
rw [← coe_multiset_prod]
[GOAL]
case intro
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : Monoid M✝
inst✝⁴ : SetLike B M✝
inst✝³ : SubmonoidClass B M✝
S : B
M : Type u_4
inst✝² : CommMonoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
m : Multiset { x // x ∈ S }
⊢ ↑(Multiset.prod m) ∈ S
[PROOFSTEP]
exact m.prod.coe_prop
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S : B
s : Submonoid M
l : List M
hl : ∀ (x : M), x ∈ l → x ∈ s
⊢ List.prod l ∈ s
[PROOFSTEP]
lift l to List s using hl
[GOAL]
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S : B
s : Submonoid M
l : List { x // x ∈ s }
⊢ List.prod (List.map Subtype.val l) ∈ s
[PROOFSTEP]
rw [← coe_list_prod]
[GOAL]
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S : B
s : Submonoid M
l : List { x // x ∈ s }
⊢ ↑(List.prod l) ∈ s
[PROOFSTEP]
exact l.prod.coe_prop
[GOAL]
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝³ : Monoid M✝
inst✝² : SetLike B M✝
inst✝¹ : SubmonoidClass B M✝
S✝ : B
s : Submonoid M✝
M : Type u_4
inst✝ : CommMonoid M
S : Submonoid M
m : Multiset M
hm : ∀ (a : M), a ∈ m → a ∈ S
⊢ Multiset.prod m ∈ S
[PROOFSTEP]
lift m to Multiset S using hm
[GOAL]
case intro
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝³ : Monoid M✝
inst✝² : SetLike B M✝
inst✝¹ : SubmonoidClass B M✝
S✝ : B
s : Submonoid M✝
M : Type u_4
inst✝ : CommMonoid M
S : Submonoid M
m : Multiset { x // x ∈ S }
⊢ Multiset.prod (Multiset.map Subtype.val m) ∈ S
[PROOFSTEP]
rw [← coe_multiset_prod]
[GOAL]
case intro
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝³ : Monoid M✝
inst✝² : SetLike B M✝
inst✝¹ : SubmonoidClass B M✝
S✝ : B
s : Submonoid M✝
M : Type u_4
inst✝ : CommMonoid M
S : Submonoid M
m : Multiset { x // x ∈ S }
⊢ ↑(Multiset.prod m) ∈ S
[PROOFSTEP]
exact m.prod.coe_prop
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
m : Multiset M
comm : Set.Pairwise {x | x ∈ m} Commute
h : ∀ (x : M), x ∈ m → x ∈ S
⊢ Multiset.noncommProd m comm ∈ S
[PROOFSTEP]
induction' m using Quotient.inductionOn with l
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
m : Multiset M
comm✝ : Set.Pairwise {x | x ∈ m} Commute
h✝ : ∀ (x : M), x ∈ m → x ∈ S
l : List M
comm : Set.Pairwise {x | x ∈ Quotient.mk (List.isSetoid M) l} Commute
h : ∀ (x : M), x ∈ Quotient.mk (List.isSetoid M) l → x ∈ S
⊢ Multiset.noncommProd (Quotient.mk (List.isSetoid M) l) comm ∈ S
[PROOFSTEP]
simp only [Multiset.quot_mk_to_coe, Multiset.noncommProd_coe]
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
m : Multiset M
comm✝ : Set.Pairwise {x | x ∈ m} Commute
h✝ : ∀ (x : M), x ∈ m → x ∈ S
l : List M
comm : Set.Pairwise {x | x ∈ Quotient.mk (List.isSetoid M) l} Commute
h : ∀ (x : M), x ∈ Quotient.mk (List.isSetoid M) l → x ∈ S
⊢ List.prod l ∈ S
[PROOFSTEP]
exact Submonoid.list_prod_mem _ h
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ (c : ι), c ∈ t → f c ∈ S
⊢ Finset.noncommProd t f comm ∈ S
[PROOFSTEP]
apply multiset_noncommProd_mem
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ (c : ι), c ∈ t → f c ∈ S
⊢ ∀ (x : M), x ∈ Multiset.map f t.val → x ∈ S
[PROOFSTEP]
intro y
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ (c : ι), c ∈ t → f c ∈ S
y : M
⊢ y ∈ Multiset.map f t.val → y ∈ S
[PROOFSTEP]
rw [Multiset.mem_map]
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ (c : ι), c ∈ t → f c ∈ S
y : M
⊢ (∃ a, a ∈ t.val ∧ f a = y) → y ∈ S
[PROOFSTEP]
rintro ⟨x, ⟨hx, rfl⟩⟩
[GOAL]
case h.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ (c : ι), c ∈ t → f c ∈ S
x : ι
hx : x ∈ t.val
⊢ f x ∈ S
[PROOFSTEP]
exact h x hx
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ⨆ (i : ι), S i ↔ ∃ i, x ∈ S i
[PROOFSTEP]
refine' ⟨_, fun ⟨i, hi⟩ => (SetLike.le_def.1 <| le_iSup S i) hi⟩
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ⨆ (i : ι), S i → ∃ i, x ∈ S i
[PROOFSTEP]
suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by simpa only [closure_iUnion, closure_eq (S _)] using this
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
this : x ∈ closure (⋃ (i : ι), ↑(S i)) → ∃ i, x ∈ S i
⊢ x ∈ ⨆ (i : ι), S i → ∃ i, x ∈ S i
[PROOFSTEP]
simpa only [closure_iUnion, closure_eq (S _)] using this
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ closure (⋃ (i : ι), ↑(S i)) → ∃ i, x ∈ S i
[PROOFSTEP]
refine' fun hx => closure_induction hx (fun _ => mem_iUnion.1) _ _
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
hx : x ∈ closure (⋃ (i : ι), ↑(S i))
⊢ ∃ i, 1 ∈ S i
[PROOFSTEP]
exact hι.elim fun i => ⟨i, (S i).one_mem⟩
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
hx : x ∈ closure (⋃ (i : ι), ↑(S i))
⊢ ∀ (x y : M), (∃ i, x ∈ S i) → (∃ i, y ∈ S i) → ∃ i, x * y ∈ S i
[PROOFSTEP]
rintro x y ⟨i, hi⟩ ⟨j, hj⟩
[GOAL]
case refine'_2.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x✝ : M
hx : x✝ ∈ closure (⋃ (i : ι), ↑(S i))
x y : M
i : ι
hi : x ∈ S i
j : ι
hj : y ∈ S j
⊢ ∃ i, x * y ∈ S i
[PROOFSTEP]
rcases hS i j with ⟨k, hki, hkj⟩
[GOAL]
case refine'_2.intro.intro.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x✝ : M
hx : x✝ ∈ closure (⋃ (i : ι), ↑(S i))
x y : M
i : ι
hi : x ∈ S i
j : ι
hj : y ∈ S j
k : ι
hki : S i ≤ S k
hkj : S j ≤ S k
⊢ ∃ i, x * y ∈ S i
[PROOFSTEP]
exact ⟨k, (S k).mul_mem (hki hi) (hkj hj)⟩
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : MulOneClass M
ι : Sort u_4
inst✝ : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ↑(⨆ (i : ι), S i) ↔ x ∈ ⋃ (i : ι), ↑(S i)
[PROOFSTEP]
simp [mem_iSup_of_directed hS]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ sSup S ↔ ∃ s, s ∈ S ∧ x ∈ s
[PROOFSTEP]
haveI : Nonempty S := Sne.to_subtype
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : M
this : Nonempty ↑S
⊢ x ∈ sSup S ↔ ∃ s, s ∈ S ∧ x ∈ s
[PROOFSTEP]
simp [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, Subtype.coe_mk]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ↑(sSup S) ↔ x ∈ ⋃ (s : Submonoid M) (_ : s ∈ S), ↑s
[PROOFSTEP]
simp [mem_sSup_of_directedOn Sne hS]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ ∀ {x : M}, x ∈ S → x ∈ S ⊔ T
[PROOFSTEP]
rw [← SetLike.le_def]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ S ≤ S ⊔ T
[PROOFSTEP]
exact le_sup_left
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ ∀ {x : M}, x ∈ T → x ∈ S ⊔ T
[PROOFSTEP]
rw [← SetLike.le_def]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ T ≤ S ⊔ T
[PROOFSTEP]
exact le_sup_right
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
i : ι
⊢ ∀ {x : M}, x ∈ S i → x ∈ iSup S
[PROOFSTEP]
rw [← SetLike.le_def]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
i : ι
⊢ S i ≤ iSup S
[PROOFSTEP]
exact le_iSup _ _
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
s : Submonoid M
hs : s ∈ S
⊢ ∀ {x : M}, x ∈ s → x ∈ sSup S
[PROOFSTEP]
rw [← SetLike.le_def]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
s : Submonoid M
hs : s ∈ S
⊢ s ≤ sSup S
[PROOFSTEP]
exact le_sSup hs
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x : M
hx : x ∈ ⨆ (i : ι), S i
hp : ∀ (i : ι) (x : M), x ∈ S i → C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
⊢ C x
[PROOFSTEP]
rw [iSup_eq_closure] at hx
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x : M
hx : x ∈ closure (⋃ (i : ι), ↑(S i))
hp : ∀ (i : ι) (x : M), x ∈ S i → C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
⊢ C x
[PROOFSTEP]
refine closure_induction hx (fun x hx => ?_) h1 hmul
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x✝ : M
hx✝ : x✝ ∈ closure (⋃ (i : ι), ↑(S i))
hp : ∀ (i : ι) (x : M), x ∈ S i → C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
x : M
hx : x ∈ ⋃ (i : ι), ↑(S i)
⊢ C x
[PROOFSTEP]
obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
[GOAL]
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x✝ : M
hx✝ : x✝ ∈ closure (⋃ (i : ι), ↑(S i))
hp : ∀ (i : ι) (x : M), x ∈ S i → C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
x : M
hx : x ∈ ⋃ (i : ι), ↑(S i)
i : ι
hi : x ∈ ↑(S i)
⊢ C x
[PROOFSTEP]
exact hp _ _ hi
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ (i : ι), S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ (i : ι), S i)
h1 : C 1 (_ : 1 ∈ ⨆ (i : ι), S i)
hmul :
  ∀ (x y : M) (hx : x ∈ ⨆ (i : ι), S i) (hy : y ∈ ⨆ (i : ι), S i),
    C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ (i : ι), S i)
x : M
hx : x ∈ ⨆ (i : ι), S i
⊢ C x hx
[PROOFSTEP]
refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ (i : ι), S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ (i : ι), S i)
h1 : C 1 (_ : 1 ∈ ⨆ (i : ι), S i)
hmul :
  ∀ (x y : M) (hx : x ∈ ⨆ (i : ι), S i) (hy : y ∈ ⨆ (i : ι), S i),
    C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ (i : ι), S i)
x : M
hx : x ∈ ⨆ (i : ι), S i
⊢ ∃ Hx, C x Hx
[PROOFSTEP]
refine' @iSup_induction _ _ ι S (fun m => ∃ hm, C m hm) _ hx (fun i x hx => _) _ fun x y => _
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ (i : ι), S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ (i : ι), S i)
h1 : C 1 (_ : 1 ∈ ⨆ (i : ι), S i)
hmul :
  ∀ (x y : M) (hx : x ∈ ⨆ (i : ι), S i) (hy : y ∈ ⨆ (i : ι), S i),
    C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ (i : ι), S i)
x✝ : M
hx✝ : x✝ ∈ ⨆ (i : ι), S i
i : ι
x : M
hx : x ∈ S i
⊢ (fun m => ∃ hm, C m hm) x
[PROOFSTEP]
exact ⟨_, hp _ _ hx⟩
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ (i : ι), S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ (i : ι), S i)
h1 : C 1 (_ : 1 ∈ ⨆ (i : ι), S i)
hmul :
  ∀ (x y : M) (hx : x ∈ ⨆ (i : ι), S i) (hy : y ∈ ⨆ (i : ι), S i),
    C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ (i : ι), S i)
x : M
hx : x ∈ ⨆ (i : ι), S i
⊢ (fun m => ∃ hm, C m hm) 1
[PROOFSTEP]
exact ⟨_, h1⟩
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ (i : ι), S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ (i : ι), S i)
h1 : C 1 (_ : 1 ∈ ⨆ (i : ι), S i)
hmul :
  ∀ (x y : M) (hx : x ∈ ⨆ (i : ι), S i) (hy : y ∈ ⨆ (i : ι), S i),
    C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ (i : ι), S i)
x✝ : M
hx : x✝ ∈ ⨆ (i : ι), S i
x y : M
⊢ (fun m => ∃ hm, C m hm) x → (fun m => ∃ hm, C m hm) y → (fun m => ∃ hm, C m hm) (x * y)
[PROOFSTEP]
rintro ⟨_, Cx⟩ ⟨_, Cy⟩
[GOAL]
case refine'_3.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ (i : ι), S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ (i : ι), S i)
h1 : C 1 (_ : 1 ∈ ⨆ (i : ι), S i)
hmul :
  ∀ (x y : M) (hx : x ∈ ⨆ (i : ι), S i) (hy : y ∈ ⨆ (i : ι), S i),
    C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ (i : ι), S i)
x✝ : M
hx : x✝ ∈ ⨆ (i : ι), S i
x y : M
w✝¹ : x ∈ ⨆ (i : ι), S i
Cx : C x w✝¹
w✝ : y ∈ ⨆ (i : ι), S i
Cy : C y w✝
⊢ ∃ hm, C (x * y) hm
[PROOFSTEP]
refine' ⟨_, hmul _ _ _ _ Cx Cy⟩
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x y : M
⊢ y ∈ closure {x} ↔ ∃ n, x ^ n = y
[PROOFSTEP]
rw [closure_singleton_eq, mem_mrange]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x y : M
⊢ (∃ x_1, ↑(↑(powersHom M) x) x_1 = y) ↔ ∃ n, x ^ n = y
[PROOFSTEP]
rfl
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
⊢ closure {1} = ⊥
[PROOFSTEP]
simp [eq_bot_iff_forall, mem_closure_singleton]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
α : Type u_4
f : α → M
⊢ mrange (↑FreeMonoid.lift f) = closure (Set.range f)
[PROOFSTEP]
rw [mrange_eq_map, ← FreeMonoid.closure_range_of, map_mclosure, ← Set.range_comp, FreeMonoid.lift_comp_of]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
⊢ closure s = mrange (↑FreeMonoid.lift Subtype.val)
[PROOFSTEP]
rw [FreeMonoid.mrange_lift, Subtype.range_coe]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
⊢ ↑(closure s) = List.prod '' {l | ∀ (x : M), x ∈ l → x ∈ s}
[PROOFSTEP]
rw [closure_eq_mrange, coe_mrange, ← Set.range_list_map_coe, ← Set.range_comp]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
⊢ Set.range ↑(↑FreeMonoid.lift Subtype.val) = Set.range (List.prod ∘ List.map Subtype.val)
[PROOFSTEP]
exact congrArg _ (funext <| FreeMonoid.lift_apply _)
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
x : M
hx : x ∈ closure s
⊢ ∃ l x_1, List.prod l = x
[PROOFSTEP]
rwa [← SetLike.mem_coe, closure_eq_image_prod, Set.mem_image_iff_bex] at hx
[GOAL]
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : Monoid M✝
M : Type u_4
inst✝ : CommMonoid M
s : Set M
x : M
hx : x ∈ closure s
⊢ ∃ l x_1, Multiset.prod l = x
[PROOFSTEP]
obtain ⟨l, h1, h2⟩ := exists_list_of_mem_closure hx
[GOAL]
case intro.intro
M✝ : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : Monoid M✝
M : Type u_4
inst✝ : CommMonoid M
s : Set M
x : M
hx : x ∈ closure s
l : List M
h1 : ∀ (y : M), y ∈ l → y ∈ s
h2 : List.prod l = x
⊢ ∃ l x_1, Multiset.prod l = x
[PROOFSTEP]
exact ⟨l, h1, (Multiset.coe_prod l).trans h2⟩
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
x : M
h : x ∈ closure s
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
⊢ p x
[PROOFSTEP]
rw [closure_eq_mrange] at h
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
x : M
h : x ∈ mrange (↑FreeMonoid.lift Subtype.val)
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
⊢ p x
[PROOFSTEP]
obtain ⟨l, rfl⟩ := h
[GOAL]
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
l : FreeMonoid { x // x ∈ s }
⊢ p (↑(↑FreeMonoid.lift Subtype.val) l)
[PROOFSTEP]
induction' l using FreeMonoid.recOn with x y ih
[GOAL]
case intro.h0
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
⊢ p (↑(↑FreeMonoid.lift Subtype.val) 1)
[PROOFSTEP]
exact H1
[GOAL]
case intro.ih
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
x : { x // x ∈ s }
y : FreeMonoid { x // x ∈ s }
ih : p (↑(↑FreeMonoid.lift Subtype.val) y)
⊢ p (↑(↑FreeMonoid.lift Subtype.val) (FreeMonoid.of x * y))
[PROOFSTEP]
simpa only [map_mul, FreeMonoid.lift_eval_of] using Hmul _ x.prop _ ih
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
hs : closure s = ⊤
x : M
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
⊢ x ∈ closure s
[PROOFSTEP]
rw [hs]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
hs : closure s = ⊤
x : M
H1 : p 1
Hmul : ∀ (x : M), x ∈ s → ∀ (y : M), p y → p (x * y)
⊢ x ∈ ⊤
[PROOFSTEP]
exact mem_top _
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
hs : closure s = ⊤
x : M
H1 : p 1
Hmul : ∀ (x y : M), y ∈ s → p x → p (x * y)
⊢ x ∈ closure s
[PROOFSTEP]
rw [hs]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
p : M → Prop
hs : closure s = ⊤
x : M
H1 : p 1
Hmul : ∀ (x y : M), y ∈ s → p x → p (x * y)
⊢ x ∈ ⊤
[PROOFSTEP]
exact mem_top _
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
n✝ n : M
i : ℕ
⊢ (fun x x_1 => x ^ x_1) n✝ i = n ↔ ↑(↑(powersHom M) n✝) i = n
[PROOFSTEP]
simp
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
n✝ n : M
i : ℕ
⊢ n✝ ^ i = n ↔ n✝ ^ ↑Multiplicative.toAdd i = n
[PROOFSTEP]
rfl
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
n : M
⊢ powers n = closure {n}
[PROOFSTEP]
ext
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
n x✝ : M
⊢ x✝ ∈ powers n ↔ x✝ ∈ closure {n}
[PROOFSTEP]
exact mem_closure_singleton.symm
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : Monoid M
inst✝ : DecidableEq M
n : M
h : Function.Injective fun m => n ^ m
x✝¹ x✝ : Multiplicative ℕ
⊢ Equiv.toFun
      { toFun := fun m => pow n (↑Multiplicative.toAdd m), invFun := fun m => ↑Multiplicative.ofAdd (log m),
        left_inv := (_ : ∀ (m : ℕ), log (pow n m) = m),
        right_inv := (_ : ∀ (p : { x // x ∈ powers n }), pow n (log p) = p) }
      (x✝¹ * x✝) =
    Equiv.toFun
        { toFun := fun m => pow n (↑Multiplicative.toAdd m), invFun := fun m => ↑Multiplicative.ofAdd (log m),
          left_inv := (_ : ∀ (m : ℕ), log (pow n m) = m),
          right_inv := (_ : ∀ (p : { x // x ∈ powers n }), pow n (log p) = p) }
        x✝¹ *
      Equiv.toFun
        { toFun := fun m => pow n (↑Multiplicative.toAdd m), invFun := fun m => ↑Multiplicative.ofAdd (log m),
          left_inv := (_ : ∀ (m : ℕ), log (pow n m) = m),
          right_inv := (_ : ∀ (p : { x // x ∈ powers n }), pow n (log p) = p) }
        x✝
[PROOFSTEP]
simp only [pow, map_mul, ofAdd_add, toAdd_mul]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
N : Type u_4
F : Type u_5
inst✝¹ : Monoid N
inst✝ : MonoidHomClass F M N
f : F
m : M
⊢ map f (powers m) = powers (↑f m)
[PROOFSTEP]
simp only [powers_eq_closure, map_mclosure f, Set.image_singleton]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
hcomm : ∀ (a : M), a ∈ s → ∀ (b : M), b ∈ s → a * b = b * a
src✝ : Monoid { x // x ∈ closure s } := toMonoid (closure s)
x y : { x // x ∈ closure s }
⊢ x * y = y * x
[PROOFSTEP]
ext
[GOAL]
case a
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
hcomm : ∀ (a : M), a ∈ s → ∀ (b : M), b ∈ s → a * b = b * a
src✝ : Monoid { x // x ∈ closure s } := toMonoid (closure s)
x y : { x // x ∈ closure s }
⊢ ↑(x * y) = ↑(y * x)
[PROOFSTEP]
simp only [Submonoid.coe_mul]
[GOAL]
case a
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
s : Set M
hcomm : ∀ (a : M), a ∈ s → ∀ (b : M), b ∈ s → a * b = b * a
src✝ : Monoid { x // x ∈ closure s } := toMonoid (closure s)
x y : { x // x ∈ closure s }
⊢ ↑x * ↑y = ↑y * ↑x
[PROOFSTEP]
exact
  closure_induction₂ x.prop y.prop hcomm Commute.one_left Commute.one_right (fun x y z => Commute.mul_left) fun x y z =>
    Commute.mul_right
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝³ : Monoid M
inst✝² : MulAction M N
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), (x • y) • z = x • y • z
⊢ IsScalarTower M N α
[PROOFSTEP]
refine' ⟨fun x => Submonoid.induction_of_closure_eq_top_left htop x _ _⟩
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝³ : Monoid M
inst✝² : MulAction M N
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), (x • y) • z = x • y • z
x : M
⊢ ∀ (y : N) (z : α), (1 • y) • z = 1 • y • z
[PROOFSTEP]
intro y z
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝³ : Monoid M
inst✝² : MulAction M N
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), (x • y) • z = x • y • z
x : M
y : N
z : α
⊢ (1 • y) • z = 1 • y • z
[PROOFSTEP]
rw [one_smul, one_smul]
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝³ : Monoid M
inst✝² : MulAction M N
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), (x • y) • z = x • y • z
x : M
⊢ ∀ (x : M),
    x ∈ s →
      ∀ (y : M),
        (∀ (y_1 : N) (z : α), (y • y_1) • z = y • y_1 • z) →
          ∀ (y_1 : N) (z : α), ((x * y) • y_1) • z = (x * y) • y_1 • z
[PROOFSTEP]
clear x
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝³ : Monoid M
inst✝² : MulAction M N
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), (x • y) • z = x • y • z
⊢ ∀ (x : M),
    x ∈ s →
      ∀ (y : M),
        (∀ (y_1 : N) (z : α), (y • y_1) • z = y • y_1 • z) →
          ∀ (y_1 : N) (z : α), ((x * y) • y_1) • z = (x * y) • y_1 • z
[PROOFSTEP]
intro x hx x' hx' y z
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝³ : Monoid M
inst✝² : MulAction M N
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), (x • y) • z = x • y • z
x : M
hx : x ∈ s
x' : M
hx' : ∀ (y : N) (z : α), (x' • y) • z = x' • y • z
y : N
z : α
⊢ ((x * x') • y) • z = (x * x') • y • z
[PROOFSTEP]
rw [mul_smul, mul_smul, hs x hx, hx']
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝² : Monoid M
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), x • y • z = y • x • z
⊢ SMulCommClass M N α
[PROOFSTEP]
refine' ⟨fun x => Submonoid.induction_of_closure_eq_top_left htop x _ _⟩
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝² : Monoid M
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), x • y • z = y • x • z
x : M
⊢ ∀ (n : N) (a : α), 1 • n • a = n • 1 • a
[PROOFSTEP]
intro y z
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝² : Monoid M
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), x • y • z = y • x • z
x : M
y : N
z : α
⊢ 1 • y • z = y • 1 • z
[PROOFSTEP]
rw [one_smul, one_smul]
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝² : Monoid M
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), x • y • z = y • x • z
x : M
⊢ ∀ (x : M),
    x ∈ s → ∀ (y : M), (∀ (n : N) (a : α), y • n • a = n • y • a) → ∀ (n : N) (a : α), (x * y) • n • a = n • (x * y) • a
[PROOFSTEP]
clear x
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝² : Monoid M
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), x • y • z = y • x • z
⊢ ∀ (x : M),
    x ∈ s → ∀ (y : M), (∀ (n : N) (a : α), y • n • a = n • y • a) → ∀ (n : N) (a : α), (x * y) • n • a = n • (x * y) • a
[PROOFSTEP]
intro x hx x' hx' y z
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
α : Type u_5
inst✝² : Monoid M
inst✝¹ : SMul N α
inst✝ : MulAction M α
s : Set M
htop : Submonoid.closure s = ⊤
hs : ∀ (x : M), x ∈ s → ∀ (y : N) (z : α), x • y • z = y • x • z
x : M
hx : x ∈ s
x' : M
hx' : ∀ (n : N) (a : α), x' • n • a = n • x' • a
y : N
z : α
⊢ (x * x') • y • z = y • (x * x') • z
[PROOFSTEP]
rw [mul_smul, mul_smul, hx', hs x hx]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
inst✝ : CommMonoid N
s t : Submonoid N
⊢ s ⊔ t = mrange (coprod (subtype s) (subtype t))
[PROOFSTEP]
rw [mrange_eq_map, ← mrange_inl_sup_mrange_inr, map_sup, map_mrange, coprod_comp_inl, map_mrange, coprod_comp_inr,
  range_subtype, range_subtype]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
N : Type u_4
inst✝ : CommMonoid N
s t : Submonoid N
x : N
⊢ x ∈ s ⊔ t ↔ ∃ y, y ∈ s ∧ ∃ z, z ∈ t ∧ y * z = x
[PROOFSTEP]
simp only [ge_iff_le, sup_eq_range, mem_mrange, coprod_apply, coe_subtype, Prod.exists, Subtype.exists, exists_prop]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
x y : A
⊢ y ∈ closure {x} ↔ ∃ n, n • x = y
[PROOFSTEP]
rw [closure_singleton_eq, AddMonoidHom.mem_mrange]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
x y : A
⊢ (∃ x_1, ↑(↑(multiplesHom A) x) x_1 = y) ↔ ∃ n, n • x = y
[PROOFSTEP]
rfl
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
⊢ closure {0} = ⊥
[PROOFSTEP]
simp [eq_bot_iff_forall, mem_closure_singleton, nsmul_zero]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
x n : A
i : ℕ
⊢ (fun i => i • x) i = n ↔ ↑(↑(multiplesHom A) x) i = n
[PROOFSTEP]
simp
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a b : R
ha : a ∈ AddSubmonoid.closure ↑S
hb : b ∈ S
⊢ a * b ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
revert b
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a : R
ha : a ∈ AddSubmonoid.closure ↑S
⊢ ∀ {b : R}, b ∈ S → a * b ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
refine' @AddSubmonoid.closure_induction _ _ _ (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure S) _ ha _ _ _
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a : R
ha : a ∈ AddSubmonoid.closure ↑S
⊢ ∀ (x : R), x ∈ ↑S → (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) x
[PROOFSTEP]
clear ha a
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a : R
ha : a ∈ AddSubmonoid.closure ↑S
⊢ (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) 0
[PROOFSTEP]
clear ha a
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a : R
ha : a ∈ AddSubmonoid.closure ↑S
⊢ ∀ (x y : R),
    (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) x →
      (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) y →
        (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) (x + y)
[PROOFSTEP]
clear ha a
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ ∀ (x : R), x ∈ ↑S → (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) x
[PROOFSTEP]
exact fun r hr b hb => AddSubmonoid.mem_closure.mpr fun y hy => hy (mul_mem hr hb)
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) 0
[PROOFSTEP]
exact fun b _ => by simp only [zero_mul, (AddSubmonoid.closure (S : Set R)).zero_mem]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
b : R
x✝ : b ∈ S
⊢ 0 * b ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
simp only [zero_mul, (AddSubmonoid.closure (S : Set R)).zero_mem]
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ ∀ (x y : R),
    (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) x →
      (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) y →
        (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure ↑S) (x + y)
[PROOFSTEP]
simp_rw [add_mul]
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ ∀ (x y : R),
    (∀ (b : R), b ∈ S → x * b ∈ AddSubmonoid.closure ↑S) →
      (∀ (b : R), b ∈ S → y * b ∈ AddSubmonoid.closure ↑S) → ∀ (b : R), b ∈ S → x * b + y * b ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
exact fun r s hr hs b hb => (AddSubmonoid.closure (S : Set R)).add_mem (hr _ hb) (hs _ hb)
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a b : R
ha : a ∈ AddSubmonoid.closure ↑S
hb : b ∈ AddSubmonoid.closure ↑S
⊢ a * b ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
revert a
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
b : R
hb : b ∈ AddSubmonoid.closure ↑S
⊢ ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * b ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
refine'
  @AddSubmonoid.closure_induction _ _ _
    (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) _ hb _ _ _
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
b : R
hb : b ∈ AddSubmonoid.closure ↑S
⊢ ∀ (x : R), x ∈ ↑S → (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) x
[PROOFSTEP]
clear hb b
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
b : R
hb : b ∈ AddSubmonoid.closure ↑S
⊢ (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) 0
[PROOFSTEP]
clear hb b
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
b : R
hb : b ∈ AddSubmonoid.closure ↑S
⊢ ∀ (x y : R),
    (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) x →
      (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) y →
        (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) (x + y)
[PROOFSTEP]
clear hb b
[GOAL]
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ ∀ (x : R), x ∈ ↑S → (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) x
[PROOFSTEP]
exact fun r hr b hb => MulMemClass.mul_right_mem_add_closure hb hr
[GOAL]
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) 0
[PROOFSTEP]
exact fun _ => by simp only [mul_zero, (AddSubmonoid.closure (S : Set R)).zero_mem]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
a✝ : R
x✝ : a✝ ∈ AddSubmonoid.closure ↑S
⊢ a✝ * 0 ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
simp only [mul_zero, (AddSubmonoid.closure (S : Set R)).zero_mem]
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ ∀ (x y : R),
    (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) x →
      (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) y →
        (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) (x + y)
[PROOFSTEP]
simp_rw [mul_add]
[GOAL]
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
R : Type u_4
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : SetLike M R
inst✝ : MulMemClass M R
S : M
⊢ ∀ (x y : R),
    (∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * x ∈ AddSubmonoid.closure ↑S) →
      (∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * y ∈ AddSubmonoid.closure ↑S) →
        ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * x + a * y ∈ AddSubmonoid.closure ↑S
[PROOFSTEP]
exact fun r s hr hs b hb => (AddSubmonoid.closure (S : Set R)).add_mem (hr hb) (hs hb)
[GOAL]
M : Type u_1
A✝ : Type u_2
B : Type u_3
A : Type u_4
inst✝ : CommMonoid A
a b c : A
⊢ c ∈ closure {a, b} ↔ ∃ m n, a ^ m * b ^ n = c
[PROOFSTEP]
rw [← Set.singleton_union, Submonoid.closure_union, mem_sup]
[GOAL]
M : Type u_1
A✝ : Type u_2
B : Type u_3
A : Type u_4
inst✝ : CommMonoid A
a b c : A
⊢ (∃ y, y ∈ closure {a} ∧ ∃ z, z ∈ closure {b} ∧ y * z = c) ↔ ∃ m n, a ^ m * b ^ n = c
[PROOFSTEP]
simp_rw [mem_closure_singleton, exists_exists_eq_and]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
⊢ ↑Additive.ofMul '' ↑(Submonoid.powers x) = ↑(AddSubmonoid.multiples (↑Additive.ofMul x))
[PROOFSTEP]
ext
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
⊢ x✝ ∈ ↑Additive.ofMul '' ↑(Submonoid.powers x) ↔ x✝ ∈ ↑(AddSubmonoid.multiples (↑Additive.ofMul x))
[PROOFSTEP]
constructor
[GOAL]
case h.mp
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
⊢ x✝ ∈ ↑Additive.ofMul '' ↑(Submonoid.powers x) → x✝ ∈ ↑(AddSubmonoid.multiples (↑Additive.ofMul x))
[PROOFSTEP]
rintro ⟨y, ⟨n, hy1⟩, hy2⟩
[GOAL]
case h.mp.intro.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
y : M
hy2 : ↑Additive.ofMul y = x✝
n : ℕ
hy1 : (fun x x_1 => x ^ x_1) x n = y
⊢ x✝ ∈ ↑(AddSubmonoid.multiples (↑Additive.ofMul x))
[PROOFSTEP]
use n
[GOAL]
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
y : M
hy2 : ↑Additive.ofMul y = x✝
n : ℕ
hy1 : (fun x x_1 => x ^ x_1) x n = y
⊢ (fun i => i • ↑Additive.ofMul x) n = x✝
[PROOFSTEP]
simpa [← ofMul_pow, hy1]
[GOAL]
case h.mpr
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
⊢ x✝ ∈ ↑(AddSubmonoid.multiples (↑Additive.ofMul x)) → x✝ ∈ ↑Additive.ofMul '' ↑(Submonoid.powers x)
[PROOFSTEP]
rintro ⟨n, hn⟩
[GOAL]
case h.mpr.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
n : ℕ
hn : (fun i => i • ↑Additive.ofMul x) n = x✝
⊢ x✝ ∈ ↑Additive.ofMul '' ↑(Submonoid.powers x)
[PROOFSTEP]
refine' ⟨x ^ n, ⟨n, rfl⟩, _⟩
[GOAL]
case h.mpr.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
x : M
x✝ : Additive M
n : ℕ
hn : (fun i => i • ↑Additive.ofMul x) n = x✝
⊢ ↑Additive.ofMul (x ^ n) = x✝
[PROOFSTEP]
rwa [ofMul_pow]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
x : A
⊢ ↑Multiplicative.ofAdd '' ↑(AddSubmonoid.multiples x) = ↑(Submonoid.powers (↑Multiplicative.ofAdd x))
[PROOFSTEP]
symm
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
x : A
⊢ ↑(Submonoid.powers (↑Multiplicative.ofAdd x)) = ↑Multiplicative.ofAdd '' ↑(AddSubmonoid.multiples x)
[PROOFSTEP]
rw [Equiv.eq_image_iff_symm_image_eq]
[GOAL]
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : AddMonoid A
x : A
⊢ ↑Multiplicative.ofAdd.symm '' ↑(Submonoid.powers (↑Multiplicative.ofAdd x)) = ↑(AddSubmonoid.multiples x)
[PROOFSTEP]
exact ofMul_image_powers_eq_multiples_ofMul


[GOAL]
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
⊢ f ≫
      mkHom (AddSubgroup.normedMk (NormedAddGroupHom.range ↑f))
        (_ : ∀ (m : ↑Y), ‖↑(AddSubgroup.normedMk (NormedAddGroupHom.range ↑f)) m‖ ≤ ‖m‖) =
    0 ≫
      mkHom (AddSubgroup.normedMk (NormedAddGroupHom.range ↑f))
        (_ : ∀ (m : ↑Y), ‖↑(AddSubgroup.normedMk (NormedAddGroupHom.range ↑f)) m‖ ≤ ‖m‖)
[PROOFSTEP]
ext x
[GOAL]
case w.h
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
x : ↑X
⊢ ↑(f ≫
          mkHom (AddSubgroup.normedMk (NormedAddGroupHom.range ↑f))
            (_ : ∀ (m : ↑Y), ‖↑(AddSubgroup.normedMk (NormedAddGroupHom.range ↑f)) m‖ ≤ ‖m‖))
      x =
    ↑(0 ≫
          mkHom (AddSubgroup.normedMk (NormedAddGroupHom.range ↑f))
            (_ : ∀ (m : ↑Y), ‖↑(AddSubgroup.normedMk (NormedAddGroupHom.range ↑f)) m‖ ≤ ‖m‖))
      x
[PROOFSTEP]
rw [Limits.zero_comp, comp_apply, SemiNormedGroupCat₁.mkHom_apply, SemiNormedGroupCat₁.zero_apply, ←
  NormedAddGroupHom.mem_ker, f.1.range.ker_normedMk, f.1.mem_range]
[GOAL]
case w.h
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
x : ↑X
⊢ ∃ w, ↑↑f w = ↑f x
[PROOFSTEP]
use x
[GOAL]
case h
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
x : ↑X
⊢ ↑↑f x = ↑f x
[PROOFSTEP]
rfl
[GOAL]
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
s : CokernelCofork f
⊢ (cokernelCocone f).pt ⟶ s.pt
[PROOFSTEP]
fconstructor
  -- The lift itself:
[GOAL]
case val
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
s : CokernelCofork f
⊢ NormedAddGroupHom ↑(cokernelCocone f).pt ↑s.pt
[PROOFSTEP]
apply NormedAddGroupHom.lift _ s.π.1
[GOAL]
case val
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
s : CokernelCofork f
⊢ ∀ (s_1 : ↑((parallelPair f 0).obj WalkingParallelPair.one)), s_1 ∈ NormedAddGroupHom.range ↑f → ↑↑(Cofork.π s) s_1 = 0
[PROOFSTEP]
rintro _ ⟨b, rfl⟩
[GOAL]
case val.intro
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
s : CokernelCofork f
b : ↑X
⊢ ↑↑(Cofork.π s) (↑(NormedAddGroupHom.toAddMonoidHom ↑f) b) = 0
[PROOFSTEP]
change (f ≫ s.π) b = 0
[GOAL]
case val.intro
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
s : CokernelCofork f
b : ↑X
⊢ ↑(f ≫ Cofork.π s) b = 0
[PROOFSTEP]
simp
  -- The lift has norm at most one:
[GOAL]
case property
X Y : SemiNormedGroupCat₁
f : X ⟶ Y
s : CokernelCofork f
⊢ NormedAddGroupHom.NormNoninc
    (NormedAddGroupHom.lift (NormedAddGroupHom.range ↑f) ↑(Cofork.π s)
      (_ :
        ∀ (s_1 : ↑((parallelPair f 0).obj WalkingParallelPair.one)),
          s_1 ∈ NormedAddGroupHom.range ↑f → ↑↑(Cofork.π s) s_1 = 0))
[PROOFSTEP]
exact NormedAddGroupHom.lift_normNoninc _ _ _ s.π.2
[GOAL]
X✝ Y✝ : SemiNormedGroupCat₁
f : X✝ ⟶ Y✝
s : CokernelCofork f
⊢ Cofork.π (cokernelCocone f) ≫ cokernelLift f s = Cofork.π s
[PROOFSTEP]
ext
[GOAL]
case w.h
X✝ Y✝ : SemiNormedGroupCat₁
f : X✝ ⟶ Y✝
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
⊢ ↑(Cofork.π (cokernelCocone f) ≫ cokernelLift f s) x✝ = ↑(Cofork.π s) x✝
[PROOFSTEP]
apply NormedAddGroupHom.lift_mk f.1.range
[GOAL]
case w.h.hf
X✝ Y✝ : SemiNormedGroupCat₁
f : X✝ ⟶ Y✝
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
⊢ ∀ (s_1 : ↑Y✝), s_1 ∈ NormedAddGroupHom.range ↑f → ↑↑(Cofork.π s) s_1 = 0
[PROOFSTEP]
rintro _ ⟨b, rfl⟩
[GOAL]
case w.h.hf.intro
X✝ Y✝ : SemiNormedGroupCat₁
f : X✝ ⟶ Y✝
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
b : ↑X✝
⊢ ↑↑(Cofork.π s) (↑(NormedAddGroupHom.toAddMonoidHom ↑f) b) = 0
[PROOFSTEP]
change (f ≫ s.π) b = 0
[GOAL]
case w.h.hf.intro
X✝ Y✝ : SemiNormedGroupCat₁
f : X✝ ⟶ Y✝
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
b : ↑X✝
⊢ ↑(f ≫ Cofork.π s) b = 0
[PROOFSTEP]
simp
[GOAL]
⊢ HasCokernels SemiNormedGroupCat₁
[PROOFSTEP]
infer_instance
[GOAL]
V W : SemiNormedGroupCat
f g : V ⟶ W
⊢ NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ f =
    NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ g
[PROOFSTEP]
change NormedAddGroupHom V W at f g
[GOAL]
V W : SemiNormedGroupCat
f g : NormedAddGroupHom ↑V ↑W
⊢ NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ f =
    NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ g
[PROOFSTEP]
ext v
[GOAL]
case h
V W : SemiNormedGroupCat
f g : NormedAddGroupHom ↑V ↑W
v : ↑(of { x // x ∈ NormedAddGroupHom.ker (f - g) })
⊢ ↑(NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ f) v =
    ↑(NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ g) v
[PROOFSTEP]
have : v.1 ∈ (f - g).ker := v.2
[GOAL]
case h
V W : SemiNormedGroupCat
f g : NormedAddGroupHom ↑V ↑W
v : ↑(of { x // x ∈ NormedAddGroupHom.ker (f - g) })
this : ↑v ∈ NormedAddGroupHom.ker (f - g)
⊢ ↑(NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ f) v =
    ↑(NormedAddGroupHom.incl (NormedAddGroupHom.ker (f - g)) ≫ g) v
[PROOFSTEP]
simpa only [NormedAddGroupHom.incl_apply, Pi.zero_apply, coe_comp, NormedAddGroupHom.coe_zero,
  NormedAddGroupHom.mem_ker, NormedAddGroupHom.coe_sub, Pi.sub_apply, sub_eq_zero] using this
[GOAL]
V W : SemiNormedGroupCat
f g : V ⟶ W
c : Fork f g
⊢ ↑(↑NormedAddGroupHom.compHom (f - g)) (Fork.ι c) = 0
[PROOFSTEP]
rw [AddMonoidHom.map_sub, AddMonoidHom.sub_apply, sub_eq_zero]
[GOAL]
V W : SemiNormedGroupCat
f g : V ⟶ W
c : Fork f g
⊢ ↑(↑NormedAddGroupHom.compHom f) (Fork.ι c) = ↑(↑NormedAddGroupHom.compHom g) (Fork.ι c)
[PROOFSTEP]
exact c.condition
[GOAL]
V W : SemiNormedGroupCat
f g✝ : V ⟶ W
c : Fork f g✝
g : c.pt ⟶ (fork f g✝).pt
h : g ≫ Fork.ι (fork f g✝) = Fork.ι c
⊢ g =
    (fun c =>
        NormedAddGroupHom.ker.lift (Fork.ι c) (f - g✝) (_ : ↑(↑NormedAddGroupHom.compHom (f - g✝)) (Fork.ι c) = 0))
      c
[PROOFSTEP]
ext x
[GOAL]
case h
V W : SemiNormedGroupCat
f g✝ : V ⟶ W
c : Fork f g✝
g : c.pt ⟶ (fork f g✝).pt
h : g ≫ Fork.ι (fork f g✝) = Fork.ι c
x : ↑c.pt
⊢ ↑g x =
    ↑((fun c =>
            NormedAddGroupHom.ker.lift (Fork.ι c) (f - g✝) (_ : ↑(↑NormedAddGroupHom.compHom (f - g✝)) (Fork.ι c) = 0))
          c)
      x
[PROOFSTEP]
dsimp
[GOAL]
case h
V W : SemiNormedGroupCat
f g✝ : V ⟶ W
c : Fork f g✝
g : c.pt ⟶ (fork f g✝).pt
h : g ≫ Fork.ι (fork f g✝) = Fork.ι c
x : ↑c.pt
⊢ ↑g x =
    ↑(NormedAddGroupHom.ker.lift (Fork.ι c) (f - g✝)
          (_ : ↑(↑NormedAddGroupHom.compHom f) (Fork.ι c) - ↑(↑NormedAddGroupHom.compHom g✝) (Fork.ι c) = 0))
      x
[PROOFSTEP]
simp_rw [← h]
[GOAL]
case h
V W : SemiNormedGroupCat
f g✝ : V ⟶ W
c : Fork f g✝
g : c.pt ⟶ (fork f g✝).pt
h : g ≫ Fork.ι (fork f g✝) = Fork.ι c
x : ↑c.pt
⊢ ↑g x =
    ↑(NormedAddGroupHom.ker.lift (g ≫ Fork.ι (fork f g✝)) (f - g✝)
          (_ : NormedAddGroupHom.comp (f - g✝) (g ≫ Fork.ι (fork f g✝)) = 0))
      x
[PROOFSTEP]
rfl
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
⊢ f ≫ AddSubgroup.normedMk (NormedAddGroupHom.range f) = 0 ≫ AddSubgroup.normedMk (NormedAddGroupHom.range f)
[PROOFSTEP]
ext
[GOAL]
case h
X Y : SemiNormedGroupCat
f : X ⟶ Y
x✝ : ↑X
⊢ ↑(f ≫ AddSubgroup.normedMk (NormedAddGroupHom.range f)) x✝ =
    ↑(0 ≫ AddSubgroup.normedMk (NormedAddGroupHom.range f)) x✝
[PROOFSTEP]
simp only [comp_apply, Limits.zero_comp]
  -- porting note: `simp` not firing on the below
[GOAL]
case h
X Y : SemiNormedGroupCat
f : X ⟶ Y
x✝ : ↑X
⊢ ↑(f ≫ AddSubgroup.normedMk (NormedAddGroupHom.range f)) x✝ = ↑0 x✝
[PROOFSTEP]
rw [comp_apply, NormedAddGroupHom.zero_apply]
  -- porting note: Lean 3 didn't need this instance
[GOAL]
case h
X Y : SemiNormedGroupCat
f : X ⟶ Y
x✝ : ↑X
⊢ ↑(AddSubgroup.normedMk (NormedAddGroupHom.range f)) (↑f x✝) = 0
[PROOFSTEP]
letI : SeminormedAddCommGroup ((forget SemiNormedGroupCat).obj Y) :=
  (inferInstance : SeminormedAddCommGroup Y)
    -- porting note: again simp doesn't seem to be firing in the below line
[GOAL]
case h
X Y : SemiNormedGroupCat
f : X ⟶ Y
x✝ : ↑X
this : SeminormedAddCommGroup ((forget SemiNormedGroupCat).obj Y) := inferInstance
⊢ ↑(AddSubgroup.normedMk (NormedAddGroupHom.range f)) (↑f x✝) = 0
[PROOFSTEP]
rw [← NormedAddGroupHom.mem_ker, f.range.ker_normedMk, f.mem_range]
[GOAL]
case h
X Y : SemiNormedGroupCat
f : X ⟶ Y
x✝ : ↑X
this : SeminormedAddCommGroup ((forget SemiNormedGroupCat).obj Y) := inferInstance
⊢ ∃ w, ↑f w = ↑f x✝
[PROOFSTEP]
simp only [exists_apply_eq_apply]
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
⊢ ∀ (s_1 : ↑Y), s_1 ∈ NormedAddGroupHom.range f → ↑(Cofork.π s) s_1 = 0
[PROOFSTEP]
rintro _ ⟨b, rfl⟩
[GOAL]
case intro
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
b : ↑X
⊢ ↑(Cofork.π s) (↑(NormedAddGroupHom.toAddMonoidHom f) b) = 0
[PROOFSTEP]
change (f ≫ s.π) b = 0
[GOAL]
case intro
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
b : ↑X
⊢ ↑(f ≫ Cofork.π s) b = 0
[PROOFSTEP]
simp
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
⊢ Cofork.π (cokernelCocone f) ≫ cokernelLift f s = Cofork.π s
[PROOFSTEP]
ext
[GOAL]
case h
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
⊢ ↑(Cofork.π (cokernelCocone f) ≫ cokernelLift f s) x✝ = ↑(Cofork.π s) x✝
[PROOFSTEP]
apply NormedAddGroupHom.lift_mk f.range
[GOAL]
case h.hf
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
⊢ ∀ (s_1 : ↑Y), s_1 ∈ NormedAddGroupHom.range f → ↑(Cofork.π s) s_1 = 0
[PROOFSTEP]
rintro _ ⟨b, rfl⟩
[GOAL]
case h.hf.intro
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
b : ↑X
⊢ ↑(Cofork.π s) (↑(NormedAddGroupHom.toAddMonoidHom f) b) = 0
[PROOFSTEP]
change (f ≫ s.π) b = 0
[GOAL]
case h.hf.intro
X Y : SemiNormedGroupCat
f : X ⟶ Y
s : CokernelCofork f
x✝ : ↑((parallelPair f 0).obj WalkingParallelPair.one)
b : ↑X
⊢ ↑(f ≫ Cofork.π s) b = 0
[PROOFSTEP]
simp
[GOAL]
⊢ HasCokernels SemiNormedGroupCat
[PROOFSTEP]
infer_instance
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ f ≫ g = 0 ≫ g
[PROOFSTEP]
simp [w]
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
⊢ f ≫ explicitCokernelπ f = 0
[PROOFSTEP]
convert (cokernelCocone f).w WalkingParallelPairHom.left
[GOAL]
case h.e'_3.h
X Y : SemiNormedGroupCat
f : X ⟶ Y
e_1✝ :
  (X ⟶ explicitCokernel f) =
    ((parallelPair f 0).obj WalkingParallelPair.zero ⟶
      ((Functor.const WalkingParallelPair).obj (cokernelCocone f).pt).obj WalkingParallelPair.one)
⊢ 0 = NatTrans.app (cokernelCocone f).ι WalkingParallelPair.zero
[PROOFSTEP]
simp
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
x : ↑X
⊢ ↑(f ≫ explicitCokernelπ f) x = 0
[PROOFSTEP]
rw [comp_explicitCokernelπ]
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
x : ↑X
⊢ ↑0 x = 0
[PROOFSTEP]
rfl
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
cond : f ≫ g = 0
x : ↑Y
⊢ ↑(explicitCokernelπ f ≫ explicitCokernelDesc cond) x = ↑g x
[PROOFSTEP]
rw [explicitCokernelπ_desc]
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
e : explicitCokernel f ⟶ Z
he : explicitCokernelπ f ≫ e = g
⊢ e = explicitCokernelDesc w
[PROOFSTEP]
apply (isColimitCokernelCocone f).uniq (Cofork.ofπ g (by simp [w]))
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
e : explicitCokernel f ⟶ Z
he : explicitCokernelπ f ≫ e = g
⊢ f ≫ g = 0 ≫ g
[PROOFSTEP]
simp [w]
[GOAL]
case x
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
e : explicitCokernel f ⟶ Z
he : explicitCokernelπ f ≫ e = g
⊢ ∀ (j : WalkingParallelPair),
    NatTrans.app (cokernelCocone f).ι j ≫ e = NatTrans.app (Cofork.ofπ g (_ : f ≫ g = 0 ≫ g)).ι j
[PROOFSTEP]
rintro (_ | _)
[GOAL]
case x.zero
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
e : explicitCokernel f ⟶ Z
he : explicitCokernelπ f ≫ e = g
⊢ NatTrans.app (cokernelCocone f).ι WalkingParallelPair.zero ≫ e =
    NatTrans.app (Cofork.ofπ g (_ : f ≫ g = 0 ≫ g)).ι WalkingParallelPair.zero
[PROOFSTEP]
convert w.symm
[GOAL]
case h.e'_2.h
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
e : explicitCokernel f ⟶ Z
he : explicitCokernelπ f ≫ e = g
e_1✝ : ((parallelPair f 0).obj WalkingParallelPair.zero ⟶ (Cofork.ofπ g (_ : f ≫ g = 0 ≫ g)).pt) = (X ⟶ Z)
⊢ NatTrans.app (cokernelCocone f).ι WalkingParallelPair.zero ≫ e = 0
[PROOFSTEP]
simp
[GOAL]
case x.one
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
e : explicitCokernel f ⟶ Z
he : explicitCokernelπ f ≫ e = g
⊢ NatTrans.app (cokernelCocone f).ι WalkingParallelPair.one ≫ e =
    NatTrans.app (Cofork.ofπ g (_ : f ≫ g = 0 ≫ g)).ι WalkingParallelPair.one
[PROOFSTEP]
exact he
[GOAL]
X Y Z W : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
cond' : f ≫ g = 0
⊢ f ≫ g ≫ h = 0
[PROOFSTEP]
rw [← CategoryTheory.Category.assoc, cond', Limits.zero_comp]
[GOAL]
X Y Z W : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
cond' : f ≫ g = 0
⊢ explicitCokernelDesc cond' ≫ h = explicitCokernelDesc (_ : f ≫ g ≫ h = 0)
[PROOFSTEP]
refine' explicitCokernelDesc_unique _ _ _
[GOAL]
X Y Z W : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
cond' : f ≫ g = 0
⊢ explicitCokernelπ f ≫ explicitCokernelDesc cond' ≫ h = g ≫ h
[PROOFSTEP]
rw [← CategoryTheory.Category.assoc, explicitCokernelπ_desc]
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
⊢ e₁ = e₂
[PROOFSTEP]
let g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
⊢ e₁ = e₂
[PROOFSTEP]
have w : f ≫ g = 0 := by simp
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
⊢ f ≫ g = 0
[PROOFSTEP]
simp
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
w : f ≫ g = 0
⊢ e₁ = e₂
[PROOFSTEP]
have : e₂ = explicitCokernelDesc w := by apply explicitCokernelDesc_unique; rfl
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
w : f ≫ g = 0
⊢ e₂ = explicitCokernelDesc w
[PROOFSTEP]
apply explicitCokernelDesc_unique
[GOAL]
case he
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
w : f ≫ g = 0
⊢ explicitCokernelπ f ≫ e₂ = g
[PROOFSTEP]
rfl
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
w : f ≫ g = 0
this : e₂ = explicitCokernelDesc w
⊢ e₁ = e₂
[PROOFSTEP]
rw [this]
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
w : f ≫ g = 0
this : e₂ = explicitCokernelDesc w
⊢ e₁ = explicitCokernelDesc w
[PROOFSTEP]
apply explicitCokernelDesc_unique
[GOAL]
case he
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
e₁ e₂ : explicitCokernel f ⟶ Z
h : explicitCokernelπ f ≫ e₁ = explicitCokernelπ f ≫ e₂
g : Y ⟶ Z := explicitCokernelπ f ≫ e₂
w : f ≫ g = 0
this : e₂ = explicitCokernelDesc w
⊢ explicitCokernelπ f ≫ e₁ = g
[PROOFSTEP]
exact h
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
⊢ Epi (explicitCokernelπ f)
[PROOFSTEP]
constructor
[GOAL]
case left_cancellation
X Y : SemiNormedGroupCat
f : X ⟶ Y
⊢ ∀ {Z : SemiNormedGroupCat} (g h : explicitCokernel f ⟶ Z), explicitCokernelπ f ≫ g = explicitCokernelπ f ≫ h → g = h
[PROOFSTEP]
intro Z g h H
[GOAL]
case left_cancellation
X Y : SemiNormedGroupCat
f : X ⟶ Y
Z : SemiNormedGroupCat
g h : explicitCokernel f ⟶ Z
H : explicitCokernelπ f ≫ g = explicitCokernelπ f ≫ h
⊢ g = h
[PROOFSTEP]
ext x
[GOAL]
case left_cancellation.h.h
X Y : SemiNormedGroupCat
f : X ⟶ Y
Z : SemiNormedGroupCat
g h : explicitCokernel f ⟶ Z
H : explicitCokernelπ f ≫ g = explicitCokernelπ f ≫ h
x : ↑Y
⊢ ↑(explicitCokernelπ f ≫ g) x = ↑(explicitCokernelπ f ≫ h) x
[PROOFSTEP]
rw [H]
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
cond : f ≫ g = 0
hg : NormedAddGroupHom.NormNoninc g
⊢ NormedAddGroupHom.NormNoninc (explicitCokernelDesc cond)
[PROOFSTEP]
refine' NormedAddGroupHom.NormNoninc.normNoninc_iff_norm_le_one.2 _
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
cond : f ≫ g = 0
hg : NormedAddGroupHom.NormNoninc g
⊢ ‖explicitCokernelDesc cond‖ ≤ 1
[PROOFSTEP]
rw [← NNReal.coe_one]
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
cond : f ≫ g = 0
hg : NormedAddGroupHom.NormNoninc g
⊢ ‖explicitCokernelDesc cond‖ ≤ ↑1
[PROOFSTEP]
exact explicitCokernelDesc_norm_le_of_norm_le cond 1 (NormedAddGroupHom.NormNoninc.normNoninc_iff_norm_le_one.1 hg)
[GOAL]
X Y Z W : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
cond : f ≫ g = 0
cond2 : g ≫ h = 0
⊢ explicitCokernelDesc cond ≫ h = 0
[PROOFSTEP]
rw [← cancel_epi (explicitCokernelπ f), ← Category.assoc, explicitCokernelπ_desc]
[GOAL]
X Y Z W : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
h : Z ⟶ W
cond : f ≫ g = 0
cond2 : g ≫ h = 0
⊢ g ≫ h = explicitCokernelπ f ≫ 0
[PROOFSTEP]
simp [cond2]
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
⊢ explicitCokernelπ f ≫ (explicitCokernelIso f).hom = cokernel.π f
[PROOFSTEP]
simp [explicitCokernelπ, explicitCokernelIso, IsColimit.coconePointUniqueUpToIso]
[GOAL]
X Y : SemiNormedGroupCat
f : X ⟶ Y
⊢ cokernel.π f ≫ (explicitCokernelIso f).inv = explicitCokernelπ f
[PROOFSTEP]
simp [explicitCokernelπ, explicitCokernelIso]
[GOAL]
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ (explicitCokernelIso f).hom ≫ cokernel.desc f g w = explicitCokernelDesc w
[PROOFSTEP]
ext1
[GOAL]
case h
X Y Z : SemiNormedGroupCat
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ explicitCokernelπ f ≫ (explicitCokernelIso f).hom ≫ cokernel.desc f g w = explicitCokernelπ f ≫ explicitCokernelDesc w
[PROOFSTEP]
simp [explicitCokernelDesc, explicitCokernelπ, explicitCokernelIso, IsColimit.coconePointUniqueUpToIso]
[GOAL]
A B C D : SemiNormedGroupCat
fab : A ⟶ B
fbd : B ⟶ D
fac : A ⟶ C
fcd : C ⟶ D
h : fab ≫ fbd = fac ≫ fcd
⊢ fab ≫ fbd ≫ explicitCokernelπ fcd = 0
[PROOFSTEP]
simp [reassoc_of% h]
[GOAL]
A B C D B' D' : SemiNormedGroupCat
fab : A ⟶ B
fbd : B ⟶ D
fac : A ⟶ C
fcd : C ⟶ D
h : fab ≫ fbd = fac ≫ fcd
fbb' : B ⟶ B'
fdd' : D ⟶ D'
condb : fab ≫ fbb' = 0
condd : fcd ≫ fdd' = 0
g : B' ⟶ D'
h' : fbb' ≫ g = fbd ≫ fdd'
⊢ explicitCokernelDesc condb ≫ g = explicitCokernel.map h ≫ explicitCokernelDesc condd
[PROOFSTEP]
delta explicitCokernel.map
[GOAL]
A B C D B' D' : SemiNormedGroupCat
fab : A ⟶ B
fbd : B ⟶ D
fac : A ⟶ C
fcd : C ⟶ D
h : fab ≫ fbd = fac ≫ fcd
fbb' : B ⟶ B'
fdd' : D ⟶ D'
condb : fab ≫ fbb' = 0
condd : fcd ≫ fdd' = 0
g : B' ⟶ D'
h' : fbb' ≫ g = fbd ≫ fdd'
⊢ explicitCokernelDesc condb ≫ g =
    explicitCokernelDesc (_ : fab ≫ fbd ≫ explicitCokernelπ fcd = 0) ≫ explicitCokernelDesc condd
[PROOFSTEP]
simp [← cancel_epi (explicitCokernelπ fab), ← Category.assoc, explicitCokernelπ_desc, h']


[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G✝ : SimpleGraph α
H✝ : SimpleGraph β
G : SimpleGraph α
H : SimpleGraph β
x y : α × β
⊢ (fun x y => Adj G x.fst y.fst ∧ x.snd = y.snd ∨ Adj H x.snd y.snd ∧ x.fst = y.fst) x y →
    (fun x y => Adj G x.fst y.fst ∧ x.snd = y.snd ∨ Adj H x.snd y.snd ∧ x.fst = y.fst) y x
[PROOFSTEP]
simp [and_comm, or_comm, eq_comm, adj_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G✝ : SimpleGraph α
H✝ : SimpleGraph β
G : SimpleGraph α
H : SimpleGraph β
x : α × β
⊢ ¬(fun x y => Adj G x.fst y.fst ∧ x.snd = y.snd ∨ Adj H x.snd y.snd ∧ x.fst = y.fst) x x
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a₁ : α
b : β
a₂ : α
⊢ Adj (G □ H) (a₁, b) (a₂, b) ↔ Adj G a₁ a₂
[PROOFSTEP]
simp only [boxProd_adj, and_true, SimpleGraph.irrefl, false_and, or_false]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
b₁ b₂ : β
⊢ Adj (G □ H) (a, b₁) (a, b₂) ↔ Adj H b₁ b₂
[PROOFSTEP]
simp only [boxProd_adj, SimpleGraph.irrefl, false_and, and_true, false_or]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
⊢ neighborSet (G □ H) x = neighborSet G x.fst ×ˢ {x.snd} ∪ {x.fst} ×ˢ neighborSet H x.snd
[PROOFSTEP]
ext ⟨a', b'⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
a' : α
b' : β
⊢ (a', b') ∈ neighborSet (G □ H) x ↔ (a', b') ∈ neighborSet G x.fst ×ˢ {x.snd} ∪ {x.fst} ×ˢ neighborSet H x.snd
[PROOFSTEP]
simp only [mem_neighborSet, Set.mem_union, boxProd_adj, Set.mem_prod, Set.mem_singleton_iff]
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
a' : α
b' : β
⊢ Adj G x.fst a' ∧ x.snd = b' ∨ Adj H x.snd b' ∧ x.fst = a' ↔ Adj G x.fst a' ∧ b' = x.snd ∨ a' = x.fst ∧ Adj H x.snd b'
[PROOFSTEP]
simp only [eq_comm, and_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
I : SimpleGraph γ
x y : (α × β) × γ
⊢ Adj (G □ (H □ I)) (↑(Equiv.prodAssoc α β γ) x) (↑(Equiv.prodAssoc α β γ) y) ↔ Adj (G □ H □ I) x y
[PROOFSTEP]
simp only [boxProd_adj, Equiv.prodAssoc_apply, or_and_right, or_assoc, Prod.ext_iff, and_assoc,
  @and_comm (x.fst.fst = _)]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
b : β
inst✝¹ : DecidableEq β
inst✝ : DecidableRel G.Adj
a₁ a₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ ofBoxProdLeft (Walk.boxProdLeft H b (cons' x y z h w)) = cons' x y z h w
[PROOFSTEP]
rw [Walk.boxProdLeft, map_cons, ofBoxProdLeft, Or.by_cases, dif_pos, ← Walk.boxProdLeft]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
b : β
inst✝¹ : DecidableEq β
inst✝ : DecidableRel G.Adj
a₁ a₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ cons (_ : Adj G (x, b).fst (↑(Embedding.toHom (boxProdLeft G H b)) y).fst) (ofBoxProdLeft (Walk.boxProdLeft H b w)) =
    cons' x y z h w
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
b : β
inst✝¹ : DecidableEq β
inst✝ : DecidableRel G.Adj
a₁ a₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (x, b).fst (↑(Embedding.toHom (boxProdLeft G H b)) y).fst ∧
    (x, b).snd = (↑(Embedding.toHom (boxProdLeft G H b)) y).snd
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
b : β
inst✝¹ : DecidableEq β
inst✝ : DecidableRel G.Adj
a₁ a₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (x, b).fst (↑(Embedding.toHom (boxProdLeft G H b)) y).fst ∧
    (x, b).snd = (↑(Embedding.toHom (boxProdLeft G H b)) y).snd
[PROOFSTEP]
simp [ofBoxProdLeft_boxProdLeft]
[GOAL]
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
b : β
inst✝¹ : DecidableEq β
inst✝ : DecidableRel G.Adj
a₁ a₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (x, b).fst (↑(Embedding.toHom (boxProdLeft G H b)) y).fst ∧
    (x, b).snd = (↑(Embedding.toHom (boxProdLeft G H b)) y).snd
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
b : β
inst✝¹ : DecidableEq β
inst✝ : DecidableRel G.Adj
a₁ a₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (x, b).fst (↑(Embedding.toHom (boxProdLeft G H b)) y).fst ∧
    (x, b).snd = (↑(Embedding.toHom (boxProdLeft G H b)) y).snd
[PROOFSTEP]
exact ⟨h, rfl⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
inst✝¹ : DecidableEq α
inst✝ : DecidableRel G.Adj
b₁ b₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ ofBoxProdRight (Walk.boxProdRight G a (cons' x y z h w)) = cons' x y z h w
[PROOFSTEP]
rw [Walk.boxProdRight, map_cons, ofBoxProdRight, Or.by_cases, dif_pos, ← Walk.boxProdRight]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
inst✝¹ : DecidableEq α
inst✝ : DecidableRel G.Adj
b₁ b₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ cons (_ : Adj G (a, x).snd (↑(Embedding.toHom (boxProdRight G G a)) y).snd)
      (ofBoxProdRight (Walk.boxProdRight G a w)) =
    cons' x y z h w
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
inst✝¹ : DecidableEq α
inst✝ : DecidableRel G.Adj
b₁ b₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (a, x).snd (↑(Embedding.toHom (boxProdRight G G a)) y).snd ∧
    (a, x).fst = (↑(Embedding.toHom (boxProdRight G G a)) y).fst
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
inst✝¹ : DecidableEq α
inst✝ : DecidableRel G.Adj
b₁ b₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (a, x).snd (↑(Embedding.toHom (boxProdRight G G a)) y).snd ∧
    (a, x).fst = (↑(Embedding.toHom (boxProdRight G G a)) y).fst
[PROOFSTEP]
simp [ofBoxProdLeft_boxProdRight]
[GOAL]
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
inst✝¹ : DecidableEq α
inst✝ : DecidableRel G.Adj
b₁ b₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (a, x).snd (↑(Embedding.toHom (boxProdRight G G a)) y).snd ∧
    (a, x).fst = (↑(Embedding.toHom (boxProdRight G G a)) y).fst
case hc
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
a : α
inst✝¹ : DecidableEq α
inst✝ : DecidableRel G.Adj
b₁ b₂ x z y : α
h : Adj G x y
w : Walk G y z
⊢ Adj G (a, x).snd (↑(Embedding.toHom (boxProdRight G G a)) y).snd ∧
    (a, x).fst = (↑(Embedding.toHom (boxProdRight G G a)) y).fst
[PROOFSTEP]
exact ⟨h, rfl⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Preconnected G
hH : Preconnected H
⊢ Preconnected (G □ H)
[PROOFSTEP]
rintro x y
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Preconnected G
hH : Preconnected H
x y : α × β
⊢ Reachable (G □ H) x y
[PROOFSTEP]
obtain ⟨w₁⟩ := hG x.1 y.1
[GOAL]
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Preconnected G
hH : Preconnected H
x y : α × β
w₁ : Walk G x.fst y.fst
⊢ Reachable (G □ H) x y
[PROOFSTEP]
obtain ⟨w₂⟩ := hH x.2 y.2
[GOAL]
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Preconnected G
hH : Preconnected H
x y : α × β
w₁ : Walk G x.fst y.fst
w₂ : Walk H x.snd y.snd
⊢ Reachable (G □ H) x y
[PROOFSTEP]
rw [← @Prod.mk.eta _ _ x, ← @Prod.mk.eta _ _ y]
[GOAL]
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Preconnected G
hH : Preconnected H
x y : α × β
w₁ : Walk G x.fst y.fst
w₂ : Walk H x.snd y.snd
⊢ Reachable (G □ H) (x.fst, x.snd) (y.fst, y.snd)
[PROOFSTEP]
exact ⟨(w₁.boxProdLeft _ _).append (w₂.boxProdRight _ _)⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty β
h : Preconnected (G □ H)
⊢ Preconnected G
[PROOFSTEP]
classical
rintro a₁ a₂
obtain ⟨w⟩ := h (a₁, Classical.arbitrary _) (a₂, Classical.arbitrary _)
exact ⟨w.ofBoxProdLeft⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty β
h : Preconnected (G □ H)
⊢ Preconnected G
[PROOFSTEP]
rintro a₁ a₂
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty β
h : Preconnected (G □ H)
a₁ a₂ : α
⊢ Reachable G a₁ a₂
[PROOFSTEP]
obtain ⟨w⟩ := h (a₁, Classical.arbitrary _) (a₂, Classical.arbitrary _)
[GOAL]
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty β
h : Preconnected (G □ H)
a₁ a₂ : α
w : Walk (G □ H) (a₁, Classical.arbitrary β) (a₂, Classical.arbitrary β)
⊢ Reachable G a₁ a₂
[PROOFSTEP]
exact ⟨w.ofBoxProdLeft⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty α
h : Preconnected (G □ H)
⊢ Preconnected H
[PROOFSTEP]
classical
rintro b₁ b₂
obtain ⟨w⟩ := h (Classical.arbitrary _, b₁) (Classical.arbitrary _, b₂)
exact ⟨w.ofBoxProdRight⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty α
h : Preconnected (G □ H)
⊢ Preconnected H
[PROOFSTEP]
rintro b₁ b₂
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty α
h : Preconnected (G □ H)
b₁ b₂ : β
⊢ Reachable H b₁ b₂
[PROOFSTEP]
obtain ⟨w⟩ := h (Classical.arbitrary _, b₁) (Classical.arbitrary _, b₂)
[GOAL]
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
inst✝ : Nonempty α
h : Preconnected (G □ H)
b₁ b₂ : β
w : Walk (G □ H) (Classical.arbitrary α, b₁) (Classical.arbitrary α, b₂)
⊢ Reachable H b₁ b₂
[PROOFSTEP]
exact ⟨w.ofBoxProdRight⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Connected G
hH : Connected H
⊢ Connected (G □ H)
[PROOFSTEP]
haveI := hG.nonempty
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Connected G
hH : Connected H
this : Nonempty α
⊢ Connected (G □ H)
[PROOFSTEP]
haveI := hH.nonempty
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
hG : Connected G
hH : Connected H
this✝ : Nonempty α
this : Nonempty β
⊢ Connected (G □ H)
[PROOFSTEP]
exact ⟨hG.preconnected.boxProd hH.preconnected⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
h : Connected (G □ H)
⊢ Connected G
[PROOFSTEP]
haveI := (nonempty_prod.1 h.nonempty).1
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
h : Connected (G □ H)
this : Nonempty α
⊢ Connected G
[PROOFSTEP]
haveI := (nonempty_prod.1 h.nonempty).2
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
h : Connected (G □ H)
this✝ : Nonempty α
this : Nonempty β
⊢ Connected G
[PROOFSTEP]
exact ⟨h.preconnected.ofBoxProdLeft⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
h : Connected (G □ H)
⊢ Connected H
[PROOFSTEP]
haveI := (nonempty_prod.1 h.nonempty).1
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
h : Connected (G □ H)
this : Nonempty α
⊢ Connected H
[PROOFSTEP]
haveI := (nonempty_prod.1 h.nonempty).2
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
h : Connected (G □ H)
this✝ : Nonempty α
this : Nonempty β
⊢ Connected H
[PROOFSTEP]
exact ⟨h.preconnected.ofBoxProdRight⟩
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝¹ : Fintype ↑(neighborSet G x.fst)
inst✝ : Fintype ↑(neighborSet H x.snd)
y : α × β
⊢ y ∈
      Finset.disjUnion (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd)
        (_ : Disjoint (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd)) ↔
    ↑(Equiv.refl (α × β)) y ∈ neighborSet (G □ H) x
[PROOFSTEP]
simp_rw [Finset.mem_disjUnion, Finset.mem_product, Finset.mem_singleton, mem_neighborFinset, mem_neighborSet,
  Equiv.refl_apply, boxProd_adj]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝¹ : Fintype ↑(neighborSet G x.fst)
inst✝ : Fintype ↑(neighborSet H x.snd)
y : α × β
⊢ Adj G x.fst y.fst ∧ y.snd = x.snd ∨ y.fst = x.fst ∧ Adj H x.snd y.snd ↔
    Adj G x.fst y.fst ∧ x.snd = y.snd ∨ Adj H x.snd y.snd ∧ x.fst = y.fst
[PROOFSTEP]
simp only [eq_comm, and_comm]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝² : Fintype ↑(neighborSet G x.fst)
inst✝¹ : Fintype ↑(neighborSet H x.snd)
inst✝ : Fintype ↑(neighborSet (G □ H) x)
⊢ neighborFinset (G □ H) x =
    Finset.disjUnion (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd)
      (_ : Disjoint (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd))
[PROOFSTEP]
letI : Fintype ((G □ H).neighborSet x) := SimpleGraph.boxProdFintypeNeighborSet _
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝² : Fintype ↑(neighborSet G x.fst)
inst✝¹ : Fintype ↑(neighborSet H x.snd)
inst✝ : Fintype ↑(neighborSet (G □ H) x)
this : Fintype ↑(neighborSet (G □ H) x) := boxProdFintypeNeighborSet x
⊢ neighborFinset (G □ H) x =
    Finset.disjUnion (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd)
      (_ : Disjoint (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd))
[PROOFSTEP]
convert_to (G □ H).neighborFinset x = _ using 2
[GOAL]
case convert_2
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝² : Fintype ↑(neighborSet G x.fst)
inst✝¹ : Fintype ↑(neighborSet H x.snd)
inst✝ : Fintype ↑(neighborSet (G □ H) x)
this : Fintype ↑(neighborSet (G □ H) x) := boxProdFintypeNeighborSet x
⊢ neighborFinset (G □ H) x =
    Finset.disjUnion (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd)
      (_ : Disjoint (neighborFinset G x.fst ×ˢ {x.snd}) ({x.fst} ×ˢ neighborFinset H x.snd))
[PROOFSTEP]
exact Eq.trans (Finset.map_map _ _ _) Finset.attach_map_val
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝² : Fintype ↑(neighborSet G x.fst)
inst✝¹ : Fintype ↑(neighborSet H x.snd)
inst✝ : Fintype ↑(neighborSet (G □ H) x)
⊢ degree (G □ H) x = degree G x.fst + degree H x.snd
[PROOFSTEP]
rw [degree, degree, degree, boxProd_neighborFinset, Finset.card_disjUnion]
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
G : SimpleGraph α
H : SimpleGraph β
x : α × β
inst✝² : Fintype ↑(neighborSet G x.fst)
inst✝¹ : Fintype ↑(neighborSet H x.snd)
inst✝ : Fintype ↑(neighborSet (G □ H) x)
⊢ Finset.card (neighborFinset G x.fst ×ˢ {x.snd}) + Finset.card ({x.fst} ×ˢ neighborFinset H x.snd) =
    Finset.card (neighborFinset G x.fst) + Finset.card (neighborFinset H x.snd)
[PROOFSTEP]
simp_rw [Finset.card_product, Finset.card_singleton, mul_one, one_mul]


[GOAL]
R : Type u_1
inst✝ : Semiring R
n : ℕ
r : R
⊢ ↑(opRingEquiv R) (op (↑(monomial n) r)) = ↑(monomial n) (op r)
[PROOFSTEP]
simp only [opRingEquiv, RingEquiv.coe_trans, Function.comp_apply, AddMonoidAlgebra.opRingEquiv_apply,
  RingEquiv.op_apply_apply, toFinsuppIso_apply, unop_op, toFinsupp_monomial, Finsupp.mapRange_single,
  toFinsuppIso_symm_apply, ofFinsupp_single]
[GOAL]
R : Type u_1
inst✝ : Semiring R
r : R
n : ℕ
⊢ ↑(opRingEquiv R) (op (↑C r * X ^ n)) = ↑C (op r) * X ^ n
[PROOFSTEP]
simp only [X_pow_mul, op_mul, op_pow, map_mul, map_pow, opRingEquiv_op_X, opRingEquiv_op_C]
[GOAL]
R : Type u_1
inst✝ : Semiring R
n : ℕ
r : Rᵐᵒᵖ
⊢ ↑(opRingEquiv R) (↑(RingEquiv.symm (opRingEquiv R)) (↑(monomial n) r)) =
    ↑(opRingEquiv R) (op (↑(monomial n) (unop r)))
[PROOFSTEP]
simp
[GOAL]
R : Type u_1
inst✝ : Semiring R
r : Rᵐᵒᵖ
n : ℕ
⊢ ↑(RingEquiv.symm (opRingEquiv R)) (↑C r * X ^ n) = op (↑C (unop r) * X ^ n)
[PROOFSTEP]
rw [C_mul_X_pow_eq_monomial, opRingEquiv_symm_monomial, C_mul_X_pow_eq_monomial]
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : R[X]ᵐᵒᵖ
n : ℕ
⊢ coeff (↑(opRingEquiv R) p) n = op (coeff (unop p) n)
[PROOFSTEP]
induction' p using MulOpposite.rec' with p
[GOAL]
case h
R : Type u_1
inst✝ : Semiring R
n : ℕ
p : R[X]
⊢ coeff (↑(opRingEquiv R) (op p)) n = op (coeff (unop (op p)) n)
[PROOFSTEP]
cases p
[GOAL]
case h.ofFinsupp
R : Type u_1
inst✝ : Semiring R
n : ℕ
toFinsupp✝ : AddMonoidAlgebra R ℕ
⊢ coeff (↑(opRingEquiv R) (op { toFinsupp := toFinsupp✝ })) n = op (coeff (unop (op { toFinsupp := toFinsupp✝ })) n)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : R[X]ᵐᵒᵖ
⊢ support (↑(opRingEquiv R) p) = support (unop p)
[PROOFSTEP]
induction' p using MulOpposite.rec' with p
[GOAL]
case h
R : Type u_1
inst✝ : Semiring R
p : R[X]
⊢ support (↑(opRingEquiv R) (op p)) = support (unop (op p))
[PROOFSTEP]
cases p
[GOAL]
case h.ofFinsupp
R : Type u_1
inst✝ : Semiring R
toFinsupp✝ : AddMonoidAlgebra R ℕ
⊢ support (↑(opRingEquiv R) (op { toFinsupp := toFinsupp✝ })) = support (unop (op { toFinsupp := toFinsupp✝ }))
[PROOFSTEP]
exact Finsupp.support_mapRange_of_injective (map_zero _) _ op_injective
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : R[X]ᵐᵒᵖ
⊢ natDegree (↑(opRingEquiv R) p) = natDegree (unop p)
[PROOFSTEP]
by_cases p0 : p = 0
[GOAL]
case pos
R : Type u_1
inst✝ : Semiring R
p : R[X]ᵐᵒᵖ
p0 : p = 0
⊢ natDegree (↑(opRingEquiv R) p) = natDegree (unop p)
[PROOFSTEP]
simp only [p0, _root_.map_zero, natDegree_zero, unop_zero]
[GOAL]
case neg
R : Type u_1
inst✝ : Semiring R
p : R[X]ᵐᵒᵖ
p0 : ¬p = 0
⊢ natDegree (↑(opRingEquiv R) p) = natDegree (unop p)
[PROOFSTEP]
simp only [p0, natDegree_eq_support_max', Ne.def, AddEquivClass.map_eq_zero_iff, not_false_iff, support_opRingEquiv,
  unop_eq_zero_iff]
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : R[X]ᵐᵒᵖ
⊢ leadingCoeff (↑(opRingEquiv R) p) = op (leadingCoeff (unop p))
[PROOFSTEP]
rw [leadingCoeff, coeff_opRingEquiv, natDegree_opRingEquiv, leadingCoeff]