-> y:a -> {z:a
| z = y}! " • No dereference expression (Haskell state is fully monadic) • Haskell code often uses modifyIORef • Observations imply stable refinements • Alternative: Embed Hoare Logic in LH (Hard) 35
Prop, r :: a -> a -> Prop > = Wrap (rgref_ref :: IORef a
) @-}! RGRef a = Wrap (IORef a) ! " {-@ newRGRef :: forall
Prop, r :: a -> a -> Prop >.! e:a
-> ! e2:a -> ! f:(x:a
-> y:a -> {v:a
| (v = y)}) -> IO (RGRef a) @-} ! newRGRef :: a -> a -> (a -> a -> a) -> IO (RGRef a)! newRGRef e e2 stabilityPf = do { r <- newIORef e; return (Wrap r) } ! " {-@ assume readRGRef :: forall
Prop, r :: a -> a -> Prop >. ! x:RGRef a -> IO (a
) @-} ! readRGRef (Wrap x) = readIORef x ! " {-@ assume writeRGRef :: forall
Prop, r :: a -> a -> Prop>. ! x:(RGRef a) -> old:a -> new:a -> IO () @-}! writeRGRef :: RGRef a -> a -> a -> IO () ! writeRGRef (Wrap x) old new = writeIORef x new! " {-@ modifyRGRef :: forall
Prop, r :: a -> a -> Prop >.! rf:(RGRef a) -> ! f:(x:a
-> a) -> ! pf:(x:a
-> y:a -> {v:a
| (v = y)}) -> IO () @-}! modifyRGRef :: RGRef a -> (a -> a) -> (a -> a -> a) -> IO () ! modifyRGRef (Wrap x) f pf = modifyIORef x (\ v -> pf v (f v)) !