l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> 

Proof state:
case mp
m : ℕ
⊢ ppred 0 = some m → succ m = 0

Next tactic:
intro h
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> 

Proof state:
case mpr
m : ℕ
⊢ succ m = 0 → ppred 0 = some m

Next tactic:
intro h
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> 

Proof state:
case mp
m : ℕ
h : ppred 0 = some m
⊢ succ m = 0

Next tactic:
contradiction
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> 

Proof state:
case mpr
m : ℕ
h : succ m = 0
⊢ ppred 0 = some m

Next tactic:
contradiction
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by 

Proof state:
m n : ℕ
⊢ ppred (n + 1) = some m ↔ succ m = n + 1

Next tactic:
constructor
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> 

Proof state:
case mp
m n : ℕ
⊢ ppred (n + 1) = some m → succ m = n + 1

Next tactic:
intro h
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> 

Proof state:
case mpr
m n : ℕ
⊢ succ m = n + 1 → ppred (n + 1) = some m

Next tactic:
intro h
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> intro h <;> 

Proof state:
case mp
m n : ℕ
h : ppred (n + 1) = some m
⊢ succ m = n + 1

Next tactic:
injection h
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> intro h <;> 

Proof state:
case mpr
m n : ℕ
h : succ m = n + 1
⊢ ppred (n + 1) = some m

Next tactic:
injection h
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> intro h <;> injection h <;> 

Proof state:
case mp
m n : ℕ
val_eq✝ : Nat.add n 0 = m
⊢ succ m = n + 1

Next tactic:
subst m
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> intro h <;> injection h <;> 

Proof state:
case mpr
m n : ℕ
n_eq✝ : m = Nat.add n 0
⊢ ppred (n + 1) = some m

Next tactic:
subst m
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> intro h <;> injection h <;> subst m <;> 

Proof state:
case mp
n : ℕ
⊢ succ (Nat.add n 0) = n + 1

Next tactic:
rfl
@[simp]
theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
  | 0 => by constructor <;> intro h <;> contradiction
  | n + 1 => by constructor <;> intro h <;> injection h <;> subst m <;> 

Proof state:
case mpr
n : ℕ
⊢ ppred (n + 1) = some (Nat.add n 0)

Next tactic:
rfl
@[simp]
theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
  | 0 => by 

Proof state:
⊢ ppred 0 = none ↔ 0 = 0

Next tactic:
simp
@[simp]
theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
  | 0 => by simp
  | n + 1 => by 

Proof state:
n : ℕ
⊢ ppred (n + 1) = none ↔ n + 1 = 0

Next tactic:
constructor
@[simp]
theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
  | 0 => by simp
  | n + 1 => by constructor <;> 

Proof state:
case mp
n : ℕ
⊢ ppred (n + 1) = none → n + 1 = 0

Next tactic:
intro
@[simp]
theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
  | 0 => by simp
  | n + 1 => by constructor <;> 

Proof state:
case mpr
n : ℕ
⊢ n + 1 = 0 → ppred (n + 1) = none

Next tactic:
intro
@[simp]
theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
  | 0 => by simp
  | n + 1 => by constructor <;> intro <;> 

Proof state:
case mp
n : ℕ
a✝ : ppred (n + 1) = none
⊢ n + 1 = 0

Next tactic:
contradiction
@[simp]
theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
  | 0 => by simp
  | n + 1 => by constructor <;> intro <;> 

Proof state:
case mpr
n : ℕ
a✝ : n + 1 = 0
⊢ ppred (n + 1) = none

Next tactic:
contradiction
theorem psub_eq_some {m : ℕ} : ∀ {n k}, psub m n = some k ↔ k + n = m
  | 0, k => by 

Proof state:
m k : ℕ
⊢ psub m 0 = some k ↔ k + 0 = m

Next tactic:
simp [eq_comm]
theorem psub_eq_some {m : ℕ} : ∀ {n k}, psub m n = some k ↔ k + n = m
  | 0, k => by simp [eq_comm]
  | n + 1, k => by
    

Proof state:
m n k : ℕ
⊢ psub m (n + 1) = some k ↔ k + (n + 1) = m

Next tactic:
apply Option.bind_eq_some.trans
theorem psub_eq_some {m : ℕ} : ∀ {n k}, psub m n = some k ↔ k + n = m
  | 0, k => by simp [eq_comm]
  | n + 1, k => by
    apply Option.bind_eq_some.trans
    

Proof state:
m n k : ℕ
⊢ (∃ a, psub m (Nat.add n 0) = some a ∧ ppred a = some k) ↔ k + (n + 1) = m

Next tactic:
simp only [psub_eq_some, ppred_eq_some]
theorem psub_eq_some {m : ℕ} : ∀ {n k}, psub m n = some k ↔ k + n = m
  | 0, k => by simp [eq_comm]
  | n + 1, k => by
    apply Option.bind_eq_some.trans
    simp only [psub_eq_some, ppred_eq_some]
    

Proof state:
m n k : ℕ
⊢ (∃ a, a + Nat.add n 0 = m ∧ succ k = a) ↔ k + (n + 1) = m

Next tactic:
simp [add_comm, add_left_comm, Nat.succ_eq_add_one]
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  

Proof state:
m n : ℕ
⊢ psub m n = none ↔ m < n

Next tactic:
cases s : psub m n
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> 

Proof state:
case none
m n : ℕ
s : psub m n = none
⊢ none = none ↔ m < n

Next tactic:
simp [eq_comm]
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> 

Proof state:
case some
m n val✝ : ℕ
s : psub m n = some val✝
⊢ some val✝ = none ↔ m < n

Next tactic:
simp [eq_comm]
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · 

Proof state:
case none
m n : ℕ
s : psub m n = none
⊢ m < n

Next tactic:
show m < n
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · show m < n
    

Proof state:
case none
m n : ℕ
s : psub m n = none
⊢ m < n

Next tactic:
refine' lt_of_not_ge fun h => _
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · show m < n
    refine' lt_of_not_ge fun h => _
    

Proof state:
case none
m n : ℕ
s : psub m n = none
h : m ≥ n
⊢ False

Next tactic:
cases' le.dest h with k e
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · show m < n
    refine' lt_of_not_ge fun h => _
    cases' le.dest h with k e
    

Proof state:
case none.intro
m n : ℕ
s : psub m n = none
h : m ≥ n
k : ℕ
e : n + k = m
⊢ False

Next tactic:
injection s.symm.trans (psub_eq_some.2 <| (add_comm _ _).trans e)
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · show m < n
    refine' lt_of_not_ge fun h => _
    cases' le.dest h with k e
    injection s.symm.trans (psub_eq_some.2 <| (add_comm _ _).trans e)
  · 

Proof state:
case some
m n val✝ : ℕ
s : psub m n = some val✝
⊢ n ≤ m

Next tactic:
show n ≤ m
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · show m < n
    refine' lt_of_not_ge fun h => _
    cases' le.dest h with k e
    injection s.symm.trans (psub_eq_some.2 <| (add_comm _ _).trans e)
  · show n ≤ m
    

Proof state:
case some
m n val✝ : ℕ
s : psub m n = some val✝
⊢ n ≤ m

Next tactic:
rw [← psub_eq_some.1 s]
theorem psub_eq_none {m n : ℕ} : psub m n = none ↔ m < n := by
  cases s : psub m n <;> simp [eq_comm]
  · show m < n
    refine' lt_of_not_ge fun h => _
    cases' le.dest h with k e
    injection s.symm.trans (psub_eq_some.2 <| (add_comm _ _).trans e)
  · show n ≤ m
    rw [← psub_eq_some.1 s]
    

Proof state:
case some
m n val✝ : ℕ
s : psub m n = some val✝
⊢ n ≤ val✝ + n

Next tactic:
apply Nat.le_add_left
theorem psub_add (m n k) :
    psub m (n + k) = (do psub (← psub m n) k) := by
    

Proof state:
m n k : ℕ
⊢ psub m (n + k) = do
    let __do_lift ← psub m n
    psub __do_lift k

Next tactic:
induction k
theorem psub_add (m n k) :
    psub m (n + k) = (do psub (← psub m n) k) := by
    induction k
    

Proof state:
case zero
m n : ℕ
⊢ psub m (n + zero) = do
    let __do_lift ← psub m n
    psub __do_lift zero
case succ
m n n✝ : ℕ
n_ih✝ :
  psub m (n + n✝) = do
    let __do_lift ← psub m n
    psub __do_lift n✝
⊢ psub m (n + succ n✝) = do
    let __do_lift ← psub m n
    psub __do_lift (succ n✝)

Next tactic:
simp only [zero_eq, add_zero, psub_zero, Option.bind_eq_bind, Option.bind_some]
theorem psub_add (m n k) :
    psub m (n + k) = (do psub (← psub m n) k) := by
    induction k
    simp only [zero_eq, add_zero, psub_zero, Option.bind_eq_bind, Option.bind_some]
    

Proof state:
case succ
m n n✝ : ℕ
n_ih✝ :
  psub m (n + n✝) = do
    let __do_lift ← psub m n
    psub __do_lift n✝
⊢ psub m (n + succ n✝) = do
    let __do_lift ← psub m n
    psub __do_lift (succ n✝)

Next tactic:
simp [*, Nat.add_succ]
theorem psub'_eq_psub (m n) : psub' m n = psub m n := by
  

Proof state:
m n : ℕ
⊢ psub' m n = psub m n

Next tactic:
rw [psub']
theorem psub'_eq_psub (m n) : psub' m n = psub m n := by
  rw [psub']
  

Proof state:
m n : ℕ
⊢ (if n ≤ m then some (m - n) else none) = psub m n

Next tactic:
split_ifs with h
theorem psub'_eq_psub (m n) : psub' m n = psub m n := by
  rw [psub']
  split_ifs with h
  

Proof state:
case pos
m n : ℕ
h : n ≤ m
⊢ some (m - n) = psub m n
case neg m n : ℕ h : ¬n ≤ m ⊢ none = psub m n

Next tactic:
exact (psub_eq_sub h).symm
theorem psub'_eq_psub (m n) : psub' m n = psub m n := by
  rw [psub']
  split_ifs with h
  exact (psub_eq_sub h).symm
  

Proof state:
case neg
m n : ℕ
h : ¬n ≤ m
⊢ none = psub m n

Next tactic:
exact (psub_eq_none.2 (not_le.1 h)).symm
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        

Proof state:
⊢ ∀ ⦃x : ℂ⦄, x ∈ {z | z.im ∈ Ioo (-π) π} → cexp x ∈ {z | 0 < z.re} ∪ {z | z.im ≠ 0}

Next tactic:
rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        

Proof state:
case mk.intro
x y : ℝ
h₁ : -π < y
h₂ : y < π
⊢ cexp { re := x, im := y } ∈ {z | 0 < z.re} ∪ {z | z.im ≠ 0}

Next tactic:
refine' (not_or_of_imp fun hz => _).symm
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        

Proof state:
case mk.intro
x y : ℝ
h₁ : -π < y
h₂ : y < π
hz : (cexp { re := x, im := y }).im = 0
⊢ cexp { re := x, im := y } ∈ {z | 0 < z.re}

Next tactic:
obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          

Proof state:
x y : ℝ
h₁ : -π < y
h₂ : y < π
hz : (cexp { re := x, im := y }).im = 0
⊢ y = 0

Next tactic:
rw [exp_im] at hz
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          

Proof state:
x y : ℝ
h₁ : -π < y
h₂ : y < π
hz : rexp { re := x, im := y }.re * Real.sin { re := x, im := y }.im = 0
⊢ y = 0

Next tactic:
simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
        

Proof state:
case mk.intro
x : ℝ
h₁ : -π < 0
h₂ : 0 < π
hz : (cexp { re := x, im := 0 }).im = 0
⊢ cexp { re := x, im := 0 } ∈ {z | 0 < z.re}

Next tactic:
rw [mem_setOf_eq, ← ofReal_def, exp_ofReal_re]
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
        rw [mem_setOf_eq, ← ofReal_def, exp_ofReal_re]
        

Proof state:
case mk.intro
x : ℝ
h₁ : -π < 0
h₂ : 0 < π
hz : (cexp { re := x, im := 0 }).im = 0
⊢ 0 < rexp x

Next tactic:
exact Real.exp_pos x
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
        rw [mem_setOf_eq, ← ofReal_def, exp_ofReal_re]
        exact Real.exp_pos x
      map_target' := fun z h => by
        

Proof state:
z : ℂ
h : z ∈ {z | 0 < z.re} ∪ {z | z.im ≠ 0}
⊢ log z ∈ {z | z.im ∈ Ioo (-π) π}

Next tactic:
simp only [mem_setOf, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and]
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
        rw [mem_setOf_eq, ← ofReal_def, exp_ofReal_re]
        exact Real.exp_pos x
      map_target' := fun z h => by
        simp only [mem_setOf, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and]
        

Proof state:
z : ℂ
h : z ∈ {z | 0 < z.re} ∪ {z | z.im ≠ 0}
⊢ 0 ≤ z.re ∨ z.im ≠ 0

Next tactic:
exact h.imp_left le_of_lt
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
        rw [mem_setOf_eq, ← ofReal_def, exp_ofReal_re]
        exact Real.exp_pos x
      map_target' := fun z h => by
        simp only [mem_setOf, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and]
        exact h.imp_left le_of_lt
      left_inv' := fun x hx => log_exp hx.1 (le_of_lt hx.2)
      right_inv' := fun x hx => exp_log <| by 

Proof state:
x : ℂ
hx : x ∈ {z | 0 < z.re} ∪ {z | z.im ≠ 0}
⊢ x ≠ 0

Next tactic:
rintro rfl
/-- `Complex.exp` as a `PartialHomeomorph` with `source = {z | -π < im z < π}` and
`target = {z | 0 < re z} ∪ {z | im z ≠ 0}`. This definition is used to prove that `Complex.log`
is complex differentiable at all points but the negative real semi-axis. -/
noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ :=
  PartialHomeomorph.ofContinuousOpen
    { toFun := exp
      invFun := log
      source := {z : ℂ | z.im ∈ Ioo (-π) π}
      target := {z : ℂ | 0 < z.re} ∪ {z : ℂ | z.im ≠ 0}
      map_source' := by
        rintro ⟨x, y⟩ ⟨h₁ : -π < y, h₂ : y < π⟩
        refine' (not_or_of_imp fun hz => _).symm
        obtain rfl : y = 0 := by
          rw [exp_im] at hz
          simpa [(Real.exp_pos _).ne', Real.sin_eq_zero_iff_of_lt_of_lt h₁ h₂] using hz
        rw [mem_setOf_eq, ← ofReal_def, exp_ofReal_re]
        exact Real.exp_pos x
      map_target' := fun z h => by
        simp only [mem_setOf, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and]
        exact h.imp_left le_of_lt
      left_inv' := fun x hx => log_exp hx.1 (le_of_lt hx.2)
      right_inv' := fun x hx => exp_log <| by rintro rfl; 

Proof state:
hx : 0 ∈ {z | 0 < z.re} ∪ {z | z.im ≠ 0}
⊢ False

Next tactic:
simp [lt_irrefl] at hx
theorem hasStrictDerivAt_log {x : ℂ} (h : 0 < x.re ∨ x.im ≠ 0) : HasStrictDerivAt log x⁻¹ x :=
  have h0 : x ≠ 0 := by 

Proof state:
x : ℂ
h : 0 < x.re ∨ x.im ≠ 0
⊢ x ≠ 0

Next tactic:
rintro rfl
theorem hasStrictDerivAt_log {x : ℂ} (h : 0 < x.re ∨ x.im ≠ 0) : HasStrictDerivAt log x⁻¹ x :=
  have h0 : x ≠ 0 := by rintro rfl; 

Proof state:
h : 0 < 0.re ∨ 0.im ≠ 0
⊢ False

Next tactic:
simp [lt_irrefl] at h
theorem hasStrictDerivAt_log {x : ℂ} (h : 0 < x.re ∨ x.im ≠ 0) : HasStrictDerivAt log x⁻¹ x :=
  have h0 : x ≠ 0 := by rintro rfl; simp [lt_irrefl] at h
  expPartialHomeomorph.hasStrictDerivAt_symm h h0 <| by
    

Proof state:
x : ℂ
h : 0 < x.re ∨ x.im ≠ 0
h0 : x ≠ 0
⊢ HasStrictDerivAt (↑expPartialHomeomorph) x (↑(PartialHomeomorph.symm expPartialHomeomorph) x)

Next tactic:
simpa [exp_log h0] using hasStrictDerivAt_exp (log x)
theorem HasStrictDerivAt.clog {f : ℂ → ℂ} {f' x : ℂ} (h₁ : HasStrictDerivAt f f' x)
    (h₂ : 0 < (f x).re ∨ (f x).im ≠ 0) : HasStrictDerivAt (fun t => log (f t)) (f' / f x) x := by
  

Proof state:
α : Type u_1
inst✝² : TopologicalSpace α
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace ℂ E
f : ℂ → ℂ
f' x : ℂ
h₁ : HasStrictDerivAt f f' x
h₂ : 0 < (f x).re ∨ (f x).im ≠ 0
⊢ HasStrictDerivAt (fun t => log (f t)) (f' / f x) x

Next tactic:
rw [div_eq_inv_mul]
theorem HasStrictDerivAt.clog {f : ℂ → ℂ} {f' x : ℂ} (h₁ : HasStrictDerivAt f f' x)
    (h₂ : 0 < (f x).re ∨ (f x).im ≠ 0) : HasStrictDerivAt (fun t => log (f t)) (f' / f x) x := by
  rw [div_eq_inv_mul]; 

Proof state:
α : Type u_1
inst✝² : TopologicalSpace α
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace ℂ E
f : ℂ → ℂ
f' x : ℂ
h₁ : HasStrictDerivAt f f' x
h₂ : 0 < (f x).re ∨ (f x).im ≠ 0
⊢ HasStrictDerivAt (fun t => log (f t)) ((f x)⁻¹ * f') x

Next tactic:
exact (hasStrictDerivAt_log h₂).comp x h₁
theorem HasStrictDerivAt.clog_real {f : ℝ → ℂ} {x : ℝ} {f' : ℂ} (h₁ : HasStrictDerivAt f f' x)
    (h₂ : 0 < (f x).re ∨ (f x).im ≠ 0) : HasStrictDerivAt (fun t => log (f t)) (f' / f x) x := by
  

Proof state:
α : Type u_1
inst✝² : TopologicalSpace α
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace ℂ E
f : ℝ → ℂ
x : ℝ
f' : ℂ
h₁ : HasStrictDerivAt f f' x
h₂ : 0 < (f x).re ∨ (f x).im ≠ 0
⊢ HasStrictDerivAt (fun t => log (f t)) (f' / f x) x

Next tactic:
simpa only [div_eq_inv_mul] using (hasStrictFDerivAt_log_real h₂).comp_hasStrictDerivAt x h₁
theorem HasDerivAt.clog {f : ℂ → ℂ} {f' x : ℂ} (h₁ : HasDerivAt f f' x)
    (h₂ : 0 < (f x).re ∨ (f x).im ≠ 0) : HasDerivAt (fun t => log (f t)) (f' / f x) x := by
  

Proof state:
α : Type u_1
inst✝² : TopologicalSpace α
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace ℂ E
f : ℂ → ℂ
f' x : ℂ
h₁ : HasDerivAt f f' x
h₂ : 0 < (f x).re ∨ (f x).im ≠ 0
⊢ HasDerivAt (fun t => log (f t)) (f' / f x) x

Next tactic:
rw [div_eq_inv_mul]
theorem HasDerivAt.clog {f : ℂ → ℂ} {f' x : ℂ} (h₁ : HasDerivAt f f' x)
    (h₂ : 0 < (f x).re ∨ (f x).im ≠ 0) : HasDerivAt (fun t => log (f t)) (f' / f x) x := by
  rw [div_eq_inv_mul]; 

Proof state:
α : Type u_1
inst✝² : TopologicalSpace α
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace ℂ E
f : ℂ → ℂ
f' x : ℂ
h₁ : HasDerivAt f f' x
h₂ : 0 < (f x).re ∨ (f x).im ≠ 0
⊢ HasDerivAt (fun t => log (f t)) ((f x)⁻¹ * f') x

Next tactic:
exact (hasStrictDerivAt_log h₂).hasDerivAt.comp x h₁