PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Data/SBV/BitVectors/Data.hs

http://github.com/LeventErkok/sbv
Haskell | 542 lines | 285 code | 93 blank | 164 comment | 2 complexity | 517cae82de29b4905a2e55e0ea451f30 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. -----------------------------------------------------------------------------
  2. -- |
  3. -- Module : Data.SBV.BitVectors.Data
  4. -- Copyright : (c) Levent Erkok
  5. -- License : BSD3
  6. -- Maintainer : erkokl@gmail.com
  7. -- Stability : experimental
  8. --
  9. -- Internal data-structures for the sbv library
  10. -----------------------------------------------------------------------------
  11. {-# LANGUAGE TypeSynonymInstances #-}
  12. {-# LANGUAGE TypeOperators #-}
  13. {-# LANGUAGE MultiParamTypeClasses #-}
  14. {-# LANGUAGE ScopedTypeVariables #-}
  15. {-# LANGUAGE FlexibleInstances #-}
  16. {-# LANGUAGE PatternGuards #-}
  17. {-# LANGUAGE DefaultSignatures #-}
  18. {-# LANGUAGE NamedFieldPuns #-}
  19. module Data.SBV.BitVectors.Data
  20. ( SBool, SWord8, SWord16, SWord32, SWord64
  21. , SInt8, SInt16, SInt32, SInt64, SInteger, SReal, SFloat, SDouble
  22. , nan, infinity, sNaN, sInfinity, RoundingMode(..), SRoundingMode
  23. , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero
  24. , sRNE, sRNA, sRTP, sRTN, sRTZ
  25. , SymWord(..)
  26. , CW(..), CWVal(..), AlgReal(..), cwSameType, cwToBool
  27. , mkConstCW ,liftCW2, mapCW, mapCW2
  28. , SW(..), trueSW, falseSW, trueCW, falseCW, normCW
  29. , SVal(..)
  30. , SBV(..), NodeId(..), mkSymSBV
  31. , ArrayContext(..), ArrayInfo, SymArray(..), SFunArray(..), mkSFunArray, SArray(..)
  32. , sbvToSW, sbvToSymSW, forceSWArg
  33. , SBVExpr(..), newExpr
  34. , cache, Cached, uncache, uncacheAI, HasKind(..)
  35. , Op(..), FPOp(..), NamedSymVar, getTableIndex
  36. , SBVPgm(..), Symbolic, SExecutable(..), runSymbolic, runSymbolic', State, getPathCondition, extendPathCondition
  37. , inProofMode, SBVRunMode(..), Kind(..), Outputtable(..), Result(..)
  38. , Logic(..), SMTLibLogic(..)
  39. , addConstraint, internalVariable, internalConstraint, isCodeGenMode
  40. , SBVType(..), newUninterpreted, addAxiom
  41. , Quantifier(..), needsExistentials
  42. , SMTLibPgm(..), SMTLibVersion(..), smtLibVersionExtension, smtLibReservedNames
  43. , SolverCapabilities(..)
  44. , extractSymbolicSimulationState
  45. , SMTScript(..), Solver(..), SMTSolver(..), SMTResult(..), SMTModel(..), SMTConfig(..), getSBranchRunConfig
  46. , declNewSArray, declNewSFunArray
  47. ) where
  48. import Control.DeepSeq (NFData(..))
  49. import Control.Monad.Reader (ask)
  50. import Control.Monad.Trans (liftIO)
  51. import Data.Int (Int8, Int16, Int32, Int64)
  52. import Data.Word (Word8, Word16, Word32, Word64)
  53. import Data.List (elemIndex, intercalate)
  54. import Data.Maybe (fromMaybe)
  55. import qualified Data.Generics as G (Data(..))
  56. import System.Random
  57. import Data.SBV.BitVectors.AlgReals
  58. import Data.SBV.Utils.Lib
  59. import Data.SBV.BitVectors.Kind
  60. import Data.SBV.BitVectors.Concrete
  61. import Data.SBV.BitVectors.Symbolic
  62. import Data.SBV.SMT.SMTLibNames
  63. import Prelude ()
  64. import Prelude.Compat
  65. -- | Get the current path condition
  66. getPathCondition :: State -> SBool
  67. getPathCondition st = SBV (getSValPathCondition st)
  68. -- | Extend the path condition with the given test value.
  69. extendPathCondition :: State -> (SBool -> SBool) -> State
  70. extendPathCondition st f = extendSValPathCondition st (unSBV . f . SBV)
  71. -- | The "Symbolic" value. The parameter 'a' is phantom, but is
  72. -- extremely important in keeping the user interface strongly typed.
  73. newtype SBV a = SBV { unSBV :: SVal }
  74. -- | A symbolic boolean/bit
  75. type SBool = SBV Bool
  76. -- | 8-bit unsigned symbolic value
  77. type SWord8 = SBV Word8
  78. -- | 16-bit unsigned symbolic value
  79. type SWord16 = SBV Word16
  80. -- | 32-bit unsigned symbolic value
  81. type SWord32 = SBV Word32
  82. -- | 64-bit unsigned symbolic value
  83. type SWord64 = SBV Word64
  84. -- | 8-bit signed symbolic value, 2's complement representation
  85. type SInt8 = SBV Int8
  86. -- | 16-bit signed symbolic value, 2's complement representation
  87. type SInt16 = SBV Int16
  88. -- | 32-bit signed symbolic value, 2's complement representation
  89. type SInt32 = SBV Int32
  90. -- | 64-bit signed symbolic value, 2's complement representation
  91. type SInt64 = SBV Int64
  92. -- | Infinite precision signed symbolic value
  93. type SInteger = SBV Integer
  94. -- | Infinite precision symbolic algebraic real value
  95. type SReal = SBV AlgReal
  96. -- | IEEE-754 single-precision floating point numbers
  97. type SFloat = SBV Float
  98. -- | IEEE-754 double-precision floating point numbers
  99. type SDouble = SBV Double
  100. -- | Not-A-Number for 'Double' and 'Float'. Surprisingly, Haskell
  101. -- Prelude doesn't have this value defined, so we provide it here.
  102. nan :: Floating a => a
  103. nan = 0/0
  104. -- | Infinity for 'Double' and 'Float'. Surprisingly, Haskell
  105. -- Prelude doesn't have this value defined, so we provide it here.
  106. infinity :: Floating a => a
  107. infinity = 1/0
  108. -- | Symbolic variant of Not-A-Number. This value will inhabit both
  109. -- 'SDouble' and 'SFloat'.
  110. sNaN :: (Floating a, SymWord a) => SBV a
  111. sNaN = literal nan
  112. -- | Symbolic variant of infinity. This value will inhabit both
  113. -- 'SDouble' and 'SFloat'.
  114. sInfinity :: (Floating a, SymWord a) => SBV a
  115. sInfinity = literal infinity
  116. -- | 'RoundingMode' can be used symbolically
  117. instance SymWord RoundingMode
  118. -- | The symbolic variant of 'RoundingMode'
  119. type SRoundingMode = SBV RoundingMode
  120. -- | Symbolic variant of 'RoundNearestTiesToEven'
  121. sRoundNearestTiesToEven :: SRoundingMode
  122. sRoundNearestTiesToEven = literal RoundNearestTiesToEven
  123. -- | Symbolic variant of 'RoundNearestTiesToAway'
  124. sRoundNearestTiesToAway :: SRoundingMode
  125. sRoundNearestTiesToAway = literal RoundNearestTiesToAway
  126. -- | Symbolic variant of 'RoundNearestPositive'
  127. sRoundTowardPositive :: SRoundingMode
  128. sRoundTowardPositive = literal RoundTowardPositive
  129. -- | Symbolic variant of 'RoundTowardNegative'
  130. sRoundTowardNegative :: SRoundingMode
  131. sRoundTowardNegative = literal RoundTowardNegative
  132. -- | Symbolic variant of 'RoundTowardZero'
  133. sRoundTowardZero :: SRoundingMode
  134. sRoundTowardZero = literal RoundTowardZero
  135. -- | Alias for 'sRoundNearestTiesToEven'
  136. sRNE :: SRoundingMode
  137. sRNE = sRoundNearestTiesToEven
  138. -- | Alias for 'sRoundNearestTiesToAway'
  139. sRNA :: SRoundingMode
  140. sRNA = sRoundNearestTiesToAway
  141. -- | Alias for 'sRoundTowardPositive'
  142. sRTP :: SRoundingMode
  143. sRTP = sRoundTowardPositive
  144. -- | Alias for 'sRoundTowardNegative'
  145. sRTN :: SRoundingMode
  146. sRTN = sRoundTowardNegative
  147. -- | Alias for 'sRoundTowardZero'
  148. sRTZ :: SRoundingMode
  149. sRTZ = sRoundTowardZero
  150. -- Not particularly "desirable", but will do if needed
  151. instance Show (SBV a) where
  152. show (SBV sv) = show sv
  153. -- Equality constraint on SBV values. Not desirable since we can't really compare two
  154. -- symbolic values, but will do.
  155. instance Eq (SBV a) where
  156. SBV a == SBV b = a == b
  157. SBV a /= SBV b = a /= b
  158. instance HasKind (SBV a) where
  159. kindOf (SBV (SVal k _)) = k
  160. -- | Convert a symbolic value to a symbolic-word
  161. sbvToSW :: State -> SBV a -> IO SW
  162. sbvToSW st (SBV s) = svToSW st s
  163. -------------------------------------------------------------------------
  164. -- * Symbolic Computations
  165. -------------------------------------------------------------------------
  166. -- | Create a symbolic variable.
  167. mkSymSBV :: forall a. Maybe Quantifier -> Kind -> Maybe String -> Symbolic (SBV a)
  168. mkSymSBV mbQ k mbNm = fmap SBV (svMkSymVar mbQ k mbNm)
  169. -- | Convert a symbolic value to an SW, inside the Symbolic monad
  170. sbvToSymSW :: SBV a -> Symbolic SW
  171. sbvToSymSW sbv = do
  172. st <- ask
  173. liftIO $ sbvToSW st sbv
  174. -- | A class representing what can be returned from a symbolic computation.
  175. class Outputtable a where
  176. -- | Mark an interim result as an output. Useful when constructing Symbolic programs
  177. -- that return multiple values, or when the result is programmatically computed.
  178. output :: a -> Symbolic a
  179. instance Outputtable (SBV a) where
  180. output i = do
  181. outputSVal (unSBV i)
  182. return i
  183. instance Outputtable a => Outputtable [a] where
  184. output = mapM output
  185. instance Outputtable () where
  186. output = return
  187. instance (Outputtable a, Outputtable b) => Outputtable (a, b) where
  188. output = mlift2 (,) output output
  189. instance (Outputtable a, Outputtable b, Outputtable c) => Outputtable (a, b, c) where
  190. output = mlift3 (,,) output output output
  191. instance (Outputtable a, Outputtable b, Outputtable c, Outputtable d) => Outputtable (a, b, c, d) where
  192. output = mlift4 (,,,) output output output output
  193. instance (Outputtable a, Outputtable b, Outputtable c, Outputtable d, Outputtable e) => Outputtable (a, b, c, d, e) where
  194. output = mlift5 (,,,,) output output output output output
  195. instance (Outputtable a, Outputtable b, Outputtable c, Outputtable d, Outputtable e, Outputtable f) => Outputtable (a, b, c, d, e, f) where
  196. output = mlift6 (,,,,,) output output output output output output
  197. instance (Outputtable a, Outputtable b, Outputtable c, Outputtable d, Outputtable e, Outputtable f, Outputtable g) => Outputtable (a, b, c, d, e, f, g) where
  198. output = mlift7 (,,,,,,) output output output output output output output
  199. instance (Outputtable a, Outputtable b, Outputtable c, Outputtable d, Outputtable e, Outputtable f, Outputtable g, Outputtable h) => Outputtable (a, b, c, d, e, f, g, h) where
  200. output = mlift8 (,,,,,,,) output output output output output output output output
  201. -------------------------------------------------------------------------------
  202. -- * Symbolic Words
  203. -------------------------------------------------------------------------------
  204. -- | A 'SymWord' is a potential symbolic bitvector that can be created instances of
  205. -- to be fed to a symbolic program. Note that these methods are typically not needed
  206. -- in casual uses with 'prove', 'sat', 'allSat' etc, as default instances automatically
  207. -- provide the necessary bits.
  208. class (HasKind a, Ord a) => SymWord a where
  209. -- | Create a user named input (universal)
  210. forall :: String -> Symbolic (SBV a)
  211. -- | Create an automatically named input
  212. forall_ :: Symbolic (SBV a)
  213. -- | Get a bunch of new words
  214. mkForallVars :: Int -> Symbolic [SBV a]
  215. -- | Create an existential variable
  216. exists :: String -> Symbolic (SBV a)
  217. -- | Create an automatically named existential variable
  218. exists_ :: Symbolic (SBV a)
  219. -- | Create a bunch of existentials
  220. mkExistVars :: Int -> Symbolic [SBV a]
  221. -- | Create a free variable, universal in a proof, existential in sat
  222. free :: String -> Symbolic (SBV a)
  223. -- | Create an unnamed free variable, universal in proof, existential in sat
  224. free_ :: Symbolic (SBV a)
  225. -- | Create a bunch of free vars
  226. mkFreeVars :: Int -> Symbolic [SBV a]
  227. -- | Similar to free; Just a more convenient name
  228. symbolic :: String -> Symbolic (SBV a)
  229. -- | Similar to mkFreeVars; but automatically gives names based on the strings
  230. symbolics :: [String] -> Symbolic [SBV a]
  231. -- | Turn a literal constant to symbolic
  232. literal :: a -> SBV a
  233. -- | Extract a literal, if the value is concrete
  234. unliteral :: SBV a -> Maybe a
  235. -- | Extract a literal, from a CW representation
  236. fromCW :: CW -> a
  237. -- | Is the symbolic word concrete?
  238. isConcrete :: SBV a -> Bool
  239. -- | Is the symbolic word really symbolic?
  240. isSymbolic :: SBV a -> Bool
  241. -- | Does it concretely satisfy the given predicate?
  242. isConcretely :: SBV a -> (a -> Bool) -> Bool
  243. -- | One stop allocator
  244. mkSymWord :: Maybe Quantifier -> Maybe String -> Symbolic (SBV a)
  245. -- minimal complete definition:: Nothing.
  246. -- Giving no instances is ok when defining an uninterpreted/enumerated sort, but otherwise you really
  247. -- want to define: literal, fromCW, mkSymWord
  248. forall = mkSymWord (Just ALL) . Just
  249. forall_ = mkSymWord (Just ALL) Nothing
  250. exists = mkSymWord (Just EX) . Just
  251. exists_ = mkSymWord (Just EX) Nothing
  252. free = mkSymWord Nothing . Just
  253. free_ = mkSymWord Nothing Nothing
  254. mkForallVars n = mapM (const forall_) [1 .. n]
  255. mkExistVars n = mapM (const exists_) [1 .. n]
  256. mkFreeVars n = mapM (const free_) [1 .. n]
  257. symbolic = free
  258. symbolics = mapM symbolic
  259. unliteral (SBV (SVal _ (Left c))) = Just $ fromCW c
  260. unliteral _ = Nothing
  261. isConcrete (SBV (SVal _ (Left _))) = True
  262. isConcrete _ = False
  263. isSymbolic = not . isConcrete
  264. isConcretely s p
  265. | Just i <- unliteral s = p i
  266. | True = False
  267. default literal :: Show a => a -> SBV a
  268. literal x = let k@(KUserSort _ conts) = kindOf x
  269. sx = show x
  270. mbIdx = case conts of
  271. Right xs -> sx `elemIndex` xs
  272. _ -> Nothing
  273. in SBV $ SVal k (Left (CW k (CWUserSort (mbIdx, sx))))
  274. default fromCW :: Read a => CW -> a
  275. fromCW (CW _ (CWUserSort (_, s))) = read s
  276. fromCW cw = error $ "Cannot convert CW " ++ show cw ++ " to kind " ++ show (kindOf (undefined :: a))
  277. default mkSymWord :: (Read a, G.Data a) => Maybe Quantifier -> Maybe String -> Symbolic (SBV a)
  278. mkSymWord mbQ mbNm = SBV <$> mkSValUserSort k mbQ mbNm
  279. where k = constructUKind (undefined :: a)
  280. instance (Random a, SymWord a) => Random (SBV a) where
  281. randomR (l, h) g = case (unliteral l, unliteral h) of
  282. (Just lb, Just hb) -> let (v, g') = randomR (lb, hb) g in (literal (v :: a), g')
  283. _ -> error "SBV.Random: Cannot generate random values with symbolic bounds"
  284. random g = let (v, g') = random g in (literal (v :: a) , g')
  285. ---------------------------------------------------------------------------------
  286. -- * Symbolic Arrays
  287. ---------------------------------------------------------------------------------
  288. -- | Flat arrays of symbolic values
  289. -- An @array a b@ is an array indexed by the type @'SBV' a@, with elements of type @'SBV' b@
  290. -- If an initial value is not provided in 'newArray_' and 'newArray' methods, then the elements
  291. -- are left unspecified, i.e., the solver is free to choose any value. This is the right thing
  292. -- to do if arrays are used as inputs to functions to be verified, typically.
  293. --
  294. -- While it's certainly possible for user to create instances of 'SymArray', the
  295. -- 'SArray' and 'SFunArray' instances already provided should cover most use cases
  296. -- in practice. (There are some differences between these models, however, see the corresponding
  297. -- declaration.)
  298. --
  299. --
  300. -- Minimal complete definition: All methods are required, no defaults.
  301. class SymArray array where
  302. -- | Create a new array, with an optional initial value
  303. newArray_ :: (HasKind a, HasKind b) => Maybe (SBV b) -> Symbolic (array a b)
  304. -- | Create a named new array, with an optional initial value
  305. newArray :: (HasKind a, HasKind b) => String -> Maybe (SBV b) -> Symbolic (array a b)
  306. -- | Read the array element at @a@
  307. readArray :: array a b -> SBV a -> SBV b
  308. -- | Reset all the elements of the array to the value @b@
  309. resetArray :: SymWord b => array a b -> SBV b -> array a b
  310. -- | Update the element at @a@ to be @b@
  311. writeArray :: SymWord b => array a b -> SBV a -> SBV b -> array a b
  312. -- | Merge two given arrays on the symbolic condition
  313. -- Intuitively: @mergeArrays cond a b = if cond then a else b@.
  314. -- Merging pushes the if-then-else choice down on to elements
  315. mergeArrays :: SymWord b => SBV Bool -> array a b -> array a b -> array a b
  316. -- | Arrays implemented in terms of SMT-arrays: <http://smtlib.cs.uiowa.edu/theories-ArraysEx.shtml>
  317. --
  318. -- * Maps directly to SMT-lib arrays
  319. --
  320. -- * Reading from an unintialized value is OK and yields an unspecified result
  321. --
  322. -- * Can check for equality of these arrays
  323. --
  324. -- * Cannot quick-check theorems using @SArray@ values
  325. --
  326. -- * Typically slower as it heavily relies on SMT-solving for the array theory
  327. --
  328. newtype SArray a b = SArray { unSArray :: SArr }
  329. instance (HasKind a, HasKind b) => Show (SArray a b) where
  330. show SArray{} = "SArray<" ++ showType (undefined :: a) ++ ":" ++ showType (undefined :: b) ++ ">"
  331. instance SymArray SArray where
  332. newArray_ = declNewSArray (\t -> "array_" ++ show t)
  333. newArray n = declNewSArray (const n)
  334. readArray (SArray arr) (SBV a) = SBV (readSArr arr a)
  335. resetArray (SArray arr) (SBV b) = SArray (resetSArr arr b)
  336. writeArray (SArray arr) (SBV a) (SBV b) = SArray (writeSArr arr a b)
  337. mergeArrays (SBV t) (SArray a) (SArray b) = SArray (mergeSArr t a b)
  338. -- | Declare a new symbolic array, with a potential initial value
  339. declNewSArray :: forall a b. (HasKind a, HasKind b) => (Int -> String) -> Maybe (SBV b) -> Symbolic (SArray a b)
  340. declNewSArray mkNm mbInit = do
  341. let aknd = kindOf (undefined :: a)
  342. bknd = kindOf (undefined :: b)
  343. arr <- newSArr (aknd, bknd) mkNm (fmap unSBV mbInit)
  344. return (SArray arr)
  345. -- | Declare a new functional symbolic array, with a potential initial value. Note that a read from an uninitialized cell will result in an error.
  346. declNewSFunArray :: forall a b. (HasKind a, HasKind b) => Maybe (SBV b) -> Symbolic (SFunArray a b)
  347. declNewSFunArray mbiVal = return $ SFunArray $ const $ fromMaybe (error "Reading from an uninitialized array entry") mbiVal
  348. -- | Arrays implemented internally as functions
  349. --
  350. -- * Internally handled by the library and not mapped to SMT-Lib
  351. --
  352. -- * Reading an uninitialized value is considered an error (will throw exception)
  353. --
  354. -- * Cannot check for equality (internally represented as functions)
  355. --
  356. -- * Can quick-check
  357. --
  358. -- * Typically faster as it gets compiled away during translation
  359. --
  360. data SFunArray a b = SFunArray (SBV a -> SBV b)
  361. instance (HasKind a, HasKind b) => Show (SFunArray a b) where
  362. show (SFunArray _) = "SFunArray<" ++ showType (undefined :: a) ++ ":" ++ showType (undefined :: b) ++ ">"
  363. -- | Lift a function to an array. Useful for creating arrays in a pure context. (Otherwise use `newArray`.)
  364. mkSFunArray :: (SBV a -> SBV b) -> SFunArray a b
  365. mkSFunArray = SFunArray
  366. -- | Add a constraint with a given probability
  367. addConstraint :: Maybe Double -> SBool -> SBool -> Symbolic ()
  368. addConstraint mt (SBV c) (SBV c') = addSValConstraint mt c c'
  369. instance NFData (SBV a) where
  370. rnf (SBV x) = rnf x `seq` ()
  371. -- | Symbolically executable program fragments. This class is mainly used for 'safe' calls, and is sufficently populated internally to cover most use
  372. -- cases. Users can extend it as they wish to allow 'safe' checks for SBV programs that return/take types that are user-defined.
  373. class SExecutable a where
  374. sName_ :: a -> Symbolic ()
  375. sName :: [String] -> a -> Symbolic ()
  376. instance NFData a => SExecutable (Symbolic a) where
  377. sName_ a = a >>= \r -> rnf r `seq` return ()
  378. sName [] = sName_
  379. sName xs = error $ "SBV.SExecutable.sName: Extra unmapped name(s): " ++ intercalate ", " xs
  380. instance SExecutable (SBV a) where
  381. sName_ v = sName_ (output v)
  382. sName xs v = sName xs (output v)
  383. -- Unit output
  384. instance SExecutable () where
  385. sName_ () = sName_ (output ())
  386. sName xs () = sName xs (output ())
  387. -- List output
  388. instance SExecutable [SBV a] where
  389. sName_ vs = sName_ (output vs)
  390. sName xs vs = sName xs (output vs)
  391. -- 2 Tuple output
  392. instance (NFData a, SymWord a, NFData b, SymWord b) => SExecutable (SBV a, SBV b) where
  393. sName_ (a, b) = sName_ (output a >> output b)
  394. sName _ = sName_
  395. -- 3 Tuple output
  396. instance (NFData a, SymWord a, NFData b, SymWord b, NFData c, SymWord c) => SExecutable (SBV a, SBV b, SBV c) where
  397. sName_ (a, b, c) = sName_ (output a >> output b >> output c)
  398. sName _ = sName_
  399. -- 4 Tuple output
  400. instance (NFData a, SymWord a, NFData b, SymWord b, NFData c, SymWord c, NFData d, SymWord d) => SExecutable (SBV a, SBV b, SBV c, SBV d) where
  401. sName_ (a, b, c, d) = sName_ (output a >> output b >> output c >> output c >> output d)
  402. sName _ = sName_
  403. -- 5 Tuple output
  404. instance (NFData a, SymWord a, NFData b, SymWord b, NFData c, SymWord c, NFData d, SymWord d, NFData e, SymWord e) => SExecutable (SBV a, SBV b, SBV c, SBV d, SBV e) where
  405. sName_ (a, b, c, d, e) = sName_ (output a >> output b >> output c >> output d >> output e)
  406. sName _ = sName_
  407. -- 6 Tuple output
  408. instance (NFData a, SymWord a, NFData b, SymWord b, NFData c, SymWord c, NFData d, SymWord d, NFData e, SymWord e, NFData f, SymWord f) => SExecutable (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) where
  409. sName_ (a, b, c, d, e, f) = sName_ (output a >> output b >> output c >> output d >> output e >> output f)
  410. sName _ = sName_
  411. -- 7 Tuple output
  412. instance (NFData a, SymWord a, NFData b, SymWord b, NFData c, SymWord c, NFData d, SymWord d, NFData e, SymWord e, NFData f, SymWord f, NFData g, SymWord g) => SExecutable (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) where
  413. sName_ (a, b, c, d, e, f, g) = sName_ (output a >> output b >> output c >> output d >> output e >> output f >> output g)
  414. sName _ = sName_
  415. -- Functions
  416. instance (SymWord a, SExecutable p) => SExecutable (SBV a -> p) where
  417. sName_ k = forall_ >>= \a -> sName_ $ k a
  418. sName (s:ss) k = forall s >>= \a -> sName ss $ k a
  419. sName [] k = sName_ k
  420. -- 2 Tuple input
  421. instance (SymWord a, SymWord b, SExecutable p) => SExecutable ((SBV a, SBV b) -> p) where
  422. sName_ k = forall_ >>= \a -> sName_ $ \b -> k (a, b)
  423. sName (s:ss) k = forall s >>= \a -> sName ss $ \b -> k (a, b)
  424. sName [] k = sName_ k
  425. -- 3 Tuple input
  426. instance (SymWord a, SymWord b, SymWord c, SExecutable p) => SExecutable ((SBV a, SBV b, SBV c) -> p) where
  427. sName_ k = forall_ >>= \a -> sName_ $ \b c -> k (a, b, c)
  428. sName (s:ss) k = forall s >>= \a -> sName ss $ \b c -> k (a, b, c)
  429. sName [] k = sName_ k
  430. -- 4 Tuple input
  431. instance (SymWord a, SymWord b, SymWord c, SymWord d, SExecutable p) => SExecutable ((SBV a, SBV b, SBV c, SBV d) -> p) where
  432. sName_ k = forall_ >>= \a -> sName_ $ \b c d -> k (a, b, c, d)
  433. sName (s:ss) k = forall s >>= \a -> sName ss $ \b c d -> k (a, b, c, d)
  434. sName [] k = sName_ k
  435. -- 5 Tuple input
  436. instance (SymWord a, SymWord b, SymWord c, SymWord d, SymWord e, SExecutable p) => SExecutable ((SBV a, SBV b, SBV c, SBV d, SBV e) -> p) where
  437. sName_ k = forall_ >>= \a -> sName_ $ \b c d e -> k (a, b, c, d, e)
  438. sName (s:ss) k = forall s >>= \a -> sName ss $ \b c d e -> k (a, b, c, d, e)
  439. sName [] k = sName_ k
  440. -- 6 Tuple input
  441. instance (SymWord a, SymWord b, SymWord c, SymWord d, SymWord e, SymWord f, SExecutable p) => SExecutable ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> p) where
  442. sName_ k = forall_ >>= \a -> sName_ $ \b c d e f -> k (a, b, c, d, e, f)
  443. sName (s:ss) k = forall s >>= \a -> sName ss $ \b c d e f -> k (a, b, c, d, e, f)
  444. sName [] k = sName_ k
  445. -- 7 Tuple input
  446. instance (SymWord a, SymWord b, SymWord c, SymWord d, SymWord e, SymWord f, SymWord g, SExecutable p) => SExecutable ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> p) where
  447. sName_ k = forall_ >>= \a -> sName_ $ \b c d e f g -> k (a, b, c, d, e, f, g)
  448. sName (s:ss) k = forall s >>= \a -> sName ss $ \b c d e f g -> k (a, b, c, d, e, f, g)
  449. sName [] k = sName_ k