File: Mathlib/Computability/Primrec.lean

full_name: Nat.unpaired
code: /-- Calls the given function on a pair of entries `n`, encoded via the pairing function. -/
@[simp, reducible]
def unpaired {α} (f : ℕ → ℕ → α) (n : ℕ) : α 
goal: α

full_name: Nat.Primrec.succ
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec Nat.succ

full_name: Nat.Primrec.comp
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)

full_name: Nat.Primrec.prec
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec f →
  Nat.Primrec g → Nat.Primrec (Nat.unpaired fun z n => Nat.rec (f z) (fun y IH => g (Nat.pair z (Nat.pair y IH))) n)

full_name: Nat.Primrec.left
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec fun n => (Nat.unpair n).1

full_name: Nat.Primrec.pair
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => Nat.pair (f n) (g n)

full_name: Nat.Primrec
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: (ℕ → ℕ) → Prop

full_name: Nat.Primrec.zero
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec fun x => 0

full_name: Nat.Primrec.right
code: /-- The primitive recursive functions `ℕ → ℕ`. -/
protected inductive Primrec : (ℕ → ℕ) → Prop
  | zero : Nat.Primrec fun _ => 0
  | protected succ : Nat.Primrec succ
  | left : Nat.Primrec fun n => n.unpair.1
  | right : Nat.Primrec fun n => n.unpair.2
  | pair {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => pair (f n) (g n)
  | comp {f g} : Nat.Primrec f → Nat.Primrec g → Nat.Primrec fun n => f (g n)
  | prec {f g} :
      Nat.Primrec f →
        Nat.Primrec g →
          Nat.Primrec (unpaired fun z n => n.rec (f z) fun y IH => g <| pair z <| pair y IH)
goal: Nat.Primrec fun n => (Nat.unpair n).2

full_name: Nat.Primrec.of_eq
code: theorem of_eq {f g : ℕ → ℕ} (hf : Nat.Primrec f) (H : ∀ n, f n = g n) : Nat.Primrec g 
goal: Nat.Primrec g

full_name: Nat.Primrec.const
code: theorem const : ∀ n : ℕ, Nat.Primrec fun _ => n
  
goal: Nat.Primrec fun x => n

full_name: Nat.Primrec.id
code: protected theorem id : Nat.Primrec id 
goal: Nat.Primrec id

full_name: Nat.Primrec.prec1
code: theorem prec1 {f} (m : ℕ) (hf : Nat.Primrec f) :
    Nat.Primrec fun n => n.rec m fun y IH => f <| Nat.pair y IH 
goal: Nat.Primrec fun n => Nat.rec m (fun y IH => f (Nat.pair y IH)) n

full_name: Nat.Primrec.casesOn1
code: theorem casesOn1 {f} (m : ℕ) (hf : Nat.Primrec f) : Nat.Primrec (Nat.casesOn · m f) 
goal: Nat.Primrec fun x => Nat.casesOn x m f

full_name: Nat.Primrec.casesOn'
code: theorem casesOn' {f g} (hf : Nat.Primrec f) (hg : Nat.Primrec g) :
    Nat.Primrec (unpaired fun z n => n.casesOn (f z) fun y => g <| Nat.pair z y) 
goal: Nat.Primrec (Nat.unpaired fun z n => Nat.casesOn n (f z) fun y => g (Nat.pair z y))

full_name: Nat.Primrec.swap
code: protected theorem swap : Nat.Primrec (unpaired (swap Nat.pair)) 
goal: Nat.Primrec (Nat.unpaired (Function.swap Nat.pair))

full_name: Nat.Primrec.swap'
code: theorem swap' {f} (hf : Nat.Primrec (unpaired f)) : Nat.Primrec (unpaired (swap f)) 
goal: Nat.Primrec (Nat.unpaired (Function.swap f))

full_name: Nat.Primrec.pred
code: theorem pred : Nat.Primrec pred 
goal: Nat.Primrec Nat.pred

full_name: Nat.Primrec.add
code: theorem add : Nat.Primrec (unpaired (· + ·)) 
goal: Nat.Primrec (Nat.unpaired fun x x_1 => x + x_1)

full_name: Nat.Primrec.sub
code: theorem sub : Nat.Primrec (unpaired (· - ·)) 
goal: Nat.Primrec (Nat.unpaired fun x x_1 => x - x_1)

full_name: Nat.Primrec.mul
code: theorem mul : Nat.Primrec (unpaired (· * ·)) 
goal: Nat.Primrec (Nat.unpaired fun x x_1 => x * x_1)

full_name: Nat.Primrec.pow
code: theorem pow : Nat.Primrec (unpaired (· ^ ·)) 
goal: Nat.Primrec (Nat.unpaired fun x x_1 => x ^ x_1)

full_name: Primcodable.prim
code: /-- A `Primcodable` type is an `Encodable` type for which
  the encode/decode functions are primitive recursive. -/
class Primcodable (α : Type*) extends Encodable α where
  -- Porting note: was `prim [] `.
  -- This means that `prim` does not take the type explicitly in Lean 4
  prim : Nat.Primrec fun n => Encodable.encode (decode n)
goal: Nat.Primrec fun n => Encodable.encode (Encodable.decode n)

full_name: Primcodable
code: /-- A `Primcodable` type is an `Encodable` type for which
  the encode/decode functions are primitive recursive. -/
class Primcodable (α : Type*) extends Encodable α where
  -- Porting note: was `prim [] `.
  -- This means that `prim` does not take the type explicitly in Lean 4
  prim : Nat.Primrec fun n => Encodable.encode (decode n)
goal: Type u_1

full_name: Primcodable.ofDenumerable
code: instance (priority := 10) ofDenumerable (α) [Denumerable α] : Primcodable α 
goal: Primcodable α

full_name: Primcodable.ofEquiv
code: /-- Builds a `Primcodable` instance from an equivalence to a `Primcodable` type. -/
def ofEquiv (α) {β} [Primcodable α] (e : β ≃ α) : Primcodable β 
goal: Primcodable β

full_name: Primcodable.empty
code: instance empty : Primcodable Empty 
goal: Primcodable Empty

full_name: Primcodable.unit
code: instance unit : Primcodable PUnit 
goal: Primcodable PUnit.{u_1 + 1}

full_name: Primcodable.option
code: instance option {α : Type*} [h : Primcodable α] : Primcodable (Option α) 
goal: Primcodable (Option α)

full_name: Primcodable.bool
code: instance bool : Primcodable Bool 
goal: Primcodable Bool

full_name: Primrec
code: /-- `Primrec f` means `f` is primitive recursive (after
  encoding its input and output as natural numbers). -/
def Primrec {α β} [Primcodable α] [Primcodable β] (f : α → β) : Prop 
goal: Prop

full_name: Primrec.encode
code: protected theorem encode : Primrec (@encode α _) 
goal: Primrec Encodable.encode

full_name: Primrec.decode
code: protected theorem decode : Primrec (@decode α _) 
goal: Primrec Encodable.decode

full_name: Primrec.dom_denumerable
code: theorem dom_denumerable {α β} [Denumerable α] [Primcodable β] {f : α → β} :
    Primrec f ↔ Nat.Primrec fun n => encode (f (ofNat α n)) 
goal: Primrec f ↔ Nat.Primrec fun n => Encodable.encode (f (Denumerable.ofNat α n))

full_name: Primrec.nat_iff
code: theorem nat_iff {f : ℕ → ℕ} : Primrec f ↔ Nat.Primrec f 
goal: Primrec f ↔ Nat.Primrec f

full_name: Primrec.encdec
code: theorem encdec : Primrec fun n => encode (@decode α _ n) 
goal: Primrec fun n => Encodable.encode (Encodable.decode n)

full_name: Primrec.option_some
code: theorem option_some : Primrec (@some α) 
goal: Primrec some

full_name: Primrec.of_eq
code: theorem of_eq {f g : α → σ} (hf : Primrec f) (H : ∀ n, f n = g n) : Primrec g 
goal: Primrec g

full_name: Primrec.const
code: theorem const (x : σ) : Primrec fun _ : α => x 
goal: Primrec fun x_1 => x

full_name: Primrec.id
code: protected theorem id : Primrec (@id α) 
goal: Primrec id

full_name: Primrec.comp
code: theorem comp {f : β → σ} {g : α → β} (hf : Primrec f) (hg : Primrec g) : Primrec fun a => f (g a) 
goal: Primrec fun a => f (g a)

full_name: Primrec.succ
code: theorem succ : Primrec Nat.succ 
goal: Primrec Nat.succ

full_name: Primrec.pred
code: theorem pred : Primrec Nat.pred 
goal: Primrec Nat.pred

full_name: Primrec.encode_iff
code: theorem encode_iff {f : α → σ} : (Primrec fun a => encode (f a)) ↔ Primrec f 
goal: (Primrec fun a => Encodable.encode (f a)) ↔ Primrec f

full_name: Primrec.ofNat_iff
code: theorem ofNat_iff {α β} [Denumerable α] [Primcodable β] {f : α → β} :
    Primrec f ↔ Primrec fun n => f (ofNat α n) 
goal: Primrec f ↔ Primrec fun n => f (Denumerable.ofNat α n)

full_name: Primrec.ofNat
code: protected theorem ofNat (α) [Denumerable α] : Primrec (ofNat α) 
goal: Primrec (Denumerable.ofNat α)

full_name: Primrec.option_some_iff
code: theorem option_some_iff {f : α → σ} : (Primrec fun a => some (f a)) ↔ Primrec f 
goal: (Primrec fun a => some (f a)) ↔ Primrec f

full_name: Primrec.of_equiv
code: theorem of_equiv {β} {e : β ≃ α} :
    haveI := Primcodable.ofEquiv α e
    Primrec e 
goal: Primrec ⇑e

full_name: Primrec.of_equiv_symm
code: theorem of_equiv_symm {β} {e : β ≃ α} :
    haveI := Primcodable.ofEquiv α e
    Primrec e.symm 
goal: Primrec ⇑e.symm

full_name: Primrec.of_equiv_iff
code: theorem of_equiv_iff {β} (e : β ≃ α) {f : σ → β} :
    haveI := Primcodable.ofEquiv α e
    (Primrec fun a => e (f a)) ↔ Primrec f 
goal: (Primrec fun a => e (f a)) ↔ Primrec f

full_name: Primrec.of_equiv_symm_iff
code: theorem of_equiv_symm_iff {β} (e : β ≃ α) {f : σ → α} :
    haveI := Primcodable.ofEquiv α e
    (Primrec fun a => e.symm (f a)) ↔ Primrec f 
goal: (Primrec fun a => e.symm (f a)) ↔ Primrec f

full_name: Primcodable.prod
code: instance prod {α β} [Primcodable α] [Primcodable β] : Primcodable (α × β) 
goal: Primcodable (α × β)

full_name: Primrec.fst
code: theorem fst {α β} [Primcodable α] [Primcodable β] : Primrec (@Prod.fst α β) 
goal: Primrec Prod.fst

full_name: Primrec.snd
code: theorem snd {α β} [Primcodable α] [Primcodable β] : Primrec (@Prod.snd α β) 
goal: Primrec Prod.snd

full_name: Primrec.pair
code: theorem pair {α β γ} [Primcodable α] [Primcodable β] [Primcodable γ] {f : α → β} {g : α → γ}
    (hf : Primrec f) (hg : Primrec g) : Primrec fun a => (f a, g a) 
goal: Primrec fun a => (f a, g a)

full_name: Primrec.unpair
code: theorem unpair : Primrec Nat.unpair 
goal: Primrec Nat.unpair

full_name: Primrec.list_get?₁
code: theorem list_get?₁ : ∀ l : List α, Primrec l.get?
  
goal: Primrec l.get?

full_name: Primrec₂
code: /-- `Primrec₂ f` means `f` is a binary primitive recursive function.
  This is technically unnecessary since we can always curry all
  the arguments together, but there are enough natural two-arg
  functions that it is convenient to express this directly. -/
def Primrec₂ {α β σ} [Primcodable α] [Primcodable β] [Primcodable σ] (f : α → β → σ) 
goal: Prop

full_name: PrimrecPred
code: /-- `PrimrecPred p` means `p : α → Prop` is a (decidable)
  primitive recursive predicate, which is to say that
  `decide ∘ p : α → Bool` is primitive recursive. -/
def PrimrecPred {α} [Primcodable α] (p : α → Prop) [DecidablePred p] 
goal: Prop

full_name: PrimrecRel
code: /-- `PrimrecRel p` means `p : α → β → Prop` is a (decidable)
  primitive recursive relation, which is to say that
  `decide ∘ p : α → β → Bool` is primitive recursive. -/
def PrimrecRel {α β} [Primcodable α] [Primcodable β] (s : α → β → Prop)
    [∀ a b, Decidable (s a b)] 
goal: Prop

full_name: Primrec₂.mk
code: theorem mk {f : α → β → σ} (hf : Primrec fun p : α × β => f p.1 p.2) : Primrec₂ f 
goal: Primrec₂ f

full_name: Primrec₂.of_eq
code: theorem of_eq {f g : α → β → σ} (hg : Primrec₂ f) (H : ∀ a b, f a b = g a b) : Primrec₂ g 
goal: Primrec₂ g

full_name: Primrec₂.const
code: theorem const (x : σ) : Primrec₂ fun (_ : α) (_ : β) => x 
goal: Primrec₂ fun x_1 x_2 => x

full_name: Primrec₂.pair
code: protected theorem pair : Primrec₂ (@Prod.mk α β) 
goal: Primrec₂ Prod.mk

full_name: Primrec₂.left
code: theorem left : Primrec₂ fun (a : α) (_ : β) => a 
goal: Primrec₂ fun a x => a

full_name: Primrec₂.right
code: theorem right : Primrec₂ fun (_ : α) (b : β) => b 
goal: Primrec₂ fun x b => b

full_name: Primrec₂.natPair
code: theorem natPair : Primrec₂ Nat.pair 
goal: Primrec₂ Nat.pair

full_name: Primrec₂.unpaired
code: theorem unpaired {f : ℕ → ℕ → α} : Primrec (Nat.unpaired f) ↔ Primrec₂ f 
goal: Primrec (Nat.unpaired f) ↔ Primrec₂ f

full_name: Primrec₂.unpaired'
code: theorem unpaired' {f : ℕ → ℕ → ℕ} : Nat.Primrec (Nat.unpaired f) ↔ Primrec₂ f 
goal: Nat.Primrec (Nat.unpaired f) ↔ Primrec₂ f

full_name: Primrec₂.encode_iff
code: theorem encode_iff {f : α → β → σ} : (Primrec₂ fun a b => encode (f a b)) ↔ Primrec₂ f 
goal: (Primrec₂ fun a b => Encodable.encode (f a b)) ↔ Primrec₂ f

full_name: Primrec₂.option_some_iff
code: theorem option_some_iff {f : α → β → σ} : (Primrec₂ fun a b => some (f a b)) ↔ Primrec₂ f 
goal: (Primrec₂ fun a b => some (f a b)) ↔ Primrec₂ f

full_name: Primrec₂.ofNat_iff
code: theorem ofNat_iff {α β σ} [Denumerable α] [Denumerable β] [Primcodable σ] {f : α → β → σ} :
    Primrec₂ f ↔ Primrec₂ fun m n : ℕ => f (ofNat α m) (ofNat β n) 
goal: Primrec₂ f ↔ Primrec₂ fun m n => f (Denumerable.ofNat α m) (Denumerable.ofNat β n)

full_name: Primrec₂.uncurry
code: theorem uncurry {f : α → β → σ} : Primrec (Function.uncurry f) ↔ Primrec₂ f 
goal: Primrec (Function.uncurry f) ↔ Primrec₂ f

full_name: Primrec₂.curry
code: theorem curry {f : α × β → σ} : Primrec₂ (Function.curry f) ↔ Primrec f 
goal: Primrec₂ (Function.curry f) ↔ Primrec f

full_name: Primrec.comp₂
code: theorem Primrec.comp₂ {f : γ → σ} {g : α → β → γ} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec₂ fun a b => f (g a b) 
goal: Primrec₂ fun a b => f (g a b)

full_name: Primrec₂.comp
code: theorem Primrec₂.comp {f : β → γ → σ} {g : α → β} {h : α → γ} (hf : Primrec₂ f) (hg : Primrec g)
    (hh : Primrec h) : Primrec fun a => f (g a) (h a) 
goal: Primrec fun a => f (g a) (h a)

full_name: Primrec₂.comp₂
code: theorem Primrec₂.comp₂ {f : γ → δ → σ} {g : α → β → γ} {h : α → β → δ} (hf : Primrec₂ f)
    (hg : Primrec₂ g) (hh : Primrec₂ h) : Primrec₂ fun a b => f (g a b) (h a b) 
goal: Primrec₂ fun a b => f (g a b) (h a b)

full_name: PrimrecPred.comp
code: theorem PrimrecPred.comp {p : β → Prop} [DecidablePred p] {f : α → β} :
    PrimrecPred p → Primrec f → PrimrecPred fun a => p (f a) 
goal: PrimrecPred p → Primrec f → PrimrecPred fun a => p (f a)

full_name: PrimrecRel.comp
code: theorem PrimrecRel.comp {R : β → γ → Prop} [∀ a b, Decidable (R a b)] {f : α → β} {g : α → γ} :
    PrimrecRel R → Primrec f → Primrec g → PrimrecPred fun a => R (f a) (g a) 
goal: PrimrecRel R → Primrec f → Primrec g → PrimrecPred fun a => R (f a) (g a)

full_name: PrimrecRel.comp₂
code: theorem PrimrecRel.comp₂ {R : γ → δ → Prop} [∀ a b, Decidable (R a b)] {f : α → β → γ}
    {g : α → β → δ} :
    PrimrecRel R → Primrec₂ f → Primrec₂ g → PrimrecRel fun a b => R (f a b) (g a b) 
goal: PrimrecRel R → Primrec₂ f → Primrec₂ g → PrimrecRel fun a b => R (f a b) (g a b)

full_name: PrimrecPred.of_eq
code: theorem PrimrecPred.of_eq {α} [Primcodable α] {p q : α → Prop} [DecidablePred p] [DecidablePred q]
    (hp : PrimrecPred p) (H : ∀ a, p a ↔ q a) : PrimrecPred q 
goal: PrimrecPred q

full_name: PrimrecRel.of_eq
code: theorem PrimrecRel.of_eq {α β} [Primcodable α] [Primcodable β] {r s : α → β → Prop}
    [∀ a b, Decidable (r a b)] [∀ a b, Decidable (s a b)] (hr : PrimrecRel r)
    (H : ∀ a b, r a b ↔ s a b) : PrimrecRel s 
goal: PrimrecRel s

full_name: Primrec₂.swap
code: theorem swap {f : α → β → σ} (h : Primrec₂ f) : Primrec₂ (swap f) 
goal: Primrec₂ (Function.swap f)

full_name: Primrec₂.nat_iff
code: theorem nat_iff {f : α → β → σ} : Primrec₂ f ↔ Nat.Primrec
    (.unpaired fun m n => encode <| (@decode α _ m).bind fun a => (@decode β _ n).map (f a)) 
goal: Primrec₂ f ↔
  Nat.Primrec
    (Nat.unpaired fun m n =>
      Encodable.encode ((Encodable.decode m).bind fun a => Option.map (f a) (Encodable.decode n)))

full_name: Primrec₂.nat_iff'
code: theorem nat_iff' {f : α → β → σ} :
    Primrec₂ f ↔
      Primrec₂ fun m n : ℕ => (@decode α _ m).bind fun a => Option.map (f a) (@decode β _ n) 
goal: Primrec₂ f ↔ Primrec₂ fun m n => (Encodable.decode m).bind fun a => Option.map (f a) (Encodable.decode n)

full_name: Primrec.to₂
code: theorem to₂ {f : α × β → σ} (hf : Primrec f) : Primrec₂ fun a b => f (a, b) 
goal: Primrec₂ fun a b => f (a, b)

full_name: Primrec.nat_rec
code: theorem nat_rec {f : α → β} {g : α → ℕ × β → β} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec₂ fun a (n : ℕ) => n.rec (motive := fun _ => β) (f a) fun n IH => g a (n, IH) 
goal: Primrec₂ fun a n => Nat.rec (f a) (fun n IH => g a (n, IH)) n

full_name: Primrec.nat_rec'
code: theorem nat_rec' {f : α → ℕ} {g : α → β} {h : α → ℕ × β → β}
    (hf : Primrec f) (hg : Primrec g) (hh : Primrec₂ h) :
    Primrec fun a => (f a).rec (motive := fun _ => β) (g a) fun n IH => h a (n, IH) 
goal: Primrec fun a => Nat.rec (g a) (fun n IH => h a (n, IH)) (f a)

full_name: Primrec.nat_rec₁
code: theorem nat_rec₁ {f : ℕ → α → α} (a : α) (hf : Primrec₂ f) : Primrec (Nat.rec a f) 
goal: Primrec fun t => Nat.rec a f t

full_name: Primrec.nat_casesOn'
code: theorem nat_casesOn' {f : α → β} {g : α → ℕ → β} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec₂ fun a (n : ℕ) => (n.casesOn (f a) (g a) : β) 
goal: Primrec₂ fun a n => Nat.casesOn n (f a) (g a)

full_name: Primrec.nat_casesOn
code: theorem nat_casesOn {f : α → ℕ} {g : α → β} {h : α → ℕ → β} (hf : Primrec f) (hg : Primrec g)
    (hh : Primrec₂ h) : Primrec fun a => ((f a).casesOn (g a) (h a) : β) 
goal: Primrec fun a => Nat.casesOn (f a) (g a) (h a)

full_name: Primrec.nat_casesOn₁
code: theorem nat_casesOn₁ {f : ℕ → α} (a : α) (hf : Primrec f) :
    Primrec (fun (n : ℕ) => (n.casesOn a f : α)) 
goal: Primrec fun n => Nat.casesOn n a f

full_name: Primrec.nat_iterate
code: theorem nat_iterate {f : α → ℕ} {g : α → β} {h : α → β → β} (hf : Primrec f) (hg : Primrec g)
    (hh : Primrec₂ h) : Primrec fun a => (h a)^[f a] (g a) 
goal: Primrec fun a => (h a)^[f a] (g a)

full_name: Primrec.option_casesOn
code: theorem option_casesOn {o : α → Option β} {f : α → σ} {g : α → β → σ} (ho : Primrec o)
    (hf : Primrec f) (hg : Primrec₂ g) :
    @Primrec _ σ _ _ fun a => Option.casesOn (o a) (f a) (g a) 
goal: Primrec fun a => Option.casesOn (o a) (f a) (g a)

full_name: Primrec.option_bind
code: theorem option_bind {f : α → Option β} {g : α → β → Option σ} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec fun a => (f a).bind (g a) 
goal: Primrec fun a => (f a).bind (g a)

full_name: Primrec.option_bind₁
code: theorem option_bind₁ {f : α → Option σ} (hf : Primrec f) : Primrec fun o => Option.bind o f 
goal: Primrec fun o => o.bind f

full_name: Primrec.option_map
code: theorem option_map {f : α → Option β} {g : α → β → σ} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec fun a => (f a).map (g a) 
goal: Primrec fun a => Option.map (g a) (f a)

full_name: Primrec.option_map₁
code: theorem option_map₁ {f : α → σ} (hf : Primrec f) : Primrec (Option.map f) 
goal: Primrec (Option.map f)

full_name: Primrec.option_iget
code: theorem option_iget [Inhabited α] : Primrec (@Option.iget α _) 
goal: Primrec Option.iget

full_name: Primrec.option_isSome
code: theorem option_isSome : Primrec (@Option.isSome α) 
goal: Primrec Option.isSome

full_name: Primrec.option_getD
code: theorem option_getD : Primrec₂ (@Option.getD α) 
goal: Primrec₂ Option.getD

full_name: Primrec.bind_decode_iff
code: theorem bind_decode_iff {f : α → β → Option σ} :
    (Primrec₂ fun a n => (@decode β _ n).bind (f a)) ↔ Primrec₂ f 
goal: (Primrec₂ fun a n => (Encodable.decode n).bind (f a)) ↔ Primrec₂ f

full_name: Primrec.map_decode_iff
code: theorem map_decode_iff {f : α → β → σ} :
    (Primrec₂ fun a n => (@decode β _ n).map (f a)) ↔ Primrec₂ f 
goal: (Primrec₂ fun a n => Option.map (f a) (Encodable.decode n)) ↔ Primrec₂ f

full_name: Primrec.nat_add
code: theorem nat_add : Primrec₂ ((· + ·) : ℕ → ℕ → ℕ) 
goal: Primrec₂ fun x x_1 => x + x_1

full_name: Primrec.nat_sub
code: theorem nat_sub : Primrec₂ ((· - ·) : ℕ → ℕ → ℕ) 
goal: Primrec₂ fun x x_1 => x - x_1

full_name: Primrec.nat_mul
code: theorem nat_mul : Primrec₂ ((· * ·) : ℕ → ℕ → ℕ) 
goal: Primrec₂ fun x x_1 => x * x_1

full_name: Primrec.cond
code: theorem cond {c : α → Bool} {f : α → σ} {g : α → σ} (hc : Primrec c) (hf : Primrec f)
    (hg : Primrec g) : Primrec fun a => bif (c a) then (f a) else (g a) 
goal: Primrec fun a => bif c a then f a else g a

full_name: Primrec.ite
code: theorem ite {c : α → Prop} [DecidablePred c] {f : α → σ} {g : α → σ} (hc : PrimrecPred c)
    (hf : Primrec f) (hg : Primrec g) : Primrec fun a => if c a then f a else g a 
goal: Primrec fun a => if c a then f a else g a

full_name: Primrec.nat_le
code: theorem nat_le : PrimrecRel ((· ≤ ·) : ℕ → ℕ → Prop) 
goal: PrimrecRel fun x x_1 => x ≤ x_1

full_name: Primrec.nat_min
code: theorem nat_min : Primrec₂ (@min ℕ _) 
goal: Primrec₂ min

full_name: Primrec.nat_max
code: theorem nat_max : Primrec₂ (@max ℕ _) 
goal: Primrec₂ max

full_name: Primrec.dom_bool
code: theorem dom_bool (f : Bool → α) : Primrec f 
goal: Primrec f

full_name: Primrec.dom_bool₂
code: theorem dom_bool₂ (f : Bool → Bool → α) : Primrec₂ f 
goal: Primrec₂ f

full_name: Primrec.not
code: protected theorem not : Primrec not 
goal: Primrec not

full_name: Primrec.and
code: protected theorem and : Primrec₂ and 
goal: Primrec₂ and

full_name: Primrec.or
code: protected theorem or : Primrec₂ or 
goal: Primrec₂ or

full_name: PrimrecPred.not
code: theorem _root_.PrimrecPred.not {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) :
    PrimrecPred fun a => ¬p a 
goal: PrimrecPred fun a => ¬p a

full_name: PrimrecPred.and
code: theorem _root_.PrimrecPred.and {p q : α → Prop} [DecidablePred p] [DecidablePred q]
    (hp : PrimrecPred p) (hq : PrimrecPred q) : PrimrecPred fun a => p a ∧ q a 
goal: PrimrecPred fun a => p a ∧ q a

full_name: PrimrecPred.or
code: theorem _root_.PrimrecPred.or {p q : α → Prop} [DecidablePred p] [DecidablePred q]
    (hp : PrimrecPred p) (hq : PrimrecPred q) : PrimrecPred fun a => p a ∨ q a 
goal: PrimrecPred fun a => p a ∨ q a

full_name: Primrec.beq
code: protected theorem beq [DecidableEq α] : Primrec₂ (@BEq.beq α _) 
goal: Primrec₂ BEq.beq

full_name: Primrec.eq
code: protected theorem eq [DecidableEq α] : PrimrecRel (@Eq α) 
goal: PrimrecRel Eq

full_name: Primrec.nat_lt
code: theorem nat_lt : PrimrecRel ((· < ·) : ℕ → ℕ → Prop) 
goal: PrimrecRel fun x x_1 => x < x_1

full_name: Primrec.option_guard
code: theorem option_guard {p : α → β → Prop} [∀ a b, Decidable (p a b)] (hp : PrimrecRel p) {f : α → β}
    (hf : Primrec f) : Primrec fun a => Option.guard (p a) (f a) 
goal: Primrec fun a => Option.guard (p a) (f a)

full_name: Primrec.option_orElse
code: theorem option_orElse : Primrec₂ ((· <|> ·) : Option α → Option α → Option α) 
goal: Primrec₂ fun x x_1 => HOrElse.hOrElse x fun x => x_1

full_name: Primrec.decode₂
code: protected theorem decode₂ : Primrec (decode₂ α) 
goal: Primrec (Encodable.decode₂ α)

full_name: Primrec.list_findIdx₁
code: theorem list_findIdx₁ {p : α → β → Bool} (hp : Primrec₂ p) :
    ∀ l : List β, Primrec fun a => l.findIdx (p a)

goal: Primrec fun a => List.findIdx (p a) l

full_name: Primrec.list_indexOf₁
code: theorem list_indexOf₁ [DecidableEq α] (l : List α) : Primrec fun a => l.indexOf a 
goal: Primrec fun a => List.indexOf a l

full_name: Primrec.dom_fintype
code: theorem dom_fintype [Finite α] (f : α → σ) : Primrec f 
goal: Primrec f

full_name: Primrec.PrimrecBounded
code: /-- A function is `PrimrecBounded` if its size is bounded by a primitive recursive function -/
def PrimrecBounded (f : α → β) : Prop 
goal: Prop

full_name: Primrec.nat_findGreatest
code: theorem nat_findGreatest {f : α → ℕ} {p : α → ℕ → Prop} [∀ x n, Decidable (p x n)]
    (hf : Primrec f) (hp : PrimrecRel p) : Primrec fun x => (f x).findGreatest (p x) 
goal: Primrec fun x => Nat.findGreatest (p x) (f x)

full_name: Primrec.of_graph
code: /-- To show a function `f : α → ℕ` is primitive recursive, it is enough to show that the function
  is bounded by a primitive recursive function and that its graph is primitive recursive -/
theorem of_graph {f : α → ℕ} (h₁ : PrimrecBounded f)
    (h₂ : PrimrecRel fun a b => f a = b) : Primrec f 
goal: Primrec f

full_name: Primrec.nat_div
code: theorem nat_div : Primrec₂ ((· / ·) : ℕ → ℕ → ℕ) 
goal: Primrec₂ fun x x_1 => x / x_1

full_name: Primrec.nat_mod
code: theorem nat_mod : Primrec₂ ((· % ·) : ℕ → ℕ → ℕ) 
goal: Primrec₂ fun x x_1 => x % x_1

full_name: Primrec.nat_bodd
code: theorem nat_bodd : Primrec Nat.bodd 
goal: Primrec Nat.bodd

full_name: Primrec.nat_div2
code: theorem nat_div2 : Primrec Nat.div2 
goal: Primrec Nat.div2

full_name: Primrec.nat_double
code: theorem nat_double : Primrec (fun n : ℕ => 2 * n) 
goal: Primrec fun n => 2 * n

full_name: Primrec.nat_double_succ
code: theorem nat_double_succ : Primrec (fun n : ℕ => 2 * n + 1) 
goal: Primrec fun n => 2 * n + 1

full_name: _private.Mathlib.Computability.Primrec.0.prim
code: private def prim : Primcodable (List β) 
goal: Primcodable (List β)

full_name: _private.Mathlib.Computability.Primrec.0.list_casesOn'
code: private theorem list_casesOn' {f : α → List β} {g : α → σ} {h : α → β × List β → σ}
    (hf : haveI := prim H; Primrec f) (hg : Primrec g) (hh : haveI := prim H; Primrec₂ h) :
    @Primrec _ σ _ _ fun a => List.casesOn (f a) (g a) fun b l => h a (b, l) 
goal: Primrec fun a => List.casesOn (f a) (g a) fun b l => h a (b, l)

full_name: _private.Mathlib.Computability.Primrec.0.list_foldl'
code: private theorem list_foldl' {f : α → List β} {g : α → σ} {h : α → σ × β → σ}
    (hf : haveI := prim H; Primrec f) (hg : Primrec g) (hh : haveI := prim H; Primrec₂ h) :
    Primrec fun a => (f a).foldl (fun s b => h a (s, b)) (g a) 
goal: Primrec fun a => List.foldl (fun s b => h a (s, b)) (g a) (f a)

full_name: _private.Mathlib.Computability.Primrec.0.list_cons'
code: private theorem list_cons' : (haveI := prim H; Primrec₂ (@List.cons β)) 
goal: Primrec₂ List.cons

full_name: _private.Mathlib.Computability.Primrec.0.list_reverse'
code: private theorem list_reverse' :
    haveI := prim H
    Primrec (@List.reverse β) 
goal: Primrec List.reverse

full_name: Primcodable.sum
code: instance sum : Primcodable (α ⊕ β) 
goal: Primcodable (α ⊕ β)

full_name: Primcodable.list
code: instance list : Primcodable (List α) 
goal: Primcodable (List α)

full_name: Primrec.sum_inl
code: theorem sum_inl : Primrec (@Sum.inl α β) 
goal: Primrec Sum.inl

full_name: Primrec.sum_inr
code: theorem sum_inr : Primrec (@Sum.inr α β) 
goal: Primrec Sum.inr

full_name: Primrec.sum_casesOn
code: theorem sum_casesOn {f : α → β ⊕ γ} {g : α → β → σ} {h : α → γ → σ} (hf : Primrec f)
    (hg : Primrec₂ g) (hh : Primrec₂ h) : @Primrec _ σ _ _ fun a => Sum.casesOn (f a) (g a) (h a) 
goal: Primrec fun a => Sum.casesOn (f a) (g a) (h a)

full_name: Primrec.list_cons
code: theorem list_cons : Primrec₂ (@List.cons α) 
goal: Primrec₂ List.cons

full_name: Primrec.list_casesOn
code: theorem list_casesOn {f : α → List β} {g : α → σ} {h : α → β × List β → σ} :
    Primrec f →
      Primrec g →
        Primrec₂ h → @Primrec _ σ _ _ fun a => List.casesOn (f a) (g a) fun b l => h a (b, l) 
goal: Primrec f → Primrec g → Primrec₂ h → Primrec fun a => List.casesOn (f a) (g a) fun b l => h a (b, l)

full_name: Primrec.list_foldl
code: theorem list_foldl {f : α → List β} {g : α → σ} {h : α → σ × β → σ} :
    Primrec f →
      Primrec g → Primrec₂ h → Primrec fun a => (f a).foldl (fun s b => h a (s, b)) (g a) 
goal: Primrec f → Primrec g → Primrec₂ h → Primrec fun a => List.foldl (fun s b => h a (s, b)) (g a) (f a)

full_name: Primrec.list_reverse
code: theorem list_reverse : Primrec (@List.reverse α) 
goal: Primrec List.reverse

full_name: Primrec.list_foldr
code: theorem list_foldr {f : α → List β} {g : α → σ} {h : α → β × σ → σ} (hf : Primrec f)
    (hg : Primrec g) (hh : Primrec₂ h) :
    Primrec fun a => (f a).foldr (fun b s => h a (b, s)) (g a) 
goal: Primrec fun a => List.foldr (fun b s => h a (b, s)) (g a) (f a)

full_name: Primrec.list_head?
code: theorem list_head? : Primrec (@List.head? α) 
goal: Primrec List.head?

full_name: Primrec.list_headI
code: theorem list_headI [Inhabited α] : Primrec (@List.headI α _) 
goal: Primrec List.headI

full_name: Primrec.list_tail
code: theorem list_tail : Primrec (@List.tail α) 
goal: Primrec List.tail

full_name: Primrec.list_rec
code: theorem list_rec {f : α → List β} {g : α → σ} {h : α → β × List β × σ → σ} (hf : Primrec f)
    (hg : Primrec g) (hh : Primrec₂ h) :
    @Primrec _ σ _ _ fun a => List.recOn (f a) (g a) fun b l IH => h a (b, l, IH) 
goal: Primrec fun a => List.recOn (f a) (g a) fun b l IH => h a (b, l, IH)

full_name: Primrec.list_get?
code: theorem list_get? : Primrec₂ (@List.get? α) 
goal: Primrec₂ List.get?

full_name: Primrec.list_getD
code: theorem list_getD (d : α) : Primrec₂ fun l n => List.getD l n d 
goal: Primrec₂ fun l n => l.getD n d

full_name: Primrec.list_getI
code: theorem list_getI [Inhabited α] : Primrec₂ (@List.getI α _) 
goal: Primrec₂ List.getI

full_name: Primrec.list_append
code: theorem list_append : Primrec₂ ((· ++ ·) : List α → List α → List α) 
goal: Primrec₂ fun x x_1 => x ++ x_1

full_name: Primrec.list_concat
code: theorem list_concat : Primrec₂ fun l (a : α) => l ++ [a] 
goal: Primrec₂ fun l a => l ++ [a]

full_name: Primrec.list_map
code: theorem list_map {f : α → List β} {g : α → β → σ} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec fun a => (f a).map (g a) 
goal: Primrec fun a => List.map (g a) (f a)

full_name: Primrec.list_range
code: theorem list_range : Primrec List.range 
goal: Primrec List.range

full_name: Primrec.list_join
code: theorem list_join : Primrec (@List.join α) 
goal: Primrec List.join

full_name: Primrec.list_bind
code: theorem list_bind {f : α → List β} {g : α → β → List σ} (hf : Primrec f) (hg : Primrec₂ g) :
    Primrec (fun a => (f a).bind (g a)) 
goal: Primrec fun a => (f a).bind (g a)

full_name: Primrec.optionToList
code: theorem optionToList : Primrec (Option.toList : Option α → List α) 
goal: Primrec Option.toList

full_name: Primrec.listFilterMap
code: theorem listFilterMap {f : α → List β} {g : α → β → Option σ}
    (hf : Primrec f) (hg : Primrec₂ g) : Primrec fun a => (f a).filterMap (g a) 
goal: Primrec fun a => List.filterMap (g a) (f a)

full_name: Primrec.list_length
code: theorem list_length : Primrec (@List.length α) 
goal: Primrec List.length

full_name: Primrec.list_findIdx
code: theorem list_findIdx {f : α → List β} {p : α → β → Bool}
    (hf : Primrec f) (hp : Primrec₂ p) : Primrec fun a => (f a).findIdx (p a) 
goal: Primrec fun a => List.findIdx (p a) (f a)

full_name: Primrec.list_indexOf
code: theorem list_indexOf [DecidableEq α] : Primrec₂ (@List.indexOf α _) 
goal: Primrec₂ List.indexOf

full_name: Primrec.nat_strong_rec
code: theorem nat_strong_rec (f : α → ℕ → σ) {g : α → List σ → Option σ} (hg : Primrec₂ g)
    (H : ∀ a n, g a ((List.range n).map (f a)) = some (f a n)) : Primrec₂ f 
goal: Primrec₂ f

full_name: Primrec.listLookup
code: theorem listLookup [DecidableEq α] : Primrec₂ (List.lookup : α → List (α × β) → Option β) 
goal: Primrec₂ List.lookup

full_name: Primrec.nat_omega_rec'
code: theorem nat_omega_rec' (f : β → σ) {m : β → ℕ} {l : β → List β} {g : β → List σ → Option σ}
    (hm : Primrec m) (hl : Primrec l) (hg : Primrec₂ g)
    (Ord : ∀ b, ∀ b' ∈ l b, m b' < m b)
    (H : ∀ b, g b ((l b).map f) = some (f b)) : Primrec f 
goal: Primrec f

full_name: Primrec.nat_omega_rec
code: theorem nat_omega_rec (f : α → β → σ) {m : α → β → ℕ}
    {l : α → β → List β} {g : α → β × List σ → Option σ}
    (hm : Primrec₂ m) (hl : Primrec₂ l) (hg : Primrec₂ g)
    (Ord : ∀ a b, ∀ b' ∈ l a b, m a b' < m a b)
    (H : ∀ a b, g a (b, (l a b).map (f a)) = some (f a b)) : Primrec₂ f 
goal: Primrec₂ f

full_name: Primcodable.subtype
code: /-- A subtype of a primitive recursive predicate is `Primcodable`. -/
def subtype {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) : Primcodable (Subtype p) 
goal: Primcodable (Subtype p)

full_name: Primcodable.fin
code: instance fin {n} : Primcodable (Fin n) 
goal: Primcodable (Fin n)

full_name: Primcodable.vector
code: instance vector {n} : Primcodable (Vector α n) 
goal: Primcodable (Mathlib.Vector α n)

full_name: Primcodable.finArrow
code: instance finArrow {n} : Primcodable (Fin n → α) 
goal: Primcodable (Fin n → α)

full_name: Primcodable.mem_range_encode
code: theorem mem_range_encode : PrimrecPred (fun n => n ∈ Set.range (encode : α → ℕ)) 
goal: PrimrecPred fun n => n ∈ Set.range Encodable.encode

full_name: Primcodable.ulower
code: instance ulower : Primcodable (ULower α) 
goal: Primcodable (ULower α)

full_name: Primrec.subtype_val
code: theorem subtype_val {p : α → Prop} [DecidablePred p] {hp : PrimrecPred p} :
    haveI := Primcodable.subtype hp
    Primrec (@Subtype.val α p) 
goal: Primrec Subtype.val

full_name: Primrec.subtype_val_iff
code: theorem subtype_val_iff {p : β → Prop} [DecidablePred p] {hp : PrimrecPred p} {f : α → Subtype p} :
    haveI := Primcodable.subtype hp
    (Primrec fun a => (f a).1) ↔ Primrec f 
goal: (Primrec fun a => ↑(f a)) ↔ Primrec f

full_name: Primrec.subtype_mk
code: theorem subtype_mk {p : β → Prop} [DecidablePred p] {hp : PrimrecPred p} {f : α → β}
    {h : ∀ a, p (f a)} (hf : Primrec f) :
    haveI := Primcodable.subtype hp
    Primrec fun a => @Subtype.mk β p (f a) (h a) 
goal: Primrec fun a => ⟨f a, ⋯⟩

full_name: Primrec.option_get
code: theorem option_get {f : α → Option β} {h : ∀ a, (f a).isSome} :
    Primrec f → Primrec fun a => (f a).get (h a) 
goal: Primrec f → Primrec fun a => (f a).get ⋯

full_name: Primrec.ulower_down
code: theorem ulower_down : Primrec (ULower.down : α → ULower α) 
goal: Primrec ULower.down

full_name: Primrec.ulower_up
code: theorem ulower_up : Primrec (ULower.up : ULower α → α) 
goal: Primrec ULower.up

full_name: Primrec.fin_val_iff
code: theorem fin_val_iff {n} {f : α → Fin n} : (Primrec fun a => (f a).1) ↔ Primrec f 
goal: (Primrec fun a => ↑(f a)) ↔ Primrec f

full_name: Primrec.fin_val
code: theorem fin_val {n} : Primrec (fun (i : Fin n) => (i : ℕ)) 
goal: Primrec fun i => ↑i

full_name: Primrec.fin_succ
code: theorem fin_succ {n} : Primrec (@Fin.succ n) 
goal: Primrec Fin.succ

full_name: Primrec.vector_toList
code: theorem vector_toList {n} : Primrec (@Vector.toList α n) 
goal: Primrec Mathlib.Vector.toList

full_name: Primrec.vector_toList_iff
code: theorem vector_toList_iff {n} {f : α → Vector β n} : (Primrec fun a => (f a).toList) ↔ Primrec f 
goal: (Primrec fun a => (f a).toList) ↔ Primrec f

full_name: Primrec.vector_cons
code: theorem vector_cons {n} : Primrec₂ (@Vector.cons α n) 
goal: Primrec₂ Mathlib.Vector.cons

full_name: Primrec.vector_length
code: theorem vector_length {n} : Primrec (@Vector.length α n) 
goal: Primrec Mathlib.Vector.length

full_name: Primrec.vector_head
code: theorem vector_head {n} : Primrec (@Vector.head α n) 
goal: Primrec Mathlib.Vector.head

full_name: Primrec.vector_tail
code: theorem vector_tail {n} : Primrec (@Vector.tail α n) 
goal: Primrec Mathlib.Vector.tail

full_name: Primrec.vector_get
code: theorem vector_get {n} : Primrec₂ (@Vector.get α n) 
goal: Primrec₂ Mathlib.Vector.get

full_name: Primrec.list_ofFn
code: theorem list_ofFn :
    ∀ {n} {f : Fin n → α → σ}, (∀ i, Primrec (f i)) → Primrec fun a => List.ofFn fun i => f i a
  
goal: (∀ (i : Fin n), Primrec (f i)) → Primrec fun a => List.ofFn fun i => f i a

full_name: Primrec.vector_ofFn
code: theorem vector_ofFn {n} {f : Fin n → α → σ} (hf : ∀ i, Primrec (f i)) :
    Primrec fun a => Vector.ofFn fun i => f i a 
goal: Primrec fun a => Mathlib.Vector.ofFn fun i => f i a

full_name: Primrec.vector_get'
code: theorem vector_get' {n} : Primrec (@Vector.get α n) 
goal: Primrec Mathlib.Vector.get

full_name: Primrec.vector_ofFn'
code: theorem vector_ofFn' {n} : Primrec (@Vector.ofFn α n) 
goal: Primrec Mathlib.Vector.ofFn

full_name: Primrec.fin_app
code: theorem fin_app {n} : Primrec₂ (@id (Fin n → σ)) 
goal: Primrec₂ id

full_name: Primrec.fin_curry₁
code: theorem fin_curry₁ {n} {f : Fin n → α → σ} : Primrec₂ f ↔ ∀ i, Primrec (f i) 
goal: Primrec₂ f ↔ ∀ (i : Fin n), Primrec (f i)

full_name: Primrec.fin_curry
code: theorem fin_curry {n} {f : α → Fin n → σ} : Primrec f ↔ Primrec₂ f 
goal: Primrec f ↔ Primrec₂ f

full_name: Nat.Primrec'.succ
code: /-- An alternative inductive definition of `Primrec` which
  does not use the pairing function on ℕ, and so has to
  work with n-ary functions on ℕ instead of unary functions.
  We prove that this is equivalent to the regular notion
  in `to_prim` and `of_prim`. -/
inductive Primrec' : ∀ {n}, (Vector ℕ n → ℕ) → Prop
  | zero : @Primrec' 0 fun _ => 0
  | succ : @Primrec' 1 fun v => succ v.head
  | get {n} (i : Fin n) : Primrec' fun v => v.get i
  | comp {m n f} (g : Fin n → Vector ℕ m → ℕ) :
      Primrec' f → (∀ i, Primrec' (g i)) → Primrec' fun a => f (ofFn fun i => g i a)
  | prec {n f g} :
      @Primrec' n f →
        @Primrec' (n + 2) g →
          Primrec' fun v : Vector ℕ (n + 1) =>
            v.head.rec (f v.tail) fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)
goal: Nat.Primrec' fun v => v.head.succ

full_name: Nat.Primrec'
code: /-- An alternative inductive definition of `Primrec` which
  does not use the pairing function on ℕ, and so has to
  work with n-ary functions on ℕ instead of unary functions.
  We prove that this is equivalent to the regular notion
  in `to_prim` and `of_prim`. -/
inductive Primrec' : ∀ {n}, (Vector ℕ n → ℕ) → Prop
  | zero : @Primrec' 0 fun _ => 0
  | succ : @Primrec' 1 fun v => succ v.head
  | get {n} (i : Fin n) : Primrec' fun v => v.get i
  | comp {m n f} (g : Fin n → Vector ℕ m → ℕ) :
      Primrec' f → (∀ i, Primrec' (g i)) → Primrec' fun a => f (ofFn fun i => g i a)
  | prec {n f g} :
      @Primrec' n f →
        @Primrec' (n + 2) g →
          Primrec' fun v : Vector ℕ (n + 1) =>
            v.head.rec (f v.tail) fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)
goal: (Mathlib.Vector ℕ n → ℕ) → Prop

full_name: Nat.Primrec'.prec
code: /-- An alternative inductive definition of `Primrec` which
  does not use the pairing function on ℕ, and so has to
  work with n-ary functions on ℕ instead of unary functions.
  We prove that this is equivalent to the regular notion
  in `to_prim` and `of_prim`. -/
inductive Primrec' : ∀ {n}, (Vector ℕ n → ℕ) → Prop
  | zero : @Primrec' 0 fun _ => 0
  | succ : @Primrec' 1 fun v => succ v.head
  | get {n} (i : Fin n) : Primrec' fun v => v.get i
  | comp {m n f} (g : Fin n → Vector ℕ m → ℕ) :
      Primrec' f → (∀ i, Primrec' (g i)) → Primrec' fun a => f (ofFn fun i => g i a)
  | prec {n f g} :
      @Primrec' n f →
        @Primrec' (n + 2) g →
          Primrec' fun v : Vector ℕ (n + 1) =>
            v.head.rec (f v.tail) fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)
goal: Nat.Primrec' f → Nat.Primrec' g → Nat.Primrec' fun v => Nat.rec (f v.tail) (fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)) v.head

full_name: Nat.Primrec'.get
code: /-- An alternative inductive definition of `Primrec` which
  does not use the pairing function on ℕ, and so has to
  work with n-ary functions on ℕ instead of unary functions.
  We prove that this is equivalent to the regular notion
  in `to_prim` and `of_prim`. -/
inductive Primrec' : ∀ {n}, (Vector ℕ n → ℕ) → Prop
  | zero : @Primrec' 0 fun _ => 0
  | succ : @Primrec' 1 fun v => succ v.head
  | get {n} (i : Fin n) : Primrec' fun v => v.get i
  | comp {m n f} (g : Fin n → Vector ℕ m → ℕ) :
      Primrec' f → (∀ i, Primrec' (g i)) → Primrec' fun a => f (ofFn fun i => g i a)
  | prec {n f g} :
      @Primrec' n f →
        @Primrec' (n + 2) g →
          Primrec' fun v : Vector ℕ (n + 1) =>
            v.head.rec (f v.tail) fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)
goal: Nat.Primrec' fun v => v.get i

full_name: Nat.Primrec'.zero
code: /-- An alternative inductive definition of `Primrec` which
  does not use the pairing function on ℕ, and so has to
  work with n-ary functions on ℕ instead of unary functions.
  We prove that this is equivalent to the regular notion
  in `to_prim` and `of_prim`. -/
inductive Primrec' : ∀ {n}, (Vector ℕ n → ℕ) → Prop
  | zero : @Primrec' 0 fun _ => 0
  | succ : @Primrec' 1 fun v => succ v.head
  | get {n} (i : Fin n) : Primrec' fun v => v.get i
  | comp {m n f} (g : Fin n → Vector ℕ m → ℕ) :
      Primrec' f → (∀ i, Primrec' (g i)) → Primrec' fun a => f (ofFn fun i => g i a)
  | prec {n f g} :
      @Primrec' n f →
        @Primrec' (n + 2) g →
          Primrec' fun v : Vector ℕ (n + 1) =>
            v.head.rec (f v.tail) fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)
goal: Nat.Primrec' fun x => 0

full_name: Nat.Primrec'.comp
code: /-- An alternative inductive definition of `Primrec` which
  does not use the pairing function on ℕ, and so has to
  work with n-ary functions on ℕ instead of unary functions.
  We prove that this is equivalent to the regular notion
  in `to_prim` and `of_prim`. -/
inductive Primrec' : ∀ {n}, (Vector ℕ n → ℕ) → Prop
  | zero : @Primrec' 0 fun _ => 0
  | succ : @Primrec' 1 fun v => succ v.head
  | get {n} (i : Fin n) : Primrec' fun v => v.get i
  | comp {m n f} (g : Fin n → Vector ℕ m → ℕ) :
      Primrec' f → (∀ i, Primrec' (g i)) → Primrec' fun a => f (ofFn fun i => g i a)
  | prec {n f g} :
      @Primrec' n f →
        @Primrec' (n + 2) g →
          Primrec' fun v : Vector ℕ (n + 1) =>
            v.head.rec (f v.tail) fun y IH => g (y ::ᵥ IH ::ᵥ v.tail)
goal: Nat.Primrec' f → (∀ (i : Fin n), Nat.Primrec' (g i)) → Nat.Primrec' fun a => f (Mathlib.Vector.ofFn fun i => g i a)

full_name: Nat.Primrec'.to_prim
code: theorem to_prim {n f} (pf : @Nat.Primrec' n f) : Primrec f 
goal: Primrec f

full_name: Nat.Primrec'.of_eq
code: theorem of_eq {n} {f g : Vector ℕ n → ℕ} (hf : Primrec' f) (H : ∀ i, f i = g i) : Primrec' g 
goal: Nat.Primrec' g

full_name: Nat.Primrec'.const
code: theorem const {n} : ∀ m, @Primrec' n fun _ => m
  
goal: Nat.Primrec' fun x => m

full_name: Nat.Primrec'.head
code: theorem head {n : ℕ} : @Primrec' n.succ head 
goal: Nat.Primrec' Mathlib.Vector.head

full_name: Nat.Primrec'.tail
code: theorem tail {n f} (hf : @Primrec' n f) : @Primrec' n.succ fun v => f v.tail 
goal: Nat.Primrec' fun v => f v.tail

full_name: Nat.Primrec'.Vec
code: /-- A function from vectors to vectors is primitive recursive when all of its projections are. -/
def Vec {n m} (f : Vector ℕ n → Vector ℕ m) : Prop 
goal: Prop

full_name: Nat.Primrec'.nil
code: protected theorem nil {n} : @Vec n 0 fun _ => nil 
goal: Nat.Primrec'.Vec fun x => Mathlib.Vector.nil

full_name: Nat.Primrec'.cons
code: protected theorem cons {n m f g} (hf : @Primrec' n f) (hg : @Vec n m g) :
    Vec fun v => f v ::ᵥ g v 
goal: Nat.Primrec'.Vec fun v => f v ::ᵥ g v

full_name: Nat.Primrec'.idv
code: theorem idv {n} : @Vec n n id 
goal: Nat.Primrec'.Vec id

full_name: Nat.Primrec'.comp'
code: theorem comp' {n m f g} (hf : @Primrec' m f) (hg : @Vec n m g) : Primrec' fun v => f (g v) 
goal: Nat.Primrec' fun v => f (g v)

full_name: Nat.Primrec'.comp₁
code: theorem comp₁ (f : ℕ → ℕ) (hf : @Primrec' 1 fun v => f v.head) {n g} (hg : @Primrec' n g) :
    Primrec' fun v => f (g v) 
goal: Nat.Primrec' fun v => f (g v)

full_name: Nat.Primrec'.comp₂
code: theorem comp₂ (f : ℕ → ℕ → ℕ) (hf : @Primrec' 2 fun v => f v.head v.tail.head) {n g h}
    (hg : @Primrec' n g) (hh : @Primrec' n h) : Primrec' fun v => f (g v) (h v) 
goal: Nat.Primrec' fun v => f (g v) (h v)

full_name: Nat.Primrec'.prec'
code: theorem prec' {n f g h} (hf : @Primrec' n f) (hg : @Primrec' n g) (hh : @Primrec' (n + 2) h) :
    @Primrec' n fun v => (f v).rec (g v) fun y IH : ℕ => h (y ::ᵥ IH ::ᵥ v) 
goal: Nat.Primrec' fun v => Nat.rec (g v) (fun y IH => h (y ::ᵥ IH ::ᵥ v)) (f v)

full_name: Nat.Primrec'.pred
code: theorem pred : @Primrec' 1 fun v => v.head.pred 
goal: Nat.Primrec' fun v => v.head.pred

full_name: Nat.Primrec'.add
code: theorem add : @Primrec' 2 fun v => v.head + v.tail.head 
goal: Nat.Primrec' fun v => v.head + v.tail.head

full_name: Nat.Primrec'.sub
code: theorem sub : @Primrec' 2 fun v => v.head - v.tail.head 
goal: Nat.Primrec' fun v => v.head - v.tail.head

full_name: Nat.Primrec'.mul
code: theorem mul : @Primrec' 2 fun v => v.head * v.tail.head 
goal: Nat.Primrec' fun v => v.head * v.tail.head

full_name: Nat.Primrec'.if_lt
code: theorem if_lt {n a b f g} (ha : @Primrec' n a) (hb : @Primrec' n b) (hf : @Primrec' n f)
    (hg : @Primrec' n g) : @Primrec' n fun v => if a v < b v then f v else g v 
goal: Nat.Primrec' fun v => if a v < b v then f v else g v

full_name: Nat.Primrec'.natPair
code: theorem natPair : @Primrec' 2 fun v => v.head.pair v.tail.head 
goal: Nat.Primrec' fun v => Nat.pair v.head v.tail.head

full_name: Nat.Primrec'.encode
code: protected theorem encode : ∀ {n}, @Primrec' n encode
  
goal: Nat.Primrec' Encodable.encode

full_name: Nat.Primrec'.sqrt
code: theorem sqrt : @Primrec' 1 fun v => v.head.sqrt 
goal: Nat.Primrec' fun v => v.head.sqrt

full_name: Nat.Primrec'.unpair₁
code: theorem unpair₁ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.1 
goal: Nat.Primrec' fun v => (Nat.unpair (f v)).1

full_name: Nat.Primrec'.unpair₂
code: theorem unpair₂ {n f} (hf : @Primrec' n f) : @Primrec' n fun v => (f v).unpair.2 
goal: Nat.Primrec' fun v => (Nat.unpair (f v)).2

full_name: Nat.Primrec'.of_prim
code: theorem of_prim {n f} : Primrec f → @Primrec' n f 
goal: Primrec f → Nat.Primrec' f

full_name: Nat.Primrec'.prim_iff
code: theorem prim_iff {n f} : @Primrec' n f ↔ Primrec f 
goal: Nat.Primrec' f ↔ Primrec f

full_name: Nat.Primrec'.prim_iff₁
code: theorem prim_iff₁ {f : ℕ → ℕ} : (@Primrec' 1 fun v => f v.head) ↔ Primrec f 
goal: (Nat.Primrec' fun v => f v.head) ↔ Primrec f

full_name: Nat.Primrec'.prim_iff₂
code: theorem prim_iff₂ {f : ℕ → ℕ → ℕ} : (@Primrec' 2 fun v => f v.head v.tail.head) ↔ Primrec₂ f 
goal: (Nat.Primrec' fun v => f v.head v.tail.head) ↔ Primrec₂ f

full_name: Nat.Primrec'.vec_iff
code: theorem vec_iff {m n f} : @Vec m n f ↔ Primrec f 
goal: Nat.Primrec'.Vec f ↔ Primrec f

full_name: Primrec.nat_sqrt
code: theorem Primrec.nat_sqrt : Primrec Nat.sqrt 
goal: Primrec Nat.sqrt