Theorem: GeneralizedContinuedFraction.IntFractPair.exists_nth_stream_eq_none_of_rat
File: Mathlib/Algebra/ContinuedFractions/Computation/TerminatesIffRat.lean

tactic: let fract_q_num := (Int.fract q).num
state_before: K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n : ℕ
q : ℚ
⊢ ∃ n, IntFractPair.stream q n = none
state_after: 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

tactic: let n := fract_q_num.natAbs + 1
state_before: 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
state_after: K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 1
⊢ ∃ n, IntFractPair.stream q n = none

tactic: cases' stream_nth_eq : IntFractPair.stream q n with ifp
state_before: K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 1
⊢ ∃ n, IntFractPair.stream q n = none
state_after: case none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 1
stream_nth_eq : IntFractPair.stream q n = none
⊢ ∃ n, IntFractPair.stream q n = none

case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
⊢ ∃ n, IntFractPair.stream q n = none

tactic: use n, stream_nth_eq
state_before: case none
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 1
stream_nth_eq : IntFractPair.stream q n = none
⊢ ∃ n, IntFractPair.stream q n = none
state_after: no goals

tactic: 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
state_before: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 1
ifp : IntFractPair ℚ
stream_nth_eq : IntFractPair.stream q n = some ifp
⊢ ∃ n, IntFractPair.stream q n = none
state_after: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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

tactic: have : fract_q_num - n = -1 := by
  have : 0 ≤ fract_q_num := Rat.num_nonneg.mpr (Int.fract_nonneg q)
  simp only [n, Nat.cast_add, Int.natAbs_of_nonneg this, Nat.cast_one,
    sub_add_eq_sub_sub_swap, sub_right_comm, sub_self, zero_sub]
state_before: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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
state_after: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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

tactic: have : 0 ≤ ifp.fr := (nth_stream_fr_nonneg_lt_one stream_nth_eq).left
state_before: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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
state_after: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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

tactic: have : 0 ≤ ifp.fr.num := Rat.num_nonneg.mpr this
state_before: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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
state_after: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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

tactic: omega
state_before: case some
K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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
state_after: no goals

tactic: have : 0 ≤ fract_q_num := Rat.num_nonneg.mpr (Int.fract_nonneg q)
state_before: K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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
state_after: K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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

tactic: simp only [n, Nat.cast_add, Int.natAbs_of_nonneg this, Nat.cast_one,
  sub_add_eq_sub_sub_swap, sub_right_comm, sub_self, zero_sub]
state_before: K : Type u_1
inst✝¹ : LinearOrderedField K
inst✝ : FloorRing K
q✝ : ℚ
n✝ : ℕ
q : ℚ
fract_q_num : ℤ := (Int.fract q).num
n : ℕ := fract_q_num.natAbs + 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
state_after: no goals