{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-cse -fno-full-laziness #-}
module Test.ChasingBottoms.IsBottom
( isBottom
, isBottomIO
, bottom
, nonBottomError
, isBottomTimeOut
, isBottomTimeOutIO
) where
import Prelude hiding (catch)
import qualified Control.Exception as E
import System.IO.Unsafe (unsafePerformIO)
import qualified Test.ChasingBottoms.TimeOut as T
isBottom :: a -> Bool
isBottom :: forall a. a -> Bool
isBottom = Maybe Int -> a -> Bool
forall a. Maybe Int -> a -> Bool
isBottomTimeOut Maybe Int
forall a. Maybe a
Nothing
bottom :: a
bottom :: forall a. a
bottom = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"_|_"
nonBottomError :: String -> a
nonBottomError :: forall a. [Char] -> a
nonBottomError = AssertionFailed -> a
forall a e. Exception e => e -> a
E.throw (AssertionFailed -> a)
-> ([Char] -> AssertionFailed) -> [Char] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> AssertionFailed
E.AssertionFailed
{-# NOINLINE isBottomTimeOut #-}
isBottomTimeOut :: Maybe Int -> a -> Bool
isBottomTimeOut :: forall a. Maybe Int -> a -> Bool
isBottomTimeOut Maybe Int
timeOutLimit a
f =
IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Maybe Int -> a -> IO Bool
forall a. Maybe Int -> a -> IO Bool
isBottomTimeOutIO Maybe Int
timeOutLimit a
f
isBottomIO :: a -> IO Bool
isBottomIO :: forall a. a -> IO Bool
isBottomIO = Maybe Int -> a -> IO Bool
forall a. Maybe Int -> a -> IO Bool
isBottomTimeOutIO Maybe Int
forall a. Maybe a
Nothing
isBottomTimeOutIO :: Maybe Int -> a -> IO Bool
isBottomTimeOutIO :: forall a. Maybe Int -> a -> IO Bool
isBottomTimeOutIO Maybe Int
timeOutLimit a
f =
IO a -> IO Bool
forall {a}. IO a -> IO Bool
maybeTimeOut (a -> IO a
forall a. a -> IO a
E.evaluate a
f) IO Bool -> [Handler Bool] -> IO Bool
forall a. IO a -> [Handler a] -> IO a
`E.catches`
[ (ArrayException -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(ArrayException
_ :: E.ArrayException) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (ErrorCall -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(ErrorCall
_ :: E.ErrorCall) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (NoMethodError -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(NoMethodError
_ :: E.NoMethodError) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (NonTermination -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(NonTermination
_ :: E.NonTermination) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (PatternMatchFail -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(PatternMatchFail
_ :: E.PatternMatchFail) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (RecConError -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(RecConError
_ :: E.RecConError) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (RecSelError -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(RecSelError
_ :: E.RecSelError) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
, (RecUpdError -> IO Bool) -> Handler Bool
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler (\(RecUpdError
_ :: E.RecUpdError) -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
]
where
maybeTimeOut :: IO a -> IO Bool
maybeTimeOut IO a
io = case Maybe Int
timeOutLimit of
Maybe Int
Nothing -> do
IO a
io
Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Just Int
lim -> do
Result a
result <- Int -> IO a -> IO (Result a)
forall a. Int -> IO a -> IO (Result a)
T.timeOut Int
lim IO a
io
case Result a
result of
T.Value a
_ -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Result a
T.NonTermination -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
T.Exception SomeException
e -> SomeException -> IO Bool
forall a e. Exception e => e -> a
E.throw SomeException
e