[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.Order).

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

```lean
theorem ne_zero_iff_exists_coeff_ne_zero_and_degree :
    f ≠ 0 ↔ (∃ n : ℕ, ∃ d : σ →₀ ℕ, coeff d f ≠ 0 ∧ degree d = n)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.ne_zero_iff_exists_coeff_ne_zero_and_weight (L134-L138)
theorem ne_zero_iff_exists_coeff_ne_zero_and_weight :
    f ≠ 0 ↔ (∃ n : ℕ, ∃ d : σ →₀ ℕ, coeff d f ≠ 0 ∧ weight w d = n) := by
simpa using ne_zero_iff_exists_coeff_ne_zero f

/-- The weighted order of a mv_power_series -/
```

-- snippet 2
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder (L139-L143)
def weightedOrder (f : MvPowerSeries σ R) : ℕ∞ := by
classical
  exact dite (f = 0) (fun _ => ⊤) fun h =>
    Nat.find ((ne_zero_iff_exists_coeff_ne_zero_and_weight w).mp h)
```

-- snippet 3
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.ne_zero_iff_weightedOrder_finite (L147-L152)
theorem ne_zero_iff_weightedOrder_finite :
    f ≠ 0 ↔ (f.weightedOrder w).toNat = f.weightedOrder w := by
simp only [weightedOrder, ne_eq, coe_toNat_eq_self, dite_eq_left_iff,
    ENat.coe_ne_top, imp_false, not_not]

/-- The `0` power series is the unique power series with infinite order. -/
```

-- snippet 4
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_eq_top_iff (L154-L159)
theorem weightedOrder_eq_top_iff :
    f.weightedOrder w = ⊤ ↔ f = 0 := by
rw [← not_iff_not, ← ne_eq, ← ne_eq, ne_zero_iff_weightedOrder_finite w, coe_toNat_eq_self]

/-- If the order of a formal power series `f` is finite,
then some coefficient of weight equal to the order of `f` is nonzero. -/
```

-- snippet 5
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.exists_coeff_ne_zero_and_weightedOrder (L160-L169)
theorem exists_coeff_ne_zero_and_weightedOrder
    (h : (toNat (f.weightedOrder w) : ℕ∞) = f.weightedOrder w) :
    ∃ d, coeff d f ≠ 0 ∧ weight w d = f.weightedOrder w := by
classical
  simp_rw [weightedOrder, dif_neg ((ne_zero_iff_weightedOrder_finite w).mpr h), Nat.cast_inj]
  generalize_proofs h1
  exact Nat.find_spec h1

/-- If the `d`th coefficient of a formal power series is nonzero,
then the weighted order of the power series is less than or equal to `weight d w`. -/
```

-- snippet 6
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_le (L170-L178)
theorem weightedOrder_le {d : σ →₀ ℕ} (h : coeff d f ≠ 0) :
    f.weightedOrder w ≤ weight w d := by
rw [weightedOrder, dif_neg]
  · simp only [ne_eq, Nat.cast_le, Nat.find_le_iff]
    exact ⟨weight w d, le_rfl, d, h, rfl⟩
  · exact (f.ne_zero_iff_exists_coeff_ne_zero_and_weight w).mpr ⟨weight w d, d, h, rfl⟩

/-- The `n`th coefficient of a formal power series is `0` if `n` is strictly
smaller than the order of the power series. -/
```

-- snippet 7
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.coeff_eq_zero_of_lt_weightedOrder (L179-L184)
theorem coeff_eq_zero_of_lt_weightedOrder {d : σ →₀ ℕ} (h : (weight w d) < f.weightedOrder w) :
    coeff d f = 0 := by
contrapose! h; exact weightedOrder_le w h

/-- The order of a formal power series is at least `n` if
the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/
```

-- snippet 8
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.nat_le_weightedOrder (L185-L195)
theorem nat_le_weightedOrder {n : ℕ} (h : ∀ d, weight w d < n → coeff d f = 0) :
    n ≤ f.weightedOrder w := by
by_contra! H
  have : (f.weightedOrder w).toNat = f.weightedOrder w := by
    rw [coe_toNat_eq_self]; exact ne_top_of_lt H
  obtain ⟨d, hfd, hd⟩ := exists_coeff_ne_zero_and_weightedOrder w this
  rw [← hd, Nat.cast_lt] at H
  exact hfd (h d H)

/-- The order of a formal power series is at least `n` if
the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/
```

-- snippet 9
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.le_weightedOrder (L196-L205)
theorem le_weightedOrder {n : ℕ∞} (h : ∀ d : σ →₀ ℕ, weight w d < n → coeff d f = 0) :
    n ≤ f.weightedOrder w := by
cases n
  · rw [top_le_iff, weightedOrder_eq_top_iff]
    ext d; exact h d (ENat.coe_lt_top _)
  · apply nat_le_weightedOrder;
    simpa only [ENat.some_eq_coe, Nat.cast_lt] using h

/-- The order of a formal power series is exactly `n` if and only if some coefficient of weight `n`
is nonzero, and the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/
```

-- snippet 10
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_eq_nat (L206-L218)
theorem weightedOrder_eq_nat {n : ℕ} :
    f.weightedOrder w = n ↔
      (∃ d, coeff d f ≠ 0 ∧ weight w d = n) ∧ ∀ d, weight w d < n → coeff d f = 0 := by
constructor
  · intro h
    obtain ⟨d, hd⟩ := f.exists_coeff_ne_zero_and_weightedOrder w (by simp only [h, toNat_coe])
    exact ⟨⟨d, by simpa [h, Nat.cast_inj, ne_eq] using hd⟩,
      fun e he ↦ f.coeff_eq_zero_of_lt_weightedOrder w (by simp only [h, Nat.cast_lt, he])⟩
  · rintro ⟨⟨d, hd', hd⟩, h⟩
    exact le_antisymm (hd.symm ▸ f.weightedOrder_le w hd') (nat_le_weightedOrder w h)

/-- The `weightedOrder` of the monomial `a*X^d` is infinite if `a = 0` and `weight w d` otherwise.
-/
```

-- snippet 11
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_monomial (L219-L233)
theorem weightedOrder_monomial {d : σ →₀ ℕ} {a : R} [Decidable (a = 0)] :
    weightedOrder w (monomial d a) = if a = 0 then (⊤ : ℕ∞) else weight w d := by
classical
  split_ifs with h
  · rw [h, weightedOrder_eq_top_iff, map_zero]
  · rw [weightedOrder_eq_nat]
    constructor
    · use d
      simp only [coeff_monomial_same, ne_eq, h, not_false_eq_true, and_self]
    · intro b hb
      rw [coeff_monomial, if_neg]
      rintro rfl
      exact hb.false

/-- The order of the monomial `a*X^n` is `n` if `a ≠ 0`. -/
```

-- snippet 12
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_monomial_of_ne_zero (L234-L238)
theorem weightedOrder_monomial_of_ne_zero {d : σ →₀ ℕ} {a : R} (h : a ≠ 0) :
    weightedOrder w (monomial d a) = weight w d := by
classical
  rw [weightedOrder_monomial, if_neg h]
```

-- snippet 13
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_one (L240-L243)
theorem weightedOrder_one [Nontrivial R] : (1 : MvPowerSeries σ R).weightedOrder w = 0 :=
weightedOrder_monomial_of_ne_zero w one_ne_zero

/-- The order of the sum of two formal power series is at least the minimum of their orders. -/
```

-- snippet 14
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.min_weightedOrder_le_add (L244-L270)
theorem min_weightedOrder_le_add :
    min (f.weightedOrder w) (g.weightedOrder w) ≤ (f + g).weightedOrder w := by
apply le_weightedOrder w
  simp +contextual only
    [coeff_eq_zero_of_lt_weightedOrder w, lt_min_iff, map_add, add_zero,
      imp_true_iff]

private theorem weightedOrder_add_of_weightedOrder_lt.aux
    (H : f.weightedOrder w < g.weightedOrder w) :
    (f + g).weightedOrder w = f.weightedOrder w := by
  obtain ⟨n, hn : (n : ℕ∞) = _⟩ := ENat.ne_top_iff_exists.mp (ne_top_of_lt H)
  rw [← hn, weightedOrder_eq_nat]
  obtain ⟨d, hd', hd⟩ := ((weightedOrder_eq_nat w).mp hn.symm).1
  constructor
  · refine ⟨d, ?_, hd⟩
    rw [← hn, ← hd] at H
    rw [(coeff _).map_add, coeff_eq_zero_of_lt_weightedOrder w H, add_zero]
    exact hd'
  · intro b hb
    suffices weight w b < weightedOrder w f by
      rw [(coeff _).map_add, coeff_eq_zero_of_lt_weightedOrder w this,
        coeff_eq_zero_of_lt_weightedOrder w (lt_trans this H), add_zero]
    rw [← hn, Nat.cast_lt]
    exact hb

/-- The `weightedOrder` of the sum of two formal power series
is the minimum of their orders if their orders differ. -/
```

-- snippet 15
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_add_of_weightedOrder_ne (L271-L281)
theorem weightedOrder_add_of_weightedOrder_ne (h : f.weightedOrder w ≠ g.weightedOrder w) :
    weightedOrder w (f + g) = weightedOrder w f ⊓ weightedOrder w g := by
refine le_antisymm ?_ (min_weightedOrder_le_add w)
  wlog H₁ : f.weightedOrder w < g.weightedOrder w
  · rw [add_comm f g, inf_comm]
    exact this _ h.symm ((le_of_not_gt H₁).lt_of_ne' h)
  simp only [le_inf_iff, weightedOrder_add_of_weightedOrder_lt.aux w H₁]
  exact ⟨le_rfl, le_of_lt H₁⟩

/-- The `weightedOrder` of the product of two formal power series
is at least the sum of their orders. -/
```

-- snippet 16
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_zero (L185-L187)
theorem coeff_zero (n : σ →₀ ℕ) : coeff n (0 : MvPowerSeries σ R) = 0 :=
rfl
```

-- snippet 17
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_one (L201-L203)
theorem coeff_one [DecidableEq σ] : coeff n (1 : MvPowerSeries σ R) = if n = 0 then 1 else 0 :=
coeff_monomial _ _ _
```

-- snippet 18
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial_mul (L230-L240)
theorem coeff_monomial_mul (a : R) :
    coeff m (monomial n a * φ) = if n ≤ m then a * coeff (m - n) φ else 0 := by
classical
  have :
    ∀ p ∈ antidiagonal m,
      coeff (p : (σ →₀ ℕ) × (σ →₀ ℕ)).1 (monomial n a) * coeff p.2 φ ≠ 0 → p.1 = n :=
    fun p _ hp => eq_of_coeff_monomial_ne_zero (left_ne_zero_of_mul hp)
  rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.filter_fst_eq_antidiagonal _ n,
    Finset.sum_ite_index]
  simp only [Finset.sum_singleton, coeff_monomial_same, Finset.sum_empty]
```

-- snippet 19
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.eq_zero_iff_forall_coeff_zero (L188-L191)
theorem eq_zero_iff_forall_coeff_zero {f : MvPowerSeries σ R} :
    f = 0 ↔ (∀ d : σ →₀ ℕ, coeff d f = 0) :=
MvPowerSeries.ext_iff
```

-- snippet 20
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.eq_of_coeff_monomial_ne_zero (L176-L179)
theorem eq_of_coeff_monomial_ne_zero {m n : σ →₀ ℕ} {a : R} (h : coeff m (monomial n a) ≠ 0) :
    m = n :=
by_contra fun h' => h <| coeff_monomial_ne h' a
```

-- snippet 21
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.commute_monomial (L263-L292)
theorem commute_monomial {a : R} {n} :
    Commute φ (monomial n a) ↔ ∀ m, Commute (coeff m φ) a := by
rw [commute_iff_eq, MvPowerSeries.ext_iff]
  refine ⟨fun h m => ?_, fun h m => ?_⟩
  · have := h (m + n)
    rwa [coeff_add_mul_monomial, add_comm, coeff_add_monomial_mul] at this
  · rw [coeff_mul_monomial, coeff_monomial_mul]
    split_ifs <;> [apply h; rfl]

protected theorem one_mul : (1 : MvPowerSeries σ R) * φ = φ :=
  ext fun n => by simpa using coeff_add_monomial_mul 0 n φ 1

protected theorem mul_one : φ * 1 = φ :=
  ext fun n => by simpa using coeff_add_mul_monomial n 0 φ 1

protected theorem mul_add (φ₁ φ₂ φ₃ : MvPowerSeries σ R) : φ₁ * (φ₂ + φ₃) = φ₁ * φ₂ + φ₁ * φ₃ :=
  ext fun n => by
    classical simp only [coeff_mul, mul_add, Finset.sum_add_distrib, map_add]

protected theorem add_mul (φ₁ φ₂ φ₃ : MvPowerSeries σ R) : (φ₁ + φ₂) * φ₃ = φ₁ * φ₃ + φ₂ * φ₃ :=
  ext fun n => by
    classical simp only [coeff_mul, add_mul, Finset.sum_add_distrib, map_add]

protected theorem mul_assoc (φ₁ φ₂ φ₃ : MvPowerSeries σ R) : φ₁ * φ₂ * φ₃ = φ₁ * (φ₂ * φ₃) := by
  ext1 n
  classical
  simp only [coeff_mul, Finset.sum_mul, Finset.mul_sum, Finset.sum_sigma']
  apply Finset.sum_nbij' (fun ⟨⟨_i, j⟩, ⟨k, l⟩⟩ ↦ ⟨(k, l + j), (l, j)⟩)
    (fun ⟨⟨i, _j⟩, ⟨k, l⟩⟩ ↦ ⟨(i + k, l), (i, k)⟩) <;> aesop (add simp [add_assoc, mul_assoc])
```

-- snippet 22
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.ne_zero_iff_exists_coeff_ne_zero (L192-L197)
theorem ne_zero_iff_exists_coeff_ne_zero (f : MvPowerSeries σ R) :
    f ≠ 0 ↔ (∃ d : σ →₀ ℕ, coeff d f ≠ 0) := by
simp only [MvPowerSeries.ext_iff, ne_eq, coeff_zero, not_forall]

variable (m n : σ →₀ ℕ) (φ ψ : MvPowerSeries σ R)
```

-- snippet 23
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial_zero_one (L207-L209)
theorem monomial_zero_one : monomial (R := R) (0 : σ →₀ ℕ) 1 = 1 :=
rfl
```

-- snippet 24
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_zero_one (L204-L206)
theorem coeff_zero_one : coeff (R := R) (0 : σ →₀ ℕ) 1 = 1 :=
coeff_monomial_same 0 1
```

-- snippet 25
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff (L137-L139)
def coeff (n : σ →₀ ℕ) : MvPowerSeries σ R →ₗ[R] R :=
LinearMap.proj n
```

-- snippet 26
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial_def (L153-L159)
theorem monomial_def [DecidableEq σ] (n : σ →₀ ℕ) :
    monomial n = LinearMap.single R (fun _ ↦ R) n := by
rw [monomial]
  -- unify the `Decidable` arguments
  convert rfl

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 27
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial_mul_monomial (L319-L333)
theorem monomial_mul_monomial (m n : σ →₀ ℕ) (a b : R) :
    monomial m a * monomial n b = monomial (m + n) (a * b) := by
classical
  ext k
  simp only [coeff_mul_monomial, coeff_monomial]
  split_ifs with h₁ h₂ h₃ h₃ h₂ <;> try rfl
  · rw [← h₂, tsub_add_cancel_of_le h₁] at h₃
    exact (h₃ rfl).elim
  · rw [h₃, add_tsub_cancel_right] at h₂
    exact (h₂ rfl).elim
  · exact zero_mul b
  · rw [h₂] at h₁
    exact (h₁ <| le_add_left le_rfl).elim

/-- The constant multivariate formal power series. -/
```

-- snippet 28
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_mul_monomial (L241-L251)
theorem coeff_mul_monomial (a : R) :
    coeff m (φ * monomial n a) = if n ≤ m then coeff (m - n) φ * a else 0 := by
classical
  have :
    ∀ p ∈ antidiagonal m,
      coeff (p : (σ →₀ ℕ) × (σ →₀ ℕ)).1 φ * coeff p.2 (monomial n a) ≠ 0 → p.2 = n :=
    fun p _ hp => eq_of_coeff_monomial_ne_zero (right_ne_zero_of_mul hp)
  rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.filter_snd_eq_antidiagonal _ n,
    Finset.sum_ite_index]
  simp only [Finset.sum_singleton, coeff_monomial_same, Finset.sum_empty]
```

-- snippet 29
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.C (L334-L339)
def C : R →+* MvPowerSeries σ R :=
{ monomial (0 : σ →₀ ℕ) with
    map_one' := rfl
    map_mul' := fun a b => Eq.trans (by simp) (monomial_mul_monomial _ _ a b).symm
    map_zero' := (monomial 0).map_zero }
```

-- snippet 30
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial (L160-L164)
theorem coeff_monomial [DecidableEq σ] (m n : σ →₀ ℕ) (a : R) :
    coeff m (monomial n a) = if m = n then a else 0 := by
dsimp only [coeff, MvPowerSeries]
  rw [monomial_def, LinearMap.proj_apply (i := m), LinearMap.single_apply, Pi.single_apply]
```

-- snippet 31
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.ext (L145-L152)
theorem ext {φ ψ : MvPowerSeries σ R} (h : ∀ n : σ →₀ ℕ, coeff n φ = coeff n ψ) : φ = ψ :=
funext h

/-- Two multivariate formal power series are equal
if and only if all their coefficients are equal. -/
add_decl_doc MvPowerSeries.ext_iff

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 32
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial (L132-L136)
def monomial (n : σ →₀ ℕ) : R →ₗ[R] MvPowerSeries σ R :=
letI := Classical.decEq σ
  LinearMap.single R (fun _ ↦ R) n

/-- The `n`th coefficient of a multivariate formal power series. -/
```

-- snippet 33
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.MvPowerSeries (L86-L94)
def MvPowerSeries (σ : Type*) (R : Type*) :=
(σ →₀ ℕ) → R

namespace MvPowerSeries

open Finsupp

variable {σ R : Type*}
```

-- snippet 34
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_comp_monomial (L181-L183)
theorem coeff_comp_monomial (n : σ →₀ ℕ) : (coeff (R := R) n).comp (monomial n) = LinearMap.id :=
LinearMap.ext <| coeff_monomial_same n
```

-- snippet 35
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_add_mul_monomial (L257-L261)
theorem coeff_add_mul_monomial (a : R) :
    coeff (m + n) (φ * monomial n a) = coeff m φ * a := by
rw [coeff_mul_monomial, if_pos, add_tsub_cancel_right]
  exact le_add_left le_rfl
```

-- snippet 36
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial_same (L166-L170)
theorem coeff_monomial_same (n : σ →₀ ℕ) (a : R) : coeff n (monomial n a) = a := by
classical
  rw [monomial_def]
  exact Pi.single_eq_same _ _
```

-- snippet 37
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_apply (L140-L143)
theorem coeff_apply (f : MvPowerSeries σ R) (d : σ →₀ ℕ) : coeff d f = f d :=
rfl

/-- Two multivariate formal power series are equal if all their coefficients are equal. -/
```

-- snippet 38
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial_ne (L171-L175)
theorem coeff_monomial_ne {m n : σ →₀ ℕ} (h : m ≠ n) (a : R) : coeff m (monomial n a) = 0 := by
classical
  rw [monomial_def]
  exact Pi.single_eq_of_ne h _
```

-- snippet 39
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_mul (L219-L229)
theorem coeff_mul [DecidableEq σ] :
    coeff n (φ * ψ) = ∑ p ∈ antidiagonal n, coeff p.1 φ * coeff p.2 ψ := by
refine Finset.sum_congr ?_ fun _ _ => rfl
  rw [Subsingleton.elim (Classical.decEq σ) ‹DecidableEq σ›]

protected theorem zero_mul : (0 : MvPowerSeries σ R) * φ = 0 :=
  ext fun n => by classical simp [coeff_mul]

protected theorem mul_zero : φ * 0 = 0 :=
  ext fun n => by classical simp [coeff_mul]
```

-- snippet 40
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_add_monomial_mul (L252-L256)
theorem coeff_add_monomial_mul (a : R) :
    coeff (m + n) (monomial m a * φ) = a * coeff n φ := by
rw [coeff_monomial_mul, if_pos, add_tsub_cancel_left]
  exact le_add_right le_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.MvPowerSeries.Order).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem ne_zero_iff_exists_coeff_ne_zero_and_degree :
    f ≠ 0 ↔ (∃ n : ℕ, ∃ d : σ →₀ ℕ, coeff d f ≠ 0 ∧ degree d = n)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.ne_zero_iff_exists_coeff_ne_zero_and_weight (L134-L138)
theorem ne_zero_iff_exists_coeff_ne_zero_and_weight :
    f ≠ 0 ↔ (∃ n : ℕ, ∃ d : σ →₀ ℕ, coeff d f ≠ 0 ∧ weight w d = n) := by
simpa using ne_zero_iff_exists_coeff_ne_zero f

/-- The weighted order of a mv_power_series -/
```

-- snippet 2
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder (L139-L143)
def weightedOrder (f : MvPowerSeries σ R) : ℕ∞ := by
classical
  exact dite (f = 0) (fun _ => ⊤) fun h =>
    Nat.find ((ne_zero_iff_exists_coeff_ne_zero_and_weight w).mp h)
```

-- snippet 3
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.ne_zero_iff_weightedOrder_finite (L147-L152)
theorem ne_zero_iff_weightedOrder_finite :
    f ≠ 0 ↔ (f.weightedOrder w).toNat = f.weightedOrder w := by
simp only [weightedOrder, ne_eq, coe_toNat_eq_self, dite_eq_left_iff,
    ENat.coe_ne_top, imp_false, not_not]

/-- The `0` power series is the unique power series with infinite order. -/
```

-- snippet 4
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_eq_top_iff (L154-L159)
theorem weightedOrder_eq_top_iff :
    f.weightedOrder w = ⊤ ↔ f = 0 := by
rw [← not_iff_not, ← ne_eq, ← ne_eq, ne_zero_iff_weightedOrder_finite w, coe_toNat_eq_self]

/-- If the order of a formal power series `f` is finite,
then some coefficient of weight equal to the order of `f` is nonzero. -/
```

-- snippet 5
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.exists_coeff_ne_zero_and_weightedOrder (L160-L169)
theorem exists_coeff_ne_zero_and_weightedOrder
    (h : (toNat (f.weightedOrder w) : ℕ∞) = f.weightedOrder w) :
    ∃ d, coeff d f ≠ 0 ∧ weight w d = f.weightedOrder w := by
classical
  simp_rw [weightedOrder, dif_neg ((ne_zero_iff_weightedOrder_finite w).mpr h), Nat.cast_inj]
  generalize_proofs h1
  exact Nat.find_spec h1

/-- If the `d`th coefficient of a formal power series is nonzero,
then the weighted order of the power series is less than or equal to `weight d w`. -/
```

-- snippet 6
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_le (L170-L178)
theorem weightedOrder_le {d : σ →₀ ℕ} (h : coeff d f ≠ 0) :
    f.weightedOrder w ≤ weight w d := by
rw [weightedOrder, dif_neg]
  · simp only [ne_eq, Nat.cast_le, Nat.find_le_iff]
    exact ⟨weight w d, le_rfl, d, h, rfl⟩
  · exact (f.ne_zero_iff_exists_coeff_ne_zero_and_weight w).mpr ⟨weight w d, d, h, rfl⟩

/-- The `n`th coefficient of a formal power series is `0` if `n` is strictly
smaller than the order of the power series. -/
```

-- snippet 7
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.coeff_eq_zero_of_lt_weightedOrder (L179-L184)
theorem coeff_eq_zero_of_lt_weightedOrder {d : σ →₀ ℕ} (h : (weight w d) < f.weightedOrder w) :
    coeff d f = 0 := by
contrapose! h; exact weightedOrder_le w h

/-- The order of a formal power series is at least `n` if
the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/
```

-- snippet 8
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.nat_le_weightedOrder (L185-L195)
theorem nat_le_weightedOrder {n : ℕ} (h : ∀ d, weight w d < n → coeff d f = 0) :
    n ≤ f.weightedOrder w := by
by_contra! H
  have : (f.weightedOrder w).toNat = f.weightedOrder w := by
    rw [coe_toNat_eq_self]; exact ne_top_of_lt H
  obtain ⟨d, hfd, hd⟩ := exists_coeff_ne_zero_and_weightedOrder w this
  rw [← hd, Nat.cast_lt] at H
  exact hfd (h d H)

/-- The order of a formal power series is at least `n` if
the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/
```

-- snippet 9
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.le_weightedOrder (L196-L205)
theorem le_weightedOrder {n : ℕ∞} (h : ∀ d : σ →₀ ℕ, weight w d < n → coeff d f = 0) :
    n ≤ f.weightedOrder w := by
cases n
  · rw [top_le_iff, weightedOrder_eq_top_iff]
    ext d; exact h d (ENat.coe_lt_top _)
  · apply nat_le_weightedOrder;
    simpa only [ENat.some_eq_coe, Nat.cast_lt] using h

/-- The order of a formal power series is exactly `n` if and only if some coefficient of weight `n`
is nonzero, and the `d`th coefficient is `0` for all `d` such that `weight w d < n`. -/
```

-- snippet 10
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_eq_nat (L206-L218)
theorem weightedOrder_eq_nat {n : ℕ} :
    f.weightedOrder w = n ↔
      (∃ d, coeff d f ≠ 0 ∧ weight w d = n) ∧ ∀ d, weight w d < n → coeff d f = 0 := by
constructor
  · intro h
    obtain ⟨d, hd⟩ := f.exists_coeff_ne_zero_and_weightedOrder w (by simp only [h, toNat_coe])
    exact ⟨⟨d, by simpa [h, Nat.cast_inj, ne_eq] using hd⟩,
      fun e he ↦ f.coeff_eq_zero_of_lt_weightedOrder w (by simp only [h, Nat.cast_lt, he])⟩
  · rintro ⟨⟨d, hd', hd⟩, h⟩
    exact le_antisymm (hd.symm ▸ f.weightedOrder_le w hd') (nat_le_weightedOrder w h)

/-- The `weightedOrder` of the monomial `a*X^d` is infinite if `a = 0` and `weight w d` otherwise.
-/
```

-- snippet 11
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_monomial (L219-L233)
theorem weightedOrder_monomial {d : σ →₀ ℕ} {a : R} [Decidable (a = 0)] :
    weightedOrder w (monomial d a) = if a = 0 then (⊤ : ℕ∞) else weight w d := by
classical
  split_ifs with h
  · rw [h, weightedOrder_eq_top_iff, map_zero]
  · rw [weightedOrder_eq_nat]
    constructor
    · use d
      simp only [coeff_monomial_same, ne_eq, h, not_false_eq_true, and_self]
    · intro b hb
      rw [coeff_monomial, if_neg]
      rintro rfl
      exact hb.false

/-- The order of the monomial `a*X^n` is `n` if `a ≠ 0`. -/
```

-- snippet 12
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_monomial_of_ne_zero (L234-L238)
theorem weightedOrder_monomial_of_ne_zero {d : σ →₀ ℕ} {a : R} (h : a ≠ 0) :
    weightedOrder w (monomial d a) = weight w d := by
classical
  rw [weightedOrder_monomial, if_neg h]
```

-- snippet 13
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_one (L240-L243)
theorem weightedOrder_one [Nontrivial R] : (1 : MvPowerSeries σ R).weightedOrder w = 0 :=
weightedOrder_monomial_of_ne_zero w one_ne_zero

/-- The order of the sum of two formal power series is at least the minimum of their orders. -/
```

-- snippet 14
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.min_weightedOrder_le_add (L244-L270)
theorem min_weightedOrder_le_add :
    min (f.weightedOrder w) (g.weightedOrder w) ≤ (f + g).weightedOrder w := by
apply le_weightedOrder w
  simp +contextual only
    [coeff_eq_zero_of_lt_weightedOrder w, lt_min_iff, map_add, add_zero,
      imp_true_iff]

private theorem weightedOrder_add_of_weightedOrder_lt.aux
    (H : f.weightedOrder w < g.weightedOrder w) :
    (f + g).weightedOrder w = f.weightedOrder w := by
  obtain ⟨n, hn : (n : ℕ∞) = _⟩ := ENat.ne_top_iff_exists.mp (ne_top_of_lt H)
  rw [← hn, weightedOrder_eq_nat]
  obtain ⟨d, hd', hd⟩ := ((weightedOrder_eq_nat w).mp hn.symm).1
  constructor
  · refine ⟨d, ?_, hd⟩
    rw [← hn, ← hd] at H
    rw [(coeff _).map_add, coeff_eq_zero_of_lt_weightedOrder w H, add_zero]
    exact hd'
  · intro b hb
    suffices weight w b < weightedOrder w f by
      rw [(coeff _).map_add, coeff_eq_zero_of_lt_weightedOrder w this,
        coeff_eq_zero_of_lt_weightedOrder w (lt_trans this H), add_zero]
    rw [← hn, Nat.cast_lt]
    exact hb

/-- The `weightedOrder` of the sum of two formal power series
is the minimum of their orders if their orders differ. -/
```

-- snippet 15
```lean
-- Mathlib.RingTheory.MvPowerSeries.Order.weightedOrder_add_of_weightedOrder_ne (L271-L281)
theorem weightedOrder_add_of_weightedOrder_ne (h : f.weightedOrder w ≠ g.weightedOrder w) :
    weightedOrder w (f + g) = weightedOrder w f ⊓ weightedOrder w g := by
refine le_antisymm ?_ (min_weightedOrder_le_add w)
  wlog H₁ : f.weightedOrder w < g.weightedOrder w
  · rw [add_comm f g, inf_comm]
    exact this _ h.symm ((le_of_not_gt H₁).lt_of_ne' h)
  simp only [le_inf_iff, weightedOrder_add_of_weightedOrder_lt.aux w H₁]
  exact ⟨le_rfl, le_of_lt H₁⟩

/-- The `weightedOrder` of the product of two formal power series
is at least the sum of their orders. -/
```

-- snippet 16
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_zero (L185-L187)
theorem coeff_zero (n : σ →₀ ℕ) : coeff n (0 : MvPowerSeries σ R) = 0 :=
rfl
```

-- snippet 17
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_one (L201-L203)
theorem coeff_one [DecidableEq σ] : coeff n (1 : MvPowerSeries σ R) = if n = 0 then 1 else 0 :=
coeff_monomial _ _ _
```

-- snippet 18
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial_mul (L230-L240)
theorem coeff_monomial_mul (a : R) :
    coeff m (monomial n a * φ) = if n ≤ m then a * coeff (m - n) φ else 0 := by
classical
  have :
    ∀ p ∈ antidiagonal m,
      coeff (p : (σ →₀ ℕ) × (σ →₀ ℕ)).1 (monomial n a) * coeff p.2 φ ≠ 0 → p.1 = n :=
    fun p _ hp => eq_of_coeff_monomial_ne_zero (left_ne_zero_of_mul hp)
  rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.filter_fst_eq_antidiagonal _ n,
    Finset.sum_ite_index]
  simp only [Finset.sum_singleton, coeff_monomial_same, Finset.sum_empty]
```

-- snippet 19
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.eq_zero_iff_forall_coeff_zero (L188-L191)
theorem eq_zero_iff_forall_coeff_zero {f : MvPowerSeries σ R} :
    f = 0 ↔ (∀ d : σ →₀ ℕ, coeff d f = 0) :=
MvPowerSeries.ext_iff
```

-- snippet 20
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.eq_of_coeff_monomial_ne_zero (L176-L179)
theorem eq_of_coeff_monomial_ne_zero {m n : σ →₀ ℕ} {a : R} (h : coeff m (monomial n a) ≠ 0) :
    m = n :=
by_contra fun h' => h <| coeff_monomial_ne h' a
```

-- snippet 21
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.commute_monomial (L263-L292)
theorem commute_monomial {a : R} {n} :
    Commute φ (monomial n a) ↔ ∀ m, Commute (coeff m φ) a := by
rw [commute_iff_eq, MvPowerSeries.ext_iff]
  refine ⟨fun h m => ?_, fun h m => ?_⟩
  · have := h (m + n)
    rwa [coeff_add_mul_monomial, add_comm, coeff_add_monomial_mul] at this
  · rw [coeff_mul_monomial, coeff_monomial_mul]
    split_ifs <;> [apply h; rfl]

protected theorem one_mul : (1 : MvPowerSeries σ R) * φ = φ :=
  ext fun n => by simpa using coeff_add_monomial_mul 0 n φ 1

protected theorem mul_one : φ * 1 = φ :=
  ext fun n => by simpa using coeff_add_mul_monomial n 0 φ 1

protected theorem mul_add (φ₁ φ₂ φ₃ : MvPowerSeries σ R) : φ₁ * (φ₂ + φ₃) = φ₁ * φ₂ + φ₁ * φ₃ :=
  ext fun n => by
    classical simp only [coeff_mul, mul_add, Finset.sum_add_distrib, map_add]

protected theorem add_mul (φ₁ φ₂ φ₃ : MvPowerSeries σ R) : (φ₁ + φ₂) * φ₃ = φ₁ * φ₃ + φ₂ * φ₃ :=
  ext fun n => by
    classical simp only [coeff_mul, add_mul, Finset.sum_add_distrib, map_add]

protected theorem mul_assoc (φ₁ φ₂ φ₃ : MvPowerSeries σ R) : φ₁ * φ₂ * φ₃ = φ₁ * (φ₂ * φ₃) := by
  ext1 n
  classical
  simp only [coeff_mul, Finset.sum_mul, Finset.mul_sum, Finset.sum_sigma']
  apply Finset.sum_nbij' (fun ⟨⟨_i, j⟩, ⟨k, l⟩⟩ ↦ ⟨(k, l + j), (l, j)⟩)
    (fun ⟨⟨i, _j⟩, ⟨k, l⟩⟩ ↦ ⟨(i + k, l), (i, k)⟩) <;> aesop (add simp [add_assoc, mul_assoc])
```

-- snippet 22
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.ne_zero_iff_exists_coeff_ne_zero (L192-L197)
theorem ne_zero_iff_exists_coeff_ne_zero (f : MvPowerSeries σ R) :
    f ≠ 0 ↔ (∃ d : σ →₀ ℕ, coeff d f ≠ 0) := by
simp only [MvPowerSeries.ext_iff, ne_eq, coeff_zero, not_forall]

variable (m n : σ →₀ ℕ) (φ ψ : MvPowerSeries σ R)
```

-- snippet 23
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial_zero_one (L207-L209)
theorem monomial_zero_one : monomial (R := R) (0 : σ →₀ ℕ) 1 = 1 :=
rfl
```

-- snippet 24
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_zero_one (L204-L206)
theorem coeff_zero_one : coeff (R := R) (0 : σ →₀ ℕ) 1 = 1 :=
coeff_monomial_same 0 1
```

-- snippet 25
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff (L137-L139)
def coeff (n : σ →₀ ℕ) : MvPowerSeries σ R →ₗ[R] R :=
LinearMap.proj n
```

-- snippet 26
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial_def (L153-L159)
theorem monomial_def [DecidableEq σ] (n : σ →₀ ℕ) :
    monomial n = LinearMap.single R (fun _ ↦ R) n := by
rw [monomial]
  -- unify the `Decidable` arguments
  convert rfl

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 27
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial_mul_monomial (L319-L333)
theorem monomial_mul_monomial (m n : σ →₀ ℕ) (a b : R) :
    monomial m a * monomial n b = monomial (m + n) (a * b) := by
classical
  ext k
  simp only [coeff_mul_monomial, coeff_monomial]
  split_ifs with h₁ h₂ h₃ h₃ h₂ <;> try rfl
  · rw [← h₂, tsub_add_cancel_of_le h₁] at h₃
    exact (h₃ rfl).elim
  · rw [h₃, add_tsub_cancel_right] at h₂
    exact (h₂ rfl).elim
  · exact zero_mul b
  · rw [h₂] at h₁
    exact (h₁ <| le_add_left le_rfl).elim

/-- The constant multivariate formal power series. -/
```

-- snippet 28
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_mul_monomial (L241-L251)
theorem coeff_mul_monomial (a : R) :
    coeff m (φ * monomial n a) = if n ≤ m then coeff (m - n) φ * a else 0 := by
classical
  have :
    ∀ p ∈ antidiagonal m,
      coeff (p : (σ →₀ ℕ) × (σ →₀ ℕ)).1 φ * coeff p.2 (monomial n a) ≠ 0 → p.2 = n :=
    fun p _ hp => eq_of_coeff_monomial_ne_zero (right_ne_zero_of_mul hp)
  rw [coeff_mul, ← Finset.sum_filter_of_ne this, Finset.filter_snd_eq_antidiagonal _ n,
    Finset.sum_ite_index]
  simp only [Finset.sum_singleton, coeff_monomial_same, Finset.sum_empty]
```

-- snippet 29
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.C (L334-L339)
def C : R →+* MvPowerSeries σ R :=
{ monomial (0 : σ →₀ ℕ) with
    map_one' := rfl
    map_mul' := fun a b => Eq.trans (by simp) (monomial_mul_monomial _ _ a b).symm
    map_zero' := (monomial 0).map_zero }
```

-- snippet 30
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial (L160-L164)
theorem coeff_monomial [DecidableEq σ] (m n : σ →₀ ℕ) (a : R) :
    coeff m (monomial n a) = if m = n then a else 0 := by
dsimp only [coeff, MvPowerSeries]
  rw [monomial_def, LinearMap.proj_apply (i := m), LinearMap.single_apply, Pi.single_apply]
```

-- snippet 31
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.ext (L145-L152)
theorem ext {φ ψ : MvPowerSeries σ R} (h : ∀ n : σ →₀ ℕ, coeff n φ = coeff n ψ) : φ = ψ :=
funext h

/-- Two multivariate formal power series are equal
if and only if all their coefficients are equal. -/
add_decl_doc MvPowerSeries.ext_iff

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 32
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.monomial (L132-L136)
def monomial (n : σ →₀ ℕ) : R →ₗ[R] MvPowerSeries σ R :=
letI := Classical.decEq σ
  LinearMap.single R (fun _ ↦ R) n

/-- The `n`th coefficient of a multivariate formal power series. -/
```

-- snippet 33
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.MvPowerSeries (L86-L94)
def MvPowerSeries (σ : Type*) (R : Type*) :=
(σ →₀ ℕ) → R

namespace MvPowerSeries

open Finsupp

variable {σ R : Type*}
```

-- snippet 34
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_comp_monomial (L181-L183)
theorem coeff_comp_monomial (n : σ →₀ ℕ) : (coeff (R := R) n).comp (monomial n) = LinearMap.id :=
LinearMap.ext <| coeff_monomial_same n
```

-- snippet 35
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_add_mul_monomial (L257-L261)
theorem coeff_add_mul_monomial (a : R) :
    coeff (m + n) (φ * monomial n a) = coeff m φ * a := by
rw [coeff_mul_monomial, if_pos, add_tsub_cancel_right]
  exact le_add_left le_rfl
```

-- snippet 36
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial_same (L166-L170)
theorem coeff_monomial_same (n : σ →₀ ℕ) (a : R) : coeff n (monomial n a) = a := by
classical
  rw [monomial_def]
  exact Pi.single_eq_same _ _
```

-- snippet 37
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_apply (L140-L143)
theorem coeff_apply (f : MvPowerSeries σ R) (d : σ →₀ ℕ) : coeff d f = f d :=
rfl

/-- Two multivariate formal power series are equal if all their coefficients are equal. -/
```

-- snippet 38
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_monomial_ne (L171-L175)
theorem coeff_monomial_ne {m n : σ →₀ ℕ} (h : m ≠ n) (a : R) : coeff m (monomial n a) = 0 := by
classical
  rw [monomial_def]
  exact Pi.single_eq_of_ne h _
```

-- snippet 39
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_mul (L219-L229)
theorem coeff_mul [DecidableEq σ] :
    coeff n (φ * ψ) = ∑ p ∈ antidiagonal n, coeff p.1 φ * coeff p.2 ψ := by
refine Finset.sum_congr ?_ fun _ _ => rfl
  rw [Subsingleton.elim (Classical.decEq σ) ‹DecidableEq σ›]

protected theorem zero_mul : (0 : MvPowerSeries σ R) * φ = 0 :=
  ext fun n => by classical simp [coeff_mul]

protected theorem mul_zero : φ * 0 = 0 :=
  ext fun n => by classical simp [coeff_mul]
```

-- snippet 40
```lean
-- Mathlib.RingTheory.MvPowerSeries.Basic.coeff_add_monomial_mul (L252-L256)
theorem coeff_add_monomial_mul (a : R) :
    coeff (m + n) (monomial m a * φ) = a * coeff n φ := by
rw [coeff_monomial_mul, if_pos, add_tsub_cancel_left]
  exact le_add_right le_rfl
```
[/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.Data.Rat.Cast.Order).

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

```lean
theorem preimage_cast_Ioo (p q : ℚ) : (↑) ⁻¹' Ioo (p : K) q = Ioo p q
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Data.Rat.Cast.Order.castHom_rat (L24-L30)
theorem castHom_rat : castHom ℚ = RingHom.id ℚ :=
RingHom.ext cast_id

section LinearOrderedField

variable {K : Type*} [Field K] [LinearOrder K] [IsStrictOrderedRing K]
```

-- snippet 2
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_pos_of_pos (L31-L34)
theorem cast_pos_of_pos (hq : 0 < q) : (0 : K) < q := by
rw [Rat.cast_def]
  exact div_pos (Int.cast_pos.2 <| num_pos.2 hq) (Nat.cast_pos.2 q.pos)
```

-- snippet 3
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_strictMono (L36-L38)
theorem cast_strictMono : StrictMono ((↑) : ℚ → K) := fun p q => by
simpa only [sub_pos, cast_sub] using cast_pos_of_pos (K := K) (q := q - p)
```

-- snippet 4
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_mono (L40-L43)
theorem cast_mono : Monotone ((↑) : ℚ → K) :=
cast_strictMono.monotone

/-- Coercion from `ℚ` as an order embedding. -/
```

-- snippet 5
```lean
-- Mathlib.Data.Rat.Cast.Order.castOrderEmbedding (L45-L47)
def castOrderEmbedding : ℚ ↪o K :=
OrderEmbedding.ofStrictMono (↑) cast_strictMono
```

-- snippet 6
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_le_natCast (L61-L63)
theorem cast_le_natCast {m : ℚ} {n : ℕ} : (m : K) ≤ n ↔ m ≤ (n : ℚ) := by
rw [← cast_le (K := K), cast_natCast]
```

-- snippet 7
```lean
-- Mathlib.Data.Rat.Cast.Order.natCast_le_cast (L65-L67)
theorem natCast_le_cast {m : ℕ} {n : ℚ} : (m : K) ≤ n ↔ (m : ℚ) ≤ n := by
rw [← cast_le (K := K), cast_natCast]
```

-- snippet 8
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_le_intCast (L69-L71)
theorem cast_le_intCast {m : ℚ} {n : ℤ} : (m : K) ≤ n ↔ m ≤ (n : ℚ) := by
rw [← cast_le (K := K), cast_intCast]
```

-- snippet 9
```lean
-- Mathlib.Data.Rat.Cast.Order.intCast_le_cast (L73-L75)
theorem intCast_le_cast {m : ℤ} {n : ℚ} : (m : K) ≤ n ↔ (m : ℚ) ≤ n := by
rw [← cast_le (K := K), cast_intCast]
```

-- snippet 10
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_lt_natCast (L77-L79)
theorem cast_lt_natCast {m : ℚ} {n : ℕ} : (m : K) < n ↔ m < (n : ℚ) := by
rw [← cast_lt (K := K), cast_natCast]
```

-- snippet 11
```lean
-- Mathlib.Data.Rat.Cast.Order.natCast_lt_cast (L81-L83)
theorem natCast_lt_cast {m : ℕ} {n : ℚ} : (m : K) < n ↔ (m : ℚ) < n := by
rw [← cast_lt (K := K), cast_natCast]
```

-- snippet 12
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_lt_intCast (L85-L87)
theorem cast_lt_intCast {m : ℚ} {n : ℤ} : (m : K) < n ↔ m < (n : ℚ) := by
rw [← cast_lt (K := K), cast_intCast]
```

-- snippet 13
```lean
-- Mathlib.Data.Rat.Cast.Order.intCast_lt_cast (L89-L91)
theorem intCast_lt_cast {m : ℤ} {n : ℚ} : (m : K) < n ↔ (m : ℚ) < n := by
rw [← cast_lt (K := K), cast_intCast]
```

-- snippet 14
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_min (L93-L94)
lemma cast_min (p q : ℚ) : (↑(min p q) : K) = min (p : K) (q : K) := (@cast_mono K _).map_min
```

-- snippet 15
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_max (L96-L97)
lemma cast_max (p q : ℚ) : (↑(max p q) : K) = max (p : K) (q : K) := (@cast_mono K _).map_max
```

-- snippet 16
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_commute (L46-L48)
lemma cast_commute (q : ℚ≥0) (a : α) : Commute (↑q) a := by
simpa only [cast_def] using (q.num.cast_commute a).div_left (q.den.cast_commute a)
```

-- snippet 17
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_one (L130-L132)
theorem cast_one : ((1 : ℚ) : α) = 1 :=
(cast_intCast _).trans Int.cast_one
```

-- snippet 18
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_intCast (L113-L115)
theorem cast_intCast (n : ℤ) : ((n : ℚ) : α) = n :=
(cast_def _).trans <| show (n / (1 : ℕ) : α) = n by rw [Nat.cast_one, div_one]
```

-- snippet 19
```lean
-- Mathlib.Data.Rat.BigOperators.cast_list_sum (L25-L27)
theorem cast_list_sum (s : List ℚ) : (↑s.sum : α) = (s.map (↑)).sum :=
map_list_sum (Rat.castHom α) _
```

-- snippet 20
```lean
-- Mathlib.Data.Rat.BigOperators.cast_multiset_prod (L47-L49)
theorem cast_multiset_prod (s : Multiset ℚ) : (↑s.prod : α) = (s.map (↑)).prod :=
map_multiset_prod (Rat.castHom α) _
```

-- snippet 21
```lean
-- Mathlib.Data.Rat.BigOperators.cast_prod (L51-L56)
theorem cast_prod (s : Finset ι) (f : ι → ℚ) : ∏ i ∈ s, f i = ∏ i ∈ s, (f i : α) :=
map_prod (Rat.castHom α) _ _

end Field

end Rat
```

-- snippet 22
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_divInt_of_ne_zero (L143-L161)
lemma cast_divInt_of_ne_zero (a : ℤ) {b : ℤ} (b0 : (b : α) ≠ 0) : (a /. b : α) = a / b := by
have b0' : b ≠ 0 := by
    refine mt ?_ b0
    simp +contextual
  rcases e : a /. b with ⟨n, d, h, c⟩
  have d0 : (d : α) ≠ 0 := by
    intro d0
    have dd := den_dvd a b
    rcases show (d : ℤ) ∣ b by rwa [e] at dd with ⟨k, ke⟩
    have : (b : α) = (d : α) * (k : α) := by rw [ke, Int.cast_mul, Int.cast_natCast]
    rw [d0, zero_mul] at this
    contradiction
  rw [mk_eq_divInt] at e
  have := congr_arg ((↑) : ℤ → α)
    ((divInt_eq_divInt_iff b0' <| ne_of_gt <| Int.natCast_pos.2 h.bot_lt).1 e)
  rw [Int.cast_mul, Int.cast_mul, Int.cast_natCast] at this
  rw [eq_comm, cast_def, div_eq_mul_inv, eq_div_iff_mul_eq d0, mul_assoc, (d.commute_cast _).eq,
    ← mul_assoc, this, mul_assoc, mul_inv_cancel₀ b0, mul_one]
```

-- snippet 23
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_mul_of_ne_zero (L83-L91)
lemma cast_mul_of_ne_zero (hq : (q.den : α) ≠ 0) (hr : (r.den : α) ≠ 0) :
    ↑(q * r) = (q * r : α) := by
rw [mul_def, cast_divNat_of_ne_zero, cast_def, cast_def,
    (Nat.commute_cast _ _).div_mul_div_comm (Nat.commute_cast _ _)]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr
```

-- snippet 24
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_natCast (L117-L120)
theorem cast_natCast (n : ℕ) : ((n : ℚ) : α) = n := by
rw [← Int.cast_natCast, cast_intCast, Int.cast_natCast]
```

-- snippet 25
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_zpow (L66-L67)
lemma cast_zpow (p : ℚ) (n : ℤ) : ↑(p ^ n) = (p ^ n : α) := map_zpow₀ (castHom α) ..
```

-- snippet 26
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_div_of_ne_zero (L97-L111)
lemma cast_div_of_ne_zero (hq : (q.den : α) ≠ 0) (hr : (r.num : α) ≠ 0) :
    ↑(q / r) = (q / r : α) := by
rw [div_def, cast_divNat_of_ne_zero, cast_def, cast_def, div_eq_mul_inv (_ / _),
    inv_div, (Nat.commute_cast _ _).div_mul_div_comm (Nat.commute_cast _ _)]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr

end NNRat

namespace Rat

variable [DivisionRing α] {p q : ℚ}
```

-- snippet 27
```lean
-- Mathlib.Data.Rat.Cast.CharZero.castHom (L53-L59)
def castHom : ℚ →+* α where
  toFun := (↑)
map_one' := cast_one
  map_mul' := cast_mul
  map_zero' := cast_zero
  map_add' := cast_add
```

-- snippet 28
```lean
-- Mathlib.Data.Rat.Cast.Defs.commute_cast (L49-L50)
lemma commute_cast (a : α) (q : ℚ≥0) : Commute a q := (cast_commute ..).symm
```

-- snippet 29
```lean
-- Mathlib.Data.Rat.BigOperators.cast_list_prod (L37-L45)
theorem cast_list_prod (s : List ℚ) : (↑s.prod : α) = (s.map (↑)).prod :=
map_list_prod (Rat.castHom α) _

end WithDivRing

section Field

variable [Field α] [CharZero α]
```

-- snippet 30
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_ne_zero (L40-L41)
lemma cast_ne_zero : (p : α) ≠ 0 ↔ p ≠ 0 := cast_eq_zero.ne
```

-- snippet 31
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_divNat (L115-L121)
lemma cast_divNat (a b : ℕ) : (divNat a b : α) = a / b := by
rw [← cast_natCast, ← cast_natCast b, ← cast_div]
  congr
  ext
  apply Rat.mkRat_eq_div

end NNRat
```

-- snippet 32
```lean
-- Mathlib.Data.Rat.Cardinal.Cardinal (L25-L25)
theorem Cardinal.mkRat : #ℚ = ℵ₀ := mk_eq_aleph0 ℚ
```

-- snippet 33
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_inv_of_ne_zero (L93-L95)
lemma cast_inv_of_ne_zero (hq : (q.num : α) ≠ 0) : (q⁻¹ : ℚ≥0) = (q⁻¹ : α) := by
rw [inv_def, cast_divNat_of_ne_zero _ hq, cast_def, inv_div]
```

-- snippet 34
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_add_of_ne_zero (L73-L81)
lemma cast_add_of_ne_zero (hq : (q.den : α) ≠ 0) (hr : (r.den : α) ≠ 0) :
    ↑(q + r) = (q + r : α) := by
rw [add_def, cast_divNat_of_ne_zero, cast_def, cast_def, mul_comm _ q.den,
    (Nat.commute_cast _ _).div_add_div (Nat.commute_cast _ _) hq hr]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr
```

-- snippet 35
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_zero (L126-L128)
theorem cast_zero : ((0 : ℚ) : α) = 0 :=
(cast_intCast _).trans Int.cast_zero
```

-- snippet 36
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_comm (L51-L52)
lemma cast_comm (q : ℚ≥0) (a : α) : q * a = a * q := cast_commute _ _
```

-- snippet 37
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_divInt (L69-L76)
theorem cast_divInt (a b : ℤ) : (a /. b : α) = a / b := by
simp only [divInt_eq_div, cast_div, cast_intCast]

end Rat

namespace NNRat
variable [DivisionSemiring α] [CharZero α] {p q : ℚ≥0}
```

-- snippet 38
```lean
-- Mathlib.Data.Rat.BigOperators.cast_sum (L33-L35)
theorem cast_sum (s : Finset ι) (f : ι → ℚ) : ∑ i ∈ s, f i = ∑ i ∈ s, (f i : α) :=
map_sum (Rat.castHom α) _ s
```

-- snippet 39
```lean
-- Mathlib.Data.Rat.BigOperators.cast_multiset_sum (L29-L31)
theorem cast_multiset_sum (s : Multiset ℚ) : (↑s.sum : α) = (s.map (↑)).sum :=
map_multiset_sum (Rat.castHom α) _
```

-- snippet 40
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_injective (L25-L36)
lemma cast_injective : Injective ((↑) : ℚ → α)
  | ⟨n₁, d₁, d₁0, c₁⟩, ⟨n₂, d₂, d₂0, c₂⟩, h => by
    have d₁a : (d₁ : α) ≠ 0 := Nat.cast_ne_zero.2 d₁0
have d₂a : (d₂ : α) ≠ 0 := Nat.cast_ne_zero.2 d₂0
    rw [mk_eq_divInt, mk_eq_divInt] at h ⊢
    rw [cast_divInt_of_ne_zero _ (by simpa), cast_divInt_of_ne_zero _ (by simpa)] at h
    norm_cast at h
    rwa [eq_div_iff_mul_eq d₂a, division_def, mul_assoc, (d₁.cast_commute (d₂ : α)).inv_left₀.eq,
      ← mul_assoc, ← division_def, eq_comm, eq_div_iff_mul_eq d₁a, eq_comm, ← Int.cast_natCast d₁,
      ← Int.cast_mul, ← Int.cast_natCast d₂, ← Int.cast_mul, Int.cast_inj, ← mkRat_eq_iff d₁0 d₂0]
      at h
```

<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.Rat.Cast.Order).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem preimage_cast_Ioo (p q : ℚ) : (↑) ⁻¹' Ioo (p : K) q = Ioo p q
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Data.Rat.Cast.Order.castHom_rat (L24-L30)
theorem castHom_rat : castHom ℚ = RingHom.id ℚ :=
RingHom.ext cast_id

section LinearOrderedField

variable {K : Type*} [Field K] [LinearOrder K] [IsStrictOrderedRing K]
```

-- snippet 2
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_pos_of_pos (L31-L34)
theorem cast_pos_of_pos (hq : 0 < q) : (0 : K) < q := by
rw [Rat.cast_def]
  exact div_pos (Int.cast_pos.2 <| num_pos.2 hq) (Nat.cast_pos.2 q.pos)
```

-- snippet 3
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_strictMono (L36-L38)
theorem cast_strictMono : StrictMono ((↑) : ℚ → K) := fun p q => by
simpa only [sub_pos, cast_sub] using cast_pos_of_pos (K := K) (q := q - p)
```

-- snippet 4
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_mono (L40-L43)
theorem cast_mono : Monotone ((↑) : ℚ → K) :=
cast_strictMono.monotone

/-- Coercion from `ℚ` as an order embedding. -/
```

-- snippet 5
```lean
-- Mathlib.Data.Rat.Cast.Order.castOrderEmbedding (L45-L47)
def castOrderEmbedding : ℚ ↪o K :=
OrderEmbedding.ofStrictMono (↑) cast_strictMono
```

-- snippet 6
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_le_natCast (L61-L63)
theorem cast_le_natCast {m : ℚ} {n : ℕ} : (m : K) ≤ n ↔ m ≤ (n : ℚ) := by
rw [← cast_le (K := K), cast_natCast]
```

-- snippet 7
```lean
-- Mathlib.Data.Rat.Cast.Order.natCast_le_cast (L65-L67)
theorem natCast_le_cast {m : ℕ} {n : ℚ} : (m : K) ≤ n ↔ (m : ℚ) ≤ n := by
rw [← cast_le (K := K), cast_natCast]
```

-- snippet 8
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_le_intCast (L69-L71)
theorem cast_le_intCast {m : ℚ} {n : ℤ} : (m : K) ≤ n ↔ m ≤ (n : ℚ) := by
rw [← cast_le (K := K), cast_intCast]
```

-- snippet 9
```lean
-- Mathlib.Data.Rat.Cast.Order.intCast_le_cast (L73-L75)
theorem intCast_le_cast {m : ℤ} {n : ℚ} : (m : K) ≤ n ↔ (m : ℚ) ≤ n := by
rw [← cast_le (K := K), cast_intCast]
```

-- snippet 10
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_lt_natCast (L77-L79)
theorem cast_lt_natCast {m : ℚ} {n : ℕ} : (m : K) < n ↔ m < (n : ℚ) := by
rw [← cast_lt (K := K), cast_natCast]
```

-- snippet 11
```lean
-- Mathlib.Data.Rat.Cast.Order.natCast_lt_cast (L81-L83)
theorem natCast_lt_cast {m : ℕ} {n : ℚ} : (m : K) < n ↔ (m : ℚ) < n := by
rw [← cast_lt (K := K), cast_natCast]
```

-- snippet 12
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_lt_intCast (L85-L87)
theorem cast_lt_intCast {m : ℚ} {n : ℤ} : (m : K) < n ↔ m < (n : ℚ) := by
rw [← cast_lt (K := K), cast_intCast]
```

-- snippet 13
```lean
-- Mathlib.Data.Rat.Cast.Order.intCast_lt_cast (L89-L91)
theorem intCast_lt_cast {m : ℤ} {n : ℚ} : (m : K) < n ↔ (m : ℚ) < n := by
rw [← cast_lt (K := K), cast_intCast]
```

-- snippet 14
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_min (L93-L94)
lemma cast_min (p q : ℚ) : (↑(min p q) : K) = min (p : K) (q : K) := (@cast_mono K _).map_min
```

-- snippet 15
```lean
-- Mathlib.Data.Rat.Cast.Order.cast_max (L96-L97)
lemma cast_max (p q : ℚ) : (↑(max p q) : K) = max (p : K) (q : K) := (@cast_mono K _).map_max
```

-- snippet 16
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_commute (L46-L48)
lemma cast_commute (q : ℚ≥0) (a : α) : Commute (↑q) a := by
simpa only [cast_def] using (q.num.cast_commute a).div_left (q.den.cast_commute a)
```

-- snippet 17
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_one (L130-L132)
theorem cast_one : ((1 : ℚ) : α) = 1 :=
(cast_intCast _).trans Int.cast_one
```

-- snippet 18
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_intCast (L113-L115)
theorem cast_intCast (n : ℤ) : ((n : ℚ) : α) = n :=
(cast_def _).trans <| show (n / (1 : ℕ) : α) = n by rw [Nat.cast_one, div_one]
```

-- snippet 19
```lean
-- Mathlib.Data.Rat.BigOperators.cast_list_sum (L25-L27)
theorem cast_list_sum (s : List ℚ) : (↑s.sum : α) = (s.map (↑)).sum :=
map_list_sum (Rat.castHom α) _
```

-- snippet 20
```lean
-- Mathlib.Data.Rat.BigOperators.cast_multiset_prod (L47-L49)
theorem cast_multiset_prod (s : Multiset ℚ) : (↑s.prod : α) = (s.map (↑)).prod :=
map_multiset_prod (Rat.castHom α) _
```

-- snippet 21
```lean
-- Mathlib.Data.Rat.BigOperators.cast_prod (L51-L56)
theorem cast_prod (s : Finset ι) (f : ι → ℚ) : ∏ i ∈ s, f i = ∏ i ∈ s, (f i : α) :=
map_prod (Rat.castHom α) _ _

end Field

end Rat
```

-- snippet 22
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_divInt_of_ne_zero (L143-L161)
lemma cast_divInt_of_ne_zero (a : ℤ) {b : ℤ} (b0 : (b : α) ≠ 0) : (a /. b : α) = a / b := by
have b0' : b ≠ 0 := by
    refine mt ?_ b0
    simp +contextual
  rcases e : a /. b with ⟨n, d, h, c⟩
  have d0 : (d : α) ≠ 0 := by
    intro d0
    have dd := den_dvd a b
    rcases show (d : ℤ) ∣ b by rwa [e] at dd with ⟨k, ke⟩
    have : (b : α) = (d : α) * (k : α) := by rw [ke, Int.cast_mul, Int.cast_natCast]
    rw [d0, zero_mul] at this
    contradiction
  rw [mk_eq_divInt] at e
  have := congr_arg ((↑) : ℤ → α)
    ((divInt_eq_divInt_iff b0' <| ne_of_gt <| Int.natCast_pos.2 h.bot_lt).1 e)
  rw [Int.cast_mul, Int.cast_mul, Int.cast_natCast] at this
  rw [eq_comm, cast_def, div_eq_mul_inv, eq_div_iff_mul_eq d0, mul_assoc, (d.commute_cast _).eq,
    ← mul_assoc, this, mul_assoc, mul_inv_cancel₀ b0, mul_one]
```

-- snippet 23
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_mul_of_ne_zero (L83-L91)
lemma cast_mul_of_ne_zero (hq : (q.den : α) ≠ 0) (hr : (r.den : α) ≠ 0) :
    ↑(q * r) = (q * r : α) := by
rw [mul_def, cast_divNat_of_ne_zero, cast_def, cast_def,
    (Nat.commute_cast _ _).div_mul_div_comm (Nat.commute_cast _ _)]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr
```

-- snippet 24
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_natCast (L117-L120)
theorem cast_natCast (n : ℕ) : ((n : ℚ) : α) = n := by
rw [← Int.cast_natCast, cast_intCast, Int.cast_natCast]
```

-- snippet 25
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_zpow (L66-L67)
lemma cast_zpow (p : ℚ) (n : ℤ) : ↑(p ^ n) = (p ^ n : α) := map_zpow₀ (castHom α) ..
```

-- snippet 26
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_div_of_ne_zero (L97-L111)
lemma cast_div_of_ne_zero (hq : (q.den : α) ≠ 0) (hr : (r.num : α) ≠ 0) :
    ↑(q / r) = (q / r : α) := by
rw [div_def, cast_divNat_of_ne_zero, cast_def, cast_def, div_eq_mul_inv (_ / _),
    inv_div, (Nat.commute_cast _ _).div_mul_div_comm (Nat.commute_cast _ _)]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr

end NNRat

namespace Rat

variable [DivisionRing α] {p q : ℚ}
```

-- snippet 27
```lean
-- Mathlib.Data.Rat.Cast.CharZero.castHom (L53-L59)
def castHom : ℚ →+* α where
  toFun := (↑)
map_one' := cast_one
  map_mul' := cast_mul
  map_zero' := cast_zero
  map_add' := cast_add
```

-- snippet 28
```lean
-- Mathlib.Data.Rat.Cast.Defs.commute_cast (L49-L50)
lemma commute_cast (a : α) (q : ℚ≥0) : Commute a q := (cast_commute ..).symm
```

-- snippet 29
```lean
-- Mathlib.Data.Rat.BigOperators.cast_list_prod (L37-L45)
theorem cast_list_prod (s : List ℚ) : (↑s.prod : α) = (s.map (↑)).prod :=
map_list_prod (Rat.castHom α) _

end WithDivRing

section Field

variable [Field α] [CharZero α]
```

-- snippet 30
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_ne_zero (L40-L41)
lemma cast_ne_zero : (p : α) ≠ 0 ↔ p ≠ 0 := cast_eq_zero.ne
```

-- snippet 31
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_divNat (L115-L121)
lemma cast_divNat (a b : ℕ) : (divNat a b : α) = a / b := by
rw [← cast_natCast, ← cast_natCast b, ← cast_div]
  congr
  ext
  apply Rat.mkRat_eq_div

end NNRat
```

-- snippet 32
```lean
-- Mathlib.Data.Rat.Cardinal.Cardinal (L25-L25)
theorem Cardinal.mkRat : #ℚ = ℵ₀ := mk_eq_aleph0 ℚ
```

-- snippet 33
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_inv_of_ne_zero (L93-L95)
lemma cast_inv_of_ne_zero (hq : (q.num : α) ≠ 0) : (q⁻¹ : ℚ≥0) = (q⁻¹ : α) := by
rw [inv_def, cast_divNat_of_ne_zero _ hq, cast_def, inv_div]
```

-- snippet 34
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_add_of_ne_zero (L73-L81)
lemma cast_add_of_ne_zero (hq : (q.den : α) ≠ 0) (hr : (r.den : α) ≠ 0) :
    ↑(q + r) = (q + r : α) := by
rw [add_def, cast_divNat_of_ne_zero, cast_def, cast_def, mul_comm _ q.den,
    (Nat.commute_cast _ _).div_add_div (Nat.commute_cast _ _) hq hr]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr
```

-- snippet 35
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_zero (L126-L128)
theorem cast_zero : ((0 : ℚ) : α) = 0 :=
(cast_intCast _).trans Int.cast_zero
```

-- snippet 36
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_comm (L51-L52)
lemma cast_comm (q : ℚ≥0) (a : α) : q * a = a * q := cast_commute _ _
```

-- snippet 37
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_divInt (L69-L76)
theorem cast_divInt (a b : ℤ) : (a /. b : α) = a / b := by
simp only [divInt_eq_div, cast_div, cast_intCast]

end Rat

namespace NNRat
variable [DivisionSemiring α] [CharZero α] {p q : ℚ≥0}
```

-- snippet 38
```lean
-- Mathlib.Data.Rat.BigOperators.cast_sum (L33-L35)
theorem cast_sum (s : Finset ι) (f : ι → ℚ) : ∑ i ∈ s, f i = ∑ i ∈ s, (f i : α) :=
map_sum (Rat.castHom α) _ s
```

-- snippet 39
```lean
-- Mathlib.Data.Rat.BigOperators.cast_multiset_sum (L29-L31)
theorem cast_multiset_sum (s : Multiset ℚ) : (↑s.sum : α) = (s.map (↑)).sum :=
map_multiset_sum (Rat.castHom α) _
```

-- snippet 40
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_injective (L25-L36)
lemma cast_injective : Injective ((↑) : ℚ → α)
  | ⟨n₁, d₁, d₁0, c₁⟩, ⟨n₂, d₂, d₂0, c₂⟩, h => by
    have d₁a : (d₁ : α) ≠ 0 := Nat.cast_ne_zero.2 d₁0
have d₂a : (d₂ : α) ≠ 0 := Nat.cast_ne_zero.2 d₂0
    rw [mk_eq_divInt, mk_eq_divInt] at h ⊢
    rw [cast_divInt_of_ne_zero _ (by simpa), cast_divInt_of_ne_zero _ (by simpa)] at h
    norm_cast at h
    rwa [eq_div_iff_mul_eq d₂a, division_def, mul_assoc, (d₁.cast_commute (d₂ : α)).inv_left₀.eq,
      ← mul_assoc, ← division_def, eq_comm, eq_div_iff_mul_eq d₁a, eq_comm, ← Int.cast_natCast d₁,
      ← Int.cast_mul, ← Int.cast_natCast d₂, ← Int.cast_mul, Int.cast_inj, ← mkRat_eq_iff d₁0 d₂0]
      at h
```
[/INST]

mistral-common:Tekken v15 (Mistral chat template, [INST]/[SYSTEM_PROMPT])


[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.LinearAlgebra.BilinearForm.Properties).

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

```lean
theorem restrict {B : BilinForm R M} (b : B.IsSymm) (W : Submodule R M) :
    (B.restrict W).IsSymm
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.IsRefl (L59-L62)
def IsRefl (B : BilinForm R M) : Prop := LinearMap.IsRefl B
namespace IsRefl
```

-- snippet 2
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.eq_zero (L63-L79)
theorem eq_zero (H : B.IsRefl) : ∀ {x y : M}, B x y = 0 → B y x = 0 := fun {x y} => H x y
protected theorem neg {B : BilinForm R₁ M₁} (hB : B.IsRefl) : (-B).IsRefl := fun x y =>
  neg_eq_zero.mpr ∘ hB x y ∘ neg_eq_zero.mp

protected theorem smul {α : Type*} [Semiring α] [IsDomain α] [Module α R] [SMulCommClass R α R]
    [IsTorsionFree α R] (a : α) {B : BilinForm R M} (hB : B.IsRefl) :
    (a • B).IsRefl := fun _ _ h =>
  (smul_eq_zero.mp h).elim (fun ha => smul_eq_zero_of_left ha _) fun hBz =>
    smul_eq_zero_of_right _ (hB _ _ hBz)

protected theorem groupSMul {α} [Group α] [DistribMulAction α R] [SMulCommClass R α R] (a : α)
    {B : BilinForm R M} (hB : B.IsRefl) : (a • B).IsRefl := fun x y =>
  (smul_eq_zero_iff_eq _).mpr ∘ hB x y ∘ (smul_eq_zero_iff_eq _).mp

end IsRefl
```

-- snippet 3
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isRefl_zero (L81-L82)
theorem isRefl_zero : (0 : BilinForm R M).IsRefl := fun _ _ _ => rfl
```

-- snippet 4
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isRefl_neg (L84-L90)
theorem isRefl_neg {B : BilinForm R₁ M₁} : (-B).IsRefl ↔ B.IsRefl :=
⟨fun h => neg_neg B ▸ h.neg, IsRefl.neg⟩

/-- The proposition that a bilinear form is symmetric -/
structure IsSymm (B : BilinForm R M) : Prop where
  protected eq : ∀ x y, B x y = B y x
```

-- snippet 5
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_def (L91-L94)
theorem isSymm_def : IsSymm B ↔ ∀ x y, B x y = B y x where
  mp := fun ⟨h⟩ ↦ h
mpr h := ⟨h⟩
```

-- snippet 6
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_iff (L95-L99)
theorem isSymm_iff : IsSymm B ↔ LinearMap.IsSymm B := by
simp [isSymm_def, LinearMap.isSymm_def]

namespace IsSymm
```

-- snippet 7
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isRefl (L100-L115)
theorem isRefl (H : B.IsSymm) : B.IsRefl := fun x y H1 => H.eq x y ▸ H1
protected theorem add {B₁ B₂ : BilinForm R M} (hB₁ : B₁.IsSymm) (hB₂ : B₂.IsSymm) :
    (B₁ + B₂).IsSymm := ⟨fun x y => (congr_arg₂ (· + ·) (hB₁.eq x y) (hB₂.eq x y) :)⟩

protected theorem sub {B₁ B₂ : BilinForm R₁ M₁} (hB₁ : B₁.IsSymm) (hB₂ : B₂.IsSymm) :
    (B₁ - B₂).IsSymm := ⟨fun x y => (congr_arg₂ Sub.sub (hB₁.eq x y) (hB₂.eq x y) :)⟩

protected theorem neg {B : BilinForm R₁ M₁} (hB : B.IsSymm) : (-B).IsSymm := ⟨fun x y =>
  congr_arg Neg.neg (hB.eq x y)⟩

protected theorem smul {α} [Monoid α] [DistribMulAction α R] [SMulCommClass R α R] (a : α)
    {B : BilinForm R M} (hB : B.IsSymm) : (a • B).IsSymm := ⟨fun x y =>
  congr_arg (a • ·) (hB.eq x y)⟩

/-- The restriction of a symmetric bilinear form on a submodule is also symmetric. -/
```

-- snippet 8
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_zero (L122-L123)
theorem isSymm_zero : (0 : BilinForm R M).IsSymm := ⟨fun _ _ => rfl⟩
```

-- snippet 9
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_neg (L125-L127)
theorem isSymm_neg {B : BilinForm R₁ M₁} : (-B).IsSymm ↔ B.IsSymm :=
⟨fun h => neg_neg B ▸ h.neg, IsSymm.neg⟩
```

-- snippet 10
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_iff_flip (L128-L137)
theorem isSymm_iff_flip : B.IsSymm ↔ flipHom B = B where
  mp := fun ⟨h⟩ ↦ by ext; simp [h]
mpr h := ⟨fun x y ↦ by rw [← flip_apply, h]⟩

section polarization

variable {R : Type*} [Field R] [NeZero (2 : R)] [Module R M] {B C : BilinForm R M}

/-- Polarization identity: a symmetric bilinear form can be expressed through the values
it takes on the diagonal. -/
```

-- snippet 11
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.IsSymm (L138-L145)
lemma IsSymm.polarization (x y : M) (hB : B.IsSymm) :
    B x y = (B (x + y) (x + y) - B x x - B y y) / 2 := by
simp only [map_add, LinearMap.add_apply]
  rw [hB.eq y x]
  ring_nf
  rw [mul_assoc, inv_mul_cancel₀ two_ne_zero, mul_one]

/-- A symmetric bilinear form is characterized by the values it takes on the diagonal. -/
```

-- snippet 12
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.ext_of_isSymm (L146-L152)
lemma ext_of_isSymm (hB : IsSymm B) (hC : IsSymm C)
    (h : ∀ x, B x x = C x x) : B = C := by
ext x y
  rw [hB.polarization, hC.polarization]
  simp_rw [h]

/-- A symmetric bilinear form is characterized by the values it takes on the diagonal. -/
```

-- snippet 13
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.ext_iff_of_isSymm (L153-L159)
lemma ext_iff_of_isSymm (hB : IsSymm B) (hC : IsSymm C) :
    B = C ↔ ∀ x, B x x = C x x where
  mp h := by simp [h]
mpr := ext_of_isSymm hB hC

end polarization
```

-- snippet 14
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_iff_basis (L160-L186)
lemma isSymm_iff_basis {ι : Type*} (b : Basis ι R M) :
    IsSymm B ↔ ∀ i j, B (b i) (b j) = B (b j) (b i) where
  mp := fun ⟨h⟩ i j ↦ h _ _
mpr := by
    refine fun h ↦ ⟨fun x y ↦ ?_⟩
    obtain ⟨fx, tx, ix, -, hx⟩ := Submodule.mem_span_iff_exists_finset_subset.1
      (by simp : x ∈ Submodule.span R (Set.range b))
    obtain ⟨fy, ty, iy, -, hy⟩ := Submodule.mem_span_iff_exists_finset_subset.1
      (by simp : y ∈ Submodule.span R (Set.range b))
    rw [← hx, ← hy]
    simp only [map_sum, map_smul, coe_sum, Finset.sum_apply, smul_apply, smul_eq_mul,
      Finset.mul_sum]
    rw [Finset.sum_comm]
    refine Finset.sum_congr rfl (fun b₁ h₁ ↦ Finset.sum_congr rfl fun b₂ h₂ ↦ ?_)
    rw [mul_left_comm]
    obtain ⟨i, rfl⟩ := ix h₁
    obtain ⟨j, rfl⟩ := iy h₂
    rw [h]

/-! ### Positive semidefinite bilinear forms -/

section PositiveSemidefinite

/-- A bilinear form `B` is **nonnegative** if for any `x` we have `0 ≤ B x x`. -/
structure IsNonneg [LE R] (B : BilinForm R M) where
  nonneg : ∀ x, 0 ≤ B x x
```

-- snippet 15
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isNonneg_def (L187-L190)
lemma isNonneg_def [LE R] {B : BilinForm R M} : B.IsNonneg ↔ ∀ x, 0 ≤ B x x :=
⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩

/-- A bilinear form is nonnegative if and only if it is nonnegative as a sesquilinear form. -/
```

-- snippet 16
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.add_left (L65-L66)
theorem add_left (x y z : M) : B (x + y) z = B x z + B y z := map_add₂ _ _ _ _
```

-- snippet 17
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.add_apply (L111-L113)
theorem add_apply (x y : M) : (B + D) x y = B x y + D x y :=
rfl
```

-- snippet 18
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.coeFnAddMonoidHom (L124-L131)
def coeFnAddMonoidHom : BilinForm R M →+ M → M → R where
  toFun := fun B x y => B x y
map_zero' := rfl
  map_add' _ _ := rfl

section flip

/-- The flip of a bilinear form, obtained by exchanging the left and right arguments. -/
```

-- snippet 19
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.zero_right (L75-L76)
theorem zero_right (x : M) : B x 0 = 0 := map_zero _
```

-- snippet 20
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.lsmul_flip_apply (L158-L160)
theorem lsmul_flip_apply (m : M) : (lsmul R M).flip m = toSpanSingleton R M m := rfl
end LinearMap
```

-- snippet 21
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.coe_injective (L94-L98)
theorem coe_injective : Function.Injective ((fun B x y => B x y) : BilinForm R M → M → M → R) :=
fun B D h => by
    ext x y
    apply congrFun₂ h
```

-- snippet 22
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.neg_left (L77-L78)
theorem neg_left (x y : M₁) : B₁ (-x) y = -B₁ x y := map_neg₂ _ _ _
```

-- snippet 23
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_left_of_tower (L85-L87)
lemma smul_left_of_tower (r : S) (x y : M) : B (r • x) y = r • B x y := by
rw [← IsScalarTower.algebraMap_smul R r, smul_left, Algebra.smul_def]
```

-- snippet 24
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flip_apply (L135-L137)
theorem flip_apply (A : BilinForm R M) (x y : M) : flipHom A x y = A y x :=
rfl
```

-- snippet 25
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_left (L67-L68)
theorem smul_left (a : R) (x y : M) : B (a • x) y = a * B x y := map_smul₂ _ _ _ _
```

-- snippet 26
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.add_right (L69-L70)
theorem add_right (x y z : M) : B x (y + z) = B x y + B x z := map_add _ _ _
```

-- snippet 27
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flipHom (L132-L133)
def flipHom : BilinForm R M ≃ₗ[R] BilinForm R M := LinearMap.lflip
```

-- snippet 28
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.zero_apply (L105-L109)
theorem zero_apply (x y : M) : (0 : BilinForm R M) x y = 0 :=
rfl

variable (B D B₁ D₁)
```

-- snippet 29
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.sub_apply (L119-L122)
theorem sub_apply (x y : M₁) : (B₁ - D₁) x y = B₁ x y - D₁ x y :=
rfl

/-- `coeFn` as an `AddMonoidHom` -/
```

-- snippet 30
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.neg_right (L79-L80)
theorem neg_right (x y : M₁) : B₁ x (-y) = -B₁ x y := map_neg _ _
```

-- snippet 31
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.sub_left (L81-L82)
theorem sub_left (x y z : M₁) : B₁ (x - y) z = B₁ x z - B₁ y z := map_sub₂ _ _ _ _
```

-- snippet 32
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flip_flip (L138-L144)
theorem flip_flip :
    flipHom.trans flipHom = LinearEquiv.refl R (BilinForm R M) := by
ext A
  simp

/-- The `flip` of a bilinear form over a commutative ring, obtained by exchanging the left and
right arguments. -/
```

-- snippet 33
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.zero_left (L73-L74)
theorem zero_left (x : M) : B 0 x = 0 := map_zero₂ _ _
```

-- snippet 34
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.neg_apply (L115-L117)
theorem neg_apply (x y : M₁) : (-B₁) x y = -B₁ x y :=
rfl
```

-- snippet 35
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_right (L71-L72)
theorem smul_right (a : R) (x y : M) : B x (a • y) = a * B x y := map_smul _ _ _
```

-- snippet 36
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.congr_fun (L102-L103)
theorem congr_fun (h : B = D) (x y : M) : B x y = D x y := congr_fun₂ h _ _
```

-- snippet 37
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.ext (L100-L101)
theorem ext (H : ∀ x y : M, B x y = D x y) : B = D := ext₂ H
```

-- snippet 38
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_right_of_tower (L88-L93)
lemma smul_right_of_tower (r : S) (x y : M) : B x (r • y) = r • B x y := by
rw [← IsScalarTower.algebraMap_smul R r, smul_right, Algebra.smul_def]

variable {D : BilinForm R M} {D₁ : BilinForm R₁ M₁}

-- TODO: instantiate `FunLike`
```

-- snippet 39
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.sub_right (L83-L84)
theorem sub_right (x y z : M₁) : B₁ x (y - z) = B₁ x y - B₁ x z := map_sub _ _ _
```

-- snippet 40
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flip (L145-L150)
abbrev flip (B : BilinForm R M) :=
flipHom B

end flip

/-- The restriction of a bilinear form on a submodule. -/
```

<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.LinearAlgebra.BilinearForm.Properties).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem restrict {B : BilinForm R M} (b : B.IsSymm) (W : Submodule R M) :
    (B.restrict W).IsSymm
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.IsRefl (L59-L62)
def IsRefl (B : BilinForm R M) : Prop := LinearMap.IsRefl B
namespace IsRefl
```

-- snippet 2
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.eq_zero (L63-L79)
theorem eq_zero (H : B.IsRefl) : ∀ {x y : M}, B x y = 0 → B y x = 0 := fun {x y} => H x y
protected theorem neg {B : BilinForm R₁ M₁} (hB : B.IsRefl) : (-B).IsRefl := fun x y =>
  neg_eq_zero.mpr ∘ hB x y ∘ neg_eq_zero.mp

protected theorem smul {α : Type*} [Semiring α] [IsDomain α] [Module α R] [SMulCommClass R α R]
    [IsTorsionFree α R] (a : α) {B : BilinForm R M} (hB : B.IsRefl) :
    (a • B).IsRefl := fun _ _ h =>
  (smul_eq_zero.mp h).elim (fun ha => smul_eq_zero_of_left ha _) fun hBz =>
    smul_eq_zero_of_right _ (hB _ _ hBz)

protected theorem groupSMul {α} [Group α] [DistribMulAction α R] [SMulCommClass R α R] (a : α)
    {B : BilinForm R M} (hB : B.IsRefl) : (a • B).IsRefl := fun x y =>
  (smul_eq_zero_iff_eq _).mpr ∘ hB x y ∘ (smul_eq_zero_iff_eq _).mp

end IsRefl
```

-- snippet 3
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isRefl_zero (L81-L82)
theorem isRefl_zero : (0 : BilinForm R M).IsRefl := fun _ _ _ => rfl
```

-- snippet 4
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isRefl_neg (L84-L90)
theorem isRefl_neg {B : BilinForm R₁ M₁} : (-B).IsRefl ↔ B.IsRefl :=
⟨fun h => neg_neg B ▸ h.neg, IsRefl.neg⟩

/-- The proposition that a bilinear form is symmetric -/
structure IsSymm (B : BilinForm R M) : Prop where
  protected eq : ∀ x y, B x y = B y x
```

-- snippet 5
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_def (L91-L94)
theorem isSymm_def : IsSymm B ↔ ∀ x y, B x y = B y x where
  mp := fun ⟨h⟩ ↦ h
mpr h := ⟨h⟩
```

-- snippet 6
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_iff (L95-L99)
theorem isSymm_iff : IsSymm B ↔ LinearMap.IsSymm B := by
simp [isSymm_def, LinearMap.isSymm_def]

namespace IsSymm
```

-- snippet 7
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isRefl (L100-L115)
theorem isRefl (H : B.IsSymm) : B.IsRefl := fun x y H1 => H.eq x y ▸ H1
protected theorem add {B₁ B₂ : BilinForm R M} (hB₁ : B₁.IsSymm) (hB₂ : B₂.IsSymm) :
    (B₁ + B₂).IsSymm := ⟨fun x y => (congr_arg₂ (· + ·) (hB₁.eq x y) (hB₂.eq x y) :)⟩

protected theorem sub {B₁ B₂ : BilinForm R₁ M₁} (hB₁ : B₁.IsSymm) (hB₂ : B₂.IsSymm) :
    (B₁ - B₂).IsSymm := ⟨fun x y => (congr_arg₂ Sub.sub (hB₁.eq x y) (hB₂.eq x y) :)⟩

protected theorem neg {B : BilinForm R₁ M₁} (hB : B.IsSymm) : (-B).IsSymm := ⟨fun x y =>
  congr_arg Neg.neg (hB.eq x y)⟩

protected theorem smul {α} [Monoid α] [DistribMulAction α R] [SMulCommClass R α R] (a : α)
    {B : BilinForm R M} (hB : B.IsSymm) : (a • B).IsSymm := ⟨fun x y =>
  congr_arg (a • ·) (hB.eq x y)⟩

/-- The restriction of a symmetric bilinear form on a submodule is also symmetric. -/
```

-- snippet 8
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_zero (L122-L123)
theorem isSymm_zero : (0 : BilinForm R M).IsSymm := ⟨fun _ _ => rfl⟩
```

-- snippet 9
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_neg (L125-L127)
theorem isSymm_neg {B : BilinForm R₁ M₁} : (-B).IsSymm ↔ B.IsSymm :=
⟨fun h => neg_neg B ▸ h.neg, IsSymm.neg⟩
```

-- snippet 10
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_iff_flip (L128-L137)
theorem isSymm_iff_flip : B.IsSymm ↔ flipHom B = B where
  mp := fun ⟨h⟩ ↦ by ext; simp [h]
mpr h := ⟨fun x y ↦ by rw [← flip_apply, h]⟩

section polarization

variable {R : Type*} [Field R] [NeZero (2 : R)] [Module R M] {B C : BilinForm R M}

/-- Polarization identity: a symmetric bilinear form can be expressed through the values
it takes on the diagonal. -/
```

-- snippet 11
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.IsSymm (L138-L145)
lemma IsSymm.polarization (x y : M) (hB : B.IsSymm) :
    B x y = (B (x + y) (x + y) - B x x - B y y) / 2 := by
simp only [map_add, LinearMap.add_apply]
  rw [hB.eq y x]
  ring_nf
  rw [mul_assoc, inv_mul_cancel₀ two_ne_zero, mul_one]

/-- A symmetric bilinear form is characterized by the values it takes on the diagonal. -/
```

-- snippet 12
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.ext_of_isSymm (L146-L152)
lemma ext_of_isSymm (hB : IsSymm B) (hC : IsSymm C)
    (h : ∀ x, B x x = C x x) : B = C := by
ext x y
  rw [hB.polarization, hC.polarization]
  simp_rw [h]

/-- A symmetric bilinear form is characterized by the values it takes on the diagonal. -/
```

-- snippet 13
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.ext_iff_of_isSymm (L153-L159)
lemma ext_iff_of_isSymm (hB : IsSymm B) (hC : IsSymm C) :
    B = C ↔ ∀ x, B x x = C x x where
  mp h := by simp [h]
mpr := ext_of_isSymm hB hC

end polarization
```

-- snippet 14
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isSymm_iff_basis (L160-L186)
lemma isSymm_iff_basis {ι : Type*} (b : Basis ι R M) :
    IsSymm B ↔ ∀ i j, B (b i) (b j) = B (b j) (b i) where
  mp := fun ⟨h⟩ i j ↦ h _ _
mpr := by
    refine fun h ↦ ⟨fun x y ↦ ?_⟩
    obtain ⟨fx, tx, ix, -, hx⟩ := Submodule.mem_span_iff_exists_finset_subset.1
      (by simp : x ∈ Submodule.span R (Set.range b))
    obtain ⟨fy, ty, iy, -, hy⟩ := Submodule.mem_span_iff_exists_finset_subset.1
      (by simp : y ∈ Submodule.span R (Set.range b))
    rw [← hx, ← hy]
    simp only [map_sum, map_smul, coe_sum, Finset.sum_apply, smul_apply, smul_eq_mul,
      Finset.mul_sum]
    rw [Finset.sum_comm]
    refine Finset.sum_congr rfl (fun b₁ h₁ ↦ Finset.sum_congr rfl fun b₂ h₂ ↦ ?_)
    rw [mul_left_comm]
    obtain ⟨i, rfl⟩ := ix h₁
    obtain ⟨j, rfl⟩ := iy h₂
    rw [h]

/-! ### Positive semidefinite bilinear forms -/

section PositiveSemidefinite

/-- A bilinear form `B` is **nonnegative** if for any `x` we have `0 ≤ B x x`. -/
structure IsNonneg [LE R] (B : BilinForm R M) where
  nonneg : ∀ x, 0 ≤ B x x
```

-- snippet 15
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Properties.isNonneg_def (L187-L190)
lemma isNonneg_def [LE R] {B : BilinForm R M} : B.IsNonneg ↔ ∀ x, 0 ≤ B x x :=
⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩

/-- A bilinear form is nonnegative if and only if it is nonnegative as a sesquilinear form. -/
```

-- snippet 16
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.add_left (L65-L66)
theorem add_left (x y z : M) : B (x + y) z = B x z + B y z := map_add₂ _ _ _ _
```

-- snippet 17
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.add_apply (L111-L113)
theorem add_apply (x y : M) : (B + D) x y = B x y + D x y :=
rfl
```

-- snippet 18
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.coeFnAddMonoidHom (L124-L131)
def coeFnAddMonoidHom : BilinForm R M →+ M → M → R where
  toFun := fun B x y => B x y
map_zero' := rfl
  map_add' _ _ := rfl

section flip

/-- The flip of a bilinear form, obtained by exchanging the left and right arguments. -/
```

-- snippet 19
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.zero_right (L75-L76)
theorem zero_right (x : M) : B x 0 = 0 := map_zero _
```

-- snippet 20
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.lsmul_flip_apply (L158-L160)
theorem lsmul_flip_apply (m : M) : (lsmul R M).flip m = toSpanSingleton R M m := rfl
end LinearMap
```

-- snippet 21
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.coe_injective (L94-L98)
theorem coe_injective : Function.Injective ((fun B x y => B x y) : BilinForm R M → M → M → R) :=
fun B D h => by
    ext x y
    apply congrFun₂ h
```

-- snippet 22
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.neg_left (L77-L78)
theorem neg_left (x y : M₁) : B₁ (-x) y = -B₁ x y := map_neg₂ _ _ _
```

-- snippet 23
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_left_of_tower (L85-L87)
lemma smul_left_of_tower (r : S) (x y : M) : B (r • x) y = r • B x y := by
rw [← IsScalarTower.algebraMap_smul R r, smul_left, Algebra.smul_def]
```

-- snippet 24
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flip_apply (L135-L137)
theorem flip_apply (A : BilinForm R M) (x y : M) : flipHom A x y = A y x :=
rfl
```

-- snippet 25
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_left (L67-L68)
theorem smul_left (a : R) (x y : M) : B (a • x) y = a * B x y := map_smul₂ _ _ _ _
```

-- snippet 26
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.add_right (L69-L70)
theorem add_right (x y z : M) : B x (y + z) = B x y + B x z := map_add _ _ _
```

-- snippet 27
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flipHom (L132-L133)
def flipHom : BilinForm R M ≃ₗ[R] BilinForm R M := LinearMap.lflip
```

-- snippet 28
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.zero_apply (L105-L109)
theorem zero_apply (x y : M) : (0 : BilinForm R M) x y = 0 :=
rfl

variable (B D B₁ D₁)
```

-- snippet 29
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.sub_apply (L119-L122)
theorem sub_apply (x y : M₁) : (B₁ - D₁) x y = B₁ x y - D₁ x y :=
rfl

/-- `coeFn` as an `AddMonoidHom` -/
```

-- snippet 30
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.neg_right (L79-L80)
theorem neg_right (x y : M₁) : B₁ x (-y) = -B₁ x y := map_neg _ _
```

-- snippet 31
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.sub_left (L81-L82)
theorem sub_left (x y z : M₁) : B₁ (x - y) z = B₁ x z - B₁ y z := map_sub₂ _ _ _ _
```

-- snippet 32
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flip_flip (L138-L144)
theorem flip_flip :
    flipHom.trans flipHom = LinearEquiv.refl R (BilinForm R M) := by
ext A
  simp

/-- The `flip` of a bilinear form over a commutative ring, obtained by exchanging the left and
right arguments. -/
```

-- snippet 33
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.zero_left (L73-L74)
theorem zero_left (x : M) : B 0 x = 0 := map_zero₂ _ _
```

-- snippet 34
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.neg_apply (L115-L117)
theorem neg_apply (x y : M₁) : (-B₁) x y = -B₁ x y :=
rfl
```

-- snippet 35
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_right (L71-L72)
theorem smul_right (a : R) (x y : M) : B x (a • y) = a * B x y := map_smul _ _ _
```

-- snippet 36
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.congr_fun (L102-L103)
theorem congr_fun (h : B = D) (x y : M) : B x y = D x y := congr_fun₂ h _ _
```

-- snippet 37
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.ext (L100-L101)
theorem ext (H : ∀ x y : M, B x y = D x y) : B = D := ext₂ H
```

-- snippet 38
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.smul_right_of_tower (L88-L93)
lemma smul_right_of_tower (r : S) (x y : M) : B x (r • y) = r • B x y := by
rw [← IsScalarTower.algebraMap_smul R r, smul_right, Algebra.smul_def]

variable {D : BilinForm R M} {D₁ : BilinForm R₁ M₁}

-- TODO: instantiate `FunLike`
```

-- snippet 39
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.sub_right (L83-L84)
theorem sub_right (x y z : M₁) : B₁ x (y - z) = B₁ x y - B₁ x z := map_sub _ _ _
```

-- snippet 40
```lean
-- Mathlib.LinearAlgebra.BilinearForm.Basic.flip (L145-L150)
abbrev flip (B : BilinForm R M) :=
flipHom B

end flip

/-- The restriction of a bilinear form on a submodule. -/
```
[/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.MeanInequalitiesPow).

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

```lean
theorem arith_mean_le_rpow_mean (w z : ι → ℝ≥0) (hw' : ∑ i ∈ s, w i = 1) {p : ℝ} (hp : 1 ≤ p) :
    ∑ i ∈ s, w i * z i ≤ (∑ i ∈ s, w i * z i ^ p) ^ (1 / p)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.pow_arith_mean_le_arith_mean_pow (L58-L62)
theorem pow_arith_mean_le_arith_mean_pow (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) (hz : ∀ i ∈ s, 0 ≤ z i) (n : ℕ) :
    (∑ i ∈ s, w i * z i) ^ n ≤ ∑ i ∈ s, w i * z i ^ n :=
(convexOn_pow n).map_sum_le hw hw' hz
```

-- snippet 2
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.pow_arith_mean_le_arith_mean_pow_of_even (L63-L67)
theorem pow_arith_mean_le_arith_mean_pow_of_even (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) {n : ℕ} (hn : Even n) :
    (∑ i ∈ s, w i * z i) ^ n ≤ ∑ i ∈ s, w i * z i ^ n :=
hn.convexOn_pow.map_sum_le hw hw' fun _ _ => Set.mem_univ _
```

-- snippet 3
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.zpow_arith_mean_le_arith_mean_zpow (L68-L72)
theorem zpow_arith_mean_le_arith_mean_zpow (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) (hz : ∀ i ∈ s, 0 < z i) (m : ℤ) :
    (∑ i ∈ s, w i * z i) ^ m ≤ ∑ i ∈ s, w i * z i ^ m :=
(convexOn_zpow m).map_sum_le hw hw' hz
```

-- snippet 4
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_arith_mean_le_arith_mean_rpow (L73-L77)
theorem rpow_arith_mean_le_arith_mean_rpow (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) (hz : ∀ i ∈ s, 0 ≤ z i) {p : ℝ} (hp : 1 ≤ p) :
    (∑ i ∈ s, w i * z i) ^ p ≤ ∑ i ∈ s, w i * z i ^ p :=
(convexOn_rpow hp).map_sum_le hw hw' hz
```

-- snippet 5
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.pow_arith_mean_le_arith_mean_pow (L95-L102)
theorem pow_arith_mean_le_arith_mean_pow (w z : ι → ℝ≥0) (hw' : ∑ i ∈ s, w i = 1) (n : ℕ) :
    (∑ i ∈ s, w i * z i) ^ n ≤ ∑ i ∈ s, w i * z i ^ n :=
mod_cast
    Real.pow_arith_mean_le_arith_mean_pow s _ _ (fun i _ => (w i).coe_nonneg)
      (mod_cast hw') (fun i _ => (z i).coe_nonneg) n

/-- Weighted generalized mean inequality, version for sums over finite sets, with `ℝ≥0`-valued
functions and real exponents. -/
```

-- snippet 6
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_arith_mean_le_arith_mean_rpow (L103-L109)
theorem rpow_arith_mean_le_arith_mean_rpow (w z : ι → ℝ≥0) (hw' : ∑ i ∈ s, w i = 1) {p : ℝ}
    (hp : 1 ≤ p) : (∑ i ∈ s, w i * z i) ^ p ≤ ∑ i ∈ s, w i * z i ^ p :=
mod_cast
    Real.rpow_arith_mean_le_arith_mean_rpow s _ _ (fun i _ => (w i).coe_nonneg)
      (mod_cast hw') (fun i _ => (z i).coe_nonneg) hp

/-- Weighted generalized mean inequality, version for two elements of `ℝ≥0` and real exponents. -/
```

-- snippet 7
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_arith_mean_le_arith_mean2_rpow (L110-L116)
theorem rpow_arith_mean_le_arith_mean2_rpow (w₁ w₂ z₁ z₂ : ℝ≥0) (hw' : w₁ + w₂ = 1) {p : ℝ}
    (hp : 1 ≤ p) : (w₁ * z₁ + w₂ * z₂) ^ p ≤ w₁ * z₁ ^ p + w₂ * z₂ ^ p := by
have h := rpow_arith_mean_le_arith_mean_rpow univ ![w₁, w₂] ![z₁, z₂] ?_ hp
  · simpa [Fin.sum_univ_succ] using h
  · simp [hw', Fin.sum_univ_succ]

/-- Unweighted mean inequality, version for two elements of `ℝ≥0` and real exponents. -/
```

-- snippet 8
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_le_mul_rpow_add_rpow (L117-L130)
theorem rpow_add_le_mul_rpow_add_rpow (z₁ z₂ : ℝ≥0) {p : ℝ} (hp : 1 ≤ p) :
    (z₁ + z₂) ^ p ≤ (2 : ℝ≥0) ^ (p - 1) * (z₁ ^ p + z₂ ^ p) := by
rcases eq_or_lt_of_le hp with (rfl | h'p)
  · simp only [rpow_one, sub_self, rpow_zero, one_mul]; rfl
  convert rpow_arith_mean_le_arith_mean2_rpow (1 / 2) (1 / 2) (2 * z₁) (2 * z₂) (add_halves 1) hp
    using 1
  · simp only [one_div, inv_mul_cancel_left₀, Ne, two_ne_zero,
      not_false_iff]
  · have A : p - 1 ≠ 0 := ne_of_gt (sub_pos.2 h'p)
    simp only [mul_rpow, rpow_sub' A, rpow_one]
    ring

/-- Weighted generalized mean inequality, version for sums over finite sets, with `ℝ≥0`-valued
functions and real exponents. -/
```

-- snippet 9
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.add_rpow_le_rpow_add (L144-L157)
theorem add_rpow_le_rpow_add {p : ℝ} (a b : ℝ≥0) (hp1 : 1 ≤ p) : a ^ p + b ^ p ≤ (a + b) ^ p := by
have hp_pos : 0 < p := by positivity
  by_cases h_zero : a + b = 0
  · simp [add_eq_zero.mp h_zero, hp_pos.ne']
  have h_nonzero : ¬(a = 0 ∧ b = 0) := by rwa [add_eq_zero] at h_zero
  have h_add : a / (a + b) + b / (a + b) = 1 := by rw [← add_div, div_self h_zero]
  have h := add_rpow_le_one_of_add_le_one (a / (a + b)) (b / (a + b)) h_add.le hp1
  rw [div_rpow a (a + b), div_rpow b (a + b)] at h
  have hab_0 : (a + b) ^ p ≠ 0 := by simp [h_nonzero]
  have h_mul : (a + b) ^ p * (a ^ p / (a + b) ^ p + b ^ p / (a + b) ^ p) ≤ (a + b) ^ p := by
    nth_rw 4 [← mul_one ((a + b) ^ p)]; gcongr
  rwa [div_eq_mul_inv, div_eq_mul_inv, mul_add, mul_comm (a ^ p), mul_comm (b ^ p), ← mul_assoc, ←
    mul_assoc, mul_inv_cancel₀ hab_0, one_mul, one_mul] at h_mul
```

-- snippet 10
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le_add (L158-L164)
theorem rpow_add_rpow_le_add {p : ℝ} (a b : ℝ≥0) (hp1 : 1 ≤ p) :
    (a ^ p + b ^ p) ^ (1 / p) ≤ a + b := by
rw [one_div]
  rw [← @NNReal.le_rpow_inv_iff _ _ p⁻¹ (by simp [lt_of_lt_of_le zero_lt_one hp1])]
  rw [inv_inv]
  exact add_rpow_le_rpow_add _ _ hp1
```

-- snippet 11
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le (L165-L177)
theorem rpow_add_rpow_le {p q : ℝ} (a b : ℝ≥0) (hp_pos : 0 < p) (hpq : p ≤ q) :
    (a ^ q + b ^ q) ^ (1 / q) ≤ (a ^ p + b ^ p) ^ (1 / p) := by
have h_rpow : ∀ a : ℝ≥0, a ^ q = (a ^ p) ^ (q / p) := fun a => by
    rw [← NNReal.rpow_mul, div_eq_inv_mul, ← mul_assoc, mul_inv_cancel₀ hp_pos.ne.symm,
      one_mul]
  have h_rpow_add_rpow_le_add :
    ((a ^ p) ^ (q / p) + (b ^ p) ^ (q / p)) ^ (1 / (q / p)) ≤ a ^ p + b ^ p := by
    refine rpow_add_rpow_le_add (a ^ p) (b ^ p) ?_
    rwa [one_le_div hp_pos]
  rw [h_rpow a, h_rpow b, one_div p, NNReal.le_rpow_inv_iff hp_pos, ← NNReal.rpow_mul, mul_comm,
    mul_one_div]
  rwa [one_div_div] at h_rpow_add_rpow_le_add
```

-- snippet 12
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_le_add_rpow (L178-L190)
theorem rpow_add_le_add_rpow {p : ℝ} (a b : ℝ≥0) (hp : 0 ≤ p) (hp1 : p ≤ 1) :
    (a + b) ^ p ≤ a ^ p + b ^ p := by
rcases hp.eq_or_lt with (rfl | hp_pos)
  · simp
  have h := rpow_add_rpow_le a b hp_pos hp1
  rw [one_div_one, one_div] at h
  repeat' rw [NNReal.rpow_one] at h
  exact (NNReal.le_rpow_inv_iff hp_pos).mp h

end NNReal

namespace Real
```

-- snippet 13
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.add_rpow_le_rpow_add (L191-L196)
lemma add_rpow_le_rpow_add {p : ℝ} {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hp1 : 1 ≤ p) :
     a ^ p + b ^ p ≤ (a + b) ^ p := by
lift a to NNReal using ha
  lift b to NNReal using hb
  exact_mod_cast NNReal.add_rpow_le_rpow_add a b hp1
```

-- snippet 14
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le_add (L197-L202)
lemma rpow_add_rpow_le_add {p : ℝ} {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hp1 : 1 ≤ p) :
    (a ^ p + b ^ p) ^ (1 / p) ≤ a + b := by
lift a to NNReal using ha
  lift b to NNReal using hb
  exact_mod_cast NNReal.rpow_add_rpow_le_add a b hp1
```

-- snippet 15
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le (L203-L209)
lemma rpow_add_rpow_le {p q : ℝ} {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hp_pos : 0 < p)
    (hpq : p ≤ q) :
    (a ^ q + b ^ q) ^ (1 / q) ≤ (a ^ p + b ^ p) ^ (1 / p) := by
lift a to NNReal using ha
  lift b to NNReal using hb
  exact_mod_cast NNReal.rpow_add_rpow_le a b hp_pos hpq
```

<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.MeanInequalitiesPow).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem arith_mean_le_rpow_mean (w z : ι → ℝ≥0) (hw' : ∑ i ∈ s, w i = 1) {p : ℝ} (hp : 1 ≤ p) :
    ∑ i ∈ s, w i * z i ≤ (∑ i ∈ s, w i * z i ^ p) ^ (1 / p)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.pow_arith_mean_le_arith_mean_pow (L58-L62)
theorem pow_arith_mean_le_arith_mean_pow (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) (hz : ∀ i ∈ s, 0 ≤ z i) (n : ℕ) :
    (∑ i ∈ s, w i * z i) ^ n ≤ ∑ i ∈ s, w i * z i ^ n :=
(convexOn_pow n).map_sum_le hw hw' hz
```

-- snippet 2
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.pow_arith_mean_le_arith_mean_pow_of_even (L63-L67)
theorem pow_arith_mean_le_arith_mean_pow_of_even (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) {n : ℕ} (hn : Even n) :
    (∑ i ∈ s, w i * z i) ^ n ≤ ∑ i ∈ s, w i * z i ^ n :=
hn.convexOn_pow.map_sum_le hw hw' fun _ _ => Set.mem_univ _
```

-- snippet 3
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.zpow_arith_mean_le_arith_mean_zpow (L68-L72)
theorem zpow_arith_mean_le_arith_mean_zpow (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) (hz : ∀ i ∈ s, 0 < z i) (m : ℤ) :
    (∑ i ∈ s, w i * z i) ^ m ≤ ∑ i ∈ s, w i * z i ^ m :=
(convexOn_zpow m).map_sum_le hw hw' hz
```

-- snippet 4
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_arith_mean_le_arith_mean_rpow (L73-L77)
theorem rpow_arith_mean_le_arith_mean_rpow (w z : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i)
    (hw' : ∑ i ∈ s, w i = 1) (hz : ∀ i ∈ s, 0 ≤ z i) {p : ℝ} (hp : 1 ≤ p) :
    (∑ i ∈ s, w i * z i) ^ p ≤ ∑ i ∈ s, w i * z i ^ p :=
(convexOn_rpow hp).map_sum_le hw hw' hz
```

-- snippet 5
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.pow_arith_mean_le_arith_mean_pow (L95-L102)
theorem pow_arith_mean_le_arith_mean_pow (w z : ι → ℝ≥0) (hw' : ∑ i ∈ s, w i = 1) (n : ℕ) :
    (∑ i ∈ s, w i * z i) ^ n ≤ ∑ i ∈ s, w i * z i ^ n :=
mod_cast
    Real.pow_arith_mean_le_arith_mean_pow s _ _ (fun i _ => (w i).coe_nonneg)
      (mod_cast hw') (fun i _ => (z i).coe_nonneg) n

/-- Weighted generalized mean inequality, version for sums over finite sets, with `ℝ≥0`-valued
functions and real exponents. -/
```

-- snippet 6
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_arith_mean_le_arith_mean_rpow (L103-L109)
theorem rpow_arith_mean_le_arith_mean_rpow (w z : ι → ℝ≥0) (hw' : ∑ i ∈ s, w i = 1) {p : ℝ}
    (hp : 1 ≤ p) : (∑ i ∈ s, w i * z i) ^ p ≤ ∑ i ∈ s, w i * z i ^ p :=
mod_cast
    Real.rpow_arith_mean_le_arith_mean_rpow s _ _ (fun i _ => (w i).coe_nonneg)
      (mod_cast hw') (fun i _ => (z i).coe_nonneg) hp

/-- Weighted generalized mean inequality, version for two elements of `ℝ≥0` and real exponents. -/
```

-- snippet 7
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_arith_mean_le_arith_mean2_rpow (L110-L116)
theorem rpow_arith_mean_le_arith_mean2_rpow (w₁ w₂ z₁ z₂ : ℝ≥0) (hw' : w₁ + w₂ = 1) {p : ℝ}
    (hp : 1 ≤ p) : (w₁ * z₁ + w₂ * z₂) ^ p ≤ w₁ * z₁ ^ p + w₂ * z₂ ^ p := by
have h := rpow_arith_mean_le_arith_mean_rpow univ ![w₁, w₂] ![z₁, z₂] ?_ hp
  · simpa [Fin.sum_univ_succ] using h
  · simp [hw', Fin.sum_univ_succ]

/-- Unweighted mean inequality, version for two elements of `ℝ≥0` and real exponents. -/
```

-- snippet 8
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_le_mul_rpow_add_rpow (L117-L130)
theorem rpow_add_le_mul_rpow_add_rpow (z₁ z₂ : ℝ≥0) {p : ℝ} (hp : 1 ≤ p) :
    (z₁ + z₂) ^ p ≤ (2 : ℝ≥0) ^ (p - 1) * (z₁ ^ p + z₂ ^ p) := by
rcases eq_or_lt_of_le hp with (rfl | h'p)
  · simp only [rpow_one, sub_self, rpow_zero, one_mul]; rfl
  convert rpow_arith_mean_le_arith_mean2_rpow (1 / 2) (1 / 2) (2 * z₁) (2 * z₂) (add_halves 1) hp
    using 1
  · simp only [one_div, inv_mul_cancel_left₀, Ne, two_ne_zero,
      not_false_iff]
  · have A : p - 1 ≠ 0 := ne_of_gt (sub_pos.2 h'p)
    simp only [mul_rpow, rpow_sub' A, rpow_one]
    ring

/-- Weighted generalized mean inequality, version for sums over finite sets, with `ℝ≥0`-valued
functions and real exponents. -/
```

-- snippet 9
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.add_rpow_le_rpow_add (L144-L157)
theorem add_rpow_le_rpow_add {p : ℝ} (a b : ℝ≥0) (hp1 : 1 ≤ p) : a ^ p + b ^ p ≤ (a + b) ^ p := by
have hp_pos : 0 < p := by positivity
  by_cases h_zero : a + b = 0
  · simp [add_eq_zero.mp h_zero, hp_pos.ne']
  have h_nonzero : ¬(a = 0 ∧ b = 0) := by rwa [add_eq_zero] at h_zero
  have h_add : a / (a + b) + b / (a + b) = 1 := by rw [← add_div, div_self h_zero]
  have h := add_rpow_le_one_of_add_le_one (a / (a + b)) (b / (a + b)) h_add.le hp1
  rw [div_rpow a (a + b), div_rpow b (a + b)] at h
  have hab_0 : (a + b) ^ p ≠ 0 := by simp [h_nonzero]
  have h_mul : (a + b) ^ p * (a ^ p / (a + b) ^ p + b ^ p / (a + b) ^ p) ≤ (a + b) ^ p := by
    nth_rw 4 [← mul_one ((a + b) ^ p)]; gcongr
  rwa [div_eq_mul_inv, div_eq_mul_inv, mul_add, mul_comm (a ^ p), mul_comm (b ^ p), ← mul_assoc, ←
    mul_assoc, mul_inv_cancel₀ hab_0, one_mul, one_mul] at h_mul
```

-- snippet 10
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le_add (L158-L164)
theorem rpow_add_rpow_le_add {p : ℝ} (a b : ℝ≥0) (hp1 : 1 ≤ p) :
    (a ^ p + b ^ p) ^ (1 / p) ≤ a + b := by
rw [one_div]
  rw [← @NNReal.le_rpow_inv_iff _ _ p⁻¹ (by simp [lt_of_lt_of_le zero_lt_one hp1])]
  rw [inv_inv]
  exact add_rpow_le_rpow_add _ _ hp1
```

-- snippet 11
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le (L165-L177)
theorem rpow_add_rpow_le {p q : ℝ} (a b : ℝ≥0) (hp_pos : 0 < p) (hpq : p ≤ q) :
    (a ^ q + b ^ q) ^ (1 / q) ≤ (a ^ p + b ^ p) ^ (1 / p) := by
have h_rpow : ∀ a : ℝ≥0, a ^ q = (a ^ p) ^ (q / p) := fun a => by
    rw [← NNReal.rpow_mul, div_eq_inv_mul, ← mul_assoc, mul_inv_cancel₀ hp_pos.ne.symm,
      one_mul]
  have h_rpow_add_rpow_le_add :
    ((a ^ p) ^ (q / p) + (b ^ p) ^ (q / p)) ^ (1 / (q / p)) ≤ a ^ p + b ^ p := by
    refine rpow_add_rpow_le_add (a ^ p) (b ^ p) ?_
    rwa [one_le_div hp_pos]
  rw [h_rpow a, h_rpow b, one_div p, NNReal.le_rpow_inv_iff hp_pos, ← NNReal.rpow_mul, mul_comm,
    mul_one_div]
  rwa [one_div_div] at h_rpow_add_rpow_le_add
```

-- snippet 12
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_le_add_rpow (L178-L190)
theorem rpow_add_le_add_rpow {p : ℝ} (a b : ℝ≥0) (hp : 0 ≤ p) (hp1 : p ≤ 1) :
    (a + b) ^ p ≤ a ^ p + b ^ p := by
rcases hp.eq_or_lt with (rfl | hp_pos)
  · simp
  have h := rpow_add_rpow_le a b hp_pos hp1
  rw [one_div_one, one_div] at h
  repeat' rw [NNReal.rpow_one] at h
  exact (NNReal.le_rpow_inv_iff hp_pos).mp h

end NNReal

namespace Real
```

-- snippet 13
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.add_rpow_le_rpow_add (L191-L196)
lemma add_rpow_le_rpow_add {p : ℝ} {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hp1 : 1 ≤ p) :
     a ^ p + b ^ p ≤ (a + b) ^ p := by
lift a to NNReal using ha
  lift b to NNReal using hb
  exact_mod_cast NNReal.add_rpow_le_rpow_add a b hp1
```

-- snippet 14
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le_add (L197-L202)
lemma rpow_add_rpow_le_add {p : ℝ} {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hp1 : 1 ≤ p) :
    (a ^ p + b ^ p) ^ (1 / p) ≤ a + b := by
lift a to NNReal using ha
  lift b to NNReal using hb
  exact_mod_cast NNReal.rpow_add_rpow_le_add a b hp1
```

-- snippet 15
```lean
-- Mathlib.Analysis.MeanInequalitiesPow.rpow_add_rpow_le (L203-L209)
lemma rpow_add_rpow_le {p q : ℝ} {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hp_pos : 0 < p)
    (hpq : p ≤ q) :
    (a ^ q + b ^ q) ^ (1 / q) ≤ (a ^ p + b ^ p) ^ (1 / p) := by
lift a to NNReal using ha
  lift b to NNReal using hb
  exact_mod_cast NNReal.rpow_add_rpow_le a b hp_pos hpq
```
[/INST]