Documentation

Cslib.Languages.CombinatoryLogic.Recursion

General recursion in the SKI calculus #

In this file we implement general recursion functions (on the natural numbers), inspired by the formalisation of Mathlib.Computability.Partrec. Since composition (B-combinator) and pairs (MkPair, Fst, Snd) have been implemented in Cslib.Computability.CombinatoryLogic.Basic, what remains are the following definitions and proofs of their correctness.

References #

TODO #

def Cslib.SKI.Church (n : ) (f x : SKI) :

Function form of the church numerals.

Equations
Instances For
    @[simp]
    theorem Cslib.SKI.Church_zero (f x : SKI) :
    Church 0 f x = x
    @[simp]
    theorem Cslib.SKI.Church_succ (n : ) (f x : SKI) :
    Church (n + 1) f x = f.app (Church n f x)
    theorem Cslib.SKI.church_red (n : ) (f f' x x' : SKI) (hf : Relation.ReflTransGen Red f f') (hx : Relation.ReflTransGen Red x x') :
    Relation.ReflTransGen Red (Church n f x) (Church n f' x')

    church commutes with reduction.

    def Cslib.SKI.IsChurch (n : ) (a : SKI) :

    The term a is βη-equivalent to a standard church numeral.

    Equations
    Instances For
      theorem Cslib.SKI.isChurch_trans (n : ) {a a' : SKI} (h : Relation.ReflTransGen Red a a') :
      IsChurch n a'IsChurch n a

      To show IsChurch n a it suffices to show the same for a reduct of a.

      Church numeral basics #

      Church zero := λ f x. x

      Equations
      Instances For

        Church one := λ f x. f x

        Equations
        Instances For

          Church succ := λ a f x. f (a f x) λ a f. B f (a f) λ a. S B a ~ S B

          Equations
          Instances For
            theorem Cslib.SKI.succ_correct (n : ) (a : SKI) (h : IsChurch n a) :
            IsChurch (n + 1) (SKI.Succ.app a)
            def Cslib.SKI.toChurch :
            SKI

            Build the canonical SKI Church numeral for n.

            Equations
            Instances For
              @[simp]
              theorem Cslib.SKI.toChurch_succ (n : ) :

              toChurch (n + 1) = SucctoChurch n.

              toChurch n correctly represents n.

              To define the predecessor, iterate the function PredAux ⟨i, j⟩ ↦ ⟨j, j+1⟩ on ⟨0,0⟩, then take the first component.

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For

                A term representing PredAux

                Equations
                Instances For
                  theorem Cslib.SKI.predAux_def (p : SKI) :
                  Relation.ReflTransGen Red (PredAux.app p) ((MkPair.app (Snd.app p)).app (SKI.Succ.app (Snd.app p)))
                  def Cslib.SKI.IsChurchPair (ns : × ) (x : SKI) :

                  Useful auxiliary definition expressing that p represents ns ∈ Nat × Nat.

                  Equations
                  Instances For
                    theorem Cslib.SKI.isChurchPair_trans (ns : × ) (a a' : SKI) (h : Relation.ReflTransGen Red a a') :
                    IsChurchPair ns a'IsChurchPair ns a
                    theorem Cslib.SKI.predAux_correct (p : SKI) (ns : × ) (h : IsChurchPair ns p) :
                    IsChurchPair (ns.2, ns.2 + 1) (PredAux.app p)

                    The stronger induction hypothesis necessary for the proof of pred_correct.

                    Predecessor := λ n. Fst ⬝ (n ⬝ PredAux ⬝ (MkPair ⬝ Zero ⬝ Zero))

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For

                      A term representing Pred

                      Equations
                      Instances For
                        theorem Cslib.SKI.pred_def (a : SKI) :
                        Relation.ReflTransGen Red (Pred.app a) (Fst.app ((a.app PredAux).app ((MkPair.app SKI.Zero).app SKI.Zero)))
                        theorem Cslib.SKI.pred_correct (n : ) (a : SKI) (h : IsChurch n a) :
                        IsChurch n.pred (Pred.app a)

                        Primitive recursion #

                        A term representing IsZero

                        Equations
                        Instances For
                          theorem Cslib.SKI.isZero_def (a : SKI) :
                          Relation.ReflTransGen Red (IsZero.app a) ((a.app (K.app FF)).app TT)
                          theorem Cslib.SKI.isZero_correct (n : ) (a : SKI) (h : IsChurch n a) :
                          IsBool (decide (n = 0)) (IsZero.app a)

                          To define Rec x g n := if n==0 then x else (Rec x g (Pred n)), we obtain a fixed point of R ↦ λ x g n. Cond ⬝ (IsZero ⬝ n) ⬝ x ⬝ (g ⬝ a ⬝ (R ⬝ x ⬝ g ⬝ (Pred ⬝ n)))

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For

                            A term representing RecAux

                            Equations
                            Instances For
                              theorem Cslib.SKI.recAux_def (R₀ x g a : SKI) :
                              Relation.ReflTransGen Red ((((RecAux.app R₀).app x).app g).app a) (((SKI.Cond.app x).app ((g.app a).app (((R₀.app x).app g).app (Pred.app a)))).app (IsZero.app a))

                              We define Rec so that Rec ⬝ x ⬝ g ⬝ a ↠ SKI.Cond ⬝ x ⬝ (g ⬝ a ⬝ (Rec ⬝ x ⬝ g ⬝ (Pred ⬝ a))) ⬝ (IsZero ⬝ a)

                              Equations
                              Instances For
                                theorem Cslib.SKI.rec_def (x g a : SKI) :
                                Relation.ReflTransGen Red (((Rec.app x).app g).app a) (((SKI.Cond.app x).app ((g.app a).app (((Rec.app x).app g).app (Pred.app a)))).app (IsZero.app a))
                                theorem Cslib.SKI.rec_zero (x g a : SKI) (ha : IsChurch 0 a) :
                                Relation.ReflTransGen Red (((Rec.app x).app g).app a) x
                                theorem Cslib.SKI.rec_succ (n : ) (x g a : SKI) (ha : IsChurch (n + 1) a) :
                                Relation.ReflTransGen Red (((Rec.app x).app g).app a) ((g.app a).app (((Rec.app x).app g).app (Pred.app a)))

                                Root-finding (μ-recursion) #

                                First define an auxiliary function RFindAbove that looks for roots above a fixed number n, as a fixed point of R ↦ λ n f. if f n = 0 then n else R f (n+1) ~ λ n f. Cond ⬝ n (R f (Succ n)) (IsZero (f n))

                                Equations
                                • One or more equations did not get rendered due to their size.
                                Instances For

                                  A term representing RFindAboveAux

                                  Equations
                                  Instances For
                                    theorem Cslib.SKI.rfindAboveAux_def (R₀ f a : SKI) :
                                    Relation.ReflTransGen Red (((RFindAboveAux.app R₀).app a).app f) (((SKI.Cond.app a).app ((R₀.app (SKI.Succ.app a)).app f)).app (IsZero.app (f.app a)))
                                    theorem Cslib.SKI.rfindAboveAux_base (R₀ f a : SKI) (hfa : IsChurch 0 (f.app a)) :
                                    Relation.ReflTransGen Red (((RFindAboveAux.app R₀).app a).app f) a
                                    theorem Cslib.SKI.rfindAboveAux_step (R₀ f a : SKI) {m : } (hfa : IsChurch (m + 1) (f.app a)) :
                                    Relation.ReflTransGen Red (((RFindAboveAux.app R₀).app a).app f) ((R₀.app (SKI.Succ.app a)).app f)

                                    Find the minimal root of fNat above a number n

                                    Equations
                                    Instances For
                                      theorem Cslib.SKI.RFindAbove_correct (fNat : ) (f x : SKI) (hf : ∀ (i : ) (y : SKI), IsChurch i yIsChurch (fNat i) (f.app y)) (n m : ) (hx : IsChurch m x) (hroot : fNat (m + n) = 0) (hpos : i < n, fNat (m + i) 0) :
                                      IsChurch (m + n) ((RFindAbove.app x).app f)

                                      Ordinary root finding is root finding above zero

                                      Equations
                                      Instances For
                                        theorem Cslib.SKI.RFind_correct (fNat : ) (f : SKI) (hf : ∀ (i : ) (y : SKI), IsChurch i yIsChurch (fNat i) (f.app y)) (n : ) (hroot : fNat n = 0) (hpos : i < n, fNat i 0) :

                                        Further numeric operations #

                                        A term representing addition on church numerals

                                        Equations
                                        Instances For
                                          theorem Cslib.SKI.add_def (a b : SKI) :
                                          Relation.ReflTransGen Red ((SKI.Add.app a).app b) ((a.app SKI.Succ).app b)
                                          theorem Cslib.SKI.add_correct (n m : ) (a b : SKI) (ha : IsChurch n a) (hb : IsChurch m b) :
                                          IsChurch (n + m) ((SKI.Add.app a).app b)

                                          A term representing multiplication on church numerals

                                          Equations
                                          Instances For
                                            theorem Cslib.SKI.mul_def (a b : SKI) :
                                            Relation.ReflTransGen Red ((SKI.Mul.app a).app b) ((a.app (SKI.Add.app b)).app SKI.Zero)
                                            theorem Cslib.SKI.mul_correct {n m : } {a b : SKI} (ha : IsChurch n a) (hb : IsChurch m b) :
                                            IsChurch (n * m) ((SKI.Mul.app a).app b)

                                            A term representing subtraction on church numerals

                                            Equations
                                            Instances For
                                              theorem Cslib.SKI.sub_def (a b : SKI) :
                                              Relation.ReflTransGen Red ((SKI.Sub.app a).app b) ((b.app Pred).app a)
                                              theorem Cslib.SKI.sub_correct (n m : ) (a b : SKI) (ha : IsChurch n a) (hb : IsChurch m b) :
                                              IsChurch (n - m) ((SKI.Sub.app a).app b)

                                              A term representing comparison on church numerals

                                              Equations
                                              Instances For
                                                theorem Cslib.SKI.le_def (a b : SKI) :
                                                Relation.ReflTransGen Red ((SKI.LE.app a).app b) (IsZero.app ((SKI.Sub.app a).app b))
                                                theorem Cslib.SKI.le_correct (n m : ) (a b : SKI) (ha : IsChurch n a) (hb : IsChurch m b) :
                                                IsBool (decide (n m)) ((SKI.LE.app a).app b)

                                                Integer square root #

                                                Inner condition for Sqrt: with &0 = n, &1 = k, computes if n < (k+1)² then 0 else 1.

                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For

                                                  SKI term for the inner condition of Sqrt

                                                  Equations
                                                  Instances For
                                                    theorem Cslib.SKI.sqrtCond_def (cn ck : SKI) :
                                                    Relation.ReflTransGen Red ((SqrtCond.app cn).app ck) (((SKI.Cond.app SKI.Zero).app SKI.One).app (SKI.Neg.app ((SKI.LE.app ((SKI.Mul.app (SKI.Succ.app ck)).app (SKI.Succ.app ck))).app cn)))

                                                    SqrtCond ⬝ n ⬝ k reduces to: return 0 if (k+1)² > n, else 1. Used by RFind to locate the smallest such k, which is √n.

                                                    Sqrt n = smallest k such that (k+1)² > n, i.e., the integer square root. Defined as λ n. RFind (SqrtCond n).

                                                    Equations
                                                    Instances For

                                                      SKI term for integer square root

                                                      Equations
                                                      Instances For
                                                        theorem Cslib.SKI.sqrt_def (cn : SKI) :
                                                        Relation.ReflTransGen Red (Sqrt.app cn) (RFind.app (SqrtCond.app cn))

                                                        Sqrt ⬝ n reduces to an RFind search for the smallest k with (k+1)² > n.

                                                        theorem Cslib.SKI.sqrt_correct (n : ) (cn : SKI) (hcn : IsChurch n cn) :
                                                        IsChurch n.sqrt (Sqrt.app cn)

                                                        Sqrt correctly computes Nat.sqrt.

                                                        Nat pairing (matching Mathlib's Nat.pair) #

                                                        NatPair a b = if a < b then bb + a else aa + a + b. With &0 = a, &1 = b. The condition a < b is ¬(b ≤ a).

                                                        Equations
                                                        • One or more equations did not get rendered due to their size.
                                                        Instances For

                                                          SKI term for Nat pairing

                                                          Equations
                                                          Instances For
                                                            theorem Cslib.SKI.natPair_def (ca cb : SKI) :
                                                            Relation.ReflTransGen Red ((NatPair.app ca).app cb) (((SKI.Cond.app ((SKI.Add.app ((SKI.Mul.app cb).app cb)).app ca)).app ((SKI.Add.app ((SKI.Add.app ((SKI.Mul.app ca).app ca)).app ca)).app cb)).app (SKI.Neg.app ((SKI.LE.app cb).app ca)))

                                                            NatPair ⬝ a ⬝ b reduces to: if a < b then b² + a, else a² + a + b.

                                                            theorem Cslib.SKI.natPair_correct (a b : ) (ca cb : SKI) (ha : IsChurch a ca) (hb : IsChurch b cb) :
                                                            IsChurch (Nat.pair a b) ((NatPair.app ca).app cb)

                                                            NatPair correctly computes Nat.pair.

                                                            Nat unpairing (matching Mathlib's Nat.unpair) #

                                                            NatUnpairLeft n = if n - s² < s then n - s² else s where s = Nat.sqrt n.

                                                            Equations
                                                            • One or more equations did not get rendered due to their size.
                                                            Instances For

                                                              SKI term for left projection of Nat.unpair

                                                              Equations
                                                              Instances For
                                                                theorem Cslib.SKI.natUnpairLeft_def (cn : SKI) :
                                                                Relation.ReflTransGen Red (NatUnpairLeft.app cn) (((SKI.Cond.app ((SKI.Sub.app cn).app ((SKI.Mul.app (Sqrt.app cn)).app (Sqrt.app cn)))).app (Sqrt.app cn)).app (SKI.Neg.app ((SKI.LE.app (Sqrt.app cn)).app ((SKI.Sub.app cn).app ((SKI.Mul.app (Sqrt.app cn)).app (Sqrt.app cn))))))

                                                                NatUnpairLeft ⬝ n reduces to: let s = √n and d = n - s²; return d if d < s, else s.

                                                                theorem Cslib.SKI.natUnpairLeft_correct (n : ) (cn : SKI) (hcn : IsChurch n cn) :
                                                                IsChurch (Nat.unpair n).1 (NatUnpairLeft.app cn)

                                                                NatUnpairLeft correctly computes the first component of Nat.unpair.

                                                                NatUnpairRight n = let s = sqrt n in if n - s² < s then s else n - s² - s.

                                                                Equations
                                                                • One or more equations did not get rendered due to their size.
                                                                Instances For

                                                                  SKI term for right projection of Nat.unpair

                                                                  Equations
                                                                  Instances For
                                                                    theorem Cslib.SKI.natUnpairRight_def (cn : SKI) :
                                                                    Relation.ReflTransGen Red (NatUnpairRight.app cn) (((SKI.Cond.app (Sqrt.app cn)).app ((SKI.Sub.app ((SKI.Sub.app cn).app ((SKI.Mul.app (Sqrt.app cn)).app (Sqrt.app cn)))).app (Sqrt.app cn))).app (SKI.Neg.app ((SKI.LE.app (Sqrt.app cn)).app ((SKI.Sub.app cn).app ((SKI.Mul.app (Sqrt.app cn)).app (Sqrt.app cn))))))

                                                                    NatUnpairRight ⬝ n reduces to: let s = √n and d = n - s²; return s if d < s, else d - s.

                                                                    theorem Cslib.SKI.natUnpairRight_correct (n : ) (cn : SKI) (hcn : IsChurch n cn) :
                                                                    IsChurch (Nat.unpair n).2 (NatUnpairRight.app cn)

                                                                    NatUnpairRight correctly computes the second component of Nat.unpair.