mios-1.2.1: SAT/Solver/Mios/Types.hs
-- | Basic data types used throughout mios.
{-# LANGUAGE
BangPatterns
, FlexibleContexts
, FlexibleInstances
, FunctionalDependencies
, MultiParamTypeClasses
#-}
{-# LANGUAGE Trustworthy #-}
module SAT.Solver.Mios.Types
(
-- Singleton
module SAT.Solver.Mios.Data.Singleton
-- Fixed Unboxed Mutable Int Vector
, module SAT.Solver.Mios.Data.Vec
-- Abstract interfaces
, VectorFamily (..)
-- * Variable
, Var
, bottomVar
, int2var
-- * Internal encoded Literal
, Lit
, lit2int
, int2lit
, bottomLit
, newLit
, positiveLit
, lit2var
, var2lit
, negateLit
-- * Assignment
, LiftedBool (..)
, lbool
, lFalse
, lTrue
, lBottom
, VarOrder (..)
-- * CNF
, CNFDescription (..)
)
where
import Control.Monad (forM)
import Data.Bits
import qualified Data.Vector.Unboxed.Mutable as UV
import SAT.Solver.Mios.Data.Singleton
import SAT.Solver.Mios.Data.Vec
-- | Public interface as /Container/
class VectorFamily s t | s -> t where
-- * Size operations
-- | erases all elements in it
clear :: s -> IO ()
clear = error "no default method for clear"
-- * Debug
-- | dump the contents
dump :: Show t => String -> s -> IO String
dump msg _ = error $ msg ++ ": no defalut method for dump"
-- | get a raw data
asVec :: s -> UV.IOVector Int
asVec = error "asVector undefined"
-- | converts into a list
asList :: s -> IO [t]
asList = error "asList undefined"
{-# MINIMAL dump #-}
-- | provides 'clear' and 'size'
instance VectorFamily Vec Int where
clear = error "Vec.clear"
{-# SPECIALIZE INLINE asList :: Vec -> IO [Int] #-}
asList v = forM [0 .. UV.length v - 1] $ UV.unsafeRead v
dump str v = (str ++) . show <$> asList v
{-# SPECIALIZE INLINE asVec :: Vec -> Vec #-}
asVec = id
-- | represents "Var"
type Var = Int
-- | Special constant in 'Var' (p.7)
bottomVar :: Var
bottomVar = 0
-- | converts a usual Int as literal to an internal 'Var' presentation
--
-- >>> int2var 1
-- 1 -- the first literal is the first variable
-- >>> int2var 2
-- 2 -- literal @2@ is variable 2
-- >>> int2var (-2)
-- 2 -- literal @-2@ is corresponding to variable 2
--
{-# INLINE int2var #-}
int2var = abs
-- | The literal data has an 'index' method which converts the literal to
-- a "small" integer suitable for array indexing. The 'var' method returns
-- the underlying variable of the literal, and the 'sign' method if the literal
-- is signed (False for /x/ and True for /-x/).
type Lit = Int
-- | Special constant in 'Lit' (p.7)
bottomLit :: Lit
bottomLit = 0
-- | converts "Var" into 'Lit'
newLit :: Var -> Lit
newLit = error "newLit undefined"
-- | returns @True@ if the literal is positive
{-# INLINE positiveLit #-}
positiveLit :: Lit -> Bool
positiveLit = even
-- | negates literal
--
-- >>> negateLit 2
-- 3
-- >>> negateLit 3
-- 2
-- >>> negateLit 4
-- 5
-- >>> negateLit 5
-- 4
{-# INLINE negateLit #-}
negateLit :: Lit -> Lit
negateLit !l = complementBit l 0 -- if even l then l + 1 else l - 1
----------------------------------------
----------------- Var
----------------------------------------
-- | converts 'Lit' into 'Var'
--
-- >>> lit2var 2
-- 1
-- >>> lit2var 3
-- 1
-- >>> lit2var 4
-- 2
-- >>> lit2var 5
-- 2
{-# INLINE lit2var #-}
lit2var :: Lit -> Var
lit2var !n = shiftR n 1
-- | converts a 'Var' to the corresponing literal
--
-- >>> var2lit 1 True
-- 2
-- >>> var2lit 1 False
-- 3
-- >>> var2lit 2 True
-- 4
-- >>> var2lit 2 False
-- 5
{-# INLINE var2lit #-}
var2lit :: Var -> Bool -> Lit
var2lit !v True = shiftL v 1
var2lit !v _ = shiftL v 1 + 1
----------------------------------------
----------------- Int
----------------------------------------
-- | converts 'Int' into 'Lit' as @lit2int . int2lit == id@
--
-- >>> int2lit 1
-- 2
-- >>> int2lit (-1)
-- 3
-- >>> int2lit 2
-- 4
-- >>> int2lit (-2)
-- 5
--
{-# INLINE int2lit #-}
int2lit :: Int -> Lit
int2lit n
| 0 < n = 2 * n
| otherwise = -2 * n + 1
-- | converts `Lit' into 'Int' as @int2lit . lit2int == id@
--
-- >>> lit2int 2
-- 1
-- >>> lit2int 3
-- -1
-- >>> lit2int 4
-- 2
-- >>> lit2int 5
-- -2
{-# INLINE lit2int #-}
lit2int :: Lit -> Int
lit2int l = case divMod l 2 of
(i, 0) -> i
(i, _) -> - i
-- | Lifted Boolean domain (p.7) that extends 'Bool' with "⊥" means /undefined/
-- design note: _|_ should be null = 0; True literals are coded to even numbers. So it should be 2.
data LiftedBool = Bottom | LFalse | LTrue
deriving (Bounded, Eq, Ord, Read, Show)
instance Enum LiftedBool where
{-# SPECIALIZE INLINE toEnum :: Int -> LiftedBool #-}
toEnum 1 = LTrue
toEnum (-1) = LFalse
toEnum _ = Bottom
{-# SPECIALIZE INLINE fromEnum :: LiftedBool -> Int #-}
fromEnum Bottom = 0
fromEnum LFalse = 1
fromEnum LTrue = 2
-- | converts 'Bool' into 'LBool'
{-# INLINE lbool #-}
lbool :: Bool -> LiftedBool
lbool True = LTrue
lbool False = LFalse
-- | A contant representing False
lFalse:: Int
lFalse = -1
-- | A constant representing True
lTrue :: Int
lTrue = 1
-- | A constant for "undefined"
lBottom :: Int
lBottom = 0
-- | Assisting ADT for the dynamic variable ordering of the solver.
-- The constructor takes references to the assignment vector and the activity
-- vector of the solver. The method 'select' will return the unassigned variable
-- with the highest activity.
class VarOrder o where
-- | constructor
newVarOrder :: (VectorFamily v1 Bool, VectorFamily v2 Double) => v1 -> v2 -> IO o
newVarOrder _ _ = error "newVarOrder undefined"
-- | Called when a new variable is created.
newVar :: o -> IO Var
newVar = error "newVar undefined"
-- | Called when variable has increased in activity.
update :: o -> Var -> IO ()
update _ = error "update undefined"
-- | Called when all variables have been assigned new activities.
updateAll :: o -> IO ()
updateAll = error "updateAll undefined"
-- | Called when variable is unbound (may be selected again).
undo :: o -> Var -> IO ()
undo _ _ = error "undo undefined"
-- | Called to select a new, unassigned variable.
select :: o -> IO Var
select = error "select undefined"
-- | misc information on CNF
data CNFDescription = CNFDescription
{
_numberOfVariables :: !Int -- ^ number of variables
, _numberOfClauses :: !Int -- ^ number of clauses
, _pathname :: Maybe FilePath -- ^ given filename
}
deriving (Eq, Ord, Show)