[Agda] generative thunk?
Conor McBride
conor at strictlypositive.org
Thu Dec 30 13:13:52 CET 2010
Folks
Just to finish the thought.
Here's that wrong'un (already copied to the tracker).
On 30 Dec 2010, at 11:43, I wrote:
> The obvious expedient of defining one copy of thunk
> and using it instead falls foul of the termination checker: if I'm
> lucky, it
> just moans in the usual miserable way, forcing me to expand
> definitions I'd
> rather keep tidy. I have an unlucky example which I'm trying to cut
> to the
> minimum, but it locks my emacs every time.
Note that I have been able to work around this problem, but the
resulting code is unreadable.
All the best
Conor
{-# OPTIONS --universe-polymorphism #-}
module DThunk where
{- This file causes hanging. The trouble is not clear. -}
import Level
------------------------------------------------------------------------
-- A type used to make recursive arguments coinductive
postulate
Lazy : forall {a} (A : Set a) -> Set a
thunk : forall {a} {A : Set a} -> A -> Lazy A
force : forall {a} {A : Set a} -> Lazy A -> A
{-# BUILTIN INFINITY Lazy #-}
{-# BUILTIN SHARP thunk #-}
{-# BUILTIN FLAT force #-}
data Protocol : Set1 where
D : Lazy Protocol -> Protocol
PI SG : (S : Set)(T : S -> Protocol) -> Protocol
_*_ : Protocol -> Protocol -> Protocol
{- I made this definition because it's the "tomorrow idiom",
accidentally hiding a generative thunk. -}
!> : Protocol -> Protocol
!> P = D (thunk P)
record One : Set where constructor <>
record Sg (S : Set)(T : S -> Set) : Set where
constructor _,_
field
fst : S
snd : T fst
open Sg public
Step : (Protocol -> Set) -> Protocol -> Set
Step F (D P) = F (force P)
Step F (PI S T) = (s : S) -> Step F (T s)
Step F (SG S T) = Sg S \ s -> Step F (T s)
Step F (P * Q) = Sg (Step F P) \ _ -> Step F Q
Now : Protocol -> Set
Now P = Step (\ _ -> One) P
Anon : (P : Protocol) -> Now P -> Protocol
Anon (D P) _ = force P
Anon (PI S T) f = PI S \ s -> Anon (T s) (f s)
Anon (SG S T) p = Anon (T (fst p)) (snd p)
Anon (P * Q) pq = Anon P (fst pq) * Anon Q (snd pq)
data [_] (P : Protocol) : Set where
_,_ : (p : Now P)(ps : Lazy [ Anon P p ]) -> [ P ]
now : {P : Protocol} -> [ P ] -> Now P
now (n , p') = n
anon : {P : Protocol}(p : [ P ]) -> Lazy [ Anon P (now p) ]
anon (n , p') = p'
{- Here's the problem setup. I used !> rather than D (thunk ..) in
the definition of the time-sliced function space. -}
_-o_ : Protocol -> Protocol -> Protocol
P -o Q = SG (Now P -> Now Q) \ f ->
!> (PI (Now P) \ p -> Anon P p -o Anon Q (f p))
_/_ : forall {S T} -> [ PI S T ] -> (s : S) -> [ T s ]
f / s = now f s , thunk (force (anon f) / s )
pi1 : forall {S T} -> [ SG S T ] -> S
pi1 p = fst (now p)
{- Now, including the following definition makes something hang
rather nastily. If you comment out the following, the checker
does respond, and it complains that -o is not productive, as
it won't look through the definition of !> -}
{--}
_$_ : {P Q : Protocol} -> [ P -o Q ] -> [ P ] -> [ Q ]
_$_ {P}{Q} f p =
pi1 f (now p) , thunk ((force (anon f) / now p) $ force (anon p))
{--}
{- If you expand !> as D (thunk ..), invoking more generativity,
the file checks ok. -}
More information about the Agda
mailing list