The final co-algebra of a multivariate qpf is again a qpf. #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
For a (n+1)
-ary QPF F (α₀,..,αₙ)
, we take the least fixed point of F
with
regards to its last argument αₙ
. The result is a 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
[ACH19] for more details.
Reference #
- Jeremy Avigad, Mario M. Carneiro and Simon Hudon. Data Types as Quotients of Polynomial Functors
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) (λ (x : β), mvqpf.repr (g x))
Characterization of desirable equivalence relations on M-types
Equations
- mvqpf.is_precongr r = ∀ ⦃x y : (mvqpf.P F).M α⦄, r x y → mvqpf.abs (mvfunctor.map (typevec.id ::: quot.mk r) (mvpfunctor.M.dest (mvqpf.P F) x)) = mvqpf.abs (mvfunctor.map (typevec.id ::: quot.mk r) (mvpfunctor.M.dest (mvqpf.P F) y))
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 mvqpf.cofix
Equations
- mvqpf.cofix.inhabited = {default := quot.mk mvqpf.Mcongr inhabited.default}
the map function for the functor cofix F
Equations
- mvqpf.cofix.map g = quot.lift (λ (x : (mvqpf.P F).M α), quot.mk mvqpf.Mcongr (mvfunctor.map g x)) _
Equations
Corecursor for cofix F
Equations
- mvqpf.cofix.corec g = λ (x : β), quot.mk mvqpf.Mcongr (mvqpf.corecF g x)
Destructor for cofix F
Equations
- mvqpf.cofix.dest = quot.lift (λ (x : (mvqpf.P F).M α), mvfunctor.map (typevec.id ::: quot.mk mvqpf.Mcongr) (mvqpf.abs (mvpfunctor.M.dest (mvqpf.P F) x))) mvqpf.cofix.dest._proof_1
Abstraction function for cofix F α
Equations
- mvqpf.cofix.abs = quot.mk mvqpf.Mcongr
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 = let f : (α ::: mvqpf.cofix F α).arrow (α ::: (mvqpf.cofix F α ⊕ β)) := typevec.id ::: sum.inl in mvqpf.cofix.corec (sum.elim (mvfunctor.map f ∘ mvqpf.cofix.dest) g) (sum.inr x)
Corecursor for cofix F
. The shape allows recursive calls to
look like recursive calls.
Equations
- mvqpf.cofix.corec₁ g x = mvqpf.cofix.corec' (λ (x : β), g sum.inl sum.inr x) x
constructor for cofix F
Equations
- mvqpf.cofix.mk = mvqpf.cofix.corec (λ (x : F (α ::: mvqpf.cofix F α)), mvfunctor.map (typevec.id ::: λ (i : mvqpf.cofix F α), i.dest) x)
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.
Equations
- mvqpf.mvqpf_cofix = {P := (mvqpf.P F).Mp, abs := λ (α : typevec n), quot.mk mvqpf.Mcongr, repr := λ (α : typevec n), mvqpf.cofix.repr, abs_repr := _, abs_map := _}