l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
by_cases h : a < b
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : a < b
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
by_cases h₂ : b < a
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : ¬a < b
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
by_cases h₂ : b < a
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> by_cases h₂ : b < a <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : a < b
h₂ : b < a
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
simp [h, h₂, Ordering.swap]
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> by_cases h₂ : b < a <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : a < b
h₂ : ¬b < a
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
simp [h, h₂, Ordering.swap]
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> by_cases h₂ : b < a <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : ¬a < b
h₂ : b < a
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
simp [h, h₂, Ordering.swap]
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> by_cases h₂ : b < a <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : ¬a < b
h₂ : ¬b < a
⊢ swap (if (fun x x_1 => x < x_1) a b then lt else if (fun x x_1 => x < x_1) b a then gt else eq) =
    if (fun x x_1 => x < x_1) b a then lt else if (fun x x_1 => x < x_1) a b then gt else eq

Next tactic:
simp [h, h₂, Ordering.swap]
@[simp]
theorem cmp_swap [Preorder α] [@DecidableRel α (· < ·)] (a b : α) : (cmp a b).swap = cmp b a := by
  unfold cmp cmpUsing
  by_cases h : a < b <;> by_cases h₂ : b < a <;> simp [h, h₂, Ordering.swap]
  

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x < x_1
a b : α
h : a < b
h₂ : b < a
⊢ False

Next tactic:
exact lt_asymm h h₂
@[simp]
theorem cmp_self_eq_eq : cmp x x = Ordering.eq := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
x y : α
⊢ cmp x x = eq

Next tactic:
rw [cmp_eq_eq_iff]
theorem cmp_eq_cmp_symm : cmp x y = cmp x' y' ↔ cmp y x = cmp y' x' :=
  ⟨fun h => by 

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ cmp y x = cmp y' x'

Next tactic:
rwa [← cmp_swap x', ← cmp_swap, swap_inj]
theorem cmp_eq_cmp_symm : cmp x y = cmp x' y' ↔ cmp y x = cmp y' x' :=
  ⟨fun h => by rwa [← cmp_swap x', ← cmp_swap, swap_inj],
   fun h => by 

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp y x = cmp y' x'
⊢ cmp x y = cmp x' y'

Next tactic:
rwa [← cmp_swap y', ← cmp_swap, swap_inj]
theorem lt_iff_lt_of_cmp_eq_cmp (h : cmp x y = cmp x' y') : x < y ↔ x' < y' := by
  

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ x < y ↔ x' < y'

Next tactic:
rw [← cmp_eq_lt_iff, ← cmp_eq_lt_iff, h]
theorem le_iff_le_of_cmp_eq_cmp (h : cmp x y = cmp x' y') : x ≤ y ↔ x' ≤ y' := by
  

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ x ≤ y ↔ x' ≤ y'

Next tactic:
rw [← not_lt, ← not_lt]
theorem le_iff_le_of_cmp_eq_cmp (h : cmp x y = cmp x' y') : x ≤ y ↔ x' ≤ y' := by
  rw [← not_lt, ← not_lt]
  

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ ¬y < x ↔ ¬y' < x'

Next tactic:
apply not_congr
theorem le_iff_le_of_cmp_eq_cmp (h : cmp x y = cmp x' y') : x ≤ y ↔ x' ≤ y' := by
  rw [← not_lt, ← not_lt]
  apply not_congr
  

Proof state:
case h
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ y < x ↔ y' < x'

Next tactic:
apply lt_iff_lt_of_cmp_eq_cmp
theorem le_iff_le_of_cmp_eq_cmp (h : cmp x y = cmp x' y') : x ≤ y ↔ x' ≤ y' := by
  rw [← not_lt, ← not_lt]
  apply not_congr
  apply lt_iff_lt_of_cmp_eq_cmp
  

Proof state:
case h.h
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ cmp y x = cmp y' x'

Next tactic:
rwa [cmp_eq_cmp_symm]
theorem eq_iff_eq_of_cmp_eq_cmp (h : cmp x y = cmp x' y') : x = y ↔ x' = y' := by
  

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : LinearOrder α
x y : α
β : Type u_3
inst✝ : LinearOrder β
x' y' : β
h : cmp x y = cmp x' y'
⊢ x = y ↔ x' = y'

Next tactic:
rw [le_antisymm_iff, le_antisymm_iff, le_iff_le_of_cmp_eq_cmp h,
      le_iff_le_of_cmp_eq_cmp (cmp_eq_cmp_symm.1 h)]
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  

Proof state:
f g : ℕ →. ℕ
hf : Partrec f
hg : Partrec g
⊢ ∃ h, Partrec h ∧ ∀ (a : ℕ), (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom)

Next tactic:
obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  

Proof state:
case intro
g : ℕ →. ℕ
hg : Partrec g
cf : Code
hf : Partrec (Code.eval cf)
⊢ ∃ h, Partrec h ∧ ∀ (a : ℕ), (∀ x ∈ h a, x ∈ Code.eval cf a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (Code.eval cf a).Dom ∨ (g a).Dom)

Next tactic:
obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
⊢ ∃ h,
    Partrec h ∧
      ∀ (a : ℕ),
        (∀ x ∈ h a, x ∈ Code.eval cf a ∨ x ∈ Code.eval cg a) ∧ ((h a).Dom ↔ (Code.eval cf a).Dom ∨ (Code.eval cg a).Dom)

Next tactic:
have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
⊢ ∃ h,
    Partrec h ∧
      ∀ (a : ℕ),
        (∀ x ∈ h a, x ∈ Code.eval cf a ∨ x ∈ Code.eval cg a) ∧ ((h a).Dom ↔ (Code.eval cf a).Dom ∨ (Code.eval cg a).Dom)

Next tactic:
refine' ⟨_, this, fun n => _⟩
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
⊢ (∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
      x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n) ∧
    ((rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom ↔
      (Code.eval cf n).Dom ∨ (Code.eval cg n).Dom)

Next tactic:
suffices
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; 

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this : ?m.248177
⊢ (∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
      x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n) ∧
    ((rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom ↔
      (Code.eval cf n).Dom ∨ (Code.eval cg n).Dom)
case this
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
⊢ ?m.248177

Next tactic:
refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · 

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
⊢ (Code.eval cf n).Dom ∨ (Code.eval cg n).Dom →
    (rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom

Next tactic:
intro h
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
h : (Code.eval cf n).Dom ∨ (Code.eval cg n).Dom
⊢ (rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom

Next tactic:
rw [Nat.rfindOpt_dom]
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    rw [Nat.rfindOpt_dom]
    

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
h : (Code.eval cf n).Dom ∨ (Code.eval cg n).Dom
⊢ ∃ n_1 a, a ∈ HOrElse.hOrElse (Code.evaln n_1 cf n) fun x => Code.evaln n_1 cg n

Next tactic:
simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    rw [Nat.rfindOpt_dom]
    simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
    

Proof state:
case intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
h : (∃ y k, Code.evaln k cf n = Option.some y) ∨ ∃ y k, Code.evaln k cg n = Option.some y
⊢ ∃ n_1 a, a ∈ HOrElse.hOrElse (Code.evaln n_1 cf n) fun x => Code.evaln n_1 cg n

Next tactic:
obtain ⟨x, k, e⟩ | ⟨x, k, e⟩ := h
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    rw [Nat.rfindOpt_dom]
    simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
    obtain ⟨x, k, e⟩ | ⟨x, k, e⟩ := h
    · 

Proof state:
case intro.intro.inl.intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
x k : ℕ
e : Code.evaln k cf n = Option.some x
⊢ ∃ n_1 a, a ∈ HOrElse.hOrElse (Code.evaln n_1 cf n) fun x => Code.evaln n_1 cg n

Next tactic:
refine' ⟨k, x, _⟩
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    rw [Nat.rfindOpt_dom]
    simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
    obtain ⟨x, k, e⟩ | ⟨x, k, e⟩ := h
    · refine' ⟨k, x, _⟩
      

Proof state:
case intro.intro.inl.intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
x k : ℕ
e : Code.evaln k cf n = Option.some x
⊢ x ∈ HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n

Next tactic:
simp only [e, Option.some_orElse, Option.mem_def]
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    rw [Nat.rfindOpt_dom]
    simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
    obtain ⟨x, k, e⟩ | ⟨x, k, e⟩ := h
    · refine' ⟨k, x, _⟩
      simp only [e, Option.some_orElse, Option.mem_def]
    · 

Proof state:
case intro.intro.inr.intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
x k : ℕ
e : Code.evaln k cg n = Option.some x
⊢ ∃ n_1 a, a ∈ HOrElse.hOrElse (Code.evaln n_1 cf n) fun x => Code.evaln n_1 cg n

Next tactic:
refine' ⟨k, _⟩
theorem merge' {f g} (hf : Nat.Partrec f) (hg : Nat.Partrec g) :
    ∃ h, Nat.Partrec h ∧
      ∀ a, (∀ x ∈ h a, x ∈ f a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (f a).Dom ∨ (g a).Dom) := by
  obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
  obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
  have : Nat.Partrec fun n => Nat.rfindOpt fun k => cf.evaln k n <|> cg.evaln k n :=
    Partrec.nat_iff.1
      (Partrec.rfindOpt <|
        Primrec.option_orElse.to_comp.comp
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cf)).pair fst)
          (Code.evaln_prim.to_comp.comp <| (snd.pair (const cg)).pair fst))
  refine' ⟨_, this, fun n => _⟩
  suffices; refine' ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, _⟩⟩
  · intro h
    rw [Nat.rfindOpt_dom]
    simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
    obtain ⟨x, k, e⟩ | ⟨x, k, e⟩ := h
    · refine' ⟨k, x, _⟩
      simp only [e, Option.some_orElse, Option.mem_def]
    · refine' ⟨k, _⟩
      

Proof state:
case intro.intro.inr.intro.intro
cf : Code
hf : Partrec (Code.eval cf)
cg : Code
hg : Partrec (Code.eval cg)
this✝ : Partrec fun n => rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
n : ℕ
this :
  ∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n
x k : ℕ
e : Code.evaln k cg n = Option.some x
⊢ ∃ a, a ∈ HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n

Next tactic:
cases' cf.evaln k n with y