l3lab/ntp-mathlib huggingface dataset:
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  

Proof state:
case intro
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
⊢ g ∈ C

Next tactic:
obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  

Proof state:
case intro.intro
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
e :
  eval c = fun b =>
    bif decide ((fun c => eval c ∈ C) (c, b).1) then (fun a b => g (a, b).2) (c, b).1 (c, b).2
    else (fun a b => f (a, b).2) (c, b).1 (c, b).2
⊢ g ∈ C

Next tactic:
simp? at e says simp only [Bool.cond_decide] at e
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says 

Proof state:
case intro.intro
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
e :
  eval c = fun b =>
    bif decide ((fun c => eval c ∈ C) (c, b).1) then (fun a b => g (a, b).2) (c, b).1 (c, b).2
    else (fun a b => f (a, b).2) (c, b).1 (c, b).2
⊢ g ∈ C

Next tactic:
simp only [Bool.cond_decide] at e
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  

Proof state:
case intro.intro
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
e : eval c = fun b => if eval c ∈ C then g b else f b
⊢ g ∈ C

Next tactic:
by_cases H : eval c ∈ C
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  by_cases H : eval c ∈ C
  · 

Proof state:
case pos
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
e : eval c = fun b => if eval c ∈ C then g b else f b
H : eval c ∈ C
⊢ g ∈ C

Next tactic:
simp only [H, if_true] at e
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  by_cases H : eval c ∈ C
  · simp only [H, if_true] at e
    

Proof state:
case pos
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
H : eval c ∈ C
e : eval c = fun b => g b
⊢ g ∈ C

Next tactic:
change (fun b => g b) ∈ C
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  by_cases H : eval c ∈ C
  · simp only [H, if_true] at e
    change (fun b => g b) ∈ C
    

Proof state:
case pos
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
H : eval c ∈ C
e : eval c = fun b => g b
⊢ (fun b => g b) ∈ C

Next tactic:
rwa [← e]
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  by_cases H : eval c ∈ C
  · simp only [H, if_true] at e
    change (fun b => g b) ∈ C
    rwa [← e]
  · 

Proof state:
case neg
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
e : eval c = fun b => if eval c ∈ C then g b else f b
H : eval c ∉ C
⊢ g ∈ C

Next tactic:
simp only [H, if_false] at e
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  by_cases H : eval c ∈ C
  · simp only [H, if_true] at e
    change (fun b => g b) ∈ C
    rwa [← e]
  · simp only [H, if_false] at e
    

Proof state:
case neg
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
H : eval c ∉ C
e : eval c = fun b => f b
⊢ g ∈ C

Next tactic:
rw [e] at H
/-- **Rice's Theorem** -/
theorem rice (C : Set (ℕ →. ℕ)) (h : ComputablePred fun c => eval c ∈ C) {f g} (hf : Nat.Partrec f)
    (hg : Nat.Partrec g) (fC : f ∈ C) : g ∈ C := by
  cases' h with _ h; skip
  obtain ⟨c, e⟩ :=
    fixed_point₂
      (Partrec.cond (h.comp fst) ((Partrec.nat_iff.2 hg).comp snd).to₂
          ((Partrec.nat_iff.2 hf).comp snd).to₂).to₂
  simp? at e says simp only [Bool.cond_decide] at e
  by_cases H : eval c ∈ C
  · simp only [H, if_true] at e
    change (fun b => g b) ∈ C
    rwa [← e]
  · simp only [H, if_false] at e
    rw [e] at H
    

Proof state:
case neg
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set (ℕ →. ℕ)
f g : ℕ →. ℕ
hf : Nat.Partrec f
hg : Nat.Partrec g
fC : f ∈ C
w✝ : DecidablePred fun c => eval c ∈ C
h : Computable fun a => decide ((fun c => eval c ∈ C) a)
c : Code
H : (fun b => f b) ∉ C
e : eval c = fun b => f b
⊢ g ∈ C

Next tactic:
contradiction
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set Code
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)
⊢ (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ

Next tactic:
classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            exact ⟨by infer_instance, Computable.const _⟩ }⟩
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical 

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set Code
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)
⊢ (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ

Next tactic:
exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            exact ⟨by infer_instance, Computable.const _⟩ }⟩
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by 

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set Code
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)
hC : ∀ (f : Code), f ∈ C ↔ eval f ∈ eval '' C
h : C = ∅ ∨ C = Set.univ
⊢ ComputablePred fun c => c ∈ C

Next tactic:
{
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            exact ⟨by infer_instance, Computable.const _⟩ }
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
C : Set Code
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)
hC : ∀ (f : Code), f ∈ C ↔ eval f ∈ eval '' C
h : C = ∅ ∨ C = Set.univ
⊢ ComputablePred fun c => c ∈ C

Next tactic:
obtain rfl | rfl := h
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> 

Proof state:
case inl
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ ∅ ↔ cg ∈ ∅)
hC : ∀ (f : Code), f ∈ ∅ ↔ eval f ∈ eval '' ∅
⊢ ComputablePred fun c => c ∈ ∅

Next tactic:
simp [ComputablePred, Set.mem_empty_iff_false]
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> 

Proof state:
case inr
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ Set.univ ↔ cg ∈ Set.univ)
hC : ∀ (f : Code), f ∈ Set.univ ↔ eval f ∈ eval '' Set.univ
⊢ ComputablePred fun c => c ∈ Set.univ

Next tactic:
simp [ComputablePred, Set.mem_empty_iff_false]
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            

Proof state:
case inl
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ ∅ ↔ cg ∈ ∅)
hC : ∀ (f : Code), f ∈ ∅ ↔ eval f ∈ eval '' ∅
⊢ ∃ x, Computable fun a => false

Next tactic:
exact ⟨by infer_instance, Computable.const _⟩
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            exact ⟨by 

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ ∅ ↔ cg ∈ ∅)
hC : ∀ (f : Code), f ∈ ∅ ↔ eval f ∈ eval '' ∅
⊢ DecidablePred fun c => c ∈ ∅

Next tactic:
infer_instance
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            

Proof state:
case inr
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ Set.univ ↔ cg ∈ Set.univ)
hC : ∀ (f : Code), f ∈ Set.univ ↔ eval f ∈ eval '' Set.univ
⊢ ∃ x, Computable fun a => true

Next tactic:
exact ⟨by infer_instance, Computable.const _⟩
theorem rice₂ (C : Set Code) (H : ∀ cf cg, eval cf = eval cg → (cf ∈ C ↔ cg ∈ C)) :
    (ComputablePred fun c => c ∈ C) ↔ C = ∅ ∨ C = Set.univ := by
  classical exact
      have hC : ∀ f, f ∈ C ↔ eval f ∈ eval '' C := fun f =>
        ⟨Set.mem_image_of_mem _, fun ⟨g, hg, e⟩ => (H _ _ e).1 hg⟩
      ⟨fun h =>
        or_iff_not_imp_left.2 fun C0 =>
          Set.eq_univ_of_forall fun cg =>
            let ⟨cf, fC⟩ := Set.nonempty_iff_ne_empty.2 C0
            (hC _).2 <|
              rice (eval '' C) (h.of_eq hC)
                (Partrec.nat_iff.1 <| eval_part.comp (const cf) Computable.id)
                (Partrec.nat_iff.1 <| eval_part.comp (const cg) Computable.id) ((hC _).1 fC),
        fun h => by {
          obtain rfl | rfl := h <;> simp [ComputablePred, Set.mem_empty_iff_false] <;>
            exact ⟨by 

Proof state:
α : Type u_1
σ : Type u_2
inst✝¹ : Primcodable α
inst✝ : Primcodable σ
H : ∀ (cf cg : Code), eval cf = eval cg → (cf ∈ Set.univ ↔ cg ∈ Set.univ)
hC : ∀ (f : Code), f ∈ Set.univ ↔ eval f ∈ eval '' Set.univ
⊢ DecidablePred fun c => c ∈ Set.univ

Next tactic:
infer_instance
theorem computable_iff_re_compl_re {p : α → Prop} [DecidablePred p] :
    ComputablePred p ↔ RePred p ∧ RePred fun a => ¬p a :=
  ⟨fun h => ⟨h.to_re, h.not.to_re⟩, fun ⟨h₁, h₂⟩ =>
    ⟨‹_›, by
      

Proof state:
α : Type u_1
σ : Type u_2
inst✝² : Primcodable α
inst✝¹ : Primcodable σ
p : α → Prop
inst✝ : DecidablePred p
x✝ : RePred p ∧ RePred fun a => ¬p a
h₁ : RePred p
h₂ : RePred fun a => ¬p a
⊢ Computable fun a => decide (p a)

Next tactic:
obtain ⟨k, pk, hk⟩ :=
        Partrec.merge (h₁.map (Computable.const true).to₂) (h₂.map (Computable.const false).to₂)
        (by
          intro a x hx y hy
          simp only [Part.mem_map_iff, Part.mem_assert_iff, Part.mem_some_iff, exists_prop,
            and_true, exists_const] at hx hy
          cases hy.1 hx.1)
theorem computable_iff_re_compl_re {p : α → Prop} [DecidablePred p] :
    ComputablePred p ↔ RePred p ∧ RePred fun a => ¬p a :=
  ⟨fun h => ⟨h.to_re, h.not.to_re⟩, fun ⟨h₁, h₂⟩ =>
    ⟨‹_›, by
      obtain ⟨k, pk, hk⟩ :=
        Partrec.merge (h₁.map (Computable.const true).to₂) (h₂.map (Computable.const false).to₂)
        (by
          

Proof state:
α : Type u_1
σ : Type u_2
inst✝² : Primcodable α
inst✝¹ : Primcodable σ
p : α → Prop
inst✝ : DecidablePred p
x✝ : RePred p ∧ RePred fun a => ¬p a
h₁ : RePred p
h₂ : RePred fun a => ¬p a
⊢ ∀ (a : α),
    ∀ x ∈ Part.map (fun b => true) (Part.assert (p a) fun x => Part.some ()),
      ∀ y ∈ Part.map (fun b => false) (Part.assert ((fun a => ¬p a) a) fun x => Part.some ()), x = y

Next tactic:
intro a x hx y hy
theorem computable_iff_re_compl_re {p : α → Prop} [DecidablePred p] :
    ComputablePred p ↔ RePred p ∧ RePred fun a => ¬p a :=
  ⟨fun h => ⟨h.to_re, h.not.to_re⟩, fun ⟨h₁, h₂⟩ =>
    ⟨‹_›, by
      obtain ⟨k, pk, hk⟩ :=
        Partrec.merge (h₁.map (Computable.const true).to₂) (h₂.map (Computable.const false).to₂)
        (by
          intro a x hx y hy
          

Proof state:
α : Type u_1
σ : Type u_2
inst✝² : Primcodable α
inst✝¹ : Primcodable σ
p : α → Prop
inst✝ : DecidablePred p
x✝ : RePred p ∧ RePred fun a => ¬p a
h₁ : RePred p
h₂ : RePred fun a => ¬p a
a : α
x : Bool
hx : x ∈ Part.map (fun b => true) (Part.assert (p a) fun x => Part.some ())
y : Bool
hy : y ∈ Part.map (fun b => false) (Part.assert ((fun a => ¬p a) a) fun x => Part.some ())
⊢ x = y

Next tactic:
simp only [Part.mem_map_iff, Part.mem_assert_iff, Part.mem_some_iff, exists_prop,
            and_true, exists_const] at hx hy
theorem computable_iff_re_compl_re {p : α → Prop} [DecidablePred p] :
    ComputablePred p ↔ RePred p ∧ RePred fun a => ¬p a :=
  ⟨fun h => ⟨h.to_re, h.not.to_re⟩, fun ⟨h₁, h₂⟩ =>
    ⟨‹_›, by
      obtain ⟨k, pk, hk⟩ :=
        Partrec.merge (h₁.map (Computable.const true).to₂) (h₂.map (Computable.const false).to₂)
        (by
          intro a x hx y hy
          simp only [Part.mem_map_iff, Part.mem_assert_iff, Part.mem_some_iff, exists_prop,
            and_true, exists_const] at hx hy
          

Proof state:
α : Type u_1
σ : Type u_2
inst✝² : Primcodable α
inst✝¹ : Primcodable σ
p : α → Prop
inst✝ : DecidablePred p
x✝ : RePred p ∧ RePred fun a => ¬p a
h₁ : RePred p
h₂ : RePred fun a => ¬p a
a : α
x y : Bool
hx : p a ∧ true = x
hy : ¬p a ∧ false = y
⊢ x = y

Next tactic:
cases hy.1 hx.1
theorem computable_iff_re_compl_re {p : α → Prop} [DecidablePred p] :
    ComputablePred p ↔ RePred p ∧ RePred fun a => ¬p a :=
  ⟨fun h => ⟨h.to_re, h.not.to_re⟩, fun ⟨h₁, h₂⟩ =>
    ⟨‹_›, by
      obtain ⟨k, pk, hk⟩ :=
        Partrec.merge (h₁.map (Computable.const true).to₂) (h₂.map (Computable.const false).to₂)
        (by
          intro a x hx y hy
          simp only [Part.mem_map_iff, Part.mem_assert_iff, Part.mem_some_iff, exists_prop,
            and_true, exists_const] at hx hy
          cases hy.1 hx.1)
      · 

Proof state:
case intro.intro
α : Type u_1
σ : Type u_2
inst✝² : Primcodable α
inst✝¹ : Primcodable σ
p : α → Prop
inst✝ : DecidablePred p
x✝ : RePred p ∧ RePred fun a => ¬p a
h₁ : RePred p
h₂ : RePred fun a => ¬p a
k : α →. Bool
pk : Partrec k
hk :
  ∀ (a : α) (x : Bool),
    x ∈ k a ↔
      x ∈ Part.map (fun b => true) (Part.assert (p a) fun x => Part.some ()) ∨
        x ∈ Part.map (fun b => false) (Part.assert ((fun a => ¬p a) a) fun x => Part.some ())
⊢ Computable fun a => decide (p a)

Next tactic:
refine' Partrec.of_eq pk fun n => Part.eq_some_iff.2 _