[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Data.Finset.Insert).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
theorem exists_mem_insert (a : α) (s : Finset α) (p : α → Prop) :
    (∃ x, x ∈ insert a s ∧ p x) ↔ p a ∨ ∃ x, x ∈ s ∧ p x
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Data.Finset.Insert.singleton_val (L70-L72)
theorem singleton_val (a : α) : ({a} : Finset α).1 = {a} :=
rfl
```

-- snippet 2
```lean
-- Mathlib.Data.Finset.Insert.mem_singleton (L74-L76)
theorem mem_singleton {a b : α} : b ∈ ({a} : Finset α) ↔ b = a :=
Multiset.mem_singleton
```

-- snippet 3
```lean
-- Mathlib.Data.Finset.Insert.eq_of_mem_singleton (L77-L79)
theorem eq_of_mem_singleton {x y : α} (h : x ∈ ({y} : Finset α)) : x = y :=
mem_singleton.1 h
```

-- snippet 4
```lean
-- Mathlib.Data.Finset.Insert.notMem_singleton (L80-L82)
theorem notMem_singleton {a b : α} : a ∉ ({b} : Finset α) ↔ a ≠ b :=
not_congr mem_singleton
```

-- snippet 5
```lean
-- Mathlib.Data.Finset.Insert.mem_singleton_self (L83-L85)
theorem mem_singleton_self (a : α) : a ∈ ({a} : Finset α) :=
mem_singleton.mpr rfl
```

-- snippet 6
```lean
-- Mathlib.Data.Finset.Insert.val_eq_singleton_iff (L87-L90)
theorem val_eq_singleton_iff {a : α} {s : Finset α} : s.val = {a} ↔ s = {a} := by
rw [← val_inj]
  rfl
```

-- snippet 7
```lean
-- Mathlib.Data.Finset.Insert.singleton_injective (L91-L93)
theorem singleton_injective : Injective (singleton : α → Finset α) := fun _a _b h =>
mem_singleton.1 (h ▸ mem_singleton_self _)
```

-- snippet 8
```lean
-- Mathlib.Data.Finset.Insert.singleton_inj (L95-L97)
theorem singleton_inj : ({a} : Finset α) = {b} ↔ a = b :=
singleton_injective.eq_iff
```

-- snippet 9
```lean
-- Mathlib.Data.Finset.Insert.singleton_nonempty (L99-L101)
theorem singleton_nonempty (a : α) : ({a} : Finset α).Nonempty :=
⟨a, mem_singleton_self a⟩
```

-- snippet 10
```lean
-- Mathlib.Data.Finset.Insert.singleton_ne_empty (L103-L105)
theorem singleton_ne_empty (a : α) : ({a} : Finset α) ≠ ∅ :=
(singleton_nonempty a).ne_empty
```

-- snippet 11
```lean
-- Mathlib.Data.Finset.Insert.empty_ne_singleton (L107-L109)
theorem empty_ne_singleton (a : α) : ∅ ≠ ({a} : Finset α) :=
(singleton_ne_empty a).symm
```

-- snippet 12
```lean
-- Mathlib.Data.Finset.Insert.empty_ssubset_singleton (L110-L112)
theorem empty_ssubset_singleton : (∅ : Finset α) ⊂ {a} :=
(singleton_nonempty _).empty_ssubset
```

-- snippet 13
```lean
-- Mathlib.Data.Finset.Insert.coe_singleton (L114-L115)
theorem coe_singleton (a : α) : (({a} : Finset α) : Set α) = {a} := by grind
```

-- snippet 14
```lean
-- Mathlib.Data.Finset.Insert.coe_eq_singleton (L117-L118)
theorem coe_eq_singleton {s : Finset α} {a : α} : (s : Set α) = {a} ↔ s = {a} := by grind
```

-- snippet 15
```lean
-- Mathlib.Data.Finset.Insert.coe_subset_singleton (L120-L121)
lemma coe_subset_singleton : (s : Set α) ⊆ {a} ↔ s ⊆ {a} := by grind
```

-- snippet 16
```lean
-- Mathlib.Data.Finset.Basic.disjUnion_eq_union (L73-L74)
theorem disjUnion_eq_union (s t h) : @disjUnion α s t h = s ∪ t := by grind
```

-- snippet 17
```lean
-- Mathlib.Data.Finset.Basic.erase_cons_of_ne (L139-L141)
theorem erase_cons_of_ne {a b : α} {s : Finset α} (ha : a ∉ s) (hb : a ≠ b) :
    (s.cons a ha).erase b = (s.erase b).cons a fun h => ha <| erase_subset _ _ h := by grind
```

-- snippet 18
```lean
-- Mathlib.Data.Finset.Basic.erase_singleton (L129-L130)
theorem erase_singleton (a : α) : ({a} : Finset α).erase a = ∅ := by grind
```

-- snippet 19
```lean
-- Mathlib.Data.Finset.Basic.ssubset_iff_exists_subset_erase (L153-L155)
theorem ssubset_iff_exists_subset_erase {s t : Finset α} : s ⊂ t ↔ ∃ a ∈ t, s ⊆ t.erase a := by
grind
```

-- snippet 20
```lean
-- Mathlib.Data.Finset.Basic.disjoint_union_right (L80-L84)
theorem disjoint_union_right : Disjoint s (t ∪ u) ↔ Disjoint s t ∧ Disjoint s u := by
simp only [disjoint_right, mem_union, or_imp, forall_and]

/-! #### inter -/
```

-- snippet 21
```lean
-- Mathlib.Data.Finset.Basic.disjoint_or_nonempty_inter (L90-L94)
theorem disjoint_or_nonempty_inter (s t : Finset α) : Disjoint s t ∨ (s ∩ t).Nonempty := by
rw [← not_disjoint_iff_nonempty_inter]
  exact em _

omit [DecidableEq α] in
```

-- snippet 22
```lean
-- Mathlib.Data.Finset.Attach.coe_attach (L58-L60)
theorem coe_attach (s : Finset α) : (s.attach : Set s) = Set.univ := by ext; simp
end Finset
```

-- snippet 23
```lean
-- Mathlib.Data.Finset.Basic.isDirected_subset (L107-L114)
instance isDirected_subset : IsDirected (Finset α) (· ⊆ ·) := isDirected_le
/-! ### erase -/

section Erase

variable [DecidableEq α] {s t u v : Finset α} {a b : α}
```

-- snippet 24
```lean
-- Mathlib.Data.Finset.Basic.disjoint_union_left (L76-L78)
theorem disjoint_union_left : Disjoint (s ∪ t) u ↔ Disjoint s u ∧ Disjoint t u := by
simp only [disjoint_left, mem_union, or_imp, forall_and]
```

-- snippet 25
```lean
-- Mathlib.Data.Finset.Attach.attach_val (L50-L52)
theorem attach_val (s : Finset α) : s.attach.1 = s.1.attach :=
rfl
```

-- snippet 26
```lean
-- Mathlib.Data.Finset.Basic.erase_insert_eq_erase (L132-L133)
theorem erase_insert_eq_erase (s : Finset α) (a : α) : (insert a s).erase a = s.erase a := by grind
```

-- snippet 27
```lean
-- Mathlib.Data.Finset.Basic.erase_eq_iff_eq_insert (L144-L146)
lemma erase_eq_iff_eq_insert (hs : a ∈ s) (ht : a ∉ t) : s.erase a = t ↔ s = insert a t := by
aesop
```

-- snippet 28
```lean
-- Mathlib.Data.Finset.Basic.not_disjoint_iff_nonempty_inter (L85-L89)
theorem not_disjoint_iff_nonempty_inter : ¬Disjoint s t ↔ (s ∩ t).Nonempty :=
not_disjoint_iff.trans <| by simp [Finset.Nonempty]

alias ⟨_, Nonempty.not_disjoint⟩ := not_disjoint_iff_nonempty_inter
```

-- snippet 29
```lean
-- Mathlib.Data.Finset.Basic.erase_cons (L159-L160)
theorem erase_cons {s : Finset α} {a : α} (h : a ∉ s) : (s.cons a h).erase a = s := by grind
```

-- snippet 30
```lean
-- Mathlib.Data.Finset.Basic.erase_ssubset_insert (L156-L158)
theorem erase_ssubset_insert (s : Finset α) (a : α) : s.erase a ⊂ insert a s :=
ssubset_iff_exists_subset_erase.2 ⟨a, mem_insert_self _ _, by grw [← subset_insert]⟩
```

-- snippet 31
```lean
-- Mathlib.Data.Finset.Basic.insert_erase_invOn (L147-L150)
lemma insert_erase_invOn :
    Set.InvOn (insert a) (fun s ↦ s.erase a) {s : Finset α | a ∈ s} {s : Finset α | a ∉ s} :=
⟨fun _s ↦ insert_erase, fun _s ↦ erase_insert⟩
```

-- snippet 32
```lean
-- Mathlib.Data.Finset.Attach.attach (L46-L48)
def attach (s : Finset α) : Finset { x // x ∈ s } :=
⟨Multiset.attach s.1, nodup_attach.2 s.2⟩
```

-- snippet 33
```lean
-- Mathlib.Data.Finset.Basic.disjoint_of_subset_iff_left_eq_empty (L95-L98)
theorem disjoint_of_subset_iff_left_eq_empty (h : s ⊆ t) :
    Disjoint s t ↔ s = ∅ :=
disjoint_of_le_iff_left_eq_bot h
```

-- snippet 34
```lean
-- Mathlib.Data.Finset.Basic.erase_empty (L116-L121)
theorem erase_empty (a : α) : erase ∅ a = ∅ :=
rfl

protected lemma Nontrivial.erase_nonempty (hs : s.Nontrivial) : (s.erase a).Nonempty :=
  (hs.exists_ne a).imp <| by simp_all
```

-- snippet 35
```lean
-- Mathlib.Data.Finset.Basic.erase_insert (L134-L135)
theorem erase_insert {a : α} {s : Finset α} (h : a ∉ s) : (insert a s).erase a = s := by grind
```

-- snippet 36
```lean
-- Mathlib.Data.Finset.Basic.pairwiseDisjoint_iff (L99-L105)
lemma pairwiseDisjoint_iff {ι : Type*} {s : Set ι} {f : ι → Finset α} :
    s.PairwiseDisjoint f ↔ ∀ ⦃i⦄, i ∈ s → ∀ ⦃j⦄, j ∈ s → (f i ∩ f j).Nonempty → i = j := by
simp [Set.PairwiseDisjoint, Set.Pairwise, not_imp_comm (a := _ = _),
    not_disjoint_iff_nonempty_inter]

end Lattice
```

-- snippet 37
```lean
-- Mathlib.Data.Finset.Attach.mem_attach (L54-L56)
theorem mem_attach (s : Finset α) : ∀ x, x ∈ s.attach :=
Multiset.mem_attach _
```

-- snippet 38
```lean
-- Mathlib.Data.Finset.Basic.erase_insert_of_ne (L136-L138)
theorem erase_insert_of_ne {a b : α} {s : Finset α} (h : a ≠ b) :
    (insert a s).erase b = insert a (s.erase b) := by grind
```

-- snippet 39
```lean
-- Mathlib.Data.Finset.Basic.erase_ssubset (L151-L152)
theorem erase_ssubset {a : α} {s : Finset α} (h : a ∈ s) : s.erase a ⊂ s := by grind
```

-- snippet 40
```lean
-- Mathlib.Data.Finset.Basic.isDirected_le (L106-L106)
instance isDirected_le : IsDirectedOrder (Finset α) := by classical infer_instance
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Data.Finset.Insert).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem exists_mem_insert (a : α) (s : Finset α) (p : α → Prop) :
    (∃ x, x ∈ insert a s ∧ p x) ↔ p a ∨ ∃ x, x ∈ s ∧ p x
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Data.Finset.Insert.singleton_val (L70-L72)
theorem singleton_val (a : α) : ({a} : Finset α).1 = {a} :=
rfl
```

-- snippet 2
```lean
-- Mathlib.Data.Finset.Insert.mem_singleton (L74-L76)
theorem mem_singleton {a b : α} : b ∈ ({a} : Finset α) ↔ b = a :=
Multiset.mem_singleton
```

-- snippet 3
```lean
-- Mathlib.Data.Finset.Insert.eq_of_mem_singleton (L77-L79)
theorem eq_of_mem_singleton {x y : α} (h : x ∈ ({y} : Finset α)) : x = y :=
mem_singleton.1 h
```

-- snippet 4
```lean
-- Mathlib.Data.Finset.Insert.notMem_singleton (L80-L82)
theorem notMem_singleton {a b : α} : a ∉ ({b} : Finset α) ↔ a ≠ b :=
not_congr mem_singleton
```

-- snippet 5
```lean
-- Mathlib.Data.Finset.Insert.mem_singleton_self (L83-L85)
theorem mem_singleton_self (a : α) : a ∈ ({a} : Finset α) :=
mem_singleton.mpr rfl
```

-- snippet 6
```lean
-- Mathlib.Data.Finset.Insert.val_eq_singleton_iff (L87-L90)
theorem val_eq_singleton_iff {a : α} {s : Finset α} : s.val = {a} ↔ s = {a} := by
rw [← val_inj]
  rfl
```

-- snippet 7
```lean
-- Mathlib.Data.Finset.Insert.singleton_injective (L91-L93)
theorem singleton_injective : Injective (singleton : α → Finset α) := fun _a _b h =>
mem_singleton.1 (h ▸ mem_singleton_self _)
```

-- snippet 8
```lean
-- Mathlib.Data.Finset.Insert.singleton_inj (L95-L97)
theorem singleton_inj : ({a} : Finset α) = {b} ↔ a = b :=
singleton_injective.eq_iff
```

-- snippet 9
```lean
-- Mathlib.Data.Finset.Insert.singleton_nonempty (L99-L101)
theorem singleton_nonempty (a : α) : ({a} : Finset α).Nonempty :=
⟨a, mem_singleton_self a⟩
```

-- snippet 10
```lean
-- Mathlib.Data.Finset.Insert.singleton_ne_empty (L103-L105)
theorem singleton_ne_empty (a : α) : ({a} : Finset α) ≠ ∅ :=
(singleton_nonempty a).ne_empty
```

-- snippet 11
```lean
-- Mathlib.Data.Finset.Insert.empty_ne_singleton (L107-L109)
theorem empty_ne_singleton (a : α) : ∅ ≠ ({a} : Finset α) :=
(singleton_ne_empty a).symm
```

-- snippet 12
```lean
-- Mathlib.Data.Finset.Insert.empty_ssubset_singleton (L110-L112)
theorem empty_ssubset_singleton : (∅ : Finset α) ⊂ {a} :=
(singleton_nonempty _).empty_ssubset
```

-- snippet 13
```lean
-- Mathlib.Data.Finset.Insert.coe_singleton (L114-L115)
theorem coe_singleton (a : α) : (({a} : Finset α) : Set α) = {a} := by grind
```

-- snippet 14
```lean
-- Mathlib.Data.Finset.Insert.coe_eq_singleton (L117-L118)
theorem coe_eq_singleton {s : Finset α} {a : α} : (s : Set α) = {a} ↔ s = {a} := by grind
```

-- snippet 15
```lean
-- Mathlib.Data.Finset.Insert.coe_subset_singleton (L120-L121)
lemma coe_subset_singleton : (s : Set α) ⊆ {a} ↔ s ⊆ {a} := by grind
```

-- snippet 16
```lean
-- Mathlib.Data.Finset.Basic.disjUnion_eq_union (L73-L74)
theorem disjUnion_eq_union (s t h) : @disjUnion α s t h = s ∪ t := by grind
```

-- snippet 17
```lean
-- Mathlib.Data.Finset.Basic.erase_cons_of_ne (L139-L141)
theorem erase_cons_of_ne {a b : α} {s : Finset α} (ha : a ∉ s) (hb : a ≠ b) :
    (s.cons a ha).erase b = (s.erase b).cons a fun h => ha <| erase_subset _ _ h := by grind
```

-- snippet 18
```lean
-- Mathlib.Data.Finset.Basic.erase_singleton (L129-L130)
theorem erase_singleton (a : α) : ({a} : Finset α).erase a = ∅ := by grind
```

-- snippet 19
```lean
-- Mathlib.Data.Finset.Basic.ssubset_iff_exists_subset_erase (L153-L155)
theorem ssubset_iff_exists_subset_erase {s t : Finset α} : s ⊂ t ↔ ∃ a ∈ t, s ⊆ t.erase a := by
grind
```

-- snippet 20
```lean
-- Mathlib.Data.Finset.Basic.disjoint_union_right (L80-L84)
theorem disjoint_union_right : Disjoint s (t ∪ u) ↔ Disjoint s t ∧ Disjoint s u := by
simp only [disjoint_right, mem_union, or_imp, forall_and]

/-! #### inter -/
```

-- snippet 21
```lean
-- Mathlib.Data.Finset.Basic.disjoint_or_nonempty_inter (L90-L94)
theorem disjoint_or_nonempty_inter (s t : Finset α) : Disjoint s t ∨ (s ∩ t).Nonempty := by
rw [← not_disjoint_iff_nonempty_inter]
  exact em _

omit [DecidableEq α] in
```

-- snippet 22
```lean
-- Mathlib.Data.Finset.Attach.coe_attach (L58-L60)
theorem coe_attach (s : Finset α) : (s.attach : Set s) = Set.univ := by ext; simp
end Finset
```

-- snippet 23
```lean
-- Mathlib.Data.Finset.Basic.isDirected_subset (L107-L114)
instance isDirected_subset : IsDirected (Finset α) (· ⊆ ·) := isDirected_le
/-! ### erase -/

section Erase

variable [DecidableEq α] {s t u v : Finset α} {a b : α}
```

-- snippet 24
```lean
-- Mathlib.Data.Finset.Basic.disjoint_union_left (L76-L78)
theorem disjoint_union_left : Disjoint (s ∪ t) u ↔ Disjoint s u ∧ Disjoint t u := by
simp only [disjoint_left, mem_union, or_imp, forall_and]
```

-- snippet 25
```lean
-- Mathlib.Data.Finset.Attach.attach_val (L50-L52)
theorem attach_val (s : Finset α) : s.attach.1 = s.1.attach :=
rfl
```

-- snippet 26
```lean
-- Mathlib.Data.Finset.Basic.erase_insert_eq_erase (L132-L133)
theorem erase_insert_eq_erase (s : Finset α) (a : α) : (insert a s).erase a = s.erase a := by grind
```

-- snippet 27
```lean
-- Mathlib.Data.Finset.Basic.erase_eq_iff_eq_insert (L144-L146)
lemma erase_eq_iff_eq_insert (hs : a ∈ s) (ht : a ∉ t) : s.erase a = t ↔ s = insert a t := by
aesop
```

-- snippet 28
```lean
-- Mathlib.Data.Finset.Basic.not_disjoint_iff_nonempty_inter (L85-L89)
theorem not_disjoint_iff_nonempty_inter : ¬Disjoint s t ↔ (s ∩ t).Nonempty :=
not_disjoint_iff.trans <| by simp [Finset.Nonempty]

alias ⟨_, Nonempty.not_disjoint⟩ := not_disjoint_iff_nonempty_inter
```

-- snippet 29
```lean
-- Mathlib.Data.Finset.Basic.erase_cons (L159-L160)
theorem erase_cons {s : Finset α} {a : α} (h : a ∉ s) : (s.cons a h).erase a = s := by grind
```

-- snippet 30
```lean
-- Mathlib.Data.Finset.Basic.erase_ssubset_insert (L156-L158)
theorem erase_ssubset_insert (s : Finset α) (a : α) : s.erase a ⊂ insert a s :=
ssubset_iff_exists_subset_erase.2 ⟨a, mem_insert_self _ _, by grw [← subset_insert]⟩
```

-- snippet 31
```lean
-- Mathlib.Data.Finset.Basic.insert_erase_invOn (L147-L150)
lemma insert_erase_invOn :
    Set.InvOn (insert a) (fun s ↦ s.erase a) {s : Finset α | a ∈ s} {s : Finset α | a ∉ s} :=
⟨fun _s ↦ insert_erase, fun _s ↦ erase_insert⟩
```

-- snippet 32
```lean
-- Mathlib.Data.Finset.Attach.attach (L46-L48)
def attach (s : Finset α) : Finset { x // x ∈ s } :=
⟨Multiset.attach s.1, nodup_attach.2 s.2⟩
```

-- snippet 33
```lean
-- Mathlib.Data.Finset.Basic.disjoint_of_subset_iff_left_eq_empty (L95-L98)
theorem disjoint_of_subset_iff_left_eq_empty (h : s ⊆ t) :
    Disjoint s t ↔ s = ∅ :=
disjoint_of_le_iff_left_eq_bot h
```

-- snippet 34
```lean
-- Mathlib.Data.Finset.Basic.erase_empty (L116-L121)
theorem erase_empty (a : α) : erase ∅ a = ∅ :=
rfl

protected lemma Nontrivial.erase_nonempty (hs : s.Nontrivial) : (s.erase a).Nonempty :=
  (hs.exists_ne a).imp <| by simp_all
```

-- snippet 35
```lean
-- Mathlib.Data.Finset.Basic.erase_insert (L134-L135)
theorem erase_insert {a : α} {s : Finset α} (h : a ∉ s) : (insert a s).erase a = s := by grind
```

-- snippet 36
```lean
-- Mathlib.Data.Finset.Basic.pairwiseDisjoint_iff (L99-L105)
lemma pairwiseDisjoint_iff {ι : Type*} {s : Set ι} {f : ι → Finset α} :
    s.PairwiseDisjoint f ↔ ∀ ⦃i⦄, i ∈ s → ∀ ⦃j⦄, j ∈ s → (f i ∩ f j).Nonempty → i = j := by
simp [Set.PairwiseDisjoint, Set.Pairwise, not_imp_comm (a := _ = _),
    not_disjoint_iff_nonempty_inter]

end Lattice
```

-- snippet 37
```lean
-- Mathlib.Data.Finset.Attach.mem_attach (L54-L56)
theorem mem_attach (s : Finset α) : ∀ x, x ∈ s.attach :=
Multiset.mem_attach _
```

-- snippet 38
```lean
-- Mathlib.Data.Finset.Basic.erase_insert_of_ne (L136-L138)
theorem erase_insert_of_ne {a b : α} {s : Finset α} (h : a ≠ b) :
    (insert a s).erase b = insert a (s.erase b) := by grind
```

-- snippet 39
```lean
-- Mathlib.Data.Finset.Basic.erase_ssubset (L151-L152)
theorem erase_ssubset {a : α} {s : Finset α} (h : a ∈ s) : s.erase a ⊂ s := by grind
```

-- snippet 40
```lean
-- Mathlib.Data.Finset.Basic.isDirected_le (L106-L106)
instance isDirected_le : IsDirectedOrder (Finset α) := by classical infer_instance
```
[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RingTheory.Congruence.Hom).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
theorem map_apply {c d : RingCon M} (h : c ≤ d) (x) :
    c.map d h x = c.lift d.mk' (fun _ _ hc => d.eq.2 <| h hc) x
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker (L62-L63)
def ker (f : M →+* N) : RingCon M := comap ⊥ f
```

-- snippet 2
```lean
-- Mathlib.RingTheory.Congruence.Hom.comap_bot (L64-L66)
theorem comap_bot (f : M →+* N) : comap ⊥ f = ker f := rfl
/-- The definition of the ring congruence relation defined by a ring homomorphism's kernel. -/
```

-- snippet 3
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker_apply (L68-L71)
theorem ker_apply (f : M →+* N) {x y} : ker f x y ↔ f x = f y :=
Iff.rfl

/-- The kernel of the quotient map induced by a ring congruence relation `c` equals `c`. -/
```

-- snippet 4
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker_mk'_eq (L72-L74)
theorem ker_mk'_eq (c : RingCon M) : ker c.mk' = c :=
ext fun _ _ => Quotient.eq''
```

-- snippet 5
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker_comp (L75-L78)
theorem ker_comp {f : M →+* N} {g : N →+* P} :
    ker (g.comp f) = (ker g).comap f :=
ext fun x y ↦ by simp [ker_apply, comap_rel]
```

-- snippet 6
```lean
-- Mathlib.RingTheory.Congruence.Hom.comap_eq (L79-L90)
theorem comap_eq {g : N →+* M} :
    c.comap g = ker (c.mk'.comp g) := by
rw [ker_comp, ker_mk'_eq]

/-- Makes an isomorphism of quotients by two ring congruence
relations, given that the relations are equal. -/
protected def congr (h : c = d) :
    c.Quotient ≃+* d.Quotient :=
  { Quotient.congr (Equiv.refl M) <| by apply RingCon.ext_iff.mp h with
    map_add' x y := by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl
    map_mul' x y := by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl }
```

-- snippet 7
```lean
-- Mathlib.RingTheory.Congruence.Hom.mapGen (L97-L102)
def mapGen {c : RingCon M} (f : M → N) : RingCon N :=
ringConGen <| Relation.Map c f f

/-- If `c` is a ring congruence on `M`, then the smallest ring
congruence relation on `N` deduced from `c` by a ring homomorphism
from `M` to `N` is the relation deduced from `c`. -/
```

-- snippet 8
```lean
-- Mathlib.RingTheory.Congruence.Hom.mapGen_eq_map_of_surjective (L103-L122)
theorem mapGen_eq_map_of_surjective
    {c : RingCon M} (f : M →+* N) (h : ker f ≤ c) (hf : Surjective f) :
    c.mapGen f = Relation.Map c f f := by
refine le_antisymm ?_ <| (RingCon.gi N).gc.le_u_l _
  have := Relation.map_equivalence c.toSetoid.2 _ hf h
  intro _ _ hg
  induction hg with
  | of _ _ a => exact a
  | refl x => exact this.refl x
  | symm _ h => exact this.symm h
  | trans _ _ h₁ h₂ => exact this.trans h₁ h₂
  | add _ _ h₁ h₂ =>
    rcases h₁ with ⟨a, b, h1, rfl, rfl⟩
    rcases h₂ with ⟨p, q, h2, rfl, rfl⟩
    exact ⟨a + p, b + q, c.add h1 h2, map_add f _ _, map_add f _ _⟩
  | mul _ _ h₁ h₂ =>
    rcases h₁ with ⟨a, b, h1, rfl, rfl⟩
    rcases h₂ with ⟨p, q, h2, rfl, rfl⟩
    exact ⟨a * p, b * q, c.mul h1 h2, map_mul f _ _, map_mul f _ _⟩
```

-- snippet 9
```lean
-- Mathlib.RingTheory.Congruence.Hom.mapGen_apply_apply_of_surjective (L123-L132)
theorem mapGen_apply_apply_of_surjective
    {c : RingCon M} (f : M →+* N) (h : ker f ≤ c) (hf : Surjective f) {x y : M} :
    c.mapGen f (f x) (f y) ↔ c x y := by
rw [mapGen_eq_map_of_surjective f h hf, Relation.map_apply]
  refine ⟨fun ⟨a, b, h₁, h₂, h₃⟩ ↦ ?_, by grind⟩
  exact c.trans (h h₂.symm) <| c.trans h₁ <| h h₃

/-- Given a ring congruence relation `c` on a semiring `M`, the order-preserving
bijection between the set of ring congruence relations containing `c` and the
ring congruence relations on the quotient of `M` by `c`. -/
```

-- snippet 10
```lean
-- Mathlib.RingTheory.Congruence.Hom.correspondence (L133-L159)
def correspondence {c : RingCon M} : Set.Ici c ≃o RingCon c.Quotient where
  toFun d := d.1.mapGen c.mk'
invFun d := ⟨d.comap (mk' c), c.ker_mk'_eq.symm.trans_le <| comap_bot c.mk' ▸ comap_mono bot_le⟩
  left_inv d := by
    ext
    simp only [comap_rel]
    rw [mapGen_apply_apply_of_surjective c.mk' (c.ker_mk'_eq.trans_le d.2) c.mk'_surjective]
  right_inv d := by
    ext x y
    simp only
    obtain ⟨x, rfl⟩ := c.mk'_surjective x
    obtain ⟨y, rfl⟩ := c.mk'_surjective y
    rw [mapGen_apply_apply_of_surjective _ (comap_bot c.mk' ▸ comap_mono bot_le) c.mk'_surjective,
      comap_rel]
  map_rel_iff' {s t} := by
    simp only [Equiv.coe_fn_mk, le_def, c.mk'_surjective.forall, ← Subtype.coe_le_coe]
    simp_rw [mapGen_apply_apply_of_surjective c.mk' (c.ker_mk'_eq.trans_le s.2) c.mk'_surjective,
      mapGen_apply_apply_of_surjective c.mk' (c.ker_mk'_eq.trans_le t.2) c.mk'_surjective]

variable (c : RingCon M)

variable (x y : M)

variable (f : M →+* P)

/-- The homomorphism on the quotient of a ring by a congruence relation `c`
induced by a homomorphism constant on the equivalence classes of `c`. -/
```

-- snippet 11
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift (L160-L167)
def lift (H : c ≤ ker f) : c.Quotient →+* P where
  __ := c.toAddCon.lift f.toAddMonoidHom H
map_one' := f.map_one
  map_mul' x y := Con.induction_on₂ x y fun m n => f.map_mul m n

variable {c f}

/-- The diagram describing the universal property for quotients of ring commutes. -/
```

-- snippet 12
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift_mk' (L168-L171)
theorem lift_mk' (H : c ≤ ker f) (x) : c.lift f H (c.mk' x) = f x :=
rfl

/-- The diagram describing the universal property for quotients of rings commutes. -/
```

-- snippet 13
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift_apply_mk' (L181-L186)
theorem lift_apply_mk' (f : c.Quotient →+* P) :
    (c.lift (f.comp c.mk') fun x y h => show f ↑x = f ↑y by rw [c.eq.2 h]) = f := by
ext x; rcases x with ⟨⟩; rfl

/-- Homomorphisms on the quotient of a ring by a ring congruence relation are
equal if they are equal on elements that are coercions from the ring. -/
```

-- snippet 14
```lean
-- Mathlib.RingTheory.Congruence.Hom.Quotient (L188-L191)
theorem Quotient.hom_ext {f g : c.Quotient →+* P} (h : f.comp c.mk' = g.comp c.mk') : f = g :=
DFunLike.ext _ _ <| c.mk'_surjective.forall.mpr fun x ↦ by exact congr($h x)

/-- The uniqueness part of the universal property for quotients of rings. -/
```

-- snippet 15
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift_unique (L192-L197)
theorem lift_unique (H : c ≤ ker f) (g : c.Quotient →+* P) (Hg : g.comp c.mk' = f) :
    g = c.lift f H :=
Quotient.hom_ext (by aesop)

/-- Surjective ring homomorphisms constant on the equivalence classes
of a ring congruence relation induce a surjective homomorphism on the quotient. -/
```

-- snippet 16
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_inf (L196-L198)
theorem coe_inf {c d : RingCon R} : ⇑(c ⊓ d) = ⇑c ⊓ ⇑d := rfl
/-- Definition of the infimum of two congruence relations. -/
```

-- snippet 17
```lean
-- Mathlib.RingTheory.Congruence.Defs.toCon_injective (L75-L76)
lemma toCon_injective : Injective fun c : RingCon R ↦ c.toCon := fun c d ↦ by cases c; congr!
```

-- snippet 18
```lean
-- Mathlib.RingTheory.Congruence.Basic.nontrivial_iff (L210-L214)
theorem nontrivial_iff : Nontrivial (RingCon R) ↔ Nontrivial R := by
cases subsingleton_or_nontrivial R
  on_goal 1 => simp_rw [← not_subsingleton_iff_nontrivial, not_iff_not]
  all_goals exact iff_of_true inferInstance ‹_›
```

-- snippet 19
```lean
-- Mathlib.RingTheory.Congruence.Basic.sup_eq_ringConGen (L253-L259)
theorem sup_eq_ringConGen (c d : RingCon R) : c ⊔ d = ringConGen fun x y => c x y ∨ d x y := by
rw [ringConGen_eq]
  apply congr_arg sInf
  simp only [le_def, or_imp, ← forall_and]

/-- The supremum of two congruence relations equals the smallest congruence relation containing
the supremum of the underlying binary operations. -/
```

-- snippet 20
```lean
-- Mathlib.RingTheory.Congruence.Defs.coe_mk (L87-L88)
theorem coe_mk (s : Con R) (h) : ⇑(mk s h) = s := rfl
```

-- snippet 21
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_eq (L220-L231)
theorem ringConGen_eq (r : R → R → Prop) :
    ringConGen r = sInf {s : RingCon R | ∀ x y, r x y → s x y} :=
le_antisymm
    (fun _x _y H =>
      RingConGen.Rel.recOn H (fun _ _ h _ hs => hs _ _ h) (RingCon.refl _)
        (fun _ => RingCon.symm _) (fun _ _ => RingCon.trans _)
        (fun _ _ h1 h2 c hc => c.add (h1 c hc) <| h2 c hc)
        (fun _ _ h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc))
    (sInf_le fun _ _ => RingConGen.Rel.of _ _)

/-- The smallest congruence relation containing a binary relation `r` is contained in any
congruence relation containing `r`. -/
```

-- snippet 22
```lean
-- Mathlib.RingTheory.Congruence.Basic.sup_def (L260-L264)
theorem sup_def {c d : RingCon R} : c ⊔ d = ringConGen (⇑c ⊔ ⇑d) := by
rw [sup_eq_ringConGen]; rfl

/-- The supremum of a set of congruence relations `S` equals the smallest congruence relation
containing the binary relation 'there exists `c ∈ S` such that `x` is related to `y` by `c`'. -/
```

-- snippet 23
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_iInf (L147-L149)
theorem coe_iInf {ι : Sort*} (f : ι → RingCon R) : ⇑(iInf f) = ⨅ i, ⇑(f i) := by
rw [iInf, coe_sInf, ← Set.range_comp, sInf_range, Function.comp_def]
```

-- snippet 24
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_of_ringCon (L243-L247)
theorem ringConGen_of_ringCon (c : RingCon R) : ringConGen c = c :=
le_antisymm (by rw [ringConGen_eq]; exact sInf_le fun _ _ => id) RingConGen.Rel.of

/-- The map sending a binary relation to the smallest congruence relation in which it is
contained is idempotent. -/
```

-- snippet 25
```lean
-- Mathlib.RingTheory.Congruence.Basic.sInf_toSetoid (L136-L141)
theorem sInf_toSetoid (S : Set (RingCon R)) : (sInf S).toSetoid = sInf ((·.toSetoid) '' S) :=
Setoid.ext fun x y =>
    ⟨fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩

/-- The infimum of a set of congruence relations is the same as the infimum of the set's image
under the map to the underlying binary relation. -/
```

-- snippet 26
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_mono (L238-L242)
theorem ringConGen_mono {r s : R → R → Prop} (h : ∀ x y, r x y → s x y) :
    ringConGen r ≤ ringConGen s :=
ringConGen_le fun x y hr => RingConGen.Rel.of _ _ <| h x y hr

/-- Congruence relations equal the smallest congruence relation in which they are contained. -/
```

-- snippet 27
```lean
-- Mathlib.RingTheory.Congruence.Basic.isScalarTower_right (L71-L74)
instance isScalarTower_right [Add R] [MulOneClass R] [SMul α R] [IsScalarTower α R R]
    (c : RingCon R) : IsScalarTower α c.Quotient c.Quotient where
  smul_assoc _ := Quotient.ind₂' fun _ _ => congr_arg Quotient.mk'' <| smul_mul_assoc _ _ _
```

-- snippet 28
```lean
-- Mathlib.RingTheory.Congruence.Basic.sSup_eq_ringConGen (L265-L273)
theorem sSup_eq_ringConGen (S : Set (RingCon R)) :
    sSup S = ringConGen fun x y => ∃ c : RingCon R, c ∈ S ∧ c x y := by
rw [ringConGen_eq]
  apply congr_arg sInf
  ext
  exact ⟨fun h _ _ ⟨r, hr⟩ => h hr.1 hr.2, fun h r hS _ _ hr => h _ _ ⟨r, hS, hr⟩⟩

/-- The supremum of a set of congruence relations is the same as the smallest congruence relation
containing the supremum of the set's image under the map to the underlying binary relation. -/
```

-- snippet 29
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_idem (L248-L252)
theorem ringConGen_idem (r : R → R → Prop) : ringConGen (ringConGen r) = ringConGen r :=
ringConGen_of_ringCon _

/-- The supremum of congruence relations `c, d` equals the smallest congruence relation containing
the binary relation '`x` is related to `y` by `c` or `d`'. -/
```

-- snippet 30
```lean
-- Mathlib.RingTheory.Congruence.Basic.le_def (L115-L116)
theorem le_def : c ≤ d ↔ ∀ {x y}, c x y → d x y := .rfl
```

-- snippet 31
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_le (L232-L237)
theorem ringConGen_le {r : R → R → Prop} {c : RingCon R}
    (h : ∀ x y, r x y → c x y) : ringConGen r ≤ c := by
rw [ringConGen_eq]; exact sInf_le h

/-- Given binary relations `r, s` with `r` contained in `s`, the smallest congruence relation
containing `s` contains the smallest congruence relation containing `r`. -/
```

-- snippet 32
```lean
-- Mathlib.RingTheory.Congruence.Basic.comap_mono (L117-L124)
theorem comap_mono {R' : Type*} [Add R'] [Mul R']
    {F : Type*} [FunLike F R R'] [AddHomClass F R R'] [MulHomClass F R R']
    {J J' : RingCon R'} {f : F} (h : J ≤ J') :
    J.comap f ≤ J'.comap f :=
fun _ _ h₁ ↦ h h₁

/-- The infimum of a set of congruence relations on a given type with multiplication and
addition. -/
```

-- snippet 33
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_sInf (L143-L145)
theorem coe_sInf (S : Set (RingCon R)) : ⇑(sInf S) = sInf ((⇑) '' S) := by
ext; simp only [sInf_image, iInf_apply, iInf_Prop_eq]; rfl
```

-- snippet 34
```lean
-- Mathlib.RingTheory.Congruence.Basic.smulCommClass (L75-L78)
instance smulCommClass [Add R] [MulOneClass R] [SMul α R] [IsScalarTower α R R]
    [SMulCommClass α R R] (c : RingCon R) : SMulCommClass α c.Quotient c.Quotient where
  smul_comm _ := Quotient.ind₂' fun _ _ => congr_arg Quotient.mk'' <| (mul_smul_comm _ _ _).symm
```

-- snippet 35
```lean
-- Mathlib.RingTheory.Congruence.Defs.ringConGen (L63-L74)
def ringConGen [Add R] [Mul R] (r : R → R → Prop) : RingCon R where
  r := RingConGen.Rel r
iseqv := ⟨RingConGen.Rel.refl, @RingConGen.Rel.symm _ _ _ _, @RingConGen.Rel.trans _ _ _ _⟩
  add' := RingConGen.Rel.add
  mul' := RingConGen.Rel.mul

namespace RingCon

section Basic

variable [Add R] [Mul R] {c d : RingCon R}
```

-- snippet 36
```lean
-- Mathlib.RingTheory.Congruence.Basic.subsingleton_iff (L215-L219)
theorem subsingleton_iff : Subsingleton (RingCon R) ↔ Subsingleton R := by
simp_rw [← not_nontrivial_iff_subsingleton, nontrivial_iff]

/-- The inductively defined smallest congruence relation containing a binary relation `r` equals
the infimum of the set of congruence relations containing `r`. -/
```

-- snippet 37
```lean
-- Mathlib.RingTheory.Congruence.Basic.sSup_def (L274-L294)
theorem sSup_def {S : Set (RingCon R)} :
    sSup S = ringConGen (sSup (@Set.image (RingCon R) (R → R → Prop) (⇑) S)) := by
rw [sSup_eq_ringConGen, sSup_image]
  congr with (x y)
  simp only [iSup_apply, iSup_Prop_eq, exists_prop]

variable (R)

/-- There is a Galois insertion of congruence relations on a type with multiplication and addition
`R` into binary relations on `R`. -/
protected def gi : @GaloisInsertion (R → R → Prop) (RingCon R) _ _ ringConGen (⇑) where
  choice r _h := ringConGen r
  gc _r c :=
    ⟨fun H _ _ h => H <| RingConGen.Rel.of _ _ h, fun H =>
      ringConGen_of_ringCon c ▸ ringConGen_mono H⟩
  le_l_u x := (ringConGen_of_ringCon x).symm ▸ le_refl x
  choice_eq _ _ := rfl

end Lattice

end RingCon
```

-- snippet 38
```lean
-- Mathlib.RingTheory.Congruence.Basic.inf_iff_and (L199-L201)
theorem inf_iff_and {c d : RingCon R} {x y} : (c ⊓ d) x y ↔ c x y ∧ d x y :=
Iff.rfl
```

-- snippet 39
```lean
-- Mathlib.RingTheory.Congruence.Basic.smulCommClass' (L79-L83)
instance smulCommClass' [Add R] [MulOneClass R] [SMul α R] [IsScalarTower α R R]
    [SMulCommClass R α R] (c : RingCon R) : SMulCommClass c.Quotient α c.Quotient :=
haveI := SMulCommClass.symm R α R
  SMulCommClass.symm _ _ _
```

-- snippet 40
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_smul (L57-L59)
theorem coe_smul (a : α) (x : R) : (↑(a • x) : c.Quotient) = a • (x : c.Quotient) :=
rfl
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RingTheory.Congruence.Hom).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem map_apply {c d : RingCon M} (h : c ≤ d) (x) :
    c.map d h x = c.lift d.mk' (fun _ _ hc => d.eq.2 <| h hc) x
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker (L62-L63)
def ker (f : M →+* N) : RingCon M := comap ⊥ f
```

-- snippet 2
```lean
-- Mathlib.RingTheory.Congruence.Hom.comap_bot (L64-L66)
theorem comap_bot (f : M →+* N) : comap ⊥ f = ker f := rfl
/-- The definition of the ring congruence relation defined by a ring homomorphism's kernel. -/
```

-- snippet 3
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker_apply (L68-L71)
theorem ker_apply (f : M →+* N) {x y} : ker f x y ↔ f x = f y :=
Iff.rfl

/-- The kernel of the quotient map induced by a ring congruence relation `c` equals `c`. -/
```

-- snippet 4
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker_mk'_eq (L72-L74)
theorem ker_mk'_eq (c : RingCon M) : ker c.mk' = c :=
ext fun _ _ => Quotient.eq''
```

-- snippet 5
```lean
-- Mathlib.RingTheory.Congruence.Hom.ker_comp (L75-L78)
theorem ker_comp {f : M →+* N} {g : N →+* P} :
    ker (g.comp f) = (ker g).comap f :=
ext fun x y ↦ by simp [ker_apply, comap_rel]
```

-- snippet 6
```lean
-- Mathlib.RingTheory.Congruence.Hom.comap_eq (L79-L90)
theorem comap_eq {g : N →+* M} :
    c.comap g = ker (c.mk'.comp g) := by
rw [ker_comp, ker_mk'_eq]

/-- Makes an isomorphism of quotients by two ring congruence
relations, given that the relations are equal. -/
protected def congr (h : c = d) :
    c.Quotient ≃+* d.Quotient :=
  { Quotient.congr (Equiv.refl M) <| by apply RingCon.ext_iff.mp h with
    map_add' x y := by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl
    map_mul' x y := by rcases x with ⟨⟩; rcases y with ⟨⟩; rfl }
```

-- snippet 7
```lean
-- Mathlib.RingTheory.Congruence.Hom.mapGen (L97-L102)
def mapGen {c : RingCon M} (f : M → N) : RingCon N :=
ringConGen <| Relation.Map c f f

/-- If `c` is a ring congruence on `M`, then the smallest ring
congruence relation on `N` deduced from `c` by a ring homomorphism
from `M` to `N` is the relation deduced from `c`. -/
```

-- snippet 8
```lean
-- Mathlib.RingTheory.Congruence.Hom.mapGen_eq_map_of_surjective (L103-L122)
theorem mapGen_eq_map_of_surjective
    {c : RingCon M} (f : M →+* N) (h : ker f ≤ c) (hf : Surjective f) :
    c.mapGen f = Relation.Map c f f := by
refine le_antisymm ?_ <| (RingCon.gi N).gc.le_u_l _
  have := Relation.map_equivalence c.toSetoid.2 _ hf h
  intro _ _ hg
  induction hg with
  | of _ _ a => exact a
  | refl x => exact this.refl x
  | symm _ h => exact this.symm h
  | trans _ _ h₁ h₂ => exact this.trans h₁ h₂
  | add _ _ h₁ h₂ =>
    rcases h₁ with ⟨a, b, h1, rfl, rfl⟩
    rcases h₂ with ⟨p, q, h2, rfl, rfl⟩
    exact ⟨a + p, b + q, c.add h1 h2, map_add f _ _, map_add f _ _⟩
  | mul _ _ h₁ h₂ =>
    rcases h₁ with ⟨a, b, h1, rfl, rfl⟩
    rcases h₂ with ⟨p, q, h2, rfl, rfl⟩
    exact ⟨a * p, b * q, c.mul h1 h2, map_mul f _ _, map_mul f _ _⟩
```

-- snippet 9
```lean
-- Mathlib.RingTheory.Congruence.Hom.mapGen_apply_apply_of_surjective (L123-L132)
theorem mapGen_apply_apply_of_surjective
    {c : RingCon M} (f : M →+* N) (h : ker f ≤ c) (hf : Surjective f) {x y : M} :
    c.mapGen f (f x) (f y) ↔ c x y := by
rw [mapGen_eq_map_of_surjective f h hf, Relation.map_apply]
  refine ⟨fun ⟨a, b, h₁, h₂, h₃⟩ ↦ ?_, by grind⟩
  exact c.trans (h h₂.symm) <| c.trans h₁ <| h h₃

/-- Given a ring congruence relation `c` on a semiring `M`, the order-preserving
bijection between the set of ring congruence relations containing `c` and the
ring congruence relations on the quotient of `M` by `c`. -/
```

-- snippet 10
```lean
-- Mathlib.RingTheory.Congruence.Hom.correspondence (L133-L159)
def correspondence {c : RingCon M} : Set.Ici c ≃o RingCon c.Quotient where
  toFun d := d.1.mapGen c.mk'
invFun d := ⟨d.comap (mk' c), c.ker_mk'_eq.symm.trans_le <| comap_bot c.mk' ▸ comap_mono bot_le⟩
  left_inv d := by
    ext
    simp only [comap_rel]
    rw [mapGen_apply_apply_of_surjective c.mk' (c.ker_mk'_eq.trans_le d.2) c.mk'_surjective]
  right_inv d := by
    ext x y
    simp only
    obtain ⟨x, rfl⟩ := c.mk'_surjective x
    obtain ⟨y, rfl⟩ := c.mk'_surjective y
    rw [mapGen_apply_apply_of_surjective _ (comap_bot c.mk' ▸ comap_mono bot_le) c.mk'_surjective,
      comap_rel]
  map_rel_iff' {s t} := by
    simp only [Equiv.coe_fn_mk, le_def, c.mk'_surjective.forall, ← Subtype.coe_le_coe]
    simp_rw [mapGen_apply_apply_of_surjective c.mk' (c.ker_mk'_eq.trans_le s.2) c.mk'_surjective,
      mapGen_apply_apply_of_surjective c.mk' (c.ker_mk'_eq.trans_le t.2) c.mk'_surjective]

variable (c : RingCon M)

variable (x y : M)

variable (f : M →+* P)

/-- The homomorphism on the quotient of a ring by a congruence relation `c`
induced by a homomorphism constant on the equivalence classes of `c`. -/
```

-- snippet 11
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift (L160-L167)
def lift (H : c ≤ ker f) : c.Quotient →+* P where
  __ := c.toAddCon.lift f.toAddMonoidHom H
map_one' := f.map_one
  map_mul' x y := Con.induction_on₂ x y fun m n => f.map_mul m n

variable {c f}

/-- The diagram describing the universal property for quotients of ring commutes. -/
```

-- snippet 12
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift_mk' (L168-L171)
theorem lift_mk' (H : c ≤ ker f) (x) : c.lift f H (c.mk' x) = f x :=
rfl

/-- The diagram describing the universal property for quotients of rings commutes. -/
```

-- snippet 13
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift_apply_mk' (L181-L186)
theorem lift_apply_mk' (f : c.Quotient →+* P) :
    (c.lift (f.comp c.mk') fun x y h => show f ↑x = f ↑y by rw [c.eq.2 h]) = f := by
ext x; rcases x with ⟨⟩; rfl

/-- Homomorphisms on the quotient of a ring by a ring congruence relation are
equal if they are equal on elements that are coercions from the ring. -/
```

-- snippet 14
```lean
-- Mathlib.RingTheory.Congruence.Hom.Quotient (L188-L191)
theorem Quotient.hom_ext {f g : c.Quotient →+* P} (h : f.comp c.mk' = g.comp c.mk') : f = g :=
DFunLike.ext _ _ <| c.mk'_surjective.forall.mpr fun x ↦ by exact congr($h x)

/-- The uniqueness part of the universal property for quotients of rings. -/
```

-- snippet 15
```lean
-- Mathlib.RingTheory.Congruence.Hom.lift_unique (L192-L197)
theorem lift_unique (H : c ≤ ker f) (g : c.Quotient →+* P) (Hg : g.comp c.mk' = f) :
    g = c.lift f H :=
Quotient.hom_ext (by aesop)

/-- Surjective ring homomorphisms constant on the equivalence classes
of a ring congruence relation induce a surjective homomorphism on the quotient. -/
```

-- snippet 16
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_inf (L196-L198)
theorem coe_inf {c d : RingCon R} : ⇑(c ⊓ d) = ⇑c ⊓ ⇑d := rfl
/-- Definition of the infimum of two congruence relations. -/
```

-- snippet 17
```lean
-- Mathlib.RingTheory.Congruence.Defs.toCon_injective (L75-L76)
lemma toCon_injective : Injective fun c : RingCon R ↦ c.toCon := fun c d ↦ by cases c; congr!
```

-- snippet 18
```lean
-- Mathlib.RingTheory.Congruence.Basic.nontrivial_iff (L210-L214)
theorem nontrivial_iff : Nontrivial (RingCon R) ↔ Nontrivial R := by
cases subsingleton_or_nontrivial R
  on_goal 1 => simp_rw [← not_subsingleton_iff_nontrivial, not_iff_not]
  all_goals exact iff_of_true inferInstance ‹_›
```

-- snippet 19
```lean
-- Mathlib.RingTheory.Congruence.Basic.sup_eq_ringConGen (L253-L259)
theorem sup_eq_ringConGen (c d : RingCon R) : c ⊔ d = ringConGen fun x y => c x y ∨ d x y := by
rw [ringConGen_eq]
  apply congr_arg sInf
  simp only [le_def, or_imp, ← forall_and]

/-- The supremum of two congruence relations equals the smallest congruence relation containing
the supremum of the underlying binary operations. -/
```

-- snippet 20
```lean
-- Mathlib.RingTheory.Congruence.Defs.coe_mk (L87-L88)
theorem coe_mk (s : Con R) (h) : ⇑(mk s h) = s := rfl
```

-- snippet 21
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_eq (L220-L231)
theorem ringConGen_eq (r : R → R → Prop) :
    ringConGen r = sInf {s : RingCon R | ∀ x y, r x y → s x y} :=
le_antisymm
    (fun _x _y H =>
      RingConGen.Rel.recOn H (fun _ _ h _ hs => hs _ _ h) (RingCon.refl _)
        (fun _ => RingCon.symm _) (fun _ _ => RingCon.trans _)
        (fun _ _ h1 h2 c hc => c.add (h1 c hc) <| h2 c hc)
        (fun _ _ h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc))
    (sInf_le fun _ _ => RingConGen.Rel.of _ _)

/-- The smallest congruence relation containing a binary relation `r` is contained in any
congruence relation containing `r`. -/
```

-- snippet 22
```lean
-- Mathlib.RingTheory.Congruence.Basic.sup_def (L260-L264)
theorem sup_def {c d : RingCon R} : c ⊔ d = ringConGen (⇑c ⊔ ⇑d) := by
rw [sup_eq_ringConGen]; rfl

/-- The supremum of a set of congruence relations `S` equals the smallest congruence relation
containing the binary relation 'there exists `c ∈ S` such that `x` is related to `y` by `c`'. -/
```

-- snippet 23
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_iInf (L147-L149)
theorem coe_iInf {ι : Sort*} (f : ι → RingCon R) : ⇑(iInf f) = ⨅ i, ⇑(f i) := by
rw [iInf, coe_sInf, ← Set.range_comp, sInf_range, Function.comp_def]
```

-- snippet 24
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_of_ringCon (L243-L247)
theorem ringConGen_of_ringCon (c : RingCon R) : ringConGen c = c :=
le_antisymm (by rw [ringConGen_eq]; exact sInf_le fun _ _ => id) RingConGen.Rel.of

/-- The map sending a binary relation to the smallest congruence relation in which it is
contained is idempotent. -/
```

-- snippet 25
```lean
-- Mathlib.RingTheory.Congruence.Basic.sInf_toSetoid (L136-L141)
theorem sInf_toSetoid (S : Set (RingCon R)) : (sInf S).toSetoid = sInf ((·.toSetoid) '' S) :=
Setoid.ext fun x y =>
    ⟨fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩

/-- The infimum of a set of congruence relations is the same as the infimum of the set's image
under the map to the underlying binary relation. -/
```

-- snippet 26
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_mono (L238-L242)
theorem ringConGen_mono {r s : R → R → Prop} (h : ∀ x y, r x y → s x y) :
    ringConGen r ≤ ringConGen s :=
ringConGen_le fun x y hr => RingConGen.Rel.of _ _ <| h x y hr

/-- Congruence relations equal the smallest congruence relation in which they are contained. -/
```

-- snippet 27
```lean
-- Mathlib.RingTheory.Congruence.Basic.isScalarTower_right (L71-L74)
instance isScalarTower_right [Add R] [MulOneClass R] [SMul α R] [IsScalarTower α R R]
    (c : RingCon R) : IsScalarTower α c.Quotient c.Quotient where
  smul_assoc _ := Quotient.ind₂' fun _ _ => congr_arg Quotient.mk'' <| smul_mul_assoc _ _ _
```

-- snippet 28
```lean
-- Mathlib.RingTheory.Congruence.Basic.sSup_eq_ringConGen (L265-L273)
theorem sSup_eq_ringConGen (S : Set (RingCon R)) :
    sSup S = ringConGen fun x y => ∃ c : RingCon R, c ∈ S ∧ c x y := by
rw [ringConGen_eq]
  apply congr_arg sInf
  ext
  exact ⟨fun h _ _ ⟨r, hr⟩ => h hr.1 hr.2, fun h r hS _ _ hr => h _ _ ⟨r, hS, hr⟩⟩

/-- The supremum of a set of congruence relations is the same as the smallest congruence relation
containing the supremum of the set's image under the map to the underlying binary relation. -/
```

-- snippet 29
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_idem (L248-L252)
theorem ringConGen_idem (r : R → R → Prop) : ringConGen (ringConGen r) = ringConGen r :=
ringConGen_of_ringCon _

/-- The supremum of congruence relations `c, d` equals the smallest congruence relation containing
the binary relation '`x` is related to `y` by `c` or `d`'. -/
```

-- snippet 30
```lean
-- Mathlib.RingTheory.Congruence.Basic.le_def (L115-L116)
theorem le_def : c ≤ d ↔ ∀ {x y}, c x y → d x y := .rfl
```

-- snippet 31
```lean
-- Mathlib.RingTheory.Congruence.Basic.ringConGen_le (L232-L237)
theorem ringConGen_le {r : R → R → Prop} {c : RingCon R}
    (h : ∀ x y, r x y → c x y) : ringConGen r ≤ c := by
rw [ringConGen_eq]; exact sInf_le h

/-- Given binary relations `r, s` with `r` contained in `s`, the smallest congruence relation
containing `s` contains the smallest congruence relation containing `r`. -/
```

-- snippet 32
```lean
-- Mathlib.RingTheory.Congruence.Basic.comap_mono (L117-L124)
theorem comap_mono {R' : Type*} [Add R'] [Mul R']
    {F : Type*} [FunLike F R R'] [AddHomClass F R R'] [MulHomClass F R R']
    {J J' : RingCon R'} {f : F} (h : J ≤ J') :
    J.comap f ≤ J'.comap f :=
fun _ _ h₁ ↦ h h₁

/-- The infimum of a set of congruence relations on a given type with multiplication and
addition. -/
```

-- snippet 33
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_sInf (L143-L145)
theorem coe_sInf (S : Set (RingCon R)) : ⇑(sInf S) = sInf ((⇑) '' S) := by
ext; simp only [sInf_image, iInf_apply, iInf_Prop_eq]; rfl
```

-- snippet 34
```lean
-- Mathlib.RingTheory.Congruence.Basic.smulCommClass (L75-L78)
instance smulCommClass [Add R] [MulOneClass R] [SMul α R] [IsScalarTower α R R]
    [SMulCommClass α R R] (c : RingCon R) : SMulCommClass α c.Quotient c.Quotient where
  smul_comm _ := Quotient.ind₂' fun _ _ => congr_arg Quotient.mk'' <| (mul_smul_comm _ _ _).symm
```

-- snippet 35
```lean
-- Mathlib.RingTheory.Congruence.Defs.ringConGen (L63-L74)
def ringConGen [Add R] [Mul R] (r : R → R → Prop) : RingCon R where
  r := RingConGen.Rel r
iseqv := ⟨RingConGen.Rel.refl, @RingConGen.Rel.symm _ _ _ _, @RingConGen.Rel.trans _ _ _ _⟩
  add' := RingConGen.Rel.add
  mul' := RingConGen.Rel.mul

namespace RingCon

section Basic

variable [Add R] [Mul R] {c d : RingCon R}
```

-- snippet 36
```lean
-- Mathlib.RingTheory.Congruence.Basic.subsingleton_iff (L215-L219)
theorem subsingleton_iff : Subsingleton (RingCon R) ↔ Subsingleton R := by
simp_rw [← not_nontrivial_iff_subsingleton, nontrivial_iff]

/-- The inductively defined smallest congruence relation containing a binary relation `r` equals
the infimum of the set of congruence relations containing `r`. -/
```

-- snippet 37
```lean
-- Mathlib.RingTheory.Congruence.Basic.sSup_def (L274-L294)
theorem sSup_def {S : Set (RingCon R)} :
    sSup S = ringConGen (sSup (@Set.image (RingCon R) (R → R → Prop) (⇑) S)) := by
rw [sSup_eq_ringConGen, sSup_image]
  congr with (x y)
  simp only [iSup_apply, iSup_Prop_eq, exists_prop]

variable (R)

/-- There is a Galois insertion of congruence relations on a type with multiplication and addition
`R` into binary relations on `R`. -/
protected def gi : @GaloisInsertion (R → R → Prop) (RingCon R) _ _ ringConGen (⇑) where
  choice r _h := ringConGen r
  gc _r c :=
    ⟨fun H _ _ h => H <| RingConGen.Rel.of _ _ h, fun H =>
      ringConGen_of_ringCon c ▸ ringConGen_mono H⟩
  le_l_u x := (ringConGen_of_ringCon x).symm ▸ le_refl x
  choice_eq _ _ := rfl

end Lattice

end RingCon
```

-- snippet 38
```lean
-- Mathlib.RingTheory.Congruence.Basic.inf_iff_and (L199-L201)
theorem inf_iff_and {c d : RingCon R} {x y} : (c ⊓ d) x y ↔ c x y ∧ d x y :=
Iff.rfl
```

-- snippet 39
```lean
-- Mathlib.RingTheory.Congruence.Basic.smulCommClass' (L79-L83)
instance smulCommClass' [Add R] [MulOneClass R] [SMul α R] [IsScalarTower α R R]
    [SMulCommClass R α R] (c : RingCon R) : SMulCommClass c.Quotient α c.Quotient :=
haveI := SMulCommClass.symm R α R
  SMulCommClass.symm _ _ _
```

-- snippet 40
```lean
-- Mathlib.RingTheory.Congruence.Basic.coe_smul (L57-L59)
theorem coe_smul (a : α) (x : R) : (↑(a • x) : c.Quotient) = a • (x : c.Quotient) :=
rfl
```
[/INST]


Instruction: Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Data.Finset.Sort).

[User]
Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

```lean
theorem max'_eq_sorted_last {s : Finset α} {h : s.Nonempty} :
    s.max' h =
      s.sort[s.sort.length - 1]'
        (by simpa using Nat.sub_lt (card_pos.mpr h) Nat.zero_lt_one)
```

Declaration: `Mathlib.Data.Finset.Sort.max'_eq_sorted_last` (module Mathlib.Data.Finset.Sort).

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Data.Finset.Sort).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

```lean
theorem max'_eq_sorted_last {s : Finset α} {h : s.Nonempty} :
    s.max' h =
      s.sort[s.sort.length - 1]'
        (by simpa using Nat.sub_lt (card_pos.mpr h) Nat.zero_lt_one)
```

Declaration: `Mathlib.Data.Finset.Sort.max'_eq_sorted_last` (module Mathlib.Data.Finset.Sort).[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Topology.Semicontinuity.Hemicontinuity).

[User]
The following proof-state transcript was extracted from a real mathlib proof. Use it to answer the question below.

```text
Proof-state transcript for `Mathlib.Topology.Semicontinuity.Hemicontinuity.UpperHemicontinuousAt`:
State 0: ⊢ lemma UpperHemicontinuousAt.of_sequences {α β : Type*} [TopologicalSpace α]
    [TopologicalSpace β] {f : α → Set β} {x₀ : α} [(𝓝 x₀).IsCountablyGenerated]
    {K : Set β} (hK : IsSeqCompact K) (hf : ∀ᶠ x in 𝓝 x₀, f x ⊆ K)
    (h : ∀ x : ℕ → α, Tendsto x atTop (𝓝 x₀) →
      ∀ y : ℕ → β, (∀ n, y n ∈ f (x n)) → ∀ y₀, Tendsto y atTop (𝓝 y₀) → y₀ ∈ f x₀) :
    UpperHemicontinuousAt f x₀
Tactic: refine .of_frequently fun t ht hft ↦ ?_
State 1: ⊢ <goal after refine .of_frequently fun t ht hft ↦ ?_>
Tactic: obtain ⟨x, hx, hfx⟩ := exists_seq_forall_of_frequently hft
State 2: ⊢ <goal after obtain ⟨x, hx, hfx⟩ := exists_seq_forall_of_frequently hft>
Tactic: choose y hy using hfx
State 3: ⊢ <goal after choose y hy using hfx>
Tactic: obtain ⟨y₀, hy₀, φ, hφ, hyφ⟩ := hK.subseq_of_frequently_in (x := y) <| by
State 4: ⊢ <goal after obtain ⟨y₀, hy₀, φ, hφ, hyφ⟩ := hK.subseq_of_frequently_in (x := y) <| by>
Tactic: refine Eventually.frequently ?_  filter_upwards [hx hf] with n hn
State 5: ⊢ <goal after refine Eventually.frequently ?_>
Tactic: exact hn (hy n).1  specialize h (x ∘ φ) (hx.comp hφ.tendsto_atTop) (y ∘ φ) (fun n ↦ (hy _).1) _ hyφ
State 6: ⊢ <goal after exact hn (hy n).1>
Tactic: exact ⟨y₀, h, ht.closure_eq ▸ mem_closure_of_tendsto hyφ <| .of_forall fun n ↦ (hy _).2⟩  /-- **Sequential characterization of upper hemicontinuity**:  If `β` is a regular space and `f : α → Set β` is upper hemicontinuous at `x₀` and `f x₀` is  closed, then for any sequences `x` and `y` (in `α` and `β`, respectively) tending to `x₀` and `y₀`,  respectively, if `y n ∈ f (x n)` frequently, then `y₀ ∈ f x₀`.  This is a partial converse of `UpperHemicontinuousAt.of_sequences`. -/
```

Question: what is the next tactic after the last recorded state, and why?

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Topology.Semicontinuity.Hemicontinuity).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]The following proof-state transcript was extracted from a real mathlib proof. Use it to answer the question below.

```text
Proof-state transcript for `Mathlib.Topology.Semicontinuity.Hemicontinuity.UpperHemicontinuousAt`:
State 0: ⊢ lemma UpperHemicontinuousAt.of_sequences {α β : Type*} [TopologicalSpace α]
    [TopologicalSpace β] {f : α → Set β} {x₀ : α} [(𝓝 x₀).IsCountablyGenerated]
    {K : Set β} (hK : IsSeqCompact K) (hf : ∀ᶠ x in 𝓝 x₀, f x ⊆ K)
    (h : ∀ x : ℕ → α, Tendsto x atTop (𝓝 x₀) →
      ∀ y : ℕ → β, (∀ n, y n ∈ f (x n)) → ∀ y₀, Tendsto y atTop (𝓝 y₀) → y₀ ∈ f x₀) :
    UpperHemicontinuousAt f x₀
Tactic: refine .of_frequently fun t ht hft ↦ ?_
State 1: ⊢ <goal after refine .of_frequently fun t ht hft ↦ ?_>
Tactic: obtain ⟨x, hx, hfx⟩ := exists_seq_forall_of_frequently hft
State 2: ⊢ <goal after obtain ⟨x, hx, hfx⟩ := exists_seq_forall_of_frequently hft>
Tactic: choose y hy using hfx
State 3: ⊢ <goal after choose y hy using hfx>
Tactic: obtain ⟨y₀, hy₀, φ, hφ, hyφ⟩ := hK.subseq_of_frequently_in (x := y) <| by
State 4: ⊢ <goal after obtain ⟨y₀, hy₀, φ, hφ, hyφ⟩ := hK.subseq_of_frequently_in (x := y) <| by>
Tactic: refine Eventually.frequently ?_  filter_upwards [hx hf] with n hn
State 5: ⊢ <goal after refine Eventually.frequently ?_>
Tactic: exact hn (hy n).1  specialize h (x ∘ φ) (hx.comp hφ.tendsto_atTop) (y ∘ φ) (fun n ↦ (hy _).1) _ hyφ
State 6: ⊢ <goal after exact hn (hy n).1>
Tactic: exact ⟨y₀, h, ht.closure_eq ▸ mem_closure_of_tendsto hyφ <| .of_forall fun n ↦ (hy _).2⟩  /-- **Sequential characterization of upper hemicontinuity**:  If `β` is a regular space and `f : α → Set β` is upper hemicontinuous at `x₀` and `f x₀` is  closed, then for any sequences `x` and `y` (in `α` and `β`, respectively) tending to `x₀` and `y₀`,  respectively, if `y n ∈ f (x n)` frequently, then `y₀ ∈ f x₀`.  This is a partial converse of `UpperHemicontinuousAt.of_sequences`. -/
```

Question: what is the next tactic after the last recorded state, and why?[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Analysis.Normed.Ring.Lemmas).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
instance Int.instNormedCommRing : NormedCommRing ℤ where
  __
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Filter (L32-L36)
theorem Filter.Tendsto.zero_mul_isBoundedUnder_le {f g : ι → α} {l : Filter ι}
    (hf : Tendsto f l (𝓝 0)) (hg : IsBoundedUnder (· ≤ ·) l ((‖·‖) ∘ g)) :
    Tendsto (fun x => f x * g x) l (𝓝 0) :=
hf.op_zero_isBoundedUnder_le hg (· * ·) norm_mul_le
```

-- snippet 2
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Filter (L37-L45)
theorem Filter.isBoundedUnder_le_mul_tendsto_zero {f g : ι → α} {l : Filter ι}
    (hf : IsBoundedUnder (· ≤ ·) l (norm ∘ f)) (hg : Tendsto g l (𝓝 0)) :
    Tendsto (fun x => f x * g x) l (𝓝 0) :=
hg.op_zero_isBoundedUnder_le hf (flip (· * ·)) fun x y =>
    (norm_mul_le y x).trans_eq (mul_comm _ _)

open Finset in
/-- Non-unital seminormed ring structure on the product of finitely many non-unital seminormed
rings, using the sup norm. -/
```

-- snippet 3
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L46-L62)
instance Pi.nonUnitalSeminormedRing {R : ι → Type*} [Fintype ι]
    [∀ i, NonUnitalSeminormedRing (R i)] : NonUnitalSeminormedRing (∀ i, R i) :=
{ seminormedAddCommGroup, nonUnitalRing with
    norm_mul_le x y := NNReal.coe_mono <| calc
      (univ.sup fun i ↦ ‖x i * y i‖₊) ≤ univ.sup ((‖x ·‖₊) * (‖y ·‖₊)) :=
        sup_mono_fun fun _ _ ↦ nnnorm_mul_le _ _
      _ ≤ (univ.sup (‖x ·‖₊)) * univ.sup (‖y ·‖₊) :=
        sup_mul_le_mul_sup_of_nonneg (fun _ _ ↦ zero_le _) fun _ _ ↦ zero_le _ }

end NonUnitalSeminormedRing

section SeminormedRing

variable [SeminormedRing α]

/-- Seminormed ring structure on the product of finitely many seminormed rings,
  using the sup norm. -/
```

-- snippet 4
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L63-L66)
instance Pi.seminormedRing {R : ι → Type*} [Fintype ι] [∀ i, SeminormedRing (R i)] :
    SeminormedRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedRing, Pi.ring with }
```

-- snippet 5
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.RingHom (L67-L71)
lemma RingHom.isometry {𝕜₁ 𝕜₂ : Type*} [SeminormedRing 𝕜₁] [SeminormedRing 𝕜₂]
    (σ : 𝕜₁ →+* 𝕜₂) [RingHomIsometric σ] :
    Isometry σ := AddMonoidHomClass.isometry_of_norm _ fun _ => RingHomIsometric.norm_map
/-- If `σ` and `σ'` are mutually inverse, then one is `RingHomIsometric` if the other is. Not an
```

-- snippet 6
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.RingHomIsometric (L73-L77)
lemma RingHomIsometric.inv {𝕜₁ 𝕜₂ : Type*} [SeminormedRing 𝕜₁] [SeminormedRing 𝕜₂]
    (σ : 𝕜₁ →+* 𝕜₂) {σ' : 𝕜₂ →+* 𝕜₁} [RingHomInvPair σ σ'] [RingHomIsometric σ] :
    RingHomIsometric σ' :=
⟨fun {x} ↦ by rw [← RingHomIsometric.norm_map (σ := σ), RingHomInvPair.comp_apply_eq₂]⟩
```

-- snippet 7
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.tendsto_pow_cobounded_cobounded (L78-L91)
lemma tendsto_pow_cobounded_cobounded
    [NormOneClass α] [NormMulClass α] {m : ℕ} (hm : m ≠ 0) :
    Tendsto (· ^ m) (cobounded α) (cobounded α) := by
simpa [← tendsto_norm_atTop_iff_cobounded] using
    (tendsto_pow_atTop hm).comp (tendsto_norm_cobounded_atTop (E := α))

end SeminormedRing

section NonUnitalNormedRing

variable [NonUnitalNormedRing α]

/-- Normed ring structure on the product of finitely many non-unital normed rings, using the sup
norm. -/
```

-- snippet 8
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L92-L102)
instance Pi.nonUnitalNormedRing {R : ι → Type*} [Fintype ι] [∀ i, NonUnitalNormedRing (R i)] :
    NonUnitalNormedRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedRing, Pi.normedAddCommGroup with }

end NonUnitalNormedRing

section NormedRing

variable [NormedRing α]

/-- Normed ring structure on the product of finitely many normed rings, using the sup norm. -/
```

-- snippet 9
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L103-L114)
instance Pi.normedRing {R : ι → Type*} [Fintype ι] [∀ i, NormedRing (R i)] :
    NormedRing (∀ i, R i) :=
{ Pi.seminormedRing, Pi.normedAddCommGroup with }

end NormedRing

section NonUnitalSeminormedCommRing

variable [NonUnitalSeminormedCommRing α]

/-- Non-unital seminormed commutative ring structure on the product of finitely many non-unital
seminormed commutative rings, using the sup norm. -/
```

-- snippet 10
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L115-L126)
instance Pi.nonUnitalSeminormedCommRing {R : ι → Type*} [Fintype ι]
    [∀ i, NonUnitalSeminormedCommRing (R i)] : NonUnitalSeminormedCommRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedRing, Pi.nonUnitalCommRing with }

end NonUnitalSeminormedCommRing

section NonUnitalNormedCommRing

variable [NonUnitalNormedCommRing α]

/-- Normed commutative ring structure on the product of finitely many non-unital normed
commutative rings, using the sup norm. -/
```

-- snippet 11
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L127-L138)
instance Pi.nonUnitalNormedCommRing {R : ι → Type*} [Fintype ι]
    [∀ i, NonUnitalNormedCommRing (R i)] : NonUnitalNormedCommRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedCommRing, Pi.normedAddCommGroup with }

end NonUnitalNormedCommRing

section SeminormedCommRing

variable [SeminormedCommRing α]

/-- Seminormed commutative ring structure on the product of finitely many seminormed commutative
rings, using the sup norm. -/
```

-- snippet 12
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L139-L150)
instance Pi.seminormedCommRing {R : ι → Type*} [Fintype ι] [∀ i, SeminormedCommRing (R i)] :
    SeminormedCommRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedCommRing, Pi.ring with }

end SeminormedCommRing

section NormedCommRing

variable [NormedCommRing α]

/-- Normed commutative ring structure on the product of finitely many normed commutative rings,
using the sup norm. -/
```

-- snippet 13
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L151-L157)
instance Pi.normedCommutativeRing {R : ι → Type*} [Fintype ι] [∀ i, NormedCommRing (R i)] :
    NormedCommRing (∀ i, R i) :=
{ Pi.seminormedCommRing, Pi.normedAddCommGroup with }

end NormedCommRing

-- see Note [lower instance priority]
```

-- snippet 14
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.lipschitzWith_sub (L212-L221)
lemma lipschitzWith_sub : LipschitzWith 2 (fun (p : ℝ≥0 × ℝ≥0) ↦ p.1 - p.2) := by
rw [← NNReal.isometry_coe.lipschitzWith_iff]
  have : Isometry (Prod.map ((↑) : ℝ≥0 → ℝ) ((↑) : ℝ≥0 → ℝ)) :=
    NNReal.isometry_coe.prodMap NNReal.isometry_coe
  convert (((LipschitzWith.prod_fst.comp this.lipschitz).sub
    (LipschitzWith.prod_snd.comp this.lipschitz)).max_const 0)
  norm_num

end NNReal
```

-- snippet 15
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.antilipschitzWith_mul_left (L236-L238)
lemma antilipschitzWith_mul_left {a : α} (ha : a ≠ 0) : AntilipschitzWith (‖a‖₊⁻¹) (a * ·) :=
AntilipschitzWith.of_le_mul_dist fun _ _ ↦ by simp [dist_eq_norm, ← mul_sub, ha]
```

-- snippet 16
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_self_homothety (L123-L125)
theorem dist_self_homothety (p₁ p₂ : P) (c : 𝕜) :
    dist p₂ (homothety p₁ c p₂) = ‖1 - c‖ * dist p₁ p₂ := by rw [dist_comm, dist_homothety_self]
```

-- snippet 17
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_lineMap_lineMap (L60-L65)
theorem dist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) :
    dist (lineMap p₁ p₂ c₁) (lineMap p₁ p₂ c₂) = dist c₁ c₂ * dist p₁ p₂ := by
rw [dist_comm p₁ p₂]
  simp only [lineMap_apply, dist_eq_norm_vsub, vadd_vsub_vadd_cancel_right,
    ← sub_smul, norm_smul, vsub_eq_sub]
```

-- snippet 18
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_left_midpoint (L140-L143)
theorem nndist_left_midpoint (p₁ p₂ : P) :
    nndist p₁ (midpoint 𝕜 p₁ p₂) = ‖(2 : 𝕜)‖₊⁻¹ * nndist p₁ p₂ :=
NNReal.eq <| dist_left_midpoint _ _
```

-- snippet 19
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_lineMap_left (L76-L78)
theorem dist_lineMap_left (p₁ p₂ : P) (c : 𝕜) : dist (lineMap p₁ p₂ c) p₁ = ‖c‖ * dist p₁ p₂ := by
simpa only [lineMap_apply_zero, dist_zero_right] using dist_lineMap_lineMap p₁ p₂ c 0
```

-- snippet 20
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_homothety_self (L118-L121)
theorem nndist_homothety_self (p₁ p₂ : P) (c : 𝕜) :
    nndist (homothety p₁ c p₂) p₂ = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_homothety_self _ _ _
```

-- snippet 21
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_homothety_center (L51-L53)
theorem dist_homothety_center (p₁ p₂ : P) (c : 𝕜) :
    dist (homothety p₁ c p₂) p₁ = ‖c‖ * dist p₁ p₂ := by rw [dist_comm, dist_center_homothety]
```

-- snippet 22
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_homothety_self (L113-L116)
theorem dist_homothety_self (p₁ p₂ : P) (c : 𝕜) :
    dist (homothety p₁ c p₂) p₂ = ‖1 - c‖ * dist p₁ p₂ := by
rw [homothety_eq_lineMap, dist_lineMap_right]
```

-- snippet 23
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_left_midpoint (L136-L138)
theorem dist_left_midpoint (p₁ p₂ : P) : dist p₁ (midpoint 𝕜 p₁ p₂) = ‖(2 : 𝕜)‖⁻¹ * dist p₁ p₂ := by
rw [midpoint, dist_comm, dist_lineMap_left, invOf_eq_inv, ← norm_inv]
```

-- snippet 24
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_left_lineMap (L85-L87)
theorem dist_left_lineMap (p₁ p₂ : P) (c : 𝕜) : dist p₁ (lineMap p₁ p₂ c) = ‖c‖ * dist p₁ p₂ :=
(dist_comm _ _).trans (dist_lineMap_left _ _ _)
```

-- snippet 25
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_midpoint_left (L145-L147)
theorem dist_midpoint_left (p₁ p₂ : P) : dist (midpoint 𝕜 p₁ p₂) p₁ = ‖(2 : 𝕜)‖⁻¹ * dist p₁ p₂ := by
rw [dist_comm, dist_left_midpoint]
```

-- snippet 26
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_right_lineMap (L108-L111)
theorem nndist_right_lineMap (p₁ p₂ : P) (c : 𝕜) :
    nndist p₂ (lineMap p₁ p₂ c) = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_right_lineMap _ _ _
```

-- snippet 27
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_center_homothety (L41-L44)
theorem dist_center_homothety (p₁ p₂ : P) (c : 𝕜) :
    dist p₁ (homothety p₁ c p₂) = ‖c‖ * dist p₁ p₂ := by
simp [homothety_def, norm_smul, ← dist_eq_norm_vsub, dist_comm]
```

-- snippet 28
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_midpoint_right (L154-L157)
theorem dist_midpoint_right (p₁ p₂ : P) :
    dist (midpoint 𝕜 p₁ p₂) p₂ = ‖(2 : 𝕜)‖⁻¹ * dist p₁ p₂ := by
rw [midpoint_comm, dist_midpoint_left, dist_comm]
```

-- snippet 29
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_midpoint_right (L159-L162)
theorem nndist_midpoint_right (p₁ p₂ : P) :
    nndist (midpoint 𝕜 p₁ p₂) p₂ = ‖(2 : 𝕜)‖₊⁻¹ * nndist p₁ p₂ :=
NNReal.eq <| dist_midpoint_right _ _
```

-- snippet 30
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_right_lineMap (L104-L106)
theorem dist_right_lineMap (p₁ p₂ : P) (c : 𝕜) : dist p₂ (lineMap p₁ p₂ c) = ‖1 - c‖ * dist p₁ p₂ :=
(dist_comm _ _).trans (dist_lineMap_right _ _ _)
```

-- snippet 31
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_self_homothety (L127-L134)
theorem nndist_self_homothety (p₁ p₂ : P) (c : 𝕜) :
    nndist p₂ (homothety p₁ c p₂) = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_self_homothety _ _ _

section invertibleTwo

variable [Invertible (2 : 𝕜)]
```

-- snippet 32
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_homothety_center (L55-L58)
theorem nndist_homothety_center (p₁ p₂ : P) (c : 𝕜) :
    nndist (homothety p₁ c p₂) p₁ = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_homothety_center _ _ _
```

-- snippet 33
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.lipschitzWith_lineMap (L71-L74)
theorem lipschitzWith_lineMap (p₁ p₂ : P) : LipschitzWith (nndist p₁ p₂) (lineMap p₁ p₂ : 𝕜 → P) :=
LipschitzWith.of_dist_le_mul fun c₁ c₂ =>
    ((dist_lineMap_lineMap p₁ p₂ c₁ c₂).trans (mul_comm _ _)).le
```

-- snippet 34
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_left_lineMap (L89-L92)
theorem nndist_left_lineMap (p₁ p₂ : P) (c : 𝕜) :
    nndist p₁ (lineMap p₁ p₂ c) = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_left_lineMap _ _ _
```

-- snippet 35
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_lineMap_right (L99-L102)
theorem nndist_lineMap_right (p₁ p₂ : P) (c : 𝕜) :
    nndist (lineMap p₁ p₂ c) p₂ = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_lineMap_right _ _ _
```

-- snippet 36
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_midpoint_left (L149-L152)
theorem nndist_midpoint_left (p₁ p₂ : P) :
    nndist (midpoint 𝕜 p₁ p₂) p₁ = ‖(2 : 𝕜)‖₊⁻¹ * nndist p₁ p₂ :=
NNReal.eq <| dist_midpoint_left _ _
```

-- snippet 37
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_center_homothety (L46-L49)
theorem nndist_center_homothety (p₁ p₂ : P) (c : 𝕜) :
    nndist p₁ (homothety p₁ c p₂) = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_center_homothety _ _ _
```

-- snippet 38
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_lineMap_left (L80-L83)
theorem nndist_lineMap_left (p₁ p₂ : P) (c : 𝕜) :
    nndist (lineMap p₁ p₂ c) p₁ = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_lineMap_left _ _ _
```

-- snippet 39
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_lineMap_lineMap (L67-L70)
theorem nndist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) :
    nndist (lineMap p₁ p₂ c₁) (lineMap p₁ p₂ c₂) = nndist c₁ c₂ * nndist p₁ p₂ :=
NNReal.eq <| dist_lineMap_lineMap _ _ _ _
```

-- snippet 40
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_lineMap_right (L94-L97)
theorem dist_lineMap_right (p₁ p₂ : P) (c : 𝕜) :
    dist (lineMap p₁ p₂ c) p₂ = ‖1 - c‖ * dist p₁ p₂ := by
simpa only [lineMap_apply_one, dist_eq_norm'] using dist_lineMap_lineMap p₁ p₂ c 1
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Analysis.Normed.Ring.Lemmas).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
instance Int.instNormedCommRing : NormedCommRing ℤ where
  __
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Filter (L32-L36)
theorem Filter.Tendsto.zero_mul_isBoundedUnder_le {f g : ι → α} {l : Filter ι}
    (hf : Tendsto f l (𝓝 0)) (hg : IsBoundedUnder (· ≤ ·) l ((‖·‖) ∘ g)) :
    Tendsto (fun x => f x * g x) l (𝓝 0) :=
hf.op_zero_isBoundedUnder_le hg (· * ·) norm_mul_le
```

-- snippet 2
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Filter (L37-L45)
theorem Filter.isBoundedUnder_le_mul_tendsto_zero {f g : ι → α} {l : Filter ι}
    (hf : IsBoundedUnder (· ≤ ·) l (norm ∘ f)) (hg : Tendsto g l (𝓝 0)) :
    Tendsto (fun x => f x * g x) l (𝓝 0) :=
hg.op_zero_isBoundedUnder_le hf (flip (· * ·)) fun x y =>
    (norm_mul_le y x).trans_eq (mul_comm _ _)

open Finset in
/-- Non-unital seminormed ring structure on the product of finitely many non-unital seminormed
rings, using the sup norm. -/
```

-- snippet 3
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L46-L62)
instance Pi.nonUnitalSeminormedRing {R : ι → Type*} [Fintype ι]
    [∀ i, NonUnitalSeminormedRing (R i)] : NonUnitalSeminormedRing (∀ i, R i) :=
{ seminormedAddCommGroup, nonUnitalRing with
    norm_mul_le x y := NNReal.coe_mono <| calc
      (univ.sup fun i ↦ ‖x i * y i‖₊) ≤ univ.sup ((‖x ·‖₊) * (‖y ·‖₊)) :=
        sup_mono_fun fun _ _ ↦ nnnorm_mul_le _ _
      _ ≤ (univ.sup (‖x ·‖₊)) * univ.sup (‖y ·‖₊) :=
        sup_mul_le_mul_sup_of_nonneg (fun _ _ ↦ zero_le _) fun _ _ ↦ zero_le _ }

end NonUnitalSeminormedRing

section SeminormedRing

variable [SeminormedRing α]

/-- Seminormed ring structure on the product of finitely many seminormed rings,
  using the sup norm. -/
```

-- snippet 4
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L63-L66)
instance Pi.seminormedRing {R : ι → Type*} [Fintype ι] [∀ i, SeminormedRing (R i)] :
    SeminormedRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedRing, Pi.ring with }
```

-- snippet 5
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.RingHom (L67-L71)
lemma RingHom.isometry {𝕜₁ 𝕜₂ : Type*} [SeminormedRing 𝕜₁] [SeminormedRing 𝕜₂]
    (σ : 𝕜₁ →+* 𝕜₂) [RingHomIsometric σ] :
    Isometry σ := AddMonoidHomClass.isometry_of_norm _ fun _ => RingHomIsometric.norm_map
/-- If `σ` and `σ'` are mutually inverse, then one is `RingHomIsometric` if the other is. Not an
```

-- snippet 6
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.RingHomIsometric (L73-L77)
lemma RingHomIsometric.inv {𝕜₁ 𝕜₂ : Type*} [SeminormedRing 𝕜₁] [SeminormedRing 𝕜₂]
    (σ : 𝕜₁ →+* 𝕜₂) {σ' : 𝕜₂ →+* 𝕜₁} [RingHomInvPair σ σ'] [RingHomIsometric σ] :
    RingHomIsometric σ' :=
⟨fun {x} ↦ by rw [← RingHomIsometric.norm_map (σ := σ), RingHomInvPair.comp_apply_eq₂]⟩
```

-- snippet 7
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.tendsto_pow_cobounded_cobounded (L78-L91)
lemma tendsto_pow_cobounded_cobounded
    [NormOneClass α] [NormMulClass α] {m : ℕ} (hm : m ≠ 0) :
    Tendsto (· ^ m) (cobounded α) (cobounded α) := by
simpa [← tendsto_norm_atTop_iff_cobounded] using
    (tendsto_pow_atTop hm).comp (tendsto_norm_cobounded_atTop (E := α))

end SeminormedRing

section NonUnitalNormedRing

variable [NonUnitalNormedRing α]

/-- Normed ring structure on the product of finitely many non-unital normed rings, using the sup
norm. -/
```

-- snippet 8
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L92-L102)
instance Pi.nonUnitalNormedRing {R : ι → Type*} [Fintype ι] [∀ i, NonUnitalNormedRing (R i)] :
    NonUnitalNormedRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedRing, Pi.normedAddCommGroup with }

end NonUnitalNormedRing

section NormedRing

variable [NormedRing α]

/-- Normed ring structure on the product of finitely many normed rings, using the sup norm. -/
```

-- snippet 9
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L103-L114)
instance Pi.normedRing {R : ι → Type*} [Fintype ι] [∀ i, NormedRing (R i)] :
    NormedRing (∀ i, R i) :=
{ Pi.seminormedRing, Pi.normedAddCommGroup with }

end NormedRing

section NonUnitalSeminormedCommRing

variable [NonUnitalSeminormedCommRing α]

/-- Non-unital seminormed commutative ring structure on the product of finitely many non-unital
seminormed commutative rings, using the sup norm. -/
```

-- snippet 10
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L115-L126)
instance Pi.nonUnitalSeminormedCommRing {R : ι → Type*} [Fintype ι]
    [∀ i, NonUnitalSeminormedCommRing (R i)] : NonUnitalSeminormedCommRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedRing, Pi.nonUnitalCommRing with }

end NonUnitalSeminormedCommRing

section NonUnitalNormedCommRing

variable [NonUnitalNormedCommRing α]

/-- Normed commutative ring structure on the product of finitely many non-unital normed
commutative rings, using the sup norm. -/
```

-- snippet 11
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L127-L138)
instance Pi.nonUnitalNormedCommRing {R : ι → Type*} [Fintype ι]
    [∀ i, NonUnitalNormedCommRing (R i)] : NonUnitalNormedCommRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedCommRing, Pi.normedAddCommGroup with }

end NonUnitalNormedCommRing

section SeminormedCommRing

variable [SeminormedCommRing α]

/-- Seminormed commutative ring structure on the product of finitely many seminormed commutative
rings, using the sup norm. -/
```

-- snippet 12
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L139-L150)
instance Pi.seminormedCommRing {R : ι → Type*} [Fintype ι] [∀ i, SeminormedCommRing (R i)] :
    SeminormedCommRing (∀ i, R i) :=
{ Pi.nonUnitalSeminormedCommRing, Pi.ring with }

end SeminormedCommRing

section NormedCommRing

variable [NormedCommRing α]

/-- Normed commutative ring structure on the product of finitely many normed commutative rings,
using the sup norm. -/
```

-- snippet 13
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.Pi (L151-L157)
instance Pi.normedCommutativeRing {R : ι → Type*} [Fintype ι] [∀ i, NormedCommRing (R i)] :
    NormedCommRing (∀ i, R i) :=
{ Pi.seminormedCommRing, Pi.normedAddCommGroup with }

end NormedCommRing

-- see Note [lower instance priority]
```

-- snippet 14
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.lipschitzWith_sub (L212-L221)
lemma lipschitzWith_sub : LipschitzWith 2 (fun (p : ℝ≥0 × ℝ≥0) ↦ p.1 - p.2) := by
rw [← NNReal.isometry_coe.lipschitzWith_iff]
  have : Isometry (Prod.map ((↑) : ℝ≥0 → ℝ) ((↑) : ℝ≥0 → ℝ)) :=
    NNReal.isometry_coe.prodMap NNReal.isometry_coe
  convert (((LipschitzWith.prod_fst.comp this.lipschitz).sub
    (LipschitzWith.prod_snd.comp this.lipschitz)).max_const 0)
  norm_num

end NNReal
```

-- snippet 15
```lean
-- Mathlib.Analysis.Normed.Ring.Lemmas.antilipschitzWith_mul_left (L236-L238)
lemma antilipschitzWith_mul_left {a : α} (ha : a ≠ 0) : AntilipschitzWith (‖a‖₊⁻¹) (a * ·) :=
AntilipschitzWith.of_le_mul_dist fun _ _ ↦ by simp [dist_eq_norm, ← mul_sub, ha]
```

-- snippet 16
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_self_homothety (L123-L125)
theorem dist_self_homothety (p₁ p₂ : P) (c : 𝕜) :
    dist p₂ (homothety p₁ c p₂) = ‖1 - c‖ * dist p₁ p₂ := by rw [dist_comm, dist_homothety_self]
```

-- snippet 17
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_lineMap_lineMap (L60-L65)
theorem dist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) :
    dist (lineMap p₁ p₂ c₁) (lineMap p₁ p₂ c₂) = dist c₁ c₂ * dist p₁ p₂ := by
rw [dist_comm p₁ p₂]
  simp only [lineMap_apply, dist_eq_norm_vsub, vadd_vsub_vadd_cancel_right,
    ← sub_smul, norm_smul, vsub_eq_sub]
```

-- snippet 18
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_left_midpoint (L140-L143)
theorem nndist_left_midpoint (p₁ p₂ : P) :
    nndist p₁ (midpoint 𝕜 p₁ p₂) = ‖(2 : 𝕜)‖₊⁻¹ * nndist p₁ p₂ :=
NNReal.eq <| dist_left_midpoint _ _
```

-- snippet 19
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_lineMap_left (L76-L78)
theorem dist_lineMap_left (p₁ p₂ : P) (c : 𝕜) : dist (lineMap p₁ p₂ c) p₁ = ‖c‖ * dist p₁ p₂ := by
simpa only [lineMap_apply_zero, dist_zero_right] using dist_lineMap_lineMap p₁ p₂ c 0
```

-- snippet 20
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_homothety_self (L118-L121)
theorem nndist_homothety_self (p₁ p₂ : P) (c : 𝕜) :
    nndist (homothety p₁ c p₂) p₂ = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_homothety_self _ _ _
```

-- snippet 21
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_homothety_center (L51-L53)
theorem dist_homothety_center (p₁ p₂ : P) (c : 𝕜) :
    dist (homothety p₁ c p₂) p₁ = ‖c‖ * dist p₁ p₂ := by rw [dist_comm, dist_center_homothety]
```

-- snippet 22
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_homothety_self (L113-L116)
theorem dist_homothety_self (p₁ p₂ : P) (c : 𝕜) :
    dist (homothety p₁ c p₂) p₂ = ‖1 - c‖ * dist p₁ p₂ := by
rw [homothety_eq_lineMap, dist_lineMap_right]
```

-- snippet 23
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_left_midpoint (L136-L138)
theorem dist_left_midpoint (p₁ p₂ : P) : dist p₁ (midpoint 𝕜 p₁ p₂) = ‖(2 : 𝕜)‖⁻¹ * dist p₁ p₂ := by
rw [midpoint, dist_comm, dist_lineMap_left, invOf_eq_inv, ← norm_inv]
```

-- snippet 24
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_left_lineMap (L85-L87)
theorem dist_left_lineMap (p₁ p₂ : P) (c : 𝕜) : dist p₁ (lineMap p₁ p₂ c) = ‖c‖ * dist p₁ p₂ :=
(dist_comm _ _).trans (dist_lineMap_left _ _ _)
```

-- snippet 25
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_midpoint_left (L145-L147)
theorem dist_midpoint_left (p₁ p₂ : P) : dist (midpoint 𝕜 p₁ p₂) p₁ = ‖(2 : 𝕜)‖⁻¹ * dist p₁ p₂ := by
rw [dist_comm, dist_left_midpoint]
```

-- snippet 26
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_right_lineMap (L108-L111)
theorem nndist_right_lineMap (p₁ p₂ : P) (c : 𝕜) :
    nndist p₂ (lineMap p₁ p₂ c) = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_right_lineMap _ _ _
```

-- snippet 27
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_center_homothety (L41-L44)
theorem dist_center_homothety (p₁ p₂ : P) (c : 𝕜) :
    dist p₁ (homothety p₁ c p₂) = ‖c‖ * dist p₁ p₂ := by
simp [homothety_def, norm_smul, ← dist_eq_norm_vsub, dist_comm]
```

-- snippet 28
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_midpoint_right (L154-L157)
theorem dist_midpoint_right (p₁ p₂ : P) :
    dist (midpoint 𝕜 p₁ p₂) p₂ = ‖(2 : 𝕜)‖⁻¹ * dist p₁ p₂ := by
rw [midpoint_comm, dist_midpoint_left, dist_comm]
```

-- snippet 29
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_midpoint_right (L159-L162)
theorem nndist_midpoint_right (p₁ p₂ : P) :
    nndist (midpoint 𝕜 p₁ p₂) p₂ = ‖(2 : 𝕜)‖₊⁻¹ * nndist p₁ p₂ :=
NNReal.eq <| dist_midpoint_right _ _
```

-- snippet 30
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_right_lineMap (L104-L106)
theorem dist_right_lineMap (p₁ p₂ : P) (c : 𝕜) : dist p₂ (lineMap p₁ p₂ c) = ‖1 - c‖ * dist p₁ p₂ :=
(dist_comm _ _).trans (dist_lineMap_right _ _ _)
```

-- snippet 31
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_self_homothety (L127-L134)
theorem nndist_self_homothety (p₁ p₂ : P) (c : 𝕜) :
    nndist p₂ (homothety p₁ c p₂) = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_self_homothety _ _ _

section invertibleTwo

variable [Invertible (2 : 𝕜)]
```

-- snippet 32
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_homothety_center (L55-L58)
theorem nndist_homothety_center (p₁ p₂ : P) (c : 𝕜) :
    nndist (homothety p₁ c p₂) p₁ = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_homothety_center _ _ _
```

-- snippet 33
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.lipschitzWith_lineMap (L71-L74)
theorem lipschitzWith_lineMap (p₁ p₂ : P) : LipschitzWith (nndist p₁ p₂) (lineMap p₁ p₂ : 𝕜 → P) :=
LipschitzWith.of_dist_le_mul fun c₁ c₂ =>
    ((dist_lineMap_lineMap p₁ p₂ c₁ c₂).trans (mul_comm _ _)).le
```

-- snippet 34
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_left_lineMap (L89-L92)
theorem nndist_left_lineMap (p₁ p₂ : P) (c : 𝕜) :
    nndist p₁ (lineMap p₁ p₂ c) = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_left_lineMap _ _ _
```

-- snippet 35
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_lineMap_right (L99-L102)
theorem nndist_lineMap_right (p₁ p₂ : P) (c : 𝕜) :
    nndist (lineMap p₁ p₂ c) p₂ = ‖1 - c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_lineMap_right _ _ _
```

-- snippet 36
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_midpoint_left (L149-L152)
theorem nndist_midpoint_left (p₁ p₂ : P) :
    nndist (midpoint 𝕜 p₁ p₂) p₁ = ‖(2 : 𝕜)‖₊⁻¹ * nndist p₁ p₂ :=
NNReal.eq <| dist_midpoint_left _ _
```

-- snippet 37
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_center_homothety (L46-L49)
theorem nndist_center_homothety (p₁ p₂ : P) (c : 𝕜) :
    nndist p₁ (homothety p₁ c p₂) = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_center_homothety _ _ _
```

-- snippet 38
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_lineMap_left (L80-L83)
theorem nndist_lineMap_left (p₁ p₂ : P) (c : 𝕜) :
    nndist (lineMap p₁ p₂ c) p₁ = ‖c‖₊ * nndist p₁ p₂ :=
NNReal.eq <| dist_lineMap_left _ _ _
```

-- snippet 39
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.nndist_lineMap_lineMap (L67-L70)
theorem nndist_lineMap_lineMap (p₁ p₂ : P) (c₁ c₂ : 𝕜) :
    nndist (lineMap p₁ p₂ c₁) (lineMap p₁ p₂ c₂) = nndist c₁ c₂ * nndist p₁ p₂ :=
NNReal.eq <| dist_lineMap_lineMap _ _ _ _
```

-- snippet 40
```lean
-- Mathlib.Analysis.Normed.Affine.AddTorsor.dist_lineMap_right (L94-L97)
theorem dist_lineMap_right (p₁ p₂ : P) (c : 𝕜) :
    dist (lineMap p₁ p₂ c) p₂ = ‖1 - c‖ * dist p₁ p₂ := by
simpa only [lineMap_apply_one, dist_eq_norm'] using dist_lineMap_lineMap p₁ p₂ c 1
```
[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Dynamics.Transitive).

[User]
Complete the following proof.

```lean
theorem IsOpen.dense_iUnion_preimage_smul [h : IsTopologicallyTransitive M α]
    {U : Set α} (hUo : IsOpen U) (hUne : U.Nonempty) : Dense (⋃ m : M, (m • ·) ⁻¹' U)
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Dynamics.Transitive).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Complete the following proof.

```lean
theorem IsOpen.dense_iUnion_preimage_smul [h : IsTopologicallyTransitive M α]
    {U : Set α} (hUo : IsOpen U) (hUne : U.Nonempty) : Dense (⋃ m : M, (m • ·) ⁻¹' U)
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Order.Antidiag.Pi).

[User]
Complete the following proof.

```lean
lemma piAntidiag_empty (n : μ) : piAntidiag (∅ : Finset ι) n = if n = 0 then {0} else ∅
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Order.Antidiag.Pi).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Complete the following proof.

```lean
lemma piAntidiag_empty (n : μ) : piAntidiag (∅ : Finset ι) n = if n = 0 then {0} else ∅
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.[/INST]


Instruction: Edit `truncFinset_monomial_eq_zero` so it still compiles and the proof is simplified where possible. Return the full updated `truncFinset_monomial_eq_zero` block.

[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RingTheory.MvPowerSeries.Trunc).

[User]
You are editing a file in `Mathlib/RingTheory/MvPowerSeries/Trunc.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.RingTheory.MvPowerSeries.Trunc.truncFinset_monomial_eq_zero`, L104-L109)
```lean
theorem truncFinset_monomial_eq_zero {x : σ →₀ ℕ} (r : R) (h : x ∉ s) :
    truncFinset R s (monomial x r) = 0 := by
classical
  ext; simp [truncFinset, MvPolynomial.coeff_sum, coeff_monomial]
  grind
```

## Edit instruction
Edit `truncFinset_monomial_eq_zero` so it still compiles and the proof is simplified where possible. Return the full updated `truncFinset_monomial_eq_zero` block.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RingTheory.MvPowerSeries.Trunc).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]You are editing a file in `Mathlib/RingTheory/MvPowerSeries/Trunc.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.RingTheory.MvPowerSeries.Trunc.truncFinset_monomial_eq_zero`, L104-L109)
```lean
theorem truncFinset_monomial_eq_zero {x : σ →₀ ℕ} (r : R) (h : x ∉ s) :
    truncFinset R s (monomial x r) = 0 := by
classical
  ext; simp [truncFinset, MvPolynomial.coeff_sum, coeff_monomial]
  grind
```

## Edit instruction
Edit `truncFinset_monomial_eq_zero` so it still compiles and the proof is simplified where possible. Return the full updated `truncFinset_monomial_eq_zero` block.
[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Logic.IsEmpty.Defs).

[User]
Complete the following proof.

```lean
instance Prod.isEmpty_left {α β} [IsEmpty α] : IsEmpty (α × β)
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Logic.IsEmpty.Defs).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Complete the following proof.

```lean
instance Prod.isEmpty_left {α β} [IsEmpty α] : IsEmpty (α × β)
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.[/INST]


Instruction: Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Lie.Weights.Killing).

[User]
Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

```lean
lemma root_apply_coroot {α : Weight K H L} (hα : α.IsNonZero) :
    α (coroot α) = 2
```

Declaration: `Mathlib.Algebra.Lie.Weights.Killing.root_apply_coroot` (module Mathlib.Algebra.Lie.Weights.Killing).

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Lie.Weights.Killing).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

```lean
lemma root_apply_coroot {α : Weight K H L} (hα : α.IsNonZero) :
    α (coroot α) = 2
```

Declaration: `Mathlib.Algebra.Lie.Weights.Killing.root_apply_coroot` (module Mathlib.Algebra.Lie.Weights.Killing).[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Group.Submonoid.Membership).

[User]
The following proof-state transcript was extracted from a real mathlib proof. Use it to answer the question below.

```text
Proof-state transcript for `Mathlib.Algebra.Group.Submonoid.Membership.induction_of_closure_eq_top_right`:
State 0: ⊢ theorem induction_of_closure_eq_top_right {s : Set M} {motive : M → Prop} (hs : closure s = ⊤)
    (x : M) (one : motive 1) (mul_right : ∀ x, ∀ y ∈ s, motive x → motive (x * y)) : motive x
Tactic: have : x ∈ closure s := by simp [hs]
State 1: ⊢ <goal after have : x ∈ closure s := by simp [hs]>
Tactic: induction this using closure_induction_right with  | one => exact one  | mul_right x _ y hy ih => exact mul_right x y hy ih  /-- The submonoid generated by an element. -/
```

Question: what is the next tactic after the last recorded state, and why?

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Group.Submonoid.Membership).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]The following proof-state transcript was extracted from a real mathlib proof. Use it to answer the question below.

```text
Proof-state transcript for `Mathlib.Algebra.Group.Submonoid.Membership.induction_of_closure_eq_top_right`:
State 0: ⊢ theorem induction_of_closure_eq_top_right {s : Set M} {motive : M → Prop} (hs : closure s = ⊤)
    (x : M) (one : motive 1) (mul_right : ∀ x, ∀ y ∈ s, motive x → motive (x * y)) : motive x
Tactic: have : x ∈ closure s := by simp [hs]
State 1: ⊢ <goal after have : x ∈ closure s := by simp [hs]>
Tactic: induction this using closure_induction_right with  | one => exact one  | mul_right x _ y hy ih => exact mul_right x y hy ih  /-- The submonoid generated by an element. -/
```

Question: what is the next tactic after the last recorded state, and why?[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RepresentationTheory.Homological.GroupCohomology.Basic).

[User]
The following Lean code fails to compile. Fix it.

```lean
theorem inhomogeneousCochains.d_def (n : ℕ) :
    (inhomogeneousCochains A).d n (n + 1) = d A n
:= by thisIsWrongLemmaNameXYZ
simp
```

## Compiler diagnostic
```
[CompilationUnit(i_begin=0, i_end=105, messages=[Message(data='unknown tactic', pos=Position(line=3, column=7), pos_end=None, severity=<Severity.ERROR: 3>, kind=None), Message(data="Function expected at\n  inhomogeneousCochains\nbut this term has type\n  ?m.1\n\nNote: Expected a function because this term is being applied to the argument\n  A\n\nHint: The identifier `inhomogeneousCochains` is unknown, and Lean's `autoImplicit` option causes an unknown identifier to be treated as an implicitly bound variable with an unknown type. However, the unknown type cannot be a function, and a function is what Lean expects here. This is often the result of a typo or a missing `import` or `open` statement.", pos=Position(line=2, column=5), pos_end=Position(line=2, column=28), severity=<Severity.ERROR: 3>, kind=None), Message(data='unsolved goals\nx✝ : Sort u_1\ninhomogeneousCochains : x✝\nα✝ M✝ : Type u_2\ns✝ : CommRing α✝\ninst✝ : Monoid M✝\nA : Rep.{u_3, u_2, u_2} α✝ M✝\nn : ℕ\n⊢ sorry = d A n', pos=Position(line=3, column=3), pos_end=Position(line=3, column=29), severity=<Severity.ERROR: 3>, kind='Tactic.unsolvedGoals')], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None), CompilationUnit(i_begin=105, i_end=132, messages=[], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None)]
```

Return a corrected, compiling version of the code.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RepresentationTheory.Homological.GroupCohomology.Basic).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]The following Lean code fails to compile. Fix it.

```lean
theorem inhomogeneousCochains.d_def (n : ℕ) :
    (inhomogeneousCochains A).d n (n + 1) = d A n
:= by thisIsWrongLemmaNameXYZ
simp
```

## Compiler diagnostic
```
[CompilationUnit(i_begin=0, i_end=105, messages=[Message(data='unknown tactic', pos=Position(line=3, column=7), pos_end=None, severity=<Severity.ERROR: 3>, kind=None), Message(data="Function expected at\n  inhomogeneousCochains\nbut this term has type\n  ?m.1\n\nNote: Expected a function because this term is being applied to the argument\n  A\n\nHint: The identifier `inhomogeneousCochains` is unknown, and Lean's `autoImplicit` option causes an unknown identifier to be treated as an implicitly bound variable with an unknown type. However, the unknown type cannot be a function, and a function is what Lean expects here. This is often the result of a typo or a missing `import` or `open` statement.", pos=Position(line=2, column=5), pos_end=Position(line=2, column=28), severity=<Severity.ERROR: 3>, kind=None), Message(data='unsolved goals\nx✝ : Sort u_1\ninhomogeneousCochains : x✝\nα✝ M✝ : Type u_2\ns✝ : CommRing α✝\ninst✝ : Monoid M✝\nA : Rep.{u_3, u_2, u_2} α✝ M✝\nn : ℕ\n⊢ sorry = d A n', pos=Position(line=3, column=3), pos_end=Position(line=3, column=29), severity=<Severity.ERROR: 3>, kind='Tactic.unsolvedGoals')], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None), CompilationUnit(i_begin=105, i_end=132, messages=[], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None)]
```

Return a corrected, compiling version of the code.[/INST]


Instruction: Edit `ContDiffAt` so it still compiles and the proof is simplified where possible. Return the full updated `ContDiffAt` block.

[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Analysis.SpecialFunctions.Sqrt).

[User]
You are editing a file in `Mathlib/Analysis/SpecialFunctions/Sqrt.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.Analysis.SpecialFunctions.Sqrt.ContDiffAt`, L150-L153)
```lean
theorem ContDiffAt.sqrt (hf : ContDiffAt ℝ n f x) (hx : f x ≠ 0) :
    ContDiffAt ℝ n (fun y => √(f y)) x := (contDiffAt_sqrt hx).comp x hf
```

## Edit instruction
Edit `ContDiffAt` so it still compiles and the proof is simplified where possible. Return the full updated `ContDiffAt` block.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Analysis.SpecialFunctions.Sqrt).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]You are editing a file in `Mathlib/Analysis/SpecialFunctions/Sqrt.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.Analysis.SpecialFunctions.Sqrt.ContDiffAt`, L150-L153)
```lean
theorem ContDiffAt.sqrt (hf : ContDiffAt ℝ n f x) (hx : f x ≠ 0) :
    ContDiffAt ℝ n (fun y => √(f y)) x := (contDiffAt_sqrt hx).comp x hf
```

## Edit instruction
Edit `ContDiffAt` so it still compiles and the proof is simplified where possible. Return the full updated `ContDiffAt` block.
[/INST]


Instruction: Edit `toArithmeticFunction` so it still compiles and the proof is simplified where possible. Return the full updated `toArithmeticFunction` block.

[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.NumberTheory.LSeries.Convolution).

[User]
You are editing a file in `Mathlib/NumberTheory/LSeries/Convolution.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.NumberTheory.LSeries.Convolution.toArithmeticFunction`, L40-L43)
```lean
def toArithmeticFunction {R : Type*} [Zero R] (f : ℕ → R) : ArithmeticFunction R where
  toFun n := if n = 0 then 0 else f n
map_zero' := rfl
```

## Edit instruction
Edit `toArithmeticFunction` so it still compiles and the proof is simplified where possible. Return the full updated `toArithmeticFunction` block.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.NumberTheory.LSeries.Convolution).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]You are editing a file in `Mathlib/NumberTheory/LSeries/Convolution.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.NumberTheory.LSeries.Convolution.toArithmeticFunction`, L40-L43)
```lean
def toArithmeticFunction {R : Type*} [Zero R] (f : ℕ → R) : ArithmeticFunction R where
  toFun n := if n = 0 then 0 else f n
map_zero' := rfl
```

## Edit instruction
Edit `toArithmeticFunction` so it still compiles and the proof is simplified where possible. Return the full updated `toArithmeticFunction` block.
[/INST]


Instruction: Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.CategoryTheory.Limits.ConeCategory).

[User]
Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

```lean
lemma Cone.toStructuredArrow_comp_proj {F : J ⥤ C} (c : Cone F) :
    c.toStructuredArrow ⋙ StructuredArrow.proj _ _ = 𝟭 J
```

Declaration: `Mathlib.CategoryTheory.Limits.ConeCategory.Cone` (module Mathlib.CategoryTheory.Limits.ConeCategory).

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.CategoryTheory.Limits.ConeCategory).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Explain the Lean statement below in plain mathematical language, then formalize a short related example in Lean 4.

```lean
lemma Cone.toStructuredArrow_comp_proj {F : J ⥤ C} (c : Cone F) :
    c.toStructuredArrow ⋙ StructuredArrow.proj _ _ = 𝟭 J
```

Declaration: `Mathlib.CategoryTheory.Limits.ConeCategory.Cone` (module Mathlib.CategoryTheory.Limits.ConeCategory).[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.NumberTheory.Padics.PadicIntegers).

[User]
Complete the following proof.

```lean
theorem norm_lt_one_add {z1 z2 : ℤ_[p]} (hz1 : ‖z1‖ < 1) (hz2 : ‖z2‖ < 1) : ‖z1 + z2‖ < 1
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.NumberTheory.Padics.PadicIntegers).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Complete the following proof.

```lean
theorem norm_lt_one_add {z1 z2 : ℤ_[p]} (hz1 : ‖z1‖ < 1) (hz2 : ‖z2‖ < 1) : ‖z1 + z2‖ < 1
```

Provide a complete Lean proof for the statement above. Do not include the statement in your answer.[/INST]