l3lab/ntp-mathlib huggingface dataset:
instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where
  tensorObj X Y := mop (unmop Y ⊗ unmop X)
  whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop
  whiskerRight f X := (X.unmop ◁ f.unmop).mop
  tensorHom f g := (g.unmop ⊗ f.unmop).mop
  tensorHom_def f g := unmop_inj (tensorHom_def' _ _)
  tensorUnit := mop (𝟙_ C)
  associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop
  leftUnitor X := (ρ_ (unmop X)).mop
  rightUnitor X := (λ_ (unmop X)).mop
  associator_naturality f g h := unmop_inj (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
X₁✝ X₂✝ X₃✝ Y₁✝ Y₂✝ Y₃✝ : Cᴹᵒᵖ
f : X₁✝ ⟶ Y₁✝
g : X₂✝ ⟶ Y₂✝
h : X₃✝ ⟶ Y₃✝
⊢ Quiver.Hom.unmop (((f ⊗ g) ⊗ h) ≫ (α_ Y₁✝ Y₂✝ Y₃✝).hom) = Quiver.Hom.unmop ((α_ X₁✝ X₂✝ X₃✝).hom ≫ (f ⊗ g ⊗ h))

Next tactic:
simp
instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where
  tensorObj X Y := mop (unmop Y ⊗ unmop X)
  whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop
  whiskerRight f X := (X.unmop ◁ f.unmop).mop
  tensorHom f g := (g.unmop ⊗ f.unmop).mop
  tensorHom_def f g := unmop_inj (tensorHom_def' _ _)
  tensorUnit := mop (𝟙_ C)
  associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop
  leftUnitor X := (ρ_ (unmop X)).mop
  rightUnitor X := (λ_ (unmop X)).mop
  associator_naturality f g h := unmop_inj (by simp)
  leftUnitor_naturality f := unmop_inj (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
X✝ Y✝ : Cᴹᵒᵖ
f : X✝ ⟶ Y✝
⊢ Quiver.Hom.unmop ((𝟙 (𝟙_ Cᴹᵒᵖ) ⊗ f) ≫ (λ_ Y✝).hom) = Quiver.Hom.unmop ((λ_ X✝).hom ≫ f)

Next tactic:
simp
instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where
  tensorObj X Y := mop (unmop Y ⊗ unmop X)
  whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop
  whiskerRight f X := (X.unmop ◁ f.unmop).mop
  tensorHom f g := (g.unmop ⊗ f.unmop).mop
  tensorHom_def f g := unmop_inj (tensorHom_def' _ _)
  tensorUnit := mop (𝟙_ C)
  associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop
  leftUnitor X := (ρ_ (unmop X)).mop
  rightUnitor X := (λ_ (unmop X)).mop
  associator_naturality f g h := unmop_inj (by simp)
  leftUnitor_naturality f := unmop_inj (by simp)
  rightUnitor_naturality f := unmop_inj (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
X✝ Y✝ : Cᴹᵒᵖ
f : X✝ ⟶ Y✝
⊢ Quiver.Hom.unmop ((f ⊗ 𝟙 (𝟙_ Cᴹᵒᵖ)) ≫ (ρ_ Y✝).hom) = Quiver.Hom.unmop ((ρ_ X✝).hom ≫ f)

Next tactic:
simp
instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where
  tensorObj X Y := mop (unmop Y ⊗ unmop X)
  whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop
  whiskerRight f X := (X.unmop ◁ f.unmop).mop
  tensorHom f g := (g.unmop ⊗ f.unmop).mop
  tensorHom_def f g := unmop_inj (tensorHom_def' _ _)
  tensorUnit := mop (𝟙_ C)
  associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop
  leftUnitor X := (ρ_ (unmop X)).mop
  rightUnitor X := (λ_ (unmop X)).mop
  associator_naturality f g h := unmop_inj (by simp)
  leftUnitor_naturality f := unmop_inj (by simp)
  rightUnitor_naturality f := unmop_inj (by simp)
  triangle X Y := unmop_inj (by simp) -- Porting note: Changed `by coherence` to `by simp`
  pentagon W X Y Z := unmop_inj (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
W X Y Z : Cᴹᵒᵖ
⊢ Quiver.Hom.unmop (((α_ W X Y).hom ⊗ 𝟙 Z) ≫ (α_ W (X ⊗ Y) Z).hom ≫ (𝟙 W ⊗ (α_ X Y Z).hom)) =
    Quiver.Hom.unmop ((α_ (W ⊗ X) Y Z).hom ≫ (α_ W X (Y ⊗ Z)).hom)

Next tactic:
dsimp
instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where
  tensorObj X Y := mop (unmop Y ⊗ unmop X)
  whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop
  whiskerRight f X := (X.unmop ◁ f.unmop).mop
  tensorHom f g := (g.unmop ⊗ f.unmop).mop
  tensorHom_def f g := unmop_inj (tensorHom_def' _ _)
  tensorUnit := mop (𝟙_ C)
  associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop
  leftUnitor X := (ρ_ (unmop X)).mop
  rightUnitor X := (λ_ (unmop X)).mop
  associator_naturality f g h := unmop_inj (by simp)
  leftUnitor_naturality f := unmop_inj (by simp)
  rightUnitor_naturality f := unmop_inj (by simp)
  triangle X Y := unmop_inj (by simp) -- Porting note: Changed `by coherence` to `by simp`
  pentagon W X Y Z := unmop_inj (by dsimp; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
W X Y Z : Cᴹᵒᵖ
⊢ (𝟙 (unmop Z) ⊗ (α_ (unmop Y) (unmop X) (unmop W)).inv) ≫
      (α_ (unmop Z) (unmop Y ⊗ unmop X) (unmop W)).inv ≫ ((α_ (unmop Z) (unmop Y) (unmop X)).inv ⊗ 𝟙 (unmop W)) =
    (α_ (unmop Z) (unmop Y) (unmop X ⊗ unmop W)).inv ≫ (α_ (unmop Z ⊗ unmop Y) (unmop X) (unmop W)).inv

Next tactic:
coherence
instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where
  tensorObj X Y := mop (unmop Y ⊗ unmop X)
  whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop
  whiskerRight f X := (X.unmop ◁ f.unmop).mop
  tensorHom f g := (g.unmop ⊗ f.unmop).mop
  tensorHom_def f g := unmop_inj (tensorHom_def' _ _)
  tensorUnit := mop (𝟙_ C)
  associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop
  leftUnitor X := (ρ_ (unmop X)).mop
  rightUnitor X := (λ_ (unmop X)).mop
  associator_naturality f g h := unmop_inj (by simp)
  leftUnitor_naturality f := unmop_inj (by simp)
  rightUnitor_naturality f := unmop_inj (by simp)
  triangle X Y := unmop_inj (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : MonoidalCategory C
X Y : Cᴹᵒᵖ
⊢ Quiver.Hom.unmop ((α_ X (𝟙_ Cᴹᵒᵖ) Y).hom ≫ (𝟙 X ⊗ (λ_ Y).hom)) = Quiver.Hom.unmop ((ρ_ X).hom ⊗ 𝟙 Y)

Next tactic:
simp
/-- A variant of `eq_whisker` with a more convenient argument order for use in tactics.  -/
theorem eq_whisker' {X Y : C} {f g : X ⟶ Y} (w : f = g) {Z : C} (h : Y ⟶ Z) :
    f ≫ h = g ≫ h := by 

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
X Y : C
f g : X ⟶ Y
w : f = g
Z : C
h : Y ⟶ Z
⊢ f ≫ h = g ≫ h

Next tactic:
rw [w]
theorem comp_right (h : Semiconj f ga gb) (h' : Semiconj f ga' gb') :
    Semiconj f (ga ∘ ga') (gb ∘ gb') :=
  fun x ↦ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f fab : α → β
fbc : β → γ
ga ga' : α → α
gb gb' : β → β
gc gc' : γ → γ
h : Semiconj f ga gb
h' : Semiconj f ga' gb'
x : α
⊢ f ((ga ∘ ga') x) = (gb ∘ gb') (f x)

Next tactic:
simp only [comp_apply, h.eq, h'.eq]
theorem comp_left (hab : Semiconj fab ga gb) (hbc : Semiconj fbc gb gc) :
    Semiconj (fbc ∘ fab) ga gc :=
  fun x ↦ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f fab : α → β
fbc : β → γ
ga ga' : α → α
gb gb' : β → β
gc gc' : γ → γ
hab : Semiconj fab ga gb
hbc : Semiconj fbc gb gc
x : α
⊢ (fbc ∘ fab) (ga x) = gc ((fbc ∘ fab) x)

Next tactic:
simp only [comp_apply, hab.eq, hbc.eq]
theorem inverses_right (h : Semiconj f ga gb) (ha : RightInverse ga' ga) (hb : LeftInverse gb' gb) :
    Semiconj f ga' gb' :=
  fun x ↦ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f fab : α → β
fbc : β → γ
ga ga' : α → α
gb gb' : β → β
gc gc' : γ → γ
h : Semiconj f ga gb
ha : RightInverse ga' ga
hb : LeftInverse gb' gb
x : α
⊢ f (ga' x) = gb' (f x)

Next tactic:
rw [← hb (f (ga' x)), ← h.eq, ha x]
theorem comp {f' : β → γ} {gc : γ → γ → γ} (hf' : Semiconj₂ f' gb gc) (hf : Semiconj₂ f ga gb) :
    Semiconj₂ (f' ∘ f) ga gc := fun x y ↦ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
f' : β → γ
gc : γ → γ → γ
hf' : Semiconj₂ f' gb gc
hf : Semiconj₂ f ga gb
x y : α
⊢ (f' ∘ f) (ga x y) = gc ((f' ∘ f) x) ((f' ∘ f) y)

Next tactic:
simp only [hf'.eq, hf.eq, comp_apply]
theorem isAssociative_right [IsAssociative α ga] (h : Semiconj₂ f ga gb) (h_surj : Surjective f) :
    IsAssociative β gb :=
  ⟨h_surj.forall₃.2 fun x₁ x₂ x₃ ↦ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsAssociative α ga
h : Semiconj₂ f ga gb
h_surj : Surjective f
x₁ x₂ x₃ : α
⊢ gb (gb (f x₁) (f x₂)) (f x₃) = gb (f x₁) (gb (f x₂) (f x₃))

Next tactic:
simp only [← h.eq, @IsAssociative.assoc _ ga]
theorem isAssociative_left [IsAssociative β gb] (h : Semiconj₂ f ga gb) (h_inj : Injective f) :
    IsAssociative α ga :=
  ⟨fun x₁ x₂ x₃ ↦ h_inj <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsAssociative β gb
h : Semiconj₂ f ga gb
h_inj : Injective f
x₁ x₂ x₃ : α
⊢ f (ga (ga x₁ x₂) x₃) = f (ga x₁ (ga x₂ x₃))

Next tactic:
simp only [h.eq, @IsAssociative.assoc _ gb]
theorem isIdempotent_right [IsIdempotent α ga] (h : Semiconj₂ f ga gb) (h_surj : Surjective f) :
    IsIdempotent β gb :=
  ⟨h_surj.forall.2 fun x ↦ by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsIdempotent α ga
h : Semiconj₂ f ga gb
h_surj : Surjective f
x : α
⊢ gb (f x) (f x) = f x

Next tactic:
simp only [← h.eq, @IsIdempotent.idempotent _ ga]
theorem isIdempotent_left [IsIdempotent β gb] (h : Semiconj₂ f ga gb) (h_inj : Injective f) :
    IsIdempotent α ga :=
  ⟨fun x ↦ h_inj <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β
ga : α → α → α
gb : β → β → β
inst✝ : IsIdempotent β gb
h : Semiconj₂ f ga gb
h_inj : Injective f
x : α
⊢ f (ga x x) = f x

Next tactic:
rw [h.eq, @IsIdempotent.idempotent _ gb]
theorem log_of_pos (hx : 0 < x) : log x = expOrderIso.symm ⟨x, hx⟩ := by
  

Proof state:
x y : ℝ
hx : 0 < x
⊢ log x = (OrderIso.symm expOrderIso) { val := x, property := hx }

Next tactic:
rw [log_of_ne_zero hx.ne']
theorem log_of_pos (hx : 0 < x) : log x = expOrderIso.symm ⟨x, hx⟩ := by
  rw [log_of_ne_zero hx.ne']
  

Proof state:
x y : ℝ
hx : 0 < x
⊢ (OrderIso.symm expOrderIso) { val := |x|, property := (_ : 0 < |x|) } =
    (OrderIso.symm expOrderIso) { val := x, property := hx }

Next tactic:
congr
theorem log_of_pos (hx : 0 < x) : log x = expOrderIso.symm ⟨x, hx⟩ := by
  rw [log_of_ne_zero hx.ne']
  congr
  

Proof state:
case h.e_6.h.e_val
x y : ℝ
hx : 0 < x
⊢ |x| = x

Next tactic:
exact abs_of_pos hx
theorem exp_log_eq_abs (hx : x ≠ 0) : exp (log x) = |x| := by
  

Proof state:
x y : ℝ
hx : x ≠ 0
⊢ rexp (log x) = |x|

Next tactic:
rw [log_of_ne_zero hx, ← coe_expOrderIso_apply, OrderIso.apply_symm_apply, Subtype.coe_mk]
theorem exp_log (hx : 0 < x) : exp (log x) = x := by
  

Proof state:
x y : ℝ
hx : 0 < x
⊢ rexp (log x) = x

Next tactic:
rw [exp_log_eq_abs hx.ne']
theorem exp_log (hx : 0 < x) : exp (log x) = x := by
  rw [exp_log_eq_abs hx.ne']
  

Proof state:
x y : ℝ
hx : 0 < x
⊢ |x| = x

Next tactic:
exact abs_of_pos hx
theorem exp_log_of_neg (hx : x < 0) : exp (log x) = -x := by
  

Proof state:
x y : ℝ
hx : x < 0
⊢ rexp (log x) = -x

Next tactic:
rw [exp_log_eq_abs (ne_of_lt hx)]
theorem exp_log_of_neg (hx : x < 0) : exp (log x) = -x := by
  rw [exp_log_eq_abs (ne_of_lt hx)]
  

Proof state:
x y : ℝ
hx : x < 0
⊢ |x| = -x

Next tactic:
exact abs_of_neg hx
theorem le_exp_log (x : ℝ) : x ≤ exp (log x) := by
  

Proof state:
x✝ y x : ℝ
⊢ x ≤ rexp (log x)

Next tactic:
by_cases h_zero : x = 0
theorem le_exp_log (x : ℝ) : x ≤ exp (log x) := by
  by_cases h_zero : x = 0
  · 

Proof state:
case pos
x✝ y x : ℝ
h_zero : x = 0
⊢ x ≤ rexp (log x)

Next tactic:
rw [h_zero, log, dif_pos rfl, exp_zero]
theorem le_exp_log (x : ℝ) : x ≤ exp (log x) := by
  by_cases h_zero : x = 0
  · rw [h_zero, log, dif_pos rfl, exp_zero]
    

Proof state:
case pos
x✝ y x : ℝ
h_zero : x = 0
⊢ 0 ≤ 1

Next tactic:
exact zero_le_one
theorem le_exp_log (x : ℝ) : x ≤ exp (log x) := by
  by_cases h_zero : x = 0
  · rw [h_zero, log, dif_pos rfl, exp_zero]
    exact zero_le_one
  · 

Proof state:
case neg
x✝ y x : ℝ
h_zero : ¬x = 0
⊢ x ≤ rexp (log x)

Next tactic:
rw [exp_log_eq_abs h_zero]
theorem le_exp_log (x : ℝ) : x ≤ exp (log x) := by
  by_cases h_zero : x = 0
  · rw [h_zero, log, dif_pos rfl, exp_zero]
    exact zero_le_one
  · rw [exp_log_eq_abs h_zero]
    

Proof state:
case neg
x✝ y x : ℝ
h_zero : ¬x = 0
⊢ x ≤ |x|

Next tactic:
exact le_abs_self _
@[simp]
theorem log_one : log 1 = 0 :=
  exp_injective <| by 

Proof state:
x y : ℝ
⊢ rexp (log 1) = rexp 0

Next tactic:
rw [exp_log zero_lt_one, exp_zero]
@[simp]
theorem log_abs (x : ℝ) : log |x| = log x := by
  

Proof state:
x✝ y x : ℝ
⊢ log |x| = log x

Next tactic:
by_cases h : x = 0
@[simp]
theorem log_abs (x : ℝ) : log |x| = log x := by
  by_cases h : x = 0
  · 

Proof state:
case pos
x✝ y x : ℝ
h : x = 0
⊢ log |x| = log x

Next tactic:
simp [h]
@[simp]
theorem log_abs (x : ℝ) : log |x| = log x := by
  by_cases h : x = 0
  · simp [h]
  · 

Proof state:
case neg
x✝ y x : ℝ
h : ¬x = 0
⊢ log |x| = log x

Next tactic:
rw [← exp_eq_exp, exp_log_eq_abs h, exp_log_eq_abs (abs_pos.2 h).ne', abs_abs]
@[simp]
theorem log_neg_eq_log (x : ℝ) : log (-x) = log x := by 

Proof state:
x✝ y x : ℝ
⊢ log (-x) = log x

Next tactic:
rw [← log_abs x, ← log_abs (-x), abs_neg]
theorem sinh_log {x : ℝ} (hx : 0 < x) : sinh (log x) = (x - x⁻¹) / 2 := by
  

Proof state:
x✝ y x : ℝ
hx : 0 < x
⊢ sinh (log x) = (x - x⁻¹) / 2

Next tactic:
rw [sinh_eq, exp_neg, exp_log hx]
theorem cosh_log {x : ℝ} (hx : 0 < x) : cosh (log x) = (x + x⁻¹) / 2 := by
  

Proof state:
x✝ y x : ℝ
hx : 0 < x
⊢ cosh (log x) = (x + x⁻¹) / 2

Next tactic:
rw [cosh_eq, exp_neg, exp_log hx]
theorem surjOn_log' : SurjOn log (Iio 0) univ := fun x _ =>
  ⟨-exp x, neg_lt_zero.2 <| exp_pos x, by 

Proof state:
x✝¹ y x : ℝ
x✝ : x ∈ univ
⊢ log (-rexp x) = x

Next tactic:
rw [log_neg_eq_log, log_exp]
theorem log_mul (hx : x ≠ 0) (hy : y ≠ 0) : log (x * y) = log x + log y :=
  exp_injective <| by
    

Proof state:
x y : ℝ
hx : x ≠ 0
hy : y ≠ 0
⊢ rexp (log (x * y)) = rexp (log x + log y)

Next tactic:
rw [exp_log_eq_abs (mul_ne_zero hx hy), exp_add, exp_log_eq_abs hx, exp_log_eq_abs hy, abs_mul]
theorem log_div (hx : x ≠ 0) (hy : y ≠ 0) : log (x / y) = log x - log y :=
  exp_injective <| by
    

Proof state:
x y : ℝ
hx : x ≠ 0
hy : y ≠ 0
⊢ rexp (log (x / y)) = rexp (log x - log y)

Next tactic:
rw [exp_log_eq_abs (div_ne_zero hx hy), exp_sub, exp_log_eq_abs hx, exp_log_eq_abs hy, abs_div]
@[simp]
theorem log_inv (x : ℝ) : log x⁻¹ = -log x := by
  

Proof state:
x✝ y x : ℝ
⊢ log x⁻¹ = -log x

Next tactic:
by_cases hx : x = 0
@[simp]
theorem log_inv (x : ℝ) : log x⁻¹ = -log x := by
  by_cases hx : x = 0; · 

Proof state:
case pos
x✝ y x : ℝ
hx : x = 0
⊢ log x⁻¹ = -log x

Next tactic:
simp [hx]
@[simp]
theorem log_inv (x : ℝ) : log x⁻¹ = -log x := by
  by_cases hx : x = 0; · simp [hx]
  

Proof state:
case neg
x✝ y x : ℝ
hx : ¬x = 0
⊢ log x⁻¹ = -log x

Next tactic:
rw [← exp_eq_exp, exp_log_eq_abs (inv_ne_zero hx), exp_neg, exp_log_eq_abs hx, abs_inv]
theorem log_le_log_iff (h : 0 < x) (h₁ : 0 < y) : log x ≤ log y ↔ x ≤ y := by
  

Proof state:
x y : ℝ
h : 0 < x
h₁ : 0 < y
⊢ log x ≤ log y ↔ x ≤ y

Next tactic:
rw [← exp_le_exp, exp_log h, exp_log h₁]
@[gcongr]
theorem log_lt_log (hx : 0 < x) (h : x < y) : log x < log y := by
  

Proof state:
x y : ℝ
hx : 0 < x
h : x < y
⊢ log x < log y

Next tactic:
rwa [← exp_lt_exp, exp_log hx, exp_log (lt_trans hx h)]
theorem log_lt_log_iff (hx : 0 < x) (hy : 0 < y) : log x < log y ↔ x < y := by
  

Proof state:
x y : ℝ
hx : 0 < x
hy : 0 < y
⊢ log x < log y ↔ x < y

Next tactic:
rw [← exp_lt_exp, exp_log hx, exp_log hy]
theorem log_le_iff_le_exp (hx : 0 < x) : log x ≤ y ↔ x ≤ exp y := by 

Proof state:
x y : ℝ
hx : 0 < x
⊢ log x ≤ y ↔ x ≤ rexp y

Next tactic:
rw [← exp_le_exp, exp_log hx]
theorem log_lt_iff_lt_exp (hx : 0 < x) : log x < y ↔ x < exp y := by 

Proof state:
x y : ℝ
hx : 0 < x
⊢ log x < y ↔ x < rexp y

Next tactic:
rw [← exp_lt_exp, exp_log hx]
theorem le_log_iff_exp_le (hy : 0 < y) : x ≤ log y ↔ exp x ≤ y := by 

Proof state:
x y : ℝ
hy : 0 < y
⊢ x ≤ log y ↔ rexp x ≤ y

Next tactic:
rw [← exp_le_exp, exp_log hy]
theorem lt_log_iff_exp_lt (hy : 0 < y) : x < log y ↔ exp x < y := by 

Proof state:
x y : ℝ
hy : 0 < y
⊢ x < log y ↔ rexp x < y

Next tactic:
rw [← exp_lt_exp, exp_log hy]
theorem log_pos_iff (hx : 0 < x) : 0 < log x ↔ 1 < x := by
  

Proof state:
x y : ℝ
hx : 0 < x
⊢ 0 < log x ↔ 1 < x

Next tactic:
rw [← log_one]
theorem log_pos_iff (hx : 0 < x) : 0 < log x ↔ 1 < x := by
  rw [← log_one]
  

Proof state:
x y : ℝ
hx : 0 < x
⊢ log 1 < log x ↔ 1 < x

Next tactic:
exact log_lt_log_iff zero_lt_one hx
theorem log_pos_of_lt_neg_one (hx : x < -1) : 0 < log x := by
  

Proof state:
x y : ℝ
hx : x < -1
⊢ 0 < log x

Next tactic:
rw [← neg_neg x, log_neg_eq_log]
theorem log_pos_of_lt_neg_one (hx : x < -1) : 0 < log x := by
  rw [← neg_neg x, log_neg_eq_log]
  

Proof state:
x y : ℝ
hx : x < -1
⊢ 0 < log (-x)

Next tactic:
have : 1 < -x := by linarith
theorem log_pos_of_lt_neg_one (hx : x < -1) : 0 < log x := by
  rw [← neg_neg x, log_neg_eq_log]
  have : 1 < -x := by 

Proof state:
x y : ℝ
hx : x < -1
⊢ 1 < -x

Next tactic:
linarith
theorem log_pos_of_lt_neg_one (hx : x < -1) : 0 < log x := by
  rw [← neg_neg x, log_neg_eq_log]
  have : 1 < -x := by linarith
  

Proof state:
x y : ℝ
hx : x < -1
this : 1 < -x
⊢ 0 < log (-x)

Next tactic:
exact log_pos this
theorem log_neg_iff (h : 0 < x) : log x < 0 ↔ x < 1 := by
  

Proof state:
x y : ℝ
h : 0 < x
⊢ log x < 0 ↔ x < 1

Next tactic:
rw [← log_one]
theorem log_neg_iff (h : 0 < x) : log x < 0 ↔ x < 1 := by
  rw [← log_one]
  

Proof state:
x y : ℝ
h : 0 < x
⊢ log x < log 1 ↔ x < 1

Next tactic:
exact log_lt_log_iff h zero_lt_one
theorem log_neg_of_lt_zero (h0 : x < 0) (h1 : -1 < x) : log x < 0 := by
  

Proof state:
x y : ℝ
h0 : x < 0
h1 : -1 < x
⊢ log x < 0

Next tactic:
rw [← neg_neg x, log_neg_eq_log]
theorem log_neg_of_lt_zero (h0 : x < 0) (h1 : -1 < x) : log x < 0 := by
  rw [← neg_neg x, log_neg_eq_log]
  

Proof state:
x y : ℝ
h0 : x < 0
h1 : -1 < x
⊢ log (-x) < 0

Next tactic:
have h0' : 0 < -x := by linarith
theorem log_neg_of_lt_zero (h0 : x < 0) (h1 : -1 < x) : log x < 0 := by
  rw [← neg_neg x, log_neg_eq_log]
  have h0' : 0 < -x := by 

Proof state:
x y : ℝ
h0 : x < 0
h1 : -1 < x
⊢ 0 < -x

Next tactic:
linarith
theorem log_neg_of_lt_zero (h0 : x < 0) (h1 : -1 < x) : log x < 0 := by
  rw [← neg_neg x, log_neg_eq_log]
  have h0' : 0 < -x := by linarith
  

Proof state:
x y : ℝ
h0 : x < 0
h1 : -1 < x
h0' : 0 < -x
⊢ log (-x) < 0

Next tactic:
have h1' : -x < 1 := by linarith
theorem log_neg_of_lt_zero (h0 : x < 0) (h1 : -1 < x) : log x < 0 := by
  rw [← neg_neg x, log_neg_eq_log]
  have h0' : 0 < -x := by linarith
  have h1' : -x < 1 := by 

Proof state:
x y : ℝ
h0 : x < 0
h1 : -1 < x
h0' : 0 < -x
⊢ -x < 1

Next tactic:
linarith
theorem log_neg_of_lt_zero (h0 : x < 0) (h1 : -1 < x) : log x < 0 := by
  rw [← neg_neg x, log_neg_eq_log]
  have h0' : 0 < -x := by linarith
  have h1' : -x < 1 := by linarith
  

Proof state:
x y : ℝ
h0 : x < 0
h1 : -1 < x
h0' : 0 < -x
h1' : -x < 1
⊢ log (-x) < 0

Next tactic:
exact log_neg h0' h1'
theorem log_nonneg_iff (hx : 0 < x) : 0 ≤ log x ↔ 1 ≤ x := by 

Proof state:
x y : ℝ
hx : 0 < x
⊢ 0 ≤ log x ↔ 1 ≤ x

Next tactic:
rw [← not_lt, log_neg_iff hx, not_lt]
theorem log_nonpos_iff (hx : 0 < x) : log x ≤ 0 ↔ x ≤ 1 := by 

Proof state:
x y : ℝ
hx : 0 < x
⊢ log x ≤ 0 ↔ x ≤ 1

Next tactic:
rw [← not_lt, log_pos_iff hx, not_lt]
theorem log_nonpos_iff' (hx : 0 ≤ x) : log x ≤ 0 ↔ x ≤ 1 := by
  

Proof state:
x y : ℝ
hx : 0 ≤ x
⊢ log x ≤ 0 ↔ x ≤ 1

Next tactic:
rcases hx.eq_or_lt with (rfl | hx)
theorem log_nonpos_iff' (hx : 0 ≤ x) : log x ≤ 0 ↔ x ≤ 1 := by
  rcases hx.eq_or_lt with (rfl | hx)
  · 

Proof state:
case inl
y : ℝ
hx : 0 ≤ 0
⊢ log 0 ≤ 0 ↔ 0 ≤ 1

Next tactic:
simp [le_refl, zero_le_one]
theorem log_nonpos_iff' (hx : 0 ≤ x) : log x ≤ 0 ↔ x ≤ 1 := by
  rcases hx.eq_or_lt with (rfl | hx)
  · simp [le_refl, zero_le_one]
  

Proof state:
case inr
x y : ℝ
hx✝ : 0 ≤ x
hx : 0 < x
⊢ log x ≤ 0 ↔ x ≤ 1

Next tactic:
exact log_nonpos_iff hx
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  

Proof state:
x y : ℝ
n : ℕ
⊢ 0 ≤ log ↑n

Next tactic:
by_cases hn : n = 0
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  

Proof state:
case pos
x y : ℝ
n : ℕ
hn : n = 0
⊢ 0 ≤ log ↑n
case neg x y : ℝ n : ℕ hn : ¬n = 0 ⊢ 0 ≤ log ↑n

Next tactic:
case pos => simp [hn]
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  

Proof state:
x y : ℝ
n : ℕ
hn : n = 0
⊢ 0 ≤ log ↑n

Next tactic:
case pos => simp [hn]
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  case pos => 

Proof state:
x y : ℝ
n : ℕ
hn : n = 0
⊢ 0 ≤ log ↑n

Next tactic:
simp [hn]
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  case pos => simp [hn]
  

Proof state:
case neg
x y : ℝ
n : ℕ
hn : ¬n = 0
⊢ 0 ≤ log ↑n

Next tactic:
case neg =>
    have : (1 : ℝ) ≤ n := mod_cast Nat.one_le_of_lt <| Nat.pos_of_ne_zero hn
    exact log_nonneg this
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  case pos => simp [hn]
  

Proof state:
x y : ℝ
n : ℕ
hn : ¬n = 0
⊢ 0 ≤ log ↑n

Next tactic:
case neg =>
    have : (1 : ℝ) ≤ n := mod_cast Nat.one_le_of_lt <| Nat.pos_of_ne_zero hn
    exact log_nonneg this
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  case pos => simp [hn]
  case neg =>
    

Proof state:
x y : ℝ
n : ℕ
hn : ¬n = 0
⊢ 0 ≤ log ↑n

Next tactic:
have : (1 : ℝ) ≤ n := mod_cast Nat.one_le_of_lt <| Nat.pos_of_ne_zero hn
theorem log_nat_cast_nonneg (n : ℕ) : 0 ≤ log n := by
  by_cases hn : n = 0
  case pos => simp [hn]
  case neg =>
    have : (1 : ℝ) ≤ n := mod_cast Nat.one_le_of_lt <| Nat.pos_of_ne_zero hn
    

Proof state:
x y : ℝ
n : ℕ
hn : ¬n = 0
this : 1 ≤ ↑n
⊢ 0 ≤ log ↑n

Next tactic:
exact log_nonneg this
theorem log_neg_nat_cast_nonneg (n : ℕ) : 0 ≤ log (-n) := by
  

Proof state:
x y : ℝ
n : ℕ
⊢ 0 ≤ log (-↑n)

Next tactic:
rw [← log_neg_eq_log, neg_neg]
theorem log_neg_nat_cast_nonneg (n : ℕ) : 0 ≤ log (-n) := by
  rw [← log_neg_eq_log, neg_neg]
  

Proof state:
x y : ℝ
n : ℕ
⊢ 0 ≤ log ↑n

Next tactic:
exact log_nat_cast_nonneg _
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  

Proof state:
x y : ℝ
n : ℤ
⊢ 0 ≤ log ↑n

Next tactic:
cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          rw [← log_neg_eq_log]
          exact log_nonneg this
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  

Proof state:
x y : ℝ
n : ℤ
x✝ : 0 < n ∨ 0 = n ∨ n < 0
⊢ 0 ≤ log ↑n

Next tactic:
cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          rw [← log_neg_eq_log]
          exact log_nonneg this
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  

Proof state:
case inl
x y : ℝ
n : ℤ
hn : 0 < n
⊢ 0 ≤ log ↑n

Next tactic:
| inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      

Proof state:
case inl
x y : ℝ
n : ℤ
hn : 0 < n
⊢ 0 ≤ log ↑n

Next tactic:
have : (1 : ℝ) ≤ n := mod_cast hn
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      

Proof state:
case inl
x y : ℝ
n : ℤ
hn : 0 < n
this : 1 ≤ ↑n
⊢ 0 ≤ log ↑n

Next tactic:
exact log_nonneg this
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  

Proof state:
case inr
x y : ℝ
n : ℤ
hn : 0 = n ∨ n < 0
⊢ 0 ≤ log ↑n

Next tactic:
| inr hn =>
      cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          rw [← log_neg_eq_log]
          exact log_nonneg this
theorem log_int_cast_nonneg (n : ℤ) : 0 ≤ log n := by
  cases lt_trichotomy 0 n with
  | inl hn =>
      have : (1 : ℝ) ≤ n := mod_cast hn
      exact log_nonneg this
  | inr hn =>
      

Proof state:
case inr
x y : ℝ
n : ℤ
hn : 0 = n ∨ n < 0
⊢ 0 ≤ log ↑n

Next tactic:
cases hn with
      | inl hn => simp [hn.symm]
      | inr hn =>
          have : (1 : ℝ) ≤ -n := by rw [← neg_zero, ← lt_neg] at hn; exact mod_cast hn
          rw [← log_neg_eq_log]
          exact log_nonneg this