rec-def-0.1: dejafu.hs
import Test.DejaFu
import Control.Concurrent.Classy
import Control.Concurrent.Classy.Async
import qualified Data.Set as S
import System.Random
import Control.Monad
import Test.Tasty
import Test.Tasty.DejaFu
import Data.Recursive.Propagator.Naive
import Data.Recursive.Propagator.P2
import System.IO.RecThunk
t n = testGroup n . pure . testAuto
tr n = testGroup n . pure . testAutoWay (randomly (mkStdGen 0) 1000) defaultMemType
main = defaultMain $ testGroup "tests" $
[ t "prop 1" $ do
p1 <- newProp (S.singleton 1)
readProp p1
, t "prop 2" $ do
p1 <- newProp (S.singleton 1)
p2 <- newProp S.empty
lift1 (S.insert 3) p1 p2
mapConcurrently readProp [p1, p2]
, tr "prop 2 rec" $ withSetup (do
p1 <- newProp S.empty
p2 <- newProp S.empty
pure (p1, p2)) $ \(p1, p2) -> do
mapConcurrently id
[ lift1 (S.insert 3) p1 p2
, lift1 (S.insert 4) p2 p1
]
mapConcurrently readProp [p1, p2]
, tr "prop 2 rec plus" $ withSetup (do
p1 <- newProp S.empty
p2 <- newProp S.empty
p3 <- newProp S.empty
pure (p1, p2, p3)) $ \(p1, p2, p3) -> do
mapConcurrently id
[ lift1 (S.insert 3) p1 p2
, lift1 (S.insert 4) p2 p1
]
mapConcurrently id
[ readProp p1
, readProp p2
, lift1 (S.insert 5) p2 p3 >> readProp p3
]
, tr "prop 3 rec" $ withSetup (do
p1 <- newProp S.empty
p2 <- newProp S.empty
p3 <- newProp S.empty
pure (p1, p2, p3)) $ \(p1, p2, p3) -> do
mapConcurrently id
[ lift1 (S.insert 3) p1 p2
, lift1 (S.insert 4) p2 p1
, lift1 (S.insert 5) p2 p3
]
mapConcurrently readProp [p1, p2, p3]
, tr "prop 3 rec variant" $ withSetup (do
p1 <- newProp S.empty
p2 <- newProp S.empty
p3 <- newProp S.empty
pure (p1, p2, p3)) $ \(p1, p2, p3) -> do
mapConcurrently id
[ lift1 (S.insert 4) p1 p2
, lift1 (S.insert 5) p2 p3
, lift2 (S.union) p2 p3 p1
]
mapConcurrently readProp [p1, p2, p3]
, tr "prop 4 rec" $ withSetup (do
p1 <- newProp S.empty
p2 <- newProp S.empty
p3 <- newProp S.empty
p4 <- newProp S.empty
pure (p1, p2, p3, p4)) $ \(p1, p2, p3, p4) -> do
mapConcurrently id
[ lift1 (S.insert 4) p1 p2
, lift2 (S.union) p1 p2 p3
, liftList (S.unions) [p1,p2,p3] p4
, lift1 (S.insert 5) p4 p1
]
mapConcurrently readProp [p1, p2, p3, p4]
, t "thunk 1" $ do
obs1 <- newIORef 0
t1 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
pure []
force t1
readIORef obs1
, t "thunk 1 rec" $ do
obs1 <- newIORef 0
t1ref <- newIORef undefined
t1 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
t1 <- readIORef t1ref
pure [t1]
writeIORef t1ref t1
force t1
readIORef obs1
, t "thunk 2 rec 12" $ do
obs1 <- newIORef 0
obs2 <- newIORef 0
t2ref <- newIORef undefined
t1 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
t2 <- readIORef t2ref
pure [t2]
t2 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
pure [t1]
writeIORef t2ref t2
mapConcurrently id
[ force t1 >> mapM readIORef [obs1, obs2]
, force t2 >> mapM readIORef [obs1, obs2]
]
, tr "thunk 2 rec 112" $ do
obs1 <- newIORef 0
obs2 <- newIORef 0
t2ref <- newIORef undefined
t1 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
t2 <- readIORef t2ref
pure [t2]
t2 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
pure [t1]
writeIORef t2ref t2
mapConcurrently id
[ force t1 >> mapM readIORef [obs1, obs2]
, force t1 >> mapM readIORef [obs1, obs2]
, force t2 >> mapM readIORef [obs1, obs2]
]
, tr "thunk 2 all-rec 112" $ do
obs1 <- newIORef 0
obs2 <- newIORef 0
t1ref <- newIORef undefined
t2ref <- newIORef undefined
t1 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
t1 <- readIORef t1ref
t2 <- readIORef t2ref
pure [t2,t1]
writeIORef t1ref t1
t2 <- thunk $ do
atomicModifyIORef' obs1 (\x -> (succ x, ()))
t2 <- readIORef t2ref
pure [t1,t2]
writeIORef t2ref t2
mapConcurrently id
[ force t1 >> mapM readIORef [obs1, obs2]
, force t1 >> mapM readIORef [obs1, obs2]
, force t2 >> mapM readIORef [obs1, obs2]
]
, t "P2 1" $ do
p1 <- newP2
False <- isTop p1
setTop p1
True <- isTop p1
pure ()
, t "P2 2" $ do
p1 <- newP2
p2 <- newP2
mapConcurrently id
[ do
False <- isTop p1
setTop p1
True <- isTop p1
pure ()
, do
False <- isTop p2
p1 `implies` p2
]
True <- isTop p2
pure ()
, t "P2 2 rec bottom" $ do
p1 <- newP2
p2 <- newP2
mapConcurrently id
[ p1 `implies` p2
, p2 `implies` p1
]
[False, False] <- mapM isTop [p1,p2]
pure ()
, t "P2 2 rec top" $ do
p1 <- newP2
p2 <- newP2
mapConcurrently id
[ p1 `implies` p2
, p2 `implies` p1
, setTop p1
]
[True, True] <- mapM isTop [p1,p2]
pure ()
]