[Agda] Agda goes coinductive
Dan Doel
dan.doel at gmail.com
Sat Jun 7 08:38:07 CEST 2008
On Friday 06 June 2008, Dan Doel wrote:
> That does work with 'map f (now v) = now (f v)' case, but it seems to cause
> trouble in the other case, and with never. Perhaps I'm just not seeing the
> solution though.
In case anyone's interested in this, after much working, I managed to work out
a strategy that seems to be working. I hope it's all right if I reproduce a
little code, as I rewrote things into a small example from the main file I'm
working in, and things are a bit different:
---- snip ----
module Partial where
codata D (a : Set) : Set where
now : (v : a) -> D a
later : (dv : D a) -> D a
data Converge {a : Set} : D a -> a -> Set where
converge-now : (v : a) -> Converge (now v) v
converge-later : {x : D a} {v : a} -> Converge x v -> Converge (later x) v
codata Diverge {a : Set} : D a -> Set where
diverge : (x : D a) -> Diverge x -> Diverge (later x)
unfold : {a : Set} -> D a -> D a
unfold (now x) = now x
unfold (later dx) = later dx
never : {a : Set} -> D a
never ~ later never
data _==_ {a : Set} (x : a) : a -> Set where
refl : x == x
==-unfold : {a : Set} (x : D a) -> unfold x == x
==-unfold (now v) = refl
==-unfold (later dv) = refl
==-resp : {a : Set}{x y : a} (f : a -> Set) -> x == y -> f x -> f y
==-resp f refl fx = fx
mapD : {a b : Set} -> (a -> b) -> D a -> D b
mapD f (now v) ~ now (f v)
mapD f (later dv) ~ later (mapD f dv)
---- snip ----
so far nothing too special. Now to prove the theorem about map:
---- snip ----
mutual
map-converge₁ : {a b : Set}{x : D a}{v : a}{f : a -> b} ->
Converge x v -> Converge (unfold (mapD f x)) (f v)
map-converge₁ {a}{b}{.(now v)}{v}{f}(converge-now .v) = converge-now (f v)
map-converge₁ (converge-later pf) = converge-later (map-converge pf)
map-converge : {a b : Set}{x : D a}{v : a}{f : a -> b} ->
Converge x v -> Converge (mapD f x) (f v)
map-converge {a}{b}{x}{v}{f} pf = ==-resp
(\t -> Converge t (f v))
(==-unfold (mapD f x))
(map-converge₁ pf)
---- snip ----
So, to prove a theorem, you prove a theorem about an expression containing
unfold, and use the fact that 'unfold x == x' to turn it into the theorem you
actually want (I had tried this before, and thought it didn't work, but I
guess I was doing something wrong).
This approach works for the divergence of never as well:
---- snip ----
mutual
diverge-never₁ : {a : Set} -> Diverge (unfold (never {a}))
diverge-never₁ ~ diverge never diverge-never
diverge-never : {a : Set} -> Diverge (never {a})
diverge-never ~ ==-resp Diverge (==-unfold never) diverge-never₁
---- snip ----
However, this does not pass the productivity checker, so things aren't
necessarily hunky-dory. Hopefully going along this route should allow me to
translate most of the proofs from General Recursion via Coinductive Types,
though (I've a lot of it translated, but struggled near the end, as most
proofs there run into this).
Thanks for your time.
-- Dan
More information about the Agda
mailing list