Theorem: Primrec.nat_rec
File: Mathlib/Computability/Primrec.lean

tactic: simp
state_before: α : Type u_2
β : Type u_1
γ : Type ?u.94667
δ : Type ?u.94670
σ : Type ?u.94673
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β
g : α → ℕ × β → β
hf : Primrec f
hg : Primrec₂ g
n : ℕ
⊢ Nat.unpaired
      (fun z n =>
        Nat.casesOn n 0 fun y =>
          Nat.unpaired
            (fun z n =>
              Nat.rec (encode (Option.map f (decode z)))
                (fun y IH =>
                  encode
                    (Option.map (fun p => g p.fst p.snd)
                      (decode
                        (Nat.pair (Nat.unpair (Nat.pair z (Nat.pair y IH))).fst
                          (Nat.pair (Nat.unpair (Nat.unpair (Nat.pair z (Nat.pair y IH))).snd).fst
                            (Nat.pred (Nat.unpair (Nat.unpair (Nat.pair z (Nat.pair y IH))).snd).snd))))))
                n)
            (Nat.pair (Nat.unpair (Nat.pair z y)).snd (Nat.unpair (Nat.unpair (Nat.pair z y)).fst).snd))
      (Nat.pair (id n) (encode (decode (Nat.unpair n).fst))) =
    Nat.unpaired
      (fun m n =>
        encode
          (Option.bind (decode m) fun a => Option.map (fun n => Nat.rec (f a) (fun n IH => g a (n, IH)) n) (decode n)))
      n

tactic: cases' @decode α _ n.unpair.1 with a
state_before: α : Type u_2
β : Type u_1
γ : Type ?u.94667
δ : Type ?u.94670
σ : Type ?u.94673
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β
g : α → ℕ × β → β
hf : Primrec f
hg : Primrec₂ g
n : ℕ
⊢ Nat.rec 0
      (fun n_1 n_ih =>
        Nat.rec (encode (Option.map f (decode n_1)))
          (fun y IH =>
            encode
              (Option.map (fun p => g p.fst p.snd)
                (Option.bind (decode n_1) fun a => Option.map (Prod.mk a ∘ Prod.mk y) (decode (Nat.pred IH)))))
          (Nat.unpair n).snd)
      (encode (decode (Nat.unpair n).fst)) =
    encode
      (Option.bind (decode (Nat.unpair n).fst) fun a =>
        some (Nat.rec (f a) (fun n IH => g a (n, IH)) (Nat.unpair n).snd))

tactic: simp [encodek]
state_before: case some
α : Type u_2
β : Type u_1
γ : Type ?u.94667
δ : Type ?u.94670
σ : Type ?u.94673
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β
g : α → ℕ × β → β
hf : Primrec f
hg : Primrec₂ g
n : ℕ
a : α
⊢ Nat.rec 0
      (fun n_1 n_ih =>
        Nat.rec (encode (Option.map f (decode n_1)))
          (fun y IH =>
            encode
              (Option.map (fun p => g p.fst p.snd)
                (Option.bind (decode n_1) fun a => Option.map (Prod.mk a ∘ Prod.mk y) (decode (Nat.pred IH)))))
          (Nat.unpair n).snd)
      (encode (some a)) =
    encode (Option.bind (some a) fun a => some (Nat.rec (f a) (fun n IH => g a (n, IH)) (Nat.unpair n).snd))

tactic: induction' n.unpair.2 with m <;> simp [encodek]
state_before: case some
α : Type u_2
β : Type u_1
γ : Type ?u.94667
δ : Type ?u.94670
σ : Type ?u.94673
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β
g : α → ℕ × β → β
hf : Primrec f
hg : Primrec₂ g
n : ℕ
a : α
⊢ Nat.rec (Nat.succ (encode (f a)))
      (fun y IH => encode (Option.map ((fun p => g p.fst p.snd) ∘ Prod.mk a ∘ Prod.mk y) (decode (Nat.pred IH))))
      (Nat.unpair n).snd =
    Nat.succ (encode (Nat.rec (f a) (fun n IH => g a (n, IH)) (Nat.unpair n).snd))

tactic: simp [*, encodek]
state_before: case some.succ
α : Type u_2
β : Type u_1
γ : Type ?u.94667
δ : Type ?u.94670
σ : Type ?u.94673
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β
g : α → ℕ × β → β
hf : Primrec f
hg : Primrec₂ g
n : ℕ
a : α
m : ℕ
n_ih✝ :
  Nat.rec (Nat.succ (encode (f a)))
      (fun y IH => encode (Option.map ((fun p => g p.fst p.snd) ∘ Prod.mk a ∘ Prod.mk y) (decode (Nat.pred IH)))) m =
    Nat.succ (encode (Nat.rec (f a) (fun n IH => g a (n, IH)) m))
⊢ encode
      (Option.map ((fun p => g p.fst p.snd) ∘ Prod.mk a ∘ Prod.mk m)
        (decode
          (Nat.pred
            (Nat.rec (Nat.succ (encode (f a)))
              (fun y IH =>
                encode (Option.map ((fun p => g p.fst p.snd) ∘ Prod.mk a ∘ Prod.mk y) (decode (Nat.pred IH))))
              m)))) =
    Nat.succ (encode (g a (m, Nat.rec (f a) (fun n IH => g a (n, IH)) m)))

tactic: rfl
state_before: case none
α : Type u_2
β : Type u_1
γ : Type ?u.94667
δ : Type ?u.94670
σ : Type ?u.94673
inst✝⁴ : Primcodable α
inst✝³ : Primcodable β
inst✝² : Primcodable γ
inst✝¹ : Primcodable δ
inst✝ : Primcodable σ
f : α → β
g : α → ℕ × β → β
hf : Primrec f
hg : Primrec₂ g
n : ℕ
⊢ Nat.rec 0
      (fun n_1 n_ih =>
        Nat.rec (encode (Option.map f (decode n_1)))
          (fun y IH =>
            encode
              (Option.map (fun p => g p.fst p.snd)
                (Option.bind (decode n_1) fun a => Option.map (Prod.mk a ∘ Prod.mk y) (decode (Nat.pred IH)))))
          (Nat.unpair n).snd)
      (encode none) =
    encode (Option.bind none fun a => some (Nat.rec (f a) (fun n IH => g a (n, IH)) (Nat.unpair n).snd))