Documentation

Mathlib.Computability.Primrec

The primitive recursive functions #

The primitive recursive functions are the least collection of functions ℕ → ℕ which are closed under projections (using the pair pairing function), composition, zero, successor, and primitive recursion (i.e. Nat.rec where the motive is C n := ℕ).

We can extend this definition to a large class of basic types by using canonical encodings of types as natural numbers (Gödel numbering), which we implement through the type class Encodable. (More precisely, we need that the composition of encode with decode yields a primitive recursive function, so we have the Primcodable type class for this.)

References #

@[reducible]
def Nat.unpaired {α : Sort u_1} (f : ℕ → ℕ → α) (n : ℕ) :
α

Calls the given function on a pair of entries n, encoded via the pairing function.

Equations
Instances For
    inductive Nat.Primrec :
    (ℕ → ℕ) → Prop

    The primitive recursive functions ℕ → ℕ.

    Instances For
      theorem Nat.Primrec.of_eq {f : ℕ → ℕ} {g : ℕ → ℕ} (hf : Nat.Primrec f) (H : ∀ (n : ℕ), f n = g n) :
      theorem Nat.Primrec.const (n : ℕ) :
      Nat.Primrec fun (x : ℕ) => n
      theorem Nat.Primrec.prec1 {f : ℕ → ℕ} (m : ℕ) (hf : Nat.Primrec f) :
      Nat.Primrec fun (n : ℕ) => Nat.rec m (fun (y IH : ℕ) => f (Nat.pair y IH)) n
      theorem Nat.Primrec.casesOn1 {f : ℕ → ℕ} (m : ℕ) (hf : Nat.Primrec f) :
      Nat.Primrec fun (x : ℕ) => Nat.casesOn x m f
      theorem Nat.Primrec.casesOn' {f : ℕ → ℕ} {g : ℕ → ℕ} (hf : Nat.Primrec f) (hg : Nat.Primrec g) :
      Nat.Primrec (Nat.unpaired fun (z n : ℕ) => Nat.casesOn n (f z) fun (y : ℕ) => g (Nat.pair z y))
      theorem Nat.Primrec.add :
      Nat.Primrec (Nat.unpaired fun (x x_1 : ℕ) => x + x_1)
      theorem Nat.Primrec.sub :
      Nat.Primrec (Nat.unpaired fun (x x_1 : ℕ) => x - x_1)
      theorem Nat.Primrec.mul :
      Nat.Primrec (Nat.unpaired fun (x x_1 : ℕ) => x * x_1)
      theorem Nat.Primrec.pow :
      Nat.Primrec (Nat.unpaired fun (x x_1 : ℕ) => x ^ x_1)
      class Primcodable (α : Type u_1) extends Encodable :
      Type u_1

      A Primcodable type is an Encodable type for which the encode/decode functions are primitive recursive.

      Instances
        def Primcodable.ofEquiv (α : Type u_1) {β : Type u_2} [Primcodable α] (e : β ≃ α) :

        Builds a Primcodable instance from an equivalence to a Primcodable type.

        Equations
        Instances For
          instance Primcodable.option {α : Type u_1} [h : Primcodable α] :
          Equations
          def Primrec {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] (f : α → β) :

          Primrec f means f is primitive recursive (after encoding its input and output as natural numbers).

          Equations
          Instances For
            theorem Primrec.encode {α : Type u_1} [Primcodable α] :
            Primrec Encodable.encode
            theorem Primrec.decode {α : Type u_1} [Primcodable α] :
            Primrec Encodable.decode
            theorem Primrec.dom_denumerable {α : Type u_4} {β : Type u_5} [Denumerable α] [Primcodable β] {f : α → β} :
            theorem Primrec.option_some {α : Type u_1} [Primcodable α] :
            Primrec some
            theorem Primrec.of_eq {α : Type u_1} {σ : Type u_3} [Primcodable α] [Primcodable σ] {f : α → σ} {g : α → σ} (hf : Primrec f) (H : ∀ (n : α), f n = g n) :
            theorem Primrec.const {α : Type u_1} {σ : Type u_3} [Primcodable α] [Primcodable σ] (x : σ) :
            Primrec fun (x_1 : α) => x
            theorem Primrec.id {α : Type u_1} [Primcodable α] :
            theorem Primrec.comp {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : β → σ} {g : α → β} (hf : Primrec f) (hg : Primrec g) :
            Primrec fun (a : α) => f (g a)
            theorem Primrec.encode_iff {α : Type u_1} {σ : Type u_3} [Primcodable α] [Primcodable σ] {f : α → σ} :
            (Primrec fun (a : α) => Encodable.encode (f a)) ↔ Primrec f
            theorem Primrec.ofNat_iff {α : Type u_4} {β : Type u_5} [Denumerable α] [Primcodable β] {f : α → β} :
            Primrec f ↔ Primrec fun (n : ℕ) => f (Denumerable.ofNat α n)
            theorem Primrec.option_some_iff {α : Type u_1} {σ : Type u_3} [Primcodable α] [Primcodable σ] {f : α → σ} :
            (Primrec fun (a : α) => some (f a)) ↔ Primrec f
            theorem Primrec.of_equiv {α : Type u_1} [Primcodable α] {β : Type u_4} {e : β ≃ α} :
            Primrec ⇑e
            theorem Primrec.of_equiv_symm {α : Type u_1} [Primcodable α] {β : Type u_4} {e : β ≃ α} :
            Primrec ⇑e.symm
            theorem Primrec.of_equiv_iff {α : Type u_1} {σ : Type u_3} [Primcodable α] [Primcodable σ] {β : Type u_4} (e : β ≃ α) {f : σ → β} :
            (Primrec fun (a : σ) => e (f a)) ↔ Primrec f
            theorem Primrec.of_equiv_symm_iff {α : Type u_1} {σ : Type u_3} [Primcodable α] [Primcodable σ] {β : Type u_4} (e : β ≃ α) {f : σ → α} :
            (Primrec fun (a : σ) => e.symm (f a)) ↔ Primrec f
            instance Primcodable.prod {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
            Primcodable (α × β)
            Equations
            theorem Primrec.fst {α : Type u_3} {β : Type u_4} [Primcodable α] [Primcodable β] :
            Primrec Prod.fst
            theorem Primrec.snd {α : Type u_3} {β : Type u_4} [Primcodable α] [Primcodable β] :
            Primrec Prod.snd
            theorem Primrec.pair {α : Type u_3} {β : Type u_4} {γ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable γ] {f : α → β} {g : α → γ} (hf : Primrec f) (hg : Primrec g) :
            Primrec fun (a : α) => (f a, g a)
            theorem Primrec.list_get?₁ {α : Type u_1} [Primcodable α] (l : List α) :
            def Primrec₂ {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] (f : α → β → σ) :

            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.

            Equations
            Instances For
              def PrimrecPred {α : Type u_1} [Primcodable α] (p : α → Prop) [DecidablePred p] :

              PrimrecPred p means p : α → Prop is a (decidable) primitive recursive predicate, which is to say that decide ∘ p : α → Bool is primitive recursive.

              Equations
              Instances For
                def PrimrecRel {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] (s : α → β → Prop) [(a : α) → (b : β) → Decidable (s a b)] :

                PrimrecRel p means p : α → β → Prop is a (decidable) primitive recursive relation, which is to say that decide ∘ p : α → β → Bool is primitive recursive.

                Equations
                Instances For
                  theorem Primrec₂.mk {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} (hf : Primrec fun (p : α × β) => f p.1 p.2) :
                  theorem Primrec₂.of_eq {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} {g : α → β → σ} (hg : Primrec₂ f) (H : ∀ (a : α) (b : β), f a b = g a b) :
                  theorem Primrec₂.const {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] (x : σ) :
                  Primrec₂ fun (x_1 : α) (x_2 : β) => x
                  theorem Primrec₂.pair {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
                  Primrec₂ Prod.mk
                  theorem Primrec₂.left {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
                  Primrec₂ fun (a : α) (x : β) => a
                  theorem Primrec₂.right {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
                  Primrec₂ fun (x : α) (b : β) => b
                  theorem Primrec₂.unpaired {α : Type u_1} [Primcodable α] {f : ℕ → ℕ → α} :
                  theorem Primrec₂.encode_iff {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} :
                  (Primrec₂ fun (a : α) (b : β) => Encodable.encode (f a b)) ↔ Primrec₂ f
                  theorem Primrec₂.option_some_iff {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} :
                  (Primrec₂ fun (a : α) (b : β) => some (f a b)) ↔ Primrec₂ f
                  theorem Primrec₂.ofNat_iff {α : Type u_4} {β : Type u_5} {σ : Type u_6} [Denumerable α] [Denumerable β] [Primcodable σ] {f : α → β → σ} :
                  theorem Primrec₂.uncurry {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} :
                  theorem Primrec₂.curry {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α × β → σ} :
                  theorem Primrec.comp₂ {α : Type u_1} {β : Type u_2} {γ : Type u_3} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable σ] {f : γ → σ} {g : α → β → γ} (hf : Primrec f) (hg : Primrec₂ g) :
                  Primrec₂ fun (a : α) (b : β) => f (g a b)
                  theorem Primrec₂.comp {α : Type u_1} {β : Type u_2} {γ : Type u_3} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable σ] {f : β → γ → σ} {g : α → β} {h : α → γ} (hf : Primrec₂ f) (hg : Primrec g) (hh : Primrec h) :
                  Primrec fun (a : α) => f (g a) (h a)
                  theorem Primrec₂.comp₂ {α : Type u_1} {β : Type u_2} {γ : Type u_3} {δ : Type u_4} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable δ] [Primcodable σ] {f : γ → δ → σ} {g : α → β → γ} {h : α → β → δ} (hf : Primrec₂ f) (hg : Primrec₂ g) (hh : Primrec₂ h) :
                  Primrec₂ fun (a : α) (b : β) => f (g a b) (h a b)
                  theorem PrimrecPred.comp {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {p : β → Prop} [DecidablePred p] {f : α → β} :
                  PrimrecPred p → Primrec f → PrimrecPred fun (a : α) => p (f a)
                  theorem PrimrecRel.comp {α : Type u_1} {β : Type u_2} {γ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable γ] {R : β → γ → Prop} [(a : β) → (b : γ) → Decidable (R a b)] {f : α → β} {g : α → γ} :
                  PrimrecRel R → Primrec f → Primrec g → PrimrecPred fun (a : α) => R (f a) (g a)
                  theorem PrimrecRel.comp₂ {α : Type u_1} {β : Type u_2} {γ : Type u_3} {δ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable δ] {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)
                  theorem PrimrecPred.of_eq {α : Type u_1} [Primcodable α] {p : α → Prop} {q : α → Prop} [DecidablePred p] [DecidablePred q] (hp : PrimrecPred p) (H : ∀ (a : α), p a ↔ q a) :
                  theorem PrimrecRel.of_eq {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {r : α → β → Prop} {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) :
                  theorem Primrec₂.swap {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} (h : Primrec₂ f) :
                  theorem Primrec₂.nat_iff {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} :
                  theorem Primrec₂.nat_iff' {α : Type u_1} {β : Type u_2} {σ : Type u_3} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} :
                  Primrec₂ f ↔ Primrec₂ fun (m n : ℕ) => Option.bind (Encodable.decode m) fun (a : α) => Option.map (f a) (Encodable.decode n)
                  theorem Primrec.to₂ {α : Type u_1} {β : Type u_2} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α × β → σ} (hf : Primrec f) :
                  Primrec₂ fun (a : α) (b : β) => f (a, b)
                  theorem Primrec.nat_rec {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → β} {g : α → ℕ × β → β} (hf : Primrec f) (hg : Primrec₂ g) :
                  Primrec₂ fun (a : α) (n : ℕ) => Nat.rec (f a) (fun (n : ℕ) (IH : (fun (x : ℕ) => β) n) => g a (n, IH)) n
                  theorem Primrec.nat_rec' {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → ℕ} {g : α → β} {h : α → ℕ × β → β} (hf : Primrec f) (hg : Primrec g) (hh : Primrec₂ h) :
                  Primrec fun (a : α) => Nat.rec (g a) (fun (n : ℕ) (IH : (fun (x : ℕ) => β) n) => h a (n, IH)) (f a)
                  theorem Primrec.nat_rec₁ {α : Type u_1} [Primcodable α] {f : ℕ → α → α} (a : α) (hf : Primrec₂ f) :
                  Primrec fun (t : ℕ) => Nat.rec a f t
                  theorem Primrec.nat_casesOn' {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → β} {g : α → ℕ → β} (hf : Primrec f) (hg : Primrec₂ g) :
                  Primrec₂ fun (a : α) (n : ℕ) => Nat.casesOn n (f a) (g a)
                  theorem Primrec.nat_casesOn {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → ℕ} {g : α → β} {h : α → ℕ → β} (hf : Primrec f) (hg : Primrec g) (hh : Primrec₂ h) :
                  Primrec fun (a : α) => Nat.casesOn (f a) (g a) (h a)
                  theorem Primrec.nat_casesOn₁ {α : Type u_1} [Primcodable α] {f : ℕ → α} (a : α) (hf : Primrec f) :
                  Primrec fun (n : ℕ) => Nat.casesOn n a f
                  theorem Primrec.nat_iterate {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → ℕ} {g : α → β} {h : α → β → β} (hf : Primrec f) (hg : Primrec g) (hh : Primrec₂ h) :
                  Primrec fun (a : α) => (h a)^[f a] (g a)
                  theorem Primrec.option_casesOn {α : Type u_1} {β : Type u_2} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable σ] {o : α → Option β} {f : α → σ} {g : α → β → σ} (ho : Primrec o) (hf : Primrec f) (hg : Primrec₂ g) :
                  Primrec fun (a : α) => Option.casesOn (o a) (f a) (g a)
                  theorem Primrec.option_bind {α : Type u_1} {β : Type u_2} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → Option β} {g : α → β → Option σ} (hf : Primrec f) (hg : Primrec₂ g) :
                  Primrec fun (a : α) => Option.bind (f a) (g a)
                  theorem Primrec.option_bind₁ {α : Type u_1} {σ : Type u_5} [Primcodable α] [Primcodable σ] {f : α → Option σ} (hf : Primrec f) :
                  Primrec fun (o : Option α) => Option.bind o f
                  theorem Primrec.option_map {α : Type u_1} {β : Type u_2} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → Option β} {g : α → β → σ} (hf : Primrec f) (hg : Primrec₂ g) :
                  Primrec fun (a : α) => Option.map (g a) (f a)
                  theorem Primrec.option_map₁ {α : Type u_1} {σ : Type u_5} [Primcodable α] [Primcodable σ] {f : α → σ} (hf : Primrec f) :
                  theorem Primrec.option_iget {α : Type u_1} [Primcodable α] [Inhabited α] :
                  Primrec Option.iget
                  theorem Primrec.option_isSome {α : Type u_1} [Primcodable α] :
                  Primrec Option.isSome
                  theorem Primrec.option_getD {α : Type u_1} [Primcodable α] :
                  Primrec₂ Option.getD
                  theorem Primrec.bind_decode_iff {α : Type u_1} {β : Type u_2} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → Option σ} :
                  (Primrec₂ fun (a : α) (n : ℕ) => Option.bind (Encodable.decode n) (f a)) ↔ Primrec₂ f
                  theorem Primrec.map_decode_iff {α : Type u_1} {β : Type u_2} {σ : Type u_5} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → β → σ} :
                  (Primrec₂ fun (a : α) (n : ℕ) => Option.map (f a) (Encodable.decode n)) ↔ Primrec₂ f
                  theorem Primrec.nat_add :
                  Primrec₂ fun (x x_1 : ℕ) => x + x_1
                  theorem Primrec.nat_sub :
                  Primrec₂ fun (x x_1 : ℕ) => x - x_1
                  theorem Primrec.nat_mul :
                  Primrec₂ fun (x x_1 : ℕ) => x * x_1
                  theorem Primrec.cond {α : Type u_1} {σ : Type u_5} [Primcodable α] [Primcodable σ] {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
                  theorem Primrec.ite {α : Type u_1} {σ : Type u_5} [Primcodable α] [Primcodable σ] {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
                  theorem Primrec.nat_le :
                  PrimrecRel fun (x x_1 : ℕ) => x ≤ x_1
                  theorem Primrec.dom_bool {α : Type u_1} [Primcodable α] (f : Bool → α) :
                  theorem Primrec.dom_bool₂ {α : Type u_1} [Primcodable α] (f : Bool → Bool → α) :
                  theorem PrimrecPred.not {α : Type u_1} [Primcodable α] {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) :
                  PrimrecPred fun (a : α) => ¬p a
                  theorem PrimrecPred.and {α : Type u_1} [Primcodable α] {p : α → Prop} {q : α → Prop} [DecidablePred p] [DecidablePred q] (hp : PrimrecPred p) (hq : PrimrecPred q) :
                  PrimrecPred fun (a : α) => p a ∧ q a
                  theorem PrimrecPred.or {α : Type u_1} [Primcodable α] {p : α → Prop} {q : α → Prop} [DecidablePred p] [DecidablePred q] (hp : PrimrecPred p) (hq : PrimrecPred q) :
                  PrimrecPred fun (a : α) => p a ∨ q a
                  theorem Primrec.beq {α : Type u_1} [Primcodable α] [DecidableEq α] :
                  Primrec₂ BEq.beq
                  theorem Primrec.eq {α : Type u_1} [Primcodable α] [DecidableEq α] :
                  theorem Primrec.nat_lt :
                  PrimrecRel fun (x x_1 : ℕ) => x < x_1
                  theorem Primrec.option_guard {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {p : α → β → Prop} [(a : α) → (b : β) → Decidable (p a b)] (hp : PrimrecRel p) {f : α → β} (hf : Primrec f) :
                  Primrec fun (a : α) => Option.guard (p a) (f a)
                  theorem Primrec.option_orElse {α : Type u_1} [Primcodable α] :
                  Primrec₂ fun (x x_1 : Option α) => HOrElse.hOrElse x fun (x : Unit) => x_1
                  theorem Primrec.list_findIdx₁ {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {p : α → β → Bool} (hp : Primrec₂ p) (l : List β) :
                  Primrec fun (a : α) => List.findIdx (p a) l
                  theorem Primrec.list_indexOf₁ {α : Type u_1} [Primcodable α] [DecidableEq α] (l : List α) :
                  Primrec fun (a : α) => List.indexOf a l
                  theorem Primrec.dom_fintype {α : Type u_1} {σ : Type u_5} [Primcodable α] [Primcodable σ] [Fintype α] (f : α → σ) :
                  def Primrec.PrimrecBounded {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] (f : α → β) :

                  A function is PrimrecBounded if its size is bounded by a primitive recursive function

                  Equations
                  Instances For
                    theorem Primrec.nat_findGreatest {α : Type u_1} [Primcodable α] {f : α → ℕ} {p : α → ℕ → Prop} [(x : α) → (n : ℕ) → Decidable (p x n)] (hf : Primrec f) (hp : PrimrecRel p) :
                    Primrec fun (x : α) => Nat.findGreatest (p x) (f x)
                    theorem Primrec.of_graph {α : Type u_1} [Primcodable α] {f : α → ℕ} (h₁ : Primrec.PrimrecBounded f) (h₂ : PrimrecRel fun (a : α) (b : ℕ) => f a = b) :

                    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 Primrec.nat_div :
                    Primrec₂ fun (x x_1 : ℕ) => x / x_1
                    theorem Primrec.nat_mod :
                    Primrec₂ fun (x x_1 : ℕ) => x % x_1
                    theorem Primrec.nat_double :
                    Primrec fun (n : ℕ) => 2 * n
                    theorem Primrec.nat_double_succ :
                    Primrec fun (n : ℕ) => 2 * n + 1
                    instance Primcodable.sum {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
                    Equations
                    instance Primcodable.list {α : Type u_1} [Primcodable α] :
                    Equations
                    theorem Primrec.sum_inl {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
                    Primrec Sum.inl
                    theorem Primrec.sum_inr {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] :
                    Primrec Sum.inr
                    theorem Primrec.sum_casesOn {α : Type u_1} {β : Type u_2} {γ : Type u_3} {σ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable γ] [Primcodable σ] {f : α → β ⊕ γ} {g : α → β → σ} {h : α → γ → σ} (hf : Primrec f) (hg : Primrec₂ g) (hh : Primrec₂ h) :
                    Primrec fun (a : α) => Sum.casesOn (f a) (g a) (h a)
                    theorem Primrec.list_cons {α : Type u_1} [Primcodable α] :
                    Primrec₂ List.cons
                    theorem Primrec.list_casesOn {α : Type u_1} {β : Type u_2} {σ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → List β} {g : α → σ} {h : α → β × List β → σ} :
                    Primrec f → Primrec g → Primrec₂ h → Primrec fun (a : α) => List.casesOn (f a) (g a) fun (b : β) (l : List β) => h a (b, l)
                    theorem Primrec.list_foldl {α : Type u_1} {β : Type u_2} {σ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → List β} {g : α → σ} {h : α → σ × β → σ} :
                    Primrec f → Primrec g → Primrec₂ h → Primrec fun (a : α) => List.foldl (fun (s : σ) (b : β) => h a (s, b)) (g a) (f a)
                    theorem Primrec.list_reverse {α : Type u_1} [Primcodable α] :
                    Primrec List.reverse
                    theorem Primrec.list_foldr {α : Type u_1} {β : Type u_2} {σ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → List β} {g : α → σ} {h : α → β × σ → σ} (hf : Primrec f) (hg : Primrec g) (hh : Primrec₂ h) :
                    Primrec fun (a : α) => List.foldr (fun (b : β) (s : σ) => h a (b, s)) (g a) (f a)
                    theorem Primrec.list_head? {α : Type u_1} [Primcodable α] :
                    Primrec List.head?
                    theorem Primrec.list_headI {α : Type u_1} [Primcodable α] [Inhabited α] :
                    Primrec List.headI
                    theorem Primrec.list_tail {α : Type u_1} [Primcodable α] :
                    Primrec List.tail
                    theorem Primrec.list_rec {α : Type u_1} {β : Type u_2} {σ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable σ] {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 : List β) (IH : σ) => h a (b, l, IH)
                    theorem Primrec.list_get? {α : Type u_1} [Primcodable α] :
                    Primrec₂ List.get?
                    theorem Primrec.list_getD {α : Type u_1} [Primcodable α] (d : α) :
                    Primrec₂ fun (l : List α) (n : ℕ) => List.getD l n d
                    theorem Primrec.list_getI {α : Type u_1} [Primcodable α] [Inhabited α] :
                    Primrec₂ List.getI
                    theorem Primrec.list_append {α : Type u_1} [Primcodable α] :
                    Primrec₂ fun (x x_1 : List α) => x ++ x_1
                    theorem Primrec.list_concat {α : Type u_1} [Primcodable α] :
                    Primrec₂ fun (l : List α) (a : α) => l ++ [a]
                    theorem Primrec.list_map {α : Type u_1} {β : Type u_2} {σ : Type u_4} [Primcodable α] [Primcodable β] [Primcodable σ] {f : α → List β} {g : α → β → σ} (hf : Primrec f) (hg : Primrec₂ g) :
                    Primrec fun (a : α) => List.map (g a) (f a)
                    theorem Primrec.list_join {α : Type u_1} [Primcodable α] :
                    Primrec List.join
                    theorem Primrec.list_length {α : Type u_1} [Primcodable α] :
                    Primrec List.length
                    theorem Primrec.list_findIdx {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → List β} {p : α → β → Bool} (hf : Primrec f) (hp : Primrec₂ p) :
                    Primrec fun (a : α) => List.findIdx (p a) (f a)
                    theorem Primrec.list_indexOf {α : Type u_1} [Primcodable α] [DecidableEq α] :
                    Primrec₂ List.indexOf
                    theorem Primrec.nat_strong_rec {α : Type u_1} {σ : Type u_4} [Primcodable α] [Primcodable σ] (f : α → ℕ → σ) {g : α → List σ → Option σ} (hg : Primrec₂ g) (H : ∀ (a : α) (n : ℕ), g a (List.map (f a) (List.range n)) = some (f a n)) :
                    def Primcodable.subtype {α : Type u_1} [Primcodable α] {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) :

                    A subtype of a primitive recursive predicate is Primcodable.

                    Equations
                    Instances For
                      instance Primcodable.fin {n : ℕ} :
                      Equations
                      instance Primcodable.vector {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Equations
                      instance Primcodable.finArrow {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primcodable (Fin n → α)
                      Equations
                      theorem Primcodable.mem_range_encode {α : Type u_1} [Primcodable α] :
                      PrimrecPred fun (n : ℕ) => n ∈ Set.range Encodable.encode
                      instance Primcodable.ulower {α : Type u_1} [Primcodable α] :
                      Equations
                      theorem Primrec.subtype_val {α : Type u_1} [Primcodable α] {p : α → Prop} [DecidablePred p] {hp : PrimrecPred p} :
                      Primrec Subtype.val
                      theorem Primrec.subtype_val_iff {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {p : β → Prop} [DecidablePred p] {hp : PrimrecPred p} {f : α → Subtype p} :
                      (Primrec fun (a : α) => ↑(f a)) ↔ Primrec f
                      theorem Primrec.subtype_mk {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {p : β → Prop} [DecidablePred p] {hp : PrimrecPred p} {f : α → β} {h : ∀ (a : α), p (f a)} (hf : Primrec f) :
                      Primrec fun (a : α) => { val := f a, property := ⋯ }
                      theorem Primrec.option_get {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {f : α → Option β} {h : ∀ (a : α), Option.isSome (f a) = true} :
                      Primrec f → Primrec fun (a : α) => Option.get (f a) ⋯
                      theorem Primrec.ulower_down {α : Type u_1} [Primcodable α] :
                      Primrec ULower.down
                      theorem Primrec.ulower_up {α : Type u_1} [Primcodable α] :
                      Primrec ULower.up
                      theorem Primrec.fin_val_iff {α : Type u_1} [Primcodable α] {n : ℕ} {f : α → Fin n} :
                      (Primrec fun (a : α) => ↑(f a)) ↔ Primrec f
                      theorem Primrec.fin_val {n : ℕ} :
                      Primrec fun (i : Fin n) => ↑i
                      theorem Primrec.fin_succ {n : ℕ} :
                      Primrec Fin.succ
                      theorem Primrec.vector_toList {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec Vector.toList
                      theorem Primrec.vector_toList_iff {α : Type u_1} {β : Type u_2} [Primcodable α] [Primcodable β] {n : ℕ} {f : α → Vector β n} :
                      (Primrec fun (a : α) => Vector.toList (f a)) ↔ Primrec f
                      theorem Primrec.vector_cons {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec₂ Vector.cons
                      theorem Primrec.vector_length {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec Vector.length
                      theorem Primrec.vector_head {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec Vector.head
                      theorem Primrec.vector_tail {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec Vector.tail
                      theorem Primrec.vector_get {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec₂ Vector.get
                      theorem Primrec.list_ofFn {α : Type u_1} {σ : Type u_4} [Primcodable α] [Primcodable σ] {n : ℕ} {f : Fin n → α → σ} :
                      (∀ (i : Fin n), Primrec (f i)) → Primrec fun (a : α) => List.ofFn fun (i : Fin n) => f i a
                      theorem Primrec.vector_ofFn {α : Type u_1} {σ : Type u_4} [Primcodable α] [Primcodable σ] {n : ℕ} {f : Fin n → α → σ} (hf : ∀ (i : Fin n), Primrec (f i)) :
                      Primrec fun (a : α) => Vector.ofFn fun (i : Fin n) => f i a
                      theorem Primrec.vector_get' {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec Vector.get
                      theorem Primrec.vector_ofFn' {α : Type u_1} [Primcodable α] {n : ℕ} :
                      Primrec Vector.ofFn
                      theorem Primrec.fin_app {σ : Type u_4} [Primcodable σ] {n : ℕ} :
                      theorem Primrec.fin_curry₁ {α : Type u_1} {σ : Type u_4} [Primcodable α] [Primcodable σ] {n : ℕ} {f : Fin n → α → σ} :
                      Primrec₂ f ↔ ∀ (i : Fin n), Primrec (f i)
                      theorem Primrec.fin_curry {α : Type u_1} {σ : Type u_4} [Primcodable α] [Primcodable σ] {n : ℕ} {f : α → Fin n → σ} :
                      inductive Nat.Primrec' {n : ℕ} :
                      (Vector ℕ n → ℕ) → Prop

                      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.

                      Instances For
                        theorem Nat.Primrec'.to_prim {n : ℕ} {f : Vector ℕ n → ℕ} (pf : Nat.Primrec' f) :
                        theorem Nat.Primrec'.of_eq {n : ℕ} {f : Vector ℕ n → ℕ} {g : Vector ℕ n → ℕ} (hf : Nat.Primrec' f) (H : ∀ (i : Vector ℕ n), f i = g i) :
                        theorem Nat.Primrec'.const {n : ℕ} (m : ℕ) :
                        Nat.Primrec' fun (x : Vector ℕ n) => m
                        theorem Nat.Primrec'.head {n : ℕ} :
                        Nat.Primrec' Vector.head
                        theorem Nat.Primrec'.tail {n : ℕ} {f : Vector ℕ n → ℕ} (hf : Nat.Primrec' f) :
                        Nat.Primrec' fun (v : Vector ℕ (Nat.succ n)) => f (Vector.tail v)
                        def Nat.Primrec'.Vec {n : ℕ} {m : ℕ} (f : Vector ℕ n → Vector ℕ m) :

                        A function from vectors to vectors is primitive recursive when all of its projections are.

                        Equations
                        Instances For
                          theorem Nat.Primrec'.nil {n : ℕ} :
                          Nat.Primrec'.Vec fun (x : Vector ℕ n) => Vector.nil
                          theorem Nat.Primrec'.cons {n : ℕ} {m : ℕ} {f : Vector ℕ n → ℕ} {g : Vector ℕ n → Vector ℕ m} (hf : Nat.Primrec' f) (hg : Nat.Primrec'.Vec g) :
                          Nat.Primrec'.Vec fun (v : Vector ℕ n) => f v ::ᵥ g v
                          theorem Nat.Primrec'.comp' {n : ℕ} {m : ℕ} {f : Vector ℕ m → ℕ} {g : Vector ℕ n → Vector ℕ m} (hf : Nat.Primrec' f) (hg : Nat.Primrec'.Vec g) :
                          Nat.Primrec' fun (v : Vector ℕ n) => f (g v)
                          theorem Nat.Primrec'.comp₁ (f : ℕ → ℕ) (hf : Nat.Primrec' fun (v : Vector ℕ 1) => f (Vector.head v)) {n : ℕ} {g : Vector ℕ n → ℕ} (hg : Nat.Primrec' g) :
                          Nat.Primrec' fun (v : Vector ℕ n) => f (g v)
                          theorem Nat.Primrec'.comp₂ (f : ℕ → ℕ → ℕ) (hf : Nat.Primrec' fun (v : Vector ℕ 2) => f (Vector.head v) (Vector.head (Vector.tail v))) {n : ℕ} {g : Vector ℕ n → ℕ} {h : Vector ℕ n → ℕ} (hg : Nat.Primrec' g) (hh : Nat.Primrec' h) :
                          Nat.Primrec' fun (v : Vector ℕ n) => f (g v) (h v)
                          theorem Nat.Primrec'.prec' {n : ℕ} {f : Vector ℕ n → ℕ} {g : Vector ℕ n → ℕ} {h : Vector ℕ (n + 2) → ℕ} (hf : Nat.Primrec' f) (hg : Nat.Primrec' g) (hh : Nat.Primrec' h) :
                          Nat.Primrec' fun (v : Vector ℕ n) => Nat.rec (g v) (fun (y IH : ℕ) => h (y ::ᵥ IH ::ᵥ v)) (f v)
                          theorem Nat.Primrec'.if_lt {n : ℕ} {a : Vector ℕ n → ℕ} {b : Vector ℕ n → ℕ} {f : Vector ℕ n → ℕ} {g : Vector ℕ n → ℕ} (ha : Nat.Primrec' a) (hb : Nat.Primrec' b) (hf : Nat.Primrec' f) (hg : Nat.Primrec' g) :
                          Nat.Primrec' fun (v : Vector ℕ n) => if a v < b v then f v else g v
                          theorem Nat.Primrec'.encode {n : ℕ} :
                          Nat.Primrec' Encodable.encode
                          theorem Nat.Primrec'.unpair₁ {n : ℕ} {f : Vector ℕ n → ℕ} (hf : Nat.Primrec' f) :
                          Nat.Primrec' fun (v : Vector ℕ n) => (Nat.unpair (f v)).1
                          theorem Nat.Primrec'.unpair₂ {n : ℕ} {f : Vector ℕ n → ℕ} (hf : Nat.Primrec' f) :
                          Nat.Primrec' fun (v : Vector ℕ n) => (Nat.unpair (f v)).2
                          theorem Nat.Primrec'.of_prim {n : ℕ} {f : Vector ℕ n → ℕ} :
                          theorem Nat.Primrec'.prim_iff₁ {f : ℕ → ℕ} :
                          (Nat.Primrec' fun (v : Vector ℕ 1) => f (Vector.head v)) ↔ Primrec f