[GOAL]
K : Type u_1
inst✝¹ : DivisionRing K
inst✝ : CharZero K
a b : ℕ
h : a ≤ b
⊢ ↑(choose b a) = ↑b ! / (↑a ! * ↑(b - a)!)
[PROOFSTEP]
have : ∀ {n : ℕ}, (n ! : K) ≠ 0 := Nat.cast_ne_zero.2 (factorial_ne_zero _)
[GOAL]
K : Type u_1
inst✝¹ : DivisionRing K
inst✝ : CharZero K
a b : ℕ
h : a ≤ b
this : ∀ {n : ℕ}, ↑n ! ≠ 0
⊢ ↑(choose b a) = ↑b ! / (↑a ! * ↑(b - a)!)
[PROOFSTEP]
rw [eq_div_iff_mul_eq (mul_ne_zero this this)]
[GOAL]
K : Type u_1
inst✝¹ : DivisionRing K
inst✝ : CharZero K
a b : ℕ
h : a ≤ b
this : ∀ {n : ℕ}, ↑n ! ≠ 0
⊢ ↑(choose b a) * (↑a ! * ↑(b - a)!) = ↑b !
[PROOFSTEP]
rw_mod_cast [← mul_assoc, choose_mul_factorial_mul_factorial h]
[GOAL]
K : Type u_1
inst✝¹ : DivisionRing K
inst✝ : CharZero K
a b : ℕ
⊢ ↑(choose (a + b) a) = ↑(a + b)! / (↑a ! * ↑b !)
[PROOFSTEP]
rw [cast_choose K (_root_.le_add_right le_rfl), add_tsub_cancel_left]
[GOAL]
K : Type u_1
inst✝¹ : DivisionRing K
inst✝ : CharZero K
a b : ℕ
⊢ ↑(choose a b) = Polynomial.eval (↑(a - (b - 1))) (pochhammer K b) / ↑b !
[PROOFSTEP]
rw [eq_div_iff_mul_eq (cast_ne_zero.2 b.factorial_ne_zero : (b ! : K) ≠ 0), ← cast_mul, mul_comm, ←
  descFactorial_eq_factorial_mul_choose, ← cast_descFactorial]
[GOAL]
K : Type u_1
inst✝¹ : DivisionRing K
inst✝ : CharZero K
a : ℕ
⊢ ↑(choose a 2) = ↑a * (↑a - 1) / 2
[PROOFSTEP]
rw [← cast_descFactorial_two, descFactorial_eq_factorial_mul_choose, factorial_two, mul_comm, cast_mul, cast_two,
  eq_div_iff_mul_eq (two_ne_zero : (2 : K) ≠ 0)]


[GOAL]
n : ℕ
⊢ ↑n = 1 ↔ Odd n
[PROOFSTEP]
rw [← @Nat.cast_one (ZMod 2), ZMod.eq_iff_modEq_nat, Nat.odd_iff, Nat.ModEq]
[GOAL]
n : ℕ
⊢ n % 2 = 1 % 2 ↔ n % 2 = 1
[PROOFSTEP]
norm_num
[GOAL]
n : ℕ
⊢ ↑n ≠ 0 ↔ Odd n
[PROOFSTEP]
constructor
[GOAL]
case mp
n : ℕ
⊢ ↑n ≠ 0 → Odd n
[PROOFSTEP]
contrapose
[GOAL]
case mp
n : ℕ
⊢ ¬Odd n → ¬↑n ≠ 0
[PROOFSTEP]
simp [eq_zero_iff_even]
[GOAL]
case mpr
n : ℕ
⊢ Odd n → ↑n ≠ 0
[PROOFSTEP]
contrapose
[GOAL]
case mpr
n : ℕ
⊢ ¬↑n ≠ 0 → ¬Odd n
[PROOFSTEP]
simp [eq_zero_iff_even]


[GOAL]
α : Type u_1
inst✝ : DivisionRing α
n✝ : ℤ
a : α
n : ℤ
⊢ (-a) ^ bit1 n = -a ^ bit1 n
[PROOFSTEP]
rw [zpow_bit1', zpow_bit1', neg_mul_neg, neg_mul_eq_mul_neg]
[GOAL]
α : Type u_1
inst✝ : DivisionRing α
n : ℤ
h : Odd n
a : α
⊢ (-a) ^ n = -a ^ n
[PROOFSTEP]
obtain ⟨k, rfl⟩ := h.exists_bit1
[GOAL]
case intro
α : Type u_1
inst✝ : DivisionRing α
a : α
k : ℤ
h : Odd (bit1 k)
⊢ (-a) ^ bit1 k = -a ^ bit1 k
[PROOFSTEP]
exact zpow_bit1_neg _ _
[GOAL]
α : Type u_1
inst✝ : DivisionRing α
n : ℤ
h : Odd n
⊢ (-1) ^ n = -1
[PROOFSTEP]
rw [h.neg_zpow, one_zpow]


[GOAL]
R : Type u_1
M : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : Module.Free R M
inst✝¹ : Module.Finite R M
inst✝ : Nontrivial M
⊢ ↑LinearMap.det 0 = 0
[PROOFSTEP]
letI : Nonempty (Module.Free.ChooseBasisIndex R M) := (Module.Free.chooseBasis R M).index_nonempty
[GOAL]
R : Type u_1
M : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : Module.Free R M
inst✝¹ : Module.Finite R M
inst✝ : Nontrivial M
this : Nonempty (Module.Free.ChooseBasisIndex R M) := Basis.index_nonempty (Module.Free.chooseBasis R M)
⊢ ↑LinearMap.det 0 = 0
[PROOFSTEP]
nontriviality R
[GOAL]
R : Type u_1
M : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : Module.Free R M
inst✝¹ : Module.Finite R M
inst✝ : Nontrivial M
this : Nonempty (Module.Free.ChooseBasisIndex R M) := Basis.index_nonempty (Module.Free.chooseBasis R M)
✝ : Nontrivial R
⊢ ↑LinearMap.det 0 = 0
[PROOFSTEP]
exact LinearMap.det_zero' (Module.Free.chooseBasis R M)


[GOAL]
F : Type u_1
inst✝² : Field F
inst✝¹ : Finite F
inst✝ : Algebra (ZMod (ringChar F)) F
a : F
ha : a ≠ 0
⊢ ∃ b, ↑(Algebra.trace (ZMod (ringChar F)) F) (a * b) ≠ 0
[PROOFSTEP]
haveI : Fact (ringChar F).Prime := ⟨CharP.char_is_prime F _⟩
[GOAL]
F : Type u_1
inst✝² : Field F
inst✝¹ : Finite F
inst✝ : Algebra (ZMod (ringChar F)) F
a : F
ha : a ≠ 0
this : Fact (Nat.Prime (ringChar F))
⊢ ∃ b, ↑(Algebra.trace (ZMod (ringChar F)) F) (a * b) ≠ 0
[PROOFSTEP]
have htr := traceForm_nondegenerate (ZMod (ringChar F)) F a
[GOAL]
F : Type u_1
inst✝² : Field F
inst✝¹ : Finite F
inst✝ : Algebra (ZMod (ringChar F)) F
a : F
ha : a ≠ 0
this : Fact (Nat.Prime (ringChar F))
htr : (∀ (n : F), BilinForm.bilin (Algebra.traceForm (ZMod (ringChar F)) F) a n = 0) → a = 0
⊢ ∃ b, ↑(Algebra.trace (ZMod (ringChar F)) F) (a * b) ≠ 0
[PROOFSTEP]
simp_rw [Algebra.traceForm_apply] at htr
[GOAL]
F : Type u_1
inst✝² : Field F
inst✝¹ : Finite F
inst✝ : Algebra (ZMod (ringChar F)) F
a : F
ha : a ≠ 0
this : Fact (Nat.Prime (ringChar F))
htr : (∀ (n : F), ↑(Algebra.trace (ZMod (ringChar F)) F) (a * n) = 0) → a = 0
⊢ ∃ b, ↑(Algebra.trace (ZMod (ringChar F)) F) (a * b) ≠ 0
[PROOFSTEP]
by_contra' hf
[GOAL]
F : Type u_1
inst✝² : Field F
inst✝¹ : Finite F
inst✝ : Algebra (ZMod (ringChar F)) F
a : F
ha : a ≠ 0
this : Fact (Nat.Prime (ringChar F))
htr : (∀ (n : F), ↑(Algebra.trace (ZMod (ringChar F)) F) (a * n) = 0) → a = 0
hf : ∀ (b : F), ↑(Algebra.trace (ZMod (ringChar F)) F) (a * b) = 0
⊢ False
[PROOFSTEP]
exact ha (htr hf)


[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
⊢ HasDerivAt exp (exp x) x
[PROOFSTEP]
rw [hasDerivAt_iff_isLittleO_nhds_zero]
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
⊢ (fun h => exp (x + h) - exp x - h • exp x) =o[𝓝 0] fun h => h
[PROOFSTEP]
have : (1 : ℕ) < 2 := by norm_num
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
⊢ 1 < 2
[PROOFSTEP]
norm_num
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
this : 1 < 2
⊢ (fun h => exp (x + h) - exp x - h • exp x) =o[𝓝 0] fun h => h
[PROOFSTEP]
refine' (IsBigO.of_bound ‖exp x‖ _).trans_isLittleO (isLittleO_pow_id this)
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
this : 1 < 2
⊢ ∀ᶠ (x_1 : ℂ) in 𝓝 0, ‖exp (x + x_1) - exp x - x_1 • exp x‖ ≤ ‖exp x‖ * ‖x_1 ^ 2‖
[PROOFSTEP]
filter_upwards [Metric.ball_mem_nhds (0 : ℂ) zero_lt_one]
[GOAL]
case h
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
this : 1 < 2
⊢ ∀ (a : ℂ), a ∈ Metric.ball 0 1 → ‖exp (x + a) - exp x - a • exp x‖ ≤ ‖exp x‖ * ‖a ^ 2‖
[PROOFSTEP]
simp only [Metric.mem_ball, dist_zero_right, norm_pow]
[GOAL]
case h
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
x : ℂ
this : 1 < 2
⊢ ∀ (a : ℂ), ‖a‖ < 1 → ‖exp (x + a) - exp x - a • exp x‖ ≤ ‖exp x‖ * ‖a‖ ^ 2
[PROOFSTEP]
exact fun z hz => exp_bound_sq x z hz.le
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
⊢ deriv^[n + 1] exp = exp
[PROOFSTEP]
rw [iterate_succ_apply, deriv_exp, iter_deriv_exp n]
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
⊢ ∀ {n : ℕ∞}, ContDiff 𝕜 n exp
[PROOFSTEP]
refine' @(contDiff_all_iff_nat.2 fun n => ?_)
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
⊢ ContDiff 𝕜 (↑n) exp
[PROOFSTEP]
have : ContDiff ℂ (↑n) exp := by
  induction' n with n ihn
  · exact contDiff_zero.2 continuous_exp
  · rw [contDiff_succ_iff_deriv]
    use differentiable_exp
    rwa [deriv_exp]
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
⊢ ContDiff ℂ (↑n) exp
[PROOFSTEP]
induction' n with n ihn
[GOAL]
case zero
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
⊢ ContDiff ℂ (↑Nat.zero) exp
[PROOFSTEP]
exact contDiff_zero.2 continuous_exp
[GOAL]
case succ
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
ihn : ContDiff ℂ (↑n) exp
⊢ ContDiff ℂ (↑(Nat.succ n)) exp
[PROOFSTEP]
rw [contDiff_succ_iff_deriv]
[GOAL]
case succ
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
ihn : ContDiff ℂ (↑n) exp
⊢ Differentiable ℂ exp ∧ ContDiff ℂ (↑n) (deriv exp)
[PROOFSTEP]
use differentiable_exp
[GOAL]
case right
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
ihn : ContDiff ℂ (↑n) exp
⊢ ContDiff ℂ (↑n) (deriv exp)
[PROOFSTEP]
rwa [deriv_exp]
[GOAL]
𝕜 : Type u_1
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedAlgebra 𝕜 ℂ
n : ℕ
this : ContDiff ℂ (↑n) exp
⊢ ContDiff 𝕜 (↑n) exp
[PROOFSTEP]
exact this.restrict_scalars 𝕜
[GOAL]
x y z : ℝ
n : ℕ
⊢ deriv^[n + 1] exp = exp
[PROOFSTEP]
rw [iterate_succ_apply, deriv_exp, iter_deriv_exp n]


[GOAL]
G : Type u_1
α : Type u_2
inst✝⁴ : Group G
inst✝³ : MulAction G α
inst✝² : MeasurableSpace G
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSMul G α
s : Set α
hs : MeasurableSet s
a : G
⊢ MeasurableSet (a • s)
[PROOFSTEP]
rw [← preimage_smul_inv]
[GOAL]
G : Type u_1
α : Type u_2
inst✝⁴ : Group G
inst✝³ : MulAction G α
inst✝² : MeasurableSpace G
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSMul G α
s : Set α
hs : MeasurableSet s
a : G
⊢ MeasurableSet ((fun x => a⁻¹ • x) ⁻¹' s)
[PROOFSTEP]
exact measurable_const_smul _ hs
[GOAL]
G₀ : Type u_1
α : Type u_2
inst✝⁴ : GroupWithZero G₀
inst✝³ : MulAction G₀ α
inst✝² : MeasurableSpace G₀
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSMul G₀ α
s : Set α
hs : MeasurableSet s
a : G₀
ha : a ≠ 0
⊢ MeasurableSet (a • s)
[PROOFSTEP]
rw [← preimage_smul_inv₀ ha]
[GOAL]
G₀ : Type u_1
α : Type u_2
inst✝⁴ : GroupWithZero G₀
inst✝³ : MulAction G₀ α
inst✝² : MeasurableSpace G₀
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSMul G₀ α
s : Set α
hs : MeasurableSet s
a : G₀
ha : a ≠ 0
⊢ MeasurableSet ((fun x => a⁻¹ • x) ⁻¹' s)
[PROOFSTEP]
exact measurable_const_smul _ hs
[GOAL]
G₀ : Type u_1
α : Type u_2
inst✝⁶ : GroupWithZero G₀
inst✝⁵ : Zero α
inst✝⁴ : MulActionWithZero G₀ α
inst✝³ : MeasurableSpace G₀
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSMul G₀ α
inst✝ : MeasurableSingletonClass α
s : Set α
hs : MeasurableSet s
a : G₀
⊢ MeasurableSet (a • s)
[PROOFSTEP]
rcases eq_or_ne a 0 with (rfl | ha)
[GOAL]
case inl
G₀ : Type u_1
α : Type u_2
inst✝⁶ : GroupWithZero G₀
inst✝⁵ : Zero α
inst✝⁴ : MulActionWithZero G₀ α
inst✝³ : MeasurableSpace G₀
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSMul G₀ α
inst✝ : MeasurableSingletonClass α
s : Set α
hs : MeasurableSet s
⊢ MeasurableSet (0 • s)
case inr
G₀ : Type u_1
α : Type u_2
inst✝⁶ : GroupWithZero G₀
inst✝⁵ : Zero α
inst✝⁴ : MulActionWithZero G₀ α
inst✝³ : MeasurableSpace G₀
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSMul G₀ α
inst✝ : MeasurableSingletonClass α
s : Set α
hs : MeasurableSet s
a : G₀
ha : a ≠ 0
⊢ MeasurableSet (a • s)
[PROOFSTEP]
exacts [(subsingleton_zero_smul_set s).measurableSet, hs.const_smul_of_ne_zero ha]


[GOAL]
R : Type u_1
S : Type u_2
inst✝⁴ : CommRing R
inst✝³ : Nontrivial R
inst✝² : LinearOrderedCommRing S
n : Type u_3
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n R
abv : AbsoluteValue R S
x : S
hx : ∀ (i j : n), ↑abv (A i j) ≤ x
σ : Perm n
x✝ : σ ∈ univ
⊢ ↑abv (↑Perm.sign σ • ∏ i : n, A (↑σ i) i) = ∏ i : n, ↑abv (A (↑σ i) i)
[PROOFSTEP]
rw [abv.map_units_int_smul, abv.map_prod]
[GOAL]
R : Type u_1
S : Type u_2
inst✝⁴ : CommRing R
inst✝³ : Nontrivial R
inst✝² : LinearOrderedCommRing S
n : Type u_3
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n R
abv : AbsoluteValue R S
x : S
hx : ∀ (i j : n), ↑abv (A i j) ≤ x
x✝¹ : Perm n
x✝ : x✝¹ ∈ univ
⊢ ∏ _i : n, x = x ^ Fintype.card n
[PROOFSTEP]
rw [prod_const, Finset.card_univ]
[GOAL]
R : Type u_1
S : Type u_2
inst✝⁴ : CommRing R
inst✝³ : Nontrivial R
inst✝² : LinearOrderedCommRing S
n : Type u_3
inst✝¹ : Fintype n
inst✝ : DecidableEq n
A : Matrix n n R
abv : AbsoluteValue R S
x : S
hx : ∀ (i j : n), ↑abv (A i j) ≤ x
⊢ ∑ _σ : Perm n, x ^ Fintype.card n = Nat.factorial (Fintype.card n) • x ^ Fintype.card n
[PROOFSTEP]
rw [sum_const, Finset.card_univ, Fintype.card_perm]
[GOAL]
R : Type u_1
S : Type u_2
inst✝⁴ : CommRing R
inst✝³ : Nontrivial R
inst✝² : LinearOrderedCommRing S
n : Type u_3
inst✝¹ : Fintype n
inst✝ : DecidableEq n
ι : Type u_4
s : Finset ι
A : ι → Matrix n n R
abv : AbsoluteValue R S
x : S
hx : ∀ (k : ι) (i j : n), ↑abv (A k i j) ≤ x
i j : n
⊢ ↑abv (Finset.sum s (fun k => A k) i j) = ↑abv (∑ k in s, A k i j)
[PROOFSTEP]
simp only [sum_apply]
[GOAL]
R : Type u_1
S : Type u_2
inst✝⁴ : CommRing R
inst✝³ : Nontrivial R
inst✝² : LinearOrderedCommRing S
n : Type u_3
inst✝¹ : Fintype n
inst✝ : DecidableEq n
ι : Type u_4
s : Finset ι
c : ι → R
A : ι → Matrix n n R
abv : AbsoluteValue R S
x : S
hx : ∀ (k : ι) (i j : n), ↑abv (A k i j) ≤ x
y : S
hy : ∀ (k : ι), ↑abv (c k) ≤ y
⊢ ↑abv (det (∑ k in s, c k • A k)) ≤ Nat.factorial (Fintype.card n) • (card s • y * x) ^ Fintype.card n
[PROOFSTEP]
simpa only [smul_mul_assoc] using
  det_sum_le s fun k i j =>
    calc
      abv (c k * A k i j) = abv (c k) * abv (A k i j) := abv.map_mul _ _
      _ ≤ y * x := mul_le_mul (hy k) (hx k i j) (abv.nonneg _) ((abv.nonneg _).trans (hy k))


[GOAL]
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ Int.gcd x y = d
[PROOFSTEP]
refine Nat.dvd_antisymm ?_ (Int.coe_nat_dvd.1 (Int.dvd_gcd h₁ h₂))
[GOAL]
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ Int.gcd x y ∣ d
[PROOFSTEP]
rw [← Int.coe_nat_dvd, ← h₃]
[GOAL]
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ ↑(Int.gcd x y) ∣ x * a + y * b
[PROOFSTEP]
apply dvd_add
[GOAL]
case h₁
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ ↑(Int.gcd x y) ∣ x * a
[PROOFSTEP]
exact (Int.gcd_dvd_left _ _).mul_right _
[GOAL]
case h₂
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ ↑(Int.gcd x y) ∣ y * b
[PROOFSTEP]
exact (Int.gcd_dvd_right _ _).mul_right _
[GOAL]
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ Nat.gcd x y = d
[PROOFSTEP]
rw [← Int.coe_nat_gcd]
[GOAL]
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ Int.gcd ↑x ↑y = d
[PROOFSTEP]
apply
  int_gcd_helper' a (-b) (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hu))
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hv))
[GOAL]
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ ↑x * ↑a + ↑y * -↑b = ↑d
[PROOFSTEP]
rw [mul_neg, ← sub_eq_add_neg, sub_eq_iff_eq_add']
[GOAL]
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ ↑x * ↑a = ↑y * ↑b + ↑d
[PROOFSTEP]
exact_mod_cast h
[GOAL]
x y d m : ℕ
hd : Nat.gcd x y = d
d0 : Nat.beq d 0 = false
dm : x * y = d * m
⊢ (fun x x_1 => x * x_1) d (Nat.lcm x y) = (fun x x_1 => x * x_1) d m
[PROOFSTEP]
dsimp only
  -- Porting note: the `dsimp only` was not necessary in Lean3.
[GOAL]
x y d m : ℕ
hd : Nat.gcd x y = d
d0 : Nat.beq d 0 = false
dm : x * y = d * m
⊢ d * Nat.lcm x y = d * m
[PROOFSTEP]
rw [← dm, ← hd, Nat.gcd_mul_lcm]
[GOAL]
x y : ℤ
x' y' d : ℕ
hx : Int.natAbs x = x'
hy : Int.natAbs y = y'
h : Nat.gcd x' y' = d
⊢ Int.gcd x y = d
[PROOFSTEP]
subst_vars
[GOAL]
x y : ℤ
⊢ Int.gcd x y = Nat.gcd (Int.natAbs x) (Int.natAbs y)
[PROOFSTEP]
rw [Int.gcd_def]
[GOAL]
x y : ℤ
x' y' d : ℕ
hx : Int.natAbs x = x'
hy : Int.natAbs y = y'
h : Nat.lcm x' y' = d
⊢ Int.lcm x y = d
[PROOFSTEP]
subst_vars
[GOAL]
x y : ℤ
⊢ Int.lcm x y = Nat.lcm (Int.natAbs x) (Int.natAbs y)
[PROOFSTEP]
rw [Int.lcm_def]


[GOAL]
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
s : Multiset R
t : Multiset M
⊢ sum s • sum t = sum (map (fun p => p.fst • p.snd) (s ×ˢ t))
[PROOFSTEP]
induction' s using Multiset.induction with a s ih
[GOAL]
case empty
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s : R
x y : M
t : Multiset M
⊢ sum 0 • sum t = sum (map (fun p => p.fst • p.snd) (0 ×ˢ t))
[PROOFSTEP]
simp
[GOAL]
case cons
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
t : Multiset M
a : R
s : Multiset R
ih : sum s • sum t = sum (map (fun p => p.fst • p.snd) (s ×ˢ t))
⊢ sum (a ::ₘ s) • sum t = sum (map (fun p => p.fst • p.snd) ((a ::ₘ s) ×ˢ t))
[PROOFSTEP]
simp [add_smul, ih, ← Multiset.smul_sum]
[GOAL]
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
f : α → R
g : β → M
s : Finset α
t : Finset β
⊢ (∑ i in s, f i) • ∑ i in t, g i = ∑ p in s ×ˢ t, f p.fst • g p.snd
[PROOFSTEP]
rw [Finset.sum_product, Finset.sum_smul, Finset.sum_congr rfl]
[GOAL]
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
f : α → R
g : β → M
s : Finset α
t : Finset β
⊢ ∀ (x : α), x ∈ s → f x • ∑ i in t, g i = ∑ y in t, f (x, y).fst • g (x, y).snd
[PROOFSTEP]
intros
[GOAL]
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
f : α → R
g : β → M
s : Finset α
t : Finset β
x✝ : α
a✝ : x✝ ∈ s
⊢ f x✝ • ∑ i in t, g i = ∑ y in t, f (x✝, y).fst • g (x✝, y).snd
[PROOFSTEP]
rw [Finset.smul_sum]
[GOAL]
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝ : CommSemiring R
s : Finset α
⊢ ↑(card s) = ∑ a in s, 1
[PROOFSTEP]
rw [Finset.sum_const, Nat.smul_one_eq_coe]


[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
⊢ ‖U i j‖ ≤ 1
[PROOFSTEP]
have norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x, ‖U i x‖ ^ 2 :=
  by
  apply Multiset.single_le_sum
  · intro x h_x
    rw [Multiset.mem_map] at h_x
    cases' h_x with a h_a
    rw [← h_a.2]
    apply sq_nonneg
  · rw [Multiset.mem_map]
    use j
    simp only [eq_self_iff_true, Finset.mem_univ_val, and_self_iff, sq_eq_sq]
      -- The L2 norm of a row is a diagonal entry of U * Uᴴ
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
⊢ ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
[PROOFSTEP]
apply Multiset.single_le_sum
[GOAL]
case a
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
⊢ ∀ (x : ℝ), x ∈ Multiset.map (fun x => ‖U i x‖ ^ 2) Finset.univ.val → 0 ≤ x
[PROOFSTEP]
intro x h_x
[GOAL]
case a
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
x : ℝ
h_x : x ∈ Multiset.map (fun x => ‖U i x‖ ^ 2) Finset.univ.val
⊢ 0 ≤ x
[PROOFSTEP]
rw [Multiset.mem_map] at h_x
[GOAL]
case a
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
x : ℝ
h_x : ∃ a, a ∈ Finset.univ.val ∧ ‖U i a‖ ^ 2 = x
⊢ 0 ≤ x
[PROOFSTEP]
cases' h_x with a h_a
[GOAL]
case a.intro
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
x : ℝ
a : n
h_a : a ∈ Finset.univ.val ∧ ‖U i a‖ ^ 2 = x
⊢ 0 ≤ x
[PROOFSTEP]
rw [← h_a.2]
[GOAL]
case a.intro
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
x : ℝ
a : n
h_a : a ∈ Finset.univ.val ∧ ‖U i a‖ ^ 2 = x
⊢ 0 ≤ ‖U i a‖ ^ 2
[PROOFSTEP]
apply sq_nonneg
[GOAL]
case a
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
⊢ ‖U i j‖ ^ 2 ∈ Multiset.map (fun x => ‖U i x‖ ^ 2) Finset.univ.val
[PROOFSTEP]
rw [Multiset.mem_map]
[GOAL]
case a
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
⊢ ∃ a, a ∈ Finset.univ.val ∧ ‖U i a‖ ^ 2 = ‖U i j‖ ^ 2
[PROOFSTEP]
use j
[GOAL]
case h
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
⊢ j ∈ Finset.univ.val ∧ ‖U i j‖ ^ 2 = ‖U i j‖ ^ 2
[PROOFSTEP]
simp only [eq_self_iff_true, Finset.mem_univ_val, and_self_iff, sq_eq_sq]
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
⊢ ‖U i j‖ ≤ 1
[PROOFSTEP]
have diag_eq_norm_sum : (U * Uᴴ) i i = ∑ x : n, ‖U i x‖ ^ 2 := by
  simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, IsROrC.mul_conj, IsROrC.normSq_eq_def',
    IsROrC.ofReal_pow];
  norm_cast
    -- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
⊢ (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
[PROOFSTEP]
simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, IsROrC.mul_conj, IsROrC.normSq_eq_def',
  IsROrC.ofReal_pow]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
⊢ ∑ x : n, ↑‖U i x‖ ^ 2 = ↑(∑ x : n, ‖U i x‖ ^ 2)
[PROOFSTEP]
norm_cast
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
⊢ ‖U i j‖ ≤ 1
[PROOFSTEP]
have re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2 :=
  by
  rw [IsROrC.ext_iff] at diag_eq_norm_sum
  rw [diag_eq_norm_sum.1]
  norm_cast
    -- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
⊢ ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
[PROOFSTEP]
rw [IsROrC.ext_iff] at diag_eq_norm_sum
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum✝ : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
diag_eq_norm_sum :
  ↑IsROrC.re ((U * Uᴴ) i i) = ↑IsROrC.re ↑(∑ x : n, ‖U i x‖ ^ 2) ∧
    ↑IsROrC.im ((U * Uᴴ) i i) = ↑IsROrC.im ↑(∑ x : n, ‖U i x‖ ^ 2)
⊢ ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
[PROOFSTEP]
rw [diag_eq_norm_sum.1]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum✝ : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
diag_eq_norm_sum :
  ↑IsROrC.re ((U * Uᴴ) i i) = ↑IsROrC.re ↑(∑ x : n, ‖U i x‖ ^ 2) ∧
    ↑IsROrC.im ((U * Uᴴ) i i) = ↑IsROrC.im ↑(∑ x : n, ‖U i x‖ ^ 2)
⊢ ↑IsROrC.re ↑(∑ x : n, ‖U i x‖ ^ 2) = ∑ x : n, ‖U i x‖ ^ 2
[PROOFSTEP]
norm_cast
  -- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
⊢ ‖U i j‖ ≤ 1
[PROOFSTEP]
have mul_eq_one : U * Uᴴ = 1 := unitary.mul_star_self_of_mem hU
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
⊢ ‖U i j‖ ≤ 1
[PROOFSTEP]
have diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1 := by
  simp only [mul_eq_one, eq_self_iff_true, Matrix.one_apply_eq, IsROrC.one_re]
    -- Putting it all together
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
⊢ ↑IsROrC.re ((U * Uᴴ) i i) = 1
[PROOFSTEP]
simp only [mul_eq_one, eq_self_iff_true, Matrix.one_apply_eq, IsROrC.one_re]
  -- Putting it all together
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
diag_eq_one : ↑IsROrC.re ((U * Uᴴ) i i) = 1
⊢ ‖U i j‖ ≤ 1
[PROOFSTEP]
rw [← sq_le_one_iff (norm_nonneg (U i j)), ← diag_eq_one, re_diag_eq_norm_sum]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : ↑IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
diag_eq_one : ↑IsROrC.re ((U * Uᴴ) i i) = 1
⊢ ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
[PROOFSTEP]
exact norm_sum
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
⊢ ‖U‖ ≤ 1
[PROOFSTEP]
conv =>
  -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
  rw [pi_norm_le_iff_of_nonneg zero_le_one]
  intro
  rw [pi_norm_le_iff_of_nonneg zero_le_one]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ‖U‖ ≤ 1
[PROOFSTEP]
  rw [pi_norm_le_iff_of_nonneg zero_le_one]
  intro
  rw [pi_norm_le_iff_of_nonneg zero_le_one]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ‖U‖ ≤ 1
[PROOFSTEP]
  rw [pi_norm_le_iff_of_nonneg zero_le_one]
  intro
  rw [pi_norm_le_iff_of_nonneg zero_le_one]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ‖U‖ ≤ 1
[PROOFSTEP]
rw [pi_norm_le_iff_of_nonneg zero_le_one]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ∀ (i : n), ‖U i‖ ≤ 1
[PROOFSTEP]
intro
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i✝ : n
| ‖U i✝‖ ≤ 1
[PROOFSTEP]
rw [pi_norm_le_iff_of_nonneg zero_le_one]
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
⊢ ∀ (i i_1 : n), ‖U i i_1‖ ≤ 1
[PROOFSTEP]
intros
[GOAL]
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i✝¹ i✝ : n
⊢ ‖U i✝¹ i✝‖ ≤ 1
[PROOFSTEP]
exact entry_norm_bound_of_unitary hU _ _


[GOAL]
⊢ DecidableRel fun x x_1 => x ≤ x_1
[PROOFSTEP]
infer_instance
[GOAL]
⊢ DecidableEq ℤ
[PROOFSTEP]
infer_instance
[GOAL]
⊢ DecidableRel fun x x_1 => x < x_1
[PROOFSTEP]
infer_instance
[GOAL]
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hlt₂ : 0 < b
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
have : 0 < a * b := Int.mul_pos hlt₁ hlt₂
[GOAL]
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hlt₂ : 0 < b
this : 0 < a * b
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
rw [h] at this
[GOAL]
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hlt₂ : 0 < b
this : 0 < 0
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
exact absurd this (lt_irrefl _)
[GOAL]
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hgt₂ : b < 0
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
have : 0 > a * b := Int.mul_neg_of_pos_of_neg hlt₁ hgt₂
[GOAL]
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hgt₂ : b < 0
this : 0 > a * b
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
rw [h] at this
[GOAL]
a b : ℤ
h : a * b = 0
hlt₁ : 0 < a
hgt₂ : b < 0
this : 0 > 0
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
exact absurd this (lt_irrefl _)
[GOAL]
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hlt₂ : 0 < b
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
have : 0 > a * b := Int.mul_neg_of_neg_of_pos hgt₁ hlt₂
[GOAL]
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hlt₂ : 0 < b
this : 0 > a * b
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
rw [h] at this
[GOAL]
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hlt₂ : 0 < b
this : 0 > 0
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
exact absurd this (lt_irrefl _)
[GOAL]
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hgt₂ : b < 0
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
have : 0 < a * b := Int.mul_pos_of_neg_of_neg hgt₁ hgt₂
[GOAL]
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hgt₂ : b < 0
this : 0 < a * b
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
rw [h] at this
[GOAL]
a b : ℤ
h : a * b = 0
hgt₁ : a < 0
hgt₂ : b < 0
this : 0 < 0
⊢ a = 0 ∨ b = 0
[PROOFSTEP]
exact absurd this (lt_irrefl _)


[GOAL]
n : ℕ
α : Type u_1
inst✝ : LinearOrder α
f : Fin n → α
P : (Fin n → α) → Prop
hf : P f
h :
  ∀ (σ : Equiv.Perm (Fin n)) (i j : Fin n),
    i < j → (f ∘ ↑σ) j < (f ∘ ↑σ) i → P (f ∘ ↑σ) → P (f ∘ ↑σ ∘ ↑(Equiv.swap i j))
⊢ P (f ∘ ↑(sort f))
[PROOFSTEP]
letI := @Preorder.lift _ (Lex (Fin n → α)) _ fun σ : Equiv.Perm (Fin n) => toLex (f ∘ σ)
[GOAL]
n : ℕ
α : Type u_1
inst✝ : LinearOrder α
f : Fin n → α
P : (Fin n → α) → Prop
hf : P f
h :
  ∀ (σ : Equiv.Perm (Fin n)) (i j : Fin n),
    i < j → (f ∘ ↑σ) j < (f ∘ ↑σ) i → P (f ∘ ↑σ) → P (f ∘ ↑σ ∘ ↑(Equiv.swap i j))
this : Preorder (Equiv.Perm (Fin n)) := Preorder.lift fun σ => ↑toLex (f ∘ ↑σ)
⊢ P (f ∘ ↑(sort f))
[PROOFSTEP]
refine'
  @WellFounded.induction_bot' _ _ _ (IsWellFounded.wf : WellFounded (· < ·)) (Equiv.refl _) (sort f) P (fun σ => f ∘ σ)
    (fun σ hσ hfσ => _) hf
[GOAL]
n : ℕ
α : Type u_1
inst✝ : LinearOrder α
f : Fin n → α
P : (Fin n → α) → Prop
hf : P f
h :
  ∀ (σ : Equiv.Perm (Fin n)) (i j : Fin n),
    i < j → (f ∘ ↑σ) j < (f ∘ ↑σ) i → P (f ∘ ↑σ) → P (f ∘ ↑σ ∘ ↑(Equiv.swap i j))
this : Preorder (Equiv.Perm (Fin n)) := Preorder.lift fun σ => ↑toLex (f ∘ ↑σ)
σ : Fin n ≃ Fin n
hσ : (fun σ => f ∘ ↑σ) σ ≠ (fun σ => f ∘ ↑σ) (sort f)
hfσ : P ((fun σ => f ∘ ↑σ) σ)
⊢ ∃ c, c < σ ∧ P ((fun σ => f ∘ ↑σ) c)
[PROOFSTEP]
obtain ⟨i, j, hij₁, hij₂⟩ := antitone_pair_of_not_sorted' hσ
[GOAL]
case intro.intro.intro
n : ℕ
α : Type u_1
inst✝ : LinearOrder α
f : Fin n → α
P : (Fin n → α) → Prop
hf : P f
h :
  ∀ (σ : Equiv.Perm (Fin n)) (i j : Fin n),
    i < j → (f ∘ ↑σ) j < (f ∘ ↑σ) i → P (f ∘ ↑σ) → P (f ∘ ↑σ ∘ ↑(Equiv.swap i j))
this : Preorder (Equiv.Perm (Fin n)) := Preorder.lift fun σ => ↑toLex (f ∘ ↑σ)
σ : Fin n ≃ Fin n
hσ : (fun σ => f ∘ ↑σ) σ ≠ (fun σ => f ∘ ↑σ) (sort f)
hfσ : P ((fun σ => f ∘ ↑σ) σ)
i j : Fin n
hij₁ : i < j
hij₂ : (f ∘ ↑σ) j < (f ∘ ↑σ) i
⊢ ∃ c, c < σ ∧ P ((fun σ => f ∘ ↑σ) c)
[PROOFSTEP]
exact ⟨σ * Equiv.swap i j, Pi.lex_desc hij₁.le hij₂, h σ i j hij₁ hij₂ hfσ⟩


[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
⊢ ∀ (n : ℕ),
    (∀ (m : ℕ), m < n → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts) →
      ∃ conts, continuantsAux (of v) n = Pair.map Rat.cast conts
[PROOFSTEP]
clear n
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
⊢ ∀ (n : ℕ),
    (∀ (m : ℕ), m < n → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts) →
      ∃ conts, continuantsAux (of v) n = Pair.map Rat.cast conts
[PROOFSTEP]
let g := of v
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
⊢ ∀ (n : ℕ),
    (∀ (m : ℕ), m < n → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts) →
      ∃ conts, continuantsAux (of v) n = Pair.map Rat.cast conts
[PROOFSTEP]
intro n IH
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < n → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ ∃ conts, continuantsAux (of v) n = Pair.map Rat.cast conts
[PROOFSTEP]
rcases n with
  (_ | _ | n)
    -- n = 0
[GOAL]
case zero
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ ∃ conts, continuantsAux (of v) Nat.zero = Pair.map Rat.cast conts
[PROOFSTEP]
suffices ∃ gp : Pair ℚ, Pair.mk (1 : K) 0 = gp.map (↑) by simpa [continuantsAux]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
this : ∃ gp, { a := 1, b := 0 } = Pair.map Rat.cast gp
⊢ ∃ conts, continuantsAux (of v) Nat.zero = Pair.map Rat.cast conts
[PROOFSTEP]
simpa [continuantsAux]
[GOAL]
case zero
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ ∃ gp, { a := 1, b := 0 } = Pair.map Rat.cast gp
[PROOFSTEP]
use Pair.mk 1 0
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ { a := 1, b := 0 } = Pair.map Rat.cast { a := 1, b := 0 }
[PROOFSTEP]
simp
  -- n = 1
[GOAL]
case succ.zero
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.succ Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ ∃ conts, continuantsAux (of v) (Nat.succ Nat.zero) = Pair.map Rat.cast conts
[PROOFSTEP]
suffices ∃ conts : Pair ℚ, Pair.mk g.h 1 = conts.map (↑) by simpa [continuantsAux]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.succ Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
this : ∃ conts, { a := g.h, b := 1 } = Pair.map Rat.cast conts
⊢ ∃ conts, continuantsAux (of v) (Nat.succ Nat.zero) = Pair.map Rat.cast conts
[PROOFSTEP]
simpa [continuantsAux]
[GOAL]
case succ.zero
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.succ Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ ∃ conts, { a := g.h, b := 1 } = Pair.map Rat.cast conts
[PROOFSTEP]
use Pair.mk ⌊v⌋ 1
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
IH : ∀ (m : ℕ), m < Nat.succ Nat.zero → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ { a := g.h, b := 1 } = Pair.map Rat.cast { a := ↑⌊v⌋, b := 1 }
[PROOFSTEP]
simp
  -- 2 ≤ n
[GOAL]
case succ.succ
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
cases' IH (n + 1) <| lt_add_one (n + 1) with pred_conts pred_conts_eq
[GOAL]
case succ.succ.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
cases' s_ppred_nth_eq : g.s.get? n with gp_n
[GOAL]
case succ.succ.intro.none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
s_ppred_nth_eq : Stream'.Seq.get? g.s n = none
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
use pred_conts
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
s_ppred_nth_eq : Stream'.Seq.get? g.s n = none
⊢ continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast pred_conts
[PROOFSTEP]
have : g.continuantsAux (n + 2) = g.continuantsAux (n + 1) :=
  continuantsAux_stable_of_terminated (n + 1).le_succ s_ppred_nth_eq
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
s_ppred_nth_eq : Stream'.Seq.get? g.s n = none
this : continuantsAux g (n + 2) = continuantsAux g (n + 1)
⊢ continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast pred_conts
[PROOFSTEP]
simp only [this, pred_conts_eq]
  -- option.some
[GOAL]
case succ.succ.intro.some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
cases' IH n <| lt_of_le_of_lt n.le_succ <| lt_add_one <| n + 1 with ppred_conts ppred_conts_eq
[GOAL]
case succ.succ.intro.some.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
ppred_conts : Pair ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast ppred_conts
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
obtain ⟨a_eq_one, z, b_eq_z⟩ : gp_n.a = 1 ∧ ∃ z : ℤ, gp_n.b = (z : K)
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
ppred_conts : Pair ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast ppred_conts
⊢ gp_n.a = 1 ∧ ∃ z, gp_n.b = ↑z
case succ.succ.intro.some.intro.intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
ppred_conts : Pair ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast ppred_conts
a_eq_one : gp_n.a = 1
z : ℤ
b_eq_z : gp_n.b = ↑z
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
exact of_part_num_eq_one_and_exists_int_part_denom_eq s_ppred_nth_eq
[GOAL]
case succ.succ.intro.some.intro.intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
ppred_conts : Pair ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast ppred_conts
a_eq_one : gp_n.a = 1
z : ℤ
b_eq_z : gp_n.b = ↑z
⊢ ∃ conts, continuantsAux (of v) (Nat.succ (Nat.succ n)) = Pair.map Rat.cast conts
[PROOFSTEP]
simp only [a_eq_one, b_eq_z, continuantsAux_recurrence s_ppred_nth_eq ppred_conts_eq pred_conts_eq]
[GOAL]
case succ.succ.intro.some.intro.intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
ppred_conts : Pair ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast ppred_conts
a_eq_one : gp_n.a = 1
z : ℤ
b_eq_z : gp_n.b = ↑z
⊢ ∃ conts,
    { a := ↑z * (Pair.map Rat.cast pred_conts).a + 1 * (Pair.map Rat.cast ppred_conts).a,
        b := ↑z * (Pair.map Rat.cast pred_conts).b + 1 * (Pair.map Rat.cast ppred_conts).b } =
      Pair.map Rat.cast conts
[PROOFSTEP]
use nextContinuants 1 (z : ℚ) ppred_conts pred_conts
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
ppred_conts : Pair ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast ppred_conts
a_eq_one : gp_n.a = 1
z : ℤ
b_eq_z : gp_n.b = ↑z
⊢ { a := ↑z * (Pair.map Rat.cast pred_conts).a + 1 * (Pair.map Rat.cast ppred_conts).a,
      b := ↑z * (Pair.map Rat.cast pred_conts).b + 1 * (Pair.map Rat.cast ppred_conts).b } =
    Pair.map Rat.cast (nextContinuants 1 (↑z) ppred_conts pred_conts)
[PROOFSTEP]
cases ppred_conts
[GOAL]
case h.mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
pred_conts : Pair ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast pred_conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
a_eq_one : gp_n.a = 1
z : ℤ
b_eq_z : gp_n.b = ↑z
a✝ b✝ : ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast { a := a✝, b := b✝ }
⊢ { a := ↑z * (Pair.map Rat.cast pred_conts).a + 1 * (Pair.map Rat.cast { a := a✝, b := b✝ }).a,
      b := ↑z * (Pair.map Rat.cast pred_conts).b + 1 * (Pair.map Rat.cast { a := a✝, b := b✝ }).b } =
    Pair.map Rat.cast (nextContinuants 1 ↑z { a := a✝, b := b✝ } pred_conts)
[PROOFSTEP]
cases pred_conts
[GOAL]
case h.mk.mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
g : GeneralizedContinuedFraction K := of v
n : ℕ
IH : ∀ (m : ℕ), m < Nat.succ (Nat.succ n) → ∃ conts, continuantsAux (of v) m = Pair.map Rat.cast conts
gp_n : Pair K
s_ppred_nth_eq : Stream'.Seq.get? g.s n = some gp_n
a_eq_one : gp_n.a = 1
z : ℤ
b_eq_z : gp_n.b = ↑z
a✝¹ b✝¹ : ℚ
ppred_conts_eq : continuantsAux (of v) n = Pair.map Rat.cast { a := a✝¹, b := b✝¹ }
a✝ b✝ : ℚ
pred_conts_eq : continuantsAux (of v) (n + 1) = Pair.map Rat.cast { a := a✝, b := b✝ }
⊢ { a := ↑z * (Pair.map Rat.cast { a := a✝, b := b✝ }).a + 1 * (Pair.map Rat.cast { a := a✝¹, b := b✝¹ }).a,
      b := ↑z * (Pair.map Rat.cast { a := a✝, b := b✝ }).b + 1 * (Pair.map Rat.cast { a := a✝¹, b := b✝¹ }).b } =
    Pair.map Rat.cast (nextContinuants 1 ↑z { a := a✝¹, b := b✝¹ } { a := a✝, b := b✝ })
[PROOFSTEP]
simp [nextContinuants, nextNumerator, nextDenominator]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
⊢ ∃ conts, continuants (of v) n = Pair.map Rat.cast conts
[PROOFSTEP]
rw [nth_cont_eq_succ_nth_cont_aux]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
⊢ ∃ conts, continuantsAux (of v) (n + 1) = Pair.map Rat.cast conts
[PROOFSTEP]
exact exists_gcf_pair_rat_eq_of_nth_conts_aux v <| n + 1
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
⊢ ∃ q, numerators (of v) n = ↑q
[PROOFSTEP]
rcases exists_gcf_pair_rat_eq_nth_conts v n with ⟨⟨a, _⟩, nth_cont_eq⟩
[GOAL]
case intro.mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
a b✝ : ℚ
nth_cont_eq : continuants (of v) n = Pair.map Rat.cast { a := a, b := b✝ }
⊢ ∃ q, numerators (of v) n = ↑q
[PROOFSTEP]
use a
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
a b✝ : ℚ
nth_cont_eq : continuants (of v) n = Pair.map Rat.cast { a := a, b := b✝ }
⊢ numerators (of v) n = ↑a
[PROOFSTEP]
simp [num_eq_conts_a, nth_cont_eq]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
⊢ ∃ q, denominators (of v) n = ↑q
[PROOFSTEP]
rcases exists_gcf_pair_rat_eq_nth_conts v n with ⟨⟨_, b⟩, nth_cont_eq⟩
[GOAL]
case intro.mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
a✝ b : ℚ
nth_cont_eq : continuants (of v) n = Pair.map Rat.cast { a := a✝, b := b }
⊢ ∃ q, denominators (of v) n = ↑q
[PROOFSTEP]
use b
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
a✝ b : ℚ
nth_cont_eq : continuants (of v) n = Pair.map Rat.cast { a := a✝, b := b }
⊢ denominators (of v) n = ↑b
[PROOFSTEP]
simp [denom_eq_conts_b, nth_cont_eq]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
⊢ ∃ q, convergents (of v) n = ↑q
[PROOFSTEP]
rcases exists_rat_eq_nth_numerator v n with ⟨Aₙ, nth_num_eq⟩
[GOAL]
case intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
Aₙ : ℚ
nth_num_eq : numerators (of v) n = ↑Aₙ
⊢ ∃ q, convergents (of v) n = ↑q
[PROOFSTEP]
rcases exists_rat_eq_nth_denominator v n with ⟨Bₙ, nth_denom_eq⟩
[GOAL]
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
Aₙ : ℚ
nth_num_eq : numerators (of v) n = ↑Aₙ
Bₙ : ℚ
nth_denom_eq : denominators (of v) n = ↑Bₙ
⊢ ∃ q, convergents (of v) n = ↑q
[PROOFSTEP]
use Aₙ / Bₙ
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
Aₙ : ℚ
nth_num_eq : numerators (of v) n = ↑Aₙ
Bₙ : ℚ
nth_denom_eq : denominators (of v) n = ↑Bₙ
⊢ convergents (of v) n = ↑(Aₙ / Bₙ)
[PROOFSTEP]
simp [nth_num_eq, nth_denom_eq, convergent_eq_num_div_denom]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
terminates : Terminates (of v)
⊢ ∃ q, v = ↑q
[PROOFSTEP]
obtain ⟨n, v_eq_conv⟩ : ∃ n, v = (of v).convergents n
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n : ℕ
terminates : Terminates (of v)
⊢ ∃ n, v = convergents (of v) n
case intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n✝ : ℕ
terminates : Terminates (of v)
n : ℕ
v_eq_conv : v = convergents (of v) n
⊢ ∃ q, v = ↑q
[PROOFSTEP]
exact of_correctness_of_terminates terminates
[GOAL]
case intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n✝ : ℕ
terminates : Terminates (of v)
n : ℕ
v_eq_conv : v = convergents (of v) n
⊢ ∃ q, v = ↑q
[PROOFSTEP]
obtain ⟨q, conv_eq_q⟩ : ∃ q : ℚ, (of v).convergents n = (↑q : K)
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n✝ : ℕ
terminates : Terminates (of v)
n : ℕ
v_eq_conv : v = convergents (of v) n
⊢ ∃ q, convergents (of v) n = ↑q
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n✝ : ℕ
terminates : Terminates (of v)
n : ℕ
v_eq_conv : v = convergents (of v) n
q : ℚ
conv_eq_q : convergents (of v) n = ↑q
⊢ ∃ q, v = ↑q
[PROOFSTEP]
exact exists_rat_eq_nth_convergent v n
[GOAL]
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n✝ : ℕ
terminates : Terminates (of v)
n : ℕ
v_eq_conv : v = convergents (of v) n
q : ℚ
conv_eq_q : convergents (of v) n = ↑q
⊢ ∃ q, v = ↑q
[PROOFSTEP]
have : v = (↑q : K) := Eq.trans v_eq_conv conv_eq_q
[GOAL]
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
n✝ : ℕ
terminates : Terminates (of v)
n : ℕ
v_eq_conv : v = convergents (of v) n
q : ℚ
conv_eq_q : convergents (of v) n = ↑q
this : v = ↑q
⊢ ∃ q, v = ↑q
[PROOFSTEP]
use q, this
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ mapFr Rat.cast (IntFractPair.of q) = IntFractPair.of v
[PROOFSTEP]
simp [IntFractPair.of, v_eq_q]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream v n
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q Nat.zero) = IntFractPair.stream v Nat.zero
case succ
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream v n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case zero =>
  -- Porting note: was
      -- simp [IntFractPair.stream, coe_of_rat_eq v_eq_q]simp only [IntFractPair.stream, Option.map_some',
    coe_of_rat_eq v_eq_q]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q Nat.zero) = IntFractPair.stream v Nat.zero
[PROOFSTEP]
case zero =>
  -- Porting note: was
      -- simp [IntFractPair.stream, coe_of_rat_eq v_eq_q]simp only [IntFractPair.stream, Option.map_some',
    coe_of_rat_eq v_eq_q]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q Nat.zero) = IntFractPair.stream v Nat.zero
[PROOFSTEP]
simp only [IntFractPair.stream, Option.map_some', coe_of_rat_eq v_eq_q]
[GOAL]
case succ
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream v n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case succ =>
  rw [v_eq_q] at IH
  cases' stream_q_nth_eq : IntFractPair.stream q n with ifp_n
  case none => simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq]
  case some =>
    cases' ifp_n with b fr
    cases' Decidable.em (fr = 0) with fr_zero fr_ne_zero
    · simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_zero]
    · replace IH : some (IntFractPair.mk b (fr : K)) = IntFractPair.stream (↑q) n; · rwa [stream_q_nth_eq] at IH
      have : (fr : K)⁻¹ = ((fr⁻¹ : ℚ) : K) := by norm_cast
      have coe_of_fr := coe_of_rat_eq this
      simpa [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_ne_zero]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream v n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case succ =>
  rw [v_eq_q] at IH
  cases' stream_q_nth_eq : IntFractPair.stream q n with ifp_n
  case none => simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq]
  case some =>
    cases' ifp_n with b fr
    cases' Decidable.em (fr = 0) with fr_zero fr_ne_zero
    · simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_zero]
    · replace IH : some (IntFractPair.mk b (fr : K)) = IntFractPair.stream (↑q) n; · rwa [stream_q_nth_eq] at IH
      have : (fr : K)⁻¹ = ((fr⁻¹ : ℚ) : K) := by norm_cast
      have coe_of_fr := coe_of_rat_eq this
      simpa [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_ne_zero]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream v n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
rw [v_eq_q] at IH
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
cases' stream_q_nth_eq : IntFractPair.stream q n with ifp_n
[GOAL]
case none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
stream_q_nth_eq : IntFractPair.stream q n = none
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
ifp_n : IntFractPair ℚ
stream_q_nth_eq : IntFractPair.stream q n = some ifp_n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case none => simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
stream_q_nth_eq : IntFractPair.stream q n = none
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case none => simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
stream_q_nth_eq : IntFractPair.stream q n = none
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq]
[GOAL]
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
ifp_n : IntFractPair ℚ
stream_q_nth_eq : IntFractPair.stream q n = some ifp_n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case some =>
  cases' ifp_n with b fr
  cases' Decidable.em (fr = 0) with fr_zero fr_ne_zero
  · simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_zero]
  · replace IH : some (IntFractPair.mk b (fr : K)) = IntFractPair.stream (↑q) n; · rwa [stream_q_nth_eq] at IH
    have : (fr : K)⁻¹ = ((fr⁻¹ : ℚ) : K) := by norm_cast
    have coe_of_fr := coe_of_rat_eq this
    simpa [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_ne_zero]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
ifp_n : IntFractPair ℚ
stream_q_nth_eq : IntFractPair.stream q n = some ifp_n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
case some =>
  cases' ifp_n with b fr
  cases' Decidable.em (fr = 0) with fr_zero fr_ne_zero
  · simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_zero]
  · replace IH : some (IntFractPair.mk b (fr : K)) = IntFractPair.stream (↑q) n; · rwa [stream_q_nth_eq] at IH
    have : (fr : K)⁻¹ = ((fr⁻¹ : ℚ) : K) := by norm_cast
    have coe_of_fr := coe_of_rat_eq this
    simpa [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_ne_zero]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
ifp_n : IntFractPair ℚ
stream_q_nth_eq : IntFractPair.stream q n = some ifp_n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
cases' ifp_n with b fr
[GOAL]
case mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
cases' Decidable.em (fr = 0) with fr_zero fr_ne_zero
[GOAL]
case mk.inl
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_zero : fr = 0
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
simp [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_zero]
[GOAL]
case mk.inr
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_ne_zero : ¬fr = 0
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
replace IH : some (IntFractPair.mk b (fr : K)) = IntFractPair.stream (↑q) n
[GOAL]
case IH
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
IH : Option.map (mapFr Rat.cast) (IntFractPair.stream q n) = IntFractPair.stream (↑q) n
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_ne_zero : ¬fr = 0
⊢ some { b := b, fr := ↑fr } = IntFractPair.stream (↑q) n
[PROOFSTEP]
rwa [stream_q_nth_eq] at IH
[GOAL]
case mk.inr
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_ne_zero : ¬fr = 0
IH : some { b := b, fr := ↑fr } = IntFractPair.stream (↑q) n
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
have : (fr : K)⁻¹ = ((fr⁻¹ : ℚ) : K) := by norm_cast
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_ne_zero : ¬fr = 0
IH : some { b := b, fr := ↑fr } = IntFractPair.stream (↑q) n
⊢ (↑fr)⁻¹ = ↑fr⁻¹
[PROOFSTEP]
norm_cast
[GOAL]
case mk.inr
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_ne_zero : ¬fr = 0
IH : some { b := b, fr := ↑fr } = IntFractPair.stream (↑q) n
this : (↑fr)⁻¹ = ↑fr⁻¹
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
have coe_of_fr := coe_of_rat_eq this
[GOAL]
case mk.inr
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
b : ℤ
fr : ℚ
stream_q_nth_eq : IntFractPair.stream q n = some { b := b, fr := fr }
fr_ne_zero : ¬fr = 0
IH : some { b := b, fr := ↑fr } = IntFractPair.stream (↑q) n
this : (↑fr)⁻¹ = ↑fr⁻¹
coe_of_fr : mapFr Rat.cast (IntFractPair.of fr⁻¹) = IntFractPair.of (↑fr)⁻¹
⊢ Option.map (mapFr Rat.cast) (IntFractPair.stream q (Nat.succ n)) = IntFractPair.stream v (Nat.succ n)
[PROOFSTEP]
simpa [IntFractPair.stream, IH.symm, v_eq_q, stream_q_nth_eq, fr_ne_zero]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Stream'.map (Option.map (mapFr Rat.cast)) (IntFractPair.stream q) = IntFractPair.stream v
[PROOFSTEP]
funext n
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
⊢ Stream'.map (Option.map (mapFr Rat.cast)) (IntFractPair.stream q) n = IntFractPair.stream v n
[PROOFSTEP]
exact IntFractPair.coe_stream_nth_rat_eq v_eq_q n
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ ↑(of q).h = (of v).h
[PROOFSTEP]
unfold of IntFractPair.seq1
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ ↑(match
          (IntFractPair.of q,
            Stream'.Seq.tail
              { val := IntFractPair.stream q, property := (_ : Stream'.IsSeq (IntFractPair.stream q)) }) with
        | (h, s) => { h := ↑h.b, s := Stream'.Seq.map (fun p => { a := 1, b := ↑p.b }) s }).h =
    (match
        (IntFractPair.of v,
          Stream'.Seq.tail
            { val := IntFractPair.stream v, property := (_ : Stream'.IsSeq (IntFractPair.stream v)) }) with
      | (h, s) => { h := ↑h.b, s := Stream'.Seq.map (fun p => { a := 1, b := ↑p.b }) s }).h
[PROOFSTEP]
rw [← IntFractPair.coe_of_rat_eq v_eq_q]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ ↑(match
          (IntFractPair.of q,
            Stream'.Seq.tail
              { val := IntFractPair.stream q, property := (_ : Stream'.IsSeq (IntFractPair.stream q)) }) with
        | (h, s) => { h := ↑h.b, s := Stream'.Seq.map (fun p => { a := 1, b := ↑p.b }) s }).h =
    (match
        (IntFractPair.mapFr Rat.cast (IntFractPair.of q),
          Stream'.Seq.tail
            { val := IntFractPair.stream v, property := (_ : Stream'.IsSeq (IntFractPair.stream v)) }) with
      | (h, s) => { h := ↑h.b, s := Stream'.Seq.map (fun p => { a := 1, b := ↑p.b }) s }).h
[PROOFSTEP]
simp
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (Pair.map Rat.cast) (Stream'.Seq.get? (of q).s n) = Stream'.Seq.get? (of v).s n
[PROOFSTEP]
simp only [of, IntFractPair.seq1, Stream'.Seq.map_get?, Stream'.Seq.get?_tail]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (Pair.map Rat.cast)
      (Option.map (fun p => { a := 1, b := ↑p.b })
        (Stream'.Seq.get? { val := IntFractPair.stream q, property := (_ : Stream'.IsSeq (IntFractPair.stream q)) }
          (n + 1))) =
    Option.map (fun p => { a := 1, b := ↑p.b })
      (Stream'.Seq.get? { val := IntFractPair.stream v, property := (_ : Stream'.IsSeq (IntFractPair.stream v)) }
        (n + 1))
[PROOFSTEP]
simp only [Stream'.Seq.get?]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (Pair.map Rat.cast) (Option.map (fun p => { a := 1, b := ↑p.b }) (IntFractPair.stream q (n + 1))) =
    Option.map (fun p => { a := 1, b := ↑p.b }) (IntFractPair.stream v (n + 1))
[PROOFSTEP]
rw [← IntFractPair.coe_stream'_rat_eq v_eq_q]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Option.map (Pair.map Rat.cast) (Option.map (fun p => { a := 1, b := ↑p.b }) (IntFractPair.stream q (n + 1))) =
    Option.map (fun p => { a := 1, b := ↑p.b })
      (Stream'.map (Option.map (IntFractPair.mapFr Rat.cast)) (IntFractPair.stream q) (n + 1))
[PROOFSTEP]
rcases succ_nth_stream_eq : IntFractPair.stream q (n + 1) with (_ | ⟨_, _⟩)
[GOAL]
case none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
succ_nth_stream_eq : IntFractPair.stream q (n + 1) = none
⊢ Option.map (Pair.map Rat.cast) (Option.map (fun p => { a := 1, b := ↑p.b }) none) =
    Option.map (fun p => { a := 1, b := ↑p.b })
      (Stream'.map (Option.map (IntFractPair.mapFr Rat.cast)) (IntFractPair.stream q) (n + 1))
[PROOFSTEP]
simp [Stream'.map, Stream'.nth, succ_nth_stream_eq]
[GOAL]
case some.mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
b✝ : ℤ
fr✝ : ℚ
succ_nth_stream_eq : IntFractPair.stream q (n + 1) = some { b := b✝, fr := fr✝ }
⊢ Option.map (Pair.map Rat.cast) (Option.map (fun p => { a := 1, b := ↑p.b }) (some { b := b✝, fr := fr✝ })) =
    Option.map (fun p => { a := 1, b := ↑p.b })
      (Stream'.map (Option.map (IntFractPair.mapFr Rat.cast)) (IntFractPair.stream q) (n + 1))
[PROOFSTEP]
simp [Stream'.map, Stream'.nth, succ_nth_stream_eq]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ Stream'.Seq.map (Pair.map Rat.cast) (of q).s = (of v).s
[PROOFSTEP]
ext n
[GOAL]
case h.a
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
a✝ : Pair K
⊢ a✝ ∈ Stream'.Seq.get? (Stream'.Seq.map (Pair.map Rat.cast) (of q).s) n ↔ a✝ ∈ Stream'.Seq.get? (of v).s n
[PROOFSTEP]
rw [← coe_of_s_get?_rat_eq v_eq_q]
[GOAL]
case h.a
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n✝ n : ℕ
a✝ : Pair K
⊢ a✝ ∈ Stream'.Seq.get? (Stream'.Seq.map (Pair.map Rat.cast) (of q).s) n ↔
    a✝ ∈ Option.map (Pair.map Rat.cast) (Stream'.Seq.get? (of q).s n)
[PROOFSTEP]
rfl
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
⊢ { h := ↑(of q).h, s := Stream'.Seq.map (Pair.map Rat.cast) (of q).s } = of v
[PROOFSTEP]
cases' gcf_v_eq : of v with h s
[GOAL]
case mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : K
s : Stream'.Seq (Pair K)
gcf_v_eq : of v = { h := h, s := s }
⊢ { h := ↑(of q).h, s := Stream'.Seq.map (Pair.map Rat.cast) (of q).s } = { h := h, s := s }
[PROOFSTEP]
subst v
[GOAL]
case mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
h : K
s : Stream'.Seq (Pair K)
gcf_v_eq : of ↑q = { h := h, s := s }
⊢ { h := ↑(of q).h, s := Stream'.Seq.map (Pair.map Rat.cast) (of q).s } = { h := h, s := s }
[PROOFSTEP]
obtain rfl : ↑⌊(q : K)⌋ = h := by injection gcf_v_eq
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
h : K
s : Stream'.Seq (Pair K)
gcf_v_eq : of ↑q = { h := h, s := s }
⊢ ↑⌊↑q⌋ = h
[PROOFSTEP]
injection gcf_v_eq
[GOAL]
case mk
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
s : Stream'.Seq (Pair K)
gcf_v_eq : of ↑q = { h := ↑⌊↑q⌋, s := s }
⊢ { h := ↑(of q).h, s := Stream'.Seq.map (Pair.map Rat.cast) (of q).s } = { h := ↑⌊↑q⌋, s := s }
[PROOFSTEP]
simp only [gcf_v_eq, Int.cast_inj, Rat.floor_cast, of_h_eq_floor, eq_self_iff_true, Rat.cast_coe_int, and_self,
  coe_of_h_rat_eq rfl, coe_of_s_rat_eq rfl]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
⊢ Terminates (of v) ↔ Terminates (of q)
[PROOFSTEP]
constructor
[GOAL]
case mp
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
⊢ Terminates (of v) → Terminates (of q)
[PROOFSTEP]
intro h
[GOAL]
case mpr
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
⊢ Terminates (of q) → Terminates (of v)
[PROOFSTEP]
intro h
[GOAL]
case mp
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
h : Terminates (of v)
⊢ Terminates (of q)
[PROOFSTEP]
cases' h with n h
[GOAL]
case mpr
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
h : Terminates (of q)
⊢ Terminates (of v)
[PROOFSTEP]
cases' h with n h
[GOAL]
case mp.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Stream'.Seq.TerminatedAt (of v).s n
⊢ Terminates (of q)
[PROOFSTEP]
use n
[GOAL]
case mpr.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Stream'.Seq.TerminatedAt (of q).s n
⊢ Terminates (of v)
[PROOFSTEP]
use n
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Stream'.Seq.TerminatedAt (of v).s n
⊢ Stream'.Seq.TerminatedAt (of q).s n
[PROOFSTEP]
simp only [Stream'.Seq.TerminatedAt, (coe_of_s_get?_rat_eq v_eq_q n).symm] at h ⊢
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Stream'.Seq.TerminatedAt (of q).s n
⊢ Stream'.Seq.TerminatedAt (of v).s n
[PROOFSTEP]
simp only [Stream'.Seq.TerminatedAt, (coe_of_s_get?_rat_eq v_eq_q n).symm] at h ⊢
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Option.map (Pair.map Rat.cast) (Stream'.Seq.get? (of q).s n) = none
⊢ Stream'.Seq.get? (of q).s n = none
[PROOFSTEP]
cases h' : (of q).s.get? n
[GOAL]
case h
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Stream'.Seq.get? (of q).s n = none
⊢ Option.map (Pair.map Rat.cast) (Stream'.Seq.get? (of q).s n) = none
[PROOFSTEP]
cases h' : (of q).s.get? n
[GOAL]
case h.none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Option.map (Pair.map Rat.cast) (Stream'.Seq.get? (of q).s n) = none
h' : Stream'.Seq.get? (of q).s n = none
⊢ none = none
[PROOFSTEP]
simp only [h'] at h
[GOAL]
case h.some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Option.map (Pair.map Rat.cast) (Stream'.Seq.get? (of q).s n) = none
val✝ : Pair ℚ
h' : Stream'.Seq.get? (of q).s n = some val✝
⊢ some val✝ = none
[PROOFSTEP]
simp only [h'] at h
[GOAL]
case h.none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h h' : Stream'.Seq.get? (of q).s n = none
⊢ Option.map (Pair.map Rat.cast) none = none
[PROOFSTEP]
simp only [h'] at h
[GOAL]
case h.some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h : Stream'.Seq.get? (of q).s n = none
val✝ : Pair ℚ
h' : Stream'.Seq.get? (of q).s n = some val✝
⊢ Option.map (Pair.map Rat.cast) (some val✝) = none
[PROOFSTEP]
simp only [h'] at h
[GOAL]
case h.none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h' : Stream'.Seq.get? (of q).s n = none
h : Option.map (Pair.map Rat.cast) none = none
⊢ none = none
[PROOFSTEP]
trivial
[GOAL]
case h.some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
val✝ : Pair ℚ
h' : Stream'.Seq.get? (of q).s n = some val✝
h : Option.map (Pair.map Rat.cast) (some val✝) = none
⊢ some val✝ = none
[PROOFSTEP]
trivial
[GOAL]
case h.none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
v✝ : K
q✝ : ℚ
v_eq_q✝ : v✝ = ↑q✝
n✝ : ℕ
v : K
q : ℚ
v_eq_q : v = ↑q
n : ℕ
h' : Stream'.Seq.get? (of q).s n = none
h : True
⊢ Option.map (Pair.map Rat.cast) none = none
[PROOFSTEP]
trivial
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
⊢ ifp_succ_n.fr.num < ifp_n.fr.num
[PROOFSTEP]
obtain ⟨ifp_n', stream_nth_eq', ifp_n_fract_ne_zero, IntFractPair.of_eq_ifp_succ_n⟩ :
  ∃ ifp_n', IntFractPair.stream q n = some ifp_n' ∧ ifp_n'.fr ≠ 0 ∧ IntFractPair.of ifp_n'.fr⁻¹ = ifp_succ_n
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
⊢ ∃ ifp_n', IntFractPair.stream q n = some ifp_n' ∧ ifp_n'.fr ≠ 0 ∧ IntFractPair.of ifp_n'.fr⁻¹ = ifp_succ_n
case intro.intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
ifp_n' : IntFractPair ℚ
stream_nth_eq' : IntFractPair.stream q n = some ifp_n'
ifp_n_fract_ne_zero : ifp_n'.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n'.fr⁻¹ = ifp_succ_n
⊢ ifp_succ_n.fr.num < ifp_n.fr.num
[PROOFSTEP]
exact succ_nth_stream_eq_some_iff.mp stream_succ_nth_eq
[GOAL]
case intro.intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
ifp_n' : IntFractPair ℚ
stream_nth_eq' : IntFractPair.stream q n = some ifp_n'
ifp_n_fract_ne_zero : ifp_n'.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n'.fr⁻¹ = ifp_succ_n
⊢ ifp_succ_n.fr.num < ifp_n.fr.num
[PROOFSTEP]
have : ifp_n = ifp_n' := by injection Eq.trans stream_nth_eq.symm stream_nth_eq'
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
ifp_n' : IntFractPair ℚ
stream_nth_eq' : IntFractPair.stream q n = some ifp_n'
ifp_n_fract_ne_zero : ifp_n'.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n'.fr⁻¹ = ifp_succ_n
⊢ ifp_n = ifp_n'
[PROOFSTEP]
injection Eq.trans stream_nth_eq.symm stream_nth_eq'
[GOAL]
case intro.intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
ifp_n' : IntFractPair ℚ
stream_nth_eq' : IntFractPair.stream q n = some ifp_n'
ifp_n_fract_ne_zero : ifp_n'.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n'.fr⁻¹ = ifp_succ_n
this : ifp_n = ifp_n'
⊢ ifp_succ_n.fr.num < ifp_n.fr.num
[PROOFSTEP]
cases this
[GOAL]
case intro.intro.intro.refl
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
stream_nth_eq' : IntFractPair.stream q n = some ifp_n
ifp_n_fract_ne_zero : ifp_n.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n.fr⁻¹ = ifp_succ_n
⊢ ifp_succ_n.fr.num < ifp_n.fr.num
[PROOFSTEP]
rw [← IntFractPair.of_eq_ifp_succ_n]
[GOAL]
case intro.intro.intro.refl
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
stream_nth_eq' : IntFractPair.stream q n = some ifp_n
ifp_n_fract_ne_zero : ifp_n.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n.fr⁻¹ = ifp_succ_n
⊢ (IntFractPair.of ifp_n.fr⁻¹).fr.num < ifp_n.fr.num
[PROOFSTEP]
cases' nth_stream_fr_nonneg_lt_one stream_nth_eq with zero_le_ifp_n_fract ifp_n_fract_lt_one
[GOAL]
case intro.intro.intro.refl.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
stream_nth_eq' : IntFractPair.stream q n = some ifp_n
ifp_n_fract_ne_zero : ifp_n.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n.fr⁻¹ = ifp_succ_n
zero_le_ifp_n_fract : 0 ≤ ifp_n.fr
ifp_n_fract_lt_one : ifp_n.fr < 1
⊢ (IntFractPair.of ifp_n.fr⁻¹).fr.num < ifp_n.fr.num
[PROOFSTEP]
have : 0 < ifp_n.fr := lt_of_le_of_ne zero_le_ifp_n_fract <| ifp_n_fract_ne_zero.symm
[GOAL]
case intro.intro.intro.refl.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_n ifp_succ_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
stream_succ_nth_eq : IntFractPair.stream q (n + 1) = some ifp_succ_n
stream_nth_eq' : IntFractPair.stream q n = some ifp_n
ifp_n_fract_ne_zero : ifp_n.fr ≠ 0
IntFractPair.of_eq_ifp_succ_n : IntFractPair.of ifp_n.fr⁻¹ = ifp_succ_n
zero_le_ifp_n_fract : 0 ≤ ifp_n.fr
ifp_n_fract_lt_one : ifp_n.fr < 1
this : 0 < ifp_n.fr
⊢ (IntFractPair.of ifp_n.fr⁻¹).fr.num < ifp_n.fr.num
[PROOFSTEP]
exact of_inv_fr_num_lt_num_of_pos this
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
⊢ ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q Nat.zero = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑Nat.zero
case succ
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q (Nat.succ n) = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑(Nat.succ n)
[PROOFSTEP]
case zero =>
  intro ifp_zero stream_zero_eq
  have : IntFractPair.of q = ifp_zero := by injection stream_zero_eq
  simp [le_refl, this.symm]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q Nat.zero = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑Nat.zero
[PROOFSTEP]
case zero =>
  intro ifp_zero stream_zero_eq
  have : IntFractPair.of q = ifp_zero := by injection stream_zero_eq
  simp [le_refl, this.symm]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q Nat.zero = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑Nat.zero
[PROOFSTEP]
intro ifp_zero stream_zero_eq
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_zero : IntFractPair ℚ
stream_zero_eq : IntFractPair.stream q Nat.zero = some ifp_zero
⊢ ifp_zero.fr.num ≤ (IntFractPair.of q).fr.num - ↑Nat.zero
[PROOFSTEP]
have : IntFractPair.of q = ifp_zero := by injection stream_zero_eq
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_zero : IntFractPair ℚ
stream_zero_eq : IntFractPair.stream q Nat.zero = some ifp_zero
⊢ IntFractPair.of q = ifp_zero
[PROOFSTEP]
injection stream_zero_eq
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n : ℕ
ifp_zero : IntFractPair ℚ
stream_zero_eq : IntFractPair.stream q Nat.zero = some ifp_zero
this : IntFractPair.of q = ifp_zero
⊢ ifp_zero.fr.num ≤ (IntFractPair.of q).fr.num - ↑Nat.zero
[PROOFSTEP]
simp [le_refl, this.symm]
[GOAL]
case succ
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q (Nat.succ n) = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑(Nat.succ n)
[PROOFSTEP]
case succ =>
  intro ifp_succ_n stream_succ_nth_eq
  suffices ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - n
    by
    rw [Int.ofNat_succ, sub_add_eq_sub_sub]
    solve_by_elim [le_sub_right_of_add_le]
  rcases succ_nth_stream_eq_some_iff.mp stream_succ_nth_eq with ⟨ifp_n, stream_nth_eq, -⟩
  have : ifp_succ_n.fr.num < ifp_n.fr.num := stream_succ_nth_fr_num_lt_nth_fr_num_rat stream_nth_eq stream_succ_nth_eq
  have : ifp_succ_n.fr.num + 1 ≤ ifp_n.fr.num := Int.add_one_le_of_lt this
  exact le_trans this (IH stream_nth_eq)
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q (Nat.succ n) = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑(Nat.succ n)
[PROOFSTEP]
case succ =>
  intro ifp_succ_n stream_succ_nth_eq
  suffices ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - n
    by
    rw [Int.ofNat_succ, sub_add_eq_sub_sub]
    solve_by_elim [le_sub_right_of_add_le]
  rcases succ_nth_stream_eq_some_iff.mp stream_succ_nth_eq with ⟨ifp_n, stream_nth_eq, -⟩
  have : ifp_succ_n.fr.num < ifp_n.fr.num := stream_succ_nth_fr_num_lt_nth_fr_num_rat stream_nth_eq stream_succ_nth_eq
  have : ifp_succ_n.fr.num + 1 ≤ ifp_n.fr.num := Int.add_one_le_of_lt this
  exact le_trans this (IH stream_nth_eq)
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
⊢ ∀ {ifp_n : IntFractPair ℚ},
    IntFractPair.stream q (Nat.succ n) = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑(Nat.succ n)
[PROOFSTEP]
intro ifp_succ_n stream_succ_nth_eq
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
⊢ ifp_succ_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑(Nat.succ n)
[PROOFSTEP]
suffices ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - n
  by
  rw [Int.ofNat_succ, sub_add_eq_sub_sub]
  solve_by_elim [le_sub_right_of_add_le]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
this : ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - ↑n
⊢ ifp_succ_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑(Nat.succ n)
[PROOFSTEP]
rw [Int.ofNat_succ, sub_add_eq_sub_sub]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
this : ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - ↑n
⊢ ifp_succ_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n - 1
[PROOFSTEP]
solve_by_elim [le_sub_right_of_add_le]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
⊢ ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - ↑n
[PROOFSTEP]
rcases succ_nth_stream_eq_some_iff.mp stream_succ_nth_eq with ⟨ifp_n, stream_nth_eq, -⟩
[GOAL]
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
ifp_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
⊢ ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - ↑n
[PROOFSTEP]
have : ifp_succ_n.fr.num < ifp_n.fr.num := stream_succ_nth_fr_num_lt_nth_fr_num_rat stream_nth_eq stream_succ_nth_eq
[GOAL]
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
ifp_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
this : ifp_succ_n.fr.num < ifp_n.fr.num
⊢ ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - ↑n
[PROOFSTEP]
have : ifp_succ_n.fr.num + 1 ≤ ifp_n.fr.num := Int.add_one_le_of_lt this
[GOAL]
case intro.intro
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q : ℚ
n✝ n : ℕ
IH : ∀ {ifp_n : IntFractPair ℚ}, IntFractPair.stream q n = some ifp_n → ifp_n.fr.num ≤ (IntFractPair.of q).fr.num - ↑n
ifp_succ_n : IntFractPair ℚ
stream_succ_nth_eq : IntFractPair.stream q (Nat.succ n) = some ifp_succ_n
ifp_n : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp_n
this✝ : ifp_succ_n.fr.num < ifp_n.fr.num
this : ifp_succ_n.fr.num + 1 ≤ ifp_n.fr.num
⊢ ifp_succ_n.fr.num + 1 ≤ (IntFractPair.of q).fr.num - ↑n
[PROOFSTEP]
exact le_trans this (IH stream_nth_eq)
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n : ℕ
q : ℚ
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
let fract_q_num := (Int.fract q).num
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
let n := fract_q_num.natAbs + 1
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
cases' stream_nth_eq : IntFractPair.stream q n with ifp
[GOAL]
case none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
stream_nth_eq : IntFractPair.stream q n = none
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
use n, stream_nth_eq
[GOAL]
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
have ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - n := stream_nth_fr_num_le_fr_num_sub_n_rat stream_nth_eq
[GOAL]
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - ↑n
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
have : fract_q_num - n = -1 :=
  by
  have : 0 ≤ fract_q_num :=
    Rat.num_nonneg_iff_zero_le.mpr
      (Int.fract_nonneg q)
        -- Porting note: was
              -- simp [Int.natAbs_of_nonneg this, sub_add_eq_sub_sub_swap, sub_right_comm]
  simp only [Nat.cast_add, Int.natAbs_of_nonneg this, Nat.cast_one, sub_add_eq_sub_sub_swap, sub_right_comm, sub_self,
    zero_sub]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - ↑n
⊢ fract_q_num - ↑n = -1
[PROOFSTEP]
have : 0 ≤ fract_q_num :=
  Rat.num_nonneg_iff_zero_le.mpr
    (Int.fract_nonneg q)
      -- Porting note: was
            -- simp [Int.natAbs_of_nonneg this, sub_add_eq_sub_sub_swap, sub_right_comm]
[GOAL]
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - ↑n
this : 0 ≤ fract_q_num
⊢ fract_q_num - ↑n = -1
[PROOFSTEP]
simp only [Nat.cast_add, Int.natAbs_of_nonneg this, Nat.cast_one, sub_add_eq_sub_sub_swap, sub_right_comm, sub_self,
  zero_sub]
[GOAL]
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - ↑n
this : fract_q_num - ↑n = -1
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
have : 0 ≤ ifp.fr := (nth_stream_fr_nonneg_lt_one stream_nth_eq).left
[GOAL]
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - ↑n
this✝ : fract_q_num - ↑n = -1
this : 0 ≤ ifp.fr
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
have : 0 ≤ ifp.fr.num := Rat.num_nonneg_iff_zero_le.mpr this
[GOAL]
case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := Int.natAbs fract_q_num + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
ifp_fr_num_le_q_fr_num_sub_n : ifp.fr.num ≤ fract_q_num - ↑n
this✝¹ : fract_q_num - ↑n = -1
this✝ : 0 ≤ ifp.fr
this : 0 ≤ ifp.fr.num
⊢ ∃ n, IntFractPair.stream q n = none
[PROOFSTEP]
linarith


[GOAL]
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝ : MonoidWithZero M₀
a b : M₀
h : Commute a b
⊢ inverse (a * b) = inverse b * inverse a
[PROOFSTEP]
by_cases hab : IsUnit (a * b)
[GOAL]
case pos
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝ : MonoidWithZero M₀
a b : M₀
h : Commute a b
hab : IsUnit (a * b)
⊢ inverse (a * b) = inverse b * inverse a
[PROOFSTEP]
obtain ⟨⟨a, rfl⟩, b, rfl⟩ := h.isUnit_mul_iff.mp hab
[GOAL]
case pos.intro.intro.intro
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝ : MonoidWithZero M₀
a b : M₀ˣ
h : Commute ↑a ↑b
hab : IsUnit (↑a * ↑b)
⊢ inverse (↑a * ↑b) = inverse ↑b * inverse ↑a
[PROOFSTEP]
rw [← Units.val_mul, inverse_unit, inverse_unit, inverse_unit, ← Units.val_mul, mul_inv_rev]
[GOAL]
case neg
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝ : MonoidWithZero M₀
a b : M₀
h : Commute a b
hab : ¬IsUnit (a * b)
⊢ inverse (a * b) = inverse b * inverse a
[PROOFSTEP]
obtain ha | hb := not_and_or.mp (mt h.isUnit_mul_iff.mpr hab)
[GOAL]
case neg.inl
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝ : MonoidWithZero M₀
a b : M₀
h : Commute a b
hab : ¬IsUnit (a * b)
ha : ¬IsUnit a
⊢ inverse (a * b) = inverse b * inverse a
[PROOFSTEP]
rw [inverse_non_unit _ hab, inverse_non_unit _ ha, mul_zero]
[GOAL]
case neg.inr
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝ : MonoidWithZero M₀
a b : M₀
h : Commute a b
hab : ¬IsUnit (a * b)
hb : ¬IsUnit b
⊢ inverse (a * b) = inverse b * inverse a
[PROOFSTEP]
rw [inverse_non_unit _ hab, inverse_non_unit _ hb, zero_mul]
[GOAL]
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝¹ : MonoidWithZero M₀
inst✝ : GroupWithZero G₀
a b c : G₀
hac : Commute a c
hbc : Commute b c
⊢ Commute (a / b) c
[PROOFSTEP]
rw [div_eq_mul_inv]
[GOAL]
α : Type u_1
M₀ : Type u_2
G₀ : Type u_3
M₀' : Type u_4
G₀' : Type u_5
F : Type u_6
F' : Type u_7
inst✝¹ : MonoidWithZero M₀
inst✝ : GroupWithZero G₀
a b c : G₀
hac : Commute a c
hbc : Commute b c
⊢ Commute (a * b⁻¹) c
[PROOFSTEP]
exact hac.mul_left hbc.inv_left₀


[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
⊢ e₁ = e₂
[PROOFSTEP]
simpa only [h₁.left_id, h₁.right_id, h₂.left_id, h₂.right_id] using distrib e₂ e₁ e₁ e₂
[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
⊢ m₁ = m₂
[PROOFSTEP]
funext a b
[GOAL]
case h.h
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
a b : X
⊢ m₁ a b = m₂ a b
[PROOFSTEP]
calc
  m₁ a b = m₁ (m₂ a e₁) (m₂ e₁ b) := by {simp only [one h₁ h₂ distrib, h₁.left_id, h₁.right_id, h₂.left_id, h₂.right_id]
  }
  _ = m₂ a b := by simp only [distrib, h₁.left_id, h₁.right_id, h₂.left_id, h₂.right_id]
[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
a b : X
⊢ m₁ a b = m₁ (m₂ a e₁) (m₂ e₁ b)
[PROOFSTEP]
{simp only [one h₁ h₂ distrib, h₁.left_id, h₁.right_id, h₂.left_id, h₂.right_id]
}
[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
a b : X
⊢ m₁ a b = m₁ (m₂ a e₁) (m₂ e₁ b)
[PROOFSTEP]
simp only [one h₁ h₂ distrib, h₁.left_id, h₁.right_id, h₂.left_id, h₂.right_id]
[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
a b : X
⊢ m₁ (m₂ a e₁) (m₂ e₁ b) = m₂ a b
[PROOFSTEP]
simp only [distrib, h₁.left_id, h₁.right_id, h₂.left_id, h₂.right_id]
[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
a b : X
⊢ m₂ a b = m₂ b a
[PROOFSTEP]
simpa [mul h₁ h₂ distrib, h₂.left_id, h₂.right_id] using distrib e₂ a b e₂
[GOAL]
X : Type u
m₁ m₂ : X → X → X
e₁ e₂ : X
h₁ : IsUnital m₁ e₁
h₂ : IsUnital m₂ e₂
distrib : ∀ (a b c d : X), m₁ (m₂ a b) (m₂ c d) = m₂ (m₁ a c) (m₁ b d)
a b c : X
⊢ m₂ (m₂ a b) c = m₂ a (m₂ b c)
[PROOFSTEP]
simpa [mul h₁ h₂ distrib, h₂.left_id, h₂.right_id] using distrib a b e₂ c


[GOAL]
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h : X ≃ₜ Y
⊢ Homotopic (comp (toContinuousMap (Homeomorph.symm h)) (toContinuousMap h)) (ContinuousMap.id X)
[PROOFSTEP]
rw [symm_comp_toContinuousMap]
[GOAL]
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h : X ≃ₜ Y
⊢ Homotopic (comp (toContinuousMap h) (toContinuousMap (Homeomorph.symm h))) (ContinuousMap.id Y)
[PROOFSTEP]
rw [toContinuousMap_comp_symm]
[GOAL]
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₁.invFun h₂.invFun) (comp h₂.toFun h₁.toFun)) (ContinuousMap.id X)
[PROOFSTEP]
refine Homotopic.trans ?_ h₁.left_inv
[GOAL]
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₁.invFun h₂.invFun) (comp h₂.toFun h₁.toFun)) (comp h₁.invFun h₁.toFun)
[PROOFSTEP]
exact ((Homotopic.refl _).hcomp h₂.left_inv).hcomp (Homotopic.refl _)
[GOAL]
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₂.toFun h₁.toFun) (comp h₁.invFun h₂.invFun)) (ContinuousMap.id Z)
[PROOFSTEP]
refine Homotopic.trans ?_ h₂.right_inv
[GOAL]
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₂.toFun h₁.toFun) (comp h₁.invFun h₂.invFun)) (comp h₂.toFun h₂.invFun)
[PROOFSTEP]
exact ((Homotopic.refl _).hcomp h₁.right_inv).hcomp (Homotopic.refl _)