File: Mathlib/Data/PFunctor/Multivariate/M.lean

full_name: MvPFunctor.M.Path
code: /-- A path from the root of a tree to one of its node -/
inductive M.Path : P.last.M → Fin2 n → Type u
  | root  (x : P.last.M)
          (a : P.A)
          (f : P.last.B a → P.last.M)
          (h : PFunctor.M.dest x = ⟨a, f⟩)
          (i : Fin2 n)
          (c : P.drop.B a i) : M.Path x i
  | child (x : P.last.M)
          (a : P.A)
          (f : P.last.B a → P.last.M)
          (h : PFunctor.M.dest x = ⟨a, f⟩)
          (j : P.last.B a)
          (i : Fin2 n)
          (c : M.Path (f j) i) : M.Path x i
goal: P.last.M → Fin2 n → Type u

full_name: MvPFunctor.M.Path.child
code: /-- A path from the root of a tree to one of its node -/
inductive M.Path : P.last.M → Fin2 n → Type u
  | root  (x : P.last.M)
          (a : P.A)
          (f : P.last.B a → P.last.M)
          (h : PFunctor.M.dest x = ⟨a, f⟩)
          (i : Fin2 n)
          (c : P.drop.B a i) : M.Path x i
  | child (x : P.last.M)
          (a : P.A)
          (f : P.last.B a → P.last.M)
          (h : PFunctor.M.dest x = ⟨a, f⟩)
          (j : P.last.B a)
          (i : Fin2 n)
          (c : M.Path (f j) i) : M.Path x i
goal: MvPFunctor.M.Path P x i

full_name: MvPFunctor.M.Path.root
code: /-- A path from the root of a tree to one of its node -/
inductive M.Path : P.last.M → Fin2 n → Type u
  | root  (x : P.last.M)
          (a : P.A)
          (f : P.last.B a → P.last.M)
          (h : PFunctor.M.dest x = ⟨a, f⟩)
          (i : Fin2 n)
          (c : P.drop.B a i) : M.Path x i
  | child (x : P.last.M)
          (a : P.A)
          (f : P.last.B a → P.last.M)
          (h : PFunctor.M.dest x = ⟨a, f⟩)
          (j : P.last.B a)
          (i : Fin2 n)
          (c : M.Path (f j) i) : M.Path x i
goal: MvPFunctor.M.Path P x i

full_name: MvPFunctor.M.Path.inhabited
code: instance M.Path.inhabited (x : P.last.M) {i} [Inhabited (P.drop.B x.head i)] :
    Inhabited (M.Path P x i) 
goal: Inhabited (MvPFunctor.M.Path P x i)

full_name: MvPFunctor.mp
code: /-- 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 `mp α` is made of a tree and a function
from its valid paths to the values it contains -/
def mp : MvPFunctor n 
goal: MvPFunctor.{u} n

full_name: MvPFunctor.M
code: /-- `n`-ary M-type for `P` -/
def M (α : TypeVec n) : Type _ 
goal: Type u

full_name: MvPFunctor.mvfunctorM
code: instance mvfunctorM : MvFunctor P.M 
goal: MvFunctor P.M

full_name: MvPFunctor.inhabitedM
code: instance inhabitedM {α : TypeVec _} [I : Inhabited P.A] [∀ i : Fin2 n, Inhabited (α i)] :
    Inhabited (P.M α) 
goal: Inhabited (P.M α)

full_name: MvPFunctor.M.corecShape
code: /-- construct through corecursion the shape of an M-type
without its contents -/
def M.corecShape {β : Type u} (g₀ : β → P.A) (g₂ : ∀ b : β, P.last.B (g₀ b) → β) :
    β → P.last.M 
goal: β → P.last.M

full_name: MvPFunctor.castDropB
code: /-- Proof of type equality as an arrow -/
def castDropB {a a' : P.A} (h : a = a') : P.drop.B a ⟹ P.drop.B a' 
goal: P.drop.B a ⟹ P.drop.B a'

full_name: MvPFunctor.castLastB
code: /-- Proof of type equality as a function -/
def castLastB {a a' : P.A} (h : a = a') : P.last.B a → P.last.B a' 
goal: P.last.B a → P.last.B a'

full_name: MvPFunctor.M.corecContents
code: /-- Using corecursion, construct the contents of an M-type -/
def M.corecContents {α : TypeVec.{u} n}
    {β : Type u}
    (g₀ : β → P.A)
    (g₁ : ∀ b : β, P.drop.B (g₀ b) ⟹ α)
    (g₂ : ∀ b : β, P.last.B (g₀ b) → β)
    (x : _)
    (b : β)
    (h : x = M.corecShape P g₀ g₂ b) :
    M.Path P x ⟹ α
  
goal: MvPFunctor.M.Path P x ⟹ α

full_name: MvPFunctor.M.corec'
code: /-- Corecursor for M-type of `P` -/
def M.corec' {α : TypeVec n} {β : Type u} (g₀ : β → P.A) (g₁ : ∀ b : β, P.drop.B (g₀ b) ⟹ α)
    (g₂ : ∀ b : β, P.last.B (g₀ b) → β) : β → P.M α 
goal: β → P.M α

full_name: MvPFunctor.M.corec
code: /-- Corecursor for M-type of `P` -/
def M.corec {α : TypeVec n} {β : Type u} (g : β → P (α.append1 β)) : β → P.M α 
goal: β → P.M α

full_name: MvPFunctor.M.pathDestLeft
code: /-- Implementation of destructor for M-type of `P` -/
def M.pathDestLeft {α : TypeVec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M}
    (h : PFunctor.M.dest x = ⟨a, f⟩) (f' : M.Path P x ⟹ α) : P.drop.B a ⟹ α 
goal: P.drop.B a ⟹ α

full_name: MvPFunctor.M.pathDestRight
code: /-- Implementation of destructor for M-type of `P` -/
def M.pathDestRight {α : TypeVec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M}
    (h : PFunctor.M.dest x = ⟨a, f⟩) (f' : M.Path P x ⟹ α) :
    ∀ j : P.last.B a, M.Path P (f j) ⟹ α 
goal: MvPFunctor.M.Path P (f j) ⟹ α

full_name: MvPFunctor.M.dest'
code: /-- Destructor for M-type of `P` -/
def M.dest' {α : TypeVec n} {x : P.last.M} {a : P.A} {f : P.last.B a → P.last.M}
    (h : PFunctor.M.dest x = ⟨a, f⟩) (f' : M.Path P x ⟹ α) : P (α.append1 (P.M α)) 
goal: ↑P (α ::: P.M α)

full_name: MvPFunctor.M.dest
code: /-- Destructor for M-types -/
def M.dest {α : TypeVec n} (x : P.M α) : P (α ::: P.M α) 
goal: ↑P (α ::: P.M α)

full_name: MvPFunctor.M.mk
code: /-- Constructor for M-types -/
def M.mk {α : TypeVec n} : P (α.append1 (P.M α)) → P.M α 
goal: ↑P (α ::: P.M α) → P.M α

full_name: MvPFunctor.M.dest'_eq_dest'
code: theorem M.dest'_eq_dest' {α : TypeVec n} {x : P.last.M} {a₁ : P.A}
    {f₁ : P.last.B a₁ → P.last.M} (h₁ : PFunctor.M.dest x = ⟨a₁, f₁⟩) {a₂ : P.A}
    {f₂ : P.last.B a₂ → P.last.M} (h₂ : PFunctor.M.dest x = ⟨a₂, f₂⟩) (f' : M.Path P x ⟹ α) :
    M.dest' P h₁ f' = M.dest' P h₂ f' 
goal: MvPFunctor.M.dest' P h₁ f' = MvPFunctor.M.dest' P h₂ f'

full_name: MvPFunctor.M.dest_eq_dest'
code: theorem M.dest_eq_dest' {α : TypeVec n} {x : P.last.M} {a : P.A}
    {f : P.last.B a → P.last.M} (h : PFunctor.M.dest x = ⟨a, f⟩) (f' : M.Path P x ⟹ α) :
    M.dest P ⟨x, f'⟩ = M.dest' P h f' 
goal: MvPFunctor.M.dest P ⟨x, f'⟩ = MvPFunctor.M.dest' P h f'

full_name: MvPFunctor.M.dest_corec'
code: theorem M.dest_corec' {α : TypeVec.{u} n} {β : Type u} (g₀ : β → P.A)
    (g₁ : ∀ b : β, P.drop.B (g₀ b) ⟹ α) (g₂ : ∀ b : β, P.last.B (g₀ b) → β) (x : β) :
    M.dest P (M.corec' P g₀ g₁ g₂ x) = ⟨g₀ x, splitFun (g₁ x) (M.corec' P g₀ g₁ g₂ ∘ g₂ x)⟩ 
goal: MvPFunctor.M.dest P (MvPFunctor.M.corec' P g₀ g₁ g₂ x) =
  ⟨g₀ x, TypeVec.splitFun (g₁ x) (MvPFunctor.M.corec' P g₀ g₁ g₂ ∘ g₂ x)⟩

full_name: MvPFunctor.M.dest_corec
code: theorem M.dest_corec {α : TypeVec n} {β : Type u} (g : β → P (α.append1 β)) (x : β) :
    M.dest P (M.corec P g x) = appendFun id (M.corec P g) <$$> g x 
goal: MvPFunctor.M.dest P (MvPFunctor.M.corec P g x) = (TypeVec.id ::: MvPFunctor.M.corec P g) <$$> g x

full_name: MvPFunctor.M.bisim_lemma
code: theorem M.bisim_lemma {α : TypeVec n} {a₁ : (mp P).A} {f₁ : (mp P).B a₁ ⟹ α} {a' : P.A}
    {f' : (P.B a').drop ⟹ α} {f₁' : (P.B a').last → M P α}
    (e₁ : M.dest P ⟨a₁, f₁⟩ = ⟨a', splitFun f' f₁'⟩) :
    ∃ (g₁' : _)(e₁' : PFunctor.M.dest a₁ = ⟨a', g₁'⟩),
      f' = M.pathDestLeft P e₁' f₁ ∧
        f₁' = fun x : (last P).B a' => ⟨g₁' x, M.pathDestRight P e₁' f₁ x⟩ 
goal: ∃ g₁',
  ∃ (e₁' : PFunctor.M.dest a₁ = ⟨a', g₁'⟩),
    f' = MvPFunctor.M.pathDestLeft P e₁' f₁ ∧ f₁' = fun x => ⟨g₁' x, MvPFunctor.M.pathDestRight P e₁' f₁ x⟩

full_name: MvPFunctor.M.bisim
code: theorem M.bisim {α : TypeVec n} (R : P.M α → P.M α → Prop)
    (h :
      ∀ x y,
        R x y →
          ∃ a f f₁ f₂,
            M.dest P x = ⟨a, splitFun f f₁⟩ ∧
              M.dest P y = ⟨a, splitFun f f₂⟩ ∧ ∀ i, R (f₁ i) (f₂ i))
    (x y) (r : R x y) : x = y 
goal: x = y

full_name: MvPFunctor.M.bisim₀
code: theorem M.bisim₀ {α : TypeVec n} (R : P.M α → P.M α → Prop) (h₀ : Equivalence R)
    (h : ∀ x y, R x y → (id ::: Quot.mk R) <$$> M.dest _ x = (id ::: Quot.mk R) <$$> M.dest _ y)
    (x y) (r : R x y) : x = y 
goal: x = y

full_name: MvPFunctor.M.bisim'
code: theorem M.bisim' {α : TypeVec n} (R : P.M α → P.M α → Prop)
    (h : ∀ x y, R x y → (id ::: Quot.mk R) <$$> M.dest _ x = (id ::: Quot.mk R) <$$> M.dest _ y)
    (x y) (r : R x y) : x = y 
goal: x = y

full_name: MvPFunctor.M.dest_map
code: theorem M.dest_map {α β : TypeVec n} (g : α ⟹ β) (x : P.M α) :
    M.dest P (g <$$> x) = (appendFun g fun x => g <$$> x) <$$> M.dest P x 
goal: MvPFunctor.M.dest P (g <$$> x) = (g ::: fun x => g <$$> x) <$$> MvPFunctor.M.dest P x

full_name: MvPFunctor.M.map_dest
code: theorem M.map_dest {α β : TypeVec n} (g : (α ::: P.M α) ⟹ (β ::: P.M β)) (x : P.M α)
    (h : ∀ x : P.M α, lastFun g x = (dropFun g <$$> x : P.M β)) :
    g <$$> M.dest P x = M.dest P (dropFun g <$$> x) 
goal: g <$$> MvPFunctor.M.dest P x = MvPFunctor.M.dest P (TypeVec.dropFun g <$$> x)