Non-primitive corecursion for sequences #
Primitive corecursive definition of the form
def foo (x : X) := hd x :: foo (tlArg x)
(where hd and tlArg are arbitrary functions) can be encoded via the corecursor Seq.corec.
It is not enough, however, to define multiplication and powser operation for multiseries.
This file implements a more general form of corecursion in the spirit of [BPT15].
This is a bare minimum that needed for the tactic, it justifies a weaker class of
corecursive definitions than [BPT15] does, and only works for Seq.
A function f : Seq α → Seq α is called friendly if for all n : ℕ the n-prefix of its result
f s depends only on the n-prefix of its input s.
In this file we develop a theory that justifies corecursive definitions of the form
def foo (x : X) := hd x :: f (foo (tlArg x))
where f is friendly.
Main definitions #
FriendlyOperation fmeans thatfis friendly.FriendlyOperationClassis a typeclass meaning that some indexed family of operations are friendly.gcorec: a generalization ofSeq.corecthat allows a corecursive call to be guarded by a friendly function.FriendlyOperation.coind,FriendlyOperation.coind_comp_friend_left,FriendlyOperation.coind_comp_friend_right: coinduction principles for proving that an operation is friendly.FriendlyOperation.eq_of_bisim: a generalisation ofSeq.eq_of_bisim'that allows using a friendly operation in the tail of the sequences.
Implementation details #
To prove that the definition of the form
def foo (x : X) := hd x :: f (foo (tlArg x))
is correct we prove that there exists a function satisfying this equation. For that we employ a
Banach fixed point theorem. We treat Seq α as a metric space here with the metric
d(s, t) := 2 ^ (-n) where n is the minimal index where s and t differ.
Then f is friendly iff it is 1-Lipschitz.
Metric space structure on Stream' α considering α as a discrete metric space.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Metric space structure on Seq α considering α as a discrete metric space.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A function on sequences is called a "friend" if any n-prefix of its output depends only on
the n-prefix of the input. Such functions can be used in the tail of (non-primitive) corecursive
definitions.
Equations
Instances For
A family of friendly operations on sequences indexed by a type γ.
- friend (c : γ) : FriendlyOperation (F c)
Instances
Main theorem of this file. It shows that there exists a function satisfying the corecursive
definition of the form def foo (x : X) := hd x :: op (foo (tlArg x)) where f is friendly.
(General) non-primitive corecursor for Seq α that allows using a friendly operation in the
tail of the corecursive definition.
Equations
Instances For
The operation cons hd · is friendly.
If two sequences have the same head and applying op reduces their distance, then
it also reduces the distance of their tails.
The operation (op (.cons hd ·)).tail is friendly if op is friendly.
The first element of op (a :: s) depends only on a.
Decomposes a friendly operation by the head of the input sequence. Returns none if the output
is nil, or some (out_hd, op') where out_hd is the head of the output and op' is a friendly
operation mapping the tail of the input to the tail of the output. See
destruct_apply_eq_unfold for the correctness statement.
Equations
Instances For
unfold correctly decomposes a friendly operation: the head of op s depends only on the
head of s (and is given by unfold), while the tail of op s is obtained by applying the
friendly operation returned by unfold to the tail of s. This gives a coinductive
characterization of FriendlyOperation. For the coinduction principle, see
FriendlyOperation.coind.
If op is friendly, then op s and op t have the same head if s and t
have the same head.