module Cudd.File (
DddmpVarInfoType(..),
DddmpMode(..),
DddmpVarMatchType(..),
cuddBddStore,
cuddBddLoad
) where
import Foreign.Storable
import Foreign.Ptr
import Foreign.C.Types
import Foreign.C.String
import Foreign.ForeignPtr
import Foreign.Marshal.Array
import Control.Monad
import Cudd.Cudd
import Cudd.C
data DddmpVarInfoType = DddmpVarids
| DddmpVarpermids
| DddmpVarauxids
| DddmpVarnames
| DddmpVardefault
deriving (Enum)
data DddmpMode = DddmpModeText
| DddmpModeBinary
| DddmpModeDefault
instance Enum DddmpMode where
succ DddmpModeText = DddmpModeBinary
succ DddmpModeBinary = DddmpModeDefault
succ DddmpModeDefault = error "DddmpMode.succ: DddmpModeDefault has no successor"
pred DddmpModeBinary = DddmpModeText
pred DddmpModeDefault = DddmpModeBinary
pred DddmpModeText = error "DddmpMode.pred: DddmpModeText has no predecessor"
enumFromTo from to = go from
where
end = fromEnum to
go v = case compare (fromEnum v) end of
LT -> v : go (succ v)
EQ -> [v]
GT -> []
enumFrom from = enumFromTo from DddmpModeDefault
fromEnum DddmpModeText = 65
fromEnum DddmpModeBinary = 66
fromEnum DddmpModeDefault = 68
toEnum 65 = DddmpModeText
toEnum 66 = DddmpModeBinary
toEnum 68 = DddmpModeDefault
toEnum unmatched = error ("DddmpMode.toEnum: Cannot match " ++ show unmatched)
foreign import ccall safe "Dddmp_cuddBddStore"
c_dddmpBddStore :: Ptr CDDManager -> CString -> Ptr CDDNode -> Ptr CString -> Ptr CInt -> CInt -> CInt -> CString -> Ptr CFile -> IO CInt
nullOnEmpty :: Storable a => [a] -> (Ptr a -> IO b) -> IO b
nullOnEmpty lst act =
case lst of
[] -> act nullPtr
_ -> withArray lst act
cuddBddStore :: DDManager -> String -> DDNode -> [Int] -> DddmpMode -> DddmpVarInfoType -> String -> IO Bool
cuddBddStore (DDManager m) name (DDNode node) auxids mode varinfo fname = liftM (/= 0) $
withCString name $ \pname ->
withForeignPtr node $ \dp ->
nullOnEmpty (map fromIntegral auxids) $ \pauxids ->
withCString fname $ \pfname ->
c_dddmpBddStore m pname dp nullPtr pauxids (fromIntegral $ fromEnum mode) (fromIntegral $ fromEnum varinfo) pfname nullPtr
data DddmpVarMatchType = DddmpVarMatchids
| DddmpVarMatchpermids
| DddmpVarMatchauxids
| DddmpVarMatchnames
| DddmpVarComposeids
deriving (Enum)
foreign import ccall safe "Dddmp_cuddBddLoad_s"
c_dddmpBddLoad :: Ptr CDDManager -> CInt -> Ptr CString -> Ptr CInt -> Ptr CInt -> CInt -> CString -> Ptr CFile -> IO (Ptr CDDNode)
cuddBddLoad :: DDManager -> DddmpVarMatchType -> [Int] -> [Int] -> DddmpMode -> String -> IO (Maybe DDNode)
cuddBddLoad (DDManager m) matchtype auxids composeids mode fname =
nullOnEmpty (map fromIntegral auxids) $ \pauxids ->
nullOnEmpty (map fromIntegral composeids) $ \pcomposeids ->
withCString fname $ \pfname -> do
node <- c_dddmpBddLoad m (fromIntegral $ fromEnum matchtype) nullPtr pauxids pcomposeids (fromIntegral $ fromEnum mode) pfname nullPtr
case node == nullPtr of
True -> return Nothing
False -> do
fp <- newForeignPtrEnv deref m node
return $ Just $ DDNode fp