Theorem: Rat.mul_def
File: .lake/packages/batteries/Batteries/Data/Rat/Lemmas.lean

tactic: show Rat.mul .. = _
state_before: a b : Rat
⊢ a * b = normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: a b : Rat
⊢ a.mul b = normalize (a.num * b.num) (a.den * b.den) ⋯

tactic: delta Rat.mul
state_before: a b : Rat
⊢ a.mul b = normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: a b : Rat
⊢ (let g1 := a.num.natAbs.gcd b.den;
    let g2 := b.num.natAbs.gcd a.den;
    { num := a.num.div ↑g1 * b.num.div ↑g2, den := a.den / g2 * (b.den / g1), den_nz := ⋯, reduced := ⋯ }) =
    normalize (a.num * b.num) (a.den * b.den) ⋯

tactic: dsimp only
state_before: a b : Rat
⊢ (let g1 := a.num.natAbs.gcd b.den;
    let g2 := b.num.natAbs.gcd a.den;
    { num := a.num.div ↑g1 * b.num.div ↑g2, den := a.den / g2 * (b.den / g1), den_nz := ⋯, reduced := ⋯ }) =
    normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: a b : Rat
⊢ { num := a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den),
      den := a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den), den_nz := ⋯, reduced := ⋯ } =
    normalize (a.num * b.num) (a.den * b.den) ⋯

tactic: have H1 : a.num.natAbs.gcd b.den ≠ 0 := Nat.gcd_ne_zero_right b.den_nz
state_before: a b : Rat
⊢ { num := a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den),
      den := a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den), den_nz := ⋯, reduced := ⋯ } =
    normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
⊢ { num := a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den),
      den := a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den), den_nz := ⋯, reduced := ⋯ } =
    normalize (a.num * b.num) (a.den * b.den) ⋯

tactic: have H2 : b.num.natAbs.gcd a.den ≠ 0 := Nat.gcd_ne_zero_right a.den_nz
state_before: a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
⊢ { num := a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den),
      den := a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den), den_nz := ⋯, reduced := ⋯ } =
    normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ { num := a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den),
      den := a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den), den_nz := ⋯, reduced := ⋯ } =
    normalize (a.num * b.num) (a.den * b.den) ⋯

tactic: rw [mk_eq_normalize, ← normalize_mul_right _ (Nat.mul_ne_zero H1 H2)]
state_before: a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ { num := a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den),
      den := a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den), den_nz := ⋯, reduced := ⋯ } =
    normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ normalize
      (a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den) *
        ↑(a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den))
      (a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den) *
        (a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den))
      ⋯ =
    normalize (a.num * b.num) (a.den * b.den) ⋯

tactic: congr 1
state_before: a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ normalize
      (a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den) *
        ↑(a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den))
      (a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den) *
        (a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den))
      ⋯ =
    normalize (a.num * b.num) (a.den * b.den) ⋯
state_after: case e_num
a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den) *
      ↑(a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den) =
    a.num * b.num

case e_den
a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den) *
      (a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den) =
    a.den * b.den

tactic: rw [Int.ofNat_mul, ← Int.mul_assoc, Int.mul_right_comm (Int.div ..),
  Int.div_mul_cancel (Int.ofNat_dvd_left.2 <| Nat.gcd_dvd_left ..), Int.mul_assoc,
  Int.div_mul_cancel (Int.ofNat_dvd_left.2 <| Nat.gcd_dvd_left ..)]
state_before: case e_num
a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ a.num.div ↑(a.num.natAbs.gcd b.den) * b.num.div ↑(b.num.natAbs.gcd a.den) *
      ↑(a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den) =
    a.num * b.num
state_after: no goals

tactic: rw [← Nat.mul_assoc, Nat.mul_right_comm, Nat.mul_right_comm (_/_),
  Nat.div_mul_cancel (Nat.gcd_dvd_right ..), Nat.mul_assoc,
  Nat.div_mul_cancel (Nat.gcd_dvd_right ..)]
state_before: case e_den
a b : Rat
H1 : a.num.natAbs.gcd b.den ≠ 0
H2 : b.num.natAbs.gcd a.den ≠ 0
⊢ a.den / b.num.natAbs.gcd a.den * (b.den / a.num.natAbs.gcd b.den) *
      (a.num.natAbs.gcd b.den * b.num.natAbs.gcd a.den) =
    a.den * b.den
state_after: no goals