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

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

```lean
theorem cast_natCast (n : ℕ) : ((n : ℚ) : α) = n
```

## Retrieved context
-- snippet 1
```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 2
```lean
-- Mathlib.Data.Rat.Cast.Defs.commute_cast (L49-L50)
lemma commute_cast (a : α) (q : ℚ≥0) : Commute a q := (cast_commute ..).symm
```

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

-- snippet 4
```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 5
```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 6
```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 7
```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 8
```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 9
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_zero (L126-L128)
theorem cast_zero : ((0 : ℚ) : α) = 0 :=
(cast_intCast _).trans Int.cast_zero
```

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

-- snippet 11
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_commute (L133-L135)
theorem cast_commute (r : ℚ) (a : α) : Commute (↑r) a := by
simpa only [cast_def] using (r.1.cast_commute a).div_left (r.2.cast_commute a)
```

-- snippet 12
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_comm (L136-L138)
theorem cast_comm (r : ℚ) (a : α) : (r : α) * a = a * r :=
(cast_commute r a).eq
```

-- snippet 13
```lean
-- Mathlib.Data.Rat.Cast.Defs.commute_cast (L139-L141)
theorem commute_cast (a : α) (r : ℚ) : Commute a r :=
(r.cast_commute a).symm
```

-- snippet 14
```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 15
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_mkRat_of_ne_zero (L163-L165)
lemma cast_mkRat_of_ne_zero (a : ℤ) {b : ℕ} (hb : (b : α) ≠ 0) : (mkRat a b : α) = a / b := by
rw [Rat.mkRat_eq_divInt, cast_divInt_of_ne_zero, Int.cast_natCast]; rwa [Int.cast_natCast]
```

-- snippet 16
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_add_of_ne_zero (L167-L175)
lemma cast_add_of_ne_zero {q r : ℚ} (hq : (q.den : α) ≠ 0) (hr : (r.den : α) ≠ 0) :
    (q + r : ℚ) = (q + r : α) := by
rw [add_def', cast_mkRat_of_ne_zero, cast_def, cast_def, mul_comm r.num,
    (Nat.cast_commute _ _).div_add_div (Nat.commute_cast _ _) hq hr]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr
```

-- snippet 17
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_inv_of_ne_zero (L191-L193)
lemma cast_inv_of_ne_zero (hq : (q.num : α) ≠ 0) : ↑(q⁻¹) = (q⁻¹ : α) := by
rw [inv_def, cast_divInt_of_ne_zero _ hq, cast_def, inv_div, Int.cast_natCast]
```

-- snippet 18
```lean
-- Mathlib.Data.Rat.Cast.Defs.eq_nnratCast (L213-L215)
lemma eq_nnratCast [DivisionSemiring α] [FunLike F ℚ≥0 α] [RingHomClass F ℚ≥0 α] (f : F) (q : ℚ≥0) :
    f q = q := by rw [← map_nnratCast f, NNRat.cast_id]
```

-- snippet 19
```lean
-- Mathlib.Data.Rat.Cast.Defs.map_ratCast (L217-L219)
theorem map_ratCast [DivisionRing α] [DivisionRing β] [RingHomClass F α β] (f : F) (q : ℚ) :
    f q = q := by rw [cast_def, map_div₀, map_intCast, map_natCast, cast_def]
```

-- snippet 20
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_nnrat' (L231-L238)
lemma ext_nnrat' (h : ∀ n : ℕ, f n = g n) : f = g :=
(DFunLike.ext f g) fun r => by
    rw [← r.num_div_den, div_eq_mul_inv, map_mul, map_mul, h, eq_on_inv₀ f g]
    apply h

/-- If monoid with zero homs `f` and `g` from `ℚ≥0` agree on the naturals then they are equal.

See note [partially-applied ext lemmas] for why `comp` is used here. -/
```

-- snippet 21
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_nnrat (L240-L245)
lemma ext_nnrat {f g : ℚ≥0 →*₀ M₀}
    (h : f.comp (Nat.castRingHom ℚ≥0 : ℕ →*₀ ℚ≥0) = g.comp (Nat.castRingHom ℚ≥0)) : f = g :=
ext_nnrat' <| DFunLike.congr_fun h

/-- If monoid with zero homs `f` and `g` from `ℚ≥0` agree on the positive naturals then they are
equal. -/
```

-- snippet 22
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_nnrat_on_pnat (L246-L256)
lemma ext_nnrat_on_pnat (same_on_pnat : ∀ n : ℕ, 0 < n → f n = g n) : f = g :=
ext_nnrat' <| DFunLike.congr_fun <| ext_nat''
    ((f : ℚ≥0 →*₀ M₀).comp (Nat.castRingHom ℚ≥0 : ℕ →*₀ ℚ≥0))
    ((g : ℚ≥0 →*₀ M₀).comp (Nat.castRingHom ℚ≥0 : ℕ →*₀ ℚ≥0)) (by simpa)

end NNRat

section Rat
variable [FunLike F ℚ M₀] [MonoidWithZeroHomClass F ℚ M₀] {f g : F}

/-- If monoid with zero homs `f` and `g` from `ℚ` agree on the integers then they are equal. -/
```

-- snippet 23
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_rat' (L257-L265)
theorem ext_rat' (h : ∀ m : ℤ, f m = g m) : f = g :=
(DFunLike.ext f g) fun r => by
    rw [← r.num_div_den, div_eq_mul_inv, map_mul, map_mul, h, ← Int.cast_natCast,
      eq_on_inv₀ f g]
    apply h

/-- If monoid with zero homs `f` and `g` from `ℚ` agree on the integers then they are equal.

See note [partially-applied ext lemmas] for why `comp` is used here. -/
```

-- snippet 24
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_rat (L267-L272)
theorem ext_rat {f g : ℚ →*₀ M₀}
    (h : f.comp (Int.castRingHom ℚ : ℤ →*₀ ℚ) = g.comp (Int.castRingHom ℚ)) : f = g :=
ext_rat' <| DFunLike.congr_fun h

/-- If monoid with zero homs `f` and `g` from `ℚ` agree on the positive naturals and `-1` then
they are equal. -/
```

-- snippet 25
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_rat_on_pnat (L273-L286)
theorem ext_rat_on_pnat (same_on_neg_one : f (-1) = g (-1))
    (same_on_pnat : ∀ n : ℕ, 0 < n → f n = g n) : f = g :=
ext_rat' <|
    DFunLike.congr_fun <|
      show
        (f : ℚ →*₀ M₀).comp (Int.castRingHom ℚ : ℤ →*₀ ℚ) =
          (g : ℚ →*₀ M₀).comp (Int.castRingHom ℚ : ℤ →*₀ ℚ)
        from ext_int' (by simpa) (by simpa)

end Rat
end MonoidWithZeroHomClass

/-- Any two ring homomorphisms from `ℚ` to a semiring are equal. If the codomain is a division ring,
then this lemma follows from `eq_ratCast`. -/
```

-- snippet 26
```lean
-- Mathlib.Data.Rat.Defs.intCast_injective (L52-L52)
lemma intCast_injective : Injective (Int.cast : ℤ → ℚ) := fun _ _ ↦ congr_arg num
```

-- snippet 27
```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 28
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_nnratCast (L48-L57)
theorem cast_nnratCast {K} [DivisionRing K] (q : ℚ≥0) :
    ((q : ℚ) : K) = (q : K) := by
rw [Rat.cast_def, NNRat.cast_def, NNRat.cast_def]
  have hn := @num_div_eq_of_coprime q.num q.den ?hdp q.coprime_num_den
  on_goal 1 => have hd := @den_div_eq_of_coprime q.num q.den ?hdp q.coprime_num_den
  case hdp => simpa only [Int.natCast_pos] using q.den_pos
  simp only [Int.cast_natCast, Nat.cast_inj] at hn hd
  rw [hn, hd, Int.cast_natCast]

/-- Casting a scientific literal via `ℚ` is the same as casting directly. -/
```

-- snippet 29
```lean
-- Mathlib.Data.Rat.Defs.num_neg_eq_neg_num (L207-L210)
theorem num_neg_eq_neg_num (q : ℚ) : (-q).num = -q.num :=
rfl

-- Not `@[simp]` as `num_ofNat` is stronger.
```

-- snippet 30
```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 31
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ioc (L111-L113)
theorem preimage_cast_Ioc (p q : ℚ) : (↑) ⁻¹' Ioc (p : K) q = Ioc p q :=
castOrderEmbedding.preimage_Ioc p q
```

-- snippet 32
```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 33
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_pow (L30-L33)
lemma cast_pow (p : ℚ) (n : ℕ) : ↑(p ^ n) = (p ^ n : α) := by
rw [cast_def, cast_def, den_pow, num_pow, Nat.cast_pow, Int.cast_pow, div_eq_mul_inv, ← inv_pow,
    ← (Int.cast_commute _ _).mul_pow, ← div_eq_mul_inv]
```

-- snippet 34
```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 35
```lean
-- Mathlib.Data.Rat.Defs.commSemigroup (L198-L199)
instance commSemigroup : CommSemigroup ℚ := by infer_instance
```

-- snippet 36
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_inv_nat (L35-L40)
theorem cast_inv_nat (n : ℕ) : ((n⁻¹ : ℚ) : α) = (n : α)⁻¹ := by
rcases n with - | n
  · simp
  rw [cast_def, inv_natCast_num, inv_natCast_den, if_neg n.succ_ne_zero,
    Int.sign_eq_one_of_pos (Int.ofNat_succ_pos n), Int.cast_one, one_div]
```

-- snippet 37
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Icc (L103-L105)
theorem preimage_cast_Icc (p q : ℚ) : (↑) ⁻¹' Icc (p : K) q = Icc p q :=
castOrderEmbedding.preimage_Icc ..
```

-- snippet 38
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_mk (L82-L87)
theorem cast_mk {K} [DivisionRing K] (q : ℚ) (h : 0 ≤ q) :
    (NNRat.cast ⟨q, h⟩ : K) = (q : K) := by
simp only [NNRat.cast_def, NNRat.num_mk, Nat.cast_natAbs, NNRat.den_mk, Rat.cast_def]
  rw [abs_of_nonneg (by simpa)]

open OfScientific in
```

-- snippet 39
```lean
-- Mathlib.Data.Rat.Defs.divInt_eq_zero (L76-L78)
theorem divInt_eq_zero {a b : ℤ} (b0 : b ≠ 0) : a /. b = 0 ↔ a = 0 := by
rw [← zero_divInt b, divInt_eq_divInt_iff b0 b0, Int.zero_mul, Int.mul_eq_zero, or_iff_left b0]
```

-- snippet 40
```lean
-- Mathlib.Data.Rat.Defs.commMonoid (L187-L195)
instance commMonoid : CommMonoid ℚ where
  mul_one := Rat.mul_one
one_mul := Rat.one_mul
  mul_comm := Rat.mul_comm
  mul_assoc := Rat.mul_assoc
  npow n q := q ^ n
  npow_zero := Rat.pow_zero
  npow_succ n q := Rat.pow_succ q n
```

-- snippet 41
```lean
-- Mathlib.Data.Rat.Defs.addSemigroup (L185-L186)
instance addSemigroup : AddSemigroup ℚ := by infer_instance
```

-- snippet 42
```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 43
```lean
-- Mathlib.Data.Rat.Defs.divInt_ne_zero (L79-L84)
theorem divInt_ne_zero {a b : ℤ} (b0 : b ≠ 0) : a /. b ≠ 0 ↔ a ≠ 0 :=
(divInt_eq_zero b0).not

-- TODO: Rename `mkRat_num_den` in Lean core
alias mkRat_num_den' := mkRat_self
```

-- snippet 44
```lean
-- Mathlib.Data.Rat.Defs.addCommGroup (L155-L172)
instance addCommGroup : AddCommGroup ℚ where
  zero_add := Rat.zero_add
add_zero := Rat.add_zero
  add_comm := Rat.add_comm
  add_assoc := Rat.add_assoc
  neg_add_cancel := Rat.neg_add_cancel
  sub_eq_add_neg := Rat.sub_eq_add_neg
  nsmul := (· * ·)
  zsmul := (· * ·)
  nsmul_zero := Rat.zero_mul
  nsmul_succ n q := by
    change ((n + 1 : Int) : Rat) * q = _
    rw [Rat.intCast_add, Rat.add_mul, Rat.intCast_one, Rat.one_mul]
    rfl
  zsmul_zero' := Rat.zero_mul
  zsmul_succ' _ _ := by simp [Rat.add_mul]
  zsmul_neg' _ _ := by rw [Int.negSucc_eq, Rat.intCast_neg, Rat.neg_mul]; rfl
```

-- snippet 45
```lean
-- Mathlib.Data.Rat.Defs.addLeftCancelSemigroup (L179-L180)
instance addLeftCancelSemigroup : AddLeftCancelSemigroup ℚ := by infer_instance
```

-- snippet 46
```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 47
```lean
-- Mathlib.Data.Rat.Defs.mul_eq_mkRat (L115-L117)
lemma mul_eq_mkRat (q r : ℚ) : q * r = mkRat (q.num * r.num) (q.den * r.den) := by
rw [mul_def, normalize_eq_mkRat]
```

-- snippet 48
```lean
-- Mathlib.Data.Rat.Defs.natCast_injective (L53-L55)
lemma natCast_injective : Injective (Nat.cast : ℕ → ℚ) :=
intCast_injective.comp fun _ _ ↦ Int.natCast_inj.1
```

-- snippet 49
```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 50
```lean
-- Mathlib.Data.Rat.Defs.div_def' (L135-L139)
lemma div_def' (q r : ℚ) : q / r = (q.num * r.den) /. (q.den * r.num) := by
rw [← divInt_div_divInt, num_divInt_den, num_divInt_den]

variable (a b c : ℚ)
```

-- snippet 51
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.Nonneg (L88-L92)
theorem Nonneg.coe_ofScientific {K} [Field K] [LinearOrder K] [IsStrictOrderedRing K]
    (m : ℕ) (s : Bool) (e : ℕ) :
    (ofScientific m s e : {x : K // 0 ≤ x}).val = ofScientific m s e := rfl
end NNRat
```

-- snippet 52
```lean
-- Mathlib.Data.Rat.Defs.monoid (L196-L197)
instance monoid : Monoid ℚ := by infer_instance
```

-- snippet 53
```lean
-- Mathlib.Data.Rat.Defs.den_neg_eq_den (L203-L205)
theorem den_neg_eq_den (q : ℚ) : (-q).den = q.den :=
rfl
```

-- snippet 54
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Iio (L131-L133)
theorem preimage_cast_Iio (q : ℚ) : (↑) ⁻¹' Iio (q : K) = Iio q :=
castOrderEmbedding.preimage_Iio q
```

-- snippet 55
```lean
-- Mathlib.Data.Rat.Defs.semigroup (L200-L201)
instance semigroup : Semigroup ℚ := by infer_instance
```

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

-- snippet 57
```lean
-- Mathlib.Data.Rat.Defs.mk'_num_den (L46-L47)
lemma mk'_num_den (q : ℚ) : mk' q.num q.den q.den_nz q.reduced = q := rfl
```

-- snippet 58
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_zpow_of_ne_zero (L73-L80)
theorem cast_zpow_of_ne_zero {K} [DivisionSemiring K] (q : ℚ≥0) (z : ℤ) (hq : (q.num : K) ≠ 0) :
    NNRat.cast (q ^ z) = (NNRat.cast q : K) ^ z := by
obtain ⟨n, rfl | rfl⟩ := z.eq_nat_or_neg
  · simp
  · simp_rw [zpow_neg, zpow_natCast, ← inv_pow, NNRat.cast_pow]
    congr
    rw [cast_inv_of_ne_zero hq]
```

-- snippet 59
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_ofScientific (L59-L66)
theorem cast_ofScientific {K} [DivisionRing K] (m : ℕ) (s : Bool) (e : ℕ) :
    (OfScientific.ofScientific m s e : ℚ) = (OfScientific.ofScientific m s e : K) := by
rw [← NNRat.cast_ofScientific (K := K), ← NNRat.cast_ofScientific, cast_nnratCast]

end Rat

namespace NNRat
```

-- snippet 60
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ioi (L127-L129)
theorem preimage_cast_Ioi (q : ℚ) : (↑) ⁻¹' Ioi (q : K) = Ioi q :=
castOrderEmbedding.preimage_Ioi q
```

-- snippet 61
```lean
-- Mathlib.Data.Rat.Defs.addCommSemigroup (L183-L184)
instance addCommSemigroup : AddCommSemigroup ℚ := by infer_instance
```

-- snippet 62
```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 63
```lean
-- Mathlib.Data.Rat.Defs.ofInt_eq_cast (L49-L51)
theorem ofInt_eq_cast (n : ℤ) : ofInt n = Int.cast n :=
rfl
```

-- snippet 64
```lean
-- Mathlib.Data.Rat.Defs.neg_def (L105-L106)
lemma neg_def (q : ℚ) : -q = -q.num /. q.den := by rw [← neg_divInt, num_divInt_den]
```

-- snippet 65
```lean
-- Mathlib.Data.Rat.Defs.pos (L44-L45)
theorem pos (a : ℚ) : 0 < a.den := Nat.pos_of_ne_zero a.den_nz
```

-- snippet 66
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_uIoc (L139-L148)
theorem preimage_cast_uIoc (p q : ℚ) : (↑) ⁻¹' uIoc (p : K) q = uIoc p q :=
(castOrderEmbedding (K := K)).preimage_uIoc p q

end LinearOrderedField
end Rat

namespace NNRat

variable {K} [Semifield K] [LinearOrder K] [IsStrictOrderedRing K] {p q : ℚ≥0}
```

-- snippet 67
```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 68
```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 69
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_uIcc (L135-L137)
theorem preimage_cast_uIcc (p q : ℚ) : (↑) ⁻¹' uIcc (p : K) q = uIcc p q :=
(castOrderEmbedding (K := K)).preimage_uIcc p q
```

-- snippet 70
```lean
-- Mathlib.Data.Rat.Defs.divInt_one_one (L142-L146)
lemma divInt_one_one : 1 /. 1 = 1 := by rw [divInt_one, Rat.intCast_one]
protected theorem zero_ne_one : 0 ≠ (1 : ℚ) := by
  rw [ne_comm, ← divInt_one_one, divInt_ne_zero] <;> lia
```

-- snippet 71
```lean
-- Mathlib.Data.Rat.Defs.mkRat_eq_divInt (L67-L68)
lemma mkRat_eq_divInt (n d) : mkRat n d = n /. d := rfl
```

-- snippet 72
```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 73
```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
```

-- snippet 74
```lean
-- Mathlib.Data.Rat.Defs.addMonoid (L177-L178)
instance addMonoid : AddMonoid ℚ := by infer_instance
```

-- snippet 75
```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 76
```lean
-- Mathlib.Data.Rat.Defs.mk'_mul_mk' (L109-L114)
lemma mk'_mul_mk' (n₁ n₂ : ℤ) (d₁ d₂ : ℕ) (hd₁ hd₂ hnd₁ hnd₂) (h₁₂ : n₁.natAbs.Coprime d₂)
    (h₂₁ : n₂.natAbs.Coprime d₁) :
    mk' n₁ d₁ hd₁ hnd₁ * mk' n₂ d₂ hd₂ hnd₂ = mk' (n₁ * n₂) (d₁ * d₂) (Nat.mul_ne_zero hd₁ hd₂) (by
      rw [Int.natAbs_mul]; exact (hnd₁.mul_left h₂₁).mul_right (h₁₂.mul_left hnd₂)) := by
rw [mul_def]; simp [mk_eq_normalize]
```

-- snippet 77
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ico (L107-L109)
theorem preimage_cast_Ico (p q : ℚ) : (↑) ⁻¹' Ico (p : K) q = Ico p q :=
castOrderEmbedding.preimage_Ico ..
```

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

-- snippet 79
```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 80
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Iic (L123-L125)
theorem preimage_cast_Iic (q : ℚ) : (↑) ⁻¹' Iic (q : K) = Iic q :=
castOrderEmbedding.preimage_Iic q
```

-- snippet 81
```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 82
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_ne_zero (L40-L41)
lemma cast_ne_zero : (p : α) ≠ 0 ↔ p ≠ 0 := cast_eq_zero.ne
```

-- snippet 83
```lean
-- Mathlib.Data.Rat.Defs.num_zero (L211-L214)
theorem num_zero : Rat.num 0 = 0 :=
rfl

-- Not `@[simp]` as `den_ofNat` is stronger.
```

-- snippet 84
```lean
-- Mathlib.Data.Rat.Defs.addRightCancelSemigroup (L181-L182)
instance addRightCancelSemigroup : AddRightCancelSemigroup ℚ := by infer_instance
```

-- snippet 85
```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 86
```lean
-- Mathlib.Data.Rat.Defs.addGroup (L173-L174)
instance addGroup : AddGroup ℚ := by infer_instance
```

-- snippet 87
```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 88
```lean
-- Mathlib.Data.Rat.Defs.nontrivial (L151-L154)
instance nontrivial : Nontrivial ℚ where exists_pair_ne := ⟨1, 0, by decide⟩
/-! ### The rational numbers are a group -/
```

-- snippet 89
```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 90
```lean
-- Mathlib.Data.Rat.Defs.pow_eq_mkRat (L118-L120)
lemma pow_eq_mkRat (q : ℚ) (n : ℕ) : q ^ n = mkRat (q.num ^ n) (q.den ^ n) := by
rw [pow_def, mk_eq_mkRat]
```

-- snippet 91
```lean
-- Mathlib.Data.Rat.Defs.num_ne_zero (L71-L72)
lemma num_ne_zero {q : ℚ} : q.num ≠ 0 ↔ q ≠ 0 := num_eq_zero.not
```

-- snippet 92
```lean
-- Mathlib.Data.Rat.Defs.intCast_eq_divInt (L85-L86)
theorem intCast_eq_divInt (z : ℤ) : (z : ℚ) = z /. 1 := mk_eq_divInt
```

-- snippet 93
```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 94
```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 95
```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 96
```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 97
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ioo (L115-L117)
theorem preimage_cast_Ioo (p q : ℚ) : (↑) ⁻¹' Ioo (p : K) q = Ioo p q :=
castOrderEmbedding.preimage_Ioo p q
```

-- snippet 98
```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 99
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ici (L119-L121)
theorem preimage_cast_Ici (q : ℚ) : (↑) ⁻¹' Ici (q : K) = Ici q :=
castOrderEmbedding.preimage_Ici q
```

-- snippet 100
```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 101
```lean
-- Mathlib.Data.Rat.Defs.pow_eq_divInt (L121-L123)
lemma pow_eq_divInt (q : ℚ) (n : ℕ) : q ^ n = q.num ^ n /. q.den ^ n := by
rw [pow_def, mk_eq_divInt, Int.natCast_pow]
```

-- snippet 102
```lean
-- Mathlib.Data.Rat.Defs.lift_binop_eq (L87-L104)
theorem lift_binop_eq (f : ℚ → ℚ → ℚ) (f₁ : ℤ → ℤ → ℤ → ℤ → ℤ) (f₂ : ℤ → ℤ → ℤ → ℤ → ℤ)
    (fv :
      ∀ {n₁ d₁ h₁ c₁ n₂ d₂ h₂ c₂},
        f ⟨n₁, d₁, h₁, c₁⟩ ⟨n₂, d₂, h₂, c₂⟩ = f₁ n₁ d₁ n₂ d₂ /. f₂ n₁ d₁ n₂ d₂)
    (f0 : ∀ {n₁ d₁ n₂ d₂}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0) (a b c d : ℤ)
    (b0 : b ≠ 0) (d0 : d ≠ 0)
    (H :
      ∀ {n₁ d₁ n₂ d₂}, a * d₁ = n₁ * b → c * d₂ = n₂ * d →
        f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂) :
    f (a /. b) (c /. d) = f₁ a b c d /. f₂ a b c d := by
generalize ha : a /. b = x; obtain ⟨n₁, d₁, h₁, c₁⟩ := x; rw [mk_eq_divInt] at ha
  generalize hc : c /. d = x; obtain ⟨n₂, d₂, h₂, c₂⟩ := x; rw [mk_eq_divInt] at hc
  rw [fv]
  have d₁0 := Int.ofNat_ne_zero.2 h₁
  have d₂0 := Int.ofNat_ne_zero.2 h₂
  exact (divInt_eq_divInt_iff (f0 d₁0 d₂0) (f0 b0 d0)).2
    (H ((divInt_eq_divInt_iff b0 d₁0).1 ha) ((divInt_eq_divInt_iff d0 d₂0).1 hc))
```

-- snippet 103
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_inv_int (L42-L46)
theorem cast_inv_int (n : ℤ) : ((n⁻¹ : ℚ) : α) = (n : α)⁻¹ := by
rcases n with n | n
  · simp [cast_inv_nat]
  · simp only [Int.cast_negSucc, cast_neg, inv_neg, cast_inv_nat]
```

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

-- snippet 105
```lean
-- Mathlib.Data.Rat.Defs.addCommMonoid (L175-L176)
instance addCommMonoid : AddCommMonoid ℚ := by infer_instance
```

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

```lean
theorem cast_natCast (n : ℕ) : ((n : ℚ) : α) = n
```

## Retrieved context
-- snippet 1
```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 2
```lean
-- Mathlib.Data.Rat.Cast.Defs.commute_cast (L49-L50)
lemma commute_cast (a : α) (q : ℚ≥0) : Commute a q := (cast_commute ..).symm
```

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

-- snippet 4
```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 5
```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 6
```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 7
```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 8
```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 9
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_zero (L126-L128)
theorem cast_zero : ((0 : ℚ) : α) = 0 :=
(cast_intCast _).trans Int.cast_zero
```

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

-- snippet 11
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_commute (L133-L135)
theorem cast_commute (r : ℚ) (a : α) : Commute (↑r) a := by
simpa only [cast_def] using (r.1.cast_commute a).div_left (r.2.cast_commute a)
```

-- snippet 12
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_comm (L136-L138)
theorem cast_comm (r : ℚ) (a : α) : (r : α) * a = a * r :=
(cast_commute r a).eq
```

-- snippet 13
```lean
-- Mathlib.Data.Rat.Cast.Defs.commute_cast (L139-L141)
theorem commute_cast (a : α) (r : ℚ) : Commute a r :=
(r.cast_commute a).symm
```

-- snippet 14
```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 15
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_mkRat_of_ne_zero (L163-L165)
lemma cast_mkRat_of_ne_zero (a : ℤ) {b : ℕ} (hb : (b : α) ≠ 0) : (mkRat a b : α) = a / b := by
rw [Rat.mkRat_eq_divInt, cast_divInt_of_ne_zero, Int.cast_natCast]; rwa [Int.cast_natCast]
```

-- snippet 16
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_add_of_ne_zero (L167-L175)
lemma cast_add_of_ne_zero {q r : ℚ} (hq : (q.den : α) ≠ 0) (hr : (r.den : α) ≠ 0) :
    (q + r : ℚ) = (q + r : α) := by
rw [add_def', cast_mkRat_of_ne_zero, cast_def, cast_def, mul_comm r.num,
    (Nat.cast_commute _ _).div_add_div (Nat.commute_cast _ _) hq hr]
  · push_cast
    rfl
  · push_cast
    exact mul_ne_zero hq hr
```

-- snippet 17
```lean
-- Mathlib.Data.Rat.Cast.Defs.cast_inv_of_ne_zero (L191-L193)
lemma cast_inv_of_ne_zero (hq : (q.num : α) ≠ 0) : ↑(q⁻¹) = (q⁻¹ : α) := by
rw [inv_def, cast_divInt_of_ne_zero _ hq, cast_def, inv_div, Int.cast_natCast]
```

-- snippet 18
```lean
-- Mathlib.Data.Rat.Cast.Defs.eq_nnratCast (L213-L215)
lemma eq_nnratCast [DivisionSemiring α] [FunLike F ℚ≥0 α] [RingHomClass F ℚ≥0 α] (f : F) (q : ℚ≥0) :
    f q = q := by rw [← map_nnratCast f, NNRat.cast_id]
```

-- snippet 19
```lean
-- Mathlib.Data.Rat.Cast.Defs.map_ratCast (L217-L219)
theorem map_ratCast [DivisionRing α] [DivisionRing β] [RingHomClass F α β] (f : F) (q : ℚ) :
    f q = q := by rw [cast_def, map_div₀, map_intCast, map_natCast, cast_def]
```

-- snippet 20
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_nnrat' (L231-L238)
lemma ext_nnrat' (h : ∀ n : ℕ, f n = g n) : f = g :=
(DFunLike.ext f g) fun r => by
    rw [← r.num_div_den, div_eq_mul_inv, map_mul, map_mul, h, eq_on_inv₀ f g]
    apply h

/-- If monoid with zero homs `f` and `g` from `ℚ≥0` agree on the naturals then they are equal.

See note [partially-applied ext lemmas] for why `comp` is used here. -/
```

-- snippet 21
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_nnrat (L240-L245)
lemma ext_nnrat {f g : ℚ≥0 →*₀ M₀}
    (h : f.comp (Nat.castRingHom ℚ≥0 : ℕ →*₀ ℚ≥0) = g.comp (Nat.castRingHom ℚ≥0)) : f = g :=
ext_nnrat' <| DFunLike.congr_fun h

/-- If monoid with zero homs `f` and `g` from `ℚ≥0` agree on the positive naturals then they are
equal. -/
```

-- snippet 22
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_nnrat_on_pnat (L246-L256)
lemma ext_nnrat_on_pnat (same_on_pnat : ∀ n : ℕ, 0 < n → f n = g n) : f = g :=
ext_nnrat' <| DFunLike.congr_fun <| ext_nat''
    ((f : ℚ≥0 →*₀ M₀).comp (Nat.castRingHom ℚ≥0 : ℕ →*₀ ℚ≥0))
    ((g : ℚ≥0 →*₀ M₀).comp (Nat.castRingHom ℚ≥0 : ℕ →*₀ ℚ≥0)) (by simpa)

end NNRat

section Rat
variable [FunLike F ℚ M₀] [MonoidWithZeroHomClass F ℚ M₀] {f g : F}

/-- If monoid with zero homs `f` and `g` from `ℚ` agree on the integers then they are equal. -/
```

-- snippet 23
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_rat' (L257-L265)
theorem ext_rat' (h : ∀ m : ℤ, f m = g m) : f = g :=
(DFunLike.ext f g) fun r => by
    rw [← r.num_div_den, div_eq_mul_inv, map_mul, map_mul, h, ← Int.cast_natCast,
      eq_on_inv₀ f g]
    apply h

/-- If monoid with zero homs `f` and `g` from `ℚ` agree on the integers then they are equal.

See note [partially-applied ext lemmas] for why `comp` is used here. -/
```

-- snippet 24
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_rat (L267-L272)
theorem ext_rat {f g : ℚ →*₀ M₀}
    (h : f.comp (Int.castRingHom ℚ : ℤ →*₀ ℚ) = g.comp (Int.castRingHom ℚ)) : f = g :=
ext_rat' <| DFunLike.congr_fun h

/-- If monoid with zero homs `f` and `g` from `ℚ` agree on the positive naturals and `-1` then
they are equal. -/
```

-- snippet 25
```lean
-- Mathlib.Data.Rat.Cast.Defs.ext_rat_on_pnat (L273-L286)
theorem ext_rat_on_pnat (same_on_neg_one : f (-1) = g (-1))
    (same_on_pnat : ∀ n : ℕ, 0 < n → f n = g n) : f = g :=
ext_rat' <|
    DFunLike.congr_fun <|
      show
        (f : ℚ →*₀ M₀).comp (Int.castRingHom ℚ : ℤ →*₀ ℚ) =
          (g : ℚ →*₀ M₀).comp (Int.castRingHom ℚ : ℤ →*₀ ℚ)
        from ext_int' (by simpa) (by simpa)

end Rat
end MonoidWithZeroHomClass

/-- Any two ring homomorphisms from `ℚ` to a semiring are equal. If the codomain is a division ring,
then this lemma follows from `eq_ratCast`. -/
```

-- snippet 26
```lean
-- Mathlib.Data.Rat.Defs.intCast_injective (L52-L52)
lemma intCast_injective : Injective (Int.cast : ℤ → ℚ) := fun _ _ ↦ congr_arg num
```

-- snippet 27
```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 28
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_nnratCast (L48-L57)
theorem cast_nnratCast {K} [DivisionRing K] (q : ℚ≥0) :
    ((q : ℚ) : K) = (q : K) := by
rw [Rat.cast_def, NNRat.cast_def, NNRat.cast_def]
  have hn := @num_div_eq_of_coprime q.num q.den ?hdp q.coprime_num_den
  on_goal 1 => have hd := @den_div_eq_of_coprime q.num q.den ?hdp q.coprime_num_den
  case hdp => simpa only [Int.natCast_pos] using q.den_pos
  simp only [Int.cast_natCast, Nat.cast_inj] at hn hd
  rw [hn, hd, Int.cast_natCast]

/-- Casting a scientific literal via `ℚ` is the same as casting directly. -/
```

-- snippet 29
```lean
-- Mathlib.Data.Rat.Defs.num_neg_eq_neg_num (L207-L210)
theorem num_neg_eq_neg_num (q : ℚ) : (-q).num = -q.num :=
rfl

-- Not `@[simp]` as `num_ofNat` is stronger.
```

-- snippet 30
```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 31
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ioc (L111-L113)
theorem preimage_cast_Ioc (p q : ℚ) : (↑) ⁻¹' Ioc (p : K) q = Ioc p q :=
castOrderEmbedding.preimage_Ioc p q
```

-- snippet 32
```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 33
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_pow (L30-L33)
lemma cast_pow (p : ℚ) (n : ℕ) : ↑(p ^ n) = (p ^ n : α) := by
rw [cast_def, cast_def, den_pow, num_pow, Nat.cast_pow, Int.cast_pow, div_eq_mul_inv, ← inv_pow,
    ← (Int.cast_commute _ _).mul_pow, ← div_eq_mul_inv]
```

-- snippet 34
```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 35
```lean
-- Mathlib.Data.Rat.Defs.commSemigroup (L198-L199)
instance commSemigroup : CommSemigroup ℚ := by infer_instance
```

-- snippet 36
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_inv_nat (L35-L40)
theorem cast_inv_nat (n : ℕ) : ((n⁻¹ : ℚ) : α) = (n : α)⁻¹ := by
rcases n with - | n
  · simp
  rw [cast_def, inv_natCast_num, inv_natCast_den, if_neg n.succ_ne_zero,
    Int.sign_eq_one_of_pos (Int.ofNat_succ_pos n), Int.cast_one, one_div]
```

-- snippet 37
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Icc (L103-L105)
theorem preimage_cast_Icc (p q : ℚ) : (↑) ⁻¹' Icc (p : K) q = Icc p q :=
castOrderEmbedding.preimage_Icc ..
```

-- snippet 38
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_mk (L82-L87)
theorem cast_mk {K} [DivisionRing K] (q : ℚ) (h : 0 ≤ q) :
    (NNRat.cast ⟨q, h⟩ : K) = (q : K) := by
simp only [NNRat.cast_def, NNRat.num_mk, Nat.cast_natAbs, NNRat.den_mk, Rat.cast_def]
  rw [abs_of_nonneg (by simpa)]

open OfScientific in
```

-- snippet 39
```lean
-- Mathlib.Data.Rat.Defs.divInt_eq_zero (L76-L78)
theorem divInt_eq_zero {a b : ℤ} (b0 : b ≠ 0) : a /. b = 0 ↔ a = 0 := by
rw [← zero_divInt b, divInt_eq_divInt_iff b0 b0, Int.zero_mul, Int.mul_eq_zero, or_iff_left b0]
```

-- snippet 40
```lean
-- Mathlib.Data.Rat.Defs.commMonoid (L187-L195)
instance commMonoid : CommMonoid ℚ where
  mul_one := Rat.mul_one
one_mul := Rat.one_mul
  mul_comm := Rat.mul_comm
  mul_assoc := Rat.mul_assoc
  npow n q := q ^ n
  npow_zero := Rat.pow_zero
  npow_succ n q := Rat.pow_succ q n
```

-- snippet 41
```lean
-- Mathlib.Data.Rat.Defs.addSemigroup (L185-L186)
instance addSemigroup : AddSemigroup ℚ := by infer_instance
```

-- snippet 42
```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 43
```lean
-- Mathlib.Data.Rat.Defs.divInt_ne_zero (L79-L84)
theorem divInt_ne_zero {a b : ℤ} (b0 : b ≠ 0) : a /. b ≠ 0 ↔ a ≠ 0 :=
(divInt_eq_zero b0).not

-- TODO: Rename `mkRat_num_den` in Lean core
alias mkRat_num_den' := mkRat_self
```

-- snippet 44
```lean
-- Mathlib.Data.Rat.Defs.addCommGroup (L155-L172)
instance addCommGroup : AddCommGroup ℚ where
  zero_add := Rat.zero_add
add_zero := Rat.add_zero
  add_comm := Rat.add_comm
  add_assoc := Rat.add_assoc
  neg_add_cancel := Rat.neg_add_cancel
  sub_eq_add_neg := Rat.sub_eq_add_neg
  nsmul := (· * ·)
  zsmul := (· * ·)
  nsmul_zero := Rat.zero_mul
  nsmul_succ n q := by
    change ((n + 1 : Int) : Rat) * q = _
    rw [Rat.intCast_add, Rat.add_mul, Rat.intCast_one, Rat.one_mul]
    rfl
  zsmul_zero' := Rat.zero_mul
  zsmul_succ' _ _ := by simp [Rat.add_mul]
  zsmul_neg' _ _ := by rw [Int.negSucc_eq, Rat.intCast_neg, Rat.neg_mul]; rfl
```

-- snippet 45
```lean
-- Mathlib.Data.Rat.Defs.addLeftCancelSemigroup (L179-L180)
instance addLeftCancelSemigroup : AddLeftCancelSemigroup ℚ := by infer_instance
```

-- snippet 46
```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 47
```lean
-- Mathlib.Data.Rat.Defs.mul_eq_mkRat (L115-L117)
lemma mul_eq_mkRat (q r : ℚ) : q * r = mkRat (q.num * r.num) (q.den * r.den) := by
rw [mul_def, normalize_eq_mkRat]
```

-- snippet 48
```lean
-- Mathlib.Data.Rat.Defs.natCast_injective (L53-L55)
lemma natCast_injective : Injective (Nat.cast : ℕ → ℚ) :=
intCast_injective.comp fun _ _ ↦ Int.natCast_inj.1
```

-- snippet 49
```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 50
```lean
-- Mathlib.Data.Rat.Defs.div_def' (L135-L139)
lemma div_def' (q r : ℚ) : q / r = (q.num * r.den) /. (q.den * r.num) := by
rw [← divInt_div_divInt, num_divInt_den, num_divInt_den]

variable (a b c : ℚ)
```

-- snippet 51
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.Nonneg (L88-L92)
theorem Nonneg.coe_ofScientific {K} [Field K] [LinearOrder K] [IsStrictOrderedRing K]
    (m : ℕ) (s : Bool) (e : ℕ) :
    (ofScientific m s e : {x : K // 0 ≤ x}).val = ofScientific m s e := rfl
end NNRat
```

-- snippet 52
```lean
-- Mathlib.Data.Rat.Defs.monoid (L196-L197)
instance monoid : Monoid ℚ := by infer_instance
```

-- snippet 53
```lean
-- Mathlib.Data.Rat.Defs.den_neg_eq_den (L203-L205)
theorem den_neg_eq_den (q : ℚ) : (-q).den = q.den :=
rfl
```

-- snippet 54
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Iio (L131-L133)
theorem preimage_cast_Iio (q : ℚ) : (↑) ⁻¹' Iio (q : K) = Iio q :=
castOrderEmbedding.preimage_Iio q
```

-- snippet 55
```lean
-- Mathlib.Data.Rat.Defs.semigroup (L200-L201)
instance semigroup : Semigroup ℚ := by infer_instance
```

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

-- snippet 57
```lean
-- Mathlib.Data.Rat.Defs.mk'_num_den (L46-L47)
lemma mk'_num_den (q : ℚ) : mk' q.num q.den q.den_nz q.reduced = q := rfl
```

-- snippet 58
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_zpow_of_ne_zero (L73-L80)
theorem cast_zpow_of_ne_zero {K} [DivisionSemiring K] (q : ℚ≥0) (z : ℤ) (hq : (q.num : K) ≠ 0) :
    NNRat.cast (q ^ z) = (NNRat.cast q : K) ^ z := by
obtain ⟨n, rfl | rfl⟩ := z.eq_nat_or_neg
  · simp
  · simp_rw [zpow_neg, zpow_natCast, ← inv_pow, NNRat.cast_pow]
    congr
    rw [cast_inv_of_ne_zero hq]
```

-- snippet 59
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_ofScientific (L59-L66)
theorem cast_ofScientific {K} [DivisionRing K] (m : ℕ) (s : Bool) (e : ℕ) :
    (OfScientific.ofScientific m s e : ℚ) = (OfScientific.ofScientific m s e : K) := by
rw [← NNRat.cast_ofScientific (K := K), ← NNRat.cast_ofScientific, cast_nnratCast]

end Rat

namespace NNRat
```

-- snippet 60
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ioi (L127-L129)
theorem preimage_cast_Ioi (q : ℚ) : (↑) ⁻¹' Ioi (q : K) = Ioi q :=
castOrderEmbedding.preimage_Ioi q
```

-- snippet 61
```lean
-- Mathlib.Data.Rat.Defs.addCommSemigroup (L183-L184)
instance addCommSemigroup : AddCommSemigroup ℚ := by infer_instance
```

-- snippet 62
```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 63
```lean
-- Mathlib.Data.Rat.Defs.ofInt_eq_cast (L49-L51)
theorem ofInt_eq_cast (n : ℤ) : ofInt n = Int.cast n :=
rfl
```

-- snippet 64
```lean
-- Mathlib.Data.Rat.Defs.neg_def (L105-L106)
lemma neg_def (q : ℚ) : -q = -q.num /. q.den := by rw [← neg_divInt, num_divInt_den]
```

-- snippet 65
```lean
-- Mathlib.Data.Rat.Defs.pos (L44-L45)
theorem pos (a : ℚ) : 0 < a.den := Nat.pos_of_ne_zero a.den_nz
```

-- snippet 66
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_uIoc (L139-L148)
theorem preimage_cast_uIoc (p q : ℚ) : (↑) ⁻¹' uIoc (p : K) q = uIoc p q :=
(castOrderEmbedding (K := K)).preimage_uIoc p q

end LinearOrderedField
end Rat

namespace NNRat

variable {K} [Semifield K] [LinearOrder K] [IsStrictOrderedRing K] {p q : ℚ≥0}
```

-- snippet 67
```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 68
```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 69
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_uIcc (L135-L137)
theorem preimage_cast_uIcc (p q : ℚ) : (↑) ⁻¹' uIcc (p : K) q = uIcc p q :=
(castOrderEmbedding (K := K)).preimage_uIcc p q
```

-- snippet 70
```lean
-- Mathlib.Data.Rat.Defs.divInt_one_one (L142-L146)
lemma divInt_one_one : 1 /. 1 = 1 := by rw [divInt_one, Rat.intCast_one]
protected theorem zero_ne_one : 0 ≠ (1 : ℚ) := by
  rw [ne_comm, ← divInt_one_one, divInt_ne_zero] <;> lia
```

-- snippet 71
```lean
-- Mathlib.Data.Rat.Defs.mkRat_eq_divInt (L67-L68)
lemma mkRat_eq_divInt (n d) : mkRat n d = n /. d := rfl
```

-- snippet 72
```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 73
```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
```

-- snippet 74
```lean
-- Mathlib.Data.Rat.Defs.addMonoid (L177-L178)
instance addMonoid : AddMonoid ℚ := by infer_instance
```

-- snippet 75
```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 76
```lean
-- Mathlib.Data.Rat.Defs.mk'_mul_mk' (L109-L114)
lemma mk'_mul_mk' (n₁ n₂ : ℤ) (d₁ d₂ : ℕ) (hd₁ hd₂ hnd₁ hnd₂) (h₁₂ : n₁.natAbs.Coprime d₂)
    (h₂₁ : n₂.natAbs.Coprime d₁) :
    mk' n₁ d₁ hd₁ hnd₁ * mk' n₂ d₂ hd₂ hnd₂ = mk' (n₁ * n₂) (d₁ * d₂) (Nat.mul_ne_zero hd₁ hd₂) (by
      rw [Int.natAbs_mul]; exact (hnd₁.mul_left h₂₁).mul_right (h₁₂.mul_left hnd₂)) := by
rw [mul_def]; simp [mk_eq_normalize]
```

-- snippet 77
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ico (L107-L109)
theorem preimage_cast_Ico (p q : ℚ) : (↑) ⁻¹' Ico (p : K) q = Ico p q :=
castOrderEmbedding.preimage_Ico ..
```

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

-- snippet 79
```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 80
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Iic (L123-L125)
theorem preimage_cast_Iic (q : ℚ) : (↑) ⁻¹' Iic (q : K) = Iic q :=
castOrderEmbedding.preimage_Iic q
```

-- snippet 81
```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 82
```lean
-- Mathlib.Data.Rat.Cast.CharZero.cast_ne_zero (L40-L41)
lemma cast_ne_zero : (p : α) ≠ 0 ↔ p ≠ 0 := cast_eq_zero.ne
```

-- snippet 83
```lean
-- Mathlib.Data.Rat.Defs.num_zero (L211-L214)
theorem num_zero : Rat.num 0 = 0 :=
rfl

-- Not `@[simp]` as `den_ofNat` is stronger.
```

-- snippet 84
```lean
-- Mathlib.Data.Rat.Defs.addRightCancelSemigroup (L181-L182)
instance addRightCancelSemigroup : AddRightCancelSemigroup ℚ := by infer_instance
```

-- snippet 85
```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 86
```lean
-- Mathlib.Data.Rat.Defs.addGroup (L173-L174)
instance addGroup : AddGroup ℚ := by infer_instance
```

-- snippet 87
```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 88
```lean
-- Mathlib.Data.Rat.Defs.nontrivial (L151-L154)
instance nontrivial : Nontrivial ℚ where exists_pair_ne := ⟨1, 0, by decide⟩
/-! ### The rational numbers are a group -/
```

-- snippet 89
```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 90
```lean
-- Mathlib.Data.Rat.Defs.pow_eq_mkRat (L118-L120)
lemma pow_eq_mkRat (q : ℚ) (n : ℕ) : q ^ n = mkRat (q.num ^ n) (q.den ^ n) := by
rw [pow_def, mk_eq_mkRat]
```

-- snippet 91
```lean
-- Mathlib.Data.Rat.Defs.num_ne_zero (L71-L72)
lemma num_ne_zero {q : ℚ} : q.num ≠ 0 ↔ q ≠ 0 := num_eq_zero.not
```

-- snippet 92
```lean
-- Mathlib.Data.Rat.Defs.intCast_eq_divInt (L85-L86)
theorem intCast_eq_divInt (z : ℤ) : (z : ℚ) = z /. 1 := mk_eq_divInt
```

-- snippet 93
```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 94
```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 95
```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 96
```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 97
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ioo (L115-L117)
theorem preimage_cast_Ioo (p q : ℚ) : (↑) ⁻¹' Ioo (p : K) q = Ioo p q :=
castOrderEmbedding.preimage_Ioo p q
```

-- snippet 98
```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 99
```lean
-- Mathlib.Data.Rat.Cast.Order.preimage_cast_Ici (L119-L121)
theorem preimage_cast_Ici (q : ℚ) : (↑) ⁻¹' Ici (q : K) = Ici q :=
castOrderEmbedding.preimage_Ici q
```

-- snippet 100
```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 101
```lean
-- Mathlib.Data.Rat.Defs.pow_eq_divInt (L121-L123)
lemma pow_eq_divInt (q : ℚ) (n : ℕ) : q ^ n = q.num ^ n /. q.den ^ n := by
rw [pow_def, mk_eq_divInt, Int.natCast_pow]
```

-- snippet 102
```lean
-- Mathlib.Data.Rat.Defs.lift_binop_eq (L87-L104)
theorem lift_binop_eq (f : ℚ → ℚ → ℚ) (f₁ : ℤ → ℤ → ℤ → ℤ → ℤ) (f₂ : ℤ → ℤ → ℤ → ℤ → ℤ)
    (fv :
      ∀ {n₁ d₁ h₁ c₁ n₂ d₂ h₂ c₂},
        f ⟨n₁, d₁, h₁, c₁⟩ ⟨n₂, d₂, h₂, c₂⟩ = f₁ n₁ d₁ n₂ d₂ /. f₂ n₁ d₁ n₂ d₂)
    (f0 : ∀ {n₁ d₁ n₂ d₂}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0) (a b c d : ℤ)
    (b0 : b ≠ 0) (d0 : d ≠ 0)
    (H :
      ∀ {n₁ d₁ n₂ d₂}, a * d₁ = n₁ * b → c * d₂ = n₂ * d →
        f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂) :
    f (a /. b) (c /. d) = f₁ a b c d /. f₂ a b c d := by
generalize ha : a /. b = x; obtain ⟨n₁, d₁, h₁, c₁⟩ := x; rw [mk_eq_divInt] at ha
  generalize hc : c /. d = x; obtain ⟨n₂, d₂, h₂, c₂⟩ := x; rw [mk_eq_divInt] at hc
  rw [fv]
  have d₁0 := Int.ofNat_ne_zero.2 h₁
  have d₂0 := Int.ofNat_ne_zero.2 h₂
  exact (divInt_eq_divInt_iff (f0 d₁0 d₂0) (f0 b0 d0)).2
    (H ((divInt_eq_divInt_iff b0 d₁0).1 ha) ((divInt_eq_divInt_iff d0 d₂0).1 hc))
```

-- snippet 103
```lean
-- Mathlib.Data.Rat.Cast.Lemmas.cast_inv_int (L42-L46)
theorem cast_inv_int (n : ℤ) : ((n⁻¹ : ℚ) : α) = (n : α)⁻¹ := by
rcases n with n | n
  · simp [cast_inv_nat]
  · simp only [Int.cast_negSucc, cast_neg, inv_neg, cast_inv_nat]
```

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

-- snippet 105
```lean
-- Mathlib.Data.Rat.Defs.addCommMonoid (L175-L176)
instance addCommMonoid : AddCommMonoid ℚ := by infer_instance
```
[/INST]

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