packages feed

mios 1.2.1 → 1.3.0

raw patch · 41 files changed

+3654/−3760 lines, 41 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- SAT.Solver.Mios: CNFDescription :: !Int -> !Int -> Maybe FilePath -> CNFDescription
- SAT.Solver.Mios: [_numberOfClauses] :: CNFDescription -> !Int
- SAT.Solver.Mios: [_numberOfVariables] :: CNFDescription -> !Int
- SAT.Solver.Mios: [_pathname] :: CNFDescription -> Maybe FilePath
- SAT.Solver.Mios: data CNFDescription
- SAT.Solver.Mios: dumpAssigmentAsCNF :: FilePath -> Bool -> [Int] -> IO ()
- SAT.Solver.Mios: executeSolver :: MiosProgramOption -> IO ()
- SAT.Solver.Mios: executeSolverOn :: FilePath -> IO ()
- SAT.Solver.Mios: executeValidator :: MiosProgramOption -> IO ()
- SAT.Solver.Mios: executeValidatorOn :: FilePath -> IO ()
- SAT.Solver.Mios: getModel :: Solver -> IO [Int]
- SAT.Solver.Mios: runSolver :: Traversable t => MiosConfiguration -> CNFDescription -> t [Int] -> IO (Either [Int] [Int])
- SAT.Solver.Mios: solve :: (Foldable t) => Solver -> t Lit -> IO Bool
- SAT.Solver.Mios: solveSAT :: Traversable m => CNFDescription -> m [Int] -> IO [Int]
- SAT.Solver.Mios: solveSATWithConfiguration :: Traversable m => MiosConfiguration -> CNFDescription -> m [Int] -> IO [Int]
- SAT.Solver.Mios: validate :: Traversable t => Solver -> t Int -> IO Bool
- SAT.Solver.Mios: validateAssignment :: (Traversable m, Traversable n) => CNFDescription -> m [Int] -> n Int -> IO Bool
- SAT.Solver.Mios: versionId :: String
- SAT.Solver.Mios.Clause: Clause :: !Bool -> !DoubleSingleton -> !BoolSingleton -> !IntSingleton -> !Vec -> Clause
- SAT.Solver.Mios.Clause: NullClause :: Clause
- SAT.Solver.Mios.Clause: [activity] :: Clause -> !DoubleSingleton
- SAT.Solver.Mios.Clause: [lbd] :: Clause -> !IntSingleton
- SAT.Solver.Mios.Clause: [learnt] :: Clause -> !Bool
- SAT.Solver.Mios.Clause: [lits] :: Clause -> !Vec
- SAT.Solver.Mios.Clause: [protected] :: Clause -> !BoolSingleton
- SAT.Solver.Mios.Clause: data Clause
- SAT.Solver.Mios.Clause: getNthClause :: ClauseVector -> Int -> IO Clause
- SAT.Solver.Mios.Clause: instance GHC.Classes.Eq SAT.Solver.Mios.Clause.Clause
- SAT.Solver.Mios.Clause: instance GHC.Show.Show SAT.Solver.Mios.Clause.Clause
- SAT.Solver.Mios.Clause: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.Clause.Clause SAT.Solver.Mios.Types.Lit
- SAT.Solver.Mios.Clause: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.Clause.ClauseVector SAT.Solver.Mios.Clause.Clause
- SAT.Solver.Mios.Clause: newClauseFromVec :: Bool -> Vec -> IO Clause
- SAT.Solver.Mios.Clause: newClauseVector :: Int -> IO ClauseVector
- SAT.Solver.Mios.Clause: setNthClause :: ClauseVector -> Int -> Clause -> IO ()
- SAT.Solver.Mios.Clause: shrinkClause :: Int -> Clause -> IO ()
- SAT.Solver.Mios.Clause: sizeOfClause :: Clause -> IO Int
- SAT.Solver.Mios.Clause: swapClauses :: ClauseVector -> Int -> Int -> IO ()
- SAT.Solver.Mios.Clause: type ClauseVector = IOVector Clause
- SAT.Solver.Mios.ClauseManager: class ClauseManager a
- SAT.Solver.Mios.ClauseManager: clearManager :: ClauseManager a => a -> IO ()
- SAT.Solver.Mios.ClauseManager: data ClauseExtManager
- SAT.Solver.Mios.ClauseManager: garbageCollect :: WatcherList -> IO ()
- SAT.Solver.Mios.ClauseManager: getClauseVector :: ClauseManager a => a -> IO ClauseVector
- SAT.Solver.Mios.ClauseManager: getKeyVector :: ClauseExtManager -> IO Vec
- SAT.Solver.Mios.ClauseManager: getNthWatcher :: WatcherList -> Lit -> ClauseExtManager
- SAT.Solver.Mios.ClauseManager: instance SAT.Solver.Mios.ClauseManager.ClauseManager SAT.Solver.Mios.ClauseManager.ClauseExtManager
- SAT.Solver.Mios.ClauseManager: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.ClauseManager.ClauseExtManager SAT.Solver.Mios.Clause.Clause
- SAT.Solver.Mios.ClauseManager: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.ClauseManager.WatcherList SAT.Solver.Mios.Clause.Clause
- SAT.Solver.Mios.ClauseManager: markClause :: ClauseExtManager -> Clause -> IO ()
- SAT.Solver.Mios.ClauseManager: newManager :: ClauseManager a => Int -> IO a
- SAT.Solver.Mios.ClauseManager: newWatcherList :: Int -> Int -> IO WatcherList
- SAT.Solver.Mios.ClauseManager: numberOfClauses :: ClauseManager a => a -> IO Int
- SAT.Solver.Mios.ClauseManager: pushClause :: ClauseManager a => a -> Clause -> IO ()
- SAT.Solver.Mios.ClauseManager: pushClauseWithKey :: ClauseExtManager -> Clause -> Lit -> IO ()
- SAT.Solver.Mios.ClauseManager: shrinkManager :: ClauseManager a => a -> Int -> IO ()
- SAT.Solver.Mios.ClauseManager: type WatcherList = Vector ClauseExtManager
- SAT.Solver.Mios.Data.Singleton: getBool :: BoolSingleton -> IO Bool
- SAT.Solver.Mios.Data.Singleton: getDouble :: DoubleSingleton -> IO Double
- SAT.Solver.Mios.Data.Singleton: getInt :: IntSingleton -> IO Int
- SAT.Solver.Mios.Data.Singleton: modifyBool :: BoolSingleton -> (Bool -> Bool) -> IO ()
- SAT.Solver.Mios.Data.Singleton: modifyDouble :: DoubleSingleton -> (Double -> Double) -> IO ()
- SAT.Solver.Mios.Data.Singleton: modifyInt :: IntSingleton -> (Int -> Int) -> IO ()
- SAT.Solver.Mios.Data.Singleton: newBool :: Bool -> IO BoolSingleton
- SAT.Solver.Mios.Data.Singleton: newDouble :: Double -> IO DoubleSingleton
- SAT.Solver.Mios.Data.Singleton: newInt :: Int -> IO IntSingleton
- SAT.Solver.Mios.Data.Singleton: setBool :: BoolSingleton -> Bool -> IO ()
- SAT.Solver.Mios.Data.Singleton: setDouble :: DoubleSingleton -> Double -> IO ()
- SAT.Solver.Mios.Data.Singleton: setInt :: IntSingleton -> Int -> IO ()
- SAT.Solver.Mios.Data.Singleton: type BoolSingleton = IOVector Bool
- SAT.Solver.Mios.Data.Singleton: type DoubleSingleton = IOVector Double
- SAT.Solver.Mios.Data.Singleton: type IntSingleton = IOVector Int
- SAT.Solver.Mios.Data.Stack: asSizedVec :: Stack -> Vec
- SAT.Solver.Mios.Data.Stack: clearStack :: Stack -> IO ()
- SAT.Solver.Mios.Data.Stack: data Stack
- SAT.Solver.Mios.Data.Stack: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.Data.Stack.Stack GHC.Types.Int
- SAT.Solver.Mios.Data.Stack: isoVec :: Stack -> IO Vec
- SAT.Solver.Mios.Data.Stack: lastOfStack :: Stack -> IO Int
- SAT.Solver.Mios.Data.Stack: newStack :: Int -> IO Stack
- SAT.Solver.Mios.Data.Stack: popFromStack :: Stack -> IO ()
- SAT.Solver.Mios.Data.Stack: pushToStack :: Stack -> Int -> IO ()
- SAT.Solver.Mios.Data.Stack: shrinkStack :: Stack -> Int -> IO ()
- SAT.Solver.Mios.Data.Stack: sizeOfStack :: Stack -> IO Int
- SAT.Solver.Mios.Data.Vec: getNth :: Vec -> Int -> IO Int
- SAT.Solver.Mios.Data.Vec: modifyNth :: Vec -> (Int -> Int) -> Int -> IO ()
- SAT.Solver.Mios.Data.Vec: newSizedVecIntFromList :: [Int] -> IO Vec
- SAT.Solver.Mios.Data.Vec: newSizedVecIntFromUVector :: Vector Int -> IO Vec
- SAT.Solver.Mios.Data.Vec: newVec :: Int -> IO Vec
- SAT.Solver.Mios.Data.Vec: newVecWith :: Int -> Int -> IO Vec
- SAT.Solver.Mios.Data.Vec: setAll :: Vec -> Int -> IO ()
- SAT.Solver.Mios.Data.Vec: setNth :: Vec -> Int -> Int -> IO ()
- SAT.Solver.Mios.Data.Vec: sizeOfVector :: Vec -> IO Int
- SAT.Solver.Mios.Data.Vec: swapBetween :: Vec -> Int -> Int -> IO ()
- SAT.Solver.Mios.Data.Vec: type Vec = IOVector Int
- SAT.Solver.Mios.Data.Vec: vecGrow :: Vec -> Int -> IO Vec
- SAT.Solver.Mios.Data.VecBool: getNthBool :: VecBool -> Int -> IO Bool
- SAT.Solver.Mios.Data.VecBool: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.Data.VecBool.VecBool GHC.Types.Bool
- SAT.Solver.Mios.Data.VecBool: modifyNthBool :: VecBool -> (Bool -> Bool) -> Int -> IO ()
- SAT.Solver.Mios.Data.VecBool: newVecBool :: Int -> Bool -> IO VecBool
- SAT.Solver.Mios.Data.VecBool: setNthBool :: VecBool -> Int -> Bool -> IO ()
- SAT.Solver.Mios.Data.VecBool: type VecBool = IOVector Bool
- SAT.Solver.Mios.Data.VecDouble: getNthDouble :: Int -> VecDouble -> IO Double
- SAT.Solver.Mios.Data.VecDouble: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.Data.VecDouble.VecDouble GHC.Types.Double
- SAT.Solver.Mios.Data.VecDouble: modifyNthDouble :: Int -> VecDouble -> (Double -> Double) -> IO ()
- SAT.Solver.Mios.Data.VecDouble: newVecDouble :: Int -> Double -> IO VecDouble
- SAT.Solver.Mios.Data.VecDouble: setNthDouble :: Int -> VecDouble -> Double -> IO ()
- SAT.Solver.Mios.Data.VecDouble: type VecDouble = IOVector Double
- SAT.Solver.Mios.Glucose: computeLBD :: Solver -> Vec -> IO Int
- SAT.Solver.Mios.Glucose: lbdOf :: Solver -> Clause -> IO Int
- SAT.Solver.Mios.Glucose: nextReduction :: Int -> Int -> Int
- SAT.Solver.Mios.Glucose: setLBD :: Solver -> Clause -> IO ()
- SAT.Solver.Mios.Glucose: updateLBD :: Solver -> Clause -> IO ()
- SAT.Solver.Mios.Internal: MiosConfiguration :: Double -> Double -> Bool -> MiosConfiguration
- SAT.Solver.Mios.Internal: [clauseDecayRate] :: MiosConfiguration -> Double
- SAT.Solver.Mios.Internal: [collectStats] :: MiosConfiguration -> Bool
- SAT.Solver.Mios.Internal: [variableDecayRate] :: MiosConfiguration -> Double
- SAT.Solver.Mios.Internal: data MiosConfiguration
- SAT.Solver.Mios.Internal: defaultConfiguration :: MiosConfiguration
- SAT.Solver.Mios.Internal: versionId :: String
- SAT.Solver.Mios.M114: simplifyDB :: Solver -> IO Bool
- SAT.Solver.Mios.M114: solve :: (Foldable t) => Solver -> t Lit -> IO Bool
- SAT.Solver.Mios.OptionParser: MiosConfiguration :: Double -> Double -> Bool -> MiosConfiguration
- SAT.Solver.Mios.OptionParser: MiosProgramOption :: Maybe String -> Maybe String -> Double -> Double -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> MiosProgramOption
- SAT.Solver.Mios.OptionParser: [_confCheckAnswer] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_confClauseDecayRate] :: MiosProgramOption -> Double
- SAT.Solver.Mios.OptionParser: [_confNoAnswer] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_confStatProbe] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_confTimeProbe] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_confVariableDecayRate] :: MiosProgramOption -> Double
- SAT.Solver.Mios.OptionParser: [_confVerbose] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_displayHelp] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_displayVersion] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [_outputFile] :: MiosProgramOption -> Maybe String
- SAT.Solver.Mios.OptionParser: [_targetFile] :: MiosProgramOption -> Maybe String
- SAT.Solver.Mios.OptionParser: [_validateAssignment] :: MiosProgramOption -> Bool
- SAT.Solver.Mios.OptionParser: [clauseDecayRate] :: MiosConfiguration -> Double
- SAT.Solver.Mios.OptionParser: [collectStats] :: MiosConfiguration -> Bool
- SAT.Solver.Mios.OptionParser: [variableDecayRate] :: MiosConfiguration -> Double
- SAT.Solver.Mios.OptionParser: data MiosConfiguration
- SAT.Solver.Mios.OptionParser: data MiosProgramOption
- SAT.Solver.Mios.OptionParser: defaultConfiguration :: MiosConfiguration
- SAT.Solver.Mios.OptionParser: miosDefaultOption :: MiosProgramOption
- SAT.Solver.Mios.OptionParser: miosOptions :: [OptDescr (MiosProgramOption -> MiosProgramOption)]
- SAT.Solver.Mios.OptionParser: miosParseOptions :: String -> [String] -> IO MiosProgramOption
- SAT.Solver.Mios.OptionParser: miosParseOptionsFromArgs :: String -> IO MiosProgramOption
- SAT.Solver.Mios.OptionParser: miosUsage :: String -> String
- SAT.Solver.Mios.OptionParser: toMiosConf :: MiosProgramOption -> MiosConfiguration
- SAT.Solver.Mios.Solver: NumOfBackjump :: StatIndex
- SAT.Solver.Mios.Solver: NumOfRestart :: StatIndex
- SAT.Solver.Mios.Solver: Solver :: !VecBool -> !Stack -> !ClauseExtManager -> !ClauseExtManager -> !WatcherList -> !Vec -> !Vec -> !Stack -> !Stack -> !IntSingleton -> !ClauseVector -> !Vec -> !VecDouble -> !VarHeap -> !MiosConfiguration -> !Int -> !DoubleSingleton -> !DoubleSingleton -> !IntSingleton -> !BoolSingleton -> !Vec -> !Stack -> !Stack -> !Vec -> !Vec -> !IntSingleton -> !Stack -> !Stack -> !Vec -> Solver
- SAT.Solver.Mios.Solver: [activities] :: Solver -> !VecDouble
- SAT.Solver.Mios.Solver: [an'seen] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [an'stack] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [an'toClear] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [assigns] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [claInc] :: Solver -> !DoubleSingleton
- SAT.Solver.Mios.Solver: [clauses] :: Solver -> !ClauseExtManager
- SAT.Solver.Mios.Solver: [config] :: Solver -> !MiosConfiguration
- SAT.Solver.Mios.Solver: [conflict] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [lastDL] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [lbd'key] :: Solver -> !IntSingleton
- SAT.Solver.Mios.Solver: [lbd'seen] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [learnts] :: Solver -> !ClauseExtManager
- SAT.Solver.Mios.Solver: [level] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [litsLearnt] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [model] :: Solver -> !VecBool
- SAT.Solver.Mios.Solver: [nVars] :: Solver -> !Int
- SAT.Solver.Mios.Solver: [ok] :: Solver -> !BoolSingleton
- SAT.Solver.Mios.Solver: [order] :: Solver -> !VarHeap
- SAT.Solver.Mios.Solver: [phases] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [pr'seen] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [qHead] :: Solver -> !IntSingleton
- SAT.Solver.Mios.Solver: [reason] :: Solver -> !ClauseVector
- SAT.Solver.Mios.Solver: [rootLevel] :: Solver -> !IntSingleton
- SAT.Solver.Mios.Solver: [stats] :: Solver -> !Vec
- SAT.Solver.Mios.Solver: [trailLim] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [trail] :: Solver -> !Stack
- SAT.Solver.Mios.Solver: [varInc] :: Solver -> !DoubleSingleton
- SAT.Solver.Mios.Solver: [watches] :: Solver -> !WatcherList
- SAT.Solver.Mios.Solver: addClause :: Solver -> Vec -> IO Bool
- SAT.Solver.Mios.Solver: assume :: Solver -> Lit -> IO Bool
- SAT.Solver.Mios.Solver: cancelUntil :: Solver -> Int -> IO ()
- SAT.Solver.Mios.Solver: claBumpActivity :: Solver -> Clause -> IO ()
- SAT.Solver.Mios.Solver: claDecayActivity :: Solver -> IO ()
- SAT.Solver.Mios.Solver: data Solver
- SAT.Solver.Mios.Solver: data StatIndex
- SAT.Solver.Mios.Solver: data VarHeap
- SAT.Solver.Mios.Solver: decisionLevel :: Solver -> IO Int
- SAT.Solver.Mios.Solver: enqueue :: Solver -> Lit -> Clause -> IO Bool
- SAT.Solver.Mios.Solver: getModel :: Solver -> IO [Int]
- SAT.Solver.Mios.Solver: getStats :: Solver -> IO [(StatIndex, Int)]
- SAT.Solver.Mios.Solver: incrementStat :: Solver -> StatIndex -> Int -> IO ()
- SAT.Solver.Mios.Solver: instance GHC.Classes.Eq SAT.Solver.Mios.Solver.StatIndex
- SAT.Solver.Mios.Solver: instance GHC.Classes.Ord SAT.Solver.Mios.Solver.StatIndex
- SAT.Solver.Mios.Solver: instance GHC.Enum.Bounded SAT.Solver.Mios.Solver.StatIndex
- SAT.Solver.Mios.Solver: instance GHC.Enum.Enum SAT.Solver.Mios.Solver.StatIndex
- SAT.Solver.Mios.Solver: instance GHC.Read.Read SAT.Solver.Mios.Solver.StatIndex
- SAT.Solver.Mios.Solver: instance GHC.Show.Show SAT.Solver.Mios.Solver.StatIndex
- SAT.Solver.Mios.Solver: instance SAT.Solver.Mios.Types.VarOrder SAT.Solver.Mios.Solver.Solver
- SAT.Solver.Mios.Solver: locked :: Solver -> Clause -> IO Bool
- SAT.Solver.Mios.Solver: nAssigns :: Solver -> IO Int
- SAT.Solver.Mios.Solver: nClauses :: Solver -> IO Int
- SAT.Solver.Mios.Solver: nLearnts :: Solver -> IO Int
- SAT.Solver.Mios.Solver: newSolver :: MiosConfiguration -> CNFDescription -> IO Solver
- SAT.Solver.Mios.Solver: valueLit :: Solver -> Lit -> IO Int
- SAT.Solver.Mios.Solver: valueVar :: Solver -> Var -> IO Int
- SAT.Solver.Mios.Solver: varBumpActivity :: Solver -> Var -> IO ()
- SAT.Solver.Mios.Solver: varDecayActivity :: Solver -> IO ()
- SAT.Solver.Mios.Types: Bottom :: LiftedBool
- SAT.Solver.Mios.Types: CNFDescription :: !Int -> !Int -> Maybe FilePath -> CNFDescription
- SAT.Solver.Mios.Types: LFalse :: LiftedBool
- SAT.Solver.Mios.Types: LTrue :: LiftedBool
- SAT.Solver.Mios.Types: [_numberOfClauses] :: CNFDescription -> !Int
- SAT.Solver.Mios.Types: [_numberOfVariables] :: CNFDescription -> !Int
- SAT.Solver.Mios.Types: [_pathname] :: CNFDescription -> Maybe FilePath
- SAT.Solver.Mios.Types: asList :: VectorFamily s t => s -> IO [t]
- SAT.Solver.Mios.Types: asVec :: VectorFamily s t => s -> IOVector Int
- SAT.Solver.Mios.Types: bottomLit :: Lit
- SAT.Solver.Mios.Types: bottomVar :: Var
- SAT.Solver.Mios.Types: class VarOrder o where newVarOrder _ _ = error "newVarOrder undefined" newVar = error "newVar undefined" update _ = error "update undefined" updateAll = error "updateAll undefined" undo _ _ = error "undo undefined" select = error "select undefined"
- SAT.Solver.Mios.Types: class VectorFamily s t | s -> t where clear = error "no default method for clear" dump msg _ = error $ msg ++ ": no defalut method for dump" asVec = error "asVector undefined" asList = error "asList undefined"
- SAT.Solver.Mios.Types: clear :: VectorFamily s t => s -> IO ()
- SAT.Solver.Mios.Types: data CNFDescription
- SAT.Solver.Mios.Types: data LiftedBool
- SAT.Solver.Mios.Types: dump :: (VectorFamily s t, Show t) => String -> s -> IO String
- SAT.Solver.Mios.Types: instance GHC.Classes.Eq SAT.Solver.Mios.Types.CNFDescription
- SAT.Solver.Mios.Types: instance GHC.Classes.Eq SAT.Solver.Mios.Types.LiftedBool
- SAT.Solver.Mios.Types: instance GHC.Classes.Ord SAT.Solver.Mios.Types.CNFDescription
- SAT.Solver.Mios.Types: instance GHC.Classes.Ord SAT.Solver.Mios.Types.LiftedBool
- SAT.Solver.Mios.Types: instance GHC.Enum.Bounded SAT.Solver.Mios.Types.LiftedBool
- SAT.Solver.Mios.Types: instance GHC.Enum.Enum SAT.Solver.Mios.Types.LiftedBool
- SAT.Solver.Mios.Types: instance GHC.Read.Read SAT.Solver.Mios.Types.LiftedBool
- SAT.Solver.Mios.Types: instance GHC.Show.Show SAT.Solver.Mios.Types.CNFDescription
- SAT.Solver.Mios.Types: instance GHC.Show.Show SAT.Solver.Mios.Types.LiftedBool
- SAT.Solver.Mios.Types: instance SAT.Solver.Mios.Types.VectorFamily SAT.Solver.Mios.Data.Vec.Vec GHC.Types.Int
- SAT.Solver.Mios.Types: int2lit :: Int -> Lit
- SAT.Solver.Mios.Types: int2var :: Integer -> Integer
- SAT.Solver.Mios.Types: lBottom :: Int
- SAT.Solver.Mios.Types: lFalse :: Int
- SAT.Solver.Mios.Types: lTrue :: Int
- SAT.Solver.Mios.Types: lbool :: Bool -> LiftedBool
- SAT.Solver.Mios.Types: lit2int :: Lit -> Int
- SAT.Solver.Mios.Types: lit2var :: Lit -> Var
- SAT.Solver.Mios.Types: negateLit :: Lit -> Lit
- SAT.Solver.Mios.Types: newLit :: Var -> Lit
- SAT.Solver.Mios.Types: newVar :: VarOrder o => o -> IO Var
- SAT.Solver.Mios.Types: newVarOrder :: (VarOrder o, VectorFamily v1 Bool, VectorFamily v2 Double) => v1 -> v2 -> IO o
- SAT.Solver.Mios.Types: positiveLit :: Lit -> Bool
- SAT.Solver.Mios.Types: select :: VarOrder o => o -> IO Var
- SAT.Solver.Mios.Types: type Lit = Int
- SAT.Solver.Mios.Types: type Var = Int
- SAT.Solver.Mios.Types: undo :: VarOrder o => o -> Var -> IO ()
- SAT.Solver.Mios.Types: update :: VarOrder o => o -> Var -> IO ()
- SAT.Solver.Mios.Types: updateAll :: VarOrder o => o -> IO ()
- SAT.Solver.Mios.Types: var2lit :: Var -> Bool -> Lit
- SAT.Solver.Mios.Validator: validate :: Traversable t => Solver -> t Int -> IO Bool
- SAT.Util.BoolExp: (-!-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
- SAT.Util.BoolExp: (-&&&-) :: [BoolForm] -> BoolForm
- SAT.Util.BoolExp: (-&-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
- SAT.Util.BoolExp: (-=-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
- SAT.Util.BoolExp: (->-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
- SAT.Util.BoolExp: (-|-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
- SAT.Util.BoolExp: (-|||-) :: [BoolForm] -> BoolForm
- SAT.Util.BoolExp: Cnf :: (Int, Int) -> [[Int]] -> BoolForm
- SAT.Util.BoolExp: asLatex :: BoolForm -> String
- SAT.Util.BoolExp: asLatex_ :: BoolForm -> String
- SAT.Util.BoolExp: asList :: BoolForm -> [[Int]]
- SAT.Util.BoolExp: asList_ :: BoolForm -> [[Int]]
- SAT.Util.BoolExp: class BoolComponent a
- SAT.Util.BoolExp: conjunctionOf :: [BoolForm] -> BoolForm
- SAT.Util.BoolExp: data BoolForm
- SAT.Util.BoolExp: disjunctionOf :: [BoolForm] -> BoolForm
- SAT.Util.BoolExp: instance GHC.Classes.Eq SAT.Util.BoolExp.BoolForm
- SAT.Util.BoolExp: instance GHC.Classes.Ord SAT.Util.BoolExp.BoolForm
- SAT.Util.BoolExp: instance GHC.Show.Show SAT.Util.BoolExp.BoolForm
- SAT.Util.BoolExp: instance SAT.Util.BoolExp.BoolComponent GHC.Types.Bool
- SAT.Util.BoolExp: instance SAT.Util.BoolExp.BoolComponent GHC.Types.Int
- SAT.Util.BoolExp: instance SAT.Util.BoolExp.BoolComponent SAT.Util.BoolExp.BoolForm
- SAT.Util.BoolExp: instance SAT.Util.BoolExp.BoolComponent SAT.Util.BoolExp.L
- SAT.Util.BoolExp: instance SAT.Util.BoolExp.BoolComponent [GHC.Types.Char]
- SAT.Util.BoolExp: neg :: (BoolComponent a) => a -> BoolForm
- SAT.Util.BoolExp: numberOfClauses :: BoolForm -> Int
- SAT.Util.BoolExp: numberOfVariables :: BoolForm -> Int
- SAT.Util.BoolExp: toBF :: BoolComponent a => a -> BoolForm
- SAT.Util.BoolExp: tseitinBase :: Int
- SAT.Util.CNFIO: asCNFString :: BoolForm -> String
- SAT.Util.CNFIO: asCNFString_ :: BoolForm -> String
- SAT.Util.CNFIO: clauseListFromFile :: FilePath -> IO [[Int]]
- SAT.Util.CNFIO: clauseListFromMinisatOutput :: FilePath -> IO [Int]
- SAT.Util.CNFIO: fromFile :: FilePath -> IO (Maybe ((Int, Int), [[Int]]))
- SAT.Util.CNFIO: fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))
- SAT.Util.CNFIO: toCNFString :: [[Int]] -> String
- SAT.Util.CNFIO: toFile :: FilePath -> [[Int]] -> IO ()
- SAT.Util.CNFIO.MinisatReader: clauseListFromMinisatOutput :: FilePath -> IO [Int]
- SAT.Util.CNFIO.MinisatReader: fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))
- SAT.Util.CNFIO.Reader: clauseListFromFile :: FilePath -> IO [[Int]]
- SAT.Util.CNFIO.Reader: fromFile :: FilePath -> IO (Maybe ((Int, Int), [[Int]]))
- SAT.Util.CNFIO.Writer: toCNFString :: [[Int]] -> String
- SAT.Util.CNFIO.Writer: toFile :: FilePath -> [[Int]] -> IO ()
- SAT.Util.CNFIO.Writer: toLatexString :: [[Int]] -> String
- SAT.Util.CNFIO.Writer: toString :: [[Int]] -> String -> String -> String
+ SAT.Mios: CNFDescription :: !Int -> !Int -> Maybe FilePath -> CNFDescription
+ SAT.Mios: [_numberOfClauses] :: CNFDescription -> !Int
+ SAT.Mios: [_numberOfVariables] :: CNFDescription -> !Int
+ SAT.Mios: [_pathname] :: CNFDescription -> Maybe FilePath
+ SAT.Mios: data CNFDescription
+ SAT.Mios: dumpAssigmentAsCNF :: FilePath -> Bool -> [Int] -> IO ()
+ SAT.Mios: executeSolver :: MiosProgramOption -> IO ()
+ SAT.Mios: executeSolverOn :: FilePath -> IO ()
+ SAT.Mios: executeValidator :: MiosProgramOption -> IO ()
+ SAT.Mios: executeValidatorOn :: FilePath -> IO ()
+ SAT.Mios: getModel :: Solver -> IO [Int]
+ SAT.Mios: runSolver :: Traversable t => MiosConfiguration -> CNFDescription -> t [Int] -> IO (Either [Int] [Int])
+ SAT.Mios: solve :: (Foldable t) => Solver -> t Lit -> IO Bool
+ SAT.Mios: solveSAT :: Traversable m => CNFDescription -> m [Int] -> IO [Int]
+ SAT.Mios: solveSATWithConfiguration :: Traversable m => MiosConfiguration -> CNFDescription -> m [Int] -> IO [Int]
+ SAT.Mios: validate :: Traversable t => Solver -> t Int -> IO Bool
+ SAT.Mios: validateAssignment :: (Traversable m, Traversable n) => CNFDescription -> m [Int] -> n Int -> IO Bool
+ SAT.Mios: versionId :: String
+ SAT.Mios.Clause: Clause :: !Bool -> !DoubleSingleton -> !BoolSingleton -> !Vec -> Clause
+ SAT.Mios.Clause: NullClause :: Clause
+ SAT.Mios.Clause: [activity] :: Clause -> !DoubleSingleton
+ SAT.Mios.Clause: [learnt] :: Clause -> !Bool
+ SAT.Mios.Clause: [lits] :: Clause -> !Vec
+ SAT.Mios.Clause: [protected] :: Clause -> !BoolSingleton
+ SAT.Mios.Clause: data Clause
+ SAT.Mios.Clause: getNthClause :: ClauseVector -> Int -> IO Clause
+ SAT.Mios.Clause: instance GHC.Classes.Eq SAT.Mios.Clause.Clause
+ SAT.Mios.Clause: instance GHC.Show.Show SAT.Mios.Clause.Clause
+ SAT.Mios.Clause: instance SAT.Mios.Types.VectorFamily SAT.Mios.Clause.Clause SAT.Mios.Types.Lit
+ SAT.Mios.Clause: instance SAT.Mios.Types.VectorFamily SAT.Mios.Clause.ClauseVector SAT.Mios.Clause.Clause
+ SAT.Mios.Clause: newClauseFromVec :: Bool -> Vec -> IO Clause
+ SAT.Mios.Clause: newClauseVector :: Int -> IO ClauseVector
+ SAT.Mios.Clause: setNthClause :: ClauseVector -> Int -> Clause -> IO ()
+ SAT.Mios.Clause: shrinkClause :: Int -> Clause -> IO ()
+ SAT.Mios.Clause: sizeOfClause :: Clause -> IO Int
+ SAT.Mios.Clause: swapClauses :: ClauseVector -> Int -> Int -> IO ()
+ SAT.Mios.Clause: type ClauseVector = IOVector Clause
+ SAT.Mios.ClauseManager: class ClauseManager a
+ SAT.Mios.ClauseManager: clearManager :: ClauseManager a => a -> IO ()
+ SAT.Mios.ClauseManager: data ClauseExtManager
+ SAT.Mios.ClauseManager: garbageCollect :: WatcherList -> IO ()
+ SAT.Mios.ClauseManager: getClauseVector :: ClauseManager a => a -> IO ClauseVector
+ SAT.Mios.ClauseManager: getKeyVector :: ClauseExtManager -> IO Vec
+ SAT.Mios.ClauseManager: getNthWatcher :: WatcherList -> Lit -> ClauseExtManager
+ SAT.Mios.ClauseManager: instance SAT.Mios.ClauseManager.ClauseManager SAT.Mios.ClauseManager.ClauseExtManager
+ SAT.Mios.ClauseManager: instance SAT.Mios.Types.VectorFamily SAT.Mios.ClauseManager.ClauseExtManager SAT.Mios.Clause.Clause
+ SAT.Mios.ClauseManager: instance SAT.Mios.Types.VectorFamily SAT.Mios.ClauseManager.WatcherList SAT.Mios.Clause.Clause
+ SAT.Mios.ClauseManager: markClause :: ClauseExtManager -> Clause -> IO ()
+ SAT.Mios.ClauseManager: newManager :: ClauseManager a => Int -> IO a
+ SAT.Mios.ClauseManager: newWatcherList :: Int -> Int -> IO WatcherList
+ SAT.Mios.ClauseManager: numberOfClauses :: ClauseManager a => a -> IO Int
+ SAT.Mios.ClauseManager: pushClause :: ClauseManager a => a -> Clause -> IO ()
+ SAT.Mios.ClauseManager: pushClauseWithKey :: ClauseExtManager -> Clause -> Lit -> IO ()
+ SAT.Mios.ClauseManager: shrinkManager :: ClauseManager a => a -> Int -> IO ()
+ SAT.Mios.ClauseManager: type WatcherList = Vector ClauseExtManager
+ SAT.Mios.Data.Singleton: getBool :: BoolSingleton -> IO Bool
+ SAT.Mios.Data.Singleton: getDouble :: DoubleSingleton -> IO Double
+ SAT.Mios.Data.Singleton: getInt :: IntSingleton -> IO Int
+ SAT.Mios.Data.Singleton: modifyBool :: BoolSingleton -> (Bool -> Bool) -> IO ()
+ SAT.Mios.Data.Singleton: modifyDouble :: DoubleSingleton -> (Double -> Double) -> IO ()
+ SAT.Mios.Data.Singleton: modifyInt :: IntSingleton -> (Int -> Int) -> IO ()
+ SAT.Mios.Data.Singleton: newBool :: Bool -> IO BoolSingleton
+ SAT.Mios.Data.Singleton: newDouble :: Double -> IO DoubleSingleton
+ SAT.Mios.Data.Singleton: newInt :: Int -> IO IntSingleton
+ SAT.Mios.Data.Singleton: setBool :: BoolSingleton -> Bool -> IO ()
+ SAT.Mios.Data.Singleton: setDouble :: DoubleSingleton -> Double -> IO ()
+ SAT.Mios.Data.Singleton: setInt :: IntSingleton -> Int -> IO ()
+ SAT.Mios.Data.Singleton: type BoolSingleton = IOVector Bool
+ SAT.Mios.Data.Singleton: type DoubleSingleton = IOVector Double
+ SAT.Mios.Data.Singleton: type IntSingleton = IOVector Int
+ SAT.Mios.Data.Stack: asSizedVec :: Stack -> Vec
+ SAT.Mios.Data.Stack: clearStack :: Stack -> IO ()
+ SAT.Mios.Data.Stack: data Stack
+ SAT.Mios.Data.Stack: instance SAT.Mios.Types.VectorFamily SAT.Mios.Data.Stack.Stack GHC.Types.Int
+ SAT.Mios.Data.Stack: lastOfStack :: Stack -> IO Int
+ SAT.Mios.Data.Stack: newStack :: Int -> IO Stack
+ SAT.Mios.Data.Stack: popFromStack :: Stack -> IO ()
+ SAT.Mios.Data.Stack: pushToStack :: Stack -> Int -> IO ()
+ SAT.Mios.Data.Stack: shrinkStack :: Stack -> Int -> IO ()
+ SAT.Mios.Data.Stack: sizeOfStack :: Stack -> IO Int
+ SAT.Mios.Data.Vec: getNth :: Vec -> Int -> IO Int
+ SAT.Mios.Data.Vec: modifyNth :: Vec -> (Int -> Int) -> Int -> IO ()
+ SAT.Mios.Data.Vec: newSizedVecIntFromList :: [Int] -> IO Vec
+ SAT.Mios.Data.Vec: newSizedVecIntFromUVector :: Vector Int -> IO Vec
+ SAT.Mios.Data.Vec: newVec :: Int -> IO Vec
+ SAT.Mios.Data.Vec: newVecWith :: Int -> Int -> IO Vec
+ SAT.Mios.Data.Vec: setAll :: Vec -> Int -> IO ()
+ SAT.Mios.Data.Vec: setNth :: Vec -> Int -> Int -> IO ()
+ SAT.Mios.Data.Vec: sizeOfVector :: Vec -> IO Int
+ SAT.Mios.Data.Vec: swapBetween :: Vec -> Int -> Int -> IO ()
+ SAT.Mios.Data.Vec: type Vec = IOVector Int
+ SAT.Mios.Data.Vec: vecGrow :: Vec -> Int -> IO Vec
+ SAT.Mios.Data.VecBool: getNthBool :: VecBool -> Int -> IO Bool
+ SAT.Mios.Data.VecBool: instance SAT.Mios.Types.VectorFamily SAT.Mios.Data.VecBool.VecBool GHC.Types.Bool
+ SAT.Mios.Data.VecBool: modifyNthBool :: VecBool -> (Bool -> Bool) -> Int -> IO ()
+ SAT.Mios.Data.VecBool: newVecBool :: Int -> Bool -> IO VecBool
+ SAT.Mios.Data.VecBool: setNthBool :: VecBool -> Int -> Bool -> IO ()
+ SAT.Mios.Data.VecBool: type VecBool = IOVector Bool
+ SAT.Mios.Data.VecDouble: getNthDouble :: Int -> VecDouble -> IO Double
+ SAT.Mios.Data.VecDouble: instance SAT.Mios.Types.VectorFamily SAT.Mios.Data.VecDouble.VecDouble GHC.Types.Double
+ SAT.Mios.Data.VecDouble: modifyNthDouble :: Int -> VecDouble -> (Double -> Double) -> IO ()
+ SAT.Mios.Data.VecDouble: newVecDouble :: Int -> Double -> IO VecDouble
+ SAT.Mios.Data.VecDouble: setNthDouble :: Int -> VecDouble -> Double -> IO ()
+ SAT.Mios.Data.VecDouble: type VecDouble = IOVector Double
+ SAT.Mios.Internal: MiosConfiguration :: !Double -> MiosConfiguration
+ SAT.Mios.Internal: [variableDecayRate] :: MiosConfiguration -> !Double
+ SAT.Mios.Internal: data MiosConfiguration
+ SAT.Mios.Internal: defaultConfiguration :: MiosConfiguration
+ SAT.Mios.Internal: versionId :: String
+ SAT.Mios.Main: simplifyDB :: Solver -> IO Bool
+ SAT.Mios.Main: solve :: (Foldable t) => Solver -> t Lit -> IO Bool
+ SAT.Mios.OptionParser: MiosConfiguration :: !Double -> MiosConfiguration
+ SAT.Mios.OptionParser: MiosProgramOption :: Maybe String -> Maybe String -> !Double -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> MiosProgramOption
+ SAT.Mios.OptionParser: [_confCheckAnswer] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_confNoAnswer] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_confStatProbe] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_confTimeProbe] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_confVariableDecayRate] :: MiosProgramOption -> !Double
+ SAT.Mios.OptionParser: [_confVerbose] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_displayHelp] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_displayVersion] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [_outputFile] :: MiosProgramOption -> Maybe String
+ SAT.Mios.OptionParser: [_targetFile] :: MiosProgramOption -> Maybe String
+ SAT.Mios.OptionParser: [_validateAssignment] :: MiosProgramOption -> !Bool
+ SAT.Mios.OptionParser: [variableDecayRate] :: MiosConfiguration -> !Double
+ SAT.Mios.OptionParser: data MiosConfiguration
+ SAT.Mios.OptionParser: data MiosProgramOption
+ SAT.Mios.OptionParser: defaultConfiguration :: MiosConfiguration
+ SAT.Mios.OptionParser: miosDefaultOption :: MiosProgramOption
+ SAT.Mios.OptionParser: miosOptions :: [OptDescr (MiosProgramOption -> MiosProgramOption)]
+ SAT.Mios.OptionParser: miosParseOptions :: String -> [String] -> IO MiosProgramOption
+ SAT.Mios.OptionParser: miosParseOptionsFromArgs :: String -> IO MiosProgramOption
+ SAT.Mios.OptionParser: miosUsage :: String -> String
+ SAT.Mios.OptionParser: toMiosConf :: MiosProgramOption -> MiosConfiguration
+ SAT.Mios.Solver: NumOfBackjump :: StatIndex
+ SAT.Mios.Solver: NumOfRestart :: StatIndex
+ SAT.Mios.Solver: Solver :: !VecBool -> !Stack -> !ClauseExtManager -> !ClauseExtManager -> !WatcherList -> !Vec -> !Vec -> !Stack -> !Stack -> !IntSingleton -> !ClauseVector -> !Vec -> !VecDouble -> !VarHeap -> !MiosConfiguration -> !Int -> !DoubleSingleton -> !IntSingleton -> !BoolSingleton -> !Vec -> !Stack -> !Stack -> !Vec -> !Stack -> !Stack -> !Vec -> Solver
+ SAT.Mios.Solver: [activities] :: Solver -> !VecDouble
+ SAT.Mios.Solver: [an'seen] :: Solver -> !Vec
+ SAT.Mios.Solver: [an'stack] :: Solver -> !Stack
+ SAT.Mios.Solver: [an'toClear] :: Solver -> !Stack
+ SAT.Mios.Solver: [assigns] :: Solver -> !Vec
+ SAT.Mios.Solver: [clauses] :: Solver -> !ClauseExtManager
+ SAT.Mios.Solver: [config] :: Solver -> !MiosConfiguration
+ SAT.Mios.Solver: [conflict] :: Solver -> !Stack
+ SAT.Mios.Solver: [lastDL] :: Solver -> !Stack
+ SAT.Mios.Solver: [learnts] :: Solver -> !ClauseExtManager
+ SAT.Mios.Solver: [level] :: Solver -> !Vec
+ SAT.Mios.Solver: [litsLearnt] :: Solver -> !Stack
+ SAT.Mios.Solver: [model] :: Solver -> !VecBool
+ SAT.Mios.Solver: [nVars] :: Solver -> !Int
+ SAT.Mios.Solver: [ok] :: Solver -> !BoolSingleton
+ SAT.Mios.Solver: [order] :: Solver -> !VarHeap
+ SAT.Mios.Solver: [phases] :: Solver -> !Vec
+ SAT.Mios.Solver: [pr'seen] :: Solver -> !Vec
+ SAT.Mios.Solver: [qHead] :: Solver -> !IntSingleton
+ SAT.Mios.Solver: [reason] :: Solver -> !ClauseVector
+ SAT.Mios.Solver: [rootLevel] :: Solver -> !IntSingleton
+ SAT.Mios.Solver: [stats] :: Solver -> !Vec
+ SAT.Mios.Solver: [trailLim] :: Solver -> !Stack
+ SAT.Mios.Solver: [trail] :: Solver -> !Stack
+ SAT.Mios.Solver: [varInc] :: Solver -> !DoubleSingleton
+ SAT.Mios.Solver: [watches] :: Solver -> !WatcherList
+ SAT.Mios.Solver: addClause :: Solver -> Vec -> IO Bool
+ SAT.Mios.Solver: assume :: Solver -> Lit -> IO Bool
+ SAT.Mios.Solver: cancelUntil :: Solver -> Int -> IO ()
+ SAT.Mios.Solver: claActivityThreshold :: Double
+ SAT.Mios.Solver: claBumpActivity :: Solver -> Clause -> IO ()
+ SAT.Mios.Solver: claRescaleActivityAfterRestart :: Solver -> IO ()
+ SAT.Mios.Solver: data Solver
+ SAT.Mios.Solver: data StatIndex
+ SAT.Mios.Solver: decisionLevel :: Solver -> IO Int
+ SAT.Mios.Solver: enqueue :: Solver -> Lit -> Clause -> IO Bool
+ SAT.Mios.Solver: getModel :: Solver -> IO [Int]
+ SAT.Mios.Solver: getStat :: Solver -> StatIndex -> IO Int
+ SAT.Mios.Solver: getStats :: Solver -> IO [(StatIndex, Int)]
+ SAT.Mios.Solver: incrementStat :: Solver -> StatIndex -> Int -> IO ()
+ SAT.Mios.Solver: instance GHC.Classes.Eq SAT.Mios.Solver.StatIndex
+ SAT.Mios.Solver: instance GHC.Classes.Ord SAT.Mios.Solver.StatIndex
+ SAT.Mios.Solver: instance GHC.Enum.Bounded SAT.Mios.Solver.StatIndex
+ SAT.Mios.Solver: instance GHC.Enum.Enum SAT.Mios.Solver.StatIndex
+ SAT.Mios.Solver: instance GHC.Read.Read SAT.Mios.Solver.StatIndex
+ SAT.Mios.Solver: instance GHC.Show.Show SAT.Mios.Solver.StatIndex
+ SAT.Mios.Solver: instance SAT.Mios.Types.VarOrder SAT.Mios.Solver.Solver
+ SAT.Mios.Solver: locked :: Solver -> Clause -> IO Bool
+ SAT.Mios.Solver: nAssigns :: Solver -> IO Int
+ SAT.Mios.Solver: nClauses :: Solver -> IO Int
+ SAT.Mios.Solver: nLearnts :: Solver -> IO Int
+ SAT.Mios.Solver: newSolver :: MiosConfiguration -> CNFDescription -> IO Solver
+ SAT.Mios.Solver: setStat :: Solver -> StatIndex -> Int -> IO ()
+ SAT.Mios.Solver: valueLit :: Solver -> Lit -> IO Int
+ SAT.Mios.Solver: valueVar :: Solver -> Var -> IO Int
+ SAT.Mios.Solver: varBumpActivity :: Solver -> Var -> IO ()
+ SAT.Mios.Solver: varDecayActivity :: Solver -> IO ()
+ SAT.Mios.Types: Bottom :: LiftedBool
+ SAT.Mios.Types: CNFDescription :: !Int -> !Int -> Maybe FilePath -> CNFDescription
+ SAT.Mios.Types: LFalse :: LiftedBool
+ SAT.Mios.Types: LTrue :: LiftedBool
+ SAT.Mios.Types: [_numberOfClauses] :: CNFDescription -> !Int
+ SAT.Mios.Types: [_numberOfVariables] :: CNFDescription -> !Int
+ SAT.Mios.Types: [_pathname] :: CNFDescription -> Maybe FilePath
+ SAT.Mios.Types: asList :: VectorFamily s t => s -> IO [t]
+ SAT.Mios.Types: asVec :: VectorFamily s t => s -> IOVector Int
+ SAT.Mios.Types: bottomLit :: Lit
+ SAT.Mios.Types: bottomVar :: Var
+ SAT.Mios.Types: class VarOrder o where newVarOrder _ _ = error "newVarOrder undefined" newVar = error "newVar undefined" update _ = error "update undefined" updateAll = error "updateAll undefined" undo _ _ = error "undo undefined" select = error "select undefined"
+ SAT.Mios.Types: class VectorFamily s t | s -> t where clear = error "no default method for clear" dump msg _ = error $ msg ++ ": no defalut method for dump" asVec = error "asVector undefined" asList = error "asList undefined"
+ SAT.Mios.Types: clear :: VectorFamily s t => s -> IO ()
+ SAT.Mios.Types: data CNFDescription
+ SAT.Mios.Types: data LiftedBool
+ SAT.Mios.Types: dump :: (VectorFamily s t, Show t) => String -> s -> IO String
+ SAT.Mios.Types: instance GHC.Classes.Eq SAT.Mios.Types.CNFDescription
+ SAT.Mios.Types: instance GHC.Classes.Eq SAT.Mios.Types.LiftedBool
+ SAT.Mios.Types: instance GHC.Classes.Ord SAT.Mios.Types.CNFDescription
+ SAT.Mios.Types: instance GHC.Classes.Ord SAT.Mios.Types.LiftedBool
+ SAT.Mios.Types: instance GHC.Enum.Bounded SAT.Mios.Types.LiftedBool
+ SAT.Mios.Types: instance GHC.Enum.Enum SAT.Mios.Types.LiftedBool
+ SAT.Mios.Types: instance GHC.Read.Read SAT.Mios.Types.LiftedBool
+ SAT.Mios.Types: instance GHC.Show.Show SAT.Mios.Types.CNFDescription
+ SAT.Mios.Types: instance GHC.Show.Show SAT.Mios.Types.LiftedBool
+ SAT.Mios.Types: instance SAT.Mios.Types.VectorFamily SAT.Mios.Data.Vec.Vec GHC.Types.Int
+ SAT.Mios.Types: int2lit :: Int -> Lit
+ SAT.Mios.Types: int2var :: Integer -> Integer
+ SAT.Mios.Types: lBottom :: Int
+ SAT.Mios.Types: lFalse :: Int
+ SAT.Mios.Types: lTrue :: Int
+ SAT.Mios.Types: lbool :: Bool -> LiftedBool
+ SAT.Mios.Types: lit2int :: Lit -> Int
+ SAT.Mios.Types: lit2var :: Lit -> Var
+ SAT.Mios.Types: negateLit :: Lit -> Lit
+ SAT.Mios.Types: newLit :: Var -> Lit
+ SAT.Mios.Types: newVar :: VarOrder o => o -> IO Var
+ SAT.Mios.Types: newVarOrder :: (VarOrder o, VectorFamily v1 Bool, VectorFamily v2 Double) => v1 -> v2 -> IO o
+ SAT.Mios.Types: positiveLit :: Lit -> Bool
+ SAT.Mios.Types: select :: VarOrder o => o -> IO Var
+ SAT.Mios.Types: type Lit = Int
+ SAT.Mios.Types: type Var = Int
+ SAT.Mios.Types: undo :: VarOrder o => o -> Var -> IO ()
+ SAT.Mios.Types: update :: VarOrder o => o -> Var -> IO ()
+ SAT.Mios.Types: updateAll :: VarOrder o => o -> IO ()
+ SAT.Mios.Types: var2lit :: Var -> Bool -> Lit
+ SAT.Mios.Util.BoolExp: (-!-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
+ SAT.Mios.Util.BoolExp: (-&&&-) :: [BoolForm] -> BoolForm
+ SAT.Mios.Util.BoolExp: (-&-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
+ SAT.Mios.Util.BoolExp: (-=-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
+ SAT.Mios.Util.BoolExp: (->-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
+ SAT.Mios.Util.BoolExp: (-|-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm
+ SAT.Mios.Util.BoolExp: (-|||-) :: [BoolForm] -> BoolForm
+ SAT.Mios.Util.BoolExp: Cnf :: (Int, Int) -> [[Int]] -> BoolForm
+ SAT.Mios.Util.BoolExp: asLatex :: BoolForm -> String
+ SAT.Mios.Util.BoolExp: asLatex_ :: BoolForm -> String
+ SAT.Mios.Util.BoolExp: asList :: BoolForm -> [[Int]]
+ SAT.Mios.Util.BoolExp: asList_ :: BoolForm -> [[Int]]
+ SAT.Mios.Util.BoolExp: class BoolComponent a
+ SAT.Mios.Util.BoolExp: conjunctionOf :: [BoolForm] -> BoolForm
+ SAT.Mios.Util.BoolExp: data BoolForm
+ SAT.Mios.Util.BoolExp: disjunctionOf :: [BoolForm] -> BoolForm
+ SAT.Mios.Util.BoolExp: instance GHC.Classes.Eq SAT.Mios.Util.BoolExp.BoolForm
+ SAT.Mios.Util.BoolExp: instance GHC.Classes.Ord SAT.Mios.Util.BoolExp.BoolForm
+ SAT.Mios.Util.BoolExp: instance GHC.Show.Show SAT.Mios.Util.BoolExp.BoolForm
+ SAT.Mios.Util.BoolExp: instance SAT.Mios.Util.BoolExp.BoolComponent GHC.Types.Bool
+ SAT.Mios.Util.BoolExp: instance SAT.Mios.Util.BoolExp.BoolComponent GHC.Types.Int
+ SAT.Mios.Util.BoolExp: instance SAT.Mios.Util.BoolExp.BoolComponent SAT.Mios.Util.BoolExp.BoolForm
+ SAT.Mios.Util.BoolExp: instance SAT.Mios.Util.BoolExp.BoolComponent SAT.Mios.Util.BoolExp.L
+ SAT.Mios.Util.BoolExp: instance SAT.Mios.Util.BoolExp.BoolComponent [GHC.Types.Char]
+ SAT.Mios.Util.BoolExp: neg :: (BoolComponent a) => a -> BoolForm
+ SAT.Mios.Util.BoolExp: numberOfClauses :: BoolForm -> Int
+ SAT.Mios.Util.BoolExp: numberOfVariables :: BoolForm -> Int
+ SAT.Mios.Util.BoolExp: toBF :: BoolComponent a => a -> BoolForm
+ SAT.Mios.Util.BoolExp: tseitinBase :: Int
+ SAT.Mios.Util.CNFIO: asCNFString :: BoolForm -> String
+ SAT.Mios.Util.CNFIO: asCNFString_ :: BoolForm -> String
+ SAT.Mios.Util.CNFIO: clauseListFromFile :: FilePath -> IO [[Int]]
+ SAT.Mios.Util.CNFIO: clauseListFromMinisatOutput :: FilePath -> IO [Int]
+ SAT.Mios.Util.CNFIO: fromFile :: FilePath -> IO (Maybe ((Int, Int), [[Int]]))
+ SAT.Mios.Util.CNFIO: fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))
+ SAT.Mios.Util.CNFIO: toCNFString :: [[Int]] -> String
+ SAT.Mios.Util.CNFIO: toFile :: FilePath -> [[Int]] -> IO ()
+ SAT.Mios.Util.CNFIO.MinisatReader: clauseListFromMinisatOutput :: FilePath -> IO [Int]
+ SAT.Mios.Util.CNFIO.MinisatReader: fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))
+ SAT.Mios.Util.CNFIO.Reader: clauseListFromFile :: FilePath -> IO [[Int]]
+ SAT.Mios.Util.CNFIO.Reader: fromFile :: FilePath -> IO (Maybe ((Int, Int), [[Int]]))
+ SAT.Mios.Util.CNFIO.Writer: toCNFString :: [[Int]] -> String
+ SAT.Mios.Util.CNFIO.Writer: toFile :: FilePath -> [[Int]] -> IO ()
+ SAT.Mios.Util.CNFIO.Writer: toLatexString :: [[Int]] -> String
+ SAT.Mios.Util.CNFIO.Writer: toString :: [[Int]] -> String -> String -> String
+ SAT.Mios.Validator: validate :: Traversable t => Solver -> t Int -> IO Bool

Files

+ SAT/Mios.hs view
@@ -0,0 +1,297 @@+-- | Minisat-based Implementation and Optimization Study on SAT solver+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE Trustworthy #-}++module SAT.Mios+       (+         -- * Interface to the core of solver+         versionId+       , CNFDescription (..)+       , module SAT.Mios.OptionParser+       , runSolver+       , solveSAT+       , solveSATWithConfiguration+       , solve+       , getModel+         -- * Assignment Validator+       , validateAssignment+       , validate+         -- * For standalone programs+       , executeSolverOn+       , executeSolver+       , executeValidatorOn+       , executeValidator+         -- * File IO+       , dumpAssigmentAsCNF+       )+       where++import Control.Monad ((<=<), unless, void, when)+import Data.Char+import qualified Data.ByteString.Char8 as B+import Data.List+import Numeric (showFFloat)+import System.CPUTime+import System.Exit+import System.IO++import SAT.Mios.Types+import SAT.Mios.Internal+import SAT.Mios.Solver+import SAT.Mios.Main+import SAT.Mios.OptionParser+import SAT.Mios.Validator++reportElapsedTime :: Bool -> String -> Integer -> IO Integer+reportElapsedTime False _ _ = return 0+reportElapsedTime _ _ 0 = getCPUTime+reportElapsedTime _ mes t = do+  now <- getCPUTime+  let toSecond = 1000000000000 :: Double+  hPutStr stderr mes+  hPutStrLn stderr $ showFFloat (Just 3) ((fromIntegral (now - t)) / toSecond) " sec"+  return now++-- | executes a solver on the given CNF file+-- This is the simplest entry to standalone programs; not for Haskell programs+executeSolverOn :: FilePath -> IO ()+executeSolverOn path = executeSolver (miosDefaultOption { _targetFile = Just path })++-- | executes a solver on the given 'arg :: MiosConfiguration'+-- | This is another entry point for standalone programs.+executeSolver :: MiosProgramOption -> IO ()+executeSolver opts@(_targetFile -> target@(Just cnfFile)) = do+  t0 <- reportElapsedTime (_confTimeProbe opts) "" 0+  (desc, cls) <- parseHeader target <$> B.readFile cnfFile+  when (_numberOfVariables desc == 0) $ error $ "couldn't load " ++ show cnfFile+  s <- newSolver (toMiosConf opts) desc+  parseClauses s desc cls+  t1 <- reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Parse: ") t0+  when (_confVerbose opts) $ do+    nc <- nClauses s+    hPutStrLn stderr $ cnfFile ++ " was loaded: #v = " ++ show (nVars s, _numberOfVariables desc) ++ " #c = " ++ show (nc, _numberOfClauses desc)+  res <- simplifyDB s+  -- when (_confVerbose opts) $ hPutStrLn stderr $ "`simplifyDB`: " ++ show res+  result <- if res then solve s [] else return False+  case result of+    True  | _confNoAnswer opts -> when (_confVerbose opts) $ hPutStrLn stderr "SATISFIABLE"+    False | _confNoAnswer opts -> when (_confVerbose opts) $ hPutStrLn stderr "UNSATISFIABLE"+    True  -> print =<< getModel s+    False -> do          -- contradiction+      -- FIXMEin future+      when (_confVerbose opts) $ hPutStrLn stderr "UNSAT"+      -- print =<< map lit2int <$> asList (conflict s)+      putStrLn "[]"+  case _outputFile opts of+    Just fname -> dumpAssigmentAsCNF fname result =<< getModel s+    Nothing -> return ()+  t2 <- reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Solve: ") t1+  when (result && _confCheckAnswer opts) $ do+    asg <- getModel s+    s' <- newSolver (toMiosConf opts) desc+    parseClauses s' desc cls+    good <- validate s' asg+    if _confVerbose opts+      then hPutStrLn stderr $ if good then "A vaild answer" else "Internal error: mios returns a wrong answer"+      else unless good $ hPutStrLn stderr "Internal error: mios returns a wrong answer"+    void $ reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Validate: ") t2+  void $ reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Total: ") t0+  when (_confStatProbe opts) $ do+    hPutStr stderr $ "## [" ++ showPath cnfFile ++ "] "+    hPutStrLn stderr . intercalate ", " . map (\(k, v) -> show k ++ ": " ++ show v) =<< getStats s++executeSolver _ = return ()++-- | new top-level interface that returns+--+-- * conflicting literal set :: Left [Int]+-- * satisfiable assignment :: Right [Int]+--+runSolver :: Traversable t => MiosConfiguration -> CNFDescription -> t [Int] -> IO (Either [Int] [Int])+runSolver m d c = do+  s <- newSolver m d+  mapM_ ((s `addClause`) <=< (newSizedVecIntFromList . map int2lit)) c+  noConf <- simplifyDB s+  if noConf+    then do+        x <- solve s []+        if x+            then Right <$> getModel s+            else Left .  map lit2int <$> asList (conflict s)+    else return $ Left []+++-- | the easiest interface for Haskell programs+-- This returns the result @::[[Int]]@ for a given @(CNFDescription, [[Int]])@+-- The first argument @target@ can be build by @Just target <- cnfFromFile targetfile@.+-- The second part of the first argument is a list of vector, which 0th element is the number of its real elements+solveSAT :: Traversable m => CNFDescription -> m [Int] -> IO [Int]+solveSAT = solveSATWithConfiguration defaultConfiguration++-- | solves the problem (2rd arg) under the configuration (1st arg)+-- and returns an assignment as list of literals :: Int+solveSATWithConfiguration :: Traversable m => MiosConfiguration -> CNFDescription -> m [Int] -> IO [Int]+solveSATWithConfiguration conf desc cls = do+  s <- newSolver conf desc+  -- mapM_ (const (newVar s)) [0 .. _numberOfVariables desc - 1]+  mapM_ ((s `addClause`) <=< (newSizedVecIntFromList . map int2lit)) cls+  noConf <- simplifyDB s+  if noConf+    then do+        result <- solve s []+        if result+            then getModel s+            else return []+    else return []++-- | validates a given assignment from STDIN for the CNF file (2nd arg)+-- this is the entry point for standalone programs+executeValidatorOn :: FilePath -> IO ()+executeValidatorOn path = executeValidator (miosDefaultOption { _targetFile = Just path })++-- | validates a given assignment for the problem (2nd arg)+-- this is another entry point for standalone programs; see app/mios.hs+executeValidator :: MiosProgramOption -> IO ()+executeValidator opts@(_targetFile -> target@(Just cnfFile)) = do+  (desc, cls) <- parseHeader target <$> B.readFile cnfFile+  when (_numberOfVariables desc == 0) . error $ "couldn't load " ++ show cnfFile+  s <- newSolver (toMiosConf opts) desc+  parseClauses s desc cls+  when (_confVerbose opts) $+    hPutStrLn stderr $ cnfFile ++ " was loaded: #v = " ++ show (_numberOfVariables desc) ++ " #c = " ++ show (_numberOfClauses desc)+  when (_confVerbose opts) $ do+    nc <- nClauses s+    nl <- nLearnts s+    hPutStrLn stderr $ "(nv, nc, nl) = " ++ show (nVars s, nc, nl)+  asg <- read <$> getContents+  unless (_confNoAnswer opts) $ print asg+  result <- s `validate` (asg :: [Int])+  if result+    then putStrLn ("It's a valid assignment for " ++ cnfFile ++ ".") >> exitSuccess+    else putStrLn ("It's an invalid assignment for " ++ cnfFile ++ ".") >> exitFailure++executeValidator _  = return ()++-- | returns True if a given assignment (2nd arg) satisfies the problem (1st arg)+-- if you want to check the @answer@ which a @slover@ returned, run @solver `validate` answer@,+-- where 'validate' @ :: Traversable t => Solver -> t Lit -> IO Bool@+validateAssignment :: (Traversable m, Traversable n) => CNFDescription -> m [Int] -> n Int -> IO Bool+validateAssignment desc cls asg = do+  s <- newSolver defaultConfiguration desc+  mapM_ ((s `addClause`) <=< (newSizedVecIntFromList . map int2lit)) cls+  s `validate` asg++-- | dumps an assigment to file.+-- 2nd arg is+--+-- * @True@ if the assigment is satisfiable assigment+--+-- * @False@ if not+--+-- >>> do y <- solve s ... ; dumpAssigmentAsCNF "result.cnf" y <$> model s+--+dumpAssigmentAsCNF :: FilePath -> Bool -> [Int] -> IO ()+dumpAssigmentAsCNF fname False _ = do+  withFile fname WriteMode $ \h -> do+    hPutStrLn h "UNSAT"++dumpAssigmentAsCNF fname True l = do+  withFile fname WriteMode $ \h -> do+    hPutStrLn h "SAT"+    hPutStrLn h . unwords $ map show l++--------------------------------------------------------------------------------+-- DIMACS CNF Reader+--------------------------------------------------------------------------------++parseHeader :: Maybe FilePath -> B.ByteString -> (CNFDescription, B.ByteString)+parseHeader target bs = if B.head bs == 'p' then (parseP l, B.tail bs') else parseHeader target (B.tail bs')+  where+    (l, bs') = B.span ('\n' /=) bs+    -- format: p cnf n m, length "p cnf" == 5+    parseP line = case B.readInt $ B.dropWhile (`elem` " \t") (B.drop 5 line) of+      Just (x, second) -> case B.readInt (B.dropWhile (`elem` " \t") second) of+        Just (y, _) -> CNFDescription x y target+        _ -> CNFDescription 0 0 target+      _ -> CNFDescription 0 0 target++parseClauses :: Solver -> CNFDescription -> B.ByteString -> IO ()+parseClauses s (CNFDescription nv nc _) bs = do+  let maxLit = int2lit $ negate nv+  buffer <- newVec $ maxLit + 1+  polvec <- newVecBool (maxLit + 1) False+  let+    loop :: Int -> B.ByteString -> IO ()+    loop ((< nc) -> False) _ = return ()+    loop i b = loop (i + 1) =<< readClause s buffer polvec b+  loop 0 bs+  -- static polarity+  let+    asg = assigns s+    checkPolarity :: Int -> IO ()+    checkPolarity ((< nv) -> False) = return ()+    checkPolarity v = do+      p <- getNthBool polvec $ var2lit v True+      n <- getNthBool polvec $ var2lit v False+      when (p == False || n == False) $ setNth asg v $ if p then lTrue else lFalse+      checkPolarity $ v + 1+  checkPolarity 1++skipWhitespace :: B.ByteString -> B.ByteString+skipWhitespace s+  | elem c " \t\n" = skipWhitespace $ B.tail s+  | otherwise = s+    where+      c = B.head s++-- | skip comment lines+-- __Pre-condition:__ we are on the benngining of a line+skipComments :: B.ByteString -> B.ByteString+skipComments s+  | c == 'c' = skipComments . B.tail . B.dropWhile (/= '\n') $ s+  | otherwise = s+  where+    c = B.head s++parseInt :: B.ByteString -> (Int, B.ByteString)+parseInt st = do+  let+    zero = ord '0'+    loop :: B.ByteString -> Int -> (Int, B.ByteString)+    loop s val = case B.head s of+      c | '0' <= c && c <= '9'  -> loop (B.tail s) (val * 10 + ord c - zero)+      _ -> (val, B.tail s)+  case B.head st of+    '-' -> let (k, x) = loop (B.tail st) 0 in (negate k, x)+    '+' -> loop st (0 :: Int)+    c | '0' <= c && c <= '9'  -> loop st 0+    _ -> error "PARSE ERROR! Unexpected char"++readClause :: Solver -> Vec -> VecBool -> B.ByteString -> IO B.ByteString+readClause s buffer pvec stream = do+  let+    loop :: Int -> B.ByteString -> IO B.ByteString+    loop i b = do+      let (k, b') = parseInt $ skipWhitespace b+      if k == 0+        then do+            -- putStrLn . ("clause: " ++) . show . map lit2int =<< asList stack+            setNth buffer 0 $ i - 1+            addClause s buffer+            return b'+        else do+            let l = int2lit k+            setNth buffer i l+            setNthBool pvec l True+            loop (i + 1) b'+  loop 1 . skipComments . skipWhitespace $ stream+++showPath :: FilePath -> String+showPath str+  | elem '/' str =  take (len - length basename) (repeat ' ') ++ basename+  |  otherwise = take (len - length basename') (repeat ' ') ++ basename'+  where+    len = 50+    basename = reverse . takeWhile (/= '/') . reverse $ str+    basename' = take len str
+ SAT/Mios/Clause.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE+    BangPatterns+  , FlexibleInstances+  , MagicHash+  , MultiParamTypeClasses+  , RecordWildCards+  , ViewPatterns+  #-}+{-# LANGUAGE Trustworthy #-}++-- | Clause, supporting pointer-based equality+module SAT.Mios.Clause+       (+         Clause (..)+--       , isLit+--       , getLit+       , shrinkClause+       , newClauseFromVec+       , sizeOfClause+         -- * Vector of Clause+       , ClauseVector+       , newClauseVector+       , getNthClause+       , setNthClause+       , swapClauses+       )+       where++import Control.Monad (forM_)+import GHC.Prim (tagToEnum#, reallyUnsafePtrEquality#)+import qualified Data.Vector as V+import qualified Data.Vector.Mutable as MV+import qualified Data.Vector.Unboxed.Mutable as UV+import Data.List (intercalate)+import SAT.Mios.Types++-- | __Fig. 7.(p.11)__+-- clause, null, binary clause.+-- This matches both of @Clause@ and @GClause@ in MiniSat+-- TODO: GADTs is better?+data Clause = Clause+              {+                learnt     :: !Bool            -- ^ whether this is a learnt clause+--              , rank       :: !IntSingleton    -- ^ goodness like LBD; computed in 'Ranking'+              , activity   :: !DoubleSingleton -- ^ activity of this clause+              , protected  :: !BoolSingleton   -- ^ protected from reduce+              , lits       :: !Vec             -- ^ which this clause consists of+              }+  | NullClause                              -- as null pointer+--  | BinaryClause Lit                        -- binary clause consists of only a propagating literal++-- | The equality on 'Clause' is defined with 'reallyUnsafePtrEquality'.+instance Eq Clause where+  {-# SPECIALIZE INLINE (==) :: Clause -> Clause -> Bool #-}+  (==) x y = x `seq` y `seq` tagToEnum# (reallyUnsafePtrEquality# x y)++instance Show Clause where+  show NullClause = "NullClause"+  show _ = "a clause"++-- | supports a restricted set of 'VectorFamily' methods+instance VectorFamily Clause Lit where+  dump mes NullClause = return $ mes ++ "Null"+  dump mes Clause{..} = do+    a <- show <$> getDouble activity+    (len:ls) <- asList lits+    return $ mes ++ "C" ++ show len ++ "{" ++ intercalate "," [show learnt, a, show . map lit2int . take len $ ls] ++ "}"+  {-# SPECIALIZE INLINE asVec :: Clause -> Vec #-}+  asVec Clause{..} = UV.unsafeTail lits+  {-# SPECIALIZE INLINE asList :: Clause -> IO [Int] #-}+  asList NullClause = return []+  asList Clause{..} = do+    (n : ls)  <- asList lits+    return $ take n ls++-- returns True if it is a 'BinaryClause'+-- FIXME: this might be discarded in minisat 2.2+-- isLit :: Clause -> Bool+-- isLit (BinaryClause _) = True+-- isLit _ = False++-- returns the literal in a BinaryClause+-- FIXME: this might be discarded in minisat 2.2+-- getLit :: Clause -> Lit+-- getLit (BinaryClause x) = x++-- coverts a binary clause to normal clause in order to reuse map-on-literals-in-a-clause codes+-- liftToClause :: Clause -> Clause+-- liftToClause (BinaryClause _) = error "So far I use generic function approach instead of lifting"++-- | copies /vec/ and return a new 'Clause'+-- Since 1.0.100 DIMACS reader should use a scratch buffer allocated statically.+{-# INLINE newClauseFromVec #-}+newClauseFromVec :: Bool -> Vec -> IO Clause+newClauseFromVec l vec = do+  n <- getNth vec 0+  v <- newVec $ n + 1+  forM_ [0 .. n] $ \i -> setNth v i =<< getNth vec i+  Clause l <$> {- newInt 0 <*> -} newDouble 0 <*> newBool False <*> return v++-- | returns the number of literals in a clause, even if the given clause is a binary clause+{-# INLINE sizeOfClause #-}+sizeOfClause :: Clause -> IO Int+-- sizeOfClause (BinaryClause _) = return 1+sizeOfClause !c = getNth (lits c) 0++-- | drop the last /N/ literals in a 'Clause' to eliminate unsatisfied literals+{-# INLINABLE shrinkClause #-}+shrinkClause :: Int -> Clause -> IO ()+shrinkClause n !c = modifyNth (lits c) (subtract n) 0++--------------------------------------------------------------------------------++-- | Mutable 'Clause' Vector+type ClauseVector = MV.IOVector Clause++instance VectorFamily ClauseVector Clause where+  asList cv = V.toList <$> V.freeze cv+  dump mes cv = do+    l <- asList cv+    sts <- mapM (dump ",") (l :: [Clause])+    return $ mes ++ tail (concat sts)++-- | returns a new 'ClauseVector'+newClauseVector  :: Int -> IO ClauseVector+newClauseVector n = do+  v <- MV.new (max 4 n)+  MV.set v NullClause+  return v++-- | returns the nth 'Clause'+{-# INLINE getNthClause #-}+getNthClause :: ClauseVector -> Int -> IO Clause+getNthClause = MV.unsafeRead++-- | sets the nth 'Clause'+{-# INLINE setNthClause #-}+setNthClause :: ClauseVector -> Int -> Clause -> IO ()+setNthClause = MV.unsafeWrite++-- | swaps the two 'Clause's+{-# INLINE swapClauses #-}+swapClauses :: ClauseVector -> Int -> Int -> IO ()+swapClauses = MV.unsafeSwap
+ SAT/Mios/ClauseManager.hs view
@@ -0,0 +1,326 @@+{-# LANGUAGE+    BangPatterns+  , DuplicateRecordFields+  , FlexibleInstances+  , MultiParamTypeClasses+  , RecordWildCards+  , ViewPatterns+  #-}+{-# LANGUAGE Trustworthy #-}++-- | A shrinkable vector of 'C.Clause'+module SAT.Mios.ClauseManager+       (+         -- * higher level interface for ClauseVector+         ClauseManager (..)+--       -- * vector of clauses+--       , SimpleManager+         -- * Manager with an extra Int (used as sort key or blocking literal)+       , ClauseExtManager+       , pushClauseWithKey+       , getKeyVector+       , markClause+--       , purifyManager+         -- * WatcherList+       , WatcherList+       , newWatcherList+       , getNthWatcher+       , garbageCollect+--       , numberOfRegisteredClauses+       )+       where++import Control.Monad (forM, unless, when)+import qualified Data.IORef as IORef+import qualified Data.List as L+import qualified Data.Vector as V+import qualified Data.Vector.Mutable as MV+import SAT.Mios.Types+import qualified SAT.Mios.Clause as C++-- | resizable clause vector+class ClauseManager a where+  newManager      :: Int -> IO a+  numberOfClauses :: a -> IO Int+  clearManager    :: a -> IO ()+  shrinkManager   :: a -> Int -> IO ()+  getClauseVector :: a -> IO C.ClauseVector+  pushClause      :: a -> C.Clause -> IO ()+--  removeClause    :: a -> C.Clause -> IO ()+--  removeNthClause :: a -> Int -> IO ()++{-+-- | The Clause Container+data SimpleManager = SimpleManager+  {+    _nActives     :: IntSingleton               -- number of active clause+  , _clauseVector :: IORef.IORef C.ClauseVector -- clause list+  }++instance ClauseManager SimpleManager where+  {-# SPECIALIZE INLINE newManager :: Int -> IO SimpleManager #-}+  newManager initialSize = do+    i <- newInt 0+    v <- C.newClauseVector initialSize+    SimpleManager i <$> IORef.newIORef v+  {-# SPECIALIZE INLINE numberOfClauses :: SimpleManager -> IO Int #-}+  numberOfClauses SimpleManager{..} = getInt _nActives+  {-# SPECIALIZE INLINE clearManager :: SimpleManager -> IO () #-}+  clearManager SimpleManager{..} = setInt _nActives 0+  {-# SPECIALIZE INLINE shrinkManager :: SimpleManager -> Int -> IO () #-}+  shrinkManager SimpleManager{..} k = modifyInt _nActives (subtract k)+  {-# SPECIALIZE INLINE getClauseVector :: SimpleManager -> IO C.ClauseVector #-}+  getClauseVector SimpleManager{..} = IORef.readIORef _clauseVector+  -- | O(1) inserter+  {-# SPECIALIZE INLINE pushClause :: SimpleManager -> C.Clause -> IO () #-}+  pushClause !SimpleManager{..} !c = do+    !n <- getInt _nActives+    !v <- IORef.readIORef _clauseVector+    if MV.length v - 1 <= n+      then do+          v' <- MV.unsafeGrow v (max 8 (MV.length v))+          -- forM_ [n  .. MV.length v' - 1] $ \i -> MV.unsafeWrite v' i C.NullClause+          MV.unsafeWrite v' n c+          IORef.writeIORef _clauseVector v'+      else MV.unsafeWrite v n c+    modifyInt _nActives (1 +)+  -- | O(1) remove-and-compact function+  {-# SPECIALIZE INLINE removeNthClause :: SimpleManager -> Int -> IO () #-}+  removeNthClause SimpleManager{..} i = do+    !n <- subtract 1 <$> getInt _nActives+    !v <- IORef.readIORef _clauseVector+    MV.unsafeWrite v i =<< MV.unsafeRead v n+    setInt _nActives n+  -- | O(n) but lightweight remove-and-compact function+  -- __Pre-conditions:__ the clause manager is empty or the clause is stored in it.+  {-# SPECIALIZE INLINE removeClause :: SimpleManager -> C.Clause -> IO () #-}+  removeClause SimpleManager{..} c = do+    -- putStrLn =<< dump "@removeClause| remove " c+    -- putStrLn =<< dump "@removeClause| from " m+    !n <- subtract 1 <$> getInt _nActives+    -- unless (0 <= n) $ error $ "removeClause catches " ++ show n+    !v <- IORef.readIORef _clauseVector+    let+      seekIndex :: Int -> IO Int+      seekIndex k = do+        c' <- MV.unsafeRead v k+        if c' == c then return k else seekIndex $ k + 1+    unless (n == -1) $ do+      !i <- seekIndex 0+      MV.unsafeWrite v i =<< MV.unsafeRead v n+      setInt _nActives n++instance VectorFamily SimpleManager C.Clause where+  dump mes SimpleManager{..} = do+    n <- getInt _nActives+    if n == 0+      then return $ mes ++ "empty clausemanager"+      else do+          l <- take n <$> (asList =<< IORef.readIORef _clauseVector)+          sts <- mapM (dump ",") (l :: [C.Clause])+          return $ mes ++ "[" ++ show n ++ "]" ++ tail (concat sts)+-}++--------------------------------------------------------------------------------++-- | Clause + Blocking Literal+data ClauseExtManager = ClauseExtManager+  {+    _nActives     :: !IntSingleton               -- number of active clause+  , _purged       :: !BoolSingleton              -- whether it needs gc+  , _clauseVector :: IORef.IORef C.ClauseVector -- clause list+  , _keyVector    :: IORef.IORef Vec            -- Int list+  }++instance ClauseManager ClauseExtManager where+  {-# SPECIALIZE INLINE newManager :: Int -> IO ClauseExtManager #-}+  newManager initialSize = do+    i <- newInt 0+    v <- C.newClauseVector initialSize+    b <- newVec (MV.length v)+    ClauseExtManager i <$> newBool False <*> IORef.newIORef v <*> IORef.newIORef b+  {-# SPECIALIZE INLINE numberOfClauses :: ClauseExtManager -> IO Int #-}+  numberOfClauses !m = getInt (_nActives m)+  {-# SPECIALIZE INLINE clearManager :: ClauseExtManager -> IO () #-}+  clearManager !m = setInt (_nActives m) 0+  {-# SPECIALIZE INLINE shrinkManager :: ClauseExtManager -> Int -> IO () #-}+  shrinkManager !m k = modifyInt (_nActives m) (subtract k)+  {-# SPECIALIZE INLINE getClauseVector :: ClauseExtManager -> IO C.ClauseVector #-}+  getClauseVector !m = IORef.readIORef (_clauseVector m)+  -- | O(1) insertion function+  {-# SPECIALIZE INLINE pushClause :: ClauseExtManager -> C.Clause -> IO () #-}+  pushClause !ClauseExtManager{..} !c = do+    -- checkConsistency m c+    !n <- getInt _nActives+    !v <- IORef.readIORef _clauseVector+    !b <- IORef.readIORef _keyVector+    if MV.length v - 1 <= n+      then do+          let len = max 8 $ MV.length v+          v' <- MV.unsafeGrow v len+          b' <- vecGrow b len+          MV.unsafeWrite v' n c+          setNth b' n 0+          IORef.writeIORef _clauseVector v'+          IORef.writeIORef _keyVector b'+      else MV.unsafeWrite v n c >> setNth b n 0+    modifyInt _nActives (1 +)+{-+  -- | O(n) but lightweight remove-and-compact function+  -- __Pre-conditions:__ the clause manager is empty or the clause is stored in it.+  {-# SPECIALIZE INLINE removeClause :: ClauseExtManager -> C.Clause -> IO () #-}+  removeClause ClauseExtManager{..} c = do+    !n <- subtract 1 <$> getInt _nActives+    !v <- IORef.readIORef _clauseVector+    !b <- IORef.readIORef _keyVector+    let+      seekIndex :: Int -> IO Int+      seekIndex k = do+        c' <- MV.unsafeRead v k+        if c' == c then return k else seekIndex $ k + 1+    unless (n == -1) $ do+      !i <- seekIndex 0+      MV.unsafeWrite v i =<< MV.unsafeRead v n+      setNth b i =<< getNth b n+      setInt _nActives n+  removeNthClause = error "removeNthClause is not implemented on ClauseExtManager"+-}++-- | sets the expire flag to a clause+{-# INLINE markClause #-}+markClause :: ClauseExtManager -> C.Clause -> IO ()+markClause ClauseExtManager{..} c = do+  !n <- getInt _nActives+  !v <- IORef.readIORef _clauseVector+  let+    seekIndex :: Int -> IO ()+    seekIndex k = do+      c' <- MV.unsafeRead v k+      if c' == c then MV.unsafeWrite v k C.NullClause else seekIndex $ k + 1+  unless (n == 0) $ do+    seekIndex 0+    setBool _purged True++{-# INLINE purifyManager #-}+purifyManager :: ClauseExtManager -> IO ()+purifyManager ClauseExtManager{..} = do+  diry <- getBool _purged+  when diry $ do+    n <- getInt _nActives+    vec <- IORef.readIORef _clauseVector+    keys <- IORef.readIORef _keyVector+    let+      loop :: Int -> Int -> IO Int+      loop ((< n) -> False) n' = return n'+      loop i j = do+        c <- C.getNthClause vec i+        if c /= C.NullClause+          then do+              unless (i == j) $ do+                C.setNthClause vec j c+                setNth keys j =<< getNth keys i+              loop (i + 1) (j + 1)+          else loop (i + 1) j+    setInt _nActives =<< loop 0 0+    setBool _purged False++-- | returns the associated Int vector+{-# INLINE getKeyVector #-}+getKeyVector :: ClauseExtManager -> IO Vec+getKeyVector ClauseExtManager{..} = IORef.readIORef _keyVector++-- | O(1) inserter+{-# INLINE pushClauseWithKey #-}+pushClauseWithKey :: ClauseExtManager -> C.Clause -> Lit -> IO ()+pushClauseWithKey !ClauseExtManager{..} !c k = do+  -- checkConsistency m c+  !n <- getInt _nActives+  !v <- IORef.readIORef _clauseVector+  !b <- IORef.readIORef _keyVector+  if MV.length v - 1 <= n+    then do+        let len = max 8 $ MV.length v+        v' <- MV.unsafeGrow v len+        b' <- vecGrow b len+        MV.unsafeWrite v' n c+        setNth b' n k+        IORef.writeIORef _clauseVector v'+        IORef.writeIORef _keyVector b'+    else MV.unsafeWrite v n c >> setNth b n k+  modifyInt _nActives (1 +)++instance VectorFamily ClauseExtManager C.Clause where+  dump mes ClauseExtManager{..} = do+    n <- getInt _nActives+    if n == 0+      then return $ mes ++ "empty ClauseExtManager"+      else do+          l <- take n <$> (asList =<< IORef.readIORef _clauseVector)+          sts <- mapM (dump ",") (l :: [C.Clause])+          return $ mes ++ "[" ++ show n ++ "]" ++ tail (concat sts)++-------------------------------------------------------------------------------- WatcherList++-- | Vector of 'ClauseExtManager'+type WatcherList = V.Vector ClauseExtManager++-- | /n/ is the number of 'Var', /m/ is default size of each watcher list+-- | For /n/ vars, we need [0 .. 2 + 2 * n - 1] slots, namely /2 * (n + 1)/-length vector+newWatcherList :: Int -> Int -> IO WatcherList+newWatcherList n m = V.fromList <$> forM [0 .. int2lit (negate n) + 1] (\_ -> newManager m)++-- | returns the watcher List :: "ClauseManager" for "Literal" /l/+{-# INLINE getNthWatcher #-}+getNthWatcher :: WatcherList -> Lit -> ClauseExtManager+getNthWatcher = V.unsafeIndex++instance VectorFamily WatcherList C.Clause where+  dump mes wl = (mes ++) . L.concat <$> forM [1 .. V.length wl - 1] (\i -> dump ("\n" ++ show (lit2int i) ++ "' watchers:") (getNthWatcher wl i))++-- | purges all expirable clauses in 'WatcherList'+{-# INLINE garbageCollect #-}+garbageCollect :: WatcherList -> IO ()+garbageCollect = V.mapM_ purifyManager++{-+numberOfRegisteredClauses :: WatcherList -> IO Int+numberOfRegisteredClauses ws = sum <$> V.mapM numberOfClauses ws+-}++{-+-------------------------------------------------------------------------------- debugging stuff++checkConsistency :: ClauseManager a => a -> C.Clause -> IO ()+checkConsistency manager c = do+  nc <- numberOfClauses manager+  vec <- getClauseVector manager+  let+    loop :: Int -> IO ()+    loop i = do+      when (i < nc) $ do+        c' <- MV.unsafeRead vec i+        when (c' == c) $ error "insert a clause to a ClauseMananger twice"+        loop $ i + 1+  loop 0++checkClauseOrder :: ClauseManager a => a -> IO ()+checkClauseOrder manager = do+  putStr "checking..."+  nc <- numberOfClauses manager+  vec <- getClauseVector manager+  let+    nthActivity :: Int -> IO Double+    nthActivity i = getDouble . C.activity =<< MV.unsafeRead vec i+    report :: Int -> Int -> IO ()+    report i j = (putStr . (++ ", ") . show =<< nthActivity i) >> when (i < j) (report (i + 1) j)+    loop :: Int -> Double -> IO ()+    loop i v = do+      when (i < nc) $ do+        c <- MV.unsafeRead vec i+        a <- getDouble (C.activity c)+        when (c == C.NullClause) $ error "null is included"+        when (v < a) $ report 0 i >> error ("unsorted clause vector: " ++ show (nc, i))+        loop (i + 1) a+  loop 0 =<< nthActivity 0+  putStrLn "done"+-}
+ SAT/Mios/Data/Singleton.hs view
@@ -0,0 +1,105 @@+{-# LANGUAGE+    BangPatterns+  #-}+{-# LANGUAGE Trustworthy #-}++-- | A fast(est) mutable data based on Data.Vector.Unboxed.Mutable++module SAT.Mios.Data.Singleton+       (+         -- * Bool+         BoolSingleton+       , newBool+       , getBool+       , setBool+       , modifyBool+         -- * Int+       , IntSingleton+       , newInt+       , getInt+       , setInt+       , modifyInt+         -- * Double+       , DoubleSingleton+       , newDouble+       , getDouble+       , setDouble+       , modifyDouble+       )+       where+import qualified Data.Vector.Unboxed.Mutable as UV++-- | mutable Int+type IntSingleton = UV.IOVector Int++-- | returns a new 'IntSingleton'+newInt :: Int -> IO IntSingleton+newInt k = do+  s <- UV.new 1+  UV.unsafeWrite s 0 k+  return s++-- | returns the value+{-# INLINE getInt #-}+getInt :: IntSingleton -> IO Int+getInt val = UV.unsafeRead val 0++-- | sets the value+{-# INLINE setInt #-}+setInt :: IntSingleton -> Int -> IO ()+setInt val !x = UV.unsafeWrite val 0 x++-- | modifies the value+{-# INLINE modifyInt #-}+modifyInt :: IntSingleton -> (Int -> Int) -> IO ()+modifyInt val f = UV.unsafeModify val f 0++-- | mutable Bool+type BoolSingleton = UV.IOVector Bool++-- | returns a new 'BoolSingleton'+newBool :: Bool -> IO BoolSingleton+newBool b = do+  s <- UV.new 1+  UV.unsafeWrite s 0 b+  return s++-- | returns the value+{-# INLINE getBool #-}+getBool :: BoolSingleton -> IO Bool+getBool val = UV.unsafeRead val 0++-- | sets the value+{-# INLINE setBool #-}+setBool :: BoolSingleton -> Bool -> IO ()+setBool val !x = UV.unsafeWrite val 0 x++-- | modifies the value+{-# INLINE modifyBool #-}+modifyBool :: BoolSingleton -> (Bool -> Bool) -> IO ()+modifyBool val f = UV.unsafeModify val f 0++-- | mutable Double+type DoubleSingleton = UV.IOVector Double++-- | returns a new 'DoubleSingleton'+newDouble :: Double -> IO DoubleSingleton+newDouble d = do+  s <- UV.new 1+  UV.unsafeWrite s 0 d+  return s++-- | returns the value+{-# INLINE getDouble #-}+getDouble :: DoubleSingleton -> IO Double+getDouble val = UV.unsafeRead val 0++-- | sets the value+{-# INLINE setDouble #-}+setDouble :: DoubleSingleton -> Double -> IO ()+setDouble val !x = UV.unsafeWrite val 0 x++-- | modifies the value+{-# INLINE modifyDouble #-}+modifyDouble :: DoubleSingleton -> (Double -> Double) -> IO ()+modifyDouble val f = UV.unsafeModify val f 0
+ SAT/Mios/Data/Stack.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE+    MultiParamTypeClasses+  #-}+{-# LANGUAGE Trustworthy #-}++-- | stack of Int, by adding the length field as the zero-th element to a 'Vec'+module SAT.Mios.Data.Stack+       (+         Stack+       , newStack+       , clearStack+       , sizeOfStack+       , pushToStack+       , popFromStack+       , lastOfStack+       , shrinkStack+       , asSizedVec+--       , isoVec+       )+       where++import qualified Data.Vector.Unboxed.Mutable as UV+import SAT.Mios.Types++-- | Unboxed mutable stack for Int.+newtype Stack = Stack (UV.IOVector Int)++instance VectorFamily Stack Int where+  dump str v = (str ++) . show <$> asList v+  {-# SPECIALIZE INLINE asVec :: Stack -> Vec #-}+  asVec (Stack v) = UV.unsafeTail v+  asList (Stack v) = do+    (n : l) <- asList v+    return $ take n l++-- | returns the number of elements+{-# INLINE sizeOfStack #-}+sizeOfStack :: Stack -> IO Int+sizeOfStack (Stack v) = UV.unsafeRead v 0++-- | clear stack+{-# INLINE clearStack #-}+clearStack :: Stack -> IO ()+clearStack (Stack v) = UV.unsafeWrite v 0 0++-- | returns a new stack which size is @size@+{-# INLINABLE newStack #-}+newStack :: Int -> IO Stack+newStack n = do+  v <- UV.new $ n + 1+  UV.set v 0+  return $ Stack v++-- | pushs an int to 'Stack'+{-# INLINE pushToStack #-}+pushToStack :: Stack -> Int -> IO ()+pushToStack (Stack v) x = do+  i <- (+ 1) <$> UV.unsafeRead v 0+  UV.unsafeWrite v i x+  UV.unsafeWrite v 0 i++-- | drops the first element from 'Stack'+{-# INLINE popFromStack #-}+popFromStack :: Stack -> IO ()+popFromStack (Stack v) = UV.unsafeModify v (subtract 1) 0++-- | peeks the last element in 'Stack'+{-# INLINE lastOfStack #-}+lastOfStack :: Stack -> IO Int+lastOfStack (Stack v) = UV.unsafeRead v =<< UV.unsafeRead v 0++-- | Shrink the stack. The given arg means the number of discards.+-- therefore, shrink s n == for [1 .. n] $ \_ -> pop s+{-# INLINE shrinkStack #-}+shrinkStack :: Stack -> Int -> IO ()+shrinkStack (Stack v) k = UV.unsafeModify v (subtract k) 0++-- | converts Stack to sized Vec; this is the method to get the internal vector+{-# INLINE asSizedVec #-}+asSizedVec :: Stack -> Vec+asSizedVec (Stack v) = v++{-+-- | isomorphic conversion to 'Vec'+--+-- Note: 'asVec' drops the 1st element and no copy (unsafe operation); 'isoVec' really copies the real elements+{-# INLINE isoVec #-}+isoVec :: Stack -> IO Vec+isoVec (Stack v) = UV.clone . flip UV.take v . (1 +) =<< UV.unsafeRead v 0+-}
+ SAT/Mios/Data/Vec.hs view
@@ -0,0 +1,86 @@+-- | The fundamental data structure: Fixed Mutable Unboxed Int Vector+{-# LANGUAGE+    BangPatterns+  #-}+{-# LANGUAGE Trustworthy #-}++module SAT.Mios.Data.Vec+       (+         Vec+       , sizeOfVector+       , getNth+       , setNth+       , swapBetween+       , modifyNth+       , setAll+       , newVec+       , newVecWith+       , newSizedVecIntFromList+       , newSizedVecIntFromUVector+       , vecGrow+       )+       where++import qualified Data.Vector.Unboxed as U+import qualified Data.Vector.Unboxed.Mutable as UV++-- | Costs of all operations are /O/(/1/)+type Vec = UV.IOVector Int++-- | returns the size of 'Vec'+{-# INLINE sizeOfVector #-}+sizeOfVector :: Vec -> IO Int+sizeOfVector v = return $! UV.length v++-- | returns a new 'Vec'+{-# INLINE newVec #-}+newVec :: Int -> IO Vec+newVec = UV.new++-- | returns a new 'Vec' filled with an Int+{-# INLINE newVecWith #-}+newVecWith :: Int -> Int -> IO Vec+newVecWith n x = do+  v <- UV.new n+  UV.set v x+  return v++-- | gets the nth value+{-# INLINE getNth #-}+getNth :: Vec -> Int -> IO Int+getNth = UV.unsafeRead++-- | sets the nth value+{-# INLINE setNth #-}+setNth :: Vec -> Int -> Int -> IO ()+setNth = UV.unsafeWrite++-- | modify the nth value+{-# INLINE modifyNth #-}+modifyNth :: Vec -> (Int -> Int) -> Int -> IO ()+modifyNth = UV.unsafeModify++-- | sets all elements+{-# INLINE setAll #-}+setAll :: Vec -> Int -> IO ()+setAll = UV.set++-- | swaps two elements+{-# INLINE swapBetween #-}+swapBetween:: Vec -> Int -> Int -> IO ()+swapBetween = UV.unsafeSwap++-- | returns a new 'Vec' from a @[Int]@+{-# INLINE newSizedVecIntFromList #-}+newSizedVecIntFromList :: [Int] -> IO Vec+newSizedVecIntFromList !l = U.unsafeThaw $ U.fromList (length l : l)++-- | returns a new 'Vec' from a Unboxed Int Vector+{-# INLINE newSizedVecIntFromUVector #-}+newSizedVecIntFromUVector :: U.Vector Int -> IO Vec+newSizedVecIntFromUVector = U.unsafeThaw++-- | calls @unasfeGrow@+{-# INLINE vecGrow #-}+vecGrow :: Vec -> Int -> IO Vec+vecGrow = UV.unsafeGrow
+ SAT/Mios/Data/VecBool.hs view
@@ -0,0 +1,55 @@+-- | Mutable Unboxed Boolean Vector+--+-- * __VecBool@::UV.IOVector Bool@ -- data type that contains a mutable list of elements+--+{-# LANGUAGE+    BangPatterns+  , FlexibleInstances+  , MultiParamTypeClasses+  #-}+{-# LANGUAGE Trustworthy #-}++module SAT.Mios.Data.VecBool+       (+         VecBool+       , newVecBool+       , getNthBool+       , setNthBool+       , modifyNthBool+       )+       where++import Control.Monad (forM)+import qualified Data.Vector.Unboxed.Mutable as UV+import SAT.Mios.Types (VectorFamily(..))++-- | Mutable unboxed Bool Vector+type VecBool = UV.IOVector Bool++-- | provides 'clear' and 'size'+instance VectorFamily VecBool Bool where+  clear _ = error "VecBool.clear"+  asList v = forM [0 .. UV.length v - 1] $ UV.unsafeRead v+  dump str v = (str ++) . show <$> asList v++-- | returns a new 'VecBool'+newVecBool :: Int -> Bool -> IO VecBool+newVecBool n x = do+  v <- UV.new n+  UV.set v x+  return v++-- | returns the nth value in 'VecBool'+{-# INLINE getNthBool #-}+getNthBool :: VecBool -> Int -> IO Bool+getNthBool = UV.unsafeRead++-- | sets the nth value+{-# INLINE setNthBool #-}+setNthBool :: VecBool -> Int -> Bool -> IO ()+setNthBool = UV.unsafeWrite++-- | sets the nth value+{-# INLINE modifyNthBool #-}+modifyNthBool :: VecBool -> (Bool -> Bool) -> Int -> IO ()+modifyNthBool = UV.unsafeModify
+ SAT/Mios/Data/VecDouble.hs view
@@ -0,0 +1,53 @@+-- | Mutable Unboxed Double Vector+{-# LANGUAGE+    BangPatterns+  , FlexibleInstances+  , MultiParamTypeClasses+  #-}+{-# LANGUAGE Trustworthy #-}++module SAT.Mios.Data.VecDouble+       (+         VecDouble+       , newVecDouble+       , getNthDouble+       , setNthDouble+       , modifyNthDouble+       )+       where++import Control.Monad (forM)+import Data.List ()+import qualified Data.Vector.Unboxed.Mutable as UV+import SAT.Mios.Types (VectorFamily(..))++-- | Mutable unboxed Double Vector+type VecDouble = UV.IOVector Double++instance VectorFamily VecDouble Double where+  clear _ = error "VecDouble.clear"+  asList v = forM [0 .. UV.length v - 1] $ UV.unsafeRead v+  dump str v = (str ++) . show <$> asList v++-- | returns a new 'VecDouble'+newVecDouble :: Int -> Double -> IO VecDouble+newVecDouble n 0 = UV.new n+newVecDouble n x = do+  v <- UV.new n+  UV.set v x+  return v++-- | returns the nth value in 'VecDouble'+{-# INLINE getNthDouble #-}+getNthDouble :: Int -> VecDouble -> IO Double+getNthDouble !n v = UV.unsafeRead v n++-- | sets the nth value+{-# INLINE setNthDouble #-}+setNthDouble :: Int -> VecDouble -> Double -> IO ()+setNthDouble !n v !x = UV.unsafeWrite v n x++-- | updates the nth value+{-# INLINE modifyNthDouble #-}+modifyNthDouble :: Int -> VecDouble -> (Double -> Double) -> IO ()+modifyNthDouble !n v !f = UV.unsafeModify v f n
+ SAT/Mios/Internal.hs view
@@ -0,0 +1,33 @@+-- | Mios Internal Settings+module SAT.Mios.Internal+       (+         versionId+       , MiosConfiguration (..)+       , defaultConfiguration+       , module Plumbing+       )+       where+import SAT.Mios.Data.VecBool as Plumbing+import SAT.Mios.Data.VecDouble as Plumbing+import SAT.Mios.Data.Stack as Plumbing++-- | version name+versionId :: String+versionId = "mios 1.3.0 -- https://github.com/shnarazk/mios" -- no more LBD++-- | solver's parameters; random decision rate was dropped.+data MiosConfiguration = MiosConfiguration+                         {+                           variableDecayRate  :: !Double  -- ^ decay rate for variable activity+--                         , clauseDecayRate    :: !Double  -- ^ decay rate for clause activity+                         }++-- | dafault configuration+--+-- * Minisat-1.14 uses @(0.95, 0.999, 0.2 = 20 / 1000)@.+-- * Minisat-2.20 uses @(0.95, 0.999, 0)@.+-- * Gulcose-4.0  uses @(0.8 , 0.999, 0)@.+-- * Mios-1.2     uses @(0.95, 0.999, 0)@.+--+defaultConfiguration :: MiosConfiguration+defaultConfiguration = MiosConfiguration 0.95 {- 0.999 -} {- 0 -}
+ SAT/Mios/Main.hs view
@@ -0,0 +1,810 @@+{-# LANGUAGE+    BangPatterns+  , RecordWildCards+  , ScopedTypeVariables+  , ViewPatterns+  #-}+{-# LANGUAGE Safe #-}++-- | This is a part of MIOS; main heuristics+module SAT.Mios.Main+       (+         simplifyDB+       , solve+       )+        where++import Control.Monad (forM_, unless, void, when)+import Data.Bits+import Data.Foldable (foldrM)+import SAT.Mios.Types+import SAT.Mios.Internal+import SAT.Mios.Clause+import SAT.Mios.ClauseManager+import SAT.Mios.Solver+-- import SAT.Mios.Ranking++-------------------------------------------------------------------------------- Ranking+-- | a special version of ranking+{-# INLINE ranking' #-}+ranking' :: Clause -> IO Int+ranking' = sizeOfClause++-- | #114: __RemoveWatch__+{-# INLINABLE removeWatch #-}+removeWatch :: Solver -> Clause -> IO ()+removeWatch (watches -> w) c = do+  let lvec = asVec c+  l1 <- negateLit <$> getNth lvec 0+  markClause (getNthWatcher w l1) c+  l2 <- negateLit <$> getNth lvec 1+  markClause (getNthWatcher w l2) c++--------------------------------------------------------------------------------+-- Operations on 'Clause'+--------------------------------------------------------------------------------++-- | __Fig. 8. (p.12)__ create a new LEARNT clause and adds it to watcher lists+-- This is a strippped-down version of 'newClause' in Solver+{-# INLINABLE newLearntClause #-}+newLearntClause :: Solver -> Vec -> IO ()+newLearntClause s@Solver{..} ps = do+  good <- getBool ok+  when good $ do+    -- ps is a 'SizedVectorInt'; ps[0] is the number of active literals+    -- Since this solver must generate only healthy learnt clauses, we need not to run misc check in 'newClause'+    k <- getNth ps 0+    case k of+     1 -> do+       l <- getNth ps 1+       unsafeEnqueue s l NullClause+     _ -> do+       -- allocate clause:+       c <- newClauseFromVec True ps+       let vec = asVec c+       -- Pick a second literal to watch:+       let+         findMax :: Int -> Int -> Int -> IO Int+         findMax ((< k) -> False) j _ = return j+         findMax i j val = do+           v' <- lit2var <$> getNth vec i+           a <- getNth assigns v'+           b <- getNth level v'+           if (a /= lBottom) && (val < b)+             then findMax (i + 1) i b+             else findMax (i + 1) j val+       swapBetween vec 1 =<< findMax 0 0 0 -- Let @max_i@ be the index of the literal with highest decision level+       -- Bump, enqueue, store clause:+       setDouble (activity c) . fromIntegral =<< decisionLevel s -- newly learnt clauses should be considered active+       -- Add clause to all managers+       pushClause learnts c+       l <- getNth vec 0+       pushClauseWithKey (getNthWatcher watches (negateLit l)) c 0+       l1 <- negateLit <$> getNth vec 1+       pushClauseWithKey (getNthWatcher watches l1) c 0+       -- update the solver state by @l@+       unsafeEnqueue s l c+       -- Since unsafeEnqueue updates the 1st literal's level, setLBD should be called after unsafeEnqueue+       -- setRank s c+       setBool (protected c) True++-- | __Simplify.__ At the top-level, a constraint may be given the opportunity to+-- simplify its representation (returns @False@) or state that the constraint is+-- satisfied under the current assignment and can be removed (returns @True@).+-- A constraint must /not/ be simplifiable to produce unit information or to be+-- conflicting; in that case the propagation has not been correctly defined.+--+-- MIOS NOTE: the original doesn't update watchers; only checks its satisfiabiliy.+{-# INLINABLE simplify #-}+simplify :: Solver -> Clause -> IO Bool+simplify s c = do+  n <- sizeOfClause c+  let+    lvec = asVec c+    loop ::Int -> IO Bool+    loop ((< n) -> False) = return False+    loop i = do+      v <- valueLit s =<< getNth lvec i+      if v == 1 then return True else loop (i + 1)+  loop 0++--------------------------------------------------------------------------------+-- MIOS NOTE on Minor methods:+--+-- * no (meaningful) 'newVar' in mios+-- * 'assume' is defined in 'Solver'+-- * `cancelUntil` is defined in 'Solver'++--------------------------------------------------------------------------------+-- Major methods++-- | M114: __Fig. 10. (p.15)__+--+-- analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel :: int&) -> [void]+--+-- __Description:_-+--   Analzye confilct and produce a reason clause.+--+-- __Pre-conditions:__+--   * 'out_learnt' is assumed to be cleared.+--   * Corrent decision level must be greater than root level.+--+-- __Post-conditions:__+--   * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.+--   * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the+--     rest of literals. There may be others from the same level though.+--+-- @analyze@ is invoked from @search@+-- {-# INLINEABLE analyze #-}+analyze :: Solver -> Clause -> IO Int+analyze s@Solver{..} confl = do+  -- litvec+  clearStack litsLearnt+  pushToStack litsLearnt 0 -- reserve the first place for the unassigned literal+  dl <- decisionLevel s+  let+    litsVec = asVec litsLearnt+    trailVec = asVec trail+    loopOnClauseChain :: Clause -> Lit -> Int -> Int -> Int -> IO Int+    loopOnClauseChain c p ti bl pathC = do -- p : literal, ti = trail index, bl = backtrack level+      when (learnt c) $ do+        claBumpActivity s c+{-+        -- update LBD like #Glucose4.0+        d <- getInt (lbd c)+        when (2 < d) $ do+          nblevels <- lbdOf s c+          when (nblevels + 1 < d) $ do -- improve the LBD+            when (d <= 30) $ setBool (protected c) True -- 30 is `lbLBDFrozenClause`+            -- seems to be interesting: keep it fro the next round+            setInt (lbd c) nblevels    -- Update it+-}+      sc <- sizeOfClause c+      let+        lvec = asVec c+        loopOnLiterals :: Int -> Int -> Int -> IO (Int, Int)+        loopOnLiterals ((< sc) -> False) b pc = return (b, pc) -- b = btLevel, pc = pathC+        loopOnLiterals j b pc = do+          (q :: Lit) <- getNth lvec j+          let v = lit2var q+          sn <- getNth an'seen v+          l <- getNth level v+          if sn == 0 && 0 < l+            then do+                varBumpActivity s v+                setNth an'seen v 1+                if dl <= l      -- cancelUntil doesn't clear level of cancelled literals+                  then do+                      -- glucose heuristics+                      r <- getNthClause reason v+                      when (r /= NullClause && learnt r) $ pushToStack lastDL q+                      -- end of glucose heuristics+                      loopOnLiterals (j + 1) b (pc + 1)+                  else pushToStack litsLearnt q >> loopOnLiterals (j + 1) (max b l) pc+            else loopOnLiterals (j + 1) b pc+      (b', pathC') <- loopOnLiterals (if p == bottomLit then 0 else 1) bl pathC+      let+        -- select next clause to look at+        nextPickedUpLit :: Int -> IO Int+        nextPickedUpLit i = do+          x <- getNth an'seen . lit2var =<< getNth trailVec i+          if x == 0 then nextPickedUpLit $ i - 1 else return i+      ti' <- nextPickedUpLit ti+      nextP <- getNth trailVec ti'+      let nextV = lit2var nextP+      confl' <- getNthClause reason nextV+      setNth an'seen nextV 0+      if 1 < pathC'+        then loopOnClauseChain confl' nextP (ti' - 1) b' (pathC' - 1)+        else setNth litsVec 0 (negateLit nextP) >> return b'+  ti <- subtract 1 <$> sizeOfStack trail+  levelToReturn <- loopOnClauseChain confl bottomLit ti 0 0+  -- Simplify phase (implemented only @expensive_ccmin@ path)+  n <- sizeOfStack litsLearnt+  clearStack an'stack           -- analyze_stack.clear();+  clearStack an'toClear         -- out_learnt.copyTo(analyze_toclear);+  pushToStack an'toClear =<< getNth litsVec 0+  let+    merger :: Int -> Int -> IO Int+    merger ((< n) -> False) b = return b+    merger i b = do+      l <- getNth litsVec i+      pushToStack an'toClear l+      -- restrict the search depth (range) to 32+      merger (i + 1) . setBit b . (31 .&.) =<< getNth level (lit2var l)+  levels <- merger 1 0+  let+    loopOnLits :: Int -> Int -> IO ()+    loopOnLits ((< n) -> False) n' = shrinkStack litsLearnt $ n - n'+    loopOnLits i j = do+      l <- getNth litsVec i+      c1 <- (NullClause ==) <$> getNthClause reason (lit2var l)+      if c1+        then setNth litsVec j l >> loopOnLits (i + 1) (j + 1)+        else do+           c2 <- not <$> analyzeRemovable s l levels+           if c2+             then setNth litsVec j l >> loopOnLits (i + 1) (j + 1)+             else loopOnLits (i + 1) j+  loopOnLits 1 1                -- the first literal is specail+  -- glucose heuristics+  nld <- sizeOfStack lastDL+  r <- sizeOfStack litsLearnt -- this is not the right value+  let+    vec = asVec lastDL+    loopOnLastDL :: Int -> IO ()+    loopOnLastDL ((< nld) -> False) = return ()+    loopOnLastDL i = do+      v <- lit2var <$> getNth vec i+      r' <- ranking' =<< getNthClause reason v+      when (r < r') $ varBumpActivity s v+      loopOnLastDL $ i + 1+  loopOnLastDL 0+  clearStack lastDL+  -- Clear seen+  k <- sizeOfStack an'toClear+  let+    vec' = asVec an'toClear+    cleaner :: Int -> IO ()+    cleaner ((< k) -> False) = return ()+    cleaner i = do+      v <- lit2var <$> getNth vec' i+      setNth an'seen v 0+      cleaner $ i + 1+  cleaner 0+  return levelToReturn++-- | #M114+-- Check if 'p' can be removed, 'abstract_levels' is used to abort early if the algorithm is+-- visiting literals at levels that cannot be removed later.+--+-- Implementation memo:+--+-- *  @an'toClear@ is initialized by @ps@ in @analyze@ (a copy of 'learnt').+--   This is used only in this function and @analyze@.+--+{-# INLINEABLE analyzeRemovable #-}+analyzeRemovable :: Solver -> Lit -> Int -> IO Bool+analyzeRemovable Solver{..} p minLevel = do+  -- assert (reason[var(p)]!= NullCaulse);+  clearStack an'stack      -- analyze_stack.clear()+  pushToStack an'stack p   -- analyze_stack.push(p);+  top <- sizeOfStack an'toClear+  let+    loopOnStack :: IO Bool+    loopOnStack = do+      k <- sizeOfStack an'stack  -- int top = analyze_toclear.size();+      if 0 == k+        then return True+        else do -- assert(reason[var(analyze_stack.last())] != GClause_NULL);+            sl <- lastOfStack an'stack+            popFromStack an'stack             -- analyze_stack.pop();+            c <- getNthClause reason (lit2var sl) -- getRoot sl+            nl <- sizeOfClause c+            let+              cvec = asVec c+              loopOnLit :: Int -> IO Bool -- loopOnLit (int i = 1; i < c.size(); i++){+              loopOnLit ((< nl) -> False) = loopOnStack+              loopOnLit i = do+                p' <- getNth cvec i              -- valid range is [0 .. nl - 1]+                let v' = lit2var p'+                l' <- getNth level v'+                c1 <- (1 /=) <$> getNth an'seen v'+                if c1 && (0 /= l')   -- if (!analyze_seen[var(p)] && level[var(p)] != 0){+                  then do+                      c3 <- (NullClause /=) <$> getNthClause reason v'+                      if c3 && testBit minLevel (l' .&. 31) -- if (reason[var(p)] != GClause_NULL && ((1 << (level[var(p)] & 31)) & min_level) != 0){+                        then do+                            setNth an'seen v' 1        -- analyze_seen[var(p)] = 1;+                            pushToStack an'stack p'    -- analyze_stack.push(p);+                            pushToStack an'toClear p'  -- analyze_toclear.push(p);+                            loopOnLit $ i + 1+                        else do+                            -- loopOnLit (int j = top; j < analyze_toclear.size(); j++) analyze_seen[var(analyze_toclear[j])] = 0;+                            top' <- sizeOfStack an'toClear+                            let vec = asVec an'toClear+                            forM_ [top .. top' - 1] $ \j -> do x <- getNth vec j; setNth an'seen (lit2var x) 0+                            -- analyze_toclear.shrink(analyze_toclear.size() - top); note: shrink n == repeat n pop+                            shrinkStack an'toClear $ top' - top+                            return False+                  else loopOnLit $ i + 1+            loopOnLit 1+  loopOnStack++-- | #114+-- analyzeFinal : (confl : Clause *) (skip_first : boot) -> [void]+--+-- __Description:__+--   Specialized analysis proceduce to express the final conflict in terms of assumptions.+--   'root_level' is allowed to point beyond end of trace (useful if called after conflict while+--   making assumptions). If 'skip_first' is TRUE, the first literal of 'confl' is ignored (needed+--   if conflict arose before search even started).+--+analyzeFinal :: Solver -> Clause -> Bool -> IO ()+analyzeFinal Solver{..} confl skipFirst = do+  clearStack conflict+  rl <- getInt rootLevel+  unless (rl == 0) $ do+    n <- sizeOfClause confl+    let+      lvec = asVec confl+      loopOnConfl :: Int -> IO ()+      loopOnConfl ((< n) -> False) = return ()+      loopOnConfl i = do+        (x :: Var) <- lit2var <$> getNth lvec i+        lvl <- getNth level x+        when (0 < lvl) $ setNth an'seen x 1+        loopOnConfl $ i + 1+    loopOnConfl $ if skipFirst then 1 else 0+    tls <- sizeOfStack trailLim+    trs <- sizeOfStack trail+    tlz <- getNth (asVec trailLim) 0+    let+      trailVec = asVec trail+      loopOnTrail :: Int -> IO ()+      loopOnTrail ((tlz <=) -> False) = return ()+      loopOnTrail i = do+        (l :: Lit) <- getNth trailVec i+        let (x :: Var) = lit2var l+        saw <- getNth an'seen x+        when (saw == 1) $ do+          (r :: Clause) <- getNthClause reason x+          if r == NullClause+            then pushToStack conflict (negateLit l)+            else do+                k <- sizeOfClause r+                let+                  cvec = asVec r+                  loopOnLits :: Int -> IO ()+                  loopOnLits ((< k) -> False) = return ()+                  loopOnLits j = do+                    (v :: Var) <- lit2var <$> getNth cvec j+                    lv <- getNth level v+                    when (0 < lv) $ setNth an'seen v 1+                    loopOnLits $ i + 1+                loopOnLits 1+        setNth an'seen x 0+        loopOnTrail $ i - 1+    loopOnTrail =<< if tls <= rl then return (trs - 1) else getNth (asVec trailLim) rl++-- | M114:+-- propagate : [void] -> [Clause+]+--+-- __Description:__+--   Porpagates all enqueued facts. If a conflict arises, the conflicting clause is returned.+--   otherwise CRef_undef.+--+-- __Post-conditions:__+--   * the propagation queue is empty, even if there was a conflict.+--+-- memo: @propagate@ is invoked by @search@,`simpleDB` and `solve`+{-# INLINABLE propagate #-}+propagate :: Solver -> IO Clause+propagate s@Solver{..} = do+  -- myVal <- getNth stats (fromEnum NumOfBackjump)+  let+{-+    myVal = 0+    bumpAllVar :: IO ()         -- not in use+    bumpAllVar = do+      let+        loop :: Int -> IO ()+        loop ((<= nVars) -> False) = return ()+        loop i = do+          c <- getNth pr'seen i+          when (c == myVal) $ varBumpActivity s i+          loop $ i + 1+      loop 1+-}+    trailVec = asVec trail+    while :: Clause -> Bool -> IO Clause+    while confl False = {- bumpAllVar >> -} return confl+    while confl True = do+      (p :: Lit) <- getNth trailVec =<< getInt qHead+      modifyInt qHead (+ 1)+      let (ws :: ClauseExtManager) = getNthWatcher watches p+      end <- numberOfClauses ws+      cvec <- getClauseVector ws+      bvec <- getKeyVector ws+--      rc <- getNthClause reason $ lit2var p+--      byGlue <- if (rc /= NullClause) && learnt rc then (== 2) <$> getInt (lbd rc) else return False+      let+{-+        checkAllLiteralsIn :: Clause -> IO () -- not in use+        checkAllLiteralsIn c = do+          nc <- sizeOfClause c+          let+            vec = asVec c+            loop :: Int -> IO ()+            loop((< nc) -> False) = return ()+            loop i = do+              (v :: Var) <- lit2var <$> getNth vec i+              setNth pr'seen v myVal+              loop $ i + 1+          loop 0+-}+        forClause :: Clause -> Int -> Int -> IO Clause+        forClause confl i@((< end) -> False) j = do+          shrinkManager ws (i - j)+          while confl =<< ((<) <$> getInt qHead <*> sizeOfStack trail)+        forClause confl i j = do+          (l :: Lit) <- getNth bvec i+          bv <- if l == 0 then return lFalse else valueLit s l+          if bv == lTrue+            then do+                 unless (i == j) $ do -- NOTE: if i == j, the path doesn't require accesses to cvec!+                   (c :: Clause) <- getNthClause cvec i+                   setNthClause cvec j c+                   setNth bvec j l+                 forClause confl (i + 1) (j + 1)+            else do+                -- checkAllLiteralsIn c+                (c :: Clause) <- getNthClause cvec i+                let+                  lits = asVec c+                  falseLit = negateLit p+                -- Make sure the false literal is data[1]+                ((falseLit ==) <$> getNth lits 0) >>= (`when` swapBetween lits 0 1)+                -- if 0th watch is true, then clause is already satisfied.+                (first :: Lit) <- getNth lits 0+                val <- valueLit s first+                if val == lTrue+                  then setNthClause cvec j c >> setNth bvec j first >> forClause confl (i + 1) (j + 1)+                  else do+                      -- Look for new watch+                      cs <- sizeOfClause c+                      let+                        forLit :: Int -> IO Clause+                        forLit ((< cs) -> False) = do+                          -- Did not find watch; clause is unit under assignment:+                          setNthClause cvec j c+                          setNth bvec j 0+                          result <- enqueue s first c+                          if not result+                            then do+                                ((== 0) <$> decisionLevel s) >>= (`when` setBool ok False)+                                -- #BBCP+                                setInt qHead =<< sizeOfStack trail+                                -- Copy the remaining watches:+                                let+                                  copy i'@((< end) -> False) j' = forClause c i' j'+                                  copy i' j' = do+                                    setNthClause cvec j' =<< getNthClause cvec i'+                                    setNth bvec j' =<< getNth bvec i'+                                    copy (i' + 1) (j' + 1)+                                copy (i + 1) (j + 1)+                            else forClause confl (i + 1) (j + 1)+                        forLit k = do+                          (l :: Lit) <- getNth lits k+                          lv <- valueLit s l+                          if lv /= lFalse+                            then do+                                swapBetween lits 1 k+                                pushClauseWithKey (getNthWatcher watches (negateLit l)) c l+                                forClause confl (i + 1) j+                            else forLit $ k + 1+                      forLit 2+      forClause confl 0 0+  while NullClause =<< ((<) <$> getInt qHead <*> sizeOfStack trail)++-- | #M22+-- reduceDB: () -> [void]+--+-- __Description:__+--   Remove half of the learnt clauses, minus the clauses locked by the current assigmnent. Locked+--   clauses are clauses that are reason to some assignment. Binary clauses are never removed.+{-# INLINABLE reduceDB #-}+reduceDB :: Solver -> IO ()+reduceDB s@Solver{..} = do+  n <- nLearnts s+  vec <- getClauseVector learnts+  let+    loop :: Int -> IO ()+    loop ((< n) -> False) = return ()+    loop i = (removeWatch s =<< getNthClause vec i) >> loop (i + 1)+  k <- sortClauses s learnts (div n 2) -- k is the number of clauses not to be purged+  loop k                               -- CAVEAT: `vec` is a zero-based vector+  garbageCollect watches+  shrinkManager learnts (n - k)++-- | (Good to Bad) Quick sort the key vector based on their activities and returns number of privileged clauses.+-- this function uses the same metrix as reduceDB_lt in glucose 4.0:+-- 1. binary clause+-- 2. smaller rank+-- 3. larger activity defined in MiniSat+-- , where smaller value is better.+--+-- they are coded into an Int as the following layout:+--+-- * 14 bit: LBD or 0 for preserved clauses+-- * 19 bit: converted activity+-- * remain: clauseVector index+--+(rankWidth :: Int, activityWidth :: Int, indexWidth :: Int) = (l, a, w - (l + a + 1))+  where+    w = finiteBitSize (0:: Int)+    (l, a) = case () of+      _ | 64 <= w -> (8, 25)   -- 30 bit =>   1G clauses+      _ | 60 <= w -> (8, 24)   -- 26 bit =>  64M clauses+      _ | 32 <= w -> (6,  7)   -- 18 bit => 256K clauses+      _ | 29 <= w -> (6,  5)   -- 17 bit => 128K clauses+--      _ -> error "Int on your CPU doesn't have sufficient bit width."++{-# INLINABLE sortClauses #-}+sortClauses :: Solver -> ClauseExtManager -> Int -> IO Int+sortClauses s cm nneeds = do+  -- constants+  let+    rankMax :: Int+    rankMax = 2 ^ rankWidth - 1+    activityMax :: Int+    activityMax = 2 ^ activityWidth - 1+    activityScale :: Double+    activityScale = fromIntegral activityMax+    indexMax :: Int+    indexMax = (2 ^ indexWidth - 1) -- 67,108,863 for 26+  n <- numberOfClauses cm+  -- when (indexMax < n) $ error $ "## The number of learnt clauses " ++ show n ++ " exceeds mios's " ++ show indexWidth ++" bit manage capacity"+  vec <- getClauseVector cm+  keys <- getKeyVector cm+  -- 1: assign keys+  let+    assignKey :: Int -> Int -> IO Int+    assignKey ((< n) -> False) m = return m+    assignKey i m = do+      c <- getNthClause vec i+      k <- (\k -> if k == 2 then return k else fromEnum <$> getBool (protected c)) =<< sizeOfClause c+      case k of+        1 -> setBool (protected c) False >> setNth keys i (shiftL 2 indexWidth + i) >> assignKey (i + 1) (m + 1)+        2 -> setNth keys i (shiftL 1 indexWidth + i) >> assignKey (i + 1) (m + 1)+        _ -> do+            l <- locked s c      -- this is expensive+            if l+              then setNth keys i (shiftL 1 indexWidth + i) >> assignKey (i + 1) (m + 1)+              else do+                  d <- ranking' c+                  b <- floor . (activityScale *) . (1 -) . logBase claActivityThreshold . max 1 <$> getDouble (activity c)+                  setNth keys i $ shiftL (min rankMax d) (activityWidth + indexWidth) + shiftL b indexWidth + i+                  assignKey (i + 1) m+  limit <- min n . (+ nneeds) <$> assignKey 0 0+  -- 2: sort keyVector+  let+    sortOnRange :: Int -> Int -> IO ()+    sortOnRange left right+      | limit < left = return ()+      | left >= right = return ()+      | left + 1 == right = do+          a <- getNth keys left+          b <- getNth keys right+          unless (a < b) $ swapBetween keys left right+      | otherwise = do+          let p = div (left + right) 2+          pivot <- getNth keys p+          swapBetween keys p left -- set a sentinel for r'+          let+            nextL :: Int -> IO Int+            nextL i@((<= right) -> False) = return i+            nextL i = do v <- getNth keys i; if v < pivot then nextL (i + 1) else return i+            nextR :: Int -> IO Int+            nextR i = do v <- getNth keys i; if pivot < v then nextR (i - 1) else return i+            divide :: Int -> Int -> IO Int+            divide l r = do+              l' <- nextL l+              r' <- nextR r+              if l' < r' then swapBetween keys l' r' >> divide (l' + 1) (r' - 1) else return r'+          m <- divide (left + 1) right+          swapBetween keys left m+          sortOnRange left (m - 1)+          sortOnRange (m + 1) right+  sortOnRange 0 (n - 1)+  -- 3: place clauses+  let+    seek :: Int -> IO ()+    seek ((< limit) -> False) = return ()+    seek i = do+      bits <- getNth keys i+      when (indexMax < bits) $ do+        c <- getNthClause vec i+        let+          sweep k = do+            k' <- (indexMax .&.) <$> getNth keys k+            setNth keys k k+            if k' == i+              then setNthClause vec k c+              else getNthClause vec k' >>= setNthClause vec k >> sweep k'+        sweep i+      seek $ i + 1+  seek 0+  return limit++-- | #M22+--+-- simplify : [void] -> [bool]+--+-- __Description:__+--   Simplify the clause database according to the current top-level assigment. Currently, the only+--   thing done here is the removal of satisfied clauses, but more things can be put here.+--+{-# INLINABLE simplifyDB #-}+simplifyDB :: Solver -> IO Bool+simplifyDB s@Solver{..} = do+  good <- getBool ok+  if good+    then do+      p <- propagate s+      if p /= NullClause+        then setBool ok False >> return False+        else do+            -- Clear watcher lists:+            n <- sizeOfStack trail+            let+              vec = asVec trail+              loopOnLit ((< n) -> False) = return ()+              loopOnLit i = do+                l <- getNth vec i+                clearManager . getNthWatcher watches $ l+                clearManager . getNthWatcher watches $ negateLit l+                loopOnLit $ i + 1+            loopOnLit 0+            -- Remove satisfied clauses:+            let+              for :: Int -> IO Bool+              for ((< 2) -> False) = return True+              for t = do+                let ptr = if t == 0 then learnts else clauses+                vec' <- getClauseVector ptr+                n' <- numberOfClauses ptr+                let+                  loopOnVector :: Int -> Int -> IO Bool+                  loopOnVector ((< n') -> False) j = shrinkManager ptr (n' - j) >> return True+                  loopOnVector i j = do+                        c <- getNthClause vec' i+                        l <- locked s c+                        r <- simplify s c+                        if not l && r+                          then removeWatch s c >> loopOnVector (i + 1) j+                          else setNthClause vec' j c >> loopOnVector (i + 1) (j + 1)+                loopOnVector 0 0+            ret <- for 0+            garbageCollect watches+            return ret+    else return False++-- | #M22+--+-- search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool]+--+-- __Description:__+--   Search for a model the specified number of conflicts.+--   NOTE: Use negative value for 'nof_conflicts' indicate infinity.+--+-- __Output:__+--   'l_True' if a partial assigment that is consistent with respect to the clause set is found. If+--   all variables are decision variables, that means that the clause set is satisfiable. 'l_False'+--   if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.+{-# INLINABLE search #-}+search :: Solver -> Int -> Int -> IO LiftedBool+search s@Solver{..} nOfConflicts nOfLearnts = do+  -- clear model+  let+    loop :: Int -> IO LiftedBool+    loop conflictC = do+      !confl <- propagate s+      d <- decisionLevel s+      if confl /= NullClause+        then do+            -- CONFLICT+            incrementStat s NumOfBackjump 1+            r <- getInt rootLevel+            if d == r+              then do+                  -- Contradiction found:+                  analyzeFinal s confl False+                  return LFalse+              else do+--                  u <- (== 0) . (flip mod 5000) <$> getNth stats (fromEnum NumOfBackjump)+--                  when u $ do+--                    d <- getDouble varDecay+--                    when (d < 0.95) $ modifyDouble varDecay (+ 0.01)+                  backtrackLevel <- analyze s confl -- 'analyze' resets litsLearnt by itself+                  (s `cancelUntil`) . max backtrackLevel =<< getInt rootLevel+                  newLearntClause s $ asSizedVec litsLearnt+                  k <- sizeOfStack litsLearnt+                  when (k == 1) $ do+                    (v :: Var) <- lit2var <$> getNth (asVec litsLearnt) 0+                    setNth level v 0+                  varDecayActivity s+                  -- claDecayActivity s+                  loop $ conflictC + 1+        else do                 -- NO CONFLICT+            -- Simplify the set of problem clauses:+            when (d == 0) . void $ simplifyDB s -- our simplifier cannot return @False@ here+            k1 <- numberOfClauses learnts+            k2 <- nAssigns s+            when (k1 - k2 >= nOfLearnts) $ reduceDB s -- Reduce the set of learnt clauses+            case () of+             _ | k2 == nVars -> do+                   -- Model found:+                   forM_ [0 .. nVars - 1] $ \i -> setNthBool model i . (lTrue ==) =<< getNth assigns (i + 1)+                   return LTrue+             _ | conflictC >= nOfConflicts -> do+                   -- Reached bound on number of conflicts+                   (s `cancelUntil`) =<< getInt rootLevel -- force a restart+                   claRescaleActivityAfterRestart s+                   incrementStat s NumOfRestart 1+                   return Bottom+             _ -> do+               -- New variable decision:+               v <- select s -- many have heuristic for polarity here+               -- << #phasesaving+               oldVal <- getNth phases v+               unsafeAssume s $ var2lit v (0 < oldVal) -- cannot return @False@+               -- >> #phasesaving+               loop conflictC+  good <- getBool ok+  if good then loop 0 else return LFalse++-- | __Fig. 16. (p.20)__+-- Main solve method.+--+-- __Pre-condition:__ If assumptions are used, 'simplifyDB' must be+-- called right before using this method. If not, a top-level conflict (resulting in a+-- non-usable internal state) cannot be distinguished from a conflict under assumptions.+solve :: (Foldable t) => Solver -> t Lit -> IO Bool+solve s@Solver{..} assumps = do+  -- PUSH INCREMENTAL ASSUMPTIONS:+  let+    injector :: Lit -> Bool -> IO Bool+    injector _ False = return False+    injector a True = do+      b <- assume s a+      if not b+        then do                 -- conflict analyze+            (confl :: Clause) <- getNthClause reason (lit2var a)+            analyzeFinal s confl True+            pushToStack conflict (negateLit a)+            cancelUntil s 0+            return False+        else do+            confl <- propagate s+            if confl /= NullClause+              then do+                  analyzeFinal s confl True+                  cancelUntil s 0+                  return False+              else return True+  good <- simplifyDB s+  x <- if good then foldrM injector True assumps else return False+  if not x+    then return False+    else do+        setInt rootLevel =<< decisionLevel s+        -- SOLVE:+        nc <- fromIntegral <$> nClauses s+        let+          while :: Double -> Double -> IO Bool+          while nOfConflicts nOfLearnts = do+            status <- search s (floor nOfConflicts) (floor nOfLearnts)+            if status == Bottom+              then while (1.5 * nOfConflicts) (1.1 * nOfLearnts)+              else cancelUntil s 0 >> return (status == LTrue)+        while 100 (nc / 3.0)++--+-- 'enqueue' is defined in 'Solver'; most functions in M114 use 'unsafeEnqueue'+--+{-# INLINABLE unsafeEnqueue #-}+unsafeEnqueue :: Solver -> Lit -> Clause -> IO ()+unsafeEnqueue s@Solver{..} p from = do+  let v = lit2var p+  setNth assigns v $! if positiveLit p then lTrue else lFalse+  setNth level v =<< decisionLevel s+  setNthClause reason v from     -- NOTE: @from@ might be NULL!+  pushToStack trail p++-- __Pre-condition:__ propagation queue is empty+{-# INLINE unsafeAssume #-}+unsafeAssume :: Solver -> Lit -> IO ()+unsafeAssume s@Solver{..} p = do+  pushToStack trailLim =<< sizeOfStack trail+  unsafeEnqueue s p NullClause
+ SAT/Mios/OptionParser.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE Safe #-}++-- | command line option parser for mios+module SAT.Mios.OptionParser+       (+         MiosConfiguration (..)+       , defaultConfiguration+       , MiosProgramOption (..)+       , miosDefaultOption+       , miosOptions+       , miosUsage+       , miosParseOptions+       , miosParseOptionsFromArgs+       , toMiosConf+       )+       where++import System.Console.GetOpt (ArgDescr(..), ArgOrder(..), getOpt, OptDescr(..), usageInfo)+import System.Environment (getArgs)+import SAT.Mios.Internal (MiosConfiguration (..), defaultConfiguration)++-- | configuration swithces+data MiosProgramOption = MiosProgramOption+                     {+                       _targetFile :: Maybe String+                     , _outputFile :: Maybe String+                     , _confVariableDecayRate :: !Double+--                     , _confClauseDecayRate :: Double+--                     , _confRandomDecisionRate :: Int+                     , _confCheckAnswer :: !Bool+                     , _confVerbose :: !Bool+                     , _confTimeProbe :: !Bool+                     , _confStatProbe :: !Bool+                     , _confNoAnswer :: !Bool+                     , _validateAssignment :: !Bool+                     , _displayHelp :: !Bool+                     , _displayVersion :: !Bool+                     }++-- | default option settings+miosDefaultOption :: MiosProgramOption+miosDefaultOption = MiosProgramOption+  {+    _targetFile = Just ""+  , _outputFile = Nothing+  , _confVariableDecayRate = variableDecayRate defaultConfiguration+--  , _confClauseDecayRate = clauseDecayRate defaultConfiguration+--  , _confRandomDecisionRate = randomDecisionRate defaultConfiguration+  , _confCheckAnswer = False+  , _confVerbose = False+  , _confTimeProbe = False+  , _confStatProbe = False+  , _confNoAnswer = False+  , _validateAssignment = False+  , _displayHelp = False+  , _displayVersion = False+  }++-- | definition of mios option+miosOptions :: [OptDescr (MiosProgramOption -> MiosProgramOption)]+miosOptions =+  [+    Option ['d'] ["variable-decay-rate"]+    (ReqArg (\v c -> c { _confVariableDecayRate = read v }) (show (_confVariableDecayRate miosDefaultOption)))+    "[solver] variable activity decay rate (0.0 - 1.0)"+--  , Option ['c'] ["clause-decay-rate"]+--    (ReqArg (\v c -> c { _confClauseDecayRate = read v }) (show (_confClauseDecayRate miosDefaultOption)))+--    "[solver] clause activity decay rate (0.0 - 1.0)"+--  , Option ['r'] ["random-decision-rate"]+--    (ReqArg (\v c -> c { _confRandomDecisionRate = read v }) (show (_confRandomDecisionRate miosDefaultOption)))+--    "[solver] random selection rate (0 - 1000)"+  , Option [':'] ["validate-assignment"]+    (NoArg (\c -> c { _validateAssignment = True }))+    "[solver] read an assignment from STDIN and validate it"+  , Option [] ["validate"]+    (NoArg (\c -> c { _confCheckAnswer = True }))+    "[solver] self-check the (satisfied) answer"+  , Option ['o'] ["output"]+    (ReqArg (\v c -> c { _outputFile = Just v })"file")+    "[option] filename to store the result"+{-+  , Option [] ["stdin"]+    (NoArg (\c -> c { _targetFile = Nothing }))+    "[option] read a CNF from STDIN instead of a file"+-}+  , Option ['v'] ["verbose"]+    (NoArg (\c -> c { _confVerbose = True }))+    "[option] display misc information"+  , Option ['X'] ["hide-solution"]+    (NoArg (\c -> c { _confNoAnswer = True }))+    "[option] hide the solution"+  , Option [] ["time"]+    (NoArg (\c -> c { _confTimeProbe = True }))+    "[option] display execution time"+  , Option [] ["stat"]+    (NoArg (\c -> c { _confStatProbe = True }))+    "[option] display statistics information"+  , Option ['h'] ["help"]+    (NoArg (\c -> c { _displayHelp = True }))+    "[misc] display this help message"+  , Option [] ["version"]+    (NoArg (\c -> c { _displayVersion = True }))+    "[misc] display program ID"+  ]++-- | generates help message+miosUsage :: String -> String+miosUsage mes = usageInfo mes miosOptions++-- | builds "MiosProgramOption" from string given as command option+miosParseOptions :: String -> [String] -> IO MiosProgramOption+miosParseOptions mes argv =+    case getOpt Permute miosOptions argv of+      (o, [], []) -> do+        return $ foldl (flip id) miosDefaultOption o+      (o, (n:_), []) -> do+        let conf = foldl (flip id) miosDefaultOption o+        return $ conf { _targetFile = Just n }+      (_, _, errs) -> ioError (userError (concat errs ++ miosUsage mes))++-- | builds "MiosProgramOption" from a String+miosParseOptionsFromArgs :: String -> IO MiosProgramOption+miosParseOptionsFromArgs mes = miosParseOptions mes =<< getArgs++-- | converts "MiosProgramOption" into "SIHConfiguration"+toMiosConf :: MiosProgramOption -> MiosConfiguration+toMiosConf opts = MiosConfiguration+                 {+                   variableDecayRate = _confVariableDecayRate opts+--                 , clauseDecayRate = _confClauseDecayRate opts+--                 , randomDecisionRate = _confRandomDecisionRate opts+                 }
+ SAT/Mios/Solver.hs view
@@ -0,0 +1,611 @@+{-# LANGUAGE+    BangPatterns+  , RecordWildCards+  , ScopedTypeVariables+  , TupleSections+  , ViewPatterns+  #-}+{-# LANGUAGE Safe #-}++-- | This is a part of MIOS; main data+module SAT.Mios.Solver+       (+         -- * Solver+         Solver (..)+       , newSolver+         -- * Misc Accessors+       , nAssigns+       , nClauses+       , nLearnts+       , decisionLevel+       , valueVar+       , valueLit+       , locked+         -- * State Modifiers+       , addClause+       , enqueue+       , assume+       , cancelUntil+       , getModel+         -- * Activities+       , claBumpActivity+--       , claDecayActivity+       , claRescaleActivityAfterRestart+       , varBumpActivity+       , varDecayActivity+       , claActivityThreshold+         -- * Stats+       , StatIndex (..)+       , getStat+       , setStat+       , incrementStat+       , getStats+       )+        where++import Control.Monad ((<=<), forM_, unless, when)+import SAT.Mios.Types+import SAT.Mios.Internal+import SAT.Mios.Clause+import SAT.Mios.ClauseManager++-- | __Fig. 2.(p.9)__ Internal State of the solver+data Solver = Solver+              {+                -- Public Interface+                model      :: !VecBool           -- ^ If found, this vector has the model+              , conflict   :: !Stack             -- ^ set of literals in the case of conflicts+                -- Clause Database+              , clauses    :: !ClauseExtManager  -- ^ List of problem constraints.+              , learnts    :: !ClauseExtManager  -- ^ List of learnt clauses.+              , watches    :: !WatcherList       -- ^ a list of constraint wathing 'p', literal-indexed+                -- Assignment Management+              , assigns    :: !Vec               -- ^ The current assignments indexed on variables; var-indexed+              , phases     :: !Vec               -- ^ The last assignments indexed on variables; var-indexed+              , trail      :: !Stack             -- ^ List of assignments in chronological order; var-indexed+              , trailLim   :: !Stack             -- ^ Separator indices for different decision levels in 'trail'.+              , qHead      :: !IntSingleton      -- ^ 'trail' is divided at qHead; assignments and queue+              , reason     :: !ClauseVector      -- ^ For each variable, the constraint that implied its value; var-indexed+              , level      :: !Vec               -- ^ For each variable, the decision level it was assigned; var-indexed+                -- Variable Order+              , activities :: !VecDouble         -- ^ Heuristic measurement of the activity of a variable; var-indexed+              , order      :: !VarHeap           -- ^ Keeps track of the dynamic variable order.+                -- Configuration+              , config     :: !MiosConfiguration -- ^ search paramerters+              , nVars      :: !Int               -- ^ number of variables+--            , claInc     :: !DoubleSingleton   -- ^ Clause activity increment amount to bump with.+--            , varDecay   :: !DoubleSingleton   -- ^ used to set 'varInc'+              , varInc     :: !DoubleSingleton   -- ^ Variable activity increment amount to bump with.+              , rootLevel  :: !IntSingleton      -- ^ Separates incremental and search assumptions.+                -- Working Memory+              , ok         :: !BoolSingleton     -- ^ return value holder+              , an'seen    :: !Vec               -- ^ scratch var for 'analyze'; var-indexed+              , an'toClear :: !Stack             -- ^ ditto+              , an'stack   :: !Stack             -- ^ ditto+              , pr'seen    :: !Vec               -- ^ used in propagate+              , litsLearnt :: !Stack             -- ^ used to create a learnt clause+              , lastDL     :: !Stack             -- ^ last decision level used in analyze+              , stats      :: !Vec               -- ^ statistics information holder+{-+              , lbd'seen   :: !Vec               -- ^ used in lbd computation+              , lbd'key    :: !IntSingleton      -- ^ used in lbd computation+-}+              }++-- | returns an everything-is-initialized solver from the arguments+newSolver :: MiosConfiguration -> CNFDescription -> IO Solver+newSolver conf (CNFDescription nv nc _) = do+  Solver+    -- Public Interface+    <$> newVecBool nv False                           -- model+    <*> newStack nv                                   -- coflict+    -- Clause Database+    <*> newManager nc                                 -- clauses+    <*> newManager nc                                 -- learnts+    <*> newWatcherList nv 2                           -- watches+    -- Assignment Management+    <*> newVecWith (nv + 1) lBottom                   -- assigns+    <*> newVecWith (nv + 1) lBottom                   -- phases+    <*> newStack nv                                   -- trail+    <*> newStack nv                                   -- trailLim+    <*> newInt 0                                      -- qHead+    <*> newClauseVector (nv + 1)                      -- reason+    <*> newVecWith (nv + 1) (-1)                      -- level+    -- Variable Order+    <*> newVecDouble (nv + 1) 0                       -- activities+    <*> newVarHeap nv                                 -- order+    -- Configuration+    <*> return conf                                   -- config+    <*> return nv                                     -- nVars+--  <*> newDouble 1.0                                 -- claInc+--  <*> newDouble (variableDecayRate conf)            -- varDecay+    <*> newDouble 1.0                                 -- varInc+    <*> newInt 0                                      -- rootLevel+    -- Working Memory+    <*> newBool True                                  -- ok+    <*> newVec (nv + 1)                               -- an'seen+    <*> newStack nv                                   -- an'toClear+    <*> newStack nv                                   -- an'stack+    <*> newVecWith (nv + 1) (-1)                      -- pr'seen+    <*> newStack nv                                   -- litsLearnt+    <*> newStack nv                                   -- lastDL+    <*> newVec (1 + fromEnum (maxBound :: StatIndex)) -- stats+{-+--    <*> newVec nv                                     -- lbd'seen+--    <*> newInt 0                                      -- lbd'key+-}++--------------------------------------------------------------------------------+-- Accessors++-- | returns the number of current assigments+{-# INLINE nAssigns #-}+nAssigns :: Solver -> IO Int+nAssigns = sizeOfStack . trail++-- | returns the number of constraints (clauses)+{-# INLINE nClauses #-}+nClauses  :: Solver -> IO Int+nClauses = numberOfClauses . clauses++-- | returns the number of learnt clauses+{-# INLINE nLearnts #-}+nLearnts :: Solver -> IO Int+nLearnts = numberOfClauses . learnts++-- | return the model as a list of literal+getModel :: Solver -> IO [Int]+getModel s = zipWith (\n b -> if b then n else negate n) [1 .. ] <$> asList (model s)++-- | returns the current decision level+{-# INLINE decisionLevel #-}+decisionLevel :: Solver -> IO Int+decisionLevel = sizeOfStack . trailLim++-- | returns the assignment (:: 'LiftedBool' = @[-1, 0, -1]@) from 'Var'+{-# INLINE valueVar #-}+valueVar :: Solver -> Var -> IO Int+valueVar = getNth . assigns++-- | returns the assignment (:: 'LiftedBool' = @[-1, 0, -1]@) from 'Lit'+{-# INLINE valueLit #-}+valueLit :: Solver -> Lit -> IO Int -- FIXME: LiftedBool+valueLit (assigns -> a) !p = (\x -> if positiveLit p then x else negate x) <$> getNth a (lit2var p)++-- | __Fig. 7. (p.11)__+-- returns @True@ if the clause is locked (used as a reason). __Learnt clauses only__+{-# INLINE locked #-}+locked :: Solver -> Clause -> IO Bool+locked s c = (c ==) <$> (getNthClause (reason s) . lit2var =<< getNth (lits c) 1)++-------------------------------------------------------------------------------- Statistics++-- | stat index+data StatIndex =+    NumOfBackjump+  | NumOfRestart+  deriving (Bounded, Enum, Eq, Ord, Read, Show)++-- | returns the value of 'StatIndex'+{-# INLINE getStat #-}+getStat :: Solver -> StatIndex -> IO Int+getStat (stats -> v) (fromEnum -> i) = getNth v i++-- | sets to 'StatIndex'+{-# INLINE setStat #-}+setStat :: Solver -> StatIndex -> Int -> IO ()+setStat (stats -> v) (fromEnum -> i) x = setNth v i x++-- | increments a stat data corresponding to 'StatIndex'+{-# INLINE incrementStat #-}+incrementStat :: Solver -> StatIndex -> Int -> IO ()+incrementStat (stats -> v) (fromEnum -> i) k = modifyNth v (+ k) i++-- | returns the statistics as list+{-# INLINABLE getStats #-}+getStats :: Solver -> IO [(StatIndex, Int)]+getStats (stats -> v) = mapM (\i -> (i, ) <$> getNth v (fromEnum i)) [minBound .. maxBound :: StatIndex]++-------------------------------------------------------------------------------- State Modifiers++-- | returns @False@ if a conflict has occured.+-- This function is called only before the solving phase to register the given clauses.+{-# INLINABLE addClause #-}+addClause :: Solver -> Vec -> IO Bool+addClause s@Solver{..} vecLits = do+  result <- clauseNew s vecLits False+  case result of+   (False, _) -> return False   -- Conflict occured+   (True, c)  -> do+     unless (c == NullClause) $ pushClause clauses c+     return True                -- No conflict++-- | __Fig. 8. (p.12)__ create a new clause and adds it to watcher lists+-- Constructor function for clauses. Returns @False@ if top-level conflict is determined.+-- @outClause@ may be set to Null if the new clause is already satisfied under the current+-- top-level assignment.+--+-- __Post-condition:__ @ps@ is cleared. For learnt clauses, all+-- literals will be false except @lits[0]@ (this by design of the 'analyze' method).+-- For the propagation to work, the second watch must be put on the literal which will+-- first be unbound by backtracking. (Note that none of the learnt-clause specific things+-- needs to done for a user defined contraint type.)+{-# INLINABLE clauseNew #-}+clauseNew :: Solver -> Vec -> Bool -> IO (Bool, Clause)+clauseNew s@Solver{..} ps isLearnt = do+  -- now ps[0] is the number of living literals+  exit <- do+    let+      handle :: Int -> Int -> Int -> IO Bool+      handle j l n      -- removes duplicates, but returns @True@ if this clause is satisfied+        | j > n = return False+        | otherwise = do+            y <- getNth ps j+            case () of+             _ | y == l -> do             -- finds a duplicate+                   swapBetween ps j n+                   modifyNth ps (subtract 1) 0+                   handle j l (n - 1)+             _ | - y == l -> setNth ps 0 0 >> return True -- p and negateLit p occurs in ps+             _ -> handle (j + 1) l n+      loopForLearnt :: Int -> IO Bool+      loopForLearnt i = do+        n <- getNth ps 0+        if n < i+          then return False+          else do+              l <- getNth ps i+              sat <- handle (i + 1) l n+              if sat+                then return True+                else loopForLearnt $ i + 1+      loop :: Int -> IO Bool+      loop i = do+        n <- getNth ps 0+        if n < i+          then return False+          else do+              l <- getNth ps i     -- check the i-th literal's satisfiability+              sat <- valueLit s l                                      -- any literal in ps is true+              case sat of+               1  -> setNth ps 0 0 >> return True+               -1 -> do+                 swapBetween ps i n+                 modifyNth ps (subtract 1) 0+                 loop i+               _ -> do+                 sat' <- handle (i + 1) l n+                 if sat'+                   then return True+                   else loop $ i + 1+    if isLearnt then loopForLearnt 1 else loop 1+  k <- getNth ps 0+  case k of+   0 -> return (exit, NullClause)+   1 -> do+     l <- getNth ps 1+     (, NullClause) <$> enqueue s l NullClause+   _ -> do+     -- allocate clause:+     c <- newClauseFromVec isLearnt ps+     let vec = asVec c+     when isLearnt $ do+       -- Pick a second literal to watch:+       let+         findMax :: Int -> Int -> Int -> IO Int+         findMax ((< k) -> False) j _ = return j+         findMax i j val = do+           v' <- lit2var <$> getNth vec i+           a <- getNth assigns v'+           b <- getNth level v'+           if (a /= lBottom) && (val < b)+             then findMax (i + 1) i b+             else findMax (i + 1) j val+       -- Let @max_i@ be the index of the literal with highest decision level+       max_i <- findMax 0 0 0+       swapBetween vec 1 max_i+       -- check literals occurences+       -- x <- asList c+       -- unless (length x == length (nub x)) $ error "new clause contains a element doubly"+       -- Bumping:+       claBumpActivity s c -- newly learnt clauses should be considered active+       forM_ [0 .. k -1] $ varBumpActivity s . lit2var <=< getNth vec -- variables in conflict clauses are bumped+     -- Add clause to watcher lists:+     l0 <- negateLit <$> getNth vec 0+     pushClauseWithKey (getNthWatcher watches l0) c 0+     l1 <- negateLit <$> getNth vec 1+     pushClauseWithKey (getNthWatcher watches l1) c 0+     return (True, c)++-- | __Fig. 9 (p.14)__+-- Puts a new fact on the propagation queue, as well as immediately updating the variable's value+-- in the assignment vector. If a conflict arises, @False@ is returned and the propagation queue is+-- cleared. The parameter 'from' contains a reference to the constraint from which 'p' was+-- propagated (defaults to @Nothing@ if omitted).+{-# INLINABLE enqueue #-}+enqueue :: Solver -> Lit -> Clause -> IO Bool+enqueue s@Solver{..} p from = do+{-+  -- bump psedue lbd of @from@+  when (from /= NullClause && learnt from) $ do+    l <- getInt (lbd from)+    k <- (12 +) <$> decisionLevel s+    when (k < l) $ setInt (lbd from) k+-}+  let signumP = if positiveLit p then lTrue else lFalse+  let v = lit2var p+  val <- valueVar s v+  if val /= lBottom+    then do -- Existing consistent assignment -- don't enqueue+        return $ val == signumP+    else do+        -- New fact, store it+        setNth assigns v signumP+        setNth level v =<< decisionLevel s+        setNthClause reason v from     -- NOTE: @from@ might be NULL!+        pushToStack trail p+        return True++-- | __Fig. 12 (p.17)__+-- returns @False@ if immediate conflict.+--+-- __Pre-condition:__ propagation queue is empty+{-# INLINE assume #-}+assume :: Solver -> Lit -> IO Bool+assume s p = do+  pushToStack (trailLim s) =<< sizeOfStack (trail s)+  enqueue s p NullClause++-- | #M22: Revert to the states at given level (keeping all assignment at 'level' but not beyond).+{-# INLINABLE cancelUntil #-}+cancelUntil :: Solver -> Int -> IO ()+cancelUntil s@Solver{..} lvl = do+  dl <- decisionLevel s+  when (lvl < dl) $ do+    let tr = asVec trail+    let tl = asVec trailLim+    lim <- getNth tl lvl+    ts <- sizeOfStack trail+    ls <- sizeOfStack trailLim+    let+      loopOnTrail :: Int -> IO ()+      loopOnTrail ((lim <=) -> False) = return ()+      loopOnTrail c = do+        x <- lit2var <$> getNth tr c+        setNth phases x =<< getNth assigns x+        setNth assigns x lBottom+        -- #reason to set reason Null+        -- if we don't clear @reason[x] :: Clause@ here, @reason[x]@ remains as locked.+        -- This means we can't reduce it from clause DB and affects the performance.+        setNthClause reason x NullClause -- 'analyze` uses reason without checking assigns+        -- FIXME: #polarity https://github.com/shnarazk/minisat/blosb/master/core/Solver.cc#L212+        undo s x+        -- insertHeap s x              -- insertVerOrder+        loopOnTrail $ c - 1+    loopOnTrail $ ts - 1+    shrinkStack trail (ts - lim)+    shrinkStack trailLim (ls - lvl)+    setInt qHead =<< sizeOfStack trail++-------------------------------------------------------------------------------- VarOrder++-- | Interfate to select a decision var based on variable activity.+instance VarOrder Solver where+  -- | __Fig. 6. (p.10)__+  -- Creates a new SAT variable in the solver.+  newVar _ = return 0+    -- i <- nVars s+    -- Version 0.4:: push watches =<< newVec      -- push'+    -- Version 0.4:: push watches =<< newVec      -- push'+    -- push undos =<< newVec        -- push'+    -- push reason NullClause       -- push'+    -- push assigns lBottom+    -- push level (-1)+    -- push activities (0.0 :: Double)+    -- newVar order+    -- growQueueSized (i + 1) propQ+    -- return i+  {-# SPECIALIZE INLINE update :: Solver -> Var -> IO () #-}+  update = increaseHeap+  {-# SPECIALIZE INLINE undo :: Solver -> Var -> IO () #-}+  undo s v = inHeap s v >>= (`unless` insertHeap s v)+  {-# SPECIALIZE INLINE select :: Solver -> IO Var #-}+  select s = do+    let+      asg = assigns s+      -- | returns the most active var (heap-based implementation)+      loop :: IO Var+      loop = do+        n <- numElementsInHeap s+        if n == 0+          then return 0+          else do+              v <- getHeapRoot s+              x <- getNth asg v+              if x == lBottom then return v else loop+    loop++-------------------------------------------------------------------------------- Activities++varActivityThreshold :: Double+varActivityThreshold = 1e100++claActivityThreshold :: Double+claActivityThreshold = 1e20++-- | __Fig. 14 (p.19)__ Bumping of clause activity+{-# INLINE varBumpActivity #-}+varBumpActivity :: Solver -> Var -> IO ()+varBumpActivity s@Solver{..} x = do+  !a <- (+) <$> getNthDouble x activities <*> getDouble varInc+  setNthDouble x activities a+  when (varActivityThreshold < a) $ varRescaleActivity s+  update s x                    -- update the position in heap++-- | __Fig. 14 (p.19)__+{-# INLINE varDecayActivity #-}+varDecayActivity :: Solver -> IO ()+varDecayActivity Solver{..} = modifyDouble varInc (/ variableDecayRate config)+-- varDecayActivity Solver{..} = modifyDouble varInc . (flip (/)) =<< getDouble varDecay++-- | __Fig. 14 (p.19)__+{-# INLINE varRescaleActivity #-}+varRescaleActivity :: Solver -> IO ()+varRescaleActivity Solver{..} = do+  forM_ [1 .. nVars] $ \i -> modifyNthDouble i activities (/ varActivityThreshold)+  modifyDouble varInc (/ varActivityThreshold)++-- | __Fig. 14 (p.19)__+{-# INLINE claBumpActivity #-}+claBumpActivity :: Solver -> Clause -> IO ()+claBumpActivity s Clause{..} = do+  dl <- decisionLevel s+  a <- (fromIntegral dl +) <$> getDouble activity+  setDouble activity a+  -- setBool protected True+  when (claActivityThreshold <= a) $ claRescaleActivity s++{-+-- | __Fig. 14 (p.19)__+{-# INLINE claDecayActivity #-}+claDecayActivity :: Solver -> IO ()+claDecayActivity Solver{..} = modifyDouble claInc (/ clauseDecayRate config)+-}++-- | __Fig. 14 (p.19)__+{-# INLINE claRescaleActivity #-}+claRescaleActivity :: Solver -> IO ()+claRescaleActivity Solver{..} = do+  vec <- getClauseVector learnts+  n <- numberOfClauses learnts+  let+    loopOnVector :: Int -> IO ()+    loopOnVector ((< n) -> False) = return ()+    loopOnVector i = do+      c <- getNthClause vec i+      modifyDouble (activity c) (/ claActivityThreshold)+      loopOnVector $ i + 1+  loopOnVector 0+  -- modifyDouble claInc (/ claActivityThreshold)++-- | __Fig. 14 (p.19)__+{-# INLINE claRescaleActivityAfterRestart #-}+claRescaleActivityAfterRestart :: Solver -> IO ()+claRescaleActivityAfterRestart Solver{..} = do+  vec <- getClauseVector learnts+  n <- numberOfClauses learnts+  let+    loopOnVector :: Int -> IO ()+    loopOnVector ((< n) -> False) = return ()+    loopOnVector i = do+      c <- getNthClause vec i+      d <- sizeOfClause c+      if d < 9+        then modifyDouble (activity c) sqrt+        else setDouble (activity c) 0+      setBool (protected c) False+      loopOnVector $ i + 1+  loopOnVector 0++-------------------------------------------------------------------------------- VarHeap++-- | 'VarHeap' is a heap tree built from two 'Vec'+-- This implementation is identical wtih that in Minisat-1.14+-- Note: the zero-th element of @heap@ is used for holding the number of elements+-- Note: VarHeap itself is not a @VarOrder@, because it requires a pointer to solver+data VarHeap = VarHeap+                {+                  heap :: Vec -- order to var+                , idxs :: Vec -- var to order (index)+                }++newVarHeap :: Int -> IO VarHeap+newVarHeap n = do+  v1 <- newVec (n + 1)+  v2 <- newVec (n + 1)+  let+    loop :: Int -> IO ()+    loop ((<= n) -> False) = setNth v1 0 n >> setNth v2 0 n+    loop i = setNth v1 i i >> setNth v2 i i >> loop (i + 1)+  loop 1+  return $ VarHeap v1 v2++{-# INLINE numElementsInHeap #-}+numElementsInHeap :: Solver -> IO Int+numElementsInHeap (order -> heap -> h) = getNth h 0++{-# INLINE inHeap #-}+inHeap :: Solver -> Var -> IO Bool+inHeap (order -> idxs -> at) n = (/= 0) <$> getNth at n++{-# INLINE increaseHeap #-}+increaseHeap :: Solver -> Int -> IO ()+increaseHeap s@(order -> idxs -> at) n = inHeap s n >>= (`when` (percolateUp s =<< getNth at n))++{-# INLINABLE percolateUp #-}+percolateUp :: Solver -> Int -> IO ()+percolateUp Solver{..} start = do+  let VarHeap to at = order+  v <- getNth to start+  ac <- getNthDouble v activities+  let+    loop :: Int -> IO ()+    loop i = do+      let iP = div i 2          -- parent+      if iP == 0+        then setNth to i v >> setNth at v i -- end+        else do+            v' <- getNth to iP+            acP <- getNthDouble v' activities+            if ac > acP+              then setNth to i v' >> setNth at v' i >> loop iP -- loop+              else setNth to i v >> setNth at v i              -- end+  loop start++{-# INLINABLE percolateDown #-}+percolateDown :: Solver -> Int -> IO ()+percolateDown Solver{..} start = do+  let (VarHeap to at) = order+  n <- getNth to 0+  v <- getNth to start+  ac <- getNthDouble v activities+  let+    loop :: Int -> IO ()+    loop i = do+      let iL = 2 * i            -- left+      if iL <= n+        then do+            let iR = iL + 1     -- right+            l <- getNth to iL+            r <- getNth to iR+            acL <- getNthDouble l activities+            acR <- getNthDouble r activities+            let (ci, child, ac') = if iR <= n && acL < acR then (iR, r, acR) else (iL, l, acL)+            if ac' > ac+              then setNth to i child >> setNth at child i >> loop ci+              else setNth to i v >> setNth at v i -- end+        else setNth to i v >> setNth at v i       -- end+  loop start++{-# INLINE insertHeap #-}+insertHeap :: Solver -> Var -> IO ()+insertHeap s@(order -> VarHeap to at) v = do+  n <- (1 +) <$> getNth to 0+  setNth at v n+  setNth to n v+  setNth to 0 n+  percolateUp s n++-- | renamed from 'getmin'+{-# INLINE getHeapRoot #-}+getHeapRoot :: Solver -> IO Int+getHeapRoot s@(order -> VarHeap to at) = do+  r <- getNth to 1+  l <- getNth to =<< getNth to 0 -- the last element's value+  setNth to 1 l+  setNth at l 1+  setNth at r 0+  modifyNth to (subtract 1) 0 -- pop+  n <- getNth to 0+  when (1 < n) $ percolateDown s 1+  return r
+ SAT/Mios/Types.hs view
@@ -0,0 +1,269 @@+{-# LANGUAGE+    BangPatterns+  , FlexibleContexts+  , FlexibleInstances+  , FunctionalDependencies+  , MultiParamTypeClasses+  #-}+{-# LANGUAGE Trustworthy #-}++-- | Basic data types used throughout mios.+module SAT.Mios.Types+       (+         -- Singleton+         module SAT.Mios.Data.Singleton+         -- Fixed Unboxed Mutable Int Vector+       , module SAT.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.Mios.Data.Singleton+import SAT.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)
+ SAT/Mios/Util/BoolExp.hs view
@@ -0,0 +1,244 @@+{-# LANGUAGE BangPatterns, FlexibleInstances, ViewPatterns, UndecidableInstances #-}+{-# LANGUAGE Safe #-}++-- | Boolean Expression module to build CNF from arbitrary expressions+-- Tseitin translation: http://en.wikipedia.org/wiki/Tseitin_transformation+module SAT.Mios.Util.BoolExp+       (+         -- * Class & Type+         BoolComponent (..)+       , BoolForm (..)+         -- * Expression contructors+       , (-|-)+       , (-&-)+       , (-=-)+       , (-!-)+       , (->-)+       , neg+         -- * List Operation+       , disjunctionOf+       , (-|||-)+       , conjunctionOf+       , (-&&&-)+         -- * Convert function+       , asList+       , asList_+       , asLatex+       , asLatex_+       , numberOfVariables+       , numberOfClauses+       , tseitinBase+       )+       where++import Data.List (foldl', intercalate)++-- | the start index for the generated variables by Tseitin encoding+tseitinBase :: Int+tseitinBase = 1600000++data L = L Int++-- | class of objects that can be interpeted as a bool expression+class BoolComponent a where+  toBF :: a -> BoolForm   -- lift to BoolForm++-- | CNF expression+data BoolForm = Cnf (Int, Int) [[Int]]+    deriving (Eq, Show)++instance BoolComponent Int where+  toBF a = Cnf (abs a, max tseitinBase (abs a)) [[a]]++instance BoolComponent L where+  toBF (L a) = Cnf (abs a, max tseitinBase (abs a)) [[a]]++instance BoolComponent [Char] where+  toBF (read -> a) = Cnf (abs a, max tseitinBase (abs a)) [[a]]++instance BoolComponent BoolForm where+  toBF = id++-- | returns the number of variables in the 'BoolForm'+numberOfVariables :: BoolForm -> Int+numberOfVariables (Cnf (a, b) _) = a + b - tseitinBase++-- | returns the number of clauses in the 'BoolForm'+numberOfClauses :: BoolForm -> Int+numberOfClauses (Cnf _ l) = length l++boolFormTrue = Cnf (-1, 1) []+boolFormFalse = Cnf (-1, -1) []++instance BoolComponent Bool where+  toBF True = boolFormTrue+  toBF False = boolFormFalse++isTrue :: BoolForm -> Bool+isTrue = (== boolFormTrue)++isFalse :: BoolForm -> Bool+isFalse = (== boolFormFalse)++-- | return a 'clause' list only if it contains some real clause (not a literal)+clausesOf :: BoolForm -> [[Int]]+clausesOf cnf@(Cnf _ [[]]) = []+clausesOf cnf@(Cnf _ [[x]]) = []+clausesOf cnf@(Cnf _ l) = l++maxRank :: BoolForm -> Int+maxRank (Cnf (n, _) _) = n++-- | returns the number of valiable used as the output of this expression.+-- and returns itself it the expression is a literal.+-- Otherwise the number is a integer larger than 'tseitinBase'.+-- Therefore @1 + max tseitinBase the-returned-value@ is the next literal variable for future.+tseitinNumber :: BoolForm -> Int+tseitinNumber (Cnf (m, n) [[x]]) = x+tseitinNumber (Cnf (_, n) _) = n++renumber :: Int -> BoolForm -> (BoolForm, Int)+renumber base (Cnf (m, n) l)+  | l == [] = (Cnf (m, n) l, 0)+  | tseitinBase < base = (Cnf (m, n') l', n')+  | otherwise = (Cnf (n', tseitinBase) l', n')+  where+    l' = map (map f) l+    n' = maximum $ map maximum l'+    offset = base - tseitinBase - 1+    f x = if abs x < tseitinBase then x else signum x * (abs x + offset)++instance Ord BoolForm where+  compare (Cnf _ a) (Cnf _ b) = compare a b++-- | disjunction constructor+--+-- >>> asList $ "3" -|- "4"+-- [[3,4,-5],[-3,5],[-4,5]]+--+-- >>> asList (("3" -|- "4") -|- "-1")+-- [[3,4,-5],[-3,5],[-4,5],[5,-1,-6],[-5,6],[1,6]]+--+(-|-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm+(toBF -> e1) -|- (toBF -> e2')+  | isTrue e1 || isTrue e2' = boolFormTrue+  | isFalse e1 && isFalse e2' = boolFormFalse+  | isFalse e1 = e2'+  | isFalse e2' = e1+  | otherwise = Cnf (m, c) $ clausesOf e1 ++ clausesOf e2 ++ [[a, b, - c], [- a, c], [- b, c]]+  where+    a = tseitinNumber e1+    (e2, b) = renumber (1 + max tseitinBase a) e2'+    m = max (maxRank e1) (maxRank e2)+    c = 1 + max tseitinBase (max a b)++-- | conjunction constructor+--+-- >>> asList $ "3" -&- "-2"+-- [[-3,2,4],[3,-4],[-2,-4]]+--+-- >>> asList $ "3" -|- ("1" -&- "2")+-- [[-1,-2,4],[1,-4],[2,-4],[3,4,-5],[-3,5],[-4,5]]+--+(-&-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm+(toBF -> e1) -&- (toBF -> e2')+  | isTrue e1 && isTrue e2' = boolFormTrue+  | isFalse e1 || isFalse e2' = boolFormFalse+  | isTrue e1 = e2'+  | isTrue e2' = e1+  | otherwise = Cnf (m, c) $ clausesOf e1 ++ clausesOf e2 ++ [[- a, - b, c], [a, - c], [b, - c]]+  where+    a = tseitinNumber e1+    (e2, b) = renumber (1 + max tseitinBase a) e2'+    m = max (maxRank e1) (maxRank e2)+    c = 1 + max tseitinBase (max a b)++-- | negate a form+--+-- >>> asList $ neg ("1" -|- "2")+-- [[1,2,-3],[-1,3],[-2,3],[-3,-4],[3,4]]+neg :: (BoolComponent a) => a -> BoolForm+neg (toBF -> e) =+  Cnf (m, c) $ clausesOf e ++ [[- a, - c], [a, c]]+  where+    a = tseitinNumber e+    m = maxRank e+    c = 1 + max tseitinBase a++-- | equal on BoolForm+(-=-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm+(toBF -> e1) -=- (toBF -> e2) = (e1 -&- e2) -|- (neg e1 -&- neg e2)++-- | negation on BoolForm+(-!-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm+(toBF -> e1) -!- (toBF -> e2) = (neg e1 -&- e2) -|- (e1 -&- neg e2)++-- | implication as a short cut+--+-- >>> asList ("1" ->- "2")+-- [[-1,-3],[1,3],[3,2,-4],[-3,4],[-2,4]]+(->-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm+(toBF -> a) ->- (toBF -> b) = (neg a) -|- b++-- | merge [BoolForm] by '(-|-)'+disjunctionOf :: [BoolForm] -> BoolForm+disjunctionOf [] = boolFormFalse+disjunctionOf (x:l) = foldl' (-|-) x l++-- | an alias of 'disjunctionOf'+(-|||-) = disjunctionOf++-- | merge [BoolForm] by '(-&-)'+conjunctionOf :: [BoolForm] -> BoolForm+conjunctionOf [] = boolFormTrue+conjunctionOf (x:l) = foldl' (-&-) x l++-- | an alias of 'conjunctionOf'+(-&&&-) = conjunctionOf++-- | converts a BoolForm to "[[Int]]"+asList_ :: BoolForm -> [[Int]]+asList_ cnf@(Cnf (m,_) _)+  | isTrue cnf = []+  | isFalse cnf = [[]]+  | otherwise = l'+  where+    (Cnf _ l', _) = renumber (m + 1) cnf++-- | converts a *satisfied* BoolForm to "[[Int]]"+asList :: BoolForm -> [[Int]]+asList cnf@(Cnf (m,n) l)+  | isTrue cnf = []+  | isFalse cnf = [[]]+  | n <= tseitinBase = l+  | otherwise = [m'] : l'+  where+    (Cnf (m', _) l', _) = renumber (m + 1) cnf++-- | make latex string from CNF, using 'asList_'+--+-- >>> asLatex $ "3" -|- "4"+-- "\\begin{displaymath}\n( x_{3} \\vee x_{4} )\n\\end{displaymath}\n"+--+asLatex_ :: BoolForm -> String+asLatex_ b = beg ++ s ++ end+  where+    beg = "\\begin{displaymath}\n"+    end = "\n\\end{displaymath}\n"+    s = intercalate " \\wedge " [ makeClause c | c <- asList_ b]+    makeClause c = "(" ++ intercalate "\\vee" [makeLiteral l | l <- c] ++ ")"+    makeLiteral l+      | 0 < l = " x_{" ++ show l ++ "} "+      | otherwise = " \\neg " ++ "x_{" ++ show (negate l) ++ "} "++-- | make latex string from CNF, using 'asList'+asLatex :: BoolForm -> String+asLatex b = beg ++ s ++ end+  where+    beg = "\\begin{displaymath}\n"+    end = "\n\\end{displaymath}\n"+    s = intercalate " \\wedge " [ makeClause c | c <- asList b]+    makeClause c = "(" ++ intercalate "\\vee" [makeLiteral l | l <- c] ++ ")"+    makeLiteral l+      | 0 < l = " x_{" ++ show l ++ "} "+      | otherwise = " \\neg " ++ "x_{" ++ show (negate l) ++ "} "
+ SAT/Mios/Util/CNFIO.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE Safe #-}++-- | Read/Write a CNF file only with ghc standard libraries+module SAT.Mios.Util.CNFIO+       (+         -- * Input+         fromFile+       , clauseListFromFile+       , fromMinisatOutput+       , clauseListFromMinisatOutput+         -- * Output+       , toFile+       , toCNFString+       , asCNFString+       , asCNFString_+         -- * Bool Operation+       , module SAT.Mios.Util.BoolExp+       )+       where+import SAT.Mios.Util.CNFIO.Reader+import SAT.Mios.Util.CNFIO.Writer+import SAT.Mios.Util.CNFIO.MinisatReader+import SAT.Mios.Util.BoolExp++-- | String from BoolFrom+asCNFString :: BoolForm -> String+asCNFString = toCNFString . asList++-- | String from BoolFrom+asCNFString_ :: BoolForm -> String+asCNFString_ = toCNFString . asList_
+ SAT/Mios/Util/CNFIO/MinisatReader.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE Safe #-}++-- | Read an output file of minisat+module SAT.Mios.Util.CNFIO.MinisatReader+       (+         -- * Interface+         fromMinisatOutput+       , clauseListFromMinisatOutput+       )+       where+-- import Control.Applicative ((<$>), (<*>), (<*), (*>))+import Data.Char+import Text.ParserCombinators.ReadP++-- parser+-- |parse a non-signed integer+{-# INLINE pint #-}+pint = do+  n <- munch isDigit+  return (read n :: Int)++{-# INLINE mint #-}+mint = do+  char '-'+  n <- munch isDigit+  return (- (read n::Int))++-- |parse a (signed) integer+{-# INLINE int #-}+int = mint <++ pint++-- |return integer list that terminates at zero+{-# INLINE seqNums #-}+seqNums = do+  skipSpaces+  x <- int+  skipSpaces+  if (x == 0) then return []  else (x :) <$> seqNums++-- |top level interface for parsing CNF+{-# INLINE parseMinisatOutput #-}+parseMinisatOutput :: ReadP ((Int, Int), [Int])+parseMinisatOutput = do+  string "SAT"+  skipSpaces+  l <- seqNums+  return ((length l,0), l)++-- |read a minisat output:+-- ((numbefOfVariables, 0), [Literal])+--+-- >>>  fromFile "result"+-- ((3, 0), [1, -2, 3])+--+{-# INLINE fromMinisatOutput #-}+fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))+fromMinisatOutput f = do+  c <- readFile f+  case readP_to_S parseMinisatOutput c of+    [(a, _)] -> return $ Just a+    _ -> return Nothing++-- | return clauses as [[Int]] from 'file'+--+-- >>> clauseListFromMinisatOutput "result"+-- [1,-2,3]+--+clauseListFromMinisatOutput :: FilePath -> IO [Int]+clauseListFromMinisatOutput l = do+  res <- fromMinisatOutput l+  case res of+    Just p -> return (snd p)+    _ -> return []
+ SAT/Mios/Util/CNFIO/Reader.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE Safe #-}++-- | Read a CNF file without haskell-platform+module SAT.Mios.Util.CNFIO.Reader+       (+         -- * Interface+         fromFile+       , clauseListFromFile+       )+       where+import Control.Applicative ((<$>), (<*>), (<*), (*>))+import Data.Char+import Text.ParserCombinators.ReadP++-- parser+{-# INLINE newline #-}+newline = char '\n'++{-# INLINE digit #-}+digit = satisfy isDigit++{-# INLINE spaces #-}+spaces = munch (`elem` " \t")++{-# INLINE noneOf #-}+noneOf s = satisfy (`notElem` s)++-- |parse a non-signed integer+{-# INLINE pint #-}+pint = do+  n <- munch isDigit+  return (read n :: Int)++{-# INLINE mint #-}+mint = do+  char '-'+  n <- munch isDigit+  return (- (read n::Int))++-- |parse a (signed) integer+{-# INLINE int #-}+int = mint <++ pint++-- |Parse something like: p FORMAT VARIABLES CLAUSES+{-# INLINE problemLine #-}+problemLine = do+  char 'p'+  skipSpaces+  (string "cnf" <++ string "CNF")+  skipSpaces+  vars <- pint+  skipSpaces+  clas <- pint+  spaces+  newline+  return (vars, clas)++-- |Parse something like: c This in an example of a comment line.+{-# INLINE commentLines #-}+commentLines = do+  l <- look+  if (head l)  == 'c'+    then do+      munch ('\n' /=)+      newline+      commentLines+    else return ()++_commentLines = do+  char 'c'+  munch ('\n' /=)+  newline+  l <- look+  if (head l)  == 'c' then commentLines else return ()++-- |Parse the preamble part+{-# INLINE preambleCNF #-}+preambleCNF = do+  commentLines+  problemLine++-- |return integer list that terminates at zero+{-# INLINE seqNums #-}+seqNums = do+  skipSpaces+  x <- int+  skipSpaces+  if (x == 0) then return []  else (x :) <$> seqNums++-- |Parse something like: 1 -2 0 4 0 -3 0+{-# INLINE parseClauses #-}+parseClauses :: Int -> ReadP [[Int]]+parseClauses n = count n seqNums++-- |top level interface for parsing CNF+{-# INLINE parseCNF #-}+parseCNF :: ReadP ((Int, Int), [[Int]])+parseCNF = do+  a <- preambleCNF+  b <- parseClauses (snd a)+  return (a, b)++-- |driver:: String -> Either ParseError Int+driver input = readP_to_S (parseClauses 1) input++-- |read a CNF file and return:+-- ((numbefOfVariables, numberOfClauses), [Literal])+--+-- >>> fromFile "acnf"+-- ((3, 4), [[1, 2], [-2, 3], [-1, 2, -3], [3]]+--+{-# INLINE fromFile #-}+fromFile :: FilePath -> IO (Maybe ((Int, Int), [[Int]]))+fromFile f = do+  c <- readFile f+  case readP_to_S parseCNF c of+    [(a, _)] -> return $ Just a+    _ -> return Nothing++-- | return clauses as [[Int]] from 'file'+--+-- >>> clauseListFromFile "a.cnf"+-- [[1, 2], [-2, 3], [-1, 2, -3], [3]]+--+clauseListFromFile :: FilePath -> IO [[Int]]+clauseListFromFile l = do+  res <- fromFile l+  case res of+    Just (_, l) -> return l+    _ -> return []
+ SAT/Mios/Util/CNFIO/Writer.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE Safe #-}++-- | Write SAT data to CNF file+module SAT.Mios.Util.CNFIO.Writer+       (+         -- * Interface+         toFile+       , toCNFString+       , toString+       , toLatexString+       )+       where+import Data.List (intercalate, nub, sort)+import System.IO++-- | Write the CNF to file 'f', using 'toCNFString'+toFile :: FilePath -> [[Int]] -> IO ()+toFile f l = writeFile f $ toCNFString l++-- | Convert [Clause] to String, where Clause is [Int]+--+-- >>> toCNFString []+-- "p cnf 0 0\n"+--+-- >>> toCNFString [[-1, 2], [-3, -4]]+-- "p cnf 4 2\n-1 2 0\n-3 -4 0\n"+--+-- >>> toCNFString [[1], [-2], [-3, -4], [1,2,3,4]]+-- "p cnf 4 4\n1 0\n-2 0\n-3 -4 0\n1 2 3 4 0\n"+--+toCNFString :: [[Int]] -> String+toCNFString l = hdr ++ str+  where+    hdr = "p cnf " ++ show numV ++ " " ++ show numC ++ "\n"+    numC = length l+    numV = last $ nub $ sort $ map abs $ concat l+    str = concat [intercalate " " (map show c) ++ " 0\n" | c <- l]++-- | converts @[[Int]]@ to a String+toString  :: [[Int]] -> String -> String -> String+toString l and' or' = intercalate a ["(" ++ intercalate o [ lit x | x <- c] ++ ")" | c <- l]+  where+    lit x+      | 0 <= x = "X" ++ show x+      | otherwise = "-X" ++ show (abs x)+    a = pad and'+    o = pad or'+    pad s = " " ++ s ++ " "++-- | converts @[[Int]]@ to a LaTeX expression+toLatexString  :: [[Int]] -> String+toLatexString l = "\\begin{eqnarray*}\n" ++ intercalate a ["(" ++ intercalate o [ lit x | x <- c] ++ ")" | c <- l] ++ "\n\\end{eqnarray*}"+  where+    lit x+      | 0 <= x = "X_{" ++ show x ++ "}"+      | otherwise = "\\overline{X_{" ++ show (abs x) ++ "}}"+    a = " \n\\wedge "+    o = " \\vee "
+ SAT/Mios/Validator.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE+    ViewPatterns+  #-}+{-# LANGUAGE Safe #-}++-- | validate an assignment+module SAT.Mios.Validator+       (+         validate+       )+       where++import Data.Foldable (toList)+import SAT.Mios.Types+import SAT.Mios.Clause+import SAT.Mios.ClauseManager+import SAT.Mios.Solver++-- | validates the assignment even if the implementation of 'Solver' is wrong; we re-implement some functions here.+validate :: Traversable t => Solver -> t Int -> IO Bool+validate s (toList -> map int2lit -> lst) = do+  assignment <- newVec $ 1 + nVars s+  vec <- getClauseVector (clauses s)+  nc <- numberOfClauses (clauses s)+  let+    inject :: Lit -> IO ()+    inject l = setNth assignment (lit2var l) $ if positiveLit l then lTrue else lFalse+    -- returns True if the literal is satisfied under the assignment+    satisfied :: Lit -> IO Bool+    satisfied l+      | positiveLit l = (lTrue ==) <$> getNth assignment (lit2var l)+      | otherwise     = (lFalse ==) <$> getNth assignment (lit2var l)+    -- returns True is any literal in the given list+    satAny :: [Lit] -> IO Bool+    satAny [] = return False+    satAny (l:ls) = do+      sat' <- satisfied l+      if sat' then return True else satAny ls+    -- traverses all clauses in 'clauses'+    loopOnVector :: Int -> IO Bool+    loopOnVector ((< nc) -> False) = return True+    loopOnVector i = do+      c <- getNthClause vec i+      sat' <- satAny =<< asList c+      if sat' then loopOnVector (i + 1) else return False+  if null lst+    then error "validator got an empty assignment."+    else mapM_ inject lst >> loopOnVector 0
− SAT/Solver/Mios.hs
@@ -1,298 +0,0 @@--- | Minisat-based Implementation and Optimization Study on SAT solver-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios-       (-         -- * Interface to the core of solver-         versionId-       , CNFDescription (..)-       , module SAT.Solver.Mios.OptionParser-       , runSolver-       , solveSAT-       , solveSATWithConfiguration-       , solve-       , getModel-         -- * Assignment Validator-       , validateAssignment-       , validate-         -- * For standalone programs-       , executeSolverOn-       , executeSolver-       , executeValidatorOn-       , executeValidator-         -- * File IO-       , dumpAssigmentAsCNF-       )-       where--import Control.Monad ((<=<), unless, void, when)-import Data.Char-import qualified Data.ByteString.Char8 as B-import Data.List-import qualified Data.Vector.Unboxed as U-import Numeric (showFFloat)-import System.CPUTime-import System.Exit-import System.IO--import SAT.Solver.Mios.Types-import SAT.Solver.Mios.Internal-import SAT.Solver.Mios.Solver-import SAT.Solver.Mios.M114-import SAT.Solver.Mios.OptionParser-import SAT.Solver.Mios.Validator--reportElapsedTime :: Bool -> String -> Integer -> IO Integer-reportElapsedTime False _ _ = return 0-reportElapsedTime _ _ 0 = getCPUTime-reportElapsedTime _ mes t = do-  now <- getCPUTime-  let toSecond = 1000000000000 :: Double-  hPutStr stderr mes-  hPutStrLn stderr $ showFFloat (Just 3) ((fromIntegral (now - t)) / toSecond) " sec"-  return now---- | executes a solver on the given CNF file--- This is the simplest entry to standalone programs; not for Haskell programs-executeSolverOn :: FilePath -> IO ()-executeSolverOn path = executeSolver (miosDefaultOption { _targetFile = Just path })---- | executes a solver on the given 'arg :: MiosConfiguration'--- | This is another entry point for standalone programs.-executeSolver :: MiosProgramOption -> IO ()-executeSolver opts@(_targetFile -> target@(Just cnfFile)) = do-  t0 <- reportElapsedTime (_confTimeProbe opts) "" 0-  (desc, cls) <- parseHeader target <$> B.readFile cnfFile-  when (_numberOfVariables desc == 0) $ error $ "couldn't load " ++ show cnfFile-  s <- newSolver (toMiosConf opts) desc-  parseClauses s desc cls-  t1 <- reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Parse: ") t0-  when (_confVerbose opts) $ do-    nc <- nClauses s-    hPutStrLn stderr $ cnfFile ++ " was loaded: #v = " ++ show (nVars s, _numberOfVariables desc) ++ " #c = " ++ show (nc, _numberOfClauses desc)-  res <- simplifyDB s-  -- when (_confVerbose opts) $ hPutStrLn stderr $ "`simplifyDB`: " ++ show res-  result <- solve s []-  case result of-    True  | _confNoAnswer opts -> when (_confVerbose opts) $ hPutStrLn stderr "SATISFIABLE"-    False | _confNoAnswer opts -> when (_confVerbose opts) $ hPutStrLn stderr "UNSATISFIABLE"-    True  -> print =<< getModel s-    False -> do          -- contradiction-      -- FIXMEin future-      when (_confVerbose opts) $ hPutStrLn stderr "UNSAT"-      -- print =<< map lit2int <$> asList (conflict s)-      putStrLn "[]"-  case _outputFile opts of-    Just fname -> dumpAssigmentAsCNF fname result =<< getModel s-    Nothing -> return ()-  t2 <- reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Solve: ") t1-  when (result && _confCheckAnswer opts) $ do-    asg <- getModel s-    s' <- newSolver (toMiosConf opts) desc-    parseClauses s' desc cls-    good <- validate s' asg-    if _confVerbose opts-      then hPutStrLn stderr $ if good then "A vaild answer" else "Internal error: mios returns a wrong answer"-      else unless good $ hPutStrLn stderr "Internal error: mios returns a wrong answer"-    void $ reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Validate: ") t2-  void $ reportElapsedTime (_confTimeProbe opts) ("## [" ++ showPath cnfFile ++ "] Total: ") t0-  when (_confStatProbe opts) $ do-    hPutStr stderr $ "## [" ++ showPath cnfFile ++ "] "-    hPutStrLn stderr . intercalate ", " . map (\(k, v) -> show k ++ ": " ++ show v) =<< getStats s--executeSolver _ = return ()---- | new top-level interface that returns------ * conflicting literal set :: Left [Int]--- * satisfiable assignment :: Right [Int]----runSolver :: Traversable t => MiosConfiguration -> CNFDescription -> t [Int] -> IO (Either [Int] [Int])-runSolver m d c = do-  s <- newSolver m d-  mapM_ ((s `addClause`) <=< (newSizedVecIntFromList . map int2lit)) c-  noConf <- simplifyDB s-  if noConf-    then do-        x <- solve s []-        if x-            then Right <$> getModel s-            else Left .  map lit2int <$> asList (conflict s)-    else return $ Left []----- | the easiest interface for Haskell programs--- This returns the result @::[[Int]]@ for a given @(CNFDescription, [[Int]])@--- The first argument @target@ can be build by @Just target <- cnfFromFile targetfile@.--- The second part of the first argument is a list of vector, which 0th element is the number of its real elements-solveSAT :: Traversable m => CNFDescription -> m [Int] -> IO [Int]-solveSAT = solveSATWithConfiguration defaultConfiguration---- | solves the problem (2rd arg) under the configuration (1st arg)--- and returns an assignment as list of literals :: Int-solveSATWithConfiguration :: Traversable m => MiosConfiguration -> CNFDescription -> m [Int] -> IO [Int]-solveSATWithConfiguration conf desc cls = do-  s <- newSolver conf desc-  -- mapM_ (const (newVar s)) [0 .. _numberOfVariables desc - 1]-  mapM_ ((s `addClause`) <=< (newSizedVecIntFromList . map int2lit)) cls-  noConf <- simplifyDB s-  if noConf-    then do-        result <- solve s []-        if result-            then getModel s-            else return []-    else return []---- | validates a given assignment from STDIN for the CNF file (2nd arg)--- this is the entry point for standalone programs-executeValidatorOn :: FilePath -> IO ()-executeValidatorOn path = executeValidator (miosDefaultOption { _targetFile = Just path })---- | validates a given assignment for the problem (2nd arg)--- this is another entry point for standalone programs; see app/mios.hs-executeValidator :: MiosProgramOption -> IO ()-executeValidator opts@(_targetFile -> target@(Just cnfFile)) = do-  (desc, cls) <- parseHeader target <$> B.readFile cnfFile-  when (_numberOfVariables desc == 0) . error $ "couldn't load " ++ show cnfFile-  s <- newSolver (toMiosConf opts) desc-  parseClauses s desc cls-  when (_confVerbose opts) $-    hPutStrLn stderr $ cnfFile ++ " was loaded: #v = " ++ show (_numberOfVariables desc) ++ " #c = " ++ show (_numberOfClauses desc)-  when (_confVerbose opts) $ do-    nc <- nClauses s-    nl <- nLearnts s-    hPutStrLn stderr $ "(nv, nc, nl) = " ++ show (nVars s, nc, nl)-  asg <- read <$> getContents-  unless (_confNoAnswer opts) $ print asg-  result <- s `validate` (asg :: [Int])-  if result-    then putStrLn ("It's a valid assignment for " ++ cnfFile ++ ".") >> exitSuccess-    else putStrLn ("It's an invalid assignment for " ++ cnfFile ++ ".") >> exitFailure--executeValidator _  = return ()---- | returns True if a given assignment (2nd arg) satisfies the problem (1st arg)--- if you want to check the @answer@ which a @slover@ returned, run @solver `validate` answer@,--- where 'validate' @ :: Traversable t => Solver -> t Lit -> IO Bool@-validateAssignment :: (Traversable m, Traversable n) => CNFDescription -> m [Int] -> n Int -> IO Bool-validateAssignment desc cls asg = do-  s <- newSolver defaultConfiguration desc-  mapM_ ((s `addClause`) <=< (newSizedVecIntFromList . map int2lit)) cls-  s `validate` asg---- | dumps an assigment to file.--- 2nd arg is------ * @True@ if the assigment is satisfiable assigment------ * @False@ if not------ >>> do y <- solve s ... ; dumpAssigmentAsCNF "result.cnf" y <$> model s----dumpAssigmentAsCNF :: FilePath -> Bool -> [Int] -> IO ()-dumpAssigmentAsCNF fname False _ = do-  withFile fname WriteMode $ \h -> do-    hPutStrLn h "UNSAT"--dumpAssigmentAsCNF fname True l = do-  withFile fname WriteMode $ \h -> do-    hPutStrLn h "SAT"-    hPutStrLn h . unwords $ map show l------------------------------------------------------------------------------------- DIMACS CNF Reader-----------------------------------------------------------------------------------parseHeader :: Maybe FilePath -> B.ByteString -> (CNFDescription, B.ByteString)-parseHeader target bs = if B.head bs == 'p' then (parseP l, B.tail bs') else parseHeader target (B.tail bs')-  where-    (l, bs') = B.span ('\n' /=) bs-    -- format: p cnf n m, length "p cnf" == 5-    parseP line = case B.readInt $ B.dropWhile (`elem` " \t") (B.drop 5 line) of-      Just (x, second) -> case B.readInt (B.dropWhile (`elem` " \t") second) of-        Just (y, _) -> CNFDescription x y target-        _ -> CNFDescription 0 0 target-      _ -> CNFDescription 0 0 target--parseClauses :: Solver -> CNFDescription -> B.ByteString -> IO ()-parseClauses s (CNFDescription nv nc _) bs = do-  let maxLit = int2lit $ negate nv-  buffer <- newVec $ maxLit + 1-  polvec <- newVecBool (maxLit + 1) False-  let-    loop :: Int -> B.ByteString -> IO ()-    loop ((< nc) -> False) _ = return ()-    loop i b = loop (i + 1) =<< readClause s buffer polvec b-  loop 0 bs-  -- static polarity-  let-    asg = assigns s-    checkPolarity :: Int -> IO ()-    checkPolarity ((< nv) -> False) = return ()-    checkPolarity v = do-      p <- getNthBool polvec $ var2lit v True-      n <- getNthBool polvec $ var2lit v False-      when (p == False || n == False) $ setNth asg v $ if p then lTrue else lFalse-      checkPolarity $ v + 1-  checkPolarity 1--skipWhitespace :: B.ByteString -> B.ByteString-skipWhitespace s-  | elem c " \t\n" = skipWhitespace $ B.tail s-  | otherwise = s-    where-      c = B.head s---- | skip comment lines--- __Pre-condition:__ we are on the benngining of a line-skipComments :: B.ByteString -> B.ByteString-skipComments s-  | c == 'c' = skipComments . B.tail . B.dropWhile (/= '\n') $ s-  | otherwise = s-  where-    c = B.head s--parseInt :: B.ByteString -> (Int, B.ByteString)-parseInt st = do-  let-    zero = ord '0'-    loop :: B.ByteString -> Int -> (Int, B.ByteString)-    loop s val = case B.head s of-      c | '0' <= c && c <= '9'  -> loop (B.tail s) (val * 10 + ord c - zero)-      _ -> (val, B.tail s)-  case B.head st of-    '-' -> let (k, x) = loop (B.tail st) 0 in (negate k, x)-    '+' -> loop st (0 :: Int)-    c | '0' <= c && c <= '9'  -> loop st 0-    _ -> error "PARSE ERROR! Unexpected char"--readClause :: Solver -> Vec -> VecBool -> B.ByteString -> IO B.ByteString-readClause s buffer pvec stream = do-  let-    loop :: Int -> B.ByteString -> IO B.ByteString-    loop i b = do-      let (k, b') = parseInt $ skipWhitespace b-      if k == 0-        then do-            -- putStrLn . ("clause: " ++) . show . map lit2int =<< asList stack-            setNth buffer 0 $ i - 1-            addClause s buffer-            return b'-        else do-            let l = int2lit k-            setNth buffer i l-            setNthBool pvec l True-            loop (i + 1) b'-  loop 1 . skipComments . skipWhitespace $ stream---showPath :: FilePath -> String-showPath str-  | elem '/' str =  take (len - length basename) (repeat ' ') ++ basename-  |  otherwise = take (len - length basename') (repeat ' ') ++ basename'-  where-    len = 50-    basename = reverse . takeWhile (/= '/') . reverse $ str-    basename' = take len str
− SAT/Solver/Mios/Clause.hs
@@ -1,144 +0,0 @@--- | Clause, a data supporting pointer-based equality-{-# LANGUAGE-    BangPatterns-  , FlexibleInstances-  , MagicHash-  , MultiParamTypeClasses-  , RecordWildCards-  , ViewPatterns-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.Clause-       (-         Clause (..)---       , isLit---       , getLit-       , shrinkClause-       , newClauseFromVec-       , sizeOfClause-         -- * Vector of Clause-       , ClauseVector-       , newClauseVector-       , getNthClause-       , setNthClause-       , swapClauses-       )-       where--import Control.Monad (forM_)-import GHC.Prim (tagToEnum#, reallyUnsafePtrEquality#)-import qualified Data.Vector as V-import qualified Data.Vector.Mutable as MV-import qualified Data.Vector.Unboxed.Mutable as UV-import Data.List (intercalate)-import SAT.Solver.Mios.Types---- | __Fig. 7.(p.11)__--- clause, null, binary clause.--- This matches both of @Clause@ and @GClause@ in MiniSat--- TODO: GADTs is better?-data Clause = Clause-              {-                learnt     :: !Bool            -- ^ whether this is a learnt clause-              , activity   :: !DoubleSingleton -- ^ activity of this clause-              , protected  :: !BoolSingleton   -- ^ protected from reduce-              , lbd        :: !IntSingleton    -- ^ storing the LBD; values are computed in Solver-              , lits       :: !Vec             -- ^ which this clause consists of-              }---  | BinaryClause Lit                        -- binary clause consists of only a propagating literal-  | NullClause                              -- as null pointer---- | The equality on 'Clause' is defined with 'reallyUnsafePtrEquality'.-instance Eq Clause where-  {-# SPECIALIZE INLINE (==) :: Clause -> Clause -> Bool #-}-  (==) x y = x `seq` y `seq` tagToEnum# (reallyUnsafePtrEquality# x y)--instance Show Clause where-  show NullClause = "NullClause"-  show _ = "a clause"---- | supports a restricted set of 'VectorFamily' methods-instance VectorFamily Clause Lit where-  dump mes NullClause = return $ mes ++ "Null"-  dump mes Clause{..} = do-    a <- show <$> getDouble activity-    (len:ls) <- asList lits-    return $ mes ++ "C" ++ show len ++ "{" ++ intercalate "," [show learnt, a, show . map lit2int . take len $ ls] ++ "}"-  {-# SPECIALIZE INLINE asVec :: Clause -> Vec #-}-  asVec Clause{..} = UV.unsafeTail lits-  {-# SPECIALIZE INLINE asList :: Clause -> IO [Int] #-}-  asList NullClause = return []-  asList Clause{..} = do-    (n : ls)  <- asList lits-    return $ take n ls---- returns True if it is a 'BinaryClause'--- FIXME: this might be discarded in minisat 2.2--- isLit :: Clause -> Bool--- isLit (BinaryClause _) = True--- isLit _ = False---- returns the literal in a BinaryClause--- FIXME: this might be discarded in minisat 2.2--- getLit :: Clause -> Lit--- getLit (BinaryClause x) = x---- coverts a binary clause to normal clause in order to reuse map-on-literals-in-a-clause codes--- liftToClause :: Clause -> Clause--- liftToClause (BinaryClause _) = error "So far I use generic function approach instead of lifting"---- | drop the last /N/ literals in a 'Clause' to eliminate unsatisfied literals-{-# INLINABLE shrinkClause #-}-shrinkClause :: Int -> Clause -> IO ()-shrinkClause !n Clause{..} = setNth lits 0 . subtract n =<< getNth lits 0---- | copies /vec/ and return a new 'Clause'--- Since 1.0.100 DIMACS reader should use a scratch buffer allocated statically.-{-# INLINE newClauseFromVec #-}-newClauseFromVec :: Bool -> Vec -> IO Clause-newClauseFromVec l vec = do-  n <- getNth vec 0-  v <- newVec $ n + 1-  forM_ [0 .. n] $ \i -> setNth v i =<< getNth vec i-  Clause l <$> newDouble 0 <*> newBool False <*> newInt n <*> return v---- | returns the number of literals in a clause, even if the given clause is a binary clause-{-# INLINE sizeOfClause #-}-sizeOfClause :: Clause -> IO Int--- sizeOfClause (BinaryClause _) = return 1-sizeOfClause !c = getNth (lits c) 0-------------------------------------------------------------------------------------- | Mutable 'Clause' Vector-type ClauseVector = MV.IOVector Clause--instance VectorFamily ClauseVector Clause where-  asList cv = V.toList <$> V.freeze cv-  dump mes cv = do-    l <- asList cv-    sts <- mapM (dump ",") (l :: [Clause])-    return $ mes ++ tail (concat sts)---- | returns a new 'ClauseVector'-newClauseVector  :: Int -> IO ClauseVector-newClauseVector n = do-  v <- MV.new (max 4 n)-  MV.set v NullClause-  return v---- | returns the nth 'Clause'-{-# INLINE getNthClause #-}-getNthClause :: ClauseVector -> Int -> IO Clause-getNthClause = MV.unsafeRead---- | sets the nth 'Clause'-{-# INLINE setNthClause #-}-setNthClause :: ClauseVector -> Int -> Clause -> IO ()-setNthClause = MV.unsafeWrite---- | swaps the two 'Clause's-{-# INLINE swapClauses #-}-swapClauses :: ClauseVector -> Int -> Int -> IO ()-swapClauses = MV.unsafeSwap
− SAT/Solver/Mios/ClauseManager.hs
@@ -1,324 +0,0 @@--- | A shrinkable 'VectorFamily' of 'C.Clause'-{-# LANGUAGE-    BangPatterns-  , DuplicateRecordFields-  , FlexibleInstances-  , MultiParamTypeClasses-  , RecordWildCards-  , ViewPatterns-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.ClauseManager-       (-         -- * higher level interface for ClauseVector-         ClauseManager (..)---       -- * vector of clauses---       , SimpleManager-         -- * Manager with an extra Int (used as sort key or blocking literal)-       , ClauseExtManager-       , pushClauseWithKey-       , getKeyVector-       , markClause---       , purifyManager-         -- * WatcherList-       , WatcherList-       , newWatcherList-       , getNthWatcher-       , garbageCollect---       , numberOfRegisteredClauses-       )-       where--import Control.Monad (forM, unless, when)-import qualified Data.IORef as IORef-import qualified Data.List as L-import qualified Data.Vector as V-import qualified Data.Vector.Mutable as MV-import SAT.Solver.Mios.Types-import qualified SAT.Solver.Mios.Clause as C---- | resizable clause vector-class ClauseManager a where-  newManager      :: Int -> IO a-  numberOfClauses :: a -> IO Int-  clearManager    :: a -> IO ()-  shrinkManager   :: a -> Int -> IO ()-  getClauseVector :: a -> IO C.ClauseVector-  pushClause      :: a -> C.Clause -> IO ()---  removeClause    :: a -> C.Clause -> IO ()---  removeNthClause :: a -> Int -> IO ()--{---- | The Clause Container-data SimpleManager = SimpleManager-  {-    _nActives     :: IntSingleton               -- number of active clause-  , _clauseVector :: IORef.IORef C.ClauseVector -- clause list-  }--instance ClauseManager SimpleManager where-  {-# SPECIALIZE INLINE newManager :: Int -> IO SimpleManager #-}-  newManager initialSize = do-    i <- newInt 0-    v <- C.newClauseVector initialSize-    SimpleManager i <$> IORef.newIORef v-  {-# SPECIALIZE INLINE numberOfClauses :: SimpleManager -> IO Int #-}-  numberOfClauses SimpleManager{..} = getInt _nActives-  {-# SPECIALIZE INLINE clearManager :: SimpleManager -> IO () #-}-  clearManager SimpleManager{..} = setInt _nActives 0-  {-# SPECIALIZE INLINE shrinkManager :: SimpleManager -> Int -> IO () #-}-  shrinkManager SimpleManager{..} k = modifyInt _nActives (subtract k)-  {-# SPECIALIZE INLINE getClauseVector :: SimpleManager -> IO C.ClauseVector #-}-  getClauseVector SimpleManager{..} = IORef.readIORef _clauseVector-  -- | O(1) inserter-  {-# SPECIALIZE INLINE pushClause :: SimpleManager -> C.Clause -> IO () #-}-  pushClause !SimpleManager{..} !c = do-    !n <- getInt _nActives-    !v <- IORef.readIORef _clauseVector-    if MV.length v - 1 <= n-      then do-          v' <- MV.unsafeGrow v (max 8 (MV.length v))-          -- forM_ [n  .. MV.length v' - 1] $ \i -> MV.unsafeWrite v' i C.NullClause-          MV.unsafeWrite v' n c-          IORef.writeIORef _clauseVector v'-      else MV.unsafeWrite v n c-    modifyInt _nActives (1 +)-  -- | O(1) remove-and-compact function-  {-# SPECIALIZE INLINE removeNthClause :: SimpleManager -> Int -> IO () #-}-  removeNthClause SimpleManager{..} i = do-    !n <- subtract 1 <$> getInt _nActives-    !v <- IORef.readIORef _clauseVector-    MV.unsafeWrite v i =<< MV.unsafeRead v n-    setInt _nActives n-  -- | O(n) but lightweight remove-and-compact function-  -- __Pre-conditions:__ the clause manager is empty or the clause is stored in it.-  {-# SPECIALIZE INLINE removeClause :: SimpleManager -> C.Clause -> IO () #-}-  removeClause SimpleManager{..} c = do-    -- putStrLn =<< dump "@removeClause| remove " c-    -- putStrLn =<< dump "@removeClause| from " m-    !n <- subtract 1 <$> getInt _nActives-    -- unless (0 <= n) $ error $ "removeClause catches " ++ show n-    !v <- IORef.readIORef _clauseVector-    let-      seekIndex :: Int -> IO Int-      seekIndex k = do-        c' <- MV.unsafeRead v k-        if c' == c then return k else seekIndex $ k + 1-    unless (n == -1) $ do-      !i <- seekIndex 0-      MV.unsafeWrite v i =<< MV.unsafeRead v n-      setInt _nActives n--instance VectorFamily SimpleManager C.Clause where-  dump mes SimpleManager{..} = do-    n <- getInt _nActives-    if n == 0-      then return $ mes ++ "empty clausemanager"-      else do-          l <- take n <$> (asList =<< IORef.readIORef _clauseVector)-          sts <- mapM (dump ",") (l :: [C.Clause])-          return $ mes ++ "[" ++ show n ++ "]" ++ tail (concat sts)--}-------------------------------------------------------------------------------------- | Clause + Blocking Literal-data ClauseExtManager = ClauseExtManager-  {-    _nActives     :: IntSingleton               -- number of active clause-  , _purged       :: BoolSingleton              -- whether it needs gc-  , _clauseVector :: IORef.IORef C.ClauseVector -- clause list-  , _keyVector    :: IORef.IORef Vec            -- Int list-  }--instance ClauseManager ClauseExtManager where-  {-# SPECIALIZE INLINE newManager :: Int -> IO ClauseExtManager #-}-  newManager initialSize = do-    i <- newInt 0-    v <- C.newClauseVector initialSize-    b <- newVec (MV.length v)-    ClauseExtManager i <$> newBool False <*> IORef.newIORef v <*> IORef.newIORef b-  {-# SPECIALIZE INLINE numberOfClauses :: ClauseExtManager -> IO Int #-}-  numberOfClauses ClauseExtManager{..} = getInt _nActives-  {-# SPECIALIZE INLINE clearManager :: ClauseExtManager -> IO () #-}-  clearManager ClauseExtManager{..} = setInt _nActives 0-  {-# SPECIALIZE INLINE shrinkManager :: ClauseExtManager -> Int -> IO () #-}-  shrinkManager ClauseExtManager{..} k = modifyInt _nActives (subtract k)-  {-# SPECIALIZE INLINE getClauseVector :: ClauseExtManager -> IO C.ClauseVector #-}-  getClauseVector ClauseExtManager{..} = IORef.readIORef _clauseVector-  -- | O(1) insertion function-  {-# SPECIALIZE INLINE pushClause :: ClauseExtManager -> C.Clause -> IO () #-}-  pushClause !ClauseExtManager{..} !c = do-    -- checkConsistency m c-    !n <- getInt _nActives-    !v <- IORef.readIORef _clauseVector-    !b <- IORef.readIORef _keyVector-    if MV.length v - 1 <= n-      then do-          let len = max 8 $ MV.length v-          v' <- MV.unsafeGrow v len-          b' <- vecGrow b len-          MV.unsafeWrite v' n c-          setNth b' n 0-          IORef.writeIORef _clauseVector v'-          IORef.writeIORef _keyVector b'-      else MV.unsafeWrite v n c >> setNth b n 0-    modifyInt _nActives (1 +)-{--  -- | O(n) but lightweight remove-and-compact function-  -- __Pre-conditions:__ the clause manager is empty or the clause is stored in it.-  {-# SPECIALIZE INLINE removeClause :: ClauseExtManager -> C.Clause -> IO () #-}-  removeClause ClauseExtManager{..} c = do-    !n <- subtract 1 <$> getInt _nActives-    !v <- IORef.readIORef _clauseVector-    !b <- IORef.readIORef _keyVector-    let-      seekIndex :: Int -> IO Int-      seekIndex k = do-        c' <- MV.unsafeRead v k-        if c' == c then return k else seekIndex $ k + 1-    unless (n == -1) $ do-      !i <- seekIndex 0-      MV.unsafeWrite v i =<< MV.unsafeRead v n-      setNth b i =<< getNth b n-      setInt _nActives n-  removeNthClause = error "removeNthClause is not implemented on ClauseExtManager"--}---- | sets the expire flag to a clause-{-# INLINE markClause #-}-markClause :: ClauseExtManager -> C.Clause -> IO ()-markClause ClauseExtManager{..} c = do-  !n <- getInt _nActives-  !v <- IORef.readIORef _clauseVector-  let-    seekIndex :: Int -> IO ()-    seekIndex k = do-      c' <- MV.unsafeRead v k-      if c' == c then MV.unsafeWrite v k C.NullClause else seekIndex $ k + 1-  unless (n == 0) $ do-    seekIndex 0-    setBool _purged True--{-# INLINE purifyManager #-}-purifyManager :: ClauseExtManager -> IO ()-purifyManager ClauseExtManager{..} = do-  diry <- getBool _purged-  when diry $ do-    n <- getInt _nActives-    vec <- IORef.readIORef _clauseVector-    keys <- IORef.readIORef _keyVector-    let-      loop :: Int -> Int -> IO Int-      loop ((< n) -> False) n' = return n'-      loop i j = do-        c <- C.getNthClause vec i-        if c /= C.NullClause-          then do-              unless (i == j) $ do-                C.setNthClause vec j c-                setNth keys j =<< getNth keys i-              loop (i + 1) (j + 1)-          else loop (i + 1) j-    setInt _nActives =<< loop 0 0-    setBool _purged False---- | returns the associated Int vector-{-# INLINE getKeyVector #-}-getKeyVector :: ClauseExtManager -> IO Vec-getKeyVector ClauseExtManager{..} = IORef.readIORef _keyVector---- | O(1) inserter-{-# INLINE pushClauseWithKey #-}-pushClauseWithKey :: ClauseExtManager -> C.Clause -> Lit -> IO ()-pushClauseWithKey !ClauseExtManager{..} !c k = do-  -- checkConsistency m c-  !n <- getInt _nActives-  !v <- IORef.readIORef _clauseVector-  !b <- IORef.readIORef _keyVector-  if MV.length v - 1 <= n-    then do-        let len = max 8 $ MV.length v-        v' <- MV.unsafeGrow v len-        b' <- vecGrow b len-        MV.unsafeWrite v' n c-        setNth b' n k-        IORef.writeIORef _clauseVector v'-        IORef.writeIORef _keyVector b'-    else MV.unsafeWrite v n c >> setNth b n k-  modifyInt _nActives (1 +)--instance VectorFamily ClauseExtManager C.Clause where-  dump mes ClauseExtManager{..} = do-    n <- getInt _nActives-    if n == 0-      then return $ mes ++ "empty ClauseExtManager"-      else do-          l <- take n <$> (asList =<< IORef.readIORef _clauseVector)-          sts <- mapM (dump ",") (l :: [C.Clause])-          return $ mes ++ "[" ++ show n ++ "]" ++ tail (concat sts)---------------------------------------------------------------------------------- WatcherList---- | Vector of 'ClauseExtManager'-type WatcherList = V.Vector ClauseExtManager---- | /n/ is the number of 'Var', /m/ is default size of each watcher list--- | For /n/ vars, we need [0 .. 2 + 2 * n - 1] slots, namely /2 * (n + 1)/-length vector-newWatcherList :: Int -> Int -> IO WatcherList-newWatcherList n m = V.fromList <$> forM [0 .. int2lit (negate n) + 1] (\_ -> newManager m)---- | returns the watcher List :: "ClauseManager" for "Literal" /l/-{-# INLINE getNthWatcher #-}-getNthWatcher :: WatcherList -> Lit-> ClauseExtManager-getNthWatcher = V.unsafeIndex--instance VectorFamily WatcherList C.Clause where-  dump mes wl = (mes ++) . L.concat <$> forM [1 .. V.length wl - 1] (\i -> dump ("\n" ++ show (lit2int i) ++ "' watchers:") (getNthWatcher wl i))---- | purges all expirable clauses in 'WatcherList'-{-# INLINE garbageCollect #-}-garbageCollect :: WatcherList -> IO ()-garbageCollect wm = V.mapM_ purifyManager wm--numberOfRegisteredClauses :: WatcherList -> IO Int-numberOfRegisteredClauses ws = sum <$> V.mapM numberOfClauses ws--{---------------------------------------------------------------------------------- debugging stuff--checkConsistency :: ClauseManager a => a -> C.Clause -> IO ()-checkConsistency manager c = do-  nc <- numberOfClauses manager-  vec <- getClauseVector manager-  let-    loop :: Int -> IO ()-    loop i = do-      when (i < nc) $ do-        c' <- MV.unsafeRead vec i-        when (c' == c) $ error "insert a clause to a ClauseMananger twice"-        loop $ i + 1-  loop 0--checkClauseOrder :: ClauseManager a => a -> IO ()-checkClauseOrder manager = do-  putStr "checking..."-  nc <- numberOfClauses manager-  vec <- getClauseVector manager-  let-    nthActivity :: Int -> IO Double-    nthActivity i = getDouble . C.activity =<< MV.unsafeRead vec i-    report :: Int -> Int -> IO ()-    report i j = (putStr . (++ ", ") . show =<< nthActivity i) >> when (i < j) (report (i + 1) j)-    loop :: Int -> Double -> IO ()-    loop i v = do-      when (i < nc) $ do-        c <- MV.unsafeRead vec i-        a <- getDouble (C.activity c)-        when (c == C.NullClause) $ error "null is included"-        when (v < a) $ report 0 i >> error ("unsorted clause vector: " ++ show (nc, i))-        loop (i + 1) a-  loop 0 =<< nthActivity 0-  putStrLn "done"--}
− SAT/Solver/Mios/Data/Singleton.hs
@@ -1,196 +0,0 @@--- | A fast(est) mutable data-{-# LANGUAGE-    BangPatterns-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.Data.Singleton-       (-         -- * Bool-         BoolSingleton-       , newBool-       , getBool-       , setBool-       , modifyBool-         -- * Int-       , IntSingleton-       , newInt-       , getInt-       , setInt-       , modifyInt-         -- * Double-       , DoubleSingleton-       , newDouble-       , getDouble-       , setDouble-       , modifyDouble-       )-       where-{--------------------------------------------- Implementation 1. :: IORef-------------------------------------------import Data.IORef--type BoolSingleton = IORef Bool--newBool :: Bool -> IO BoolSingleton-newBool = newIORef--{-# INLINE getBool #-}-getBool :: BoolSingleton -> IO Bool-getBool = readIORef--{-# INLINE setBool #-}-setBool :: BoolSingleton -> Bool -> IO ()-setBool = writeIORef--{-# INLINE modifyBool #-}-modifyBool :: BoolSingleton -> (Bool -> Bool) -> IO ()-modifyBool = modifyIORef'--type IntSingleton = IORef Int--newInt :: Int -> IO IntSingleton-newInt = newIORef--{-# INLINE getInt #-}-getInt :: IntSingleton -> IO Int-getInt = readIORef--{-# INLINE setInt #-}-setInt :: IntSingleton -> Int -> IO ()-setInt = writeIORef--{-# INLINE modifyInt #-}-modifyInt :: IntSingleton -> (Int -> Int) -> IO ()-modifyInt = modifyIORef'--type DoubleSingleton = IORef Double--newDouble :: Double -> IO DoubleSingleton-newDouble = newIORef--{-# INLINE getDouble #-}-getDouble :: DoubleSingleton -> IO Double-getDouble = readIORef--{-# INLINE setDouble #-}-setDouble :: DoubleSingleton -> Double -> IO ()-setDouble = writeIORef--{-# INLINE modifyDouble #-}-modifyDouble :: DoubleSingleton -> (Double -> Double) -> IO ()-modifyDouble = modifyIORef'--}-{--------------------------------------------- Implementation 2. :: Data.Mutable.IOURef-------------------------------------------import qualified Data.Mutable as M--newtype IntSingleton = IntSingleton-                       {-                         mutableInt :: M.IOURef Int-                       }--newInt :: IO IntSingleton-newInt = IntSingleton <$> M.newRef 0--{-# INLINE getInt #-}-getInt :: IntSingleton -> IO Int-getInt !(IntSingleton val) = M.readRef val--{-# INLINE setInt #-}-setInt :: IntSingleton -> Int -> IO ()-setInt !(IntSingleton val) !x = M.writeRef val x--{-# INLINE modifyInt #-}-modifyInt :: IntSingleton -> (Int -> Int) -> IO ()-modifyInt !(IntSingleton val) !f = M.modifyRef' val f--}---- {--------------------------------------------- Implementation 3. :: Data.Vector.Unboxed.Mutable-------------------------------------------import qualified Data.Vector.Unboxed.Mutable as UV---- | mutable Int-type IntSingleton = UV.IOVector Int---- | returns a new 'IntSingleton'-newInt :: Int -> IO IntSingleton-newInt k = do-  s <- UV.new 1-  UV.unsafeWrite s 0 k-  return s---- | returns the value-{-# INLINE getInt #-}-getInt :: IntSingleton -> IO Int-getInt val = UV.unsafeRead val 0---- | sets the value-{-# INLINE setInt #-}-setInt :: IntSingleton -> Int -> IO ()-setInt val !x = UV.unsafeWrite val 0 x---- | modifies the value-{-# INLINE modifyInt #-}-modifyInt :: IntSingleton -> (Int -> Int) -> IO ()-modifyInt val !f = UV.unsafeModify val f 0---- | mutable Bool-type BoolSingleton = UV.IOVector Bool---- | returns a new 'BoolSingleton'-newBool :: Bool -> IO BoolSingleton-newBool b = do-  s <- UV.new 1-  UV.unsafeWrite s 0 b-  return s---- | returns the value-{-# INLINE getBool #-}-getBool :: BoolSingleton -> IO Bool-getBool val = UV.unsafeRead val 0---- | sets the value-{-# INLINE setBool #-}-setBool :: BoolSingleton -> Bool -> IO ()-setBool val !x = UV.unsafeWrite val 0 x---- | modifies the value-{-# INLINE modifyBool #-}-modifyBool :: BoolSingleton -> (Bool -> Bool) -> IO ()-modifyBool val !f = UV.unsafeModify val f 0---- | mutable Double-type DoubleSingleton = UV.IOVector Double---- | returns a new 'DoubleSingleton'-newDouble :: Double -> IO DoubleSingleton-newDouble d = do-  s <- UV.new 1-  UV.unsafeWrite s 0 d-  return s---- | returns the value-{-# INLINE getDouble #-}-getDouble :: DoubleSingleton -> IO Double-getDouble val = UV.unsafeRead val 0---- | sets the value-{-# INLINE setDouble #-}-setDouble :: DoubleSingleton -> Double -> IO ()-setDouble val !x = UV.unsafeWrite val 0 x---- | modifies the value-{-# INLINE modifyDouble #-}-modifyDouble :: DoubleSingleton -> (Double -> Double) -> IO ()-modifyDouble val !f = UV.unsafeModify val f 0--- -}
− SAT/Solver/Mios/Data/Stack.hs
@@ -1,93 +0,0 @@--- | stack of Int, by adding the length field as the zero-th element to a 'Vec'-{-# LANGUAGE-    BangPatterns-  , FlexibleInstances-  , MultiParamTypeClasses-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.Data.Stack-       (-         Stack-       , newStack-       , clearStack-       , sizeOfStack-       , pushToStack-       , popFromStack-       , lastOfStack-       , shrinkStack-       , asSizedVec-       , isoVec-       )-       where--import qualified Data.Vector.Unboxed.Mutable as UV-import SAT.Solver.Mios.Types---- | Unboxed mutable stack for Int.-newtype Stack = Stack-                  {-                    ivec :: UV.IOVector Int-                  }--instance VectorFamily Stack Int where-  dump str v = (str ++) . show <$> asList v-  {-# SPECIALIZE INLINE asVec :: Stack -> Vec #-}-  asVec (Stack v) = UV.unsafeTail v-  asList (Stack v) = do-    (n : l) <- asList v-    return $ take n l---- | returns the number of elements-{-# INLINE sizeOfStack #-}-sizeOfStack :: Stack -> IO Int-sizeOfStack (Stack v) = UV.unsafeRead v 0---- | clear stack-{-# INLINE clearStack #-}-clearStack :: Stack -> IO ()-clearStack (Stack v) = UV.unsafeWrite v 0 0---- | returns a new stack which size is @size@-{-# INLINABLE newStack #-}-newStack :: Int -> IO Stack-newStack n = do-  v <- UV.new $ n + 1-  UV.set v 0-  return $ Stack v---- | pushs an int to 'Stack'-{-# INLINE pushToStack #-}-pushToStack :: Stack -> Int -> IO ()-pushToStack (Stack v) !x = do-  !i <- (+ 1) <$> UV.unsafeRead v 0-  UV.unsafeWrite v i x-  UV.unsafeWrite v 0 i---- | drops the first element from 'Stack'-{-# INLINE popFromStack #-}-popFromStack :: Stack -> IO ()-popFromStack (Stack v) = UV.unsafeModify v (subtract 1) 0---- | peeks the last element in 'Stack'-{-# INLINE lastOfStack #-}-lastOfStack :: Stack -> IO Int-lastOfStack (Stack v) = UV.unsafeRead v =<< UV.unsafeRead v 0---- | Shrink the stack. The given arg means the number of discards.--- therefore, shrink s n == for [1 .. n] $ \_ -> pop s-{-# INLINE shrinkStack #-}-shrinkStack :: Stack -> Int -> IO ()-shrinkStack (Stack v) k = UV.unsafeModify v (subtract k) 0---- | converts Stack to sized Vec; this is the method to get the internal vector-{-# INLINE asSizedVec #-}-asSizedVec :: Stack -> Vec-asSizedVec (Stack v) = v---- | isomorphic conversion to 'Vec'------ Note: 'asVec' drops the 1st element and no copy (unsafe operation); 'isoVec' really copies the real elements-{-# INLINE isoVec #-}-isoVec :: Stack -> IO Vec-isoVec (Stack v) = UV.clone . flip UV.take v . (1 +) =<< UV.unsafeRead v 0
− SAT/Solver/Mios/Data/Vec.hs
@@ -1,86 +0,0 @@--- | The fundamental data structure: Fixed Mutable Unboxed Int Vector-{-# LANGUAGE-    BangPatterns-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.Data.Vec-       (-         Vec-       , sizeOfVector-       , getNth-       , setNth-       , swapBetween-       , modifyNth-       , setAll-       , newVec-       , newVecWith-       , newSizedVecIntFromList-       , newSizedVecIntFromUVector-       , vecGrow-       )-       where--import qualified Data.Vector.Unboxed as U-import qualified Data.Vector.Unboxed.Mutable as UV---- | Costs of all operations are /O/(/1/)-type Vec = UV.IOVector Int---- | returns the size of 'Vec'-{-# INLINE sizeOfVector #-}-sizeOfVector :: Vec -> IO Int-sizeOfVector v = return $! UV.length v---- | returns a new 'Vec'-{-# INLINE newVec #-}-newVec :: Int -> IO Vec-newVec = UV.new---- | returns a new 'Vec' filled with an Int-{-# INLINE newVecWith #-}-newVecWith :: Int -> Int -> IO Vec-newVecWith n x = do-  v <- UV.new n-  UV.set v x-  return v---- | gets the nth value-{-# INLINE getNth #-}-getNth :: Vec -> Int -> IO Int-getNth = UV.unsafeRead---- | sets the nth value-{-# INLINE setNth #-}-setNth :: Vec -> Int -> Int -> IO ()-setNth = UV.unsafeWrite---- | modify the nth value-{-# INLINE modifyNth #-}-modifyNth :: Vec -> (Int -> Int) -> Int -> IO ()-modifyNth = UV.unsafeModify---- | sets all elements-{-# INLINE setAll #-}-setAll :: Vec -> Int -> IO ()-setAll = UV.set---- | swaps two elements-{-# INLINE swapBetween #-}-swapBetween:: Vec -> Int -> Int -> IO ()-swapBetween = UV.unsafeSwap---- | returns a new 'Vec' from a @[Int]@-{-# INLINE newSizedVecIntFromList #-}-newSizedVecIntFromList :: [Int] -> IO Vec-newSizedVecIntFromList !l = U.unsafeThaw $ U.fromList (length l : l)---- | returns a new 'Vec' from a Unboxed Int Vector-{-# INLINE newSizedVecIntFromUVector #-}-newSizedVecIntFromUVector :: U.Vector Int -> IO Vec-newSizedVecIntFromUVector = U.unsafeThaw---- | calls @unasfeGrow@-{-# INLINE vecGrow #-}-vecGrow :: Vec -> Int -> IO Vec-vecGrow = UV.unsafeGrow
− SAT/Solver/Mios/Data/VecBool.hs
@@ -1,55 +0,0 @@--- | Mutable Unboxed Boolean Vector------ * __VecBool@::UV.IOVector Bool@ -- data type that contains a mutable list of elements----{-# LANGUAGE-    BangPatterns-  , FlexibleInstances-  , MultiParamTypeClasses-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.Data.VecBool-       (-         VecBool-       , newVecBool-       , getNthBool-       , setNthBool-       , modifyNthBool-       )-       where--import Control.Monad (forM)-import qualified Data.Vector.Unboxed.Mutable as UV-import SAT.Solver.Mios.Types (VectorFamily(..))---- | Mutable unboxed Bool Vector-type VecBool = UV.IOVector Bool---- | provides 'clear' and 'size'-instance VectorFamily VecBool Bool where-  clear _ = error "VecBool.clear"-  asList v = forM [0 .. UV.length v - 1] $ UV.unsafeRead v-  dump str v = (str ++) . show <$> asList v---- | returns a new 'VecBool'-newVecBool :: Int -> Bool -> IO VecBool-newVecBool n x = do-  v <- UV.new n-  UV.set v x-  return v---- | returns the nth value in 'VecBool'-{-# INLINE getNthBool #-}-getNthBool :: VecBool -> Int -> IO Bool-getNthBool = UV.unsafeRead---- | sets the nth value-{-# INLINE setNthBool #-}-setNthBool :: VecBool -> Int -> Bool -> IO ()-setNthBool = UV.unsafeWrite---- | sets the nth value-{-# INLINE modifyNthBool #-}-modifyNthBool :: VecBool -> (Bool -> Bool) -> Int -> IO ()-modifyNthBool = UV.unsafeModify
− SAT/Solver/Mios/Data/VecDouble.hs
@@ -1,53 +0,0 @@--- | Mutable Unboxed Double Vector-{-# LANGUAGE-    BangPatterns-  , FlexibleInstances-  , MultiParamTypeClasses-  #-}-{-# LANGUAGE Trustworthy #-}--module SAT.Solver.Mios.Data.VecDouble-       (-         VecDouble-       , newVecDouble-       , getNthDouble-       , setNthDouble-       , modifyNthDouble-       )-       where--import Control.Monad (forM)-import Data.List ()-import qualified Data.Vector.Unboxed.Mutable as UV-import SAT.Solver.Mios.Types (VectorFamily(..))---- | Mutable unboxed Double Vector-type VecDouble = UV.IOVector Double--instance VectorFamily VecDouble Double where-  clear _ = error "VecDouble.clear"-  asList v = forM [0 .. UV.length v - 1] $ UV.unsafeRead v-  dump str v = (str ++) . show <$> asList v---- | returns a new 'VecDouble'-newVecDouble :: Int -> Double -> IO VecDouble-newVecDouble n 0 = UV.new n-newVecDouble n x = do-  v <- UV.new n-  UV.set v x-  return v---- | returns the nth value in 'VecDouble'-{-# INLINE getNthDouble #-}-getNthDouble :: Int -> VecDouble -> IO Double-getNthDouble !n v = UV.unsafeRead v n---- | sets the nth value-{-# INLINE setNthDouble #-}-setNthDouble :: Int -> VecDouble -> Double -> IO ()-setNthDouble !n v !x = UV.unsafeWrite v n x---- | updates the nth value-{-# INLINE modifyNthDouble #-}-modifyNthDouble :: Int -> VecDouble -> (Double -> Double) -> IO ()-modifyNthDouble !n v !f = UV.unsafeModify v f n
− SAT/Solver/Mios/Glucose.hs
@@ -1,72 +0,0 @@--- | This is a part of MIOS-{-# LANGUAGE-    BangPatterns-  , RecordWildCards-  , ScopedTypeVariables-  , ViewPatterns-  #-}-{-# LANGUAGE Safe #-}--module SAT.Solver.Mios.Glucose-       (-         computeLBD-       , lbdOf-       , setLBD-       , updateLBD-       , nextReduction-       )-        where--import Control.Monad (when)-import SAT.Solver.Mios.Types-import SAT.Solver.Mios.Clause-import SAT.Solver.Mios.Solver---- | returns the LBD vaule for 'Vec[1 ..]'-computeLBD :: Solver -> Vec -> IO Int-computeLBD Solver{..} vec = do-  key <- (1 +) <$> getInt lbd'key-  setInt lbd'key key-  nv <- getNth vec 0-  let-    loop :: Int -> Int -> IO Int-    loop ((<= nv) -> False) n = return n-    loop !i !n = do-      l <- getNth level . lit2var =<< getNth vec i-      seen <- if l == 0 then return True else (key ==) <$> getNth lbd'seen l-      if seen-        then loop (i + 1) n-        else setNth lbd'seen l key >> loop (i + 1) (n + 1)-  loop 1 0---- | returns the LBD value of 'Clause'-{-# INLINE lbdOf #-}-lbdOf :: Solver -> Clause -> IO Int-lbdOf s (lits -> v) = computeLBD s v---- | update the LBD field in 'Clause'-{-# INLINE setLBD #-}-setLBD :: Solver -> Clause -> IO ()-setLBD s c = setInt (lbd c) =<< lbdOf s c---- | update the lbd field of /c/-{-# INLINE updateLBD #-}-updateLBD :: Solver -> Clause -> IO ()-updateLBD _ NullClause = error "LBD71"-updateLBD _ (learnt -> False) = return ()-updateLBD s c@Clause{..} = setInt lbd =<< lbdOf s c---- | 0 based------ >>> nextReduction 0--- 20000--- >>> nextReduction 1--- 40000 + 200 = 20000 + 20000 + 200--- >>> nextReduction 2--- 6000 + 600 = 20000 + 20200 + 20000 + 400--- >>> nextReduction 3--- 80000 + 1200 = 20000 + 20200 + 20400 + 20000 + 600----nextReduction :: Int -> Int -> Int--- nextReduction _ n = 30000 + 10000 * n-nextReduction b n = b + 300 * n
− SAT/Solver/Mios/Internal.hs
@@ -1,34 +0,0 @@--- | Internal Settings-module SAT.Solver.Mios.Internal-       (-         versionId-       , MiosConfiguration (..)-       , defaultConfiguration-       , module Plumbing-       )-       where-import SAT.Solver.Mios.Data.VecBool as Plumbing-import SAT.Solver.Mios.Data.VecDouble as Plumbing-import SAT.Solver.Mios.Data.Stack as Plumbing---- | version name-versionId :: String-versionId = "mios 1.2 <https://github.com/shnarazk/mios/>" -- blocking literal + lbd + phase-saving---- | solver's parameters; random decision rate was dropped.-data MiosConfiguration = MiosConfiguration-                         {-                           variableDecayRate  :: Double  -- ^ decay rate for variable activity-                         , clauseDecayRate    :: Double  -- ^ decay rate for clause activity-                         , collectStats       :: Bool    -- ^ whether collect and report statistics-                         }---- | dafault configuration------ * Minisat-1.14 uses @(0.95, 0.999, 0.2 = 20 / 1000)@.--- * Minisat-2.20 uses @(0.95, 0.999, 0)@.--- * Gulcose-4.0  uses @(0.8 , 0.999, 0)@.--- * Mios-1.2     uses @(0.95, 0.999, 0)@.----defaultConfiguration :: MiosConfiguration-defaultConfiguration = MiosConfiguration 0.95 0.999 {- 0 -} False
− SAT/Solver/Mios/M114.hs
@@ -1,816 +0,0 @@--- | This is a part of MIOS-{-# LANGUAGE-    BangPatterns-  , RecordWildCards-  , ScopedTypeVariables-  , ViewPatterns-  #-}-{-# LANGUAGE Safe #-}--module SAT.Solver.Mios.M114-       (-         simplifyDB-       , solve-       )-        where--import Control.Monad (forM_, unless, void, when)-import Data.Bits-import Data.Foldable (foldrM)-import SAT.Solver.Mios.Types-import SAT.Solver.Mios.Internal-import SAT.Solver.Mios.Clause-import SAT.Solver.Mios.ClauseManager-import SAT.Solver.Mios.Solver-import SAT.Solver.Mios.Glucose---- | #114: __RemoveWatch__-{-# INLINABLE removeWatch #-}-removeWatch :: Solver -> Clause -> IO ()-removeWatch Solver{..} c = do-  let lvec = asVec c-  l1 <- negateLit <$> getNth lvec 0-  markClause (getNthWatcher watches l1) c-  l2 <- negateLit <$> getNth lvec 1-  markClause (getNthWatcher watches l2) c------------------------------------------------------------------------------------- Operations on 'Clause'------------------------------------------------------------------------------------- | __Fig. 8. (p.12)__ create a new LEARNT clause and adds it to watcher lists--- This is a strippped-down version of 'newClause' in Solver-{-# INLINABLE newLearntClause #-}-newLearntClause :: Solver -> Vec -> IO ()-newLearntClause s@Solver{..} ps = do-  good <- getBool ok-  when good $ do-    -- ps is a 'SizedVectorInt'; ps[0] is the number of active literals-    -- Since this solver must generate only healthy learnt clauses, we need not to run misc check in 'newClause'-    k <- getNth ps 0-    case k of-     1 -> do-       l <- getNth ps 1-       unsafeEnqueue s l NullClause-     _ -> do-       -- allocate clause:-       c <- newClauseFromVec True ps-       let vec = asVec c-       -- Pick a second literal to watch:-       let-         findMax :: Int -> Int -> Int -> IO Int-         findMax ((< k) -> False) j _ = return j-         findMax i j val = do-           v' <- lit2var <$> getNth vec i-           a <- getNth assigns v'-           b <- getNth level v'-           if (a /= lBottom) && (val < b)-             then findMax (i + 1) i b-             else findMax (i + 1) j val-       swapBetween vec 1 =<< findMax 0 0 0 -- Let @max_i@ be the index of the literal with highest decision level-       -- Bump, enqueue, store clause:-       claBumpActivity s c -- newly learnt clauses should be considered active-       -- Add clause to all managers-       pushClause learnts c-       l <- getNth vec 0-       pushClauseWithKey (getNthWatcher watches (negateLit l)) c 0-       l1 <- negateLit <$> getNth vec 1-       pushClauseWithKey (getNthWatcher watches l1) c 0-       -- update the solver state by @l@-       unsafeEnqueue s l c-       -- Since unsafeEnqueue updates the 1st literal's level, setLBD should be called after unsafeEnqueue-       setLBD s c---- | __Simplify.__ At the top-level, a constraint may be given the opportunity to--- simplify its representation (returns @False@) or state that the constraint is--- satisfied under the current assignment and can be removed (returns @True@).--- A constraint must /not/ be simplifiable to produce unit information or to be--- conflicting; in that case the propagation has not been correctly defined.------ MIOS NOTE: the original doesn't update watchers; only checks its satisfiabiliy.-{-# INLINABLE simplify #-}-simplify :: Solver -> Clause -> IO Bool-simplify s c = do-  n <- sizeOfClause c-  let-    lvec = asVec c-    loop ::Int -> IO Bool-    loop ((< n) -> False) = return False-    loop i = do-      v <- valueLit s =<< getNth lvec i-      if v == 1 then return True else loop (i + 1)-  loop 0------------------------------------------------------------------------------------- MIOS NOTE on Minor methods:------ * no (meaningful) 'newVar' in mios--- * 'assume' is defined in 'Solver'--- * `cancelUntil` is defined in 'Solver'------------------------------------------------------------------------------------- Major methods---- | M114: __Fig. 10. (p.15)__------ analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel :: int&) -> [void]------ __Description:_----   Analzye confilct and produce a reason clause.------ __Pre-conditions:__---   * 'out_learnt' is assumed to be cleared.---   * Corrent decision level must be greater than root level.------ __Post-conditions:__---   * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.---   * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the---     rest of literals. There may be others from the same level though.------ @analyze@ is invoked from @search@--- {-# INLINEABLE analyze #-}-analyze :: Solver -> Clause -> IO Int-analyze s@Solver{..} confl = do-  -- litvec-  clearStack litsLearnt-  pushToStack litsLearnt 0 -- reserve the first place for the unassigned literal-  dl <- decisionLevel s-  let-    litsVec = asVec litsLearnt-    trailVec = asVec trail-    loopOnClauseChain :: Clause -> Lit -> Int -> Int -> Int -> IO Int-    loopOnClauseChain c p ti bl pathC = do -- p : literal, ti = trail index, bl = backtrack level-      when (learnt c) $ do-        claBumpActivity s c-        -- update LBD like #Glucose4.0-        d <- getInt (lbd c)-        when (2 < d) $ do-          nblevels <- lbdOf s c-          when (nblevels + 1 < d) $ do -- improve the LBD-            when (d <= 30) $ setBool (protected c) True -- 30 is `lbLBDFrozenClause`-            -- seems to be interesting: keep it fro the next round-            setInt (lbd c) nblevels    -- Update it-      sc <- sizeOfClause c-      let-        lvec = asVec c-        loopOnLiterals :: Int -> Int -> Int -> IO (Int, Int)-        loopOnLiterals ((< sc) -> False) b pc = return (b, pc) -- b = btLevel, pc = pathC-        loopOnLiterals j b pc = do-          (q :: Lit) <- getNth lvec j-          let v = lit2var q-          sn <- getNth an'seen v-          l <- getNth level v-          if sn == 0 && 0 < l-            then do-                varBumpActivity s v-                setNth an'seen v 1-                if dl <= l      -- cancelUntil doesn't clear level of cancelled literals-                  then do-                      -- glucose heuristics-                      r <- getNthClause reason v-                      when (r /= NullClause && learnt r) $ pushToStack lastDL q-                      -- end of glucose heuristics-                      loopOnLiterals (j + 1) b (pc + 1)-                  else pushToStack litsLearnt q >> loopOnLiterals (j + 1) (max b l) pc-            else loopOnLiterals (j + 1) b pc-      (b', pathC') <- loopOnLiterals (if p == bottomLit then 0 else 1) bl pathC-      let-        -- select next clause to look at-        nextPickedUpLit :: Int -> IO Int-        nextPickedUpLit i = do-          x <- getNth an'seen . lit2var =<< getNth trailVec i-          if x == 0 then nextPickedUpLit $ i - 1 else return i-      ti' <- nextPickedUpLit ti-      nextP <- getNth trailVec ti'-      let nextV = lit2var nextP-      confl' <- getNthClause reason nextV-      setNth an'seen nextV 0-      if 1 < pathC'-        then loopOnClauseChain confl' nextP (ti' - 1) b' (pathC' - 1)-        else setNth litsVec 0 (negateLit nextP) >> return b'-  ti <- subtract 1 <$> sizeOfStack trail-  levelToReturn <- loopOnClauseChain confl bottomLit ti 0 0-  -- Simplify phase (implemented only @expensive_ccmin@ path)-  n <- sizeOfStack litsLearnt-  clearStack an'stack           -- analyze_stack.clear();-  clearStack an'toClear         -- out_learnt.copyTo(analyze_toclear);-  pushToStack an'toClear =<< getNth litsVec 0-  let-    merger :: Int -> Int -> IO Int-    merger ((< n) -> False) b = return b-    merger i b = do-      l <- getNth litsVec i-      pushToStack an'toClear l-      -- restrict the search depth (range) to 32-      merger (i + 1) . setBit b . (31 .&.) =<< getNth level (lit2var l)-  levels <- merger 1 0-  let-    loopOnLits :: Int -> Int -> IO ()-    loopOnLits ((< n) -> False) n' = shrinkStack litsLearnt $ n - n'-    loopOnLits i j = do-      l <- getNth litsVec i-      c1 <- (NullClause ==) <$> getNthClause reason (lit2var l)-      if c1-        then setNth litsVec j l >> loopOnLits (i + 1) (j + 1)-        else do-           c2 <- not <$> analyzeRemovable s l levels-           if c2-             then setNth litsVec j l >> loopOnLits (i + 1) (j + 1)-             else loopOnLits (i + 1) j-  loopOnLits 1 1                -- the first literal is specail-  -- glucose heuristics-  nld <- sizeOfStack lastDL-  lbd' <- computeLBD s $ asSizedVec litsLearnt -- this is not the right value-  let-    vec = asVec lastDL-    loopOnLastDL :: Int -> IO ()-    loopOnLastDL ((< nld) -> False) = return ()-    loopOnLastDL i = do-      v <- lit2var <$> getNth vec i-      d' <- getInt . lbd =<< getNthClause reason v-      when (lbd' < d') $ varBumpActivity s v-      loopOnLastDL $ i + 1-  loopOnLastDL 0-  clearStack lastDL-  -- Clear seen-  k <- sizeOfStack an'toClear-  let-    vec' = asVec an'toClear-    cleaner :: Int -> IO ()-    cleaner ((< k) -> False) = return ()-    cleaner i = do-      v <- lit2var <$> getNth vec' i-      setNth an'seen v 0-      cleaner $ i + 1-  cleaner 0-  return levelToReturn---- | #M114--- Check if 'p' can be removed, 'abstract_levels' is used to abort early if the algorithm is--- visiting literals at levels that cannot be removed later.------ Implementation memo:------ *  @an'toClear@ is initialized by @ps@ in @analyze@ (a copy of 'learnt').---   This is used only in this function and @analyze@.----{-# INLINEABLE analyzeRemovable #-}-analyzeRemovable :: Solver -> Lit -> Int -> IO Bool-analyzeRemovable Solver{..} p minLevel = do-  -- assert (reason[var(p)]!= NullCaulse);-  clearStack an'stack      -- analyze_stack.clear()-  pushToStack an'stack p   -- analyze_stack.push(p);-  top <- sizeOfStack an'toClear-  let-    loopOnStack :: IO Bool-    loopOnStack = do-      k <- sizeOfStack an'stack  -- int top = analyze_toclear.size();-      if 0 == k-        then return True-        else do -- assert(reason[var(analyze_stack.last())] != GClause_NULL);-            sl <- lastOfStack an'stack-            popFromStack an'stack             -- analyze_stack.pop();-            c <- getNthClause reason (lit2var sl) -- getRoot sl-            nl <- sizeOfClause c-            let-              cvec = asVec c-              loopOnLit :: Int -> IO Bool -- loopOnLit (int i = 1; i < c.size(); i++){-              loopOnLit ((< nl) -> False) = loopOnStack-              loopOnLit i = do-                p' <- getNth cvec i              -- valid range is [0 .. nl - 1]-                let v' = lit2var p'-                l' <- getNth level v'-                c1 <- (1 /=) <$> getNth an'seen v'-                if c1 && (0 /= l')   -- if (!analyze_seen[var(p)] && level[var(p)] != 0){-                  then do-                      c3 <- (NullClause /=) <$> getNthClause reason v'-                      if c3 && testBit minLevel (l' .&. 31) -- if (reason[var(p)] != GClause_NULL && ((1 << (level[var(p)] & 31)) & min_level) != 0){-                        then do-                            setNth an'seen v' 1        -- analyze_seen[var(p)] = 1;-                            pushToStack an'stack p'    -- analyze_stack.push(p);-                            pushToStack an'toClear p'  -- analyze_toclear.push(p);-                            loopOnLit $ i + 1-                        else do-                            -- loopOnLit (int j = top; j < analyze_toclear.size(); j++) analyze_seen[var(analyze_toclear[j])] = 0;-                            top' <- sizeOfStack an'toClear-                            let vec = asVec an'toClear-                            forM_ [top .. top' - 1] $ \j -> do x <- getNth vec j; setNth an'seen (lit2var x) 0-                            -- analyze_toclear.shrink(analyze_toclear.size() - top); note: shrink n == repeat n pop-                            shrinkStack an'toClear $ top' - top-                            return False-                  else loopOnLit $ i + 1-            loopOnLit 1-  loopOnStack---- | #114--- analyzeFinal : (confl : Clause *) (skip_first : boot) -> [void]------ __Description:__---   Specialized analysis proceduce to express the final conflict in terms of assumptions.---   'root_level' is allowed to point beyond end of trace (useful if called after conflict while---   making assumptions). If 'skip_first' is TRUE, the first literal of 'confl' is ignored (needed---   if conflict arose before search even started).----analyzeFinal :: Solver -> Clause -> Bool -> IO ()-analyzeFinal Solver{..} confl skipFirst = do-  clearStack conflict-  rl <- getInt rootLevel-  unless (rl == 0) $ do-    n <- sizeOfClause confl-    let-      lvec = asVec confl-      loopOnConfl :: Int -> IO ()-      loopOnConfl ((< n) -> False) = return ()-      loopOnConfl i = do-        (x :: Var) <- lit2var <$> getNth lvec i-        lvl <- getNth level x-        when (0 < lvl) $ setNth an'seen x 1-        loopOnConfl $ i + 1-    loopOnConfl $ if skipFirst then 1 else 0-    tls <- sizeOfStack trailLim-    trs <- sizeOfStack trail-    tlz <- getNth (asVec trailLim) 0-    let-      trailVec = asVec trail-      loopOnTrail :: Int -> IO ()-      loopOnTrail ((tlz <=) -> False) = return ()-      loopOnTrail i = do-        (l :: Lit) <- getNth trailVec i-        let (x :: Var) = lit2var l-        saw <- getNth an'seen x-        when (saw == 1) $ do-          (r :: Clause) <- getNthClause reason x-          if r == NullClause-            then pushToStack conflict (negateLit l)-            else do-                k <- sizeOfClause r-                let-                  cvec = asVec r-                  loopOnLits :: Int -> IO ()-                  loopOnLits ((< k) -> False) = return ()-                  loopOnLits j = do-                    (v :: Var) <- lit2var <$> getNth cvec j-                    lv <- getNth level v-                    when (0 < lv) $ setNth an'seen v 1-                    loopOnLits $ i + 1-                loopOnLits 1-        setNth an'seen x 0-        loopOnTrail $ i - 1-    loopOnTrail =<< if tls <= rl then return (trs - 1) else getNth (asVec trailLim) rl---- | M114:--- propagate : [void] -> [Clause+]------ __Description:__---   Porpagates all enqueued facts. If a conflict arises, the cornflicting clause is returned.---   otherwise CRef_undef.------ __Post-conditions:__---   * the propagation queue is empty, even if there was a conflict.------ memo: @propagate@ is invoked by @search@,`simpleDB` and `solve`-{-# INLINABLE propagate #-}-propagate :: Solver -> IO Clause-propagate s@Solver{..} = do-  -- myVal <- getNth stats (fromEnum NumOfBackjump)-  let-{--    myVal = 0-    bumpAllVar :: IO ()         -- not in use-    bumpAllVar = do-      let-        loop :: Int -> IO ()-        loop ((<= nVars) -> False) = return ()-        loop i = do-          c <- getNth pr'seen i-          when (c == myVal) $ varBumpActivity s i-          loop $ i + 1-      loop 1--}-    trailVec = asVec trail-    while :: Clause -> Bool -> IO Clause-    while confl False = {- bumpAllVar >> -} return confl-    while confl True = do-      (p :: Lit) <- getNth trailVec =<< getInt qHead-      modifyInt qHead (+ 1)-      let (ws :: ClauseExtManager) = getNthWatcher watches p-      end <- numberOfClauses ws-      cvec <- getClauseVector ws-      bvec <- getKeyVector ws---      rc <- getNthClause reason $ lit2var p---      byGlue <- if (rc /= NullClause) && learnt rc then (== 2) <$> getInt (lbd rc) else return False-      let-{--        checkAllLiteralsIn :: Clause -> IO () -- not in use-        checkAllLiteralsIn c = do-          nc <- sizeOfClause c-          let-            vec = asVec c-            loop :: Int -> IO ()-            loop((< nc) -> False) = return ()-            loop i = do-              (v :: Var) <- lit2var <$> getNth vec i-              setNth pr'seen v myVal-              loop $ i + 1-          loop 0--}-        forClause :: Clause -> Int -> Int -> IO Clause-        forClause confl i@((< end) -> False) j = do-          shrinkManager ws (i - j)-          while confl =<< ((<) <$> getInt qHead <*> sizeOfStack trail)-        forClause confl i j = do-          (l :: Lit) <- getNth bvec i-          bv <- if l == 0 then return lFalse else valueLit s l-          if bv == lTrue-            then do-                 unless (i == j) $ do -- NOTE: if i == j, the path doesn't require accesses to cvec!-                   (c :: Clause) <- getNthClause cvec i-                   setNthClause cvec j c-                   setNth bvec j l-                 forClause confl (i + 1) (j + 1)-            else do-                -- checkAllLiteralsIn c-                (c :: Clause) <- getNthClause cvec i-                let-                  lits = asVec c-                  falseLit = negateLit p-                -- Make sure the false literal is data[1]-                ((falseLit ==) <$> getNth lits 0) >>= (`when` swapBetween lits 0 1)-                -- if 0th watch is true, then clause is already satisfied.-                (first :: Lit) <- getNth lits 0-                val <- valueLit s first-                if val == lTrue-                  then setNthClause cvec j c >> setNth bvec j first >> forClause confl (i + 1) (j + 1)-                  else do-                      -- Look for new watch-                      cs <- sizeOfClause c-                      let-                        forLit :: Int -> IO Clause-                        forLit ((< cs) -> False) = do-                          -- Did not find watch; clause is unit under assignment:-                          setNthClause cvec j c-                          setNth bvec j 0-                          result <- enqueue s first c-                          if not result-                            then do-                                ((== 0) <$> decisionLevel s) >>= (`when` setBool ok False)-                                setInt qHead =<< sizeOfStack trail-                                -- Copy the remaining watches:-                                let-                                  copy i'@((< end) -> False) j' = forClause c i' j'-                                  copy i' j' = do-                                    setNthClause cvec j' =<< getNthClause cvec i'-                                    setNth bvec j' =<< getNth bvec i'-                                    copy (i' + 1) (j' + 1)-                                copy (i + 1) (j + 1)-                            else forClause confl (i + 1) (j + 1)-                        forLit k = do-                          (l :: Lit) <- getNth lits k-                          lv <- valueLit s l-                          if lv /= lFalse-                            then do-                                swapBetween lits 1 k-                                pushClauseWithKey (getNthWatcher watches (negateLit l)) c l-                                forClause confl (i + 1) j-                            else forLit $ k + 1-                      forLit 2-      forClause confl 0 0-  while NullClause =<< ((<) <$> getInt qHead <*> sizeOfStack trail)---- | #M22--- reduceDB: () -> [void]------ __Description:__---   Remove half of the learnt clauses, minus the clauses locked by the current assigmnent. Locked---   clauses are clauses that are reason to some assignment. Binary clauses are never removed.-{-# INLINABLE reduceDB #-}-reduceDB :: Solver -> IO ()-reduceDB s@Solver{..} = do-  n <- nLearnts s-  vec <- getClauseVector learnts-  let-    loop :: Int -> IO ()-    loop ((< n) -> False) = return ()-    loop i = (removeWatch s =<< getNthClause vec i) >> loop (i + 1)-  k <- sortClauses s learnts (div n 2) -- k is the number of clauses not to be purged-  loop k                               -- CAVEAT: `vec` is a zero-based vector-  garbageCollect watches-  shrinkManager learnts (n - k)---- | (Good to Bad) Quick sort the key vector based on their activities and returns number of privileged clauses.--- this function uses the same metrix as reduceDB_lt in glucose 4.0:--- 1. binary clause--- 2. smaller lbd--- 3. larger activity defined in MiniSat--- , where smaller value is better.------ they are coded into an Int as the following layout:------ * 14 bit: LBD or 0 for preserved clauses--- * 19 bit: converted activity--- * remain: clauseVector index----(lbdWidth :: Int, activityWidth :: Int, indexWidth :: Int) = (l, a, w - (l + a + 1))-  where-    w = finiteBitSize (0:: Int)-    (l, a) = case () of-      _ | 64 <= w -> (16, 19)   -- 28 bit => 256M clauses-      _ | 60 <= w -> (14, 19)   -- 26 bit =>  32M clauses-      _ | 32 <= w -> ( 7,  6)   -- 18 bit => 256K clauses-      _ | 29 <= w -> ( 6,  5)   -- 17 bit => 128K clauses-      _ -> error "Int on your CPU doesn't have sufficient bit width."--{-# INLINABLE sortClauses #-}-sortClauses :: Solver -> ClauseExtManager -> Int -> IO Int-sortClauses s cm nneeds = do-  -- constants-  let-    lbdMax :: Int-    lbdMax = 2 ^ lbdWidth - 1-    activityMax :: Int-    activityMax = 2 ^ activityWidth - 1-    activityScale :: Double-    activityScale = fromIntegral activityMax-    indexMax :: Int-    indexMax = (2 ^ indexWidth - 1) -- 67,108,863 for 26-  n <- numberOfClauses cm-  when (indexMax < n) $ error $ "## The number of learnt clauses " ++ show n ++ " exceeds mios's " ++ show indexWidth ++" bit manage capacity"-  vec <- getClauseVector cm-  keys <- getKeyVector cm-  -- 1: assign keys-  let-    assignKey :: Int -> Int -> IO Int-    assignKey ((< n) -> False) m = return m-    assignKey i m = do-      c <- getNthClause vec i-      k <- (\k -> if k == 2 then return k else fromEnum <$> getBool (protected c)) =<< sizeOfClause c-      case k of-        1 -> setBool (protected c) False >> setNth keys i (shiftL 2 indexWidth + i) >> assignKey (i + 1) (m + 1)-        2 -> setNth keys i (shiftL 1 indexWidth + i) >> assignKey (i + 1) (m + 1)-        _ -> do-            l <- locked s c      -- this is expensive-            if l-              then setNth keys i (shiftL 1 indexWidth + i) >> assignKey (i + 1) (m + 1)-              else do-                  d <- getInt $ lbd c-                  b <- floor . (activityScale *) . (1 -) . logBase 1e100 . max 1 <$> getDouble (activity c)-                  setNth keys i $ shiftL (min lbdMax d) (activityWidth + indexWidth) + shiftL b indexWidth + i-                  assignKey (i + 1) m-  limit <- min n . (+ nneeds) <$> assignKey 0 0-  -- 2: sort keyVector-  let-    sortOnRange :: Int -> Int -> IO ()-    sortOnRange left right-      | limit < left = return ()-      | left >= right = return ()-      | left + 1 == right = do-          a <- getNth keys left-          b <- getNth keys right-          unless (a < b) $ swapBetween keys left right-      | otherwise = do-          let p = div (left + right) 2-          pivot <- getNth keys p-          swapBetween keys p left -- set a sentinel for r'-          let-            nextL :: Int -> IO Int-            nextL i@((<= right) -> False) = return i-            nextL i = do v <- getNth keys i; if v < pivot then nextL (i + 1) else return i-            nextR :: Int -> IO Int-            -- nextR i@((left <=) -> False) = return i-            nextR i = do v <- getNth keys i; if pivot < v then nextR (i - 1) else return i-            divide :: Int -> Int -> IO Int-            divide l r = do-              l' <- nextL l-              r' <- nextR r-              if l' < r' then swapBetween keys l' r' >> divide (l' + 1) (r' - 1) else return r'-          m <- divide (left + 1) right-          swapBetween keys left m-          sortOnRange left (m - 1)-          sortOnRange (m + 1) right-  sortOnRange 0 (n - 1)-  -- 3: place clauses-  let-    seek :: Int -> IO ()-    seek ((< limit) -> False) = return ()-    seek i = do-      bits <- getNth keys i-      when (indexMax < bits) $ do-        c <- getNthClause vec i-        let-          sweep k = do-            k' <- (indexMax .&.) <$> getNth keys k-            setNth keys k k-            if k' == i-              then setNthClause vec k c-              else getNthClause vec k' >>= setNthClause vec k >> sweep k'-        sweep i-      seek $ i + 1-  seek 0-  return limit---- | #M22------ simplify : [void] -> [bool]------ __Description:__---   Simplify the clause database according to the current top-level assigment. Currently, the only---   thing done here is the removal of satisfied clauses, but more things can be put here.----{-# INLINABLE simplifyDB #-}-simplifyDB :: Solver -> IO Bool-simplifyDB s@Solver{..} = do-  good <- getBool ok-  if good-    then do-      p <- propagate s-      if p /= NullClause-        then setBool ok False >> return False-        else do-            -- Clear watcher lists:-            n <- sizeOfStack trail-            let-              vec = asVec trail-              loopOnLit ((< n) -> False) = return ()-              loopOnLit i = do-                l <- getNth vec i-                clearManager . getNthWatcher watches $ l-                clearManager . getNthWatcher watches $ negateLit l-                loopOnLit $ i + 1-            loopOnLit 0-            -- Remove satisfied clauses:-            let-              for :: Int -> IO Bool-              for ((< 2) -> False) = return True-              for t = do-                let ptr = if t == 0 then learnts else clauses-                vec' <- getClauseVector ptr-                n' <- numberOfClauses ptr-                let-                  loopOnVector :: Int -> Int -> IO Bool-                  loopOnVector ((< n') -> False) j = shrinkManager ptr (n' - j) >> return True-                  loopOnVector i j = do-                        c <- getNthClause vec' i-                        l <- locked s c-                        r <- simplify s c-                        if not l && r-                          then removeWatch s c >> loopOnVector (i + 1) j-                          else setNthClause vec' j c >> loopOnVector (i + 1) (j + 1)-                loopOnVector 0 0-            ret <- for 0-            garbageCollect watches-            return ret-    else return False---- | #M22------ search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool]------ __Description:__---   Search for a model the specified number of conflicts.---   NOTE: Use negative value for 'nof_conflicts' indicate infinity.------ __Output:__---   'l_True' if a partial assigment that is consistent with respect to the clause set is found. If---   all variables are decision variables, that means that the clause set is satisfiable. 'l_False'---   if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.-{-# INLINABLE search #-}-search :: Solver -> Int -> Int -> IO LiftedBool-search s@Solver{..} nOfConflicts nOfLearnts = do-  -- clear model-  let-    loop :: Int -> IO LiftedBool-    loop conflictC = do-      !confl <- propagate s-      d <- decisionLevel s-      if confl /= NullClause-        then do-            -- CONFLICT-            incrementStat s NumOfBackjump 1-            r <- getInt rootLevel-            if d == r-              then do-                  -- Contradiction found:-                  analyzeFinal s confl False-                  return LFalse-              else do---                  u <- (== 0) . (flip mod 5000) <$> getNth stats (fromEnum NumOfBackjump)---                  when u $ do---                    d <- getDouble varDecay---                    when (d < 0.95) $ modifyDouble varDecay (+ 0.01)-                  backtrackLevel <- analyze s confl -- 'analyze' resets litsLearnt by itself-                  (s `cancelUntil`) . max backtrackLevel =<< getInt rootLevel-                  newLearntClause s $ asSizedVec litsLearnt-                  k <- sizeOfStack litsLearnt-                  when (k == 1) $ do-                    (v :: Var) <- lit2var <$> getNth (asVec litsLearnt) 0-                    setNth level v 0-                  varDecayActivity s-                  claDecayActivity s-                  loop $ conflictC + 1-        else do                 -- NO CONFLICT-            -- Simplify the set of problem clauses:-            when (d == 0) . void $ simplifyDB s -- our simplifier cannot return @False@ here-            k1 <- numberOfClauses learnts-            k2 <- nAssigns s-            when (k1 - k2 >= nOfLearnts) $ reduceDB s -- Reduce the set of learnt clauses-            case () of-             _ | k2 == nVars -> do-                   -- Model found:-                   forM_ [0 .. nVars - 1] $ \i -> setNthBool model i . (lTrue ==) =<< getNth assigns (i + 1)-                   return LTrue-             _ | conflictC >= nOfConflicts -> do-                   -- Reached bound on number of conflicts-                   (s `cancelUntil`) =<< getInt rootLevel -- force a restart-                   incrementStat s NumOfRestart 1-                   return Bottom-             _ -> do-               -- New variable decision:-               v <- select s -- many have heuristic for polarity here-               -- << #phasesaving-               oldVal <- getNth phases v-               unsafeAssume s $ var2lit v (0 < oldVal) -- cannot return @False@-               -- >> #phasesaving-               loop conflictC-  good <- getBool ok-  if good then loop 0 else return LFalse---- | __Fig. 16. (p.20)__--- Main solve method.------ __Pre-condition:__ If assumptions are used, 'simplifyDB' must be--- called right before using this method. If not, a top-level conflict (resulting in a--- non-usable internal state) cannot be distinguished from a conflict under assumptions.-solve :: (Foldable t) => Solver -> t Lit -> IO Bool-solve s@Solver{..} assumps = do-  -- PUSH INCREMENTAL ASSUMPTIONS:-  let-    injector :: Lit -> Bool -> IO Bool-    injector _ False = return False-    injector a True = do-      b <- assume s a-      if not b-        then do                 -- conflict analyze-            (confl :: Clause) <- getNthClause reason (lit2var a)-            analyzeFinal s confl True-            pushToStack conflict (negateLit a)-            cancelUntil s 0-            return False-        else do-            confl <- propagate s-            if confl /= NullClause-              then do-                  analyzeFinal s confl True-                  cancelUntil s 0-                  return False-              else return True-  good <- simplifyDB s-  x <- if good then foldrM injector True assumps else return False-  if not x-    then return False-    else do-        setInt rootLevel =<< decisionLevel s-        -- SOLVE:-        nc <- fromIntegral <$> nClauses s-        let-          while :: Double -> Double -> IO Bool-          while nOfConflicts nOfLearnts = do-            status <- search s (floor nOfConflicts) (floor nOfLearnts)-            if status == Bottom-              then while (1.5 * nOfConflicts) (1.1 * nOfLearnts)-              else cancelUntil s 0 >> return (status == LTrue)-        while 100 (nc / 3.0)-------- 'enqueue' is defined in 'Solver'; functions in M114 use 'unsafeEnqueue'----{-# INLINABLE unsafeEnqueue #-}-unsafeEnqueue :: Solver -> Lit -> Clause -> IO ()-unsafeEnqueue s@Solver{..} p from = do-  let v = lit2var p-  setNth assigns v $! if positiveLit p then lTrue else lFalse-  setNth level v =<< decisionLevel s-  setNthClause reason v from     -- NOTE: @from@ might be NULL!-  pushToStack trail p---- __Pre-condition:__ propagation queue is empty-{-# INLINE unsafeAssume #-}-unsafeAssume :: Solver -> Lit -> IO ()-unsafeAssume s@Solver{..} p = do-  pushToStack trailLim =<< sizeOfStack trail-  unsafeEnqueue s p NullClause--{---- | for debug-fromAssigns :: Vec -> IO [Int]-fromAssigns as = zipWith f [1 .. ] . tail <$> asList as-  where-    f n x-      | x == lTrue = n-      | x == lFalse = negate n-      | otherwise = 0---- | for debug-dumpAssignment :: String -> Vec -> IO String-dumpAssignment mes v = (mes ++) . show <$> fromAssigns v--}
− SAT/Solver/Mios/OptionParser.hs
@@ -1,132 +0,0 @@-{-# LANGUAGE Safe #-}--- | command line option parser for mios-module SAT.Solver.Mios.OptionParser-       (-         MiosConfiguration (..)-       , defaultConfiguration-       , MiosProgramOption (..)-       , miosDefaultOption-       , miosOptions-       , miosUsage-       , miosParseOptions-       , miosParseOptionsFromArgs-       , toMiosConf-       )-       where--import System.Console.GetOpt (ArgDescr(..), ArgOrder(..), getOpt, OptDescr(..), usageInfo)-import System.Environment (getArgs)-import SAT.Solver.Mios.Internal (MiosConfiguration (..), defaultConfiguration)---- | configuration swithces-data MiosProgramOption = MiosProgramOption-                     {-                       _targetFile :: Maybe String-                     , _outputFile :: Maybe String-                     , _confVariableDecayRate :: Double-                     , _confClauseDecayRate :: Double---                     , _confRandomDecisionRate :: Int-                     , _confCheckAnswer :: Bool-                     , _confVerbose :: Bool-                     , _confTimeProbe :: Bool-                     , _confStatProbe :: Bool-                     , _confNoAnswer :: Bool-                     , _validateAssignment :: Bool-                     , _displayHelp :: Bool-                     , _displayVersion :: Bool-                     }---- | default option settings-miosDefaultOption :: MiosProgramOption-miosDefaultOption = MiosProgramOption-  {-    _targetFile = Just ""-  , _outputFile = Nothing-  , _confVariableDecayRate = variableDecayRate defaultConfiguration-  , _confClauseDecayRate = clauseDecayRate defaultConfiguration---  , _confRandomDecisionRate = randomDecisionRate defaultConfiguration-  , _confCheckAnswer = False-  , _confVerbose = False-  , _confTimeProbe = False-  , _confStatProbe = collectStats defaultConfiguration-  , _confNoAnswer = False-  , _validateAssignment = False-  , _displayHelp = False-  , _displayVersion = False-  }---- | definition of mios option-miosOptions :: [OptDescr (MiosProgramOption -> MiosProgramOption)]-miosOptions =-  [-    Option ['d'] ["variable-decay-rate"]-    (ReqArg (\v c -> c { _confVariableDecayRate = read v }) (show (_confVariableDecayRate miosDefaultOption)))-    "[solver] variable activity decay rate (0.0 - 1.0)"-  , Option ['c'] ["clause-decay-rate"]-    (ReqArg (\v c -> c { _confClauseDecayRate = read v }) (show (_confClauseDecayRate miosDefaultOption)))-    "[solver] clause activity decay rate (0.0 - 1.0)"---  , Option ['r'] ["random-decision-rate"]---    (ReqArg (\v c -> c { _confRandomDecisionRate = read v }) (show (_confRandomDecisionRate miosDefaultOption)))---    "[solver] random selection rate (0 - 1000)"-  , Option [':'] ["validate-assignment"]-    (NoArg (\c -> c { _validateAssignment = True }))-    "[solver] read an assignment from STDIN and validate it"-  , Option [] ["validate"]-    (NoArg (\c -> c { _confCheckAnswer = True }))-    "[solver] self-check the (satisfied) answer"-  , Option ['o'] ["output"]-    (ReqArg (\v c -> c { _outputFile = Just v })"file")-    "[option] filename to store the result"-{--  , Option [] ["stdin"]-    (NoArg (\c -> c { _targetFile = Nothing }))-    "[option] read a CNF from STDIN instead of a file"--}-  , Option ['v'] ["verbose"]-    (NoArg (\c -> c { _confVerbose = True }))-    "[option] display misc information"-  , Option ['X'] ["hide-solution"]-    (NoArg (\c -> c { _confNoAnswer = True }))-    "[option] hide the solution"-  , Option [] ["time"]-    (NoArg (\c -> c { _confTimeProbe = True }))-    "[option] display execution time"-  , Option [] ["stat"]-    (NoArg (\c -> c { _confStatProbe = True }))-    "[option] display statistics information"-  , Option ['h'] ["help"]-    (NoArg (\c -> c { _displayHelp = True }))-    "[misc] display this help message"-  , Option [] ["version"]-    (NoArg (\c -> c { _displayVersion = True }))-    "[misc] display program ID"-  ]---- | generates help message-miosUsage :: String -> String-miosUsage mes = usageInfo mes miosOptions---- | builds "MiosProgramOption" from string given as command option-miosParseOptions :: String -> [String] -> IO MiosProgramOption-miosParseOptions mes argv =-    case getOpt Permute miosOptions argv of-      (o, [], []) -> do-        return $ foldl (flip id) miosDefaultOption o-      (o, (n:_), []) -> do-        let conf = foldl (flip id) miosDefaultOption o-        return $ conf { _targetFile = Just n }-      (_, _, errs) -> ioError (userError (concat errs ++ miosUsage mes))---- | builds "MiosProgramOption" from a String-miosParseOptionsFromArgs :: String -> IO MiosProgramOption-miosParseOptionsFromArgs mes = miosParseOptions mes =<< getArgs---- | converts "MiosProgramOption" into "SIHConfiguration"-toMiosConf :: MiosProgramOption -> MiosConfiguration-toMiosConf opts = MiosConfiguration-                 {-                   variableDecayRate = _confVariableDecayRate opts-                 , clauseDecayRate = _confClauseDecayRate opts---                 , randomDecisionRate = _confRandomDecisionRate opts-                 , collectStats = _confStatProbe opts-                 }
− SAT/Solver/Mios/Solver.hs
@@ -1,554 +0,0 @@--- | This is a part of MIOS-{-# LANGUAGE-    BangPatterns-  , RecordWildCards-  , ScopedTypeVariables-  , TupleSections-  , ViewPatterns-  #-}-{-# LANGUAGE Safe #-}--module SAT.Solver.Mios.Solver-       (-         -- * Solver-         Solver (..)-       , newSolver-         -- * Misc Accessors-       , nAssigns-       , nClauses-       , nLearnts-       , decisionLevel-       , valueVar-       , valueLit-       , locked-       , VarHeap-         -- * State Modifiers-       , addClause-       , enqueue-       , assume-       , cancelUntil-       , getModel-         -- * Activities-       , claBumpActivity-       , claDecayActivity-       , varBumpActivity-       , varDecayActivity-         -- * Stats-       , StatIndex (..)-       , incrementStat-       , getStats-       )-        where--import Control.Monad ((<=<), forM_, unless, when)-import SAT.Solver.Mios.Types-import SAT.Solver.Mios.Internal-import SAT.Solver.Mios.Clause-import SAT.Solver.Mios.ClauseManager---- | __Fig. 2.(p.9)__ Internal State of the solver-data Solver = Solver-              {-                -- Public Interface-                model      :: !VecBool           -- ^ If found, this vector has the model-              , conflict   :: !Stack             -- ^ set of literals in the case of conflicts-                -- Clause Database-              , clauses    :: !ClauseExtManager  -- ^ List of problem constraints.-              , learnts    :: !ClauseExtManager  -- ^ List of learnt clauses.-              , watches    :: !WatcherList       -- ^ a list of constraint wathing 'p', literal-indexed-                -- Assignment Management-              , assigns    :: !Vec               -- ^ The current assignments indexed on variables; var-indexed-              , phases     :: !Vec               -- ^ The last assignments indexed on variables; var-indexed-              , trail      :: !Stack             -- ^ List of assignments in chronological order; var-indexed-              , trailLim   :: !Stack             -- ^ Separator indices for different decision levels in 'trail'.-              , qHead      :: !IntSingleton      -- ^ 'trail' is divided at qHead; assignments and queue-              , reason     :: !ClauseVector      -- ^ For each variable, the constraint that implied its value; var-indexed-              , level      :: !Vec               -- ^ For each variable, the decision level it was assigned; var-indexed-                -- Variable Order-              , activities :: !VecDouble         -- ^ Heuristic measurement of the activity of a variable; var-indexed-              , order      :: !VarHeap           -- ^ Keeps track of the dynamic variable order.-                -- Configuration-              , config     :: !MiosConfiguration -- ^ search paramerters-              , nVars      :: !Int               -- ^ number of variables-              , claInc     :: !DoubleSingleton   -- ^ Clause activity increment amount to bump with.---            , varDecay   :: !DoubleSingleton   -- ^ used to set 'varInc'-              , varInc     :: !DoubleSingleton   -- ^ Variable activity increment amount to bump with.-              , rootLevel  :: !IntSingleton      -- ^ Separates incremental and search assumptions.-                -- Working Memory-              , ok         :: !BoolSingleton     -- ^ return value holder-              , an'seen    :: !Vec               -- ^ scratch var for 'analyze'; var-indexed-              , an'toClear :: !Stack             -- ^ ditto-              , an'stack   :: !Stack             -- ^ ditto-              , pr'seen    :: !Vec               -- ^ used in propagate-              , lbd'seen   :: !Vec               -- ^ used in lbd computation-              , lbd'key    :: !IntSingleton      -- ^ used in lbd computation-              , litsLearnt :: !Stack             -- ^ used to create a learnt clause-              , lastDL     :: !Stack             -- ^ last decision level used in analyze-              , stats      :: !Vec               -- ^ statistics information holder-              }---- | returns an everything-is-initialized solver from the arguments-newSolver :: MiosConfiguration -> CNFDescription -> IO Solver-newSolver conf (CNFDescription nv nc _) = do-  Solver-    -- Public Interface-    <$> newVecBool nv False                           -- model-    <*> newStack nv                                   -- coflict-    -- Clause Database-    <*> newManager nc                                 -- clauses-    <*> newManager nc                                 -- learnts-    <*> newWatcherList nv 2                           -- watches-    -- Assignment Management-    <*> newVecWith (nv + 1) lBottom                   -- assigns-    <*> newVecWith (nv + 1) lBottom                   -- phases-    <*> newStack nv                                   -- trail-    <*> newStack nv                                   -- trailLim-    <*> newInt 0                                      -- qHead-    <*> newClauseVector (nv + 1)                      -- reason-    <*> newVecWith (nv + 1) (-1)                      -- level-    -- Variable Order-    <*> newVecDouble (nv + 1) 0                       -- activities-    <*> newVarHeap nv                                 -- order-    -- Configuration-    <*> return conf                                   -- config-    <*> return nv                                     -- nVars-    <*> newDouble 1.0                                 -- claInc---  <*> newDouble (variableDecayRate conf)            -- varDecay-    <*> newDouble 1.0                                 -- varInc-    <*> newInt 0                                      -- rootLevel-    -- Working Memory-    <*> newBool True                                  -- ok-    <*> newVec (nv + 1)                               -- an'seen-    <*> newStack nv                                   -- an'toClear-    <*> newStack nv                                   -- an'stack-    <*> newVecWith (nv + 1) (-1)                      -- pr'seen-    <*> newVec nv                                     -- lbd'seen-    <*> newInt 0                                      -- lbd'key-    <*> newStack nv                                   -- litsLearnt-    <*> newStack nv                                   -- lastDL-    <*> newVec (1 + fromEnum (maxBound :: StatIndex)) -- stats------------------------------------------------------------------------------------- Accessors---- | returns the number of current assigments-{-# INLINE nAssigns #-}-nAssigns :: Solver -> IO Int-nAssigns = sizeOfStack . trail---- | returns the number of constraints (clauses)-{-# INLINE nClauses #-}-nClauses  :: Solver -> IO Int-nClauses = numberOfClauses . clauses---- | returns the number of learnt clauses-{-# INLINE nLearnts #-}-nLearnts :: Solver -> IO Int-nLearnts = numberOfClauses . learnts---- | return the model as a list of literal-getModel :: Solver -> IO [Int]-getModel s = zipWith (\n b -> if b then n else negate n) [1 .. ] <$> asList (model s)---- | returns the current decision level-{-# INLINE decisionLevel #-}-decisionLevel :: Solver -> IO Int-decisionLevel Solver{..} = sizeOfStack trailLim---- | returns the assignment (:: 'LiftedBool' = @[-1, 0, -1]@) from 'Var'-{-# INLINE valueVar #-}-valueVar :: Solver -> Var -> IO Int-valueVar s !x = getNth (assigns s) x---- | returns the assignment (:: 'LiftedBool' = @[-1, 0, -1]@) from 'Lit'-{-# INLINE valueLit #-}-valueLit :: Solver -> Lit -> IO Int -- FIXME: LiftedBool-valueLit Solver{..} !p = if positiveLit p then getNth assigns (lit2var p) else negate <$> getNth assigns (lit2var p)---- | __Fig. 7. (p.11)__--- returns @True@ if the clause is locked (used as a reason). __Learnt clauses only__-{-# INLINE locked #-}-locked :: Solver -> Clause -> IO Bool-locked Solver{..} c@Clause{..} =  (c ==) <$> (getNthClause reason . lit2var =<< getNth lits 1)---- | stats-data StatIndex =-    NumOfBackjump-  | NumOfRestart-  deriving (Bounded, Enum, Eq, Ord, Read, Show)---- | increments a stat data corresponding to 'StatIndex'-incrementStat :: Solver -> StatIndex -> Int -> IO ()-incrementStat (config -> collectStats -> False) _ _ = return ()-incrementStat (stats -> v) (fromEnum -> i) k = modifyNth v (+ k) i---- | returns the statistics as list-getStats :: Solver -> IO [(StatIndex, Int)]-getStats (config -> collectStats -> False) = return []-getStats (stats -> v) = mapM (\i -> (i, ) <$> getNth v (fromEnum i)) [minBound .. maxBound :: StatIndex]---------------------------------------------------------------------------------- State Modifiers---- | returns @False@ if a conflict has occured.--- This function is called only before the solving phase to register the given clauses.-{-# INLINABLE addClause #-}-addClause :: Solver -> Vec -> IO Bool-addClause s@Solver{..} vecLits = do-  result <- clauseNew s vecLits False-  case result of-   (False, _) -> return False   -- Conflict occured-   (True, c)  -> do-     unless (c == NullClause) $ pushClause clauses c-     return True                -- No conflict---- | __Fig. 8. (p.12)__ create a new clause and adds it to watcher lists--- Constructor function for clauses. Returns @False@ if top-level conflict is determined.--- @outClause@ may be set to Null if the new clause is already satisfied under the current--- top-level assignment.------ __Post-condition:__ @ps@ is cleared. For learnt clauses, all--- literals will be false except @lits[0]@ (this by design of the 'analyze' method).--- For the propagation to work, the second watch must be put on the literal which will--- first be unbound by backtracking. (Note that none of the learnt-clause specific things--- needs to done for a user defined contraint type.)-{-# INLINABLE clauseNew #-}-clauseNew :: Solver -> Vec -> Bool -> IO (Bool, Clause)-clauseNew s@Solver{..} ps isLearnt = do-  -- now ps[0] is the number of living literals-  exit <- do-    let-      handle :: Int -> Int -> Int -> IO Bool-      handle j l n      -- removes duplicates, but returns @True@ if this clause is satisfied-        | j > n = return False-        | otherwise = do-            y <- getNth ps j-            case () of-             _ | y == l -> do             -- finds a duplicate-                   swapBetween ps j n-                   modifyNth ps (subtract 1) 0-                   handle j l (n - 1)-             _ | - y == l -> setNth ps 0 0 >> return True -- p and negateLit p occurs in ps-             _ -> handle (j + 1) l n-      loopForLearnt :: Int -> IO Bool-      loopForLearnt i = do-        n <- getNth ps 0-        if n < i-          then return False-          else do-              l <- getNth ps i-              sat <- handle (i + 1) l n-              if sat-                then return True-                else loopForLearnt $ i + 1-      loop :: Int -> IO Bool-      loop i = do-        n <- getNth ps 0-        if n < i-          then return False-          else do-              l <- getNth ps i     -- check the i-th literal's satisfiability-              sat <- valueLit s l                                      -- any literal in ps is true-              case sat of-               1  -> setNth ps 0 0 >> return True-               -1 -> do-                 swapBetween ps i n-                 modifyNth ps (subtract 1) 0-                 loop i-               _ -> do-                 sat' <- handle (i + 1) l n-                 if sat'-                   then return True-                   else loop $ i + 1-    if isLearnt then loopForLearnt 1 else loop 1-  k <- getNth ps 0-  case k of-   0 -> return (exit, NullClause)-   1 -> do-     l <- getNth ps 1-     (, NullClause) <$> enqueue s l NullClause-   _ -> do-     -- allocate clause:-     c <- newClauseFromVec isLearnt ps-     let vec = asVec c-     when isLearnt $ do-       -- Pick a second literal to watch:-       let-         findMax :: Int -> Int -> Int -> IO Int-         findMax ((< k) -> False) j _ = return j-         findMax i j val = do-           v' <- lit2var <$> getNth vec i-           a <- getNth assigns v'-           b <- getNth level v'-           if (a /= lBottom) && (val < b)-             then findMax (i + 1) i b-             else findMax (i + 1) j val-       -- Let @max_i@ be the index of the literal with highest decision level-       max_i <- findMax 0 0 0-       swapBetween vec 1 max_i-       -- check literals occurences-       -- x <- asList c-       -- unless (length x == length (nub x)) $ error "new clause contains a element doubly"-       -- Bumping:-       claBumpActivity s c -- newly learnt clauses should be considered active-       forM_ [0 .. k -1] $ varBumpActivity s . lit2var <=< getNth vec -- variables in conflict clauses are bumped-     -- Add clause to watcher lists:-     l0 <- negateLit <$> getNth vec 0-     pushClauseWithKey (getNthWatcher watches l0) c 0-     l1 <- negateLit <$> getNth vec 1-     pushClauseWithKey (getNthWatcher watches l1) c 0-     return (True, c)---- | __Fig. 9 (p.14)__--- Puts a new fact on the propagation queue, as well as immediately updating the variable's value--- in the assignment vector. If a conflict arises, @False@ is returned and the propagation queue is--- cleared. The parameter 'from' contains a reference to the constraint from which 'p' was--- propagated (defaults to @Nothing@ if omitted).-{-# INLINABLE enqueue #-}-enqueue :: Solver -> Lit -> Clause -> IO Bool-enqueue s@Solver{..} p from = do-  -- putStrLn . ("ssigns " ++) . show . map lit2int =<< asList trail-  -- putStrLn =<< dump ("enqueue " ++ show (lit2int p) ++ " ") from-  let signumP = if positiveLit p then lTrue else lFalse-  let v = lit2var p-  val <- valueVar s v-  if val /= lBottom-    then do -- Existing consistent assignment -- don't enqueue-        return $ val == signumP-    else do-        -- New fact, store it-        setNth assigns v $! signumP-        setNth level v =<< decisionLevel s-        setNthClause reason v from     -- NOTE: @from@ might be NULL!-        pushToStack trail p-        return True---- | __Fig. 12 (p.17)__--- returns @False@ if immediate conflict.------ __Pre-condition:__ propagation queue is empty-{-# INLINE assume #-}-assume :: Solver -> Lit -> IO Bool-assume s@Solver{..} p = do-  pushToStack trailLim =<< sizeOfStack trail-  enqueue s p NullClause---- | #M22: Revert to the states at given level (keeping all assignment at 'level' but not beyond).-{-# INLINABLE cancelUntil #-}-cancelUntil :: Solver -> Int -> IO ()-cancelUntil s@Solver{..} lvl = do-  dl <- decisionLevel s-  when (lvl < dl) $ do-    let tr = asVec trail-    let tl = asVec trailLim-    lim <- getNth tl lvl-    ts <- sizeOfStack trail-    ls <- sizeOfStack trailLim-    let-      loopOnTrail :: Int -> IO ()-      loopOnTrail ((lim <=) -> False) = return ()-      loopOnTrail c = do-        x <- lit2var <$> getNth tr c-        setNth phases x =<< getNth assigns x-        setNth assigns x lBottom-        -- #reason to set reason Null-        -- if we don't clear @reason[x] :: Clause@ here, @reason[x]@ remains as locked.-        -- This means we can't reduce it from clause DB and affects the performance.-        setNthClause reason x NullClause -- 'analyze` uses reason without checking assigns-        -- FIXME: #polarity https://github.com/shnarazk/minisat/blosb/master/core/Solver.cc#L212-        undo s x-        -- insertHeap s x              -- insertVerOrder-        loopOnTrail $ c - 1-    loopOnTrail $ ts - 1-    shrinkStack trail (ts - lim)-    shrinkStack trailLim (ls - lvl)-    setInt qHead =<< sizeOfStack trail---------------------------------------------------------------------------------- VarOrder---- | Interfate to select a decision var based on variable activity.-instance VarOrder Solver where-  -- | __Fig. 6. (p.10)__-  -- Creates a new SAT variable in the solver.-  newVar _ = return 0-    -- i <- nVars s-    -- Version 0.4:: push watches =<< newVec      -- push'-    -- Version 0.4:: push watches =<< newVec      -- push'-    -- push undos =<< newVec        -- push'-    -- push reason NullClause       -- push'-    -- push assigns lBottom-    -- push level (-1)-    -- push activities (0.0 :: Double)-    -- newVar order-    -- growQueueSized (i + 1) propQ-    -- return i-  {-# SPECIALIZE INLINE update :: Solver -> Var -> IO () #-}-  update = increaseHeap-  {-# SPECIALIZE INLINE undo :: Solver -> Var -> IO () #-}-  undo s v = inHeap s v >>= (`unless` insertHeap s v)-  {-# SPECIALIZE INLINE select :: Solver -> IO Var #-}-  select s = do-    let-      asg = assigns s-      -- | returns the most active var (heap-based implementation)-      loop :: IO Var-      loop = do-        n <- numElementsInHeap s-        if n == 0-          then return 0-          else do-              v <- getHeapRoot s-              x <- getNth asg v-              if x == lBottom then return v else loop-    loop---------------------------------------------------------------------------------- Activities---- | __Fig. 14 (p.19)__ Bumping of clause activity-{-# INLINE varBumpActivity #-}-varBumpActivity :: Solver -> Var -> IO ()-varBumpActivity s@Solver{..} !x = do-  !a <- (+) <$> getNthDouble x activities <*> getDouble varInc-  if 1e100 < a-    then varRescaleActivity s-    else setNthDouble x activities a-  update s x---- | __Fig. 14 (p.19)__-{-# INLINE varDecayActivity #-}-varDecayActivity :: Solver -> IO ()-varDecayActivity Solver{..} = modifyDouble varInc (/ variableDecayRate config)--- varDecayActivity Solver{..} = modifyDouble varInc . (flip (/)) =<< getDouble varDecay---- | __Fig. 14 (p.19)__-{-# INLINE varRescaleActivity #-}-varRescaleActivity :: Solver -> IO ()-varRescaleActivity Solver{..} = do-  forM_ [1 .. nVars] $ \i -> modifyNthDouble i activities (* 1e-100)-  modifyDouble varInc (* 1e-100)---- | __Fig. 14 (p.19)__-{-# INLINE claBumpActivity #-}-claBumpActivity :: Solver -> Clause -> IO ()-claBumpActivity s@Solver{..} Clause{..} = do-  a <- (+) <$> getDouble activity <*> getDouble claInc-  if 1e100 < a-    then claRescaleActivity s-    else setDouble activity a---- | __Fig. 14 (p.19)__-{-# INLINE claDecayActivity #-}-claDecayActivity :: Solver -> IO ()-claDecayActivity Solver{..} = modifyDouble claInc (/ clauseDecayRate config)---- | __Fig. 14 (p.19)__-{-# INLINE claRescaleActivity #-}-claRescaleActivity :: Solver -> IO ()-claRescaleActivity Solver{..} = do-  vec <- getClauseVector learnts-  n <- numberOfClauses learnts-  let-    loopOnVector :: Int -> IO ()-    loopOnVector ((< n) -> False) = return ()-    loopOnVector i = do-      c <- getNthClause vec i-      modifyDouble (activity c) (* 1e-20) -- not 1e-100-      loopOnVector $ i + 1-  loopOnVector 0-  modifyDouble claInc (* 1e-20)           -- not 1e-100---------------------------------------------------------------------------------- VarHeap---- | 'VarHeap' is a heap tree built from two 'Vec'--- This implementation is identical wtih that in Minisat-1.14--- Note: the zero-th element of @heap@ is used for holding the number of elements--- Note: VarHeap itself is not a @VarOrder@, because it requires a pointer to solver-data VarHeap = VarHeap-                {-                  heap :: Vec -- order to var-                , idxs :: Vec -- var to order (index)-                }--newVarHeap :: Int -> IO VarHeap-newVarHeap n = VarHeap <$> newSizedVecIntFromList lst <*> newSizedVecIntFromList lst-  where-    lst = [1 .. n]--{-# INLINE numElementsInHeap #-}-numElementsInHeap :: Solver -> IO Int-numElementsInHeap (order -> heap -> h) = getNth h 0--{-# INLINE inHeap #-}-inHeap :: Solver -> Var -> IO Bool-inHeap (order -> idxs -> at) n = (/= 0) <$> getNth at n--{-# INLINE increaseHeap #-}-increaseHeap :: Solver -> Int -> IO ()-increaseHeap s@(order -> idxs -> at) n = inHeap s n >>= (`when` (percolateUp s =<< getNth at n))--{-# INLINABLE percolateUp #-}-percolateUp :: Solver -> Int -> IO ()-percolateUp Solver{..} start = do-  let VarHeap to at = order-  v <- getNth to start-  ac <- getNthDouble v activities-  let-    loop :: Int -> IO ()-    loop i = do-      let iP = div i 2          -- parent-      if iP == 0-        then setNth to i v >> setNth at v i -- end-        else do-            v' <- getNth to iP-            acP <- getNthDouble v' activities-            if ac > acP-              then setNth to i v' >> setNth at v' i >> loop iP -- loop-              else setNth to i v >> setNth at v i              -- end-  loop start--{-# INLINABLE percolateDown #-}-percolateDown :: Solver -> Int -> IO ()-percolateDown Solver{..} start = do-  let (VarHeap to at) = order-  n <- getNth to 0-  v <- getNth to start-  ac <- getNthDouble v activities-  let-    loop :: Int -> IO ()-    loop i = do-      let iL = 2 * i            -- left-      if iL <= n-        then do-            let iR = iL + 1     -- right-            l <- getNth to iL-            r <- getNth to iR-            acL <- getNthDouble l activities-            acR <- getNthDouble r activities-            let (ci, child, ac') = if iR <= n && acL < acR then (iR, r, acR) else (iL, l, acL)-            if ac' > ac-              then setNth to i child >> setNth at child i >> loop ci-              else setNth to i v >> setNth at v i -- end-        else setNth to i v >> setNth at v i       -- end-  loop start--{-# INLINE insertHeap #-}-insertHeap :: Solver -> Var -> IO ()-insertHeap s@(order -> VarHeap to at) v = do-  n <- (1 +) <$> getNth to 0-  setNth at v n-  setNth to n v-  setNth to 0 n-  percolateUp s n---- | renamed from 'getmin'-{-# INLINE getHeapRoot #-}-getHeapRoot :: Solver -> IO Int-getHeapRoot s@(order -> VarHeap to at) = do-  r <- getNth to 1-  l <- getNth to =<< getNth to 0 -- the last element's value-  setNth to 1 l-  setNth at l 1-  setNth at r 0-  modifyNth to (subtract 1) 0 -- pop-  n <- getNth to 0-  when (1 < n) $ percolateDown s 1-  return r
− SAT/Solver/Mios/Types.hs
@@ -1,269 +0,0 @@--- | 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)
− SAT/Solver/Mios/Validator.hs
@@ -1,47 +0,0 @@--- | validate an assignment-{-# LANGUAGE-    ViewPatterns-  #-}-{-# LANGUAGE Safe #-}-module SAT.Solver.Mios.Validator-       (-         validate-       )-       where--import Data.Foldable (toList)-import SAT.Solver.Mios.Types-import SAT.Solver.Mios.Clause-import SAT.Solver.Mios.ClauseManager-import SAT.Solver.Mios.Solver---- | validates the assignment even if the implementation of 'Solver' is wrong; we re-implement some functions here.-validate :: Traversable t => Solver -> t Int -> IO Bool-validate s (toList -> map int2lit -> lst) = do-  assignment <- newVec $ 1 + nVars s-  vec <- getClauseVector (clauses s)-  nc <- numberOfClauses (clauses s)-  let-    inject :: Lit -> IO ()-    inject l = setNth assignment (lit2var l) $ if positiveLit l then lTrue else lFalse-    -- return True if the literal is satisfied under the assignment-    satisfied :: Lit -> IO Bool-    satisfied l-      | positiveLit l = (lTrue ==) <$> getNth assignment (lit2var l)-      | otherwise     = (lFalse ==) <$> getNth assignment (lit2var l)-    -- return True is any literal in the given list-    satAny :: [Lit] -> IO Bool-    satAny [] = return False-    satAny (l:ls) = do-      sat' <- satisfied l-      if sat' then return True else satAny ls-    -- traverse all clauses in 'clauses'-    loopOnVector :: Int -> IO Bool-    loopOnVector ((< nc) -> False) = return True-    loopOnVector i = do-      c <- getNthClause vec i-      sat' <- satAny =<< asList c-      if sat' then loopOnVector (i + 1) else return False-  if null lst-    then error "validator got an empty assignment."-    else mapM_ inject lst >> loopOnVector 0
− SAT/Util/BoolExp.hs
@@ -1,244 +0,0 @@-{-# LANGUAGE BangPatterns, FlexibleInstances, ViewPatterns, UndecidableInstances #-}-{-# LANGUAGE Safe #-}---- | Boolean Expression module to build CNF from arbitrary expressions--- Tseitin translation: http://en.wikipedia.org/wiki/Tseitin_transformation-module SAT.Util.BoolExp-       (-         -- * Class & Type-         BoolComponent (..)-       , BoolForm (..)-         -- * Expression contructors-       , (-|-)-       , (-&-)-       , (-=-)-       , (-!-)-       , (->-)-       , neg-         -- * List Operation-       , disjunctionOf-       , (-|||-)-       , conjunctionOf-       , (-&&&-)-         -- * Convert function-       , asList-       , asList_-       , asLatex-       , asLatex_-       , numberOfVariables-       , numberOfClauses-       , tseitinBase-       )-       where--import Data.List (foldl', intercalate)---- | the start index for the generated variables by Tseitin encoding-tseitinBase :: Int-tseitinBase = 1600000--data L = L Int---- | class of objects that can be interpeted as a bool expression-class BoolComponent a where-  toBF :: a -> BoolForm   -- lift to BoolForm---- | CNF expression-data BoolForm = Cnf (Int, Int) [[Int]]-    deriving (Eq, Show)--instance BoolComponent Int where-  toBF a = Cnf (abs a, max tseitinBase (abs a)) [[a]]--instance BoolComponent L where-  toBF (L a) = Cnf (abs a, max tseitinBase (abs a)) [[a]]--instance BoolComponent [Char] where-  toBF (read -> a) = Cnf (abs a, max tseitinBase (abs a)) [[a]]--instance BoolComponent BoolForm where-  toBF = id---- | returns the number of variables in the 'BoolForm'-numberOfVariables :: BoolForm -> Int-numberOfVariables (Cnf (a, b) _) = a + b - tseitinBase---- | returns the number of clauses in the 'BoolForm'-numberOfClauses :: BoolForm -> Int-numberOfClauses (Cnf _ l) = length l--boolFormTrue = Cnf (-1, 1) []-boolFormFalse = Cnf (-1, -1) []--instance BoolComponent Bool where-  toBF True = boolFormTrue-  toBF False = boolFormFalse--isTrue :: BoolForm -> Bool-isTrue = (== boolFormTrue)--isFalse :: BoolForm -> Bool-isFalse = (== boolFormFalse)---- | return a 'clause' list only if it contains some real clause (not a literal)-clausesOf :: BoolForm -> [[Int]]-clausesOf cnf@(Cnf _ [[]]) = []-clausesOf cnf@(Cnf _ [[x]]) = []-clausesOf cnf@(Cnf _ l) = l--maxRank :: BoolForm -> Int-maxRank (Cnf (n, _) _) = n---- | returns the number of valiable used as the output of this expression.--- and returns itself it the expression is a literal.--- Otherwise the number is a integer larger than 'tseitinBase'.--- Therefore @1 + max tseitinBase the-returned-value@ is the next literal variable for future.-tseitinNumber :: BoolForm -> Int-tseitinNumber (Cnf (m, n) [[x]]) = x-tseitinNumber (Cnf (_, n) _) = n--renumber :: Int -> BoolForm -> (BoolForm, Int)-renumber base (Cnf (m, n) l)-  | l == [] = (Cnf (m, n) l, 0)-  | tseitinBase < base = (Cnf (m, n') l', n')-  | otherwise = (Cnf (n', tseitinBase) l', n')-  where-    l' = map (map f) l-    n' = maximum $ map maximum l'-    offset = base - tseitinBase - 1-    f x = if abs x < tseitinBase then x else signum x * (abs x + offset)--instance Ord BoolForm where-  compare (Cnf _ a) (Cnf _ b) = compare a b---- | disjunction constructor------ >>> asList $ "3" -|- "4"--- [[3,4,-5],[-3,5],[-4,5]]------ >>> asList (("3" -|- "4") -|- "-1")--- [[3,4,-5],[-3,5],[-4,5],[5,-1,-6],[-5,6],[1,6]]----(-|-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm-(toBF -> e1) -|- (toBF -> e2')-  | isTrue e1 || isTrue e2' = boolFormTrue-  | isFalse e1 && isFalse e2' = boolFormFalse-  | isFalse e1 = e2'-  | isFalse e2' = e1-  | otherwise = Cnf (m, c) $ clausesOf e1 ++ clausesOf e2 ++ [[a, b, - c], [- a, c], [- b, c]]-  where-    a = tseitinNumber e1-    (e2, b) = renumber (1 + max tseitinBase a) e2'-    m = max (maxRank e1) (maxRank e2)-    c = 1 + max tseitinBase (max a b)---- | conjunction constructor------ >>> asList $ "3" -&- "-2"--- [[-3,2,4],[3,-4],[-2,-4]]------ >>> asList $ "3" -|- ("1" -&- "2")--- [[-1,-2,4],[1,-4],[2,-4],[3,4,-5],[-3,5],[-4,5]]----(-&-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm-(toBF -> e1) -&- (toBF -> e2')-  | isTrue e1 && isTrue e2' = boolFormTrue-  | isFalse e1 || isFalse e2' = boolFormFalse-  | isTrue e1 = e2'-  | isTrue e2' = e1-  | otherwise = Cnf (m, c) $ clausesOf e1 ++ clausesOf e2 ++ [[- a, - b, c], [a, - c], [b, - c]]-  where-    a = tseitinNumber e1-    (e2, b) = renumber (1 + max tseitinBase a) e2'-    m = max (maxRank e1) (maxRank e2)-    c = 1 + max tseitinBase (max a b)---- | negate a form------ >>> asList $ neg ("1" -|- "2")--- [[1,2,-3],[-1,3],[-2,3],[-3,-4],[3,4]]-neg :: (BoolComponent a) => a -> BoolForm-neg (toBF -> e) =-  Cnf (m, c) $ clausesOf e ++ [[- a, - c], [a, c]]-  where-    a = tseitinNumber e-    m = maxRank e-    c = 1 + max tseitinBase a---- | equal on BoolForm-(-=-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm-(toBF -> e1) -=- (toBF -> e2) = (e1 -&- e2) -|- (neg e1 -&- neg e2)---- | negation on BoolForm-(-!-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm-(toBF -> e1) -!- (toBF -> e2) = (neg e1 -&- e2) -|- (e1 -&- neg e2)---- | implication as a short cut------ >>> asList ("1" ->- "2")--- [[-1,-3],[1,3],[3,2,-4],[-3,4],[-2,4]]-(->-) :: (BoolComponent a, BoolComponent b) => a -> b -> BoolForm-(toBF -> a) ->- (toBF -> b) = (neg a) -|- b---- | merge [BoolForm] by '(-|-)'-disjunctionOf :: [BoolForm] -> BoolForm-disjunctionOf [] = boolFormFalse-disjunctionOf (x:l) = foldl' (-|-) x l---- | an alias of 'disjunctionOf'-(-|||-) = disjunctionOf---- | merge [BoolForm] by '(-&-)'-conjunctionOf :: [BoolForm] -> BoolForm-conjunctionOf [] = boolFormTrue-conjunctionOf (x:l) = foldl' (-&-) x l---- | an alias of 'conjunctionOf'-(-&&&-) = conjunctionOf---- | converts a BoolForm to "[[Int]]"-asList_ :: BoolForm -> [[Int]]-asList_ cnf@(Cnf (m,_) _)-  | isTrue cnf = []-  | isFalse cnf = [[]]-  | otherwise = l'-  where-    (Cnf _ l', _) = renumber (m + 1) cnf---- | converts a *satisfied* BoolForm to "[[Int]]"-asList :: BoolForm -> [[Int]]-asList cnf@(Cnf (m,n) l)-  | isTrue cnf = []-  | isFalse cnf = [[]]-  | n <= tseitinBase = l-  | otherwise = [m'] : l'-  where-    (Cnf (m', _) l', _) = renumber (m + 1) cnf---- | make latex string from CNF, using 'asList_'------ >>> asLatex $ "3" -|- "4"--- "\\begin{displaymath}\n( x_{3} \\vee x_{4} )\n\\end{displaymath}\n"----asLatex_ :: BoolForm -> String-asLatex_ b = beg ++ s ++ end-  where-    beg = "\\begin{displaymath}\n"-    end = "\n\\end{displaymath}\n"-    s = intercalate " \\wedge " [ makeClause c | c <- asList_ b]-    makeClause c = "(" ++ intercalate "\\vee" [makeLiteral l | l <- c] ++ ")"-    makeLiteral l-      | 0 < l = " x_{" ++ show l ++ "} "-      | otherwise = " \\neg " ++ "x_{" ++ show (negate l) ++ "} "---- | make latex string from CNF, using 'asList'-asLatex :: BoolForm -> String-asLatex b = beg ++ s ++ end-  where-    beg = "\\begin{displaymath}\n"-    end = "\n\\end{displaymath}\n"-    s = intercalate " \\wedge " [ makeClause c | c <- asList b]-    makeClause c = "(" ++ intercalate "\\vee" [makeLiteral l | l <- c] ++ ")"-    makeLiteral l-      | 0 < l = " x_{" ++ show l ++ "} "-      | otherwise = " \\neg " ++ "x_{" ++ show (negate l) ++ "} "
− SAT/Util/CNFIO.hs
@@ -1,31 +0,0 @@-{-# LANGUAGE Safe #-}---- | Read/Write a CNF file only with ghc standard libraries-module SAT.Util.CNFIO-       (-         -- * Input-         fromFile-       , clauseListFromFile-       , fromMinisatOutput-       , clauseListFromMinisatOutput-         -- * Output-       , toFile-       , toCNFString-       , asCNFString-       , asCNFString_-         -- * Bool Operation-       , module SAT.Util.BoolExp-       )-       where-import SAT.Util.CNFIO.Reader-import SAT.Util.CNFIO.Writer-import SAT.Util.CNFIO.MinisatReader-import SAT.Util.BoolExp---- | String from BoolFrom-asCNFString :: BoolForm -> String-asCNFString = toCNFString . asList---- | String from BoolFrom-asCNFString_ :: BoolForm -> String-asCNFString_ = toCNFString . asList_
− SAT/Util/CNFIO/MinisatReader.hs
@@ -1,73 +0,0 @@-{-# LANGUAGE Safe #-}---- | Read an output file of minisat-module SAT.Util.CNFIO.MinisatReader-       (-         -- * Interface-         fromMinisatOutput-       , clauseListFromMinisatOutput-       )-       where--- import Control.Applicative ((<$>), (<*>), (<*), (*>))-import Data.Char-import Text.ParserCombinators.ReadP---- parser--- |parse a non-signed integer-{-# INLINE pint #-}-pint = do-  n <- munch isDigit-  return (read n :: Int)--{-# INLINE mint #-}-mint = do-  char '-'-  n <- munch isDigit-  return (- (read n::Int))---- |parse a (signed) integer-{-# INLINE int #-}-int = mint <++ pint---- |return integer list that terminates at zero-{-# INLINE seqNums #-}-seqNums = do-  skipSpaces-  x <- int-  skipSpaces-  if (x == 0) then return []  else (x :) <$> seqNums---- |top level interface for parsing CNF-{-# INLINE parseMinisatOutput #-}-parseMinisatOutput :: ReadP ((Int, Int), [Int])-parseMinisatOutput = do-  string "SAT"-  skipSpaces-  l <- seqNums-  return ((length l,0), l)---- |read a minisat output:--- ((numbefOfVariables, 0), [Literal])------ >>>  fromFile "result"--- ((3, 0), [1, -2, 3])----{-# INLINE fromMinisatOutput #-}-fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))-fromMinisatOutput f = do-  c <- readFile f-  case readP_to_S parseMinisatOutput c of-    [(a, _)] -> return $ Just a-    _ -> return Nothing---- | return clauses as [[Int]] from 'file'------ >>> clauseListFromMinisatOutput "result"--- [1,-2,3]----clauseListFromMinisatOutput :: FilePath -> IO [Int]-clauseListFromMinisatOutput l = do-  res <- fromMinisatOutput l-  case res of-    Just p -> return (snd p)-    _ -> return []
− SAT/Util/CNFIO/Reader.hs
@@ -1,130 +0,0 @@-{-# LANGUAGE Safe #-}---- | Read a CNF file without haskell-platform-module SAT.Util.CNFIO.Reader-       (-         -- * Interface-         fromFile-       , clauseListFromFile-       )-       where-import Control.Applicative ((<$>), (<*>), (<*), (*>))-import Data.Char-import Text.ParserCombinators.ReadP---- parser-{-# INLINE newline #-}-newline = char '\n'--{-# INLINE digit #-}-digit = satisfy isDigit--{-# INLINE spaces #-}-spaces = munch (`elem` " \t")--{-# INLINE noneOf #-}-noneOf s = satisfy (`notElem` s)---- |parse a non-signed integer-{-# INLINE pint #-}-pint = do-  n <- munch isDigit-  return (read n :: Int)--{-# INLINE mint #-}-mint = do-  char '-'-  n <- munch isDigit-  return (- (read n::Int))---- |parse a (signed) integer-{-# INLINE int #-}-int = mint <++ pint---- |Parse something like: p FORMAT VARIABLES CLAUSES-{-# INLINE problemLine #-}-problemLine = do-  char 'p'-  skipSpaces-  (string "cnf" <++ string "CNF")-  skipSpaces-  vars <- pint-  skipSpaces-  clas <- pint-  spaces-  newline-  return (vars, clas)---- |Parse something like: c This in an example of a comment line.-{-# INLINE commentLines #-}-commentLines = do-  l <- look-  if (head l)  == 'c'-    then do-      munch ('\n' /=)-      newline-      commentLines-    else return ()--_commentLines = do-  char 'c'-  munch ('\n' /=)-  newline-  l <- look-  if (head l)  == 'c' then commentLines else return ()---- |Parse the preamble part-{-# INLINE preambleCNF #-}-preambleCNF = do-  commentLines-  problemLine---- |return integer list that terminates at zero-{-# INLINE seqNums #-}-seqNums = do-  skipSpaces-  x <- int-  skipSpaces-  if (x == 0) then return []  else (x :) <$> seqNums---- |Parse something like: 1 -2 0 4 0 -3 0-{-# INLINE parseClauses #-}-parseClauses :: Int -> ReadP [[Int]]-parseClauses n = count n seqNums---- |top level interface for parsing CNF-{-# INLINE parseCNF #-}-parseCNF :: ReadP ((Int, Int), [[Int]])-parseCNF = do-  a <- preambleCNF-  b <- parseClauses (snd a)-  return (a, b)---- |driver:: String -> Either ParseError Int-driver input = readP_to_S (parseClauses 1) input---- |read a CNF file and return:--- ((numbefOfVariables, numberOfClauses), [Literal])------ >>> fromFile "acnf"--- ((3, 4), [[1, 2], [-2, 3], [-1, 2, -3], [3]]----{-# INLINE fromFile #-}-fromFile :: FilePath -> IO (Maybe ((Int, Int), [[Int]]))-fromFile f = do-  c <- readFile f-  case readP_to_S parseCNF c of-    [(a, _)] -> return $ Just a-    _ -> return Nothing---- | return clauses as [[Int]] from 'file'------ >>> clauseListFromFile "a.cnf"--- [[1, 2], [-2, 3], [-1, 2, -3], [3]]----clauseListFromFile :: FilePath -> IO [[Int]]-clauseListFromFile l = do-  res <- fromFile l-  case res of-    Just (_, l) -> return l-    _ -> return []
− SAT/Util/CNFIO/Writer.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE Safe #-}---- | Write SAT data to CNF file-module SAT.Util.CNFIO.Writer-       (-         -- * Interface-         toFile-       , toCNFString-       , toString-       , toLatexString-       )-       where-import Data.List (intercalate, nub, sort)-import System.IO---- | Write the CNF to file 'f', using 'toCNFString'-toFile :: FilePath -> [[Int]] -> IO ()-toFile f l = writeFile f $ toCNFString l---- | Convert [Clause] to String, where Clause is [Int]------ >>> toCNFString []--- "p cnf 0 0\n"------ >>> toCNFString [[-1, 2], [-3, -4]]--- "p cnf 4 2\n-1 2 0\n-3 -4 0\n"------ >>> toCNFString [[1], [-2], [-3, -4], [1,2,3,4]]--- "p cnf 4 4\n1 0\n-2 0\n-3 -4 0\n1 2 3 4 0\n"----toCNFString :: [[Int]] -> String-toCNFString l = hdr ++ str-  where-    hdr = "p cnf " ++ show numV ++ " " ++ show numC ++ "\n"-    numC = length l-    numV = last $ nub $ sort $ map abs $ concat l-    str = concat [intercalate " " (map show c) ++ " 0\n" | c <- l]---- | converts @[[Int]]@ to a String-toString  :: [[Int]] -> String -> String -> String-toString l and' or' = intercalate a ["(" ++ intercalate o [ lit x | x <- c] ++ ")" | c <- l]-  where-    lit x-      | 0 <= x = "X" ++ show x-      | otherwise = "-X" ++ show (abs x)-    a = pad and'-    o = pad or'-    pad s = " " ++ s ++ " "---- | converts @[[Int]]@ to a LaTeX expression-toLatexString  :: [[Int]] -> String-toLatexString l = "\\begin{eqnarray*}\n" ++ intercalate a ["(" ++ intercalate o [ lit x | x <- c] ++ ")" | c <- l] ++ "\n\\end{eqnarray*}"-  where-    lit x-      | 0 <= x = "X_{" ++ show x ++ "}"-      | otherwise = "\\overline{X_{" ++ show (abs x) ++ "}}"-    a = " \n\\wedge "-    o = " \\vee "
app/mios.hs view
@@ -5,7 +5,7 @@        )        where -import SAT.Solver.Mios+import SAT.Mios  -- | main main :: IO ()
mios.cabal view
@@ -2,14 +2,14 @@ -- see http://haskell.org/cabal/users-guide/  name:                   mios-version:                1.2.1+version:                1.3.0 synopsis:               A Minisat-based SAT solver in Haskell description:    A modern and fast SAT solver written in Haskell, based on Minisat-1.14 and 2.2.-  By using CDCL, watch literals, VSIDS, restart, blocking-literals, LBD and so on,-  the current version is only 1.8 time slower than Minisat-1.14.-  "Mios" is an abbreviation of /Minisat-based Implementation and Optimization Study on SAT solver/.+  By using CDCL, watch literals, VSIDS, restart, blocking-literals, LBD and so on.+  The current version is only 2.0 time slower than Minisat-2.2.+  'Mios' is an abbreviation of 'Minisat-based Implementation and Optimization Study on SAT solver'.   .  homepage:               https://github.com/shnarazk/mios@@ -17,7 +17,7 @@ license-file:           LICENSE author:                 Shuji Narazaki <narazaki@nagasaki-u.ac.jp> maintainer:             Shuji Narazaki <narazaki@nagasaki-u.ac.jp>-category:               Artificial Intelligence, Constraint Solver+category:               Artificial Intelligence, Constraints build-type:             Simple cabal-version:          >=1.16 @@ -25,36 +25,43 @@   Description:	        Compile with llvm   Default:	        False +Flag lib+  Description:	        Build the solver library+  Default:	        True+ library-  buildable:	        True+  if flag(lib)+    buildable:	        True+  else+    buildable:	        False   default-language:	Haskell2010   default-extensions:  Strict   exposed-modules:-                        SAT.Solver.Mios-                        SAT.Solver.Mios.Clause-                        SAT.Solver.Mios.ClauseManager-                        SAT.Solver.Mios.Data.VecBool-                        SAT.Solver.Mios.Data.VecDouble-                        SAT.Solver.Mios.Data.Vec-                        SAT.Solver.Mios.Data.Singleton-                        SAT.Solver.Mios.Data.Stack-                        SAT.Solver.Mios.Internal-                        SAT.Solver.Mios.Glucose-                        SAT.Solver.Mios.M114-                        SAT.Solver.Mios.OptionParser-                        SAT.Solver.Mios.Solver-                        SAT.Solver.Mios.Types-                        SAT.Solver.Mios.Validator-                        SAT.Util.CNFIO-                        SAT.Util.CNFIO.MinisatReader-                        SAT.Util.CNFIO.Reader-                        SAT.Util.CNFIO.Writer-                        SAT.Util.BoolExp+                        SAT.Mios+                        SAT.Mios.Clause+                        SAT.Mios.ClauseManager+                        SAT.Mios.Data.VecBool+                        SAT.Mios.Data.VecDouble+                        SAT.Mios.Data.Vec+                        SAT.Mios.Data.Singleton+                        SAT.Mios.Data.Stack+                        SAT.Mios.Internal+                        SAT.Mios.Main+                        SAT.Mios.OptionParser+--                        SAT.Mios.Ranking+                        SAT.Mios.Solver+                        SAT.Mios.Types+                        SAT.Mios.Validator+                        SAT.Mios.Util.CNFIO+                        SAT.Mios.Util.CNFIO.MinisatReader+                        SAT.Mios.Util.CNFIO.Reader+                        SAT.Mios.Util.CNFIO.Writer+                        SAT.Mios.Util.BoolExp   build-depends:        base ==4.9.*, vector >=0.11, containers >=0.5, ghc-prim >=0.5, bytestring >=0.10, primitive >=0.6   if flag(llvm)-    ghc-options:	-ignore-asserts -funbox-strict-fields -fllvm -optlo-O3+    ghc-options:	-O2 -ignore-asserts -funbox-strict-fields -fllvm -optlo-O3   else-    ghc-options:	-ignore-asserts -funbox-strict-fields -msse4.2+    ghc-options:	-O2 -ignore-asserts -funbox-strict-fields -msse4.2  executable mios   main-is:              app/mios.hs@@ -63,27 +70,27 @@   default-extensions:  Strict   build-depends:        base ==4.9.*, vector >=0.11, containers >=0.5, ghc-prim >=0.5, bytestring >=0.10, primitive >=0.6   if flag(llvm)-    ghc-options:	-ignore-asserts -funbox-strict-fields -fllvm -optlo-O3+    ghc-options:	-O2 -ignore-asserts -funbox-strict-fields -fllvm -optlo-O3   else-    ghc-options:	-ignore-asserts -funbox-strict-fields -msse4.2+    ghc-options:	-O2 -ignore-asserts -funbox-strict-fields -msse4.2   other-modules:-                        SAT.Solver.Mios-                        SAT.Solver.Mios.Clause-                        SAT.Solver.Mios.ClauseManager-                        SAT.Solver.Mios.Data.VecBool-                        SAT.Solver.Mios.Data.VecDouble-                        SAT.Solver.Mios.Data.Vec-                        SAT.Solver.Mios.Data.Singleton-                        SAT.Solver.Mios.Data.Stack-                        SAT.Solver.Mios.Internal-                        SAT.Solver.Mios.Glucose-                        SAT.Solver.Mios.M114-                        SAT.Solver.Mios.OptionParser-                        SAT.Solver.Mios.Solver-                        SAT.Solver.Mios.Types-                        SAT.Solver.Mios.Validator-                        SAT.Util.CNFIO-                        SAT.Util.CNFIO.MinisatReader-                        SAT.Util.CNFIO.Reader-                        SAT.Util.CNFIO.Writer-                        SAT.Util.BoolExp+                        SAT.Mios+                        SAT.Mios.Clause+                        SAT.Mios.ClauseManager+                        SAT.Mios.Data.VecBool+                        SAT.Mios.Data.VecDouble+                        SAT.Mios.Data.Vec+                        SAT.Mios.Data.Singleton+                        SAT.Mios.Data.Stack+                        SAT.Mios.Internal+                        SAT.Mios.Main+                        SAT.Mios.OptionParser+--                        SAT.Mios.Ranking+                        SAT.Mios.Solver+                        SAT.Mios.Types+                        SAT.Mios.Validator+                        SAT.Mios.Util.CNFIO+                        SAT.Mios.Util.CNFIO.MinisatReader+                        SAT.Mios.Util.CNFIO.Reader+                        SAT.Mios.Util.CNFIO.Writer+                        SAT.Mios.Util.BoolExp