monadiccp-0.6: Control/CP/FD/Gecode/Interface.hsc
{-# LANGUAGE CPP #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# CFILES glue/interface.cpp #-}
module Control.CP.FD.Gecode.Interface (
CGOperator(..),
CGIntVar(..),
CGBoolVar(..),
CGBool(..),
CGVal(..),
toCGIntVar,
toCGBoolVar,
toCGVal,
fromCGVal,
toCGBool,
fromCGBool,
Space,
Search,
newSpace,
copySpace,
newSearch,
runSearch,
IntTermInfo(..),
getIntTermInfo,
mapGOperator,
c_gecode_int_dom,
c_gecode_int_rel,
c_gecode_int_rel_cf,
c_gecode_int_rel_cs,
c_gecode_int_value,
c_gecode_int_mult,
c_gecode_int_div,
c_gecode_int_mod,
c_gecode_int_abs,
c_gecode_int_linear,
c_gecode_int_alldiff,
c_gecode_int_sorted,
c_gecode_int_newvar,
c_gecode_int_branch,
c_gecode_bool_newvar
) where
#ifdef RGECODE
import Foreign
import Foreign.C
import Foreign.C.Types
import Foreign.ForeignPtr
import Control.CP.FD.Gecode.Common
#include "gecodeglue.h"
newtype CGOperator = CGOperator CInt
deriving Storable
newtype CGIntVar = CGIntVar CInt
deriving Storable
newtype CGBoolVar = CGBoolVar CInt
deriving Storable
newtype CGBool = CGBool CInt
deriving Storable
newtype CGVal = CGVal CInt
deriving Storable
mapGOperator :: GOperator -> CGOperator
mapGOperator OEqual = CGOperator #const GOPERATOR_OEQUAL
mapGOperator ODiff = CGOperator #const GOPERATOR_ODIFF
mapGOperator OLess = CGOperator #const GOPERATOR_OLESS
newtype GecodeModel = GecodeModel (Ptr GecodeModel)
newtype GecodeSearch = GecodeSearch (Ptr GecodeSearch)
foreign import ccall unsafe "gecode_model_create" c_gecode_model_create :: IO (Ptr GecodeModel)
foreign import ccall unsafe "gecode_model_destroy" c_gecode_model_destroy :: Ptr GecodeModel -> IO ()
foreign import ccall unsafe "&gecode_model_destroy" c_gecode_model_finalize :: FunPtr (Ptr GecodeModel -> IO ())
foreign import ccall unsafe "gecode_model_copy" c_gecode_model_copy :: Ptr GecodeModel -> IO (Ptr GecodeModel)
foreign import ccall unsafe "gecode_model_fail" c_gecode_model_fail :: Ptr GecodeModel -> IO ()
foreign import ccall unsafe "gecode_int_newvar" c_gecode_int_newvar :: Ptr GecodeModel -> IO CGIntVar
foreign import ccall unsafe "gecode_int_rel" c_gecode_int_rel :: Ptr GecodeModel -> CGIntVar -> CGOperator -> CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_rel_cf" c_gecode_int_rel_cf :: Ptr GecodeModel -> CGVal -> CGOperator -> CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_rel_cs" c_gecode_int_rel_cs :: Ptr GecodeModel -> CGIntVar -> CGOperator -> CGVal -> IO CGBool
foreign import ccall unsafe "gecode_int_value" c_gecode_int_value :: Ptr GecodeModel -> CGIntVar -> CGVal -> IO CGBool
foreign import ccall unsafe "gecode_int_mult" c_gecode_int_mult :: Ptr GecodeModel -> CGIntVar -> CGIntVar -> CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_div" c_gecode_int_div :: Ptr GecodeModel -> CGIntVar -> CGIntVar -> CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_mod" c_gecode_int_mod :: Ptr GecodeModel -> CGIntVar -> CGIntVar -> CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_abs" c_gecode_int_abs :: Ptr GecodeModel -> CGIntVar -> CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_dom" c_gecode_int_dom :: Ptr GecodeModel -> CGIntVar -> CGVal -> CGVal -> IO CGBool
foreign import ccall unsafe "gecode_int_linear" c_gecode_int_linear :: Ptr GecodeModel -> CInt -> Ptr CGIntVar -> Ptr CGVal -> CGOperator -> CGVal -> IO CGBool
foreign import ccall unsafe "gecode_int_alldiff" c_gecode_int_alldiff :: Ptr GecodeModel -> CInt -> Ptr CGIntVar -> IO CGBool
foreign import ccall unsafe "gecode_int_sorted" c_gecode_int_sorted :: Ptr GecodeModel -> CInt -> Ptr CGIntVar -> CGBool -> IO CGBool
foreign import ccall unsafe "gecode_int_info" c_gecode_int_info :: Ptr GecodeModel -> CGIntVar -> Ptr CGVal -> Ptr CGVal -> Ptr CGVal -> Ptr CInt -> Ptr CGVal -> IO ()
foreign import ccall unsafe "gecode_int_branch" c_gecode_int_branch :: Ptr GecodeModel -> CInt -> Ptr CGIntVar -> IO ()
foreign import ccall unsafe "gecode_bool_newvar" c_gecode_bool_newvar :: Ptr GecodeModel -> IO CGBoolVar
foreign import ccall unsafe "gecode_bool_branch" c_gecode_bool_branch :: Ptr GecodeModel -> CInt -> Ptr CGBoolVar -> IO ()
foreign import ccall unsafe "gecode_search_create" c_gecode_search_create :: Ptr GecodeModel -> IO (Ptr GecodeSearch)
foreign import ccall unsafe "&gecode_search_destroy" c_gecode_search_finalize :: FunPtr (Ptr GecodeSearch -> IO ())
foreign import ccall unsafe "gecode_search_destroy" c_gecode_search_destroy :: Ptr GecodeSearch -> IO ()
foreign import ccall unsafe "gecode_search_next" c_gecode_search_next :: Ptr GecodeSearch -> IO (Ptr GecodeModel)
---- accessor functions
toCGIntVar :: Integral a => a -> CGIntVar
toCGIntVar n = CGIntVar $ fromIntegral n
toCGBoolVar :: Integral a => a -> CGBoolVar
toCGBoolVar n = CGBoolVar $ fromIntegral n
toCGVal :: Integral a => a -> CGVal
toCGVal n = CGVal $ fromIntegral n
fromCGVal :: Num a => CGVal -> a
fromCGVal (CGVal x) = fromIntegral x
toCGBool :: Bool -> CGBool
toCGBool n = CGBool $ if n then 1 else 0
fromCGBool :: CGBool -> Bool
fromCGBool (CGBool x) = x /= 0
type Space = ForeignPtr GecodeModel
type Search = ForeignPtr GecodeSearch
newSpace :: IO Space
newSpace = do
x <- c_gecode_model_create
newForeignPtr c_gecode_model_finalize x
copySpace :: Space -> IO Space
copySpace s = withForeignPtr s $ \ptr -> do
x <- c_gecode_model_copy ptr
newForeignPtr c_gecode_model_finalize x
newSearch :: Space -> IO Search
newSearch s = withForeignPtr s $ \ptr -> do
x <- c_gecode_search_create ptr
newForeignPtr c_gecode_search_finalize x
runSearch :: Search -> IO (Maybe Space)
runSearch s = withForeignPtr s $ \ptr -> do
x <- c_gecode_search_next ptr
if (x == nullPtr)
then return Nothing
else do
res <- newForeignPtr c_gecode_model_finalize x
return $ Just res
data IntTermInfo = IntTermInfo { iti_low :: CInt, iti_high :: CInt, iti_med :: CInt, iti_size :: CInt, iti_val :: Maybe CInt }
getIntTermInfo :: Integral a => Space -> a -> IO IntTermInfo
getIntTermInfo s i = do
alloca $ \pLow ->
alloca $ \pHigh ->
alloca $ \pMed ->
alloca $ \pSize ->
alloca $ \pVal -> do
withForeignPtr s $ \ptr -> c_gecode_int_info ptr (toCGIntVar i) pLow pHigh pMed pSize pVal
vLow <- peek pLow
vHigh <- peek pHigh
vMed <- peek pMed
vSize <- peek pSize
vVal <- peek pVal
return $ IntTermInfo {
iti_low = fromCGVal vLow,
iti_high = fromCGVal vHigh,
iti_med = fromCGVal vMed,
iti_size = fromIntegral vSize,
iti_val = if (vSize==1) then Just (fromCGVal vVal) else Nothing
}
#endif