Theorem: Computable.bind_decode_iff
File: Mathlib/Computability/Partrec.lean

Proof steps:
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ fun a n => (decode n).bind (f a)
n : ℕ
⊢ ((↑(decode n)).bind fun a =>
      map encode
        ((fun a =>
            (do
                  let n ← (↑fun n => encode (decode n)) a.2
                  ↑n.ppred).bind
              ↑fun b => (fun a n => (decode n).bind (f a)) (a, b).1.1 (a, b).1.2)
          a)) =
    (↑(decode n)).bind fun a => map encode ((↑fun p => f p.1 p.2) a)
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ fun a n => (decode n).bind (f a)
n : ℕ
⊢ ((↑((decode (Nat.unpair n).1).bind fun a => Option.some (a, (Nat.unpair n).2))).bind fun a =>
      (↑(encode (decode a.2)).ppred).bind fun y => Part.some (encode ((decode a.2).bind fun a_1 => f a.1 a_1))) =
    (↑((decode (Nat.unpair n).1).bind fun a => Option.map (Prod.mk a) (decode (Nat.unpair n).2))).bind fun a =>
      Part.some (encode (f a.1 a.2))
tactic: simp only [decode_prod_val, decode_nat, Option.map_some', PFun.coe_val, bind_eq_bind,
          bind_some, Part.map_bind, map_some]
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ fun a n => (decode n).bind (f a)
n : ℕ
⊢ ((↑((decode (Nat.unpair n).1).bind fun a => Option.some (a, (Nat.unpair n).2))).bind fun a =>
      (↑(encode (decode a.2)).ppred).bind fun y => Part.some (encode ((decode a.2).bind fun a_1 => f a.1 a_1))) =
    (↑((decode (Nat.unpair n).1).bind fun a => Option.map (Prod.mk a) (decode (Nat.unpair n).2))).bind fun a =>
      Part.some (encode (f a.1 a.2))
state_after: case some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ fun a n => (decode n).bind (f a)
n : ℕ
val✝ : α
⊢ ((↑(encode (decode (Nat.unpair n).2)).ppred).bind fun y =>
      Part.some (encode ((decode (Nat.unpair n).2).bind fun a => f val✝ a))) =
    (↑(Option.map (Prod.mk val✝) (decode (Nat.unpair n).2))).bind fun a => Part.some (encode (f a.1 a.2))
tactic: cases decode (α := α) n.unpair.1 <;> simp
state_before: case some
α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ fun a n => (decode n).bind (f a)
n : ℕ
val✝ : α
⊢ ((↑(encode (decode (Nat.unpair n).2)).ppred).bind fun y =>
      Part.some (encode ((decode (Nat.unpair n).2).bind fun a => f val✝ a))) =
    (↑(Option.map (Prod.mk val✝) (decode (Nat.unpair n).2))).bind fun a => Part.some (encode (f a.1 a.2))
state_after: no goals
tactic: cases decode (α := β) n.unpair.2 <;> simp
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
⊢ Computable₂ fun a n => (decode n).bind (f a)
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
this : Partrec fun a => Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)
⊢ Computable₂ fun a n => (decode n).bind (f a)
tactic: have :
      Partrec fun a : α × ℕ =>
        (encode (decode (α := β) a.2)).casesOn (some Option.none)
          fun n => Part.map (f a.1) (decode (α := β) n) :=
      Partrec.nat_casesOn_right
        (h := fun (a : α × ℕ) (n : ℕ) ↦ map (fun b ↦ f a.1 b) (Part.ofOption (decode n)))
        (Primrec.encdec.to_comp.comp snd) (const Option.none)
        ((ofOption (Computable.decode.comp snd)).map (hf.comp (fst.comp <| fst.comp fst) snd).to₂)
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
this : Partrec fun a => Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)
⊢ Computable₂ fun a n => (decode n).bind (f a)
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
this : Partrec fun a => Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)
a : α × ℕ
⊢ (Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)) =
    (↑fun p => (fun a n => (decode n).bind (f a)) p.1 p.2) a
tactic: refine this.of_eq fun a => ?_
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
this : Partrec fun a => Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)
a : α × ℕ
⊢ (Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)) =
    (↑fun p => (fun a n => (decode n).bind (f a)) p.1 p.2) a
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
this : Partrec fun a => Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)
a : α × ℕ
⊢ Nat.rec (Part.some Option.none) (fun n n_ih => map (f a.1) ↑(decode n)) (encode (decode a.2)) =
    Part.some ((decode a.2).bind (f a.1))
tactic: simp
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
σ : Type u_4
inst✝³ : Primcodable α
inst✝² : Primcodable β
inst✝¹ : Primcodable γ
inst✝ : Primcodable σ
f : α → β → Option σ
hf : Computable₂ f
this : Partrec fun a => Nat.casesOn (encode (decode a.2)) (Part.some Option.none) fun n => map (f a.1) ↑(decode n)
a : α × ℕ
⊢ Nat.rec (Part.some Option.none) (fun n n_ih => map (f a.1) ↑(decode n)) (encode (decode a.2)) =
    Part.some ((decode a.2).bind (f a.1))
state_after: no goals
tactic: cases decode (α := β) a.2 <;> simp [encodek]