l3lab/ntp-mathlib huggingface dataset:
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, _⟩
      cases' cf.evaln k n with y
      · 

Proof state:
case intro.intro.inr.intro.intro.none
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 Option.none fun x => Code.evaln k cg n

Next tactic:
exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by 

Proof state:
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
⊢ x ∈ HOrElse.hOrElse Option.none fun x => Code.evaln k cg n

Next tactic:
simp only [e, Option.mem_def, Option.none_orElse]
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · 

Proof state:
case intro.intro.inr.intro.intro.some
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
y : ℕ
⊢ ∃ a, a ∈ HOrElse.hOrElse (Option.some y) fun x => Code.evaln k cg n

Next tactic:
exact ⟨y, by simp only [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]
    · refine' ⟨k, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by 

Proof state:
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
y : ℕ
⊢ y ∈ HOrElse.hOrElse (Option.some y) fun x => Code.evaln k cg n

Next tactic:
simp only [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]
    · refine' ⟨k, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  

Proof state:
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 : ℕ
⊢ ∀ 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

Next tactic:
intro x 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
    · refine' ⟨k, x, _⟩
      simp only [e, Option.some_orElse, Option.mem_def]
    · refine' ⟨k, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  

Proof state:
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 x : ℕ
h : 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

Next tactic:
obtain ⟨k, e⟩ := Nat.rfindOpt_spec 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
    · refine' ⟨k, x, _⟩
      simp only [e, Option.some_orElse, Option.mem_def]
    · refine' ⟨k, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  

Proof state:
case this.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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k : ℕ
e : x ∈ HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
⊢ x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
revert e
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  

Proof state:
case this.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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k : ℕ
⊢ (x ∈ HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n) → x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
simp only [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]
    · refine' ⟨k, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  simp only [Option.mem_def]
  

Proof state:
case this.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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k : ℕ
⊢ (HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n) = Option.some x →
    x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
cases' e' : cf.evaln k n with y
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  simp only [Option.mem_def]
  cases' e' : cf.evaln k n with y <;> 

Proof state:
case this.intro.none
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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k : ℕ
e' : Code.evaln k cf n = Option.none
⊢ (HOrElse.hOrElse Option.none fun x => Code.evaln k cg n) = Option.some x → x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
simp
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  simp only [Option.mem_def]
  cases' e' : cf.evaln k n with y <;> 

Proof state:
case this.intro.some
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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k y : ℕ
e' : Code.evaln k cf n = Option.some y
⊢ (HOrElse.hOrElse (Option.some y) fun x => Code.evaln k cg n) = Option.some x → x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
simp
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  simp only [Option.mem_def]
  cases' e' : cf.evaln k n with y <;> simp <;> 

Proof state:
case this.intro.none
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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k : ℕ
e' : Code.evaln k cf n = Option.none
⊢ Code.evaln k cg n = Option.some x → x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
intro e
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  simp only [Option.mem_def]
  cases' e' : cf.evaln k n with y <;> simp <;> 

Proof state:
case this.intro.some
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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k y : ℕ
e' : Code.evaln k cf n = Option.some y
⊢ y = x → x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
intro e
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, _⟩
      cases' cf.evaln k n with y
      · exact ⟨x, by simp only [e, Option.mem_def, Option.none_orElse]⟩
      · exact ⟨y, by simp only [Option.some_orElse, Option.mem_def]⟩
  intro x h
  obtain ⟨k, e⟩ := Nat.rfindOpt_spec h
  revert e
  simp only [Option.mem_def]
  cases' e' : cf.evaln k n with y <;> simp <;> intro e
  · 

Proof state:
case this.intro.none
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 : ℕ
h : x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n
k : ℕ
e' : Code.evaln k cf n = Option.none
e : Code.evaln k cg n = Option.some x
⊢ x ∈ Code.eval cf n ∨ x ∈ Code.eval cg n

Next tactic:
exact Or.inr (Code.evaln_sound e)