l3lab/ntp-mathlib huggingface dataset:
theorem Subgroup.fg_iff_add_fg (P : Subgroup G) : P.FG ↔ P.toAddSubgroup.FG := by
  rw [Subgroup.fg_iff_submonoid_fg, AddSubgroup.fg_iff_addSubmonoid_fg]
  

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
P : Subgroup G
⊢ Submonoid.FG P.toSubmonoid ↔ AddSubmonoid.FG (toAddSubgroup P).toAddSubmonoid

Next tactic:
exact (Subgroup.toSubmonoid P).fg_iff_add_fg
theorem AddSubgroup.fg_iff_mul_fg (P : AddSubgroup H) : P.FG ↔ P.toSubgroup.FG := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
P : AddSubgroup H
⊢ FG P ↔ Subgroup.FG (toSubgroup P)

Next tactic:
rw [AddSubgroup.fg_iff_addSubmonoid_fg, Subgroup.fg_iff_submonoid_fg]
theorem AddSubgroup.fg_iff_mul_fg (P : AddSubgroup H) : P.FG ↔ P.toSubgroup.FG := by
  rw [AddSubgroup.fg_iff_addSubmonoid_fg, Subgroup.fg_iff_submonoid_fg]
  

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
P : AddSubgroup H
⊢ AddSubmonoid.FG P.toAddSubmonoid ↔ Submonoid.FG (toSubgroup P).toSubmonoid

Next tactic:
exact AddSubmonoid.fg_iff_mul_fg (AddSubgroup.toAddSubmonoid P)
@[to_additive]
instance (priority := 100) Group.fg_of_finite [Finite G] : Group.FG G := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
inst✝ : Finite G
⊢ FG G

Next tactic:
cases nonempty_fintype G
@[to_additive]
instance (priority := 100) Group.fg_of_finite [Finite G] : Group.FG G := by
  cases nonempty_fintype G
  

Proof state:
case intro
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
inst✝ : Finite G
val✝ : Fintype G
⊢ FG G

Next tactic:
exact ⟨⟨Finset.univ, by rw [Finset.coe_univ]; exact Subgroup.closure_univ⟩⟩
@[to_additive]
instance (priority := 100) Group.fg_of_finite [Finite G] : Group.FG G := by
  cases nonempty_fintype G
  exact ⟨⟨Finset.univ, by 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
inst✝ : Finite G
val✝ : Fintype G
⊢ Subgroup.closure ↑Finset.univ = ⊤

Next tactic:
rw [Finset.coe_univ]
@[to_additive]
instance (priority := 100) Group.fg_of_finite [Finite G] : Group.FG G := by
  cases nonempty_fintype G
  exact ⟨⟨Finset.univ, by rw [Finset.coe_univ]; 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
inst✝ : Finite G
val✝ : Fintype G
⊢ Subgroup.closure Set.univ = ⊤

Next tactic:
exact Subgroup.closure_univ
@[to_additive]
instance Group.closure_finset_fg (s : Finset G) : Group.FG (Subgroup.closure (s : Set G)) := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
⊢ FG ↥(Subgroup.closure ↑s)

Next tactic:
refine' ⟨⟨s.preimage Subtype.val (Subtype.coe_injective.injOn _), _⟩⟩
@[to_additive]
instance Group.closure_finset_fg (s : Finset G) : Group.FG (Subgroup.closure (s : Set G)) := by
  refine' ⟨⟨s.preimage Subtype.val (Subtype.coe_injective.injOn _), _⟩⟩
  

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
⊢ Subgroup.closure ↑(Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))) = ⊤

Next tactic:
rw [Finset.coe_preimage, ← Subgroup.coeSubtype, Subgroup.closure_preimage_eq_top]
@[to_additive]
theorem Group.rank_le_of_surjective [Group.FG G] [Group.FG G'] (f : G →* G')
    (hf : Function.Surjective f) : Group.rank G' ≤ Group.rank G := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝⁶ : Monoid M
inst✝⁵ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝⁴ : Group G
inst✝³ : AddGroup H
G' : Type u_5
inst✝² : Group G'
inst✝¹ : FG G
inst✝ : FG G'
f : G →* G'
hf : Function.Surjective ⇑f
⊢ rank G' ≤ rank G

Next tactic:
classical
    obtain ⟨S, hS1, hS2⟩ := Group.rank_spec G
    trans (S.image f).card
    · apply Group.rank_le
      rw [Finset.coe_image, ← MonoidHom.map_closure, hS2, Subgroup.map_top_of_surjective f hf]
    · exact Finset.card_image_le.trans_eq hS1
@[to_additive]
theorem Group.rank_le_of_surjective [Group.FG G] [Group.FG G'] (f : G →* G')
    (hf : Function.Surjective f) : Group.rank G' ≤ Group.rank G := by
  classical
    

Proof state:
M : Type u_1
N : Type u_2
inst✝⁶ : Monoid M
inst✝⁵ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝⁴ : Group G
inst✝³ : AddGroup H
G' : Type u_5
inst✝² : Group G'
inst✝¹ : FG G
inst✝ : FG G'
f : G →* G'
hf : Function.Surjective ⇑f
⊢ rank G' ≤ rank G

Next tactic:
obtain ⟨S, hS1, hS2⟩ := Group.rank_spec G
@[to_additive]
theorem Group.rank_le_of_surjective [Group.FG G] [Group.FG G'] (f : G →* G')
    (hf : Function.Surjective f) : Group.rank G' ≤ Group.rank G := by
  classical
    obtain ⟨S, hS1, hS2⟩ := Group.rank_spec G
    

Proof state:
case intro.intro
M : Type u_1
N : Type u_2
inst✝⁶ : Monoid M
inst✝⁵ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝⁴ : Group G
inst✝³ : AddGroup H
G' : Type u_5
inst✝² : Group G'
inst✝¹ : FG G
inst✝ : FG G'
f : G →* G'
hf : Function.Surjective ⇑f
S : Finset G
hS1 : Finset.card S = rank G
hS2 : Subgroup.closure ↑S = ⊤
⊢ rank G' ≤ rank G

Next tactic:
trans (S.image f).card
@[to_additive]
theorem Group.rank_le_of_surjective [Group.FG G] [Group.FG G'] (f : G →* G')
    (hf : Function.Surjective f) : Group.rank G' ≤ Group.rank G := by
  classical
    obtain ⟨S, hS1, hS2⟩ := Group.rank_spec G
    trans (S.image f).card
    · 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁶ : Monoid M
inst✝⁵ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝⁴ : Group G
inst✝³ : AddGroup H
G' : Type u_5
inst✝² : Group G'
inst✝¹ : FG G
inst✝ : FG G'
f : G →* G'
hf : Function.Surjective ⇑f
S : Finset G
hS1 : Finset.card S = rank G
hS2 : Subgroup.closure ↑S = ⊤
⊢ rank G' ≤ Finset.card (Finset.image (⇑f) S)

Next tactic:
apply Group.rank_le
@[to_additive]
theorem Group.rank_le_of_surjective [Group.FG G] [Group.FG G'] (f : G →* G')
    (hf : Function.Surjective f) : Group.rank G' ≤ Group.rank G := by
  classical
    obtain ⟨S, hS1, hS2⟩ := Group.rank_spec G
    trans (S.image f).card
    · apply Group.rank_le
      

Proof state:
case hS
M : Type u_1
N : Type u_2
inst✝⁶ : Monoid M
inst✝⁵ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝⁴ : Group G
inst✝³ : AddGroup H
G' : Type u_5
inst✝² : Group G'
inst✝¹ : FG G
inst✝ : FG G'
f : G →* G'
hf : Function.Surjective ⇑f
S : Finset G
hS1 : Finset.card S = rank G
hS2 : Subgroup.closure ↑S = ⊤
⊢ Subgroup.closure ↑(Finset.image (⇑f) S) = ⊤

Next tactic:
rw [Finset.coe_image, ← MonoidHom.map_closure, hS2, Subgroup.map_top_of_surjective f hf]
@[to_additive]
theorem Group.rank_le_of_surjective [Group.FG G] [Group.FG G'] (f : G →* G')
    (hf : Function.Surjective f) : Group.rank G' ≤ Group.rank G := by
  classical
    obtain ⟨S, hS1, hS2⟩ := Group.rank_spec G
    trans (S.image f).card
    · apply Group.rank_le
      rw [Finset.coe_image, ← MonoidHom.map_closure, hS2, Subgroup.map_top_of_surjective f hf]
    · 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁶ : Monoid M
inst✝⁵ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝⁴ : Group G
inst✝³ : AddGroup H
G' : Type u_5
inst✝² : Group G'
inst✝¹ : FG G
inst✝ : FG G'
f : G →* G'
hf : Function.Surjective ⇑f
S : Finset G
hS1 : Finset.card S = rank G
hS2 : Subgroup.closure ↑S = ⊤
⊢ Finset.card (Finset.image (⇑f) S) ≤ rank G

Next tactic:
exact Finset.card_image_le.trans_eq hS1
@[to_additive]
theorem rank_congr {H K : Subgroup G} [Group.FG H] [Group.FG K] (h : H = K) :
    Group.rank H = Group.rank K := by 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁵ : Monoid M
inst✝⁴ : AddMonoid N
G : Type u_3
H✝ : Type u_4
inst✝³ : Group G
inst✝² : AddGroup H✝
H K : Subgroup G
inst✝¹ : Group.FG ↥H
inst✝ : Group.FG ↥K
h : H = K
⊢ Group.rank ↥H = Group.rank ↥K

Next tactic:
subst h
@[to_additive]
theorem rank_congr {H K : Subgroup G} [Group.FG H] [Group.FG K] (h : H = K) :
    Group.rank H = Group.rank K := by subst h; 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁵ : Monoid M
inst✝⁴ : AddMonoid N
G : Type u_3
H✝ : Type u_4
inst✝³ : Group G
inst✝² : AddGroup H✝
H : Subgroup G
inst✝¹ inst✝ : Group.FG ↥H
⊢ Group.rank ↥H = Group.rank ↥H

Next tactic:
rfl
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
⊢ Group.rank ↥(closure ↑s) ≤ Finset.card s

Next tactic:
classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
    apply (Group.rank_le (closure (s : Set G)) ht).trans
    suffices H : Set.InjOn Subtype.val (t : Set (closure (s : Set G)))
    rw [← Finset.card_image_of_injOn H, Finset.image_preimage]
    · apply Finset.card_filter_le
    · apply Subtype.coe_injective.injOn
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
⊢ Group.rank ↥(closure ↑s) ≤ Finset.card s

Next tactic:
let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
⊢ Group.rank ↥(closure ↑s) ≤ Finset.card s

Next tactic:
have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
⊢ closure ↑t = ⊤

Next tactic:
rw [Finset.coe_preimage]
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
⊢ closure (Subtype.val ⁻¹' ↑s) = ⊤

Next tactic:
exact closure_preimage_eq_top (s : Set G)
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
    

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
ht : closure ↑t = ⊤
⊢ Group.rank ↥(closure ↑s) ≤ Finset.card s

Next tactic:
apply (Group.rank_le (closure (s : Set G)) ht).trans
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
    apply (Group.rank_le (closure (s : Set G)) ht).trans
    

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
ht : closure ↑t = ⊤
⊢ Finset.card t ≤ Finset.card s

Next tactic:
suffices H : Set.InjOn Subtype.val (t : Set (closure (s : Set G)))
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
    apply (Group.rank_le (closure (s : Set G)) ht).trans
    suffices H : Set.InjOn Subtype.val (t : Set (closure (s : Set G)))
    

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H✝
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
ht : closure ↑t = ⊤
H : Set.InjOn Subtype.val ↑t
⊢ Finset.card t ≤ Finset.card s
case H
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
ht : closure ↑t = ⊤
⊢ Set.InjOn Subtype.val ↑t

Next tactic:
rw [← Finset.card_image_of_injOn H, Finset.image_preimage]
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
    apply (Group.rank_le (closure (s : Set G)) ht).trans
    suffices H : Set.InjOn Subtype.val (t : Set (closure (s : Set G)))
    rw [← Finset.card_image_of_injOn H, Finset.image_preimage]
    · 

Proof state:
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H✝ : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H✝
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
ht : closure ↑t = ⊤
H : Set.InjOn Subtype.val ↑t
⊢ Finset.card (Finset.filter (fun x => x ∈ Set.range Subtype.val) s) ≤ Finset.card s

Next tactic:
apply Finset.card_filter_le
@[to_additive]
theorem rank_closure_finset_le_card (s : Finset G) : Group.rank (closure (s : Set G)) ≤ s.card := by
  classical
    let t : Finset (closure (s : Set G)) := s.preimage Subtype.val (Subtype.coe_injective.injOn _)
    have ht : closure (t : Set (closure (s : Set G))) = ⊤ := by
      rw [Finset.coe_preimage]
      exact closure_preimage_eq_top (s : Set G)
    apply (Group.rank_le (closure (s : Set G)) ht).trans
    suffices H : Set.InjOn Subtype.val (t : Set (closure (s : Set G)))
    rw [← Finset.card_image_of_injOn H, Finset.image_preimage]
    · apply Finset.card_filter_le
    · 

Proof state:
case H
M : Type u_1
N : Type u_2
inst✝³ : Monoid M
inst✝² : AddMonoid N
G : Type u_3
H : Type u_4
inst✝¹ : Group G
inst✝ : AddGroup H
s : Finset G
t : Finset ↥(closure ↑s) := Finset.preimage s Subtype.val (_ : Set.InjOn (fun a => ↑a) (Subtype.val ⁻¹' ↑s))
ht : closure ↑t = ⊤
⊢ Set.InjOn Subtype.val ↑t

Next tactic:
apply Subtype.coe_injective.injOn
@[to_additive]
theorem rank_closure_finite_le_nat_card (s : Set G) [Finite s] :
    Group.rank (closure s) ≤ Nat.card s := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
s : Set G
inst✝ : Finite ↑s
⊢ Group.rank ↥(closure s) ≤ Nat.card ↑s

Next tactic:
haveI := Fintype.ofFinite s
@[to_additive]
theorem rank_closure_finite_le_nat_card (s : Set G) [Finite s] :
    Group.rank (closure s) ≤ Nat.card s := by
  haveI := Fintype.ofFinite s
  

Proof state:
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
s : Set G
inst✝ : Finite ↑s
this : Fintype ↑s
⊢ Group.rank ↥(closure s) ≤ Nat.card ↑s

Next tactic:
rw [Nat.card_eq_fintype_card, ← s.toFinset_card, ← rank_congr (congr_arg _ s.coe_toFinset)]
@[to_additive]
theorem rank_closure_finite_le_nat_card (s : Set G) [Finite s] :
    Group.rank (closure s) ≤ Nat.card s := by
  haveI := Fintype.ofFinite s
  rw [Nat.card_eq_fintype_card, ← s.toFinset_card, ← rank_congr (congr_arg _ s.coe_toFinset)]
  

Proof state:
M : Type u_1
N : Type u_2
inst✝⁴ : Monoid M
inst✝³ : AddMonoid N
G : Type u_3
H : Type u_4
inst✝² : Group G
inst✝¹ : AddGroup H
s : Set G
inst✝ : Finite ↑s
this : Fintype ↑s
⊢ Group.rank ↥(closure ↑(Set.toFinset s)) ≤ Finset.card (Set.toFinset s)

Next tactic:
exact rank_closure_finset_le_card s.toFinset
theorem norm_eq_one_of_not_exists_basis (h : ¬∃ s : Finset S, Nonempty (Basis s R S)) (x : S) :
    norm R x = 1 := by 

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬∃ s, Nonempty (Basis { x // x ∈ s } R S)
x : S
⊢ (norm R) x = 1

Next tactic:
rw [norm_apply, LinearMap.det]
theorem norm_eq_one_of_not_exists_basis (h : ¬∃ s : Finset S, Nonempty (Basis s R S)) (x : S) :
    norm R x = 1 := by rw [norm_apply, LinearMap.det]; 

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬∃ s, Nonempty (Basis { x // x ∈ s } R S)
x : S
⊢ (if H : ∃ s, Nonempty (Basis { x // x ∈ s } R S) then
        detAux (Trunc.mk (Nonempty.some (_ : Nonempty (Basis { x // x ∈ Exists.choose H } R S))))
      else 1)
      ((lmul R S) x) =
    1

Next tactic:
split_ifs
theorem norm_eq_one_of_not_exists_basis (h : ¬∃ s : Finset S, Nonempty (Basis s R S)) (x : S) :
    norm R x = 1 := by rw [norm_apply, LinearMap.det]; split_ifs <;> 

Proof state:
case pos
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬∃ s, Nonempty (Basis { x // x ∈ s } R S)
x : S
h✝ : ∃ s, Nonempty (Basis { x // x ∈ s } R S)
⊢ (detAux (Trunc.mk (Nonempty.some (_ : Nonempty (Basis { x // x ∈ Exists.choose h✝ } R S))))) ((lmul R S) x) = 1

Next tactic:
trivial
theorem norm_eq_one_of_not_exists_basis (h : ¬∃ s : Finset S, Nonempty (Basis s R S)) (x : S) :
    norm R x = 1 := by rw [norm_apply, LinearMap.det]; split_ifs <;> 

Proof state:
case neg
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬∃ s, Nonempty (Basis { x // x ∈ s } R S)
x : S
h✝ : ¬∃ s, Nonempty (Basis { x // x ∈ s } R S)
⊢ 1 ((lmul R S) x) = 1

Next tactic:
trivial
theorem norm_eq_one_of_not_module_finite (h : ¬Module.Finite R S) (x : S) : norm R x = 1 := by
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬Module.Finite R S
x : S
⊢ (norm R) x = 1

Next tactic:
refine norm_eq_one_of_not_exists_basis _ (mt ?_ h) _
theorem norm_eq_one_of_not_module_finite (h : ¬Module.Finite R S) (x : S) : norm R x = 1 := by
  refine norm_eq_one_of_not_exists_basis _ (mt ?_ h) _
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬Module.Finite R S
x : S
⊢ (∃ s, Nonempty (Basis { x // x ∈ s } R S)) → Module.Finite R S

Next tactic:
rintro ⟨s, ⟨b⟩⟩
theorem norm_eq_one_of_not_module_finite (h : ¬Module.Finite R S) (x : S) : norm R x = 1 := by
  refine norm_eq_one_of_not_exists_basis _ (mt ?_ h) _
  rintro ⟨s, ⟨b⟩⟩
  

Proof state:
case intro.intro
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
h : ¬Module.Finite R S
x : S
s : Finset S
b : Basis { x // x ∈ s } R S
⊢ Module.Finite R S

Next tactic:
exact Module.Finite.of_basis b
theorem norm_eq_matrix_det [Fintype ι] [DecidableEq ι] (b : Basis ι R S) (s : S) :
    norm R s = Matrix.det (Algebra.leftMulMatrix b s) := by
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁹ : CommRing R
inst✝⁸ : Ring S
inst✝⁷ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁶ : Field K
inst✝⁵ : Field L
inst✝⁴ : Field F
inst✝³ : Algebra K L
inst✝² : Algebra K F
ι : Type w
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
b : Basis ι R S
s : S
⊢ (norm R) s = det ((leftMulMatrix b) s)

Next tactic:
rw [norm_apply, ← LinearMap.det_toMatrix b, ← toMatrix_lmul_eq]
theorem norm_eq_matrix_det [Fintype ι] [DecidableEq ι] (b : Basis ι R S) (s : S) :
    norm R s = Matrix.det (Algebra.leftMulMatrix b s) := by
  rw [norm_apply, ← LinearMap.det_toMatrix b, ← toMatrix_lmul_eq]; 

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁹ : CommRing R
inst✝⁸ : Ring S
inst✝⁷ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁶ : Field K
inst✝⁵ : Field L
inst✝⁴ : Field F
inst✝³ : Algebra K L
inst✝² : Algebra K F
ι : Type w
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
b : Basis ι R S
s : S
⊢ det ((toMatrix b b) ((lmul R S) s)) = det ((toMatrix b b) (mulLeft R s))

Next tactic:
rfl
/-- If `x` is in the base ring `K`, then the norm is `x ^ [L : K]`. -/
theorem norm_algebraMap_of_basis [Fintype ι] (b : Basis ι R S) (x : R) :
    norm R (algebraMap R S x) = x ^ Fintype.card ι := by
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : Ring S
inst✝⁶ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field F
inst✝² : Algebra K L
inst✝¹ : Algebra K F
ι : Type w
inst✝ : Fintype ι
b : Basis ι R S
x : R
⊢ (norm R) ((algebraMap R S) x) = x ^ Fintype.card ι

Next tactic:
haveI := Classical.decEq ι
/-- If `x` is in the base ring `K`, then the norm is `x ^ [L : K]`. -/
theorem norm_algebraMap_of_basis [Fintype ι] (b : Basis ι R S) (x : R) :
    norm R (algebraMap R S x) = x ^ Fintype.card ι := by
  haveI := Classical.decEq ι
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : Ring S
inst✝⁶ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field F
inst✝² : Algebra K L
inst✝¹ : Algebra K F
ι : Type w
inst✝ : Fintype ι
b : Basis ι R S
x : R
this : DecidableEq ι
⊢ (norm R) ((algebraMap R S) x) = x ^ Fintype.card ι

Next tactic:
rw [norm_apply, ← det_toMatrix b, lmul_algebraMap]