Derek Elkins wrote:
> On Sat, Oct 16, 2010 at 9:21 PM, Ben Franksen <[email protected]>
> wrote:
>> I have a formal proof where I am stuck at a certain point.
>>
>> Suppose we have a function
>>
>> f :: IORef a -> IO b
>>
>> I want to prove that
>>
>> f r == do
>> s1 <- readIORef r
>> r' <- newIORef s1
>> x <- f r'
>> s3 <- readIORef r'
>> writeIORef r s3
>> return x
>>
>> What happens here is that the temporary IORef r' takes the place of the
>> argument r, and after we apply f to it we take its content and store it
>> in the original r. This should be the same as using r as argument to f in
>> the first place.
>>
>> How can I prove this formally?
>
> You haven't provided us with any information about the formal model
> you are using and your question is somewhat ambiguously phrased, hence
> Thomas' response where, I'm pretty sure, he misunderstood what you
> were asking.
I don't have a model. Up to this point I can make do with equational
reasoning.
This is the context. I have this class
class Embed i o where
type Content i o
embed :: (Content i o -> i a) -> o a
callback :: o a -> Content i o -> i a
which I _think_ should have these laws attached
L1: embed . callback == id
L2: callback . embed == id
and an instance
newtype StateIO s a = StateIO { unStateIO :: StateT s IO a }
instance Embed IO (StateIO s) where
type Content IO (StateIO s) = IORef s
embed f = StateIO $ StateT $ \s -> do
r <- newIORef s
x <- f r
s' <- readIORef r
return (x, s')
callback action r = do
s <- readIORef r
(x, s') <- runStateT (unStateIO action) s
writeIORef r s'
return x
The original idea comes from this message
http://www.haskell.org/pipermail/haskell-cafe/2007-July/028501.html
but I have deviated somewhat from Jules' notation and generalised.
Now I want to prove the laws. L1 is straight forward:
embed (callback o)
= { def embed }
StateIO $ StateT $ \s1 -> do
r <- newIORef s1
x <- callback o r
s4 <- readIORef r
return (x, s4)
= { def callback }
StateIO $ StateT $ \s1 -> do
r <- newIORef s1
x <- do
s2 <- readIORef r
(x, s3) <- runStateT (unStateIO o) s2
writeIORef r s3
return x
s4 <- readIORef r
return (x, s4)
= { Monad laws }
StateIO $ StateT $ \s1 -> do
r <- newIORef s1
s2 <- readIORef r
(x, s3) <- runStateT (unStateIO o) s2
writeIORef r s3
s4 <- readIORef r
return (x, s4)
= { IORef laws }
StateIO $ StateT $ \s1 -> do
r <- newIORef s1
(x, s3) <- runStateT (unStateIO o) s1
writeIORef r s3
return (x, s3)
= { reorder (r is unused in second stmt), Monad laws }
StateIO $ StateT $ \s1 -> do
(x, s3) <- runStateT (unStateIO o) s1
r <- newIORef s1
writeIORef r s3
return (x, s3)
= { IORef laws }
StateIO $ StateT $ \s1 -> do
(x, s3) <- runStateT (unStateIO o) s1
return (x, s3)
= { Monad laws }
StateIO $ StateT $ \s1 -> runStateT (unStateIO o) s1
= {def StateIO, StateT }
o
You might question the step marked { IORef laws }. I don't know if this has
been formalized anywhere but I thought it safe to assume a law that states
do
r <- newIORef a
b <- readIORef r
g b
=
do
r <- newIORef a
g a
assuming that a is not used any further.
Similarly I have used the "law"
do
writeIORef r a
b <- readIORef r
g b
=
do
writeIORef r a
g a
Both of these are so obviously satisfied that I accept them as axioms.
Now, when I try to prove L2, I can reason similarly and get
callback (embed f) r
= { def callback }
do
s1 <- readIORef r
(x, s4) <- runStateT (unStateIO (embed f)) s1
writeIORef r s4
return x
= { def embed }
do
s1 <- readIORef r
(x, s4) <- runStateT (unStateIO $ StateIO $ StateT $ \s2 -> do
r' <- newIORef s2
x <- f r'
s3 <- readIORef r'
return (x, s3)
) s1
writeIORef r s4
return x
= { def StateIO, StateT, beta reduce }
do
s1 <- readIORef r
(x, s4) <- do
r' <- newIORef s1
x <- f r'
s3 <- readIORef r'
return (x, s3)
writeIORef r s4
return x
= { Monad laws }
do
s1 <- readIORef r
r' <- newIORef s1
x <- f r'
s3 <- readIORef r'
writeIORef r s3
return x
= { IORef laws }
do
s1 <- readIORef r
r' <- newIORef s1
x <- f r'
s3 <- readIORef r'
writeIORef r s3
return x
= { ??? }
f r
and I would like to reduce the last step to the same level of "obviosity" as
in the previous proof.
> At any rate, if you intend to prove this for any arbitrary f, I can't
> tell you how to prove it formally because it's not true.
How do you know that? Can you give an example where it fails?
Cheers
Ben
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe