Documentation

Mathlib.Data.PFunctor.Univariate.M

M-types #

M types are potentially infinite tree-like structures. They are defined as the greatest fixpoint of a polynomial functor.

CofixA F n is an n level approximation of an M-type

Instances For

    The label of the root of the tree for a non-trivial approximation of the cofix of a pfunctor.

    Equations
    Instances For

      for a non-trivial approximation, return all the subtrees of the root

      Equations
      Instances For

        Relation between two approximations of the cofix of a pfunctor that state they both contain the same data until one of them is truncated

        Instances For

          Given an infinite series of approximations approx, AllAgree approx states that they are all consistent with each other.

          Equations
          Instances For
            @[deprecated PFunctor.Approx.agree_trivial (since := "2024-12-25")]

            Alias of PFunctor.Approx.agree_trivial.

            def PFunctor.Approx.sCorec {F : PFunctor.{u}} {X : Type w} (f : XF X) :
            X(n : ) → PFunctor.Approx.CofixA F n

            sCorec f i n creates an approximation of height n of the final coalgebra of f

            Equations
            Instances For
              theorem PFunctor.Approx.P_corec {F : PFunctor.{u}} {X : Type w} (f : XF X) (i : X) (n : ) :

              Path F provides indices to access internal nodes in Corec F

              Equations
              Instances For
                structure PFunctor.MIntl (F : PFunctor.{u}) :

                Internal definition for M. It is needed to avoid name clashes between M.mk and M.cases_on and the declarations generated for the structure

                Instances For

                  For polynomial functor F, M F is its final coalgebra

                  Equations
                  • F.M = F.MIntl
                  Instances For
                    Equations
                    theorem PFunctor.M.ext' (F : PFunctor.{u}) (x y : F.M) (H : ∀ (i : ), x.approx i = y.approx i) :
                    x = y
                    def PFunctor.M.corec {F : PFunctor.{u}} {X : Type u_1} (f : XF X) (i : X) :
                    F.M

                    Corecursor for the M-type defined by F.

                    Equations
                    Instances For
                      def PFunctor.M.head {F : PFunctor.{u}} (x : F.M) :
                      F.A

                      given a tree generated by F, head gives us the first piece of data it contains

                      Equations
                      Instances For
                        def PFunctor.M.children {F : PFunctor.{u}} (x : F.M) (i : F.B x.head) :
                        F.M

                        return all the subtrees of the root of a tree x : M F

                        Equations
                        Instances For
                          def PFunctor.M.ichildren {F : PFunctor.{u}} [Inhabited F.M] [DecidableEq F.A] (i : F.Idx) (x : F.M) :
                          F.M

                          select a subtree using an i : F.Idx or return an arbitrary tree if i designates no subtree of x

                          Equations
                          Instances For
                            theorem PFunctor.M.head_succ {F : PFunctor.{u}} (n m : ) (x : F.M) :
                            PFunctor.Approx.head' (x.approx n.succ) = PFunctor.Approx.head' (x.approx m.succ)
                            theorem PFunctor.M.head_eq_head' {F : PFunctor.{u}} (x : F.M) (n : ) :
                            x.head = PFunctor.Approx.head' (x.approx (n + 1))
                            theorem PFunctor.M.head'_eq_head {F : PFunctor.{u}} (x : F.M) (n : ) :
                            PFunctor.Approx.head' (x.approx (n + 1)) = x.head
                            theorem PFunctor.M.truncate_approx {F : PFunctor.{u}} (x : F.M) (n : ) :
                            PFunctor.Approx.truncate (x.approx (n + 1)) = x.approx n
                            def PFunctor.M.dest {F : PFunctor.{u}} :
                            F.MF F.M

                            unfold an M-type

                            Equations
                            • x✝.dest = x✝.head, fun (i : F.B x✝.head) => x✝.children i
                            Instances For
                              def PFunctor.M.Approx.sMk {F : PFunctor.{u}} (x : F F.M) (n : ) :

                              generates the approximations needed for M.mk

                              Equations
                              Instances For
                                def PFunctor.M.mk {F : PFunctor.{u}} (x : F F.M) :
                                F.M

                                constructor for M-types

                                Equations
                                Instances For
                                  inductive PFunctor.M.Agree' {F : PFunctor.{u}} :
                                  F.MF.MProp

                                  Agree' n relates two trees of type M F that are the same up to depth n

                                  Instances For
                                    @[simp]
                                    theorem PFunctor.M.dest_mk {F : PFunctor.{u}} (x : F F.M) :
                                    (PFunctor.M.mk x).dest = x
                                    @[simp]
                                    theorem PFunctor.M.mk_dest {F : PFunctor.{u}} (x : F.M) :
                                    PFunctor.M.mk x.dest = x
                                    theorem PFunctor.M.mk_inj {F : PFunctor.{u}} {x y : F F.M} (h : PFunctor.M.mk x = PFunctor.M.mk y) :
                                    x = y
                                    def PFunctor.M.cases {F : PFunctor.{u}} {r : F.MSort w} (f : (x : F F.M) → r (PFunctor.M.mk x)) (x : F.M) :
                                    r x

                                    destructor for M-types

                                    Equations
                                    Instances For
                                      def PFunctor.M.casesOn {F : PFunctor.{u}} {r : F.MSort w} (x : F.M) (f : (x : F F.M) → r (PFunctor.M.mk x)) :
                                      r x

                                      destructor for M-types

                                      Equations
                                      Instances For
                                        def PFunctor.M.casesOn' {F : PFunctor.{u}} {r : F.MSort w} (x : F.M) (f : (a : F.A) → (f : F.B aF.M) → r (PFunctor.M.mk a, f)) :
                                        r x

                                        destructor for M-types, similar to casesOn but also gives access directly to the root and subtrees on an M-type

                                        Equations
                                        • x.casesOn' f = x.casesOn fun (x : F F.M) => match x with | a, g => f a g
                                        Instances For
                                          theorem PFunctor.M.approx_mk {F : PFunctor.{u}} (a : F.A) (f : F.B aF.M) (i : ) :
                                          (PFunctor.M.mk a, f).approx i.succ = PFunctor.Approx.CofixA.intro a fun (j : F.B a) => (f j).approx i
                                          @[simp]
                                          theorem PFunctor.M.agree'_refl {F : PFunctor.{u}} {n : } (x : F.M) :
                                          theorem PFunctor.M.agree_iff_agree' {F : PFunctor.{u}} {n : } (x y : F.M) :
                                          PFunctor.Approx.Agree (x.approx n) (y.approx (n + 1)) PFunctor.M.Agree' n x y
                                          @[simp]
                                          theorem PFunctor.M.cases_mk {F : PFunctor.{u}} {r : F.MSort u_2} (x : F F.M) (f : (x : F F.M) → r (PFunctor.M.mk x)) :
                                          @[simp]
                                          theorem PFunctor.M.casesOn_mk {F : PFunctor.{u}} {r : F.MSort u_2} (x : F F.M) (f : (x : F F.M) → r (PFunctor.M.mk x)) :
                                          (PFunctor.M.mk x).casesOn f = f x
                                          @[simp]
                                          theorem PFunctor.M.casesOn_mk' {F : PFunctor.{u}} {r : F.MSort u_2} {a : F.A} (x : F.B aF.M) (f : (a : F.A) → (f : F.B aF.M) → r (PFunctor.M.mk a, f)) :
                                          (PFunctor.M.mk a, x).casesOn' f = f a x

                                          IsPath p x tells us if p is a valid path through x

                                          Instances For
                                            theorem PFunctor.M.isPath_cons {F : PFunctor.{u}} {xs : PFunctor.Approx.Path F} {a a' : F.A} {f : F.B aF.M} {i : F.B a'} :
                                            PFunctor.M.IsPath (a', i :: xs) (PFunctor.M.mk a, f)a = a'
                                            theorem PFunctor.M.isPath_cons' {F : PFunctor.{u}} {xs : PFunctor.Approx.Path F} {a : F.A} {f : F.B aF.M} {i : F.B a} :
                                            PFunctor.M.IsPath (a, i :: xs) (PFunctor.M.mk a, f)PFunctor.M.IsPath xs (f i)

                                            follow a path through a value of M F and return the subtree found at the end of the path if it is a valid path for that value and return a default tree

                                            Equations
                                            Instances For
                                              def PFunctor.M.iselect {F : PFunctor.{u}} [DecidableEq F.A] [Inhabited F.M] (ps : PFunctor.Approx.Path F) :
                                              F.MF.A

                                              similar to isubtree but returns the data at the end of the path instead of the whole subtree

                                              Equations
                                              Instances For
                                                @[simp]
                                                theorem PFunctor.M.head_mk {F : PFunctor.{u}} (x : F F.M) :
                                                (PFunctor.M.mk x).head = x.fst
                                                theorem PFunctor.M.children_mk {F : PFunctor.{u}} {a : F.A} (x : F.B aF.M) (i : F.B (PFunctor.M.mk a, x).head) :
                                                (PFunctor.M.mk a, x).children i = x (cast i)
                                                @[simp]
                                                theorem PFunctor.M.ichildren_mk {F : PFunctor.{u}} [DecidableEq F.A] [Inhabited F.M] (x : F F.M) (i : F.Idx) :
                                                @[simp]
                                                theorem PFunctor.M.isubtree_cons {F : PFunctor.{u}} [DecidableEq F.A] [Inhabited F.M] (ps : PFunctor.Approx.Path F) {a : F.A} (f : F.B aF.M) {i : F.B a} :
                                                PFunctor.M.isubtree (a, i :: ps) (PFunctor.M.mk a, f) = PFunctor.M.isubtree ps (f i)
                                                @[simp]
                                                theorem PFunctor.M.iselect_nil {F : PFunctor.{u}} [DecidableEq F.A] [Inhabited F.M] {a : F.A} (f : F.B aF.M) :
                                                @[simp]
                                                theorem PFunctor.M.iselect_cons {F : PFunctor.{u}} [DecidableEq F.A] [Inhabited F.M] (ps : PFunctor.Approx.Path F) {a : F.A} (f : F.B aF.M) {i : F.B a} :
                                                PFunctor.M.iselect (a, i :: ps) (PFunctor.M.mk a, f) = PFunctor.M.iselect ps (f i)
                                                theorem PFunctor.M.corec_def {F : PFunctor.{u}} {X : Type u_2} (f : XF X) (x₀ : X) :
                                                PFunctor.M.corec f x₀ = PFunctor.M.mk (F.map (PFunctor.M.corec f) (f x₀))
                                                theorem PFunctor.M.ext_aux {F : PFunctor.{u}} [Inhabited F.M] [DecidableEq F.A] {n : } (x y z : F.M) (hx : PFunctor.M.Agree' n z x) (hy : PFunctor.M.Agree' n z y) (hrec : ∀ (ps : PFunctor.Approx.Path F), n = List.length psPFunctor.M.iselect ps x = PFunctor.M.iselect ps y) :
                                                x.approx (n + 1) = y.approx (n + 1)
                                                theorem PFunctor.M.ext {F : PFunctor.{u}} [Inhabited F.M] (x y : F.M) (H : ∀ (ps : PFunctor.Approx.Path F), PFunctor.M.iselect ps x = PFunctor.M.iselect ps y) :
                                                x = y
                                                structure PFunctor.M.IsBisimulation {F : PFunctor.{u}} (R : F.MF.MProp) :

                                                Bisimulation is the standard proof technique for equality between infinite tree-like structures

                                                • head {a a' : F.A} {f : F.B aF.M} {f' : F.B a'F.M} : R (PFunctor.M.mk a, f) (PFunctor.M.mk a', f')a = a'

                                                  The head of the trees are equal

                                                • tail {a : F.A} {f f' : F.B aF.M} : R (PFunctor.M.mk a, f) (PFunctor.M.mk a, f')∀ (i : F.B a), R (f i) (f' i)

                                                  The tails are equal

                                                Instances For
                                                  theorem PFunctor.M.nth_of_bisim {F : PFunctor.{u}} (R : F.MF.MProp) [Inhabited F.M] (bisim : PFunctor.M.IsBisimulation R) (s₁ s₂ : F.M) (ps : PFunctor.Approx.Path F) :
                                                  R s₁ s₂PFunctor.M.IsPath ps s₁ PFunctor.M.IsPath ps s₂PFunctor.M.iselect ps s₁ = PFunctor.M.iselect ps s₂ ∃ (a : F.A) (f : F.B aF.M) (f' : F.B aF.M), PFunctor.M.isubtree ps s₁ = PFunctor.M.mk a, f PFunctor.M.isubtree ps s₂ = PFunctor.M.mk a, f' ∀ (i : F.B a), R (f i) (f' i)
                                                  theorem PFunctor.M.eq_of_bisim {F : PFunctor.{u}} (R : F.MF.MProp) [Nonempty F.M] (bisim : PFunctor.M.IsBisimulation R) (s₁ s₂ : F.M) :
                                                  R s₁ s₂s₁ = s₂
                                                  def PFunctor.M.corecOn {F : PFunctor.{u}} {X : Type u_2} (x₀ : X) (f : XF X) :
                                                  F.M

                                                  corecursor for M F with swapped arguments

                                                  Equations
                                                  Instances For
                                                    theorem PFunctor.M.dest_corec {P : PFunctor.{u}} {α : Type u_2} (g : αP α) (x : α) :
                                                    (PFunctor.M.corec g x).dest = P.map (PFunctor.M.corec g) (g x)
                                                    theorem PFunctor.M.bisim {P : PFunctor.{u}} (R : P.MP.MProp) (h : ∀ (x y : P.M), R x y∃ (a : P.A) (f : P.B aP.M) (f' : P.B aP.M), x.dest = a, f y.dest = a, f' ∀ (i : P.B a), R (f i) (f' i)) (x y : P.M) :
                                                    R x yx = y
                                                    theorem PFunctor.M.bisim' {P : PFunctor.{u}} {α : Type u_3} (Q : αProp) (u v : αP.M) (h : ∀ (x : α), Q x∃ (a : P.A) (f : P.B aP.M) (f' : P.B aP.M), (u x).dest = a, f (v x).dest = a, f' ∀ (i : P.B a), ∃ (x' : α), Q x' f i = u x' f' i = v x') (x : α) :
                                                    Q xu x = v x
                                                    theorem PFunctor.M.bisim_equiv {P : PFunctor.{u}} (R : P.MP.MProp) (h : ∀ (x y : P.M), R x y∃ (a : P.A) (f : P.B aP.M) (f' : P.B aP.M), x.dest = a, f y.dest = a, f' ∀ (i : P.B a), R (f i) (f' i)) (x y : P.M) :
                                                    R x yx = y
                                                    theorem PFunctor.M.corec_unique {P : PFunctor.{u}} {α : Type u_2} (g : αP α) (f : αP.M) (hyp : ∀ (x : α), (f x).dest = P.map f (g x)) :
                                                    def PFunctor.M.corec₁ {P : PFunctor.{u}} {α : Type u} (F : (X : Type u) → (αX)αP X) :
                                                    αP.M

                                                    corecursor where the state of the computation can be sent downstream in the form of a recursive call

                                                    Equations
                                                    Instances For
                                                      def PFunctor.M.corec' {P : PFunctor.{u}} {α : Type u} (F : {X : Type u} → (αX)αP.M P X) (x : α) :
                                                      P.M

                                                      corecursor where it is possible to return a fully formed value at any point of the computation

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