{-# 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