The final co-algebra of a multivariate qpf is again a qpf. #
For a (n+1)
-ary QPF F (α₀,..,αₙ)
, we take the least fixed point of F
with
regards to its last argument αₙ
. The result is an n
-ary functor: Fix F (α₀,..,αₙ₋₁)
.
Making Fix F
into a functor allows us to take the fixed point, compose with other functors
and take a fixed point again.
Main definitions #
Cofix.mk
- constructorCofix.dest
- destructorCofix.corec
- corecursor: useful for formulating infinite, productive computationsCofix.bisim
- bisimulation: proof technique to show the equality of possibly infinite values ofCofix F α
Implementation notes #
For F
a QPF, we define Cofix F α
in terms of the M-type of the polynomial functor P
of F
.
We define the relation Mcongr
and take its quotient as the definition of Cofix F α
.
Mcongr
is taken as the weakest bisimulation on M-type. See
[avigad-carneiro-hudon2019] for more details.
Reference #
- Jeremy Avigad, Mario M. Carneiro and Simon Hudon. [Data Types as Quotients of Polynomial Functors][avigad-carneiro-hudon2019]
corecF
is used as a basis for defining the corecursor of Cofix F α
. corecF
uses corecursion to construct the M-type generated by q.P
and uses function on F
as a corecursive step
Equations
- MvQPF.corecF g = MvPFunctor.M.corec (MvQPF.P F) fun (x : β) => MvQPF.repr (g x)
Instances For
Characterization of desirable equivalence relations on M-types
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equivalence relation on M-types representing a value of type Cofix F
Equations
- MvQPF.Mcongr x y = ∃ (r : (MvQPF.P F).M α → (MvQPF.P F).M α → Prop), MvQPF.IsPrecongr r ∧ r x y
Instances For
Greatest fixed point of functor F. The result is a functor with one fewer parameters
than the input. For F a b c
a ternary functor, fix F is a binary functor such that
Cofix F a b = F a b (Cofix F a b)
Equations
- MvQPF.Cofix F α = Quot MvQPF.Mcongr
Instances For
maps every element of the W type to a canonical representative
Equations
- MvQPF.mRepr = MvQPF.corecF (MvQPF.abs ∘ MvPFunctor.M.dest (MvQPF.P F))
Instances For
the map function for the functor Cofix F
Equations
- MvQPF.Cofix.map g = Quot.lift (fun (x : (MvQPF.P F).M α) => Quot.mk MvQPF.Mcongr (MvFunctor.map g x)) ⋯
Instances For
Equations
- MvQPF.Cofix.mvfunctor = { map := @MvQPF.Cofix.map n F q }
Corecursor for Cofix F
Equations
- MvQPF.Cofix.corec g x = Quot.mk MvQPF.Mcongr (MvQPF.corecF g x)
Instances For
Destructor for Cofix F
Equations
- MvQPF.Cofix.dest = Quot.lift (fun (x : (MvQPF.P F).M α) => MvFunctor.map (TypeVec.id ::: Quot.mk MvQPF.Mcongr) (MvQPF.abs (MvPFunctor.M.dest (MvQPF.P F) x))) ⋯
Instances For
Abstraction function for cofix F α
Instances For
Representation function for Cofix F α
Equations
- MvQPF.Cofix.repr = MvPFunctor.M.corec (MvQPF.P F) (MvQPF.repr ∘ MvQPF.Cofix.dest)
Instances For
Corecursor for Cofix F
Equations
- MvQPF.Cofix.corec'₁ g x = MvQPF.Cofix.corec (fun (x : β) => g id) x
Instances For
More flexible corecursor for Cofix F
. Allows the return of a fully formed
value instead of making a recursive call
Equations
- MvQPF.Cofix.corec' g x = MvQPF.Cofix.corec (Sum.elim (MvFunctor.map (TypeVec.id ::: Sum.inl) ∘ MvQPF.Cofix.dest) g) (Sum.inr x)
Instances For
Corecursor for Cofix F
. The shape allows recursive calls to
look like recursive calls.
Equations
- MvQPF.Cofix.corec₁ g x = MvQPF.Cofix.corec' (fun (x : β) => g Sum.inl Sum.inr x) x
Instances For
constructor for Cofix F
Equations
- MvQPF.Cofix.mk = MvQPF.Cofix.corec fun (x : F (α ::: MvQPF.Cofix F α)) => MvFunctor.map (TypeVec.id ::: fun (i : MvQPF.Cofix F α) => i.dest) x
Instances For
Bisimulation principles for Cofix F
#
The following theorems are bisimulation principles. The general idea
is to use a bisimulation relation to prove the equality between
specific values of type Cofix F α
.
A bisimulation relation R
for values x y : Cofix F α
:
- holds for
x y
:R x y
- for any values
x y
that satisfyR
, their root has the same shape and their children can be paired in such a way that they satisfyR
.
Bisimulation principle using map
and Quot.mk
to match and relate children of two trees.
Bisimulation principle using LiftR
to match and relate children of two trees.
Bisimulation principle using LiftR'
to match and relate children of two trees.
Bisimulation principle the values ⟨a,f⟩
of the polynomial functor representing
Cofix F α
as well as an invariant Q : β → Prop
and a state β
generating the
left-hand side and right-hand side of the equality through functions u v : β → Cofix F α
liftR_map
, liftR_map_last
and liftR_map_last'
are useful for reasoning about
the induction step in bisimulation proofs.
tactic for proof by bisimulation
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- MvQPF.mvqpfCofix = MvQPF.mk (MvQPF.P F).mp (fun {α : TypeVec.{?u.40} n} => Quot.mk MvQPF.Mcongr) (fun {α : TypeVec.{?u.40} n} => MvQPF.Cofix.repr) ⋯ ⋯