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

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₂ 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: cases decode (α := α) n.unpair.1 <;> 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₂ 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.2 <;> 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: 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
⊢ 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: 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)
⊢ 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: 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.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: cases decode (α := β) a.2 <;> simp [encodek]
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