Theorem: Rat.mul_def
File: Std/Data/Rat/Lemmas.lean

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

tactic: delta Rat.mul
state_before: a b : Rat
⊢ Rat.mul a b = normalize (a.num * b.num) (a.den * b.den)

tactic: dsimp only
state_before: a b : Rat
⊢ (let g1 := Nat.gcd (Int.natAbs a.num) b.den;
    let g2 := Nat.gcd (Int.natAbs b.num) a.den;
    mk' (Int.div a.num ↑g1 * Int.div b.num ↑g2) (a.den / g2 * (b.den / g1))) =
    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
⊢ mk' (Int.div a.num ↑(Nat.gcd (Int.natAbs a.num) b.den) * Int.div b.num ↑(Nat.gcd (Int.natAbs b.num) a.den))
      (a.den / Nat.gcd (Int.natAbs b.num) a.den * (b.den / Nat.gcd (Int.natAbs a.num) b.den)) =
    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 : Nat.gcd (Int.natAbs a.num) b.den ≠ 0
⊢ mk' (Int.div a.num ↑(Nat.gcd (Int.natAbs a.num) b.den) * Int.div b.num ↑(Nat.gcd (Int.natAbs b.num) a.den))
      (a.den / Nat.gcd (Int.natAbs b.num) a.den * (b.den / Nat.gcd (Int.natAbs a.num) b.den)) =
    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 : Nat.gcd (Int.natAbs a.num) b.den ≠ 0
H2 : Nat.gcd (Int.natAbs b.num) a.den ≠ 0
⊢ mk' (Int.div a.num ↑(Nat.gcd (Int.natAbs a.num) b.den) * Int.div b.num ↑(Nat.gcd (Int.natAbs b.num) a.den))
      (a.den / Nat.gcd (Int.natAbs b.num) a.den * (b.den / Nat.gcd (Int.natAbs a.num) b.den)) =
    normalize (a.num * b.num) (a.den * b.den)

tactic: congr 1
state_before: a b : Rat
H1 : Nat.gcd (Int.natAbs a.num) b.den ≠ 0
H2 : Nat.gcd (Int.natAbs b.num) a.den ≠ 0
⊢ normalize
      (Int.div a.num ↑(Nat.gcd (Int.natAbs a.num) b.den) * Int.div b.num ↑(Nat.gcd (Int.natAbs b.num) a.den) *
        ↑(Nat.gcd (Int.natAbs a.num) b.den * Nat.gcd (Int.natAbs b.num) a.den))
      (a.den / Nat.gcd (Int.natAbs b.num) a.den * (b.den / Nat.gcd (Int.natAbs a.num) b.den) *
        (Nat.gcd (Int.natAbs a.num) b.den * Nat.gcd (Int.natAbs b.num) a.den)) =
    normalize (a.num * b.num) (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 : Nat.gcd (Int.natAbs a.num) b.den ≠ 0
H2 : Nat.gcd (Int.natAbs b.num) a.den ≠ 0
⊢ Int.div a.num ↑(Nat.gcd (Int.natAbs a.num) b.den) * Int.div b.num ↑(Nat.gcd (Int.natAbs b.num) a.den) *
      ↑(Nat.gcd (Int.natAbs a.num) b.den * Nat.gcd (Int.natAbs b.num) a.den) =
    a.num * b.num

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 : Nat.gcd (Int.natAbs a.num) b.den ≠ 0
H2 : Nat.gcd (Int.natAbs b.num) a.den ≠ 0
⊢ a.den / Nat.gcd (Int.natAbs b.num) a.den * (b.den / Nat.gcd (Int.natAbs a.num) b.den) *
      (Nat.gcd (Int.natAbs a.num) b.den * Nat.gcd (Int.natAbs b.num) a.den) =
    a.den * b.den