[GOAL]
s t : ℤ
r' : ℕ
s' t' : ℤ
⊢ xgcdAux 0 s t r' s' t' = (r', s', t')
[PROOFSTEP]
simp [xgcdAux]
[GOAL]
r : ℕ
s t : ℤ
r' : ℕ
s' t' : ℤ
h : 0 < r
⊢ xgcdAux r s t r' s' t' = xgcdAux (r' % r) (s' - ↑r' / ↑r * s) (t' - ↑r' / ↑r * t) r s t
[PROOFSTEP]
obtain ⟨r, rfl⟩ := Nat.exists_eq_succ_of_ne_zero h.ne'
[GOAL]
case intro
s t : ℤ
r' : ℕ
s' t' : ℤ
r : ℕ
h : 0 < succ r
⊢ xgcdAux (succ r) s t r' s' t' =
    xgcdAux (r' % succ r) (s' - ↑r' / ↑(succ r) * s) (t' - ↑r' / ↑(succ r) * t) (succ r) s t
[PROOFSTEP]
rfl
[GOAL]
s : ℕ
⊢ gcdA 0 s = 0
[PROOFSTEP]
unfold gcdA
[GOAL]
s : ℕ
⊢ (xgcd 0 s).fst = 0
[PROOFSTEP]
rw [xgcd, xgcd_zero_left]
[GOAL]
s : ℕ
⊢ gcdB 0 s = 1
[PROOFSTEP]
unfold gcdB
[GOAL]
s : ℕ
⊢ (xgcd 0 s).snd = 1
[PROOFSTEP]
rw [xgcd, xgcd_zero_left]
[GOAL]
s : ℕ
h : s ≠ 0
⊢ gcdA s 0 = 1
[PROOFSTEP]
unfold gcdA xgcd
[GOAL]
s : ℕ
h : s ≠ 0
⊢ (xgcdAux s 1 0 0 0 1).snd.fst = 1
[PROOFSTEP]
obtain ⟨s, rfl⟩ := Nat.exists_eq_succ_of_ne_zero h
[GOAL]
case intro
s : ℕ
h : succ s ≠ 0
⊢ (xgcdAux (succ s) 1 0 0 0 1).snd.fst = 1
[PROOFSTEP]
rw [xgcdAux_succ]
[GOAL]
case intro
s : ℕ
h : succ s ≠ 0
⊢ (xgcdAux (0 % succ s) (0 - ↑0 / ↑(succ s) * 1) (1 - ↑0 / ↑(succ s) * 0) (succ s) 1 0).snd.fst = 1
[PROOFSTEP]
rfl
[GOAL]
s : ℕ
h : s ≠ 0
⊢ gcdB s 0 = 0
[PROOFSTEP]
unfold gcdB xgcd
[GOAL]
s : ℕ
h : s ≠ 0
⊢ (xgcdAux s 1 0 0 0 1).snd.snd = 0
[PROOFSTEP]
obtain ⟨s, rfl⟩ := Nat.exists_eq_succ_of_ne_zero h
[GOAL]
case intro
s : ℕ
h : succ s ≠ 0
⊢ (xgcdAux (succ s) 1 0 0 0 1).snd.snd = 0
[PROOFSTEP]
rw [xgcdAux_succ]
[GOAL]
case intro
s : ℕ
h : succ s ≠ 0
⊢ (xgcdAux (0 % succ s) (0 - ↑0 / ↑(succ s) * 1) (1 - ↑0 / ↑(succ s) * 0) (succ s) 1 0).snd.snd = 0
[PROOFSTEP]
rfl
[GOAL]
x y : ℕ
⊢ ∀ (n : ℕ) (s t s' t' : ℤ), (xgcdAux 0 s t n s' t').fst = gcd 0 n
[PROOFSTEP]
simp
[GOAL]
x✝ y✝ x y : ℕ
h : 0 < x
IH : ∀ (s t s' t' : ℤ), (xgcdAux (y % x) s t x s' t').fst = gcd (y % x) x
s t s' t' : ℤ
⊢ (xgcdAux x s t y s' t').fst = gcd x y
[PROOFSTEP]
simp [xgcdAux_rec, h, IH]
[GOAL]
x✝ y✝ x y : ℕ
h : 0 < x
IH : ∀ (s t s' t' : ℤ), (xgcdAux (y % x) s t x s' t').fst = gcd (y % x) x
s t s' t' : ℤ
⊢ gcd (y % x) x = gcd x y
[PROOFSTEP]
rw [← gcd_rec]
[GOAL]
x y : ℕ
⊢ xgcdAux x 1 0 y 0 1 = (gcd x y, xgcd x y)
[PROOFSTEP]
rw [xgcd, ← xgcdAux_fst x y 1 0 0 1]
[GOAL]
x y : ℕ
⊢ xgcd x y = (gcdA x y, gcdB x y)
[PROOFSTEP]
unfold gcdA gcdB
[GOAL]
x y : ℕ
⊢ xgcd x y = ((xgcd x y).fst, (xgcd x y).snd)
[PROOFSTEP]
cases xgcd x y
[GOAL]
case mk
x y : ℕ
fst✝ snd✝ : ℤ
⊢ (fst✝, snd✝) = ((fst✝, snd✝).fst, (fst✝, snd✝).snd)
[PROOFSTEP]
rfl
[GOAL]
x y r r' : ℕ
⊢ ∀ {s t s' t' : ℤ}, Nat.P x y (r, s, t) → Nat.P x y (r', s', t') → Nat.P x y (xgcdAux r s t r' s' t')
[PROOFSTEP]
induction r, r' using gcd.induction with
| H0 => simp
| H1 a b h IH =>
  intro s t s' t' p p'
  rw [xgcdAux_rec h]; refine' IH _ p; dsimp [P] at *
  rw [Int.emod_def]; generalize (b / a : ℤ) = k
  rw [p, p', mul_sub, sub_add_eq_add_sub, mul_sub, add_mul, mul_comm k t, mul_comm k s, ← mul_assoc, ← mul_assoc,
    add_comm (x * s * k), ← add_sub_assoc, sub_sub]
[GOAL]
x y r r' : ℕ
⊢ ∀ {s t s' t' : ℤ}, Nat.P x y (r, s, t) → Nat.P x y (r', s', t') → Nat.P x y (xgcdAux r s t r' s' t')
[PROOFSTEP]
induction r, r' using gcd.induction with
| H0 => simp
| H1 a b h IH =>
  intro s t s' t' p p'
  rw [xgcdAux_rec h]; refine' IH _ p; dsimp [P] at *
  rw [Int.emod_def]; generalize (b / a : ℤ) = k
  rw [p, p', mul_sub, sub_add_eq_add_sub, mul_sub, add_mul, mul_comm k t, mul_comm k s, ← mul_assoc, ← mul_assoc,
    add_comm (x * s * k), ← add_sub_assoc, sub_sub]
[GOAL]
case H0
x y n✝ : ℕ
⊢ ∀ {s t s' t' : ℤ}, Nat.P x y (0, s, t) → Nat.P x y (n✝, s', t') → Nat.P x y (xgcdAux 0 s t n✝ s' t')
[PROOFSTEP]

| H0 => simp
[GOAL]
case H0
x y n✝ : ℕ
⊢ ∀ {s t s' t' : ℤ}, Nat.P x y (0, s, t) → Nat.P x y (n✝, s', t') → Nat.P x y (xgcdAux 0 s t n✝ s' t')
[PROOFSTEP]
simp
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH : ∀ {s t s' t' : ℤ}, Nat.P x y (b % a, s, t) → Nat.P x y (a, s', t') → Nat.P x y (xgcdAux (b % a) s t a s' t')
⊢ ∀ {s t s' t' : ℤ}, Nat.P x y (a, s, t) → Nat.P x y (b, s', t') → Nat.P x y (xgcdAux a s t b s' t')
[PROOFSTEP]

| H1 a b h IH =>
  intro s t s' t' p p'
  rw [xgcdAux_rec h]; refine' IH _ p; dsimp [P] at *
  rw [Int.emod_def]; generalize (b / a : ℤ) = k
  rw [p, p', mul_sub, sub_add_eq_add_sub, mul_sub, add_mul, mul_comm k t, mul_comm k s, ← mul_assoc, ← mul_assoc,
    add_comm (x * s * k), ← add_sub_assoc, sub_sub]
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH : ∀ {s t s' t' : ℤ}, Nat.P x y (b % a, s, t) → Nat.P x y (a, s', t') → Nat.P x y (xgcdAux (b % a) s t a s' t')
⊢ ∀ {s t s' t' : ℤ}, Nat.P x y (a, s, t) → Nat.P x y (b, s', t') → Nat.P x y (xgcdAux a s t b s' t')
[PROOFSTEP]
intro s t s' t' p p'
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH : ∀ {s t s' t' : ℤ}, Nat.P x y (b % a, s, t) → Nat.P x y (a, s', t') → Nat.P x y (xgcdAux (b % a) s t a s' t')
s t s' t' : ℤ
p : Nat.P x y (a, s, t)
p' : Nat.P x y (b, s', t')
⊢ Nat.P x y (xgcdAux a s t b s' t')
[PROOFSTEP]
rw [xgcdAux_rec h]
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH : ∀ {s t s' t' : ℤ}, Nat.P x y (b % a, s, t) → Nat.P x y (a, s', t') → Nat.P x y (xgcdAux (b % a) s t a s' t')
s t s' t' : ℤ
p : Nat.P x y (a, s, t)
p' : Nat.P x y (b, s', t')
⊢ Nat.P x y (xgcdAux (b % a) (s' - ↑b / ↑a * s) (t' - ↑b / ↑a * t) a s t)
[PROOFSTEP]
refine' IH _ p
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH : ∀ {s t s' t' : ℤ}, Nat.P x y (b % a, s, t) → Nat.P x y (a, s', t') → Nat.P x y (xgcdAux (b % a) s t a s' t')
s t s' t' : ℤ
p : Nat.P x y (a, s, t)
p' : Nat.P x y (b, s', t')
⊢ Nat.P x y (b % a, s' - ↑b / ↑a * s, t' - ↑b / ↑a * t)
[PROOFSTEP]
dsimp [P] at *
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH :
  ∀ {s t s' t' : ℤ},
    ↑b % ↑a = ↑x * s + ↑y * t →
      ↑a = ↑x * s' + ↑y * t' →
        ↑(xgcdAux (b % a) s t a s' t').fst =
          ↑x * (xgcdAux (b % a) s t a s' t').2.fst + ↑y * (xgcdAux (b % a) s t a s' t').2.snd
s t s' t' : ℤ
p : ↑a = ↑x * s + ↑y * t
p' : ↑b = ↑x * s' + ↑y * t'
⊢ ↑b % ↑a = ↑x * (s' - ↑b / ↑a * s) + ↑y * (t' - ↑b / ↑a * t)
[PROOFSTEP]
rw [Int.emod_def]
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH :
  ∀ {s t s' t' : ℤ},
    ↑b % ↑a = ↑x * s + ↑y * t →
      ↑a = ↑x * s' + ↑y * t' →
        ↑(xgcdAux (b % a) s t a s' t').fst =
          ↑x * (xgcdAux (b % a) s t a s' t').2.fst + ↑y * (xgcdAux (b % a) s t a s' t').2.snd
s t s' t' : ℤ
p : ↑a = ↑x * s + ↑y * t
p' : ↑b = ↑x * s' + ↑y * t'
⊢ ↑b - ↑a * (↑b / ↑a) = ↑x * (s' - ↑b / ↑a * s) + ↑y * (t' - ↑b / ↑a * t)
[PROOFSTEP]
generalize (b / a : ℤ) = k
[GOAL]
case H1
x y a b : ℕ
h : 0 < a
IH :
  ∀ {s t s' t' : ℤ},
    ↑b % ↑a = ↑x * s + ↑y * t →
      ↑a = ↑x * s' + ↑y * t' →
        ↑(xgcdAux (b % a) s t a s' t').fst =
          ↑x * (xgcdAux (b % a) s t a s' t').2.fst + ↑y * (xgcdAux (b % a) s t a s' t').2.snd
s t s' t' : ℤ
p : ↑a = ↑x * s + ↑y * t
p' : ↑b = ↑x * s' + ↑y * t'
k : ℤ
⊢ ↑b - ↑a * k = ↑x * (s' - k * s) + ↑y * (t' - k * t)
[PROOFSTEP]
rw [p, p', mul_sub, sub_add_eq_add_sub, mul_sub, add_mul, mul_comm k t, mul_comm k s, ← mul_assoc, ← mul_assoc,
  add_comm (x * s * k), ← add_sub_assoc, sub_sub]
[GOAL]
x y : ℕ
⊢ ↑(gcd x y) = ↑x * gcdA x y + ↑y * gcdB x y
[PROOFSTEP]
have := @xgcdAux_P x y x y 1 0 0 1 (by simp [P]) (by simp [P])
[GOAL]
x y : ℕ
⊢ Nat.P x y (x, 1, 0)
[PROOFSTEP]
simp [P]
[GOAL]
x y : ℕ
⊢ Nat.P x y (y, 0, 1)
[PROOFSTEP]
simp [P]
[GOAL]
x y : ℕ
this : Nat.P x y (xgcdAux x 1 0 y 0 1)
⊢ ↑(gcd x y) = ↑x * gcdA x y + ↑y * gcdB x y
[PROOFSTEP]
rwa [xgcdAux_val, xgcd_val] at this
[GOAL]
k n : ℕ
hk : gcd n k < k
⊢ ∃ m, n * m % k = gcd n k
[PROOFSTEP]
have hk' := Int.ofNat_ne_zero.2 (ne_of_gt (lt_of_le_of_lt (zero_le (gcd n k)) hk))
[GOAL]
k n : ℕ
hk : gcd n k < k
hk' : ↑k ≠ 0
⊢ ∃ m, n * m % k = gcd n k
[PROOFSTEP]
have key := congr_arg (fun (m : ℤ) => (m % k).toNat) (gcd_eq_gcd_ab n k)
[GOAL]
k n : ℕ
hk : gcd n k < k
hk' : ↑k ≠ 0
key : (fun m => Int.toNat (m % ↑k)) ↑(gcd n k) = (fun m => Int.toNat (m % ↑k)) (↑n * gcdA n k + ↑k * gcdB n k)
⊢ ∃ m, n * m % k = gcd n k
[PROOFSTEP]
simp only at key
[GOAL]
k n : ℕ
hk : gcd n k < k
hk' : ↑k ≠ 0
key : Int.toNat (↑(gcd n k) % ↑k) = Int.toNat ((↑n * gcdA n k + ↑k * gcdB n k) % ↑k)
⊢ ∃ m, n * m % k = gcd n k
[PROOFSTEP]
rw [Int.add_mul_emod_self_left, ← Int.coe_nat_mod, Int.toNat_coe_nat, mod_eq_of_lt hk] at key
[GOAL]
k n : ℕ
hk : gcd n k < k
hk' : ↑k ≠ 0
key : gcd n k = Int.toNat (↑n * gcdA n k % ↑k)
⊢ ∃ m, n * m % k = gcd n k
[PROOFSTEP]
refine' ⟨(n.gcdA k % k).toNat, Eq.trans (Int.ofNat.inj _) key.symm⟩
[GOAL]
k n : ℕ
hk : gcd n k < k
hk' : ↑k ≠ 0
key : gcd n k = Int.toNat (↑n * gcdA n k % ↑k)
⊢ Int.ofNat (n * Int.toNat (gcdA n k % ↑k) % k) = Int.ofNat (Int.toNat (↑n * gcdA n k % ↑k))
[PROOFSTEP]
rw [Int.ofNat_eq_coe, Int.coe_nat_mod, Int.ofNat_mul, Int.toNat_of_nonneg (Int.emod_nonneg _ hk'), Int.ofNat_eq_coe,
  Int.toNat_of_nonneg (Int.emod_nonneg _ hk'), Int.mul_emod, Int.emod_emod, ← Int.mul_emod]
[GOAL]
m n : ℕ
⊢ ↑(gcd ↑m -[n+1]) = ↑m * gcdA ↑m -[n+1] + -(↑n + 1) * -Nat.gcdB (natAbs ↑m) (Nat.succ n)
[PROOFSTEP]
rw [neg_mul_neg]
[GOAL]
m n : ℕ
⊢ ↑(gcd ↑m -[n+1]) = ↑m * gcdA ↑m -[n+1] + (↑n + 1) * Nat.gcdB (natAbs ↑m) (Nat.succ n)
[PROOFSTEP]
apply Nat.gcd_eq_gcd_ab
[GOAL]
m n : ℕ
⊢ ↑(gcd -[m+1] ↑n) = -(↑m + 1) * -Nat.gcdA (Nat.succ m) (natAbs ↑n) + ↑n * gcdB -[m+1] ↑n
[PROOFSTEP]
rw [neg_mul_neg]
[GOAL]
m n : ℕ
⊢ ↑(gcd -[m+1] ↑n) = (↑m + 1) * Nat.gcdA (Nat.succ m) (natAbs ↑n) + ↑n * gcdB -[m+1] ↑n
[PROOFSTEP]
apply Nat.gcd_eq_gcd_ab
[GOAL]
m n : ℕ
⊢ ↑(gcd -[m+1] -[n+1]) =
    -(↑m + 1) * -Nat.gcdA (Nat.succ m) (natAbs -[n+1]) + -(↑n + 1) * -Nat.gcdB (natAbs -[m+1]) (Nat.succ n)
[PROOFSTEP]
rw [neg_mul_neg, neg_mul_neg]
[GOAL]
m n : ℕ
⊢ ↑(gcd -[m+1] -[n+1]) =
    (↑m + 1) * Nat.gcdA (Nat.succ m) (natAbs -[n+1]) + (↑n + 1) * Nat.gcdB (natAbs -[m+1]) (Nat.succ n)
[PROOFSTEP]
apply Nat.gcd_eq_gcd_ab
[GOAL]
a b : ℤ
H : b ∣ a
⊢ natAbs (a / b) = natAbs a / natAbs b
[PROOFSTEP]
rcases Nat.eq_zero_or_pos (natAbs b) with (h | h)
[GOAL]
case inl
a b : ℤ
H : b ∣ a
h : natAbs b = 0
⊢ natAbs (a / b) = natAbs a / natAbs b
[PROOFSTEP]
rw [natAbs_eq_zero.1 h]
[GOAL]
case inl
a b : ℤ
H : b ∣ a
h : natAbs b = 0
⊢ natAbs (a / 0) = natAbs a / natAbs 0
[PROOFSTEP]
simp [Int.ediv_zero]
[GOAL]
case inr
a b : ℤ
H : b ∣ a
h : natAbs b > 0
⊢ natAbs (a / b) = natAbs a / natAbs b
[PROOFSTEP]
calc
  natAbs (a / b) = natAbs (a / b) * 1 := by rw [mul_one]
  _ = natAbs (a / b) * (natAbs b / natAbs b) := by rw [Nat.div_self h]
  _ = natAbs (a / b) * natAbs b / natAbs b := by rw [Nat.mul_div_assoc _ dvd_rfl]
  _ = natAbs (a / b * b) / natAbs b := by rw [natAbs_mul (a / b) b]
  _ = natAbs a / natAbs b := by rw [Int.ediv_mul_cancel H]
[GOAL]
a b : ℤ
H : b ∣ a
h : natAbs b > 0
⊢ natAbs (a / b) = natAbs (a / b) * 1
[PROOFSTEP]
rw [mul_one]
[GOAL]
a b : ℤ
H : b ∣ a
h : natAbs b > 0
⊢ natAbs (a / b) * 1 = natAbs (a / b) * (natAbs b / natAbs b)
[PROOFSTEP]
rw [Nat.div_self h]
[GOAL]
a b : ℤ
H : b ∣ a
h : natAbs b > 0
⊢ natAbs (a / b) * (natAbs b / natAbs b) = natAbs (a / b) * natAbs b / natAbs b
[PROOFSTEP]
rw [Nat.mul_div_assoc _ dvd_rfl]
[GOAL]
a b : ℤ
H : b ∣ a
h : natAbs b > 0
⊢ natAbs (a / b) * natAbs b / natAbs b = natAbs (a / b * b) / natAbs b
[PROOFSTEP]
rw [natAbs_mul (a / b) b]
[GOAL]
a b : ℤ
H : b ∣ a
h : natAbs b > 0
⊢ natAbs (a / b * b) / natAbs b = natAbs a / natAbs b
[PROOFSTEP]
rw [Int.ediv_mul_cancel H]
[GOAL]
i j k : ℤ
k_non_zero : k ≠ 0
H : k * i ∣ k * j
l : ℤ
H1 : k * j = k * i * l
⊢ i ∣ j
[PROOFSTEP]
rw [mul_assoc] at H1
[GOAL]
i j k : ℤ
k_non_zero : k ≠ 0
H : k * i ∣ k * j
l : ℤ
H1 : k * j = k * (i * l)
⊢ i ∣ j
[PROOFSTEP]
exact ⟨_, mul_left_cancel₀ k_non_zero H1⟩
[GOAL]
i j k : ℤ
k_non_zero : k ≠ 0
H : i * k ∣ j * k
⊢ i ∣ j
[PROOFSTEP]
rw [mul_comm i k, mul_comm j k] at H
[GOAL]
i j k : ℤ
k_non_zero : k ≠ 0
H : k * i ∣ k * j
⊢ i ∣ j
[PROOFSTEP]
exact dvd_of_mul_dvd_mul_left k_non_zero H
[GOAL]
i j : ℤ
⊢ gcd i j * lcm i j = natAbs (i * j)
[PROOFSTEP]
rw [Int.gcd, Int.lcm, Nat.gcd_mul_lcm, natAbs_mul]
[GOAL]
i : ℤ
⊢ gcd i i = natAbs i
[PROOFSTEP]
simp [gcd]
[GOAL]
i : ℤ
⊢ gcd 0 i = natAbs i
[PROOFSTEP]
simp [gcd]
[GOAL]
i : ℤ
⊢ gcd i 0 = natAbs i
[PROOFSTEP]
simp [gcd]
[GOAL]
x y : ℤ
⊢ gcd x (-y) = gcd x y
[PROOFSTEP]
rw [Int.gcd, Int.gcd, natAbs_neg]
[GOAL]
x y : ℤ
⊢ gcd (-x) y = gcd x y
[PROOFSTEP]
rw [Int.gcd, Int.gcd, natAbs_neg]
[GOAL]
i j k : ℤ
⊢ gcd (i * j) (i * k) = natAbs i * gcd j k
[PROOFSTEP]
rw [Int.gcd, Int.gcd, natAbs_mul, natAbs_mul]
[GOAL]
i j k : ℤ
⊢ Nat.gcd (natAbs i * natAbs j) (natAbs i * natAbs k) = natAbs i * Nat.gcd (natAbs j) (natAbs k)
[PROOFSTEP]
apply Nat.gcd_mul_left
[GOAL]
i j k : ℤ
⊢ gcd (i * j) (k * j) = gcd i k * natAbs j
[PROOFSTEP]
rw [Int.gcd, Int.gcd, natAbs_mul, natAbs_mul]
[GOAL]
i j k : ℤ
⊢ Nat.gcd (natAbs i * natAbs j) (natAbs k * natAbs j) = Nat.gcd (natAbs i) (natAbs k) * natAbs j
[PROOFSTEP]
apply Nat.gcd_mul_right
[GOAL]
i j : ℤ
⊢ gcd i j = 0 ↔ i = 0 ∧ j = 0
[PROOFSTEP]
rw [gcd, Nat.gcd_eq_zero_iff, natAbs_eq_zero, natAbs_eq_zero]
[GOAL]
i j k : ℤ
H1 : k ∣ i
H2 : k ∣ j
⊢ gcd (i / k) (j / k) = gcd i j / natAbs k
[PROOFSTEP]
rw [gcd, natAbs_ediv i k H1, natAbs_ediv j k H2]
[GOAL]
i j k : ℤ
H1 : k ∣ i
H2 : k ∣ j
⊢ Nat.gcd (natAbs i / natAbs k) (natAbs j / natAbs k) = gcd i j / natAbs k
[PROOFSTEP]
exact Nat.gcd_div (natAbs_dvd_natAbs.mpr H1) (natAbs_dvd_natAbs.mpr H2)
[GOAL]
i j : ℤ
H : 0 < gcd i j
⊢ gcd (i / ↑(gcd i j)) (j / ↑(gcd i j)) = 1
[PROOFSTEP]
rw [gcd_div (gcd_dvd_left i j) (gcd_dvd_right i j), natAbs_ofNat, Nat.div_self H]
[GOAL]
i j : ℤ
H : j ∣ i
⊢ gcd i j = natAbs j
[PROOFSTEP]
rw [gcd_comm, gcd_eq_left H]
[GOAL]
x y : ℤ
hc : gcd x y ≠ 0
⊢ x ≠ 0 ∨ y ≠ 0
[PROOFSTEP]
contrapose! hc
[GOAL]
x y : ℤ
hc : x = 0 ∧ y = 0
⊢ gcd x y = 0
[PROOFSTEP]
rw [hc.left, hc.right, gcd_zero_right, natAbs_zero]
[GOAL]
m n : ℤ
k : ℕ
k0 : 0 < k
⊢ m ^ k ∣ n ^ k ↔ m ∣ n
[PROOFSTEP]
refine' ⟨fun h => _, fun h => pow_dvd_pow_of_dvd h _⟩
[GOAL]
m n : ℤ
k : ℕ
k0 : 0 < k
h : m ^ k ∣ n ^ k
⊢ m ∣ n
[PROOFSTEP]
rwa [← natAbs_dvd_natAbs, ← Nat.pow_dvd_pow_iff k0, ← Int.natAbs_pow, ← Int.natAbs_pow, natAbs_dvd_natAbs]
[GOAL]
a b : ℤ
n : ℕ
⊢ gcd a b ∣ n ↔ ∃ x y, ↑n = a * x + b * y
[PROOFSTEP]
constructor
[GOAL]
case mp
a b : ℤ
n : ℕ
⊢ gcd a b ∣ n → ∃ x y, ↑n = a * x + b * y
[PROOFSTEP]
intro h
[GOAL]
case mp
a b : ℤ
n : ℕ
h : gcd a b ∣ n
⊢ ∃ x y, ↑n = a * x + b * y
[PROOFSTEP]
rw [← Nat.mul_div_cancel' h, Int.ofNat_mul, gcd_eq_gcd_ab, add_mul, mul_assoc, mul_assoc]
[GOAL]
case mp
a b : ℤ
n : ℕ
h : gcd a b ∣ n
⊢ ∃ x y, a * (gcdA a b * ↑(n / gcd a b)) + b * (gcdB a b * ↑(n / gcd a b)) = a * x + b * y
[PROOFSTEP]
exact ⟨_, _, rfl⟩
[GOAL]
case mpr
a b : ℤ
n : ℕ
⊢ (∃ x y, ↑n = a * x + b * y) → gcd a b ∣ n
[PROOFSTEP]
rintro ⟨x, y, h⟩
[GOAL]
case mpr.intro.intro
a b : ℤ
n : ℕ
x y : ℤ
h : ↑n = a * x + b * y
⊢ gcd a b ∣ n
[PROOFSTEP]
rw [← Int.coe_nat_dvd, h]
[GOAL]
case mpr.intro.intro
a b : ℤ
n : ℕ
x y : ℤ
h : ↑n = a * x + b * y
⊢ ↑(gcd a b) ∣ a * x + b * y
[PROOFSTEP]
exact dvd_add (dvd_mul_of_dvd_left (gcd_dvd_left a b) _) (dvd_mul_of_dvd_left (gcd_dvd_right a b) y)
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a c = 1
⊢ a ∣ b
[PROOFSTEP]
have := gcd_eq_gcd_ab a c
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a c = 1
this : ↑(gcd a c) = a * gcdA a c + c * gcdB a c
⊢ a ∣ b
[PROOFSTEP]
simp only [hab, Int.ofNat_zero, Int.ofNat_succ, zero_add] at this
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a c = 1
this : 1 = a * gcdA a c + c * gcdB a c
⊢ a ∣ b
[PROOFSTEP]
have : b * a * gcdA a c + b * c * gcdB a c = b := by simp [mul_assoc, ← mul_add, ← this]
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a c = 1
this : 1 = a * gcdA a c + c * gcdB a c
⊢ b * a * gcdA a c + b * c * gcdB a c = b
[PROOFSTEP]
simp [mul_assoc, ← mul_add, ← this]
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a c = 1
this✝ : 1 = a * gcdA a c + c * gcdB a c
this : b * a * gcdA a c + b * c * gcdB a c = b
⊢ a ∣ b
[PROOFSTEP]
rw [← this]
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a c = 1
this✝ : 1 = a * gcdA a c + c * gcdB a c
this : b * a * gcdA a c + b * c * gcdB a c = b
⊢ a ∣ b * a * gcdA a c + b * c * gcdB a c
[PROOFSTEP]
exact dvd_add (dvd_mul_of_dvd_left (dvd_mul_left a b) _) (dvd_mul_of_dvd_left habc _)
[GOAL]
a b c : ℤ
habc : a ∣ b * c
hab : gcd a b = 1
⊢ a ∣ c
[PROOFSTEP]
rw [mul_comm] at habc
[GOAL]
a b c : ℤ
habc : a ∣ c * b
hab : gcd a b = 1
⊢ a ∣ c
[PROOFSTEP]
exact dvd_of_dvd_mul_left_of_gcd_one habc hab
[GOAL]
a b : ℤ
ha : a ≠ 0
⊢ IsLeast {n | 0 < n ∧ ∃ x y, ↑n = a * x + b * y} (gcd a b)
[PROOFSTEP]
simp_rw [← gcd_dvd_iff]
[GOAL]
a b : ℤ
ha : a ≠ 0
⊢ IsLeast {n | 0 < n ∧ gcd a b ∣ n} (gcd a b)
[PROOFSTEP]
constructor
[GOAL]
case left
a b : ℤ
ha : a ≠ 0
⊢ gcd a b ∈ {n | 0 < n ∧ gcd a b ∣ n}
[PROOFSTEP]
simpa [and_true_iff, dvd_refl, Set.mem_setOf_eq] using gcd_pos_of_ne_zero_left b ha
[GOAL]
case right
a b : ℤ
ha : a ≠ 0
⊢ gcd a b ∈ lowerBounds {n | 0 < n ∧ gcd a b ∣ n}
[PROOFSTEP]
simp only [lowerBounds, and_imp, Set.mem_setOf_eq]
[GOAL]
case right
a b : ℤ
ha : a ≠ 0
⊢ ∀ ⦃a_1 : ℕ⦄, 0 < a_1 → gcd a b ∣ a_1 → gcd a b ≤ a_1
[PROOFSTEP]
exact fun n hn_pos hn => Nat.le_of_dvd hn_pos hn
[GOAL]
i j : ℤ
⊢ lcm i j = lcm j i
[PROOFSTEP]
rw [Int.lcm, Int.lcm]
[GOAL]
i j : ℤ
⊢ Nat.lcm (natAbs i) (natAbs j) = Nat.lcm (natAbs j) (natAbs i)
[PROOFSTEP]
exact Nat.lcm_comm _ _
[GOAL]
i j k : ℤ
⊢ lcm (↑(lcm i j)) k = lcm i ↑(lcm j k)
[PROOFSTEP]
rw [Int.lcm, Int.lcm, Int.lcm, Int.lcm, natAbs_ofNat, natAbs_ofNat]
[GOAL]
i j k : ℤ
⊢ Nat.lcm (Nat.lcm (natAbs i) (natAbs j)) (natAbs k) = Nat.lcm (natAbs i) (Nat.lcm (natAbs j) (natAbs k))
[PROOFSTEP]
apply Nat.lcm_assoc
[GOAL]
i : ℤ
⊢ lcm 0 i = 0
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i : ℤ
⊢ Nat.lcm (natAbs 0) (natAbs i) = 0
[PROOFSTEP]
apply Nat.lcm_zero_left
[GOAL]
i : ℤ
⊢ lcm i 0 = 0
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i : ℤ
⊢ Nat.lcm (natAbs i) (natAbs 0) = 0
[PROOFSTEP]
apply Nat.lcm_zero_right
[GOAL]
i : ℤ
⊢ lcm 1 i = natAbs i
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i : ℤ
⊢ Nat.lcm (natAbs 1) (natAbs i) = natAbs i
[PROOFSTEP]
apply Nat.lcm_one_left
[GOAL]
i : ℤ
⊢ lcm i 1 = natAbs i
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i : ℤ
⊢ Nat.lcm (natAbs i) (natAbs 1) = natAbs i
[PROOFSTEP]
apply Nat.lcm_one_right
[GOAL]
i : ℤ
⊢ lcm i i = natAbs i
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i : ℤ
⊢ Nat.lcm (natAbs i) (natAbs i) = natAbs i
[PROOFSTEP]
apply Nat.lcm_self
[GOAL]
i j : ℤ
⊢ i ∣ ↑(lcm i j)
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i j : ℤ
⊢ i ∣ ↑(Nat.lcm (natAbs i) (natAbs j))
[PROOFSTEP]
apply coe_nat_dvd_right.mpr
[GOAL]
i j : ℤ
⊢ natAbs i ∣ Nat.lcm (natAbs i) (natAbs j)
[PROOFSTEP]
apply Nat.dvd_lcm_left
[GOAL]
i j : ℤ
⊢ j ∣ ↑(lcm i j)
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i j : ℤ
⊢ j ∣ ↑(Nat.lcm (natAbs i) (natAbs j))
[PROOFSTEP]
apply coe_nat_dvd_right.mpr
[GOAL]
i j : ℤ
⊢ natAbs j ∣ Nat.lcm (natAbs i) (natAbs j)
[PROOFSTEP]
apply Nat.dvd_lcm_right
[GOAL]
i j k : ℤ
⊢ i ∣ k → j ∣ k → ↑(lcm i j) ∣ k
[PROOFSTEP]
rw [Int.lcm]
[GOAL]
i j k : ℤ
⊢ i ∣ k → j ∣ k → ↑(Nat.lcm (natAbs i) (natAbs j)) ∣ k
[PROOFSTEP]
intro hi hj
[GOAL]
i j k : ℤ
hi : i ∣ k
hj : j ∣ k
⊢ ↑(Nat.lcm (natAbs i) (natAbs j)) ∣ k
[PROOFSTEP]
exact coe_nat_dvd_left.mpr (Nat.lcm_dvd (natAbs_dvd_natAbs.mpr hi) (natAbs_dvd_natAbs.mpr hj))
[GOAL]
M : Type u_1
inst✝ : Monoid M
x : M
m n : ℕ
hm : x ^ m = 1
hn : x ^ n = 1
⊢ x ^ Nat.gcd m n = 1
[PROOFSTEP]
rcases m with (rfl | m)
[GOAL]
case zero
M : Type u_1
inst✝ : Monoid M
x : M
n : ℕ
hn : x ^ n = 1
hm : x ^ Nat.zero = 1
⊢ x ^ Nat.gcd Nat.zero n = 1
[PROOFSTEP]
simp [hn]
[GOAL]
case succ
M : Type u_1
inst✝ : Monoid M
x : M
n : ℕ
hn : x ^ n = 1
m : ℕ
hm : x ^ Nat.succ m = 1
⊢ x ^ Nat.gcd (Nat.succ m) n = 1
[PROOFSTEP]
obtain ⟨y, rfl⟩ := isUnit_ofPowEqOne hm m.succ_ne_zero
[GOAL]
case succ.intro
M : Type u_1
inst✝ : Monoid M
n m : ℕ
y : Mˣ
hn : ↑y ^ n = 1
hm : ↑y ^ Nat.succ m = 1
⊢ ↑y ^ Nat.gcd (Nat.succ m) n = 1
[PROOFSTEP]
simp only [← Units.val_pow_eq_pow_val] at *
[GOAL]
case succ.intro
M : Type u_1
inst✝ : Monoid M
n m : ℕ
y : Mˣ
hn : ↑(y ^ n) = 1
hm : ↑(y ^ Nat.succ m) = 1
⊢ ↑(y ^ Nat.gcd (Nat.succ m) n) = 1
[PROOFSTEP]
rw [← Units.val_one, ← zpow_coe_nat, ← Units.ext_iff] at *
[GOAL]
case succ.intro
M : Type u_1
inst✝ : Monoid M
n m : ℕ
y : Mˣ
hn : y ^ ↑n = 1
hm : y ^ ↑(Nat.succ m) = 1
⊢ y ^ ↑(Nat.gcd (Nat.succ m) n) = 1
[PROOFSTEP]
simp only [Nat.gcd_eq_gcd_ab, zpow_add, zpow_mul, hm, hn, one_zpow, one_mul]


[GOAL]
R : Type u_1
inst✝ : MonoidWithZero R
a✝ b✝ : R
hx₁ : a✝ ∈ {x | ∀ (z : R), z * x = 0 → z = 0}
hx₂ : b✝ ∈ {x | ∀ (z : R), z * x = 0 → z = 0}
x✝ : R
hz : x✝ * (a✝ * b✝) = 0
⊢ x✝ = 0
[PROOFSTEP]
rw [← mul_assoc] at hz
[GOAL]
R : Type u_1
inst✝ : MonoidWithZero R
a✝ b✝ : R
hx₁ : a✝ ∈ {x | ∀ (z : R), z * x = 0 → z = 0}
hx₂ : b✝ ∈ {x | ∀ (z : R), z * x = 0 → z = 0}
x✝ : R
hz : x✝ * a✝ * b✝ = 0
⊢ x✝ = 0
[PROOFSTEP]
exact hx₁ _ (hx₂ _ hz)
[GOAL]
R : Type u_1
inst✝ : MonoidWithZero R
x✝ : R
hz : x✝ * 1 = 0
⊢ x✝ = 0
[PROOFSTEP]
rwa [mul_one] at hz
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
x r : M
hr : r ∈ M⁰
⊢ x = 0 → x * r = 0
[PROOFSTEP]
simp (config := { contextual := true })
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
r x : M₁
hr : r ∈ M₁⁰
⊢ r * x = 0 ↔ x = 0
[PROOFSTEP]
rw [mul_comm, mul_right_mem_nonZeroDivisors_eq_zero_iff hr]
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
x y r : R
hr : r ∈ R⁰
⊢ x * r = y * r ↔ x = y
[PROOFSTEP]
refine ⟨fun h ↦ ?_, congrArg (· * r)⟩
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
x y r : R
hr : r ∈ R⁰
h : x * r = y * r
⊢ x = y
[PROOFSTEP]
rw [← sub_eq_zero, ← mul_right_mem_nonZeroDivisors_eq_zero_iff hr, sub_mul, h, sub_self]
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
x y r : R'
hr : r ∈ R'⁰
⊢ r * x = r * y ↔ x = y
[PROOFSTEP]
simp_rw [mul_comm r, mul_cancel_right_mem_nonZeroDivisors hr]
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
⊢ a * b ∈ M₁⁰ ↔ a ∈ M₁⁰ ∧ b ∈ M₁⁰
[PROOFSTEP]
constructor
[GOAL]
case mp
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
⊢ a * b ∈ M₁⁰ → a ∈ M₁⁰ ∧ b ∈ M₁⁰
[PROOFSTEP]
intro h
[GOAL]
case mp
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
⊢ a ∈ M₁⁰ ∧ b ∈ M₁⁰
[PROOFSTEP]
constructor
[GOAL]
case mp.left
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
⊢ a ∈ M₁⁰
[PROOFSTEP]
intro x h'
[GOAL]
case mp.right
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
⊢ b ∈ M₁⁰
[PROOFSTEP]
intro x h'
[GOAL]
case mp.left
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
x : M₁
h' : x * a = 0
⊢ x = 0
[PROOFSTEP]
apply h
[GOAL]
case mp.right
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
x : M₁
h' : x * b = 0
⊢ x = 0
[PROOFSTEP]
apply h
[GOAL]
case mp.left.a
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
x : M₁
h' : x * a = 0
⊢ x * (a * b) = 0
[PROOFSTEP]
rw [← mul_assoc, h', zero_mul]
[GOAL]
case mp.right.a
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
h : a * b ∈ M₁⁰
x : M₁
h' : x * b = 0
⊢ x * (a * b) = 0
[PROOFSTEP]
rw [mul_comm a b, ← mul_assoc, h', zero_mul]
[GOAL]
case mpr
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
⊢ a ∈ M₁⁰ ∧ b ∈ M₁⁰ → a * b ∈ M₁⁰
[PROOFSTEP]
rintro ⟨ha, hb⟩ x hx
[GOAL]
case mpr.intro
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
ha : a ∈ M₁⁰
hb : b ∈ M₁⁰
x : M₁
hx : x * (a * b) = 0
⊢ x = 0
[PROOFSTEP]
apply ha
[GOAL]
case mpr.intro.a
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
ha : a ∈ M₁⁰
hb : b ∈ M₁⁰
x : M₁
hx : x * (a * b) = 0
⊢ x * a = 0
[PROOFSTEP]
apply hb
[GOAL]
case mpr.intro.a.a
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁴ : MonoidWithZero M
inst✝³ : MonoidWithZero M'
inst✝² : CommMonoidWithZero M₁
inst✝¹ : Ring R
inst✝ : CommRing R'
a b : M₁
ha : a ∈ M₁⁰
hb : b ∈ M₁⁰
x : M₁
hx : x * (a * b) = 0
⊢ x * a * b = 0
[PROOFSTEP]
rw [mul_assoc, hx]
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M'
inst✝ : MonoidWithZeroHomClass F M M'
f : F
hf : Function.Injective ↑f
S : Submonoid M
hS : S ≤ M⁰
⊢ Submonoid.map f S ≤ M'⁰
[PROOFSTEP]
cases subsingleton_or_nontrivial M
[GOAL]
case inl
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M'
inst✝ : MonoidWithZeroHomClass F M M'
f : F
hf : Function.Injective ↑f
S : Submonoid M
hS : S ≤ M⁰
h✝ : Subsingleton M
⊢ Submonoid.map f S ≤ M'⁰
[PROOFSTEP]
simp [Subsingleton.elim S ⊥]
[GOAL]
case inr
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M'
inst✝ : MonoidWithZeroHomClass F M M'
f : F
hf : Function.Injective ↑f
S : Submonoid M
hS : S ≤ M⁰
h✝ : Nontrivial M
⊢ Submonoid.map f S ≤ M'⁰
[PROOFSTEP]
exact
  le_nonZeroDivisors_of_noZeroDivisors fun h ↦
    let ⟨x, hx, hx0⟩ := h
    zero_ne_one (hS (hf (hx0.trans (map_zero f).symm) ▸ hx : 0 ∈ S) 1 (mul_zero 1)).symm
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
s : Multiset M₁
⊢ Multiset.prod s = 0 ↔ ∃ r x, r = 0
[PROOFSTEP]
constructor
[GOAL]
case mp
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
s : Multiset M₁
⊢ Multiset.prod s = 0 → ∃ r x, r = 0
case mpr
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
s : Multiset M₁
⊢ (∃ r x, r = 0) → Multiset.prod s = 0
[PROOFSTEP]
swap
[GOAL]
case mpr
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
s : Multiset M₁
⊢ (∃ r x, r = 0) → Multiset.prod s = 0
[PROOFSTEP]
rintro ⟨r, hrs, rfl⟩
[GOAL]
case mpr.intro.intro
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
s : Multiset M₁
hrs : 0 ∈ s
⊢ Multiset.prod s = 0
[PROOFSTEP]
exact Multiset.prod_eq_zero hrs
[GOAL]
case mp
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
s : Multiset M₁
⊢ Multiset.prod s = 0 → ∃ r x, r = 0
[PROOFSTEP]
induction' s using Multiset.induction_on with a s ih
[GOAL]
case mp.empty
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
⊢ Multiset.prod 0 = 0 → ∃ r x, r = 0
[PROOFSTEP]
intro habs
[GOAL]
case mp.empty
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
habs : Multiset.prod 0 = 0
⊢ ∃ r x, r = 0
[PROOFSTEP]
simp at habs
[GOAL]
case mp.cons
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
⊢ Multiset.prod (a ::ₘ s) = 0 → ∃ r x, r = 0
[PROOFSTEP]
rw [Multiset.prod_cons]
[GOAL]
case mp.cons
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
⊢ a * Multiset.prod s = 0 → ∃ r x, r = 0
[PROOFSTEP]
intro hprod
[GOAL]
case mp.cons
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
hprod : a * Multiset.prod s = 0
⊢ ∃ r x, r = 0
[PROOFSTEP]
replace hprod := eq_zero_or_eq_zero_of_mul_eq_zero hprod
[GOAL]
case mp.cons
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
hprod : a = 0 ∨ Multiset.prod s = 0
⊢ ∃ r x, r = 0
[PROOFSTEP]
cases' hprod with ha hb
[GOAL]
case mp.cons.inl
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
ha : a = 0
⊢ ∃ r x, r = 0
[PROOFSTEP]
exact ⟨a, Multiset.mem_cons_self a s, ha⟩
[GOAL]
case mp.cons.inr
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
hb : Multiset.prod s = 0
⊢ ∃ r x, r = 0
[PROOFSTEP]
apply (ih hb).imp _
[GOAL]
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
hb : Multiset.prod s = 0
⊢ ∀ (a_1 : M₁), (∃ x, a_1 = 0) → ∃ x, a_1 = 0
[PROOFSTEP]
rintro b ⟨hb₁, hb₂⟩
[GOAL]
case intro
M : Type u_1
M' : Type u_2
M₁ : Type u_3
R : Type u_4
R' : Type u_5
F : Type u_6
inst✝⁶ : MonoidWithZero M
inst✝⁵ : MonoidWithZero M'
inst✝⁴ : CommMonoidWithZero M₁
inst✝³ : Ring R
inst✝² : CommRing R'
inst✝¹ : NoZeroDivisors M₁
inst✝ : Nontrivial M₁
a : M₁
s : Multiset M₁
ih : Multiset.prod s = 0 → ∃ r x, r = 0
hb : Multiset.prod s = 0
b : M₁
hb₁ : b ∈ s
hb₂ : b = 0
⊢ ∃ x, b = 0
[PROOFSTEP]
exact ⟨Multiset.mem_cons_of_mem hb₁, hb₂⟩


[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g : α → E
⊢ AEMeasurable g ↔ AEMeasurable fun x => ↑(f x) • g x
[PROOFSTEP]
constructor
[GOAL]
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g : α → E
⊢ AEMeasurable g → AEMeasurable fun x => ↑(f x) • g x
[PROOFSTEP]
rintro ⟨g', g'meas, hg'⟩
[GOAL]
case mp.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
⊢ AEMeasurable fun x => ↑(f x) • g x
[PROOFSTEP]
have A : MeasurableSet {x : α | f x ≠ 0} := (hf (measurableSet_singleton 0)).compl
[GOAL]
case mp.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
⊢ AEMeasurable fun x => ↑(f x) • g x
[PROOFSTEP]
refine' ⟨fun x => (f x : ℝ) • g' x, hf.coe_nnreal_real.smul g'meas, _⟩
[GOAL]
case mp.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
⊢ (fun x => ↑(f x) • g x) =ᵐ[μ] fun x => ↑(f x) • g' x
[PROOFSTEP]
apply @ae_of_ae_restrict_of_ae_restrict_compl _ _ _ {x | f x ≠ 0}
[GOAL]
case mp.intro.intro.ht
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
⊢ ∀ᵐ (x : α) ∂Measure.restrict μ {x | f x ≠ 0}, (fun x => ↑(f x) • g x) x = (fun x => ↑(f x) • g' x) x
[PROOFSTEP]
rw [EventuallyEq, ae_withDensity_iff hf.coe_nnreal_ennreal] at hg'
[GOAL]
case mp.intro.intro.ht
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = g' x
A : MeasurableSet {x | f x ≠ 0}
⊢ ∀ᵐ (x : α) ∂Measure.restrict μ {x | f x ≠ 0}, (fun x => ↑(f x) • g x) x = (fun x => ↑(f x) • g' x) x
[PROOFSTEP]
rw [ae_restrict_iff' A]
[GOAL]
case mp.intro.intro.ht
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = g' x
A : MeasurableSet {x | f x ≠ 0}
⊢ ∀ᵐ (x : α) ∂μ, x ∈ {x | f x ≠ 0} → (fun x => ↑(f x) • g x) x = (fun x => ↑(f x) • g' x) x
[PROOFSTEP]
filter_upwards [hg']
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = g' x
A : MeasurableSet {x | f x ≠ 0}
⊢ ∀ (a : α), (↑(f a) ≠ 0 → g a = g' a) → f a ≠ 0 → ↑(f a) • g a = ↑(f a) • g' a
[PROOFSTEP]
intro a ha h'a
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = g' x
A : MeasurableSet {x | f x ≠ 0}
a : α
ha : ↑(f a) ≠ 0 → g a = g' a
h'a : f a ≠ 0
⊢ ↑(f a) • g a = ↑(f a) • g' a
[PROOFSTEP]
have : (f a : ℝ≥0∞) ≠ 0 := by simpa only [Ne.def, coe_eq_zero] using h'a
[GOAL]
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = g' x
A : MeasurableSet {x | f x ≠ 0}
a : α
ha : ↑(f a) ≠ 0 → g a = g' a
h'a : f a ≠ 0
⊢ ↑(f a) ≠ 0
[PROOFSTEP]
simpa only [Ne.def, coe_eq_zero] using h'a
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = g' x
A : MeasurableSet {x | f x ≠ 0}
a : α
ha : ↑(f a) ≠ 0 → g a = g' a
h'a : f a ≠ 0
this : ↑(f a) ≠ 0
⊢ ↑(f a) • g a = ↑(f a) • g' a
[PROOFSTEP]
rw [ha this]
[GOAL]
case mp.intro.intro.htc
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
⊢ ∀ᵐ (x : α) ∂Measure.restrict μ {x | f x ≠ 0}ᶜ, (fun x => ↑(f x) • g x) x = (fun x => ↑(f x) • g' x) x
[PROOFSTEP]
filter_upwards [ae_restrict_mem A.compl]
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
⊢ ∀ (a : α), a ∈ {x | f x ≠ 0}ᶜ → ↑(f a) • g a = ↑(f a) • g' a
[PROOFSTEP]
intro x hx
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
x : α
hx : x ∈ {x | f x ≠ 0}ᶜ
⊢ ↑(f x) • g x = ↑(f x) • g' x
[PROOFSTEP]
simp only [Classical.not_not, mem_setOf_eq, mem_compl_iff] at hx
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
A : MeasurableSet {x | f x ≠ 0}
x : α
hx : f x = 0
⊢ ↑(f x) • g x = ↑(f x) • g' x
[PROOFSTEP]
simp [hx]
[GOAL]
case mpr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g : α → E
⊢ (AEMeasurable fun x => ↑(f x) • g x) → AEMeasurable g
[PROOFSTEP]
rintro ⟨g', g'meas, hg'⟩
[GOAL]
case mpr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
⊢ AEMeasurable g
[PROOFSTEP]
refine' ⟨fun x => (f x : ℝ)⁻¹ • g' x, hf.coe_nnreal_real.inv.smul g'meas, _⟩
[GOAL]
case mpr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
⊢ g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] fun x => (↑(f x))⁻¹ • g' x
[PROOFSTEP]
rw [EventuallyEq, ae_withDensity_iff hf.coe_nnreal_ennreal]
[GOAL]
case mpr.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
⊢ ∀ᵐ (x : α) ∂μ, ↑(f x) ≠ 0 → g x = (↑(f x))⁻¹ • g' x
[PROOFSTEP]
filter_upwards [hg']
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
⊢ ∀ (a : α), ↑(f a) • g a = g' a → ↑(f a) ≠ 0 → g a = (↑(f a))⁻¹ • g' a
[PROOFSTEP]
intro x hx h'x
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
x : α
hx : ↑(f x) • g x = g' x
h'x : ↑(f x) ≠ 0
⊢ g x = (↑(f x))⁻¹ • g' x
[PROOFSTEP]
rw [← hx, smul_smul, _root_.inv_mul_cancel, one_smul]
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
x : α
hx : ↑(f x) • g x = g' x
h'x : ↑(f x) ≠ 0
⊢ ↑(f x) ≠ 0
[PROOFSTEP]
simp only [Ne.def, coe_eq_zero] at h'x
[GOAL]
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : TopologicalSpace.SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : (fun x => ↑(f x) • g x) =ᵐ[μ] g'
x : α
hx : ↑(f x) • g x = g' x
h'x : ¬f x = 0
⊢ ↑(f x) ≠ 0
[PROOFSTEP]
simpa only [NNReal.coe_eq_zero, Ne.def] using h'x


[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
⊢ (yoneda.map (NatTrans.app h.unit X) ≫
      NatTrans.mk fun Y f => L.preimage (↑(Adjunction.homEquiv h Y.unop (L.obj X)).symm f)) =
    𝟙 (yoneda.obj ((𝟭 C).obj X))
[PROOFSTEP]
ext x
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
x : Cᵒᵖ
a✝ : (yoneda.obj ((𝟭 C).obj X)).obj x
⊢ NatTrans.app
      (yoneda.map (NatTrans.app h.unit X) ≫
        NatTrans.mk fun Y f => L.preimage (↑(Adjunction.homEquiv h Y.unop (L.obj X)).symm f))
      x a✝ =
    NatTrans.app (𝟙 (yoneda.obj ((𝟭 C).obj X))) x a✝
[PROOFSTEP]
apply L.map_injective
[GOAL]
case w.h.h.a
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
x : Cᵒᵖ
a✝ : (yoneda.obj ((𝟭 C).obj X)).obj x
⊢ L.map
      (NatTrans.app
        (yoneda.map (NatTrans.app h.unit X) ≫
          NatTrans.mk fun Y f => L.preimage (↑(Adjunction.homEquiv h Y.unop (L.obj X)).symm f))
        x a✝) =
    L.map (NatTrans.app (𝟙 (yoneda.obj ((𝟭 C).obj X))) x a✝)
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
⊢ (NatTrans.mk fun Y f => L.preimage (↑(Adjunction.homEquiv h Y.unop (L.obj X)).symm f)) ≫
      yoneda.map (NatTrans.app h.unit X) =
    𝟙 (yoneda.obj ((L ⋙ R).obj X))
[PROOFSTEP]
ext x
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
x : Cᵒᵖ
a✝ : (yoneda.obj ((L ⋙ R).obj X)).obj x
⊢ NatTrans.app
      ((NatTrans.mk fun Y f => L.preimage (↑(Adjunction.homEquiv h Y.unop (L.obj X)).symm f)) ≫
        yoneda.map (NatTrans.app h.unit X))
      x a✝ =
    NatTrans.app (𝟙 (yoneda.obj ((L ⋙ R).obj X))) x a✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
x : Cᵒᵖ
a✝ : (yoneda.obj ((L ⋙ R).obj X)).obj x
⊢ L.preimage (↑(Adjunction.homEquiv h x.unop (L.obj X)).symm a✝) ≫ NatTrans.app h.unit X = a✝
[PROOFSTEP]
simp only [Adjunction.homEquiv_counit, preimage_comp, preimage_map, Category.assoc]
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
x : Cᵒᵖ
a✝ : (yoneda.obj ((L ⋙ R).obj X)).obj x
⊢ a✝ ≫ L.preimage (NatTrans.app h.counit (L.obj X)) ≫ NatTrans.app h.unit X = a✝
[PROOFSTEP]
rw [← h.unit_naturality]
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
X : C
x : Cᵒᵖ
a✝ : (yoneda.obj ((L ⋙ R).obj X)).obj x
⊢ a✝ ≫ NatTrans.app h.unit (R.obj (L.obj X)) ≫ R.map (L.map (L.preimage (NatTrans.app h.counit (L.obj X)))) = a✝
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X : D
⊢ (coyoneda.map (NatTrans.app h.counit X).op ≫
      NatTrans.mk fun Y f => R.preimage (↑(Adjunction.homEquiv h (R.obj X) Y) f)) =
    𝟙 (coyoneda.obj (op ((𝟭 D).obj X)))
[PROOFSTEP]
ext x
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X x : D
a✝ : (coyoneda.obj (op ((𝟭 D).obj X))).obj x
⊢ NatTrans.app
      (coyoneda.map (NatTrans.app h.counit X).op ≫
        NatTrans.mk fun Y f => R.preimage (↑(Adjunction.homEquiv h (R.obj X) Y) f))
      x a✝ =
    NatTrans.app (𝟙 (coyoneda.obj (op ((𝟭 D).obj X)))) x a✝
[PROOFSTEP]
apply R.map_injective
[GOAL]
case w.h.h.a
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X x : D
a✝ : (coyoneda.obj (op ((𝟭 D).obj X))).obj x
⊢ R.map
      (NatTrans.app
        (coyoneda.map (NatTrans.app h.counit X).op ≫
          NatTrans.mk fun Y f => R.preimage (↑(Adjunction.homEquiv h (R.obj X) Y) f))
        x a✝) =
    R.map (NatTrans.app (𝟙 (coyoneda.obj (op ((𝟭 D).obj X)))) x a✝)
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X : D
⊢ (NatTrans.mk fun Y f => R.preimage (↑(Adjunction.homEquiv h (R.obj X) Y) f)) ≫
      coyoneda.map (NatTrans.app h.counit X).op =
    𝟙 (coyoneda.obj (op ((R ⋙ L).obj X)))
[PROOFSTEP]
ext x
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X x : D
a✝ : (coyoneda.obj (op ((R ⋙ L).obj X))).obj x
⊢ NatTrans.app
      ((NatTrans.mk fun Y f => R.preimage (↑(Adjunction.homEquiv h (R.obj X) Y) f)) ≫
        coyoneda.map (NatTrans.app h.counit X).op)
      x a✝ =
    NatTrans.app (𝟙 (coyoneda.obj (op ((R ⋙ L).obj X)))) x a✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X x : D
a✝ : (coyoneda.obj (op ((R ⋙ L).obj X))).obj x
⊢ NatTrans.app h.counit X ≫ R.preimage (↑(Adjunction.homEquiv h (R.obj X) x) a✝) = a✝
[PROOFSTEP]
simp only [Adjunction.homEquiv_unit, preimage_comp, preimage_map]
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X x : D
a✝ : (coyoneda.obj (op ((R ⋙ L).obj X))).obj x
⊢ NatTrans.app h.counit X ≫ R.preimage (NatTrans.app h.unit (R.obj X)) ≫ a✝ = a✝
[PROOFSTEP]
rw [← h.counit_naturality]
[GOAL]
case w.h.h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
X x : D
a✝ : (coyoneda.obj (op ((R ⋙ L).obj X))).obj x
⊢ L.map (R.map (R.preimage (NatTrans.app h.unit (R.obj X)) ≫ a✝)) ≫ NatTrans.app h.counit x = a✝
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝² : Category.{v₁, u₁} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝ : IsIso h.unit
X Y : C
f g : X ⟶ Y
H : L.map f = L.map g
⊢ f = g
[PROOFSTEP]
rw [← (h.homEquiv X (L.obj Y)).apply_eq_iff_eq] at H
[GOAL]
C : Type u₁
inst✝² : Category.{v₁, u₁} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝ : IsIso h.unit
X Y : C
f g : X ⟶ Y
H : ↑(Adjunction.homEquiv h X (L.obj Y)) (L.map f) = ↑(Adjunction.homEquiv h X (L.obj Y)) (L.map g)
⊢ f = g
[PROOFSTEP]
simpa using H =≫ inv (h.unit.app Y)
[GOAL]
C : Type u₁
inst✝² : Category.{v₁, u₁} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝ : IsIso h.counit
X Y : D
f g : X ⟶ Y
H : R.map f = R.map g
⊢ f = g
[PROOFSTEP]
rw [← (h.homEquiv (R.obj X) Y).symm.apply_eq_iff_eq] at H
[GOAL]
C : Type u₁
inst✝² : Category.{v₁, u₁} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝ : IsIso h.counit
X Y : D
f g : X ⟶ Y
H : ↑(Adjunction.homEquiv h (R.obj X) Y).symm (R.map f) = ↑(Adjunction.homEquiv h (R.obj X) Y).symm (R.map g)
⊢ f = g
[PROOFSTEP]
simpa using inv (h.counit.app X) ≫= H
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
⊢ IsIso (whiskerLeft L h.counit)
[PROOFSTEP]
have := h.left_triangle
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
this : whiskerRight h.unit L ≫ whiskerLeft L h.counit = 𝟙 (𝟭 C ⋙ L)
⊢ IsIso (whiskerLeft L h.counit)
[PROOFSTEP]
rw [← IsIso.eq_inv_comp] at this
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
this : whiskerLeft L h.counit = inv (whiskerRight h.unit L) ≫ 𝟙 (𝟭 C ⋙ L)
⊢ IsIso (whiskerLeft L h.counit)
[PROOFSTEP]
rw [this]
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
this : whiskerLeft L h.counit = inv (whiskerRight h.unit L) ≫ 𝟙 (𝟭 C ⋙ L)
⊢ IsIso (inv (whiskerRight h.unit L) ≫ 𝟙 (𝟭 C ⋙ L))
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
⊢ IsIso (whiskerRight h.counit R)
[PROOFSTEP]
have := h.right_triangle
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
this : whiskerLeft R h.unit ≫ whiskerRight h.counit R = 𝟙 (R ⋙ 𝟭 C)
⊢ IsIso (whiskerRight h.counit R)
[PROOFSTEP]
rw [← IsIso.eq_inv_comp] at this
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
this : whiskerRight h.counit R = inv (whiskerLeft R h.unit) ≫ 𝟙 (R ⋙ 𝟭 C)
⊢ IsIso (whiskerRight h.counit R)
[PROOFSTEP]
rw [this]
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full L
inst✝ : Faithful L
this : whiskerRight h.counit R = inv (whiskerLeft R h.unit) ≫ 𝟙 (R ⋙ 𝟭 C)
⊢ IsIso (inv (whiskerLeft R h.unit) ≫ 𝟙 (R ⋙ 𝟭 C))
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
⊢ IsIso (whiskerLeft R h.unit)
[PROOFSTEP]
have := h.right_triangle
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
this : whiskerLeft R h.unit ≫ whiskerRight h.counit R = 𝟙 (R ⋙ 𝟭 C)
⊢ IsIso (whiskerLeft R h.unit)
[PROOFSTEP]
rw [← IsIso.eq_comp_inv] at this
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
this : whiskerLeft R h.unit = 𝟙 (R ⋙ 𝟭 C) ≫ inv (whiskerRight h.counit R)
⊢ IsIso (whiskerLeft R h.unit)
[PROOFSTEP]
rw [this]
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
this : whiskerLeft R h.unit = 𝟙 (R ⋙ 𝟭 C) ≫ inv (whiskerRight h.counit R)
⊢ IsIso (𝟙 (R ⋙ 𝟭 C) ≫ inv (whiskerRight h.counit R))
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
⊢ IsIso (whiskerRight h.unit L)
[PROOFSTEP]
have := h.left_triangle
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
this : whiskerRight h.unit L ≫ whiskerLeft L h.counit = 𝟙 (𝟭 C ⋙ L)
⊢ IsIso (whiskerRight h.unit L)
[PROOFSTEP]
rw [← IsIso.eq_comp_inv] at this
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
this : whiskerRight h.unit L = 𝟙 (𝟭 C ⋙ L) ≫ inv (whiskerLeft L h.counit)
⊢ IsIso (whiskerRight h.unit L)
[PROOFSTEP]
rw [this]
[GOAL]
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
L : C ⥤ D
R : D ⥤ C
h : L ⊣ R
inst✝¹ : Full R
inst✝ : Faithful R
this : whiskerRight h.unit L = 𝟙 (𝟭 C ⋙ L) ≫ inv (whiskerLeft L h.counit)
⊢ IsIso (𝟙 (𝟭 C ⋙ L) ≫ inv (whiskerLeft L h.counit))
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁶ : Category.{v₂, u₂} D
L✝ : C ⥤ D
R✝ : D ⥤ C
h : L✝ ⊣ R✝
C' : Type u₃
inst✝⁵ : Category.{v₃, u₃} C'
D' : Type u₄
inst✝⁴ : Category.{v₄, u₄} D'
iC : C ⥤ C'
iD : D ⥤ D'
L' : C' ⥤ D'
R' : D' ⥤ C'
adj : L' ⊣ R'
L : C ⥤ D
R : D ⥤ C
comm1 : iC ⋙ L' ≅ L ⋙ iD
comm2 : iD ⋙ R' ≅ R ⋙ iC
inst✝³ : Full iC
inst✝² : Faithful iC
inst✝¹ : Full iD
inst✝ : Faithful iD
X' X : C
Y : D
f : X' ⟶ X
g : X ⟶ R.obj Y
⊢ ↑((fun X Y =>
              Trans.trans
                (Trans.trans
                  (Trans.trans
                    (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                    (homEquiv adj (iC.obj X) (iD.obj Y)))
                  (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                (equivOfFullyFaithful iC).symm)
            X' Y).symm
      (f ≫ g) =
    L.map f ≫
      ↑((fun X Y =>
                Trans.trans
                  (Trans.trans
                    (Trans.trans
                      (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                      (homEquiv adj (iC.obj X) (iD.obj Y)))
                    (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                  (equivOfFullyFaithful iC).symm)
              X Y).symm
        g
[PROOFSTEP]
apply iD.map_injective
[GOAL]
case a
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁶ : Category.{v₂, u₂} D
L✝ : C ⥤ D
R✝ : D ⥤ C
h : L✝ ⊣ R✝
C' : Type u₃
inst✝⁵ : Category.{v₃, u₃} C'
D' : Type u₄
inst✝⁴ : Category.{v₄, u₄} D'
iC : C ⥤ C'
iD : D ⥤ D'
L' : C' ⥤ D'
R' : D' ⥤ C'
adj : L' ⊣ R'
L : C ⥤ D
R : D ⥤ C
comm1 : iC ⋙ L' ≅ L ⋙ iD
comm2 : iD ⋙ R' ≅ R ⋙ iC
inst✝³ : Full iC
inst✝² : Faithful iC
inst✝¹ : Full iD
inst✝ : Faithful iD
X' X : C
Y : D
f : X' ⟶ X
g : X ⟶ R.obj Y
⊢ iD.map
      (↑((fun X Y =>
                Trans.trans
                  (Trans.trans
                    (Trans.trans
                      (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                      (homEquiv adj (iC.obj X) (iD.obj Y)))
                    (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                  (equivOfFullyFaithful iC).symm)
              X' Y).symm
        (f ≫ g)) =
    iD.map
      (L.map f ≫
        ↑((fun X Y =>
                  Trans.trans
                    (Trans.trans
                      (Trans.trans
                        (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                        (homEquiv adj (iC.obj X) (iD.obj Y)))
                      (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                    (equivOfFullyFaithful iC).symm)
                X Y).symm
          g)
[PROOFSTEP]
simpa [Trans.trans] using (comm1.inv.naturality_assoc f _).symm
[GOAL]
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁶ : Category.{v₂, u₂} D
L✝ : C ⥤ D
R✝ : D ⥤ C
h : L✝ ⊣ R✝
C' : Type u₃
inst✝⁵ : Category.{v₃, u₃} C'
D' : Type u₄
inst✝⁴ : Category.{v₄, u₄} D'
iC : C ⥤ C'
iD : D ⥤ D'
L' : C' ⥤ D'
R' : D' ⥤ C'
adj : L' ⊣ R'
L : C ⥤ D
R : D ⥤ C
comm1 : iC ⋙ L' ≅ L ⋙ iD
comm2 : iD ⋙ R' ≅ R ⋙ iC
inst✝³ : Full iC
inst✝² : Faithful iC
inst✝¹ : Full iD
inst✝ : Faithful iD
X : C
Y' Y : D
f : L.obj X ⟶ Y'
g : Y' ⟶ Y
⊢ ↑((fun X Y =>
            Trans.trans
              (Trans.trans
                (Trans.trans
                  (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                  (homEquiv adj (iC.obj X) (iD.obj Y)))
                (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
              (equivOfFullyFaithful iC).symm)
          X Y)
      (f ≫ g) =
    ↑((fun X Y =>
              Trans.trans
                (Trans.trans
                  (Trans.trans
                    (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                    (homEquiv adj (iC.obj X) (iD.obj Y)))
                  (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                (equivOfFullyFaithful iC).symm)
            X Y')
        f ≫
      R.map g
[PROOFSTEP]
apply iC.map_injective
[GOAL]
case a
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁶ : Category.{v₂, u₂} D
L✝ : C ⥤ D
R✝ : D ⥤ C
h : L✝ ⊣ R✝
C' : Type u₃
inst✝⁵ : Category.{v₃, u₃} C'
D' : Type u₄
inst✝⁴ : Category.{v₄, u₄} D'
iC : C ⥤ C'
iD : D ⥤ D'
L' : C' ⥤ D'
R' : D' ⥤ C'
adj : L' ⊣ R'
L : C ⥤ D
R : D ⥤ C
comm1 : iC ⋙ L' ≅ L ⋙ iD
comm2 : iD ⋙ R' ≅ R ⋙ iC
inst✝³ : Full iC
inst✝² : Faithful iC
inst✝¹ : Full iD
inst✝ : Faithful iD
X : C
Y' Y : D
f : L.obj X ⟶ Y'
g : Y' ⟶ Y
⊢ iC.map
      (↑((fun X Y =>
              Trans.trans
                (Trans.trans
                  (Trans.trans
                    (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                    (homEquiv adj (iC.obj X) (iD.obj Y)))
                  (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                (equivOfFullyFaithful iC).symm)
            X Y)
        (f ≫ g)) =
    iC.map
      (↑((fun X Y =>
                Trans.trans
                  (Trans.trans
                    (Trans.trans
                      (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                      (homEquiv adj (iC.obj X) (iD.obj Y)))
                    (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                  (equivOfFullyFaithful iC).symm)
              X Y')
          f ≫
        R.map g)
[PROOFSTEP]
suffices : R'.map (iD.map g) ≫ comm2.hom.app Y = comm2.hom.app Y' ≫ iC.map (R.map g)
[GOAL]
case a
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁶ : Category.{v₂, u₂} D
L✝ : C ⥤ D
R✝ : D ⥤ C
h : L✝ ⊣ R✝
C' : Type u₃
inst✝⁵ : Category.{v₃, u₃} C'
D' : Type u₄
inst✝⁴ : Category.{v₄, u₄} D'
iC : C ⥤ C'
iD : D ⥤ D'
L' : C' ⥤ D'
R' : D' ⥤ C'
adj : L' ⊣ R'
L : C ⥤ D
R : D ⥤ C
comm1 : iC ⋙ L' ≅ L ⋙ iD
comm2 : iD ⋙ R' ≅ R ⋙ iC
inst✝³ : Full iC
inst✝² : Faithful iC
inst✝¹ : Full iD
inst✝ : Faithful iD
X : C
Y' Y : D
f : L.obj X ⟶ Y'
g : Y' ⟶ Y
this : R'.map (iD.map g) ≫ NatTrans.app comm2.hom Y = NatTrans.app comm2.hom Y' ≫ iC.map (R.map g)
⊢ iC.map
      (↑((fun X Y =>
              Trans.trans
                (Trans.trans
                  (Trans.trans
                    (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                    (homEquiv adj (iC.obj X) (iD.obj Y)))
                  (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                (equivOfFullyFaithful iC).symm)
            X Y)
        (f ≫ g)) =
    iC.map
      (↑((fun X Y =>
                Trans.trans
                  (Trans.trans
                    (Trans.trans
                      (Trans.trans (equivOfFullyFaithful iD) (Iso.homCongr (comm1.symm.app X) (Iso.refl (iD.obj Y))))
                      (homEquiv adj (iC.obj X) (iD.obj Y)))
                    (Iso.homCongr (Iso.refl (iC.obj X)) (comm2.app Y)))
                  (equivOfFullyFaithful iC).symm)
              X Y')
          f ≫
        R.map g)
[PROOFSTEP]
simp [Trans.trans, this]
[GOAL]
case this
C : Type u₁
inst✝⁷ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁶ : Category.{v₂, u₂} D
L✝ : C ⥤ D
R✝ : D ⥤ C
h : L✝ ⊣ R✝
C' : Type u₃
inst✝⁵ : Category.{v₃, u₃} C'
D' : Type u₄
inst✝⁴ : Category.{v₄, u₄} D'
iC : C ⥤ C'
iD : D ⥤ D'
L' : C' ⥤ D'
R' : D' ⥤ C'
adj : L' ⊣ R'
L : C ⥤ D
R : D ⥤ C
comm1 : iC ⋙ L' ≅ L ⋙ iD
comm2 : iD ⋙ R' ≅ R ⋙ iC
inst✝³ : Full iC
inst✝² : Faithful iC
inst✝¹ : Full iD
inst✝ : Faithful iD
X : C
Y' Y : D
f : L.obj X ⟶ Y'
g : Y' ⟶ Y
⊢ R'.map (iD.map g) ≫ NatTrans.app comm2.hom Y = NatTrans.app comm2.hom Y' ≫ iC.map (R.map g)
[PROOFSTEP]
apply comm2.hom.naturality g


[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
L M N K : ModuleCat R
f : L ⟶ M
g : M ⟶ N
w✝ : f ≫ g = 0
h k : _root_.homology f g w✝ ⟶ K
w :
  ∀ (x : { x // x ∈ LinearMap.ker g }),
    ↑h (↑(cokernel.π (imageToKernel f g w✝)) (↑toKernelSubobject x)) =
      ↑k (↑(cokernel.π (imageToKernel f g w✝)) (↑toKernelSubobject x))
⊢ h = k
[PROOFSTEP]
refine'
  cokernel_funext fun n =>
    _
      -- porting note: as `equiv_rw` was not ported, it was replaced by `Equiv.surjective`
        -- Gosh it would be nice if `equiv_rw` could directly use an isomorphism, or an enriched `≃`.
[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
L M N K : ModuleCat R
f : L ⟶ M
g : M ⟶ N
w✝ : f ≫ g = 0
h k : _root_.homology f g w✝ ⟶ K
w :
  ∀ (x : { x // x ∈ LinearMap.ker g }),
    ↑h (↑(cokernel.π (imageToKernel f g w✝)) (↑toKernelSubobject x)) =
      ↑k (↑(cokernel.π (imageToKernel f g w✝)) (↑toKernelSubobject x))
n : (CategoryTheory.forget (ModuleCat R)).obj (Subobject.underlying.obj (kernelSubobject g))
⊢ ↑h (↑(cokernel.π (imageToKernel f g w✝)) n) = ↑k (↑(cokernel.π (imageToKernel f g w✝)) n)
[PROOFSTEP]
obtain ⟨n, rfl⟩ := (kernelSubobjectIso g ≪≫ ModuleCat.kernelIsoKer g).toLinearEquiv.toEquiv.symm.surjective n
[GOAL]
case intro
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
L M N K : ModuleCat R
f : L ⟶ M
g : M ⟶ N
w✝ : f ≫ g = 0
h k : _root_.homology f g w✝ ⟶ K
w :
  ∀ (x : { x // x ∈ LinearMap.ker g }),
    ↑h (↑(cokernel.π (imageToKernel f g w✝)) (↑toKernelSubobject x)) =
      ↑k (↑(cokernel.π (imageToKernel f g w✝)) (↑toKernelSubobject x))
n : ↑(of R { x // x ∈ LinearMap.ker g })
⊢ ↑h
      (↑(cokernel.π (imageToKernel f g w✝))
        (↑(LinearEquiv.toEquiv (Iso.toLinearEquiv (kernelSubobjectIso g ≪≫ kernelIsoKer g))).symm n)) =
    ↑k
      (↑(cokernel.π (imageToKernel f g w✝))
        (↑(LinearEquiv.toEquiv (Iso.toLinearEquiv (kernelSubobjectIso g ≪≫ kernelIsoKer g))).symm n))
[PROOFSTEP]
exact w n
[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C✝ D C : HomologicalComplex (ModuleCat R) c
i : ι
x y : ↑(Subobject.underlying.obj (cycles C i))
w : ↑(Subobject.arrow (cycles C i)) x = ↑(Subobject.arrow (cycles C i)) y
⊢ x = y
[PROOFSTEP]
apply_fun (C.cycles i).arrow using (ModuleCat.mono_iff_injective _).mp (cycles C i).arrow_mono
[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C✝ D C : HomologicalComplex (ModuleCat R) c
i : ι
x y : ↑(Subobject.underlying.obj (cycles C i))
w : ↑(Subobject.arrow (cycles C i)) x = ↑(Subobject.arrow (cycles C i)) y
⊢ ↑(Subobject.arrow (cycles C i)) x = ↑(Subobject.arrow (cycles C i)) y
[PROOFSTEP]
exact w
[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f : C ⟶ D
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(Hom.f f i) ↑x ∈ LinearMap.ker (dFrom D i)
[PROOFSTEP]
rw [LinearMap.mem_ker, Hom.comm_from_apply, x.2, map_zero]
[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f : C ⟶ D
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(cyclesMap f i) (toCycles x) =
    toCycles { val := ↑(Hom.f f i) ↑x, property := (_ : ↑(Hom.f f i) ↑x ∈ LinearMap.ker (dFrom D i)) }
[PROOFSTEP]
ext
[GOAL]
case w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f : C ⟶ D
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(Subobject.arrow (cycles D i)) (↑(cyclesMap f i) (toCycles x)) =
    ↑(Subobject.arrow (cycles D i))
      (toCycles { val := ↑(Hom.f f i) ↑x, property := (_ : ↑(Hom.f f i) ↑x ∈ LinearMap.ker (dFrom D i)) })
[PROOFSTEP]
rw [cyclesMap_arrow_apply, toKernelSubobject_arrow, toKernelSubobject_arrow]
[GOAL]
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
⊢ (homologyFunctor (ModuleCat R) c i).map f = (homologyFunctor (ModuleCat R) c i).map g
[PROOFSTEP]
apply homology_ext
[GOAL]
case w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
⊢ ∀ (x : { x // x ∈ LinearMap.ker (dFrom C i) }),
    ↑((homologyFunctor (ModuleCat R) c i).map f)
        (↑(cokernel.π (imageToKernel (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0))) (↑toKernelSubobject x)) =
      ↑((homologyFunctor (ModuleCat R) c i).map g)
        (↑(cokernel.π (imageToKernel (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0))) (↑toKernelSubobject x))
[PROOFSTEP]
intro x
[GOAL]
case w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑((homologyFunctor (ModuleCat R) c i).map f)
      (↑(cokernel.π (imageToKernel (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0))) (↑toKernelSubobject x)) =
    ↑((homologyFunctor (ModuleCat R) c i).map g)
      (↑(cokernel.π (imageToKernel (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0))) (↑toKernelSubobject x))
[PROOFSTEP]
simp only [homologyFunctor_map]
[GOAL]
case w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(homology.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo f i) (Hom.sqFrom f i)
          (_ : (Hom.sqTo f i).right = (Hom.sqTo f i).right))
      (↑(cokernel.π (imageToKernel (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0))) (↑toKernelSubobject x)) =
    ↑(homology.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo g i) (Hom.sqFrom g i)
          (_ : (Hom.sqTo g i).right = (Hom.sqTo g i).right))
      (↑(cokernel.π (imageToKernel (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0))) (↑toKernelSubobject x))
[PROOFSTEP]
erw [homology.π_map_apply, homology.π_map_apply]
  -- To check that two elements are equal mod boundaries, it suffices to exhibit a boundary:
[GOAL]
case w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(homology.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0))
      (↑(kernelSubobjectMap (Hom.sqFrom f i)) (↑toKernelSubobject x)) =
    ↑(homology.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0))
      (↑(kernelSubobjectMap (Hom.sqFrom g i)) (↑toKernelSubobject x))
[PROOFSTEP]
refine'
  cokernel_π_imageSubobject_ext _ _ ((toPrev i h.hom) x.1)
    _
      -- Moreover, to check that two cycles are equal, it suffices to check their underlying elements:
[GOAL]
case w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(kernelSubobjectMap (Hom.sqFrom f i)) (↑toKernelSubobject x) =
    ↑(kernelSubobjectMap (Hom.sqFrom g i)) (↑toKernelSubobject x) +
      ↑(imageToKernel (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0))
        (↑(factorThruImageSubobject (dTo D i)) (↑(↑(toPrev i) h.hom) ↑x))
[PROOFSTEP]
ext
[GOAL]
case w.w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(Subobject.arrow (cycles D i)) (↑(kernelSubobjectMap (Hom.sqFrom f i)) (↑toKernelSubobject x)) =
    ↑(Subobject.arrow (cycles D i))
      (↑(kernelSubobjectMap (Hom.sqFrom g i)) (↑toKernelSubobject x) +
        ↑(imageToKernel (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0))
          (↑(factorThruImageSubobject (dTo D i)) (↑(↑(toPrev i) h.hom) ↑x)))
[PROOFSTEP]
erw [map_add, CategoryTheory.Limits.kernelSubobjectMap_arrow_apply,
  CategoryTheory.Limits.kernelSubobjectMap_arrow_apply, ModuleCat.toKernelSubobject_arrow, imageToKernel_arrow_apply,
  imageSubobject_arrow_comp_apply]
[GOAL]
case w.w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ ↑(Hom.sqFrom f i).left ↑x = ↑(Hom.sqFrom g i).left ↑x + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x)
[PROOFSTEP]
rw [Hom.sqFrom_left, Hom.sqFrom_left, h.comm i, LinearMap.add_apply, LinearMap.add_apply, prevD_eq_toPrev_dTo,
  dNext_eq_dFrom_fromNext, comp_apply, comp_apply, x.2, map_zero]
[GOAL]
case w.w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ 0 + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x) + ↑(Hom.f g i) ↑x = ↑(Hom.f g i) ↑x + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x)
[PROOFSTEP]
dsimp
[GOAL]
case w.w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ 0 + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x) + ↑(Hom.f g i) ↑x = ↑(Hom.f g i) ↑x + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x)
[PROOFSTEP]
abel
[GOAL]
case w.w
R : Type v
inst✝ : Ring R
ι : Type u_1
c : ComplexShape ι
C D : HomologicalComplex (ModuleCat R) c
f g : C ⟶ D
h : Homotopy f g
i : ι
x : { x // x ∈ LinearMap.ker (dFrom C i) }
⊢ 0 + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x) + ↑(Hom.f g i) ↑x = ↑(Hom.f g i) ↑x + ↑(dTo D i) (↑(↑(toPrev i) h.hom) ↑x)
[PROOFSTEP]
abel


[GOAL]
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
⊢ Surjective fun v i => ↑(MvPolynomial.eval v) (ps i)
[PROOFSTEP]
have is_int : ∀ x : R, IsIntegral K x := fun x => isAlgebraic_iff_isIntegral.1 (alg x)
[GOAL]
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
⊢ Surjective fun v i => ↑(MvPolynomial.eval v) (ps i)
[PROOFSTEP]
classical
intro v
cases nonempty_fintype ι
let s : Finset R :=
  (Finset.biUnion (univ : Finset ι) fun i => (ps i).support.image fun x => coeff x (ps i)) ∪ (univ : Finset ι).image v
have hv : ∀ i, v i ∈ Algebra.adjoin K (s : Set R) := fun j =>
  Algebra.subset_adjoin (mem_union_right _ (mem_image.2 ⟨j, mem_univ _, rfl⟩))
have hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ (ps i).support → coeff k (ps i) ∈ Algebra.adjoin K (s : Set R) := fun i k hk =>
  Algebra.subset_adjoin (mem_union_left _ (mem_biUnion.2 ⟨i, mem_univ _, mem_image_of_mem _ hk⟩))
letI := isNoetherian_adjoin_finset s fun x _ => is_int x
letI := Module.IsNoetherian.finite K (Algebra.adjoin K (s : Set R))
letI : Finite (Algebra.adjoin K (s : Set R)) :=
  FiniteDimensional.finite_of_finite K
    (Algebra.adjoin K (s : Set R))
      -- The restriction of the polynomial map, `ps`, to the subalgebra generated by `s`
let res : (ι → Algebra.adjoin K (s : Set R)) → ι → Algebra.adjoin K (s : Set R) := fun x i =>
  ⟨eval (fun j : ι => (x j : R)) (ps i), eval_mem (hs₁ _) fun i => (x i).2⟩
have hres_inj : Injective res := by
  intro x y hxy
  ext i
  simp only [Subtype.ext_iff, funext_iff] at hxy
  exact congr_fun (hinj (funext hxy)) i
have hres_surj : Surjective res := Finite.injective_iff_surjective.1 hres_inj
cases' hres_surj fun i => ⟨v i, hv i⟩ with w hw
use fun i => w i
simpa only [Subtype.ext_iff, funext_iff] using hw
[GOAL]
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
⊢ Surjective fun v i => ↑(MvPolynomial.eval v) (ps i)
[PROOFSTEP]
intro v
[GOAL]
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
cases nonempty_fintype ι
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
let s : Finset R :=
  (Finset.biUnion (univ : Finset ι) fun i => (ps i).support.image fun x => coeff x (ps i)) ∪ (univ : Finset ι).image v
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
have hv : ∀ i, v i ∈ Algebra.adjoin K (s : Set R) := fun j =>
  Algebra.subset_adjoin (mem_union_right _ (mem_image.2 ⟨j, mem_univ _, rfl⟩))
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
have hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ (ps i).support → coeff k (ps i) ∈ Algebra.adjoin K (s : Set R) := fun i k hk =>
  Algebra.subset_adjoin (mem_union_left _ (mem_biUnion.2 ⟨i, mem_univ _, mem_image_of_mem _ hk⟩))
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
letI := isNoetherian_adjoin_finset s fun x _ => is_int x
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
letI := Module.IsNoetherian.finite K (Algebra.adjoin K (s : Set R))
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } := Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
letI : Finite (Algebra.adjoin K (s : Set R)) :=
  FiniteDimensional.finite_of_finite K
    (Algebra.adjoin K (s : Set R))
      -- The restriction of the polynomial map, `ps`, to the subalgebra generated by `s`
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
let res : (ι → Algebra.adjoin K (s : Set R)) → ι → Algebra.adjoin K (s : Set R) := fun x i =>
  ⟨eval (fun j : ι => (x j : R)) (ps i), eval_mem (hs₁ _) fun i => (x i).2⟩
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
have hres_inj : Injective res := by
  intro x y hxy
  ext i
  simp only [Subtype.ext_iff, funext_iff] at hxy
  exact congr_fun (hinj (funext hxy)) i
[GOAL]
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
⊢ Injective res
[PROOFSTEP]
intro x y hxy
[GOAL]
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
x y : ι → { x // x ∈ Algebra.adjoin K ↑s }
hxy : res x = res y
⊢ x = y
[PROOFSTEP]
ext i
[GOAL]
case h.a
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
x y : ι → { x // x ∈ Algebra.adjoin K ↑s }
hxy : res x = res y
i : ι
⊢ ↑(x i) = ↑(y i)
[PROOFSTEP]
simp only [Subtype.ext_iff, funext_iff] at hxy
[GOAL]
case h.a
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
x y : ι → { x // x ∈ Algebra.adjoin K ↑s }
i : ι
hxy : ∀ (a : ι), ↑(MvPolynomial.eval fun j => ↑(x j)) (ps a) = ↑(MvPolynomial.eval fun j => ↑(y j)) (ps a)
⊢ ↑(x i) = ↑(y i)
[PROOFSTEP]
exact congr_fun (hinj (funext hxy)) i
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
hres_inj : Injective res
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
have hres_surj : Surjective res := Finite.injective_iff_surjective.1 hres_inj
[GOAL]
case intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
hres_inj : Injective res
hres_surj : Surjective res
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
cases' hres_surj fun i => ⟨v i, hv i⟩ with w hw
[GOAL]
case intro.intro
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
hres_inj : Injective res
hres_surj : Surjective res
w : ι → { x // x ∈ Algebra.adjoin K ↑s }
hw : res w = fun i => { val := v i, property := (_ : v i ∈ Algebra.adjoin K ↑s) }
⊢ ∃ a, (fun v i => ↑(MvPolynomial.eval v) (ps i)) a = v
[PROOFSTEP]
use fun i => w i
[GOAL]
case h
ι : Type u_1
K : Type u_2
R : Type u_3
inst✝⁴ : Field K
inst✝³ : Finite K
inst✝² : CommRing R
inst✝¹ : Finite ι
inst✝ : Algebra K R
alg : Algebra.IsAlgebraic K R
ps : ι → MvPolynomial ι R
hinj : Injective fun v i => ↑(MvPolynomial.eval v) (ps i)
is_int : ∀ (x : R), IsIntegral K x
v : (i : ι) → (fun x => R) (ps i)
val✝ : Fintype ι
s : Finset R :=
  (Finset.biUnion univ fun i => image (fun x => coeff x (ps i)) (MvPolynomial.support (ps i))) ∪ image v univ
hv : ∀ (i : ι), v i ∈ Algebra.adjoin K ↑s
hs₁ : ∀ (i : ι) (k : ι →₀ ℕ), k ∈ MvPolynomial.support (ps i) → coeff k (ps i) ∈ Algebra.adjoin K ↑s
this✝¹ : IsNoetherian K { x // x ∈ Algebra.adjoin K ↑s } := isNoetherian_adjoin_finset s fun x x_1 => is_int x
this✝ : Module.Finite K { x // x ∈ Algebra.adjoin K ↑s } :=
  Module.IsNoetherian.finite K { x // x ∈ Algebra.adjoin K ↑s }
this : Finite { x // x ∈ Algebra.adjoin K ↑s } := FiniteDimensional.finite_of_finite K { x // x ∈ Algebra.adjoin K ↑s }
res : (ι → { x // x ∈ Algebra.adjoin K ↑s }) → ι → { x // x ∈ Algebra.adjoin K ↑s } :=
  fun x i =>
    { val := ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i),
      property := (_ : ↑(MvPolynomial.eval fun j => ↑(x j)) (ps i) ∈ Algebra.adjoin K ↑s) }
hres_inj : Injective res
hres_surj : Surjective res
w : ι → { x // x ∈ Algebra.adjoin K ↑s }
hw : res w = fun i => { val := v i, property := (_ : v i ∈ Algebra.adjoin K ↑s) }
⊢ ((fun v i => ↑(MvPolynomial.eval v) (ps i)) fun i => ↑(w i)) = v
[PROOFSTEP]
simpa only [Subtype.ext_iff, funext_iff] using hw