-- Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean
lemma eventually_atTop_nonneg_or_nonpos (hf : GrowsPolynomially f) :
    (∀ᶠ x in atTop, 0 ≤ f x) ∨ (∀ᶠ x in atTop, f x ≤ 0)

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
x : ℝ
hxlb : n₀ ⊔ 2 ≤ x
hxub : x < 2 * (n₀ ⊔ 2)
h₁ : n₀ ≤ 2 * (n₀ ⊔ 2)
⊢ f x = f (n₀ ⊔ 2)

Tactic:
have h₂ := hn₀ (2 * max n₀ 2) h₁ (max n₀ 2) ⟨by simp [hxlb], by linarith⟩

Result:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
x : ℝ
hxlb : n₀ ⊔ 2 ≤ x
hxub : x < 2 * (n₀ ⊔ 2)
h₁ : n₀ ≤ 2 * (n₀ ⊔ 2)
h₂ : f (n₀ ⊔ 2) = c₂ * f (2 * (n₀ ⊔ 2))
⊢ f x = f (n₀ ⊔ 2)

Proof state:
case h
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hlt : c₁ < c₂
x : ℝ
hx : ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hx_nonneg : 0 ≤ x
⊢ 0 ≤ f x

Tactic:
have h' : 3 / 4 * x ∈ Set.Icc (1 / 2 * x) x := by
  rw [Set.mem_Icc]
  exact ⟨by gcongr ?_ * x; norm_num, by linarith⟩

Result:
case h
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hlt : c₁ < c₂
x : ℝ
hx : ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hx_nonneg : 0 ≤ x
h' : 3 / 4 * x ∈ Set.Icc (1 / 2 * x) x
⊢ 0 ≤ f x

Proof state:
case h
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hgt : c₂ < c₁
x : ℝ
hx : ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hx_nonneg : 0 ≤ x
h' : 3 / 4 * x ∈ Set.Icc (1 / 2 * x) x
hu : f (3 / 4 * x) ∈ Set.Icc (c₁ * f x) (c₂ * f x)
⊢ f x ≤ 0

Tactic:
have hu := Set.nonempty_of_mem hu

Result:
case h
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hgt : c₂ < c₁
x : ℝ
hx : ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hx_nonneg : 0 ≤ x
h' : 3 / 4 * x ∈ Set.Icc (1 / 2 * x) x
hu✝ : f (3 / 4 * x) ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hu : (Set.Icc (c₁ * f x) (c₂ * f x)).Nonempty
⊢ f x ≤ 0

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
le_2n : n₀ ⊔ 2 ≤ 2 ^ n * (n₀ ⊔ 2)
n₀_le_z : n₀ ≤ z
fz_eq_c₂fz : f z = c₂ * f z
z_to_half_z' : f (1 / 2 * z) = c₂ * f z
z_to_half_z : f (1 / 2 * z) = f z
⊢ 1 / 2 * (2 ^ n * (n₀ ⊔ 2)) ≤ 1 / 2 * z

Tactic:
gcongr

Result:
case h
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
le_2n : n₀ ⊔ 2 ≤ 2 ^ n * (n₀ ⊔ 2)
n₀_le_z : n₀ ≤ z
fz_eq_c₂fz : f z = c₂ * f z
z_to_half_z' : f (1 / 2 * z) = c₂ * f z
z_to_half_z : f (1 / 2 * z) = f z
⊢ 2 ^ n * (n₀ ⊔ 2) ≤ z

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u = c₂ * f x
⊢ ∃ c, ∀ᶠ (x : ℝ) in atTop, f x = c

Tactic:
rw [eventually_atTop] at h

Result:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
h : ∃ a, ∀ b ≥ a, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
⊢ ∃ c, ∀ᶠ (x : ℝ) in atTop, f x = c

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
⊢ f z = f (n₀ ⊔ 2)

Tactic:
have le_2n : max n₀ 2 ≤ (2 : ℝ)^n * max n₀ 2 := by
  nth_rewrite 1 [← one_mul (max n₀ 2)]
  gcongr
  exact one_le_pow₀ (by norm_num : (1 : ℝ) ≤ 2)

Result:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
le_2n : n₀ ⊔ 2 ≤ 2 ^ n * (n₀ ⊔ 2)
⊢ f z = f (n₀ ⊔ 2)

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
le_2n : n₀ ⊔ 2 ≤ 2 ^ n * (n₀ ⊔ 2)
n₀_le_z : n₀ ≤ z
fz_eq_c₂fz : f z = c₂ * f z
⊢ 1 / 2 * z ≤ z

Tactic:
linarith

Result:
no goals

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
⊢ n₀ ⊔ 2 ≤ 2 ^ n * (n₀ ⊔ 2)

Tactic:
nth_rewrite 1 [← one_mul (max n₀ 2)]

Result:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
n : ℕ
hn : n ≥ 1
hyp_ind : ∀ z ∈ Set.Ico (n₀ ⊔ 2) (2 ^ n * (n₀ ⊔ 2)), f z = f (n₀ ⊔ 2)
z : ℝ
hz : z ∈ Set.Ico (2 ^ n * (n₀ ⊔ 2)) (2 ^ (n + 1) * (n₀ ⊔ 2))
z_nonneg : 0 ≤ z
⊢ 1 * (n₀ ⊔ 2) ≤ 2 ^ n * (n₀ ⊔ 2)

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
x : ℝ
hxlb : n₀ ⊔ 2 ≤ x
hxub : x < 2 * (n₀ ⊔ 2)
h₁ : n₀ ≤ 2 * (n₀ ⊔ 2)
h₂ : f (n₀ ⊔ 2) = c₂ * f (2 * (n₀ ⊔ 2))
⊢ f x = f (n₀ ⊔ 2)

Tactic:
rw [h₂]

Result:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
heq : c₁ = c₂
n₀ : ℝ
hn₀ : ∀ b ≥ n₀, ∀ u ∈ Set.Icc (1 / 2 * b) b, f u = c₂ * f b
x : ℝ
hxlb : n₀ ⊔ 2 ≤ x
hxub : x < 2 * (n₀ ⊔ 2)
h₁ : n₀ ≤ 2 * (n₀ ⊔ 2)
h₂ : f (n₀ ⊔ 2) = c₂ * f (2 * (n₀ ⊔ 2))
⊢ f x = c₂ * f (2 * (n₀ ⊔ 2))

Proof state:
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hgt : c₂ < c₁
x : ℝ
hx : ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hx_nonneg : 0 ≤ x
⊢ 1 / 2 * x ≤ 3 / 4 * x

Tactic:
gcongr ?_ * x

Result:
case h
f : ℝ → ℝ
hf : GrowsPolynomially f
c₁ : ℝ
left✝¹ : c₁ > 0
c₂ : ℝ
left✝ : c₂ > 0
h : ∀ᶠ (x : ℝ) in atTop, ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hgt : c₂ < c₁
x : ℝ
hx : ∀ u ∈ Set.Icc (1 / 2 * x) x, f u ∈ Set.Icc (c₁ * f x) (c₂ * f x)
hx_nonneg : 0 ≤ x
⊢ 1 / 2 ≤ 3 / 4