grisette-0.13.0.1: test/Grisette/Unified/UnifiedClassesTest.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Unused LANGUAGE pragma" #-}
-- {-# OPTIONS_GHC -ddump-splices #-}
module Grisette.Unified.UnifiedClassesTest (unifiedClassesTest) where
import Control.Monad.Except (ExceptT, MonadError (throwError))
import Control.Monad.Identity (Identity (Identity))
import qualified Data.Text as T
import GHC.TypeNats (KnownNat, type (<=))
import Grisette
( Mergeable,
SymBool,
SymEq,
SymInteger,
SymWordN,
Union,
WordN,
deriveWith,
mrgReturn,
symAnd,
)
import qualified Grisette
import Grisette.Internal.TH.Derivation.Common
( DeriveConfig
( bitSizePositions,
evalModeConfig,
needExtraMergeableUnderEvalMode
),
EvalModeConfig (EvalModeConstraints),
)
import Grisette.TestUtil.SymbolicAssertion ((.@?=))
import Grisette.Unified
( BaseMonad,
EvalModeBV,
EvalModeBase,
EvalModeInteger,
GetBool,
GetData,
GetInteger,
GetWordN,
UnifiedBranching,
UnifiedSymEq,
UnifiedSymEq1,
mrgIf,
(.==),
)
import Test.Framework (Test, testGroup)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit ((@?=))
type M mode = ExceptT T.Text (BaseMonad mode)
testBranching ::
forall mode m.
( EvalModeBase mode,
EvalModeInteger mode,
UnifiedBranching mode m,
MonadError T.Text m
) =>
GetInteger mode ->
m (GetInteger mode)
testBranching x =
mrgIf (x .== 1 :: GetBool mode) (return x) (throwError "err")
testBranchingBase ::
forall mode.
(EvalModeBase mode, EvalModeInteger mode) =>
GetInteger mode ->
M mode (GetInteger mode)
testBranchingBase x =
mrgIf (x .== 1 :: GetBool mode) (return x) (throwError "err")
data X mode n f a
= X
(GetBool mode)
[GetWordN mode n]
(GetData mode (X mode n f a))
[GetData mode (X mode n f a)]
a
(f a)
| XNil
#if MIN_VERSION_base(4,16,0)
deriveWith
( mempty
{ evalModeConfig =
[(0, EvalModeConstraints [''EvalModeBV, ''EvalModeBase])],
bitSizePositions = [1],
needExtraMergeableUnderEvalMode = True
}
)
[''X]
[ ''Mergeable,
''Eq,
''SymEq,
''UnifiedSymEq
]
testSEq ::
forall mode n f a.
( EvalModeBase mode,
EvalModeBV mode,
1 <= n,
KnownNat n,
UnifiedSymEq1 mode f,
UnifiedSymEq mode a
) =>
X mode n f a ->
X mode n f a ->
GetBool mode
testSEq = (.==)
unifiedClassesTest :: Test
unifiedClassesTest =
testGroup
"UnifiedClasses"
[ testGroup
"UnifiedBranching"
[ testCase "branchingBase 'Con" $
testBranchingBase (1 :: Integer) @?= return 1,
testCase "branchingBase 'Sym" $ do
let a = "a" :: SymInteger
let expected =
Grisette.mrgIf
(a Grisette..== 1)
(return a)
(throwError "err")
testBranchingBase a .@?= expected,
testCase "branching 'Con" $
testBranching 1 @?= (return 1 :: Either T.Text Integer),
testCase "branching 'Sym" $
testBranching 1 .@?= (return 1 :: ExceptT T.Text Union SymInteger)
],
testGroup
"UnifiedSEq"
[ testCase "testSEq 'Con" $ do
let x1 = X True [1 :: WordN 8] (Identity XNil) [Identity XNil] (1 :: Integer) [1]
let x2 = X False [1 :: WordN 8] (Identity XNil) [Identity XNil] (1 :: Integer) [2]
testSEq x1 x1 .@?= True
testSEq x1 x2 .@?= False,
testCase "testSEq 'Sym" $ do
let x1 =
X
"a"
[1 :: SymWordN 8]
(mrgReturn XNil)
[mrgReturn XNil]
("x" :: SymInteger)
["w"]
let x2 =
X
"b"
[1 :: SymWordN 8]
(mrgReturn XNil)
[mrgReturn XNil]
("y" :: SymInteger)
["z"]
testSEq x1 x2
.@?= symAnd
[ (("a" :: SymBool) .== "b"),
(("x" :: SymInteger) .== "y"),
(("w" :: SymInteger) .== "z")
]
]
]
#else
unifiedClassesTest :: Test
unifiedClassesTest = testGroup "UnifiedClasses" []
#endif