packages feed

copilot-sbv 0.1 → 0.2

raw patch · 9 files changed

+624/−222 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Copilot.Compile.SBV.Copilot2SBV: ArrIn :: Id -> ArrInput -> Input
- Copilot.Compile.SBV.Copilot2SBV: ArrInput :: QueueIn a -> ArrInput
- Copilot.Compile.SBV.Copilot2SBV: ExtIn :: Name -> ExtInput -> Input
- Copilot.Compile.SBV.Copilot2SBV: data ArrInput
- Copilot.Compile.SBV.Copilot2SBV: data Input
- Copilot.Compile.SBV.MetaTable: ExternFunInfo :: [(UType, UExpr)] -> Type a -> ExternFunInfo
- Copilot.Compile.SBV.MetaTable: StreamInfo :: [a] -> Type a -> StreamInfo
- Copilot.Compile.SBV.MetaTable: argToCall :: Arg -> [String]
- Copilot.Compile.SBV.MetaTable: data ExternFunInfo
- Copilot.Compile.SBV.MetaTable: data StreamInfo
- Copilot.Compile.SBV.MetaTable: externFunInfoArgs :: ExternFunInfo -> [(UType, UExpr)]
- Copilot.Compile.SBV.MetaTable: externFunInfoType :: ExternFunInfo -> Type a
- Copilot.Compile.SBV.MetaTable: externInfoMap :: MetaTable -> ExternInfoMap
- Copilot.Compile.SBV.MetaTable: streamInfoQueue :: StreamInfo -> [a]
- Copilot.Compile.SBV.MetaTable: streamInfoType :: StreamInfo -> Type a
- Copilot.Compile.SBV.MetaTable: type ExternInfoMap = Map Name UType
+ Copilot.Compile.SBV: sbvDirName :: String
+ Copilot.Compile.SBV.Code: getExtArrs :: MetaTable -> [SBVFunc]
+ Copilot.Compile.SBV.Common: mkExtArrFn :: String -> String
+ Copilot.Compile.SBV.Common: mkExtTmpFun :: String -> Tag -> String
+ Copilot.Compile.SBV.Copilot2SBV: Inputs :: [Ext] -> [Ext] -> [Ext] -> [ExtQue] -> Inputs
+ Copilot.Compile.SBV.Copilot2SBV: QueInput :: QueueIn a -> QueInput
+ Copilot.Compile.SBV.Copilot2SBV: data Inputs
+ Copilot.Compile.SBV.Copilot2SBV: data QueInput
+ Copilot.Compile.SBV.Copilot2SBV: extArrs :: Inputs -> [Ext]
+ Copilot.Compile.SBV.Copilot2SBV: extFuns :: Inputs -> [Ext]
+ Copilot.Compile.SBV.Copilot2SBV: extQues :: Inputs -> [ExtQue]
+ Copilot.Compile.SBV.Copilot2SBV: extVars :: Inputs -> [Ext]
+ Copilot.Compile.SBV.Copilot2SBV: type Ext = (Name, ExtInput)
+ Copilot.Compile.SBV.Copilot2SBV: type ExtQue = (Id, QueInput)
+ Copilot.Compile.SBV.MetaTable: collectArgs :: Expr a -> [String]
+ Copilot.Compile.SBV.MetaTable: externArrInfoMap :: MetaTable -> ExternArrInfoMap
+ Copilot.Compile.SBV.MetaTable: externVarInfoMap :: MetaTable -> ExternVarInfoMap
+ Copilot.Compile.SBV.MetaTable: type ExternArrInfoMap = Map Name ExtArray
+ Copilot.Compile.SBV.MetaTable: type ExternVarInfoMap = Map Name ExtVar
+ Copilot.Compile.SBV.Witness: CastInst :: CastInst a b
+ Copilot.Compile.SBV.Witness: NumInst :: NumInst a
+ Copilot.Compile.SBV.Witness: castInst :: Type a -> Type b -> CastInst a b
+ Copilot.Compile.SBV.Witness: data CastInst a b
+ Copilot.Compile.SBV.Witness: data NumInst a
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Bool
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Int16
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Int32
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Int8
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Word16
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Word32
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Word64
+ Copilot.Compile.SBV.Witness: instance SBVCast Bool Word8
+ Copilot.Compile.SBV.Witness: instance SBVCast Int16 Int16
+ Copilot.Compile.SBV.Witness: instance SBVCast Int16 Int32
+ Copilot.Compile.SBV.Witness: instance SBVCast Int16 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Int32 Int32
+ Copilot.Compile.SBV.Witness: instance SBVCast Int32 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Int64 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Int8 Int16
+ Copilot.Compile.SBV.Witness: instance SBVCast Int8 Int32
+ Copilot.Compile.SBV.Witness: instance SBVCast Int8 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Int8 Int8
+ Copilot.Compile.SBV.Witness: instance SBVCast Word16 Int32
+ Copilot.Compile.SBV.Witness: instance SBVCast Word16 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word16 Word16
+ Copilot.Compile.SBV.Witness: instance SBVCast Word16 Word32
+ Copilot.Compile.SBV.Witness: instance SBVCast Word16 Word64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word32 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word32 Word32
+ Copilot.Compile.SBV.Witness: instance SBVCast Word32 Word64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word64 Word64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Int16
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Int32
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Int64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Word16
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Word32
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Word64
+ Copilot.Compile.SBV.Witness: instance SBVCast Word8 Word8
+ Copilot.Compile.SBV.Witness: numInst :: Type a -> NumInst a
+ Copilot.Compile.SBV.Witness: sbvCast :: SBVCast a b => SBV a -> SBV b
- Copilot.Compile.SBV.Copilot2SBV: arrInput :: ArrInput -> QueueIn a
+ Copilot.Compile.SBV.Copilot2SBV: arrInput :: QueInput -> QueueIn a
- Copilot.Compile.SBV.Copilot2SBV: c2sExpr :: [Input] -> Expr a -> SBV a
+ Copilot.Compile.SBV.Copilot2SBV: c2sExpr :: Inputs -> Expr a -> SBV a
- Copilot.Compile.SBV.MetaTable: ExternFun :: Name -> Arg
+ Copilot.Compile.SBV.MetaTable: ExternFun :: Name -> Tag -> Arg
- Copilot.Compile.SBV.MetaTable: MetaTable :: StreamInfoMap -> ExternInfoMap -> ExternFunInfoMap -> TriggerInfoMap -> ObserverInfoMap -> MetaTable
+ Copilot.Compile.SBV.MetaTable: MetaTable :: StreamInfoMap -> ExternVarInfoMap -> ExternArrInfoMap -> ExternFunInfoMap -> TriggerInfoMap -> ObserverInfoMap -> MetaTable
- Copilot.Compile.SBV.MetaTable: type ExternFunInfoMap = Map Name ExternFunInfo
+ Copilot.Compile.SBV.MetaTable: type ExternFunInfoMap = Map Name ExtFun
- Copilot.Compile.SBV.MetaTable: type StreamInfoMap = Map Id StreamInfo
+ Copilot.Compile.SBV.MetaTable: type StreamInfoMap = Map Id Stream

Files

copilot-sbv.cabal view
@@ -1,6 +1,6 @@ cabal-version             : >= 1.10 name                      : copilot-sbv-version                   : 0.1+version                   : 0.2 synopsis                  : A compiler for CoPilot targeting SBV. description               : Blah blah blah... license                   : BSD3
src/Copilot/Compile/SBV.hs view
@@ -4,6 +4,7 @@  module Copilot.Compile.SBV   ( compile+  , sbvDirName   , module Copilot.Compile.SBV.Params   ) where @@ -14,7 +15,8 @@  import Copilot.Compile.SBV.Driver (driver, driverName) import Copilot.Compile.SBV.Makefile (makefile, makefileName)-import Copilot.Compile.SBV.Code (updateStates, updateObservers, fireTriggers)+import Copilot.Compile.SBV.Code +  (updateStates, updateObservers, fireTriggers, getExtArrs) import Copilot.Compile.SBV.MetaTable (allocMetaTable) import Copilot.Compile.SBV.Params @@ -22,10 +24,13 @@  -- Note: we put everything in a directory named by the dirName. +sbvDirName :: String+sbvDirName = "copilot-sbv"+ compile :: Params -> C.Spec -> IO () compile params spec = do   let meta    = allocMetaTable spec-      dirName = withPrefix (prefix params) "copilot"+      dirName = withPrefix (prefix params) sbvDirName       sbvName = withPrefix (prefix params) "internal"   putStrLn "Compiling SBV-generated functions .." @@ -34,7 +39,9 @@     sbvName     (  updateStates    meta spec     ++ updateObservers meta spec-    ++ fireTriggers    meta spec )+    ++ fireTriggers    meta spec +    ++ getExtArrs      meta +    )    putStrLn ""   putStrLn $ "Generating Copilot driver " ++ driverName params ++ " .."
src/Copilot/Compile/SBV/Code.hs view
@@ -9,6 +9,7 @@   ( updateStates   , updateObservers   , fireTriggers+  , getExtArrs   ) where  import Copilot.Compile.SBV.Copilot2SBV@@ -20,9 +21,10 @@ import Copilot.Core.Type.Equality ((=~=), coerce, cong)  import qualified Data.SBV as S-import qualified Data.SBV.Internals as S+--import qualified Data.SBV.Internals as S  import qualified Data.Map as M+import Control.Monad (foldM) import Prelude hiding (id)  --------------------------------------------------------------------------------@@ -43,15 +45,16 @@   updateStreamState C.Stream { C.streamId       = id                              , C.streamExpr     = e                              , C.streamExprType = t1-                                                      } =-    mkSBVFunc (mkUpdateStFn id) $ do-      inputs <- mkInputs meta (c2Args e)-      let e' = c2sExpr inputs e-      let Just strmInfo = M.lookup id (streamInfoMap meta) -      updateStreamState1 t1 e' strmInfo+                                                      } +    = mkSBVFunc (mkUpdateStFn id) $ do+        inputs <- mkInputs meta (c2Args e)+        let e' = c2sExpr inputs e+        let Just strmInfo = M.lookup id (streamInfoMap meta) +        updateStreamState1 t1 e' strmInfo -  updateStreamState1 :: C.Type a -> S.SBV a -> StreamInfo -> S.SBVCodeGen ()-  updateStreamState1 t1 e1 (StreamInfo _ t2) = do+  updateStreamState1 :: C.Type a -> S.SBV a -> C.Stream -> S.SBVCodeGen ()+  updateStreamState1 t1 e1 C.Stream { C.streamExprType = t2 }+    = do     W.SymWordInst <- return (W.symWordInst t2)     W.HasSignAndSizeInst <- return (W.hasSignAndSizeInst t2)     Just p <- return (t1 =~= t2)@@ -112,55 +115,128 @@  -------------------------------------------------------------------------------- --- We first need to analyze the expression, running down it to get all the drop--- ids and externals mentioned in it.  The we use those inputs to process the--- expression.  XXX MUST be put in the monad in the same order as the function--- call (argToCall from MetaTable.hs).+-- Generate an SBV function that calculates the Copilot expression to get the+-- next index to sample an external array.+getExtArrs :: MetaTable -> [SBVFunc]+getExtArrs meta@(MetaTable { externArrInfoMap = arrs })+  = map mkIdx (M.toList arrs)+  +  where+  mkIdx :: (C.Name, C.ExtArray) -> SBVFunc+  mkIdx (name, C.ExtArray { C.externArrayIdx     = idx+                          , C.externArrayIdxType = t   })+    = +    mkSBVFunc (mkExtArrFn name) mkSBVExpr+    where+    mkSBVExpr :: S.SBVCodeGen ()+    mkSBVExpr = do+      inputs <- mkInputs meta (c2Args idx)+      W.SymWordInst <- return (W.symWordInst t)+      W.HasSignAndSizeInst <- return (W.hasSignAndSizeInst t)+      S.cgReturn (c2sExpr inputs idx) -mkInputs :: MetaTable -> [Arg] -> S.SBVCodeGen [Input]-mkInputs meta args =-  mapM argToInput args+-------------------------------------------------------------------------------- +-- mkInputs takes the datatype containing the entire spec (meta) as well as all+-- possible arguments to the SBV function generating the expression.  From those+-- arguments, it then generates in the SBVCodeGen monad---the actual Inputs---+-- the queues to hold streams as well as external variables.++-- XXX MUST be put in the monad in the same order as the function call+-- (argToCall from MetaTable.hs).++mkInputs :: MetaTable -> [Arg] -> S.SBVCodeGen Inputs+mkInputs meta args = +  foldM argToInput (Inputs [] [] [] []) args +   where-  argToInput :: Arg -> S.SBVCodeGen Input-  argToInput (Extern name) = -    let extInfos = externInfoMap meta in+  argToInput :: Inputs -> Arg -> S.SBVCodeGen Inputs++-----------------------------------------+ +  -- External variables+  argToInput acc (Extern name) = +    let extInfos = externVarInfoMap meta in     let Just extInfo = M.lookup name extInfos in     mkExtInput extInfo      where -    mkExtInput :: C.UType -> S.SBVCodeGen Input-    mkExtInput C.UType { C.uTypeType = t } = do-      ext <- mkExtInput_ t-      return $ ExtIn name (ExtInput { extInput = ext -                                    , extType  = t })+    mkExtInput :: C.ExtVar -> S.SBVCodeGen Inputs+    mkExtInput (C.ExtVar _ C.UType { C.uTypeType = t }) = do+      ext <- mkExtInput_ t (mkExtTmpVar name)+      return acc { extVars = (name, (ExtInput { extInput = ext +                                              , extType  = t })+                             ) : extVars acc } -    mkExtInput_ :: C.Type a -> S.SBVCodeGen (S.SBV a)-    mkExtInput_ t = do-     W.SymWordInst        <- return (W.symWordInst t)-     W.HasSignAndSizeInst <- return (W.hasSignAndSizeInst t)-     ext <- S.cgInput (mkExtTmpVar name)-     return ext+----------------------------------------- -  argToInput (Queue id) =+-- External arrays+  argToInput acc (ExternArr name) = +    let extInfos = externArrInfoMap meta in+    let Just extInfo = M.lookup name extInfos in+    mkExtInput extInfo++    where +    mkExtInput :: C.ExtArray -> S.SBVCodeGen Inputs+    mkExtInput C.ExtArray { C.externArrayElemType = t }+      = do+      v <- mkExtInput_ t (mkExtTmpVar name)+      return acc { extArrs = (name, ExtInput +                                      { extInput  = v+                                      , extType   = t }+                             ) : extArrs acc }++-----------------------------------------++-- External functions+  argToInput acc (ExternFun name tag) =+    let extInfos = externFunInfoMap meta in+    let Just extInfo = M.lookup name extInfos in+    mkExtInput extInfo++    where+    mkExtInput :: C.ExtFun -> S.SBVCodeGen Inputs+    mkExtInput C.ExtFun { C.externFunType = t }+      = do+      v <- mkExtInput_ t (mkExtTmpFun name tag)+      return acc { extFuns = (name, ExtInput +                                      { extInput = v+                                      , extType  = t }+                             ) : extFuns acc }++-----------------------------------------++-- Stream queues+  argToInput acc (Queue id) =     let strmInfos = streamInfoMap meta in     let Just strmInfo = M.lookup id strmInfos in-    mkArrInput strmInfo+    mkQueInput strmInfo      where-    mkArrInput :: StreamInfo -> S.SBVCodeGen Input-    mkArrInput StreamInfo { streamInfoQueue = que-                          , streamInfoType  = t } = do-      arr <- mkArrInput_ t que+    mkQueInput :: C.Stream -> S.SBVCodeGen Inputs+    mkQueInput C.Stream { C.streamBuffer = que+                        , C.streamExprType  = t } = do+      arr <- mkQueInput_ t que       ptr <- S.cgInput (mkQueuePtrVar id) -      return $ ArrIn id (ArrInput (QueueIn { queue   = arr-                                           , quePtr  = ptr-                                           , arrType = t }))--    mkArrInput_ :: C.Type a -> [a] -> S.SBVCodeGen [S.SBV a]-    mkArrInput_ t que = do+      return acc { extQues = (id, QueInput (QueueIn { queue   = arr+                                                    , quePtr  = ptr+                                                    , arrType = t })+                             ) : extQues acc+                 }+                   +    mkQueInput_ :: C.Type a -> [a] -> S.SBVCodeGen [S.SBV a]+    mkQueInput_ t que = do       W.SymWordInst        <- return (W.symWordInst t)       W.HasSignAndSizeInst <- return (W.hasSignAndSizeInst t)       arr <- S.cgInputArr (length que) (mkQueueVar id)       return arr++-----------------------------------------++mkExtInput_ :: C.Type a -> String -> S.SBVCodeGen (S.SBV a)+mkExtInput_ t name = do+  W.SymWordInst        <- return (W.symWordInst t)+  W.HasSignAndSizeInst <- return (W.hasSignAndSizeInst t)+  ext <- S.cgInput name+  return ext
src/Copilot/Compile/SBV/Common.hs view
@@ -2,19 +2,23 @@ -- Copyright © 2011 National Institute of Aerospace / Galois, Inc. -------------------------------------------------------------------------------- +-- Builds names of functions and variables used.+ module Copilot.Compile.SBV.Common   ( mkTmpStVar   , mkUpdateStFn   , mkQueueVar   , mkQueuePtrVar   , mkExtTmpVar+  , mkExtTmpFun+  , mkExtArrFn   , mkObserverFn   , mkTriggerGuardFn   , mkTriggerArgFn   , mkTriggerArgIdx   ) where -import Copilot.Core (Id)+import Copilot.Core (Id, Tag) import Prelude hiding (id)  mkVar :: String -> Id -> String@@ -35,14 +39,20 @@ mkExtTmpVar :: String -> String mkExtTmpVar = ("ext_" ++) +mkExtTmpFun :: String -> Tag -> String+mkExtTmpFun name tag = "ext_" ++ name ++ "_" ++ show tag++mkExtArrFn :: String -> String+mkExtArrFn = (++) "mk_ext_arr_"+ mkObserverFn :: String -> String-mkObserverFn = ("observer_" ++)+mkObserverFn = ("mk_observer_" ++)  mkTriggerGuardFn :: String -> String-mkTriggerGuardFn = ("trigger_guard_" ++)+mkTriggerGuardFn = ("mk_trigger_guard_" ++)  mkTriggerArgFn :: Int -> String -> String-mkTriggerArgFn i nm = "trigger_" ++ nm ++ "_arg_" ++ show i+mkTriggerArgFn i nm = "mk_trigger_" ++ nm ++ "_arg_" ++ show i  mkTriggerArgIdx :: [a] -> [(Int, a)] mkTriggerArgIdx args = zip [0,1 ..] args
src/Copilot/Compile/SBV/Copilot2SBV.hs view
@@ -6,9 +6,12 @@  module Copilot.Compile.SBV.Copilot2SBV   ( c2sExpr-  , Input(..)+  , Inputs(..)+  , Ext+--  , ExtArr+  , ExtQue   , ExtInput(..)-  , ArrInput(..)+  , QueInput(..)   , QueueIn(..)   )  where@@ -18,37 +21,45 @@ import qualified Data.Map as M  import qualified Data.SBV as S-import qualified Data.SBV.Internals as S+--import qualified Data.SBV.Internals as S  import qualified Copilot.Compile.SBV.Queue as Q import qualified Copilot.Compile.SBV.Witness as W  import Copilot.Core (Op1 (..), Op2 (..), Op3 (..), badUsage) import qualified Copilot.Core as C+import Copilot.Core.Error (impossible) import Copilot.Core.Type.Equality ((=~=), coerce, cong) - -------------------------------------------------------------------------------- -data Input = -    ExtIn C.Name ExtInput-  | ArrIn C.Id ArrInput+type Ext = (C.Name, ExtInput)+type ExtQue = (C.Id, QueInput) +-- These are all the inputs to the to the SBV expression we're building.+data Inputs = Inputs+  { extVars  :: [Ext] -- external variables+  , extArrs  :: [Ext] -- external arrays+  , extFuns  :: [Ext] -- external functions+  , extQues  :: [ExtQue] }++-- External input -- variables, arrays, and functions data ExtInput = forall a. ExtInput    { extInput :: S.SBV a   , extType  :: C.Type a } -data ArrInput = forall a. ArrInput +-- Stream queues+data QueInput = forall a. QueInput    { arrInput :: QueueIn a }  data QueueIn a = QueueIn-  { queue  :: [S.SBV a]-  , quePtr :: S.SBV Q.QueueSize +  { queue    :: [S.SBV a]+  , quePtr   :: S.SBV Q.QueueSize    , arrType  :: C.Type a }  -------------------------------------------------------------------------------- -c2sExpr :: [Input] -> C.Expr a -> S.SBV a+c2sExpr :: Inputs -> C.Expr a -> S.SBV a c2sExpr inputs e = c2sExpr_ e M.empty inputs  --------------------------------------------------------------------------------@@ -61,7 +72,19 @@  -------------------------------------------------------------------------------- -c2sExpr_ :: C.Expr a -> Env -> [Input] -> S.SBV a+lookupInput :: Eq a => a -> [(a,b)] -> b+lookupInput id prs =+  case lookup id prs of+    Nothing   -> impossible "lookupInput" "copilot-sbv"+    Just val  -> val++--------------------------------------------------------------------------------++-- Translate a Copilot expression into an SBV expression.  The environment+-- passed in is for tracking let expression bindings (in the Copilot language),+-- and the list of inputs are all the external things needed as input to the SBV+-- function.+c2sExpr_ :: C.Expr a -> Env -> Inputs -> S.SBV a c2sExpr_ e0 env inputs = case e0 of    C.Const t x ->@@ -69,21 +92,13 @@    ---------------------------------------------------- -  C.Drop t i id ->-    let que :: ArrInput-        Just que = foldl -          ( \acc x -> case x of-                        ArrIn id' q -> if id' == id then Just q -                                         else acc-                        ExtIn _ _ -> acc ) -          Nothing-          inputs -    in -    drop1 t que-+  C.Drop t i id -> drop1 t que     where-    drop1 :: C.Type a -> ArrInput -> S.SBV a-    drop1 t1 ArrInput { arrInput = QueueIn { queue   = que +    que :: QueInput+    que = lookupInput id (extQues inputs)++    drop1 :: C.Type a -> QueInput -> S.SBV a+    drop1 t1 QueInput { arrInput = QueueIn { queue   = que'                                            , quePtr  = qPtr                                            , arrType = t2 } } =       let Just p = t2 =~= t1 in@@ -91,7 +106,7 @@         W.SymWordInst ->            case W.hasSignAndSizeInst t2 of             W.HasSignAndSizeInst ->-              coerce (cong p) (Q.lookahead i que qPtr)+              coerce (cong p) (Q.lookahead i que' qPtr)    ---------------------------------------------------- @@ -115,39 +130,46 @@    ---------------------------------------------------- -  C.ExternVar t name ->-    let ext :: ExtInput-        Just ext = foldl -          ( \acc x -> case x of-                        ArrIn _ _ -> acc-                        ExtIn nm e -> if nm == name then Just e-                                        else acc ) -          Nothing-          inputs -    in getSBV t ext+  C.ExternVar t name _ -> +    getSBV t ext      where +    ext :: ExtInput+    ext = lookupInput name (extVars inputs) +     getSBV :: C.Type a -> ExtInput -> S.SBV a-    getSBV t1 ExtInput { extInput = ext+    getSBV t1 ExtInput { extInput = ext'                        , extType  = t2 } =       let Just p = t2 =~= t1 in-      coerce (cong p) ext+      coerce (cong p) ext'    ---------------------------------------------------- -  -- externFun t name _ = C2AExpr $ \ _ meta ->-  --   let Just extFunInfo = M.lookup name (externFunInfoMap meta) in-  --   externFun1 t extFunInfo+  C.ExternArray _ t name _ _ _ _ -> +    getSBV t getExtArr -  --   where-  --   externFun1 t1-  --     ExternFunInfo-  --       { externFunInfoVar  = var-  --       , externFunInfoType = t2-  --       } =-  --     let Just p = t2 =~= t1 in-  --     case W.exprInst t2 of-  --       W.ExprInst -> coerce (cong p) (A.value var)+    where +    getExtArr :: ExtInput+    getExtArr = lookupInput name (extArrs inputs)++    getSBV t1 ExtInput { extInput  = v+                       , extType = t2 }+      = let Just p = t2 =~= t1 in+        coerce (cong p) v++  ----------------------------------------------------++  C.ExternFun t name _ _ _ ->+    getSBV t getExtFun++    where+    getExtFun :: ExtInput+    getExtFun = lookupInput name (extFuns inputs)++    getSBV t1 ExtInput { extType  = t2+                       , extInput = v }+      = let Just p = t2 =~= t1 in+        coerce (cong p) v     ---------------------------------------------------- @@ -189,6 +211,9 @@   BwNot t -> case W.bitsInst    t of                         W.BitsInst            -> (S.complement) +  Cast t0 t1 -> case W.castInst t0 t1 of +                  W.CastInst -> W.sbvCast+   Recip _ -> noFloatOpsErr "recip"   Exp   _ -> noFloatOpsErr "exp"   Sqrt  _ -> noFloatOpsErr "sqrt"@@ -235,6 +260,20 @@   BwAnd t -> case W.bitsInst     t of W.BitsInst       -> (S..&.)   BwOr  t -> case W.bitsInst     t of W.BitsInst       -> (S..|.)   BwXor t -> case W.bitsInst     t of W.BitsInst       -> (S.xor)+  BwShiftL tvec tidx -> +    case W.bitsInst tvec of +      W.BitsInst -> +        \vec idx -> case W.symWordInst tidx of+                      W.SymWordInst -> case S.unliteral idx of+                                         Nothing -> badUsage "Using the SBV backend, shiftL only supports constant shift indicies"+                                         Just x  -> S.shiftL vec (fromIntegral x)+  BwShiftR tvec tidx -> +    case W.bitsInst tvec of +      W.BitsInst -> +        \vec idx -> case W.symWordInst tidx of+                      W.SymWordInst -> case S.unliteral idx of+                                         Nothing -> badUsage "Using the SBV backend, shiftR only supports constant shift indicies"+                                         Just x  -> S.shiftR vec (fromIntegral x)    Fdiv  _ -> noFloatOpsErr "fdiv"   Pow   _ -> noFloatOpsErr "pow"@@ -245,3 +284,7 @@   Mux t ->     case W.mergeableInst t of        W.MergeableInst -> \b c1 c2 -> S.ite b c1 c2+++--------------------------------------------------------------------------------+
src/Copilot/Compile/SBV/Driver.hs view
@@ -24,6 +24,7 @@ import Copilot.Compile.SBV.Params  import qualified Copilot.Core as C+--import Copilot.Core.Type.Equality ((=~=), coerce, cong) import qualified Copilot.Core.Type.Show as C (showWithType, ShowType(..)) import Copilot.Compile.Header.C99 (c99HeaderName) @@ -44,6 +45,7 @@ mkArgs :: [Doc] -> Doc mkArgs args = hsep (punctuate comma args) +-- | Call a C function. mkFuncCall :: String -> [Doc] -> Doc mkFuncCall f args = text f <> lparen <> mkArgs args <> rparen @@ -88,22 +90,24 @@     mkFunc (withPrefix (prefix params) "step")            (   mkFuncCall sampleExtsF    [] <> semi             $$ mkFuncCall updateStatesF  [] <> semi+            $$ mkFuncCall updateBuffersF [] <> semi+            $$ mkFuncCall updatePtrsF    [] <> semi             $$ mkFuncCall observersF     [] <> semi             $$ mkFuncCall triggersF      [] <> semi-            $$ mkFuncCall updateBuffersF [] <> semi-            $$ mkFuncCall updatePtrsF    [] <> semi)+           )    copilot = vcat $ intersperse (text "")     [ sampleExts meta     , updateStates streams-    , fireTriggers meta-    , updateObservers params meta     , updateBuffers meta-    , updatePtrs meta ]+    , updatePtrs meta +    , updateObservers params meta+    , fireTriggers meta+    ]  -------------------------------------------------------------------------------- --- Declare gloabl variables.+-- Declare global variables.  data Decl = Decl { retT    :: Doc                  , declVar :: Doc@@ -115,15 +119,15 @@   where   getVars :: MetaTable -> [Decl]    getVars MetaTable { streamInfoMap = streams -                    , externInfoMap = externs } = +                    , externVarInfoMap = externs } =         map getTmpStVars (M.toList streams)     ++ map getQueueVars (M.toList streams)     ++ map getQueuePtrVars (map fst $ M.toList streams)     ++ map getExtVars (M.toList externs) -  getTmpStVars :: (C.Id, StreamInfo) -> Decl-  getTmpStVars (id, StreamInfo { streamInfoType  = t-                               , streamInfoQueue = que }) = +  getTmpStVars :: (C.Id, C.Stream) -> Decl+  getTmpStVars (id, C.Stream { C.streamExprType  = t+                               , C.streamBuffer = que }) =      Decl (retType t) (text $ mkTmpStVar id) getFirst     where      -- ASSUME queue is nonempty!@@ -131,9 +135,9 @@     headErr [] = C.impossible "headErr" "copilot-sbv"     headErr xs = head xs   -  getQueueVars :: (C.Id, StreamInfo) -> Decl-  getQueueVars (id, StreamInfo { streamInfoType = t-                               , streamInfoQueue = que }) =+  getQueueVars :: (C.Id, C.Stream) -> Decl+  getQueueVars (id, C.Stream { C.streamExprType = t+                             , C.streamBuffer = que }) =     Decl (retType t)           (text (mkQueueVar id) <> lbrack <> int (length que) <> rbrack)          getInits@@ -151,8 +155,8 @@     queSize :: C.Type QueueSize     queSize = C.typeOf  -  getExtVars :: (C.Name, C.UType) -> Decl-  getExtVars (var, C.UType { C.uTypeType = t }) = +  getExtVars :: (C.Name, C.ExtVar) -> Decl+  getExtVars (var, C.ExtVar _ (C.UType { C.uTypeType = t })) =      Decl (retType t) (text $ mkExtTmpVar var) (int 0)    varDecl :: Decl -> Doc@@ -175,44 +179,89 @@     C.Observer       { C.observerName     = name       , C.observerExprType = t } =-    retType t <+> text (withPrefix prfx name) <> text ";"+    retType t <+> text (withPrefix prfx name) <> semi  --------------------------------------------------------------------------------  sampleExts :: MetaTable -> Doc-sampleExts MetaTable { externInfoMap = extMap } =-  mkFunc sampleExtsF $ vcat $ map sampleExt ((fst . unzip . M.toList) extMap)+sampleExts MetaTable { externVarInfoMap = extVMap+                     , externArrInfoMap = extAMap+                     , externFunInfoMap = extFMap } +  =+  -- Arrays and functions have to come after vars.  This is because we may use+  -- the assignment of extVars in the definition of extArrs.  We could write it+  -- differently, but it's easier.  The Analyzer.hs copilot-core prevents arrays+  -- or functions from being used in arrays or functions.+  mkFunc sampleExtsF $ vcat (extVars ++ extArrs ++ extFuns)    where-  sampleExt :: C.Name -> Doc-  sampleExt name = text (mkExtTmpVar name) <+> equals <+> text name <> semi+  extVars = map sampleVExt ((fst . unzip . M.toList) extVMap)+  extArrs = map sampleAExt (M.toList extAMap)+  extFuns = map sampleFExt (M.toList extFMap)  -------------------------------------------------------------------------------- +-- Variables+sampleVExt :: C.Name -> Doc+sampleVExt name = +  text (mkExtTmpVar name) <+> equals <+> text name <> semi++--------------------------------------------------------------------------------+-- Arrays++-- Currenty, Analyze.hs in copilot-language forbids recurssion in+-- external arrays or functions (i.e., an external array can't use another+-- external array to compute it's index), so a lot of what is below isn't+-- currently necessary.+sampleAExt :: (C.Name, C.ExtArray) -> Doc+sampleAExt (name, C.ExtArray { C.externArrayIdx = idx })+  = +  text (mkExtTmpVar name) <+> equals <+> arrIdx name idx+ +  where +  arrIdx :: C.Name -> C.Expr a -> Doc+  arrIdx name' e = +    text name' <> lbrack <> idxFCall e <> rbrack <> semi++  -- Ok, because the analyzer disallows arrays or function calls in index+  -- expressions, and we assign all variables before arrays.+  idxFCall :: C.Expr a -> Doc+  idxFCall e = +    mkFuncCall (mkExtArrFn name) (map text $ collectArgs e)++--------------------------------------------------------------------------------++-- External functions+sampleFExt :: (C.Name, C.ExtFun) -> Doc+sampleFExt (name, C.ExtFun { C.externFunArgs = args })+  = +  text (mkExtTmpVar name) <+> equals <+> text name <> lparen+    <+> hsep (punctuate comma $ map mkArgCall (zip [(0 :: Int) ..] args))+    <> rparen <> semi++     where+     mkArgCall = undefined--  (i, ( C.UType { C.uTypeType = t}++--------------------------------------------------------------------------------+ updateStates :: [C.Stream] -> Doc updateStates streams =   mkFunc updateStatesF $ vcat $ map updateSt streams-   where-  -- tmp_X = updateState(arg0, arg1, ... );   updateSt :: C.Stream -> Doc   updateSt C.Stream { C.streamId   = id                     , C.streamExpr = e } =     text (mkTmpStVar id) <+> equals       <+> mkFuncCall (mkUpdateStFn id)-                     (map text getArgs)-      <> semi-    where-    getArgs :: [String]-    getArgs = concatMap argToCall (c2Args e)+                     (map text $ collectArgs e)+      <>  semi  --------------------------------------------------------------------------------  updateObservers :: Params -> MetaTable -> Doc-updateObservers params MetaTable { observerInfoMap = observers } =-+updateObservers params MetaTable { observerInfoMap = observers } +  =   mkFunc observersF $ vcat $ map updateObsv (M.toList observers)-   where   updateObsv :: (C.Name, ObserverInfo) -> Doc   updateObsv (name, ObserverInfo { observerArgs = args }) =@@ -222,20 +271,23 @@ --------------------------------------------------------------------------------  fireTriggers :: MetaTable -> Doc-fireTriggers MetaTable { triggerInfoMap = triggers } =-+fireTriggers MetaTable { triggerInfoMap = triggers } +  =   mkFunc triggersF $ vcat $ map fireTrig (M.toList triggers)    where   -- if (guard) trigger(args);   fireTrig :: (C.Name, TriggerInfo) -> Doc   fireTrig (name, TriggerInfo { guardArgs      = gArgs-                              , triggerArgArgs = argArgs }) =-    text "if" <+> lparen <> guardF <> rparen <+>-      mkFuncCall name (map mkArg (mkTriggerArgIdx argArgs)) <> semi+                              , triggerArgArgs = argArgs }) +    = +    let f = mkFuncCall name (map mkArg (mkTriggerArgIdx argArgs)) <> semi in+    text "if" <+> lparen <> guardF <> rparen $+$ nest 2 f+     where     guardF :: Doc     guardF = mkFuncCall (mkTriggerGuardFn name) (map text gArgs)+     mkArg :: (Int, [String]) -> Doc     mkArg (i, args) =       mkFuncCall (mkTriggerArgFn i name) (map text args)@@ -243,11 +295,12 @@ --------------------------------------------------------------------------------  updateBuffers :: MetaTable -> Doc-updateBuffers MetaTable { streamInfoMap = strMap } =+updateBuffers MetaTable { streamInfoMap = strMap } +  =   mkFunc updateBuffersF $ vcat $ map updateBuf (M.toList strMap)    where-  updateBuf :: (C.Id, StreamInfo) -> Doc+  updateBuf :: (C.Id, C.Stream) -> Doc   updateBuf (id, _) =     updateFunc (mkQueueVar id) (mkQueuePtrVar id) (mkTmpStVar id) @@ -263,8 +316,8 @@   mkFunc updatePtrsF $ vcat $ map varAndUpdate (M.toList strMap)    where -  varAndUpdate :: (C.Id, StreamInfo) -> Doc-  varAndUpdate (id, StreamInfo { streamInfoQueue = que }) =+  varAndUpdate :: (C.Id, C.Stream) -> Doc+  varAndUpdate (id, C.Stream { C.streamBuffer = que }) =     updateFunc (fromIntegral $ length que) (mkQueuePtrVar id)    -- idx = (idx + 1) % queueSize;@@ -276,7 +329,8 @@  -------------------------------------------------------------------------------- -sampleExtsF, triggersF, observersF, updatePtrsF, updateBuffersF, updateStatesF :: String+sampleExtsF, triggersF, observersF, updatePtrsF :: String+updateBuffersF, updateStatesF :: String updatePtrsF    = "updatePtrs" updateBuffersF = "updateBuffers" updateStatesF  = "updateStates"
src/Copilot/Compile/SBV/Makefile.hs view
@@ -28,7 +28,8 @@   wr (text "# Makefile rules for the Copilot driver.")   wr (text "")   wr $ text "driver" <> colon -        <+> text (driverName params) <+> text fileName <> text ".h"+        <+> text (driverName params) <+> text fileName <> text ".h" +        <+> text "internal.a"   wr $ text "\t"           <> (hsep [ text "$" <> braces (text "CC")                   , text "$" <> braces (text "CCFLAGS")
src/Copilot/Compile/SBV/MetaTable.hs view
@@ -5,10 +5,11 @@ {-# LANGUAGE ExistentialQuantification, GADTs #-}  module Copilot.Compile.SBV.MetaTable-  ( StreamInfo (..)-  , StreamInfoMap-  , ExternInfoMap-  , ExternFunInfo (..)+  ( --StreamInfo (..)+    StreamInfoMap+  , ExternVarInfoMap+  , ExternArrInfoMap+--  , ExternFunInfo (..)   , ExternFunInfoMap   , TriggerInfo (..)   , TriggerInfoMap@@ -16,39 +17,26 @@   , ObserverInfoMap   , MetaTable (..)   , allocMetaTable-  , argToCall+  , collectArgs   , Arg(..)   , c2Args   ) where  import Copilot.Compile.SBV.Common import qualified Copilot.Core as C---import qualified Copilot.Core.External as C (ExternVar (..), externVars)  import Data.Map (Map) import Data.List (nub)+import Data.Maybe (fromJust) import qualified Data.Map as M import Prelude hiding (id)  -------------------------------------------------------------------------------- -data StreamInfo = forall a . StreamInfo-  { streamInfoQueue   :: [a]-  , streamInfoType    :: C.Type a }--type StreamInfoMap = Map C.Id StreamInfo------------------------------------------------------------------------------------type ExternInfoMap = Map C.Name C.UType------------------------------------------------------------------------------------data ExternFunInfo = forall a . ExternFunInfo-  { externFunInfoArgs :: [(C.UType, C.UExpr)]-  , externFunInfoType :: C.Type a }--type ExternFunInfoMap = Map C.Name ExternFunInfo+type StreamInfoMap = Map C.Id C.Stream+type ExternVarInfoMap = Map C.Name C.ExtVar+type ExternArrInfoMap = Map C.Name C.ExtArray+type ExternFunInfoMap = Map C.Name C.ExtFun  -------------------------------------------------------------------------------- @@ -69,7 +57,8 @@  data MetaTable = MetaTable   { streamInfoMap     :: StreamInfoMap-  , externInfoMap     :: ExternInfoMap+  , externVarInfoMap  :: ExternVarInfoMap+  , externArrInfoMap  :: ExternArrInfoMap   , externFunInfoMap  :: ExternFunInfoMap   , triggerInfoMap    :: TriggerInfoMap   , observerInfoMap   :: ObserverInfoMap }@@ -79,50 +68,56 @@ allocMetaTable :: C.Spec -> MetaTable allocMetaTable spec =   let-    streamInfoMap_   = M.fromList $ map allocStream (C.specStreams spec)-    externInfoMap_   = M.fromList $ map allocExtern (C.externVars spec)-    triggerInfoMap_  = M.fromList $ map allocTrigger (C.specTriggers spec)-    observerInfoMap_ = M.fromList $ map allocObserver (C.specObservers spec)+    streamInfoMap_    = M.fromList $ map allocStream     (C.specStreams spec)+    externVarInfoMap_ = M.fromList $ map allocExternVars (C.externVars spec)+    externArrInfoMap_ = M.fromList $ map allocExternArrs (C.externArrays spec)+    externFunInfoMap_ = M.fromList $ map allocExternFuns (C.externFuns spec)+    triggerInfoMap_   = M.fromList $ map allocTrigger    (C.specTriggers spec)+    observerInfoMap_  = M.fromList $ map allocObserver   (C.specObservers spec)   in-    MetaTable-      streamInfoMap_-      externInfoMap_-      (error "undefined in MetaTable.hs in copilot-sbv.")-      triggerInfoMap_-      observerInfoMap_+    MetaTable { streamInfoMap    = streamInfoMap_+              , externVarInfoMap = externVarInfoMap_+              , externArrInfoMap = externArrInfoMap_+              , externFunInfoMap = externFunInfoMap_+              , triggerInfoMap   = triggerInfoMap_+              , observerInfoMap  = observerInfoMap_+              }+      +-------------------------------------------------------------------------------- +allocStream :: C.Stream -> (C.Id, C.Stream)+allocStream strm = +  (C.streamId strm, strm)+ -------------------------------------------------------------------------------- -allocStream :: C.Stream -> (C.Id, StreamInfo)-allocStream C.Stream-              { C.streamId       = id-              , C.streamBuffer   = buf-              , C.streamExprType = t-              } =-  let-    strmInfo =-      StreamInfo-        { streamInfoQueue       = buf-        , streamInfoType        = t } in-  (id, strmInfo)+allocExternVars :: C.ExtVar -> (C.Name, C.ExtVar)+allocExternVars var =+  (C.externVarName var, var)  -------------------------------------------------------------------------------- -allocExtern :: C.ExtVar -> (C.Name, C.UType)-allocExtern (C.ExtVar name t) =-  (name, t)+allocExternArrs :: C.ExtArray -> (C.Name, C.ExtArray)+allocExternArrs arr =+  (C.externArrayName arr, arr)  -------------------------------------------------------------------------------- +allocExternFuns :: C.ExtFun -> (C.Name, C.ExtFun)+allocExternFuns fun =+  (C.externFunName fun, fun)++--------------------------------------------------------------------------------+ allocTrigger :: C.Trigger -> (C.Name, TriggerInfo) allocTrigger C.Trigger { C.triggerName  = name                        , C.triggerGuard = guard-                       , C.triggerArgs  = args } = +                       , C.triggerArgs  = args } +  =   let mkArgArgs :: C.UExpr -> [String]-      mkArgArgs C.UExpr { C.uExprExpr = e } = -        nub (concatMap argToCall (c2Args e)) in+      mkArgArgs C.UExpr { C.uExprExpr = e } = collectArgs e in   let triggerInfo = -        TriggerInfo { guardArgs      = nub (concatMap argToCall (c2Args guard))+        TriggerInfo { guardArgs      = collectArgs guard                      , triggerArgArgs = map mkArgArgs args } in   (name, triggerInfo) @@ -130,31 +125,38 @@  allocObserver :: C.Observer -> (C.Name, ObserverInfo) allocObserver C.Observer { C.observerName = name-                         , C.observerExpr = e } =-  let-    observerInfo =-      ObserverInfo { observerArgs = nub (concatMap argToCall (c2Args e)) }-  in-    (name, observerInfo)+                         , C.observerExpr = e } +  = +  let observerInfo = ObserverInfo { observerArgs = collectArgs e } in+  (name, observerInfo)  ----------------------------------------------------------------------------------- Getting SBV function args from the expressions. -c2Args :: C.Expr a -> [Arg]-c2Args e = nub $ c2Args_ e- -- Kinds of arguments to SBV functions data Arg = Extern    C.Name-         | ExternFun C.Name+         | ExternFun C.Name C.Tag          | ExternArr C.Name          | Queue     C.Id   deriving Eq +-- | Normal argument calls. argToCall :: Arg -> [String]-argToCall (Extern name) = [mkExtTmpVar name]-argToCall (Queue id ) = [ mkQueueVar id -                        , mkQueuePtrVar id ]+argToCall (Extern name)        = [mkExtTmpVar name]+argToCall (ExternArr name)     = [mkExtTmpVar name]+argToCall (ExternFun name tag) = [mkExtTmpFun name tag]+argToCall (Queue id)           = [ mkQueueVar id +                                 , mkQueuePtrVar id ] +--------------------------------------------------------------------------------++collectArgs :: C.Expr a -> [String]+collectArgs e = concatMap argToCall (nub $ c2Args e)++-- extCollectArgs :: C.Expr a -> [String]+-- extCollectArgs e = nub (concatMap extArgToCall (c2Args e))++--------------------------------------------------------------------------------+ -- Gathers the names of the arguments to the SBV updateState function so that we -- can construct the prototypes. @@ -163,27 +165,33 @@ -- are pushed into the SBVCodeGen.  However, there should really be an API for -- getting the prototypes. +c2Args :: C.Expr a -> [Arg]+c2Args e = nub $ c2Args_ e+ c2Args_ :: C.Expr a -> [Arg] c2Args_ e0 = case e0 of-  C.Const _ _ -> [] +  C.Const _ _            -> []  -  C.Drop _ _ id -> [ Queue id ]+  C.Drop _ _ id          -> [ Queue id ]  -  C.Local _ _ _ e1 e2 -> c2Args_ e1 ++ c2Args_ e2+  C.Local _ _ _ e1 e2    -> c2Args_ e1 ++ c2Args_ e2 -  C.Var _ _ -> []+  C.Var _ _              -> [] -  C.ExternVar   _ name -> [Extern name]+  C.ExternVar   _ name _ -> [Extern name] -  C.ExternFun   _ name args _ -> -    ExternFun name : concatMap (\C.UExpr { C.uExprExpr = expr } -                                             -> c2Args expr) -                                        args+  C.ExternFun   _ name args _ tag -> +    (ExternFun name (fromJust tag)) : +      concatMap (\C.UExpr { C.uExprExpr = expr } +                     -> c2Args expr) +                args -  C.ExternArray _ _ name idx _ -> ExternArr name : c2Args_ idx+  C.ExternArray _ _ name _ _ _ _  -> [ExternArr name]  -  C.Op1 _ e -> c2Args_ e+  C.Op1 _ e        -> c2Args_ e -  C.Op2 _ e1 e2 -> c2Args_ e1 ++ c2Args_ e2+  C.Op2 _ e1 e2    -> c2Args_ e1 ++ c2Args_ e2    C.Op3 _ e1 e2 e3 -> c2Args_ e1 ++ c2Args_ e2 ++ c2Args_ e3++--------------------------------------------------------------------------------
src/Copilot/Compile/SBV/Witness.hs view
@@ -2,12 +2,14 @@ -- Copyright © 2011 National Institute of Aerospace / Galois, Inc. -------------------------------------------------------------------------------- -{-# LANGUAGE FlexibleContexts, GADTs #-}+{-# LANGUAGE FlexibleContexts, GADTs, MultiParamTypeClasses #-}  module Copilot.Compile.SBV.Witness   ( SymWordInst(..)       , symWordInst+  , NumInst(..)           , numInst   , HasSignAndSizeInst(..), hasSignAndSizeInst   , EqInst(..)            , eqInst +  , CastInst(..)          , castInst   , sbvCast   , BVDivisibleInst(..)   , divInst   , OrdInst(..)           , ordInst    , MergeableInst(..)     , mergeableInst @@ -18,6 +20,8 @@ import qualified Data.SBV.Internals as S import qualified Copilot.Core as C +import Data.Word (Word8, Word16, Word32, Word64)+import Data.Int (Int8, Int16, Int32, Int64) import Data.Bits  --------------------------------------------------------------------------------@@ -42,6 +46,21 @@  -------------------------------------------------------------------------------- +data NumInst a = Num a => NumInst++numInst :: C.Type a -> NumInst a+numInst t =+  case t of+    C.Bool   -> badInst+    C.Int8   -> NumInst ; C.Int16  -> NumInst+    C.Int32  -> NumInst ; C.Int64  -> NumInst+    C.Word8  -> NumInst ; C.Word16 -> NumInst+    C.Word32 -> NumInst ; C.Word64 -> NumInst+    C.Float  -> badInst+    C.Double -> badInst++--------------------------------------------------------------------------------+ data HasSignAndSizeInst a = S.HasSignAndSize a => HasSignAndSizeInst  hasSignAndSizeInst :: C.Type a -> HasSignAndSizeInst a@@ -139,3 +158,187 @@     C.Double -> badInst  --------------------------------------------------------------------------------++data CastInst a b = SBVCast a b => CastInst++castInst :: C.Type a -> C.Type b -> CastInst a b+castInst t0 t1 = +  case t0 of+    C.Bool   -> case t1 of+                  C.Bool    -> CastInst+                  C.Word8   -> CastInst+                  C.Word16  -> CastInst+                  C.Word32  -> CastInst+                  C.Word64  -> CastInst+                  C.Int8    -> CastInst+                  C.Int16   -> CastInst+                  C.Int32   -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst++    C.Word8  -> case t1 of+                  C.Word8   -> CastInst+                  C.Word16  -> CastInst+                  C.Word32  -> CastInst+                  C.Word64  -> CastInst+                  C.Int16   -> CastInst+                  C.Int32   -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Word16 -> case t1 of+                  C.Word16  -> CastInst+                  C.Word32  -> CastInst+                  C.Word64  -> CastInst+                  C.Int32   -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Word32 -> case t1 of+                  C.Word32  -> CastInst+                  C.Word64  -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Word64 -> case t1 of+                  C.Word64  -> CastInst+                  _         -> badInst++    C.Int8   -> case t1 of+                  C.Int8    -> CastInst+                  C.Int16   -> CastInst+                  C.Int32   -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Int16  -> case t1 of+                  C.Int16   -> CastInst+                  C.Int32   -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Int32  -> case t1 of+                  C.Int32   -> CastInst+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Int64  -> case t1 of+                  C.Int64   -> CastInst+                  _         -> badInst+    C.Float  -> badInst+    C.Double -> badInst++--------------------------------------------------------------------------------+-- | A class for casting SBV values.  We return errors for casts allowed by+-- Copilot.++class SBVCast a b where+  sbvCast :: S.SBV a -> S.SBV b++--------------------------------------------------------------------------------++castBool :: (Num a, S.SymWord a) => S.SBV Bool -> S.SBV a+castBool x = case S.unliteral x of+               Just bool -> if bool then 1 else 0+               Nothing   -> S.ite x 1 0++castErr :: a+castErr = C.badUsage $ "the SBV backend does not currently support casts to signed word types"++--------------------------------------------------------------------------------++instance SBVCast Bool Bool where+  sbvCast = id+instance SBVCast Bool Word8 where+  sbvCast = castBool+instance SBVCast Bool Word16 where+  sbvCast = castBool+instance SBVCast Bool Word32 where+  sbvCast = castBool+instance SBVCast Bool Word64 where+  sbvCast = castBool++instance SBVCast Bool Int8 where+  sbvCast = castErr +instance SBVCast Bool Int16 where+  sbvCast = castErr +instance SBVCast Bool Int32 where+  sbvCast = castErr +instance SBVCast Bool Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Word8 Word8 where+  sbvCast = id+instance SBVCast Word8 Word16 where+  sbvCast = S.extend+instance SBVCast Word8 Word32 where+  sbvCast = S.extend . S.extend+instance SBVCast Word8 Word64 where+  sbvCast = S.extend . S.extend . S.extend++instance SBVCast Word8 Int16 where+  sbvCast = castErr +instance SBVCast Word8 Int32 where+  sbvCast = castErr +instance SBVCast Word8 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Word16 Word16 where+  sbvCast = id+instance SBVCast Word16 Word32 where+  sbvCast = S.extend+instance SBVCast Word16 Word64 where+  sbvCast = S.extend . S.extend++instance SBVCast Word16 Int32 where+  sbvCast = castErr +instance SBVCast Word16 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Word32 Word32 where+  sbvCast = id+instance SBVCast Word32 Word64 where+  sbvCast = S.extend++instance SBVCast Word32 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Word64 Word64 where+  sbvCast = id++--------------------------------------------------------------------------------++instance SBVCast Int8 Int8 where+  sbvCast = castErr +instance SBVCast Int8 Int16 where+  sbvCast = castErr +instance SBVCast Int8 Int32 where+  sbvCast = castErr +instance SBVCast Int8 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Int16 Int16 where+  sbvCast = castErr +instance SBVCast Int16 Int32 where+  sbvCast = castErr +instance SBVCast Int16 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Int32 Int32 where+  sbvCast = castErr +instance SBVCast Int32 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------++instance SBVCast Int64 Int64 where+  sbvCast = castErr ++--------------------------------------------------------------------------------+