mathlib documentation

data.pfunctor.multivariate.M

The M construction as a multivariate polynomial functor.

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

Main definitions

Implementation notes

Dual view of M-types:

Specifically, we define the polynomial functor Mp as:

As a result Mp.obj α is made of a dataless tree and a function from its valid paths to values of α

The difference with the polynomial functor of an initial algebra is that A is a possibly infinite tree.

Reference

inductive mvpfunctor.M.path {n : } (P : mvpfunctor (n + 1)) :
P.last.Mfin2 nType u

A path from the root of a tree to one of its node

@[instance]
def mvpfunctor.M.path.inhabited {n : } (P : mvpfunctor (n + 1)) (x : P.last.M) {i : fin2 n} [inhabited (P.drop.B x.head i)] :

Equations
def mvpfunctor.Mp {n : } :
mvpfunctor (n + 1)mvpfunctor n

Polynomial functor of the M-type of P. A is a data-less possibly infinite tree whereas, for a given a : A, B a is a valid path in tree a so that Wp.obj α is made of a tree and a function from its valid paths to the values it contains

Equations
def mvpfunctor.M {n : } :
mvpfunctor (n + 1)typevec nType u

n-ary M-type for P

Equations
@[instance]
def mvpfunctor.mvfunctor_M {n : } (P : mvpfunctor (n + 1)) :

Equations
@[instance]
def mvpfunctor.inhabited_M {n : } (P : mvpfunctor (n + 1)) {α : typevec n} [I : inhabited P.A] [Π (i : fin2 n), inhabited (α i)] :
inhabited (P.M α)

Equations
def mvpfunctor.M.corec_shape {n : } (P : mvpfunctor (n + 1)) {β : Type u} (g₀ : β → P.A) :
(Π (b : β), P.last.B (g₀ b) → β)β → P.last.M

construct through corecursion the shape of an M-type without its contents

Equations
def mvpfunctor.cast_dropB {n : } (P : mvpfunctor (n + 1)) {a a' : P.A} :
a = a'P.drop.B a P.drop.B a'

Proof of type equality as an arrow

Equations
def mvpfunctor.cast_lastB {n : } (P : mvpfunctor (n + 1)) {a a' : P.A} :
a = a'P.last.B aP.last.B a'

Proof of type equality as a function

Equations
def mvpfunctor.M.corec_contents {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {β : Type u} (g₀ : β → P.A) (g₁ : Π (b : β), P.drop.B (g₀ b) α) (g₂ : Π (b : β), P.last.B (g₀ b) → β) (x : P.last.M) (b : β) :
x = mvpfunctor.M.corec_shape P g₀ g₂ bmvpfunctor.M.path P x α

Using corecursion, construct the contents of an M-type

Equations
def mvpfunctor.M.corec' {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {β : Type u} (g₀ : β → P.A) :
(Π (b : β), P.drop.B (g₀ b) α)(Π (b : β), P.last.B (g₀ b) → β)β → P.M α

Corecursor for M-type of P

Equations
def mvpfunctor.M.corec {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {β : Type u} :
(β → P.obj ::: β))β → P.M α

Corecursor for M-type of P

Equations
def mvpfunctor.M.path_dest_left {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M} :
x.dest = a, f⟩mvpfunctor.M.path P x αP.drop.B a α

Implementation of destructor for M-type of P

Equations
def mvpfunctor.M.path_dest_right {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M} (h : x.dest = a, f⟩) (f' : mvpfunctor.M.path P x α) (j : P.last.B a) :

Implementation of destructor for M-type of P

Equations
def mvpfunctor.M.dest' {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M} :
x.dest = a, f⟩mvpfunctor.M.path P x αP.obj ::: P.M α)

Destructor for M-type of P

Equations
def mvpfunctor.M.dest {n : } (P : mvpfunctor (n + 1)) {α : typevec n} :
P.M αP.obj ::: P.M α)

Destructor for M-types

Equations
def mvpfunctor.M.mk {n : } (P : mvpfunctor (n + 1)) {α : typevec n} :
P.obj ::: P.M α)P.M α

Constructor for M-types

Equations
theorem mvpfunctor.M.dest'_eq_dest' {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {x : P.last.M} {a₁ : P.A} {f₁ : P.last.B a₁ → P.last.M} (h₁ : x.dest = a₁, f₁⟩) {a₂ : P.A} {f₂ : P.last.B a₂ → P.last.M} (h₂ : x.dest = a₂, f₂⟩) (f' : mvpfunctor.M.path P x α) :

theorem mvpfunctor.M.dest_eq_dest' {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M} (h : x.dest = a, f⟩) (f' : mvpfunctor.M.path P x α) :

theorem mvpfunctor.M.dest_corec' {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {β : Type u} (g₀ : β → P.A) (g₁ : Π (b : β), P.drop.B (g₀ b) α) (g₂ : Π (b : β), P.last.B (g₀ b) → β) (x : β) :
mvpfunctor.M.dest P (mvpfunctor.M.corec' P g₀ g₁ g₂ x) = g₀ x, typevec.split_fun (g₁ x) (mvpfunctor.M.corec' P g₀ g₁ g₂ g₂ x)

theorem mvpfunctor.M.dest_corec {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {β : Type u} (g : β → P.obj ::: β)) (x : β) :

theorem mvpfunctor.M.bisim_lemma {n : } (P : mvpfunctor (n + 1)) {α : typevec n} {a₁ : P.Mp.A} {f₁ : P.Mp.B a₁ α} {a' : P.A} {f' : (P.B a').drop α} {f₁' : (P.B a').lastP.M α} :
mvpfunctor.M.dest P a₁, f₁⟩ = a', typevec.split_fun f' f₁'(∃ (g₁' : P.last.B a' → P.last.M) (e₁' : pfunctor.M.dest a₁ = a', g₁'⟩), f' = mvpfunctor.M.path_dest_left P e₁' f₁ f₁' = λ (x : P.last.B a'), g₁' x, mvpfunctor.M.path_dest_right P e₁' f₁ x⟩)

theorem mvpfunctor.M.bisim {n : } (P : mvpfunctor (n + 1)) {α : typevec n} (R : P.M αP.M α → Prop) (h : ∀ (x y : P.M α), R x y(∃ (a : P.A) (f : (P.B a).drop ::: P.M α).drop) (f₁ f₂ : (P.B a).last::: P.M α).last), mvpfunctor.M.dest P x = a, typevec.split_fun f f₁ mvpfunctor.M.dest P y = a, typevec.split_fun f f₂ ∀ (i : (P.B a).last), R (f₁ i) (f₂ i))) (x y : P.M α) :
R x yx = y

theorem mvpfunctor.M.bisim₀ {n : } (P : mvpfunctor (n + 1)) {α : typevec n} (R : P.M αP.M α → Prop) (h₀ : equivalence R) (h : ∀ (x y : P.M α), R x y(typevec.id ::: quot.mk R) <$$> mvpfunctor.M.dest P x = (typevec.id ::: quot.mk R) <$$> mvpfunctor.M.dest P y) (x y : P.M α) :
R x yx = y

theorem mvpfunctor.M.bisim' {n : } (P : mvpfunctor (n + 1)) {α : typevec n} (R : P.M αP.M α → Prop) (h : ∀ (x y : P.M α), R x y(typevec.id ::: quot.mk R) <$$> mvpfunctor.M.dest P x = (typevec.id ::: quot.mk R) <$$> mvpfunctor.M.dest P y) (x y : P.M α) :
R x yx = y

theorem mvpfunctor.M.dest_map {n : } (P : mvpfunctor (n + 1)) {α β : typevec n} (g : α β) (x : P.M α) :
mvpfunctor.M.dest P (g <$$> x) = (g ::: λ (x : P.M α), g <$$> x) <$$> mvpfunctor.M.dest P x

theorem mvpfunctor.M.map_dest {n : } (P : mvpfunctor (n + 1)) {α β : typevec n} (g : α ::: P.M α β ::: P.M β) (x : P.M α) :