module Proof.Util(module Proof.Util) where
import System.IO.Unsafe
import System.Environment
import Control.DeepSeq
rnf2 a b = rnf a `seq` rnf b
rnf3 a b c = rnf a `seq` rnf b `seq` rnf c
rnf4 a b c d = rnf a `seq` rnf b `seq` rnf c `seq` rnf d
rnf5 a b c d e = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e
headNote note (x:xs) = x
headNote note [] = error $ "headNote on [], " ++ note
fast = "--fast" `elem` unsafePerformIO getArgs
idempotent :: (Show a, Eq a) => String -> (a -> a) -> (a -> a)
idempotent name f x0
| fast = x1
| x1 == x2 = x1
| otherwise = error $ unlines
["START Idempotent check failed for " ++ name ++ "!"
,"Input:"
,show x0
,"After first application:"
,show x1
,"After second application:"
,show x2
,"END Idempotent check failed for " ++ name ++ "!"
]
where x1 = f x0
x2 = f x1
equivalentOn :: (Show a, Show b, Eq b) => (a -> b) -> String -> a -> a -> a
equivalentOn op name x y
| fast = y
| xx == yy = y
| otherwise = unsafePerformIO $ do
writeFile "error.log" $ "-- Equivalent check failed for " ++ name ++ "\n" ++ show x
error $ unlines
["START Equivalent check failed for " ++ name ++ "!"
,"Input:"
,show x
,"Output:"
,show y
,"Input (reduced):"
,show xx
,"Output (reduced):"
,show yy
,"END Equivalent check failed for " ++ name ++ "!"
]
where xx = op x
yy = op y
simpleReadsPrec :: (String -> a) -> (Int -> ReadS a)
simpleReadsPrec f _ s = [(f s, "")]