Theorem: Nat.Partrec.merge'
File: Mathlib/Computability/Halting.lean

Proof steps:
state_before: 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)
state_after: case intro
g : ℕ →. ℕ
hg : Partrec g
cf : Code
hf : Partrec cf.eval
⊢ ∃ h, Partrec h ∧ ∀ (a : ℕ), (∀ x ∈ h a, x ∈ cf.eval a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (cf.eval a).Dom ∨ (g a).Dom)
tactic: obtain ⟨cf, rfl⟩ := Code.exists_code.1 hf
state_before: case intro
g : ℕ →. ℕ
hg : Partrec g
cf : Code
hf : Partrec cf.eval
⊢ ∃ h, Partrec h ∧ ∀ (a : ℕ), (∀ x ∈ h a, x ∈ cf.eval a ∨ x ∈ g a) ∧ ((h a).Dom ↔ (cf.eval a).Dom ∨ (g a).Dom)
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
⊢ ∃ h,
    Partrec h ∧ ∀ (a : ℕ), (∀ x ∈ h a, x ∈ cf.eval a ∨ x ∈ cg.eval a) ∧ ((h a).Dom ↔ (cf.eval a).Dom ∨ (cg.eval a).Dom)
tactic: obtain ⟨cg, rfl⟩ := Code.exists_code.1 hg
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
⊢ ∃ h,
    Partrec h ∧ ∀ (a : ℕ), (∀ x ∈ h a, x ∈ cf.eval a ∨ x ∈ cg.eval a) ∧ ((h a).Dom ↔ (cf.eval a).Dom ∨ (cg.eval a).Dom)
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval a ∨ x ∈ cg.eval a) ∧ ((h a).Dom ↔ (cf.eval a).Dom ∨ (cg.eval a).Dom)
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))
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval a ∨ x ∈ cg.eval a) ∧ ((h a).Dom ↔ (cf.eval a).Dom ∨ (cg.eval a).Dom)
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n) ∧
    ((rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom ↔
      (cf.eval n).Dom ∨ (cg.eval n).Dom)
tactic: refine ⟨_, this, fun n => ?_⟩
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
⊢ (∀ x ∈ rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n,
      x ∈ cf.eval n ∨ x ∈ cg.eval n) ∧
    ((rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom ↔
      (cf.eval n).Dom ∨ (cg.eval n).Dom)
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
⊢ (cf.eval n).Dom ∨ (cg.eval n).Dom →
    (rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom
tactic: refine ⟨this, ⟨fun h => (this _ ⟨h, rfl⟩).imp Exists.fst Exists.fst, ?_⟩⟩
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
⊢ (cf.eval n).Dom ∨ (cg.eval n).Dom →
    (rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
h : (cf.eval n).Dom ∨ (cg.eval n).Dom
⊢ (rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom
tactic: intro h
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
h : (cf.eval n).Dom ∨ (cg.eval n).Dom
⊢ (rfindOpt fun k => HOrElse.hOrElse (Code.evaln k cf n) fun x => Code.evaln k cg n).Dom
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
h : (cf.eval n).Dom ∨ (cg.eval n).Dom
⊢ ∃ n_1 a, a ∈ HOrElse.hOrElse (Code.evaln n_1 cf n) fun x => Code.evaln n_1 cg n
tactic: rw [Nat.rfindOpt_dom]
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval n
h : (cf.eval n).Dom ∨ (cg.eval n).Dom
⊢ ∃ n_1 a, a ∈ HOrElse.hOrElse (Code.evaln n_1 cf n) fun x => Code.evaln n_1 cg n
state_after: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval 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
tactic: simp only [dom_iff_mem, Code.evaln_complete, Option.mem_def] at h
state_before: case intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval 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
state_after: case intro.intro.inl.intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval 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

case intro.intro.inr.intro.intro
cf : Code
hf : Partrec cf.eval
cg : Code
hg : Partrec cg.eval
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 ∈ cf.eval n ∨ x ∈ cg.eval 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
tactic: obtain ⟨x, k, e⟩ | ⟨x, k, e⟩ := h