module Data.SBV.SMT.Utils (
SMTLibConverter
, SMTLibIncConverter
, annotateWithName
, showTimeoutValue
, alignDiagnostic
, alignPlain
, debug
, mergeSExpr
)
where
import Data.SBV.Core.Data
import Data.List (intercalate)
import qualified Data.Set as Set (Set)
type SMTLibConverter a = Set.Set Kind
-> Bool
-> [String]
-> [(Quantifier, NamedSymVar)]
-> [Either SW (SW, [SW])]
-> [(SW, CW)]
-> [((Int, Kind, Kind), [SW])]
-> [(Int, ArrayInfo)]
-> [(String, SBVType)]
-> [(String, [String])]
-> SBVPgm
-> [(Maybe String, SW)]
-> SW
-> SMTConfig
-> a
type SMTLibIncConverter a = [NamedSymVar]
-> Set.Set Kind
-> [(SW, CW)]
-> SBVPgm
-> SMTConfig
-> a
annotateWithName :: String -> String -> String
annotateWithName nm x = "(! " ++ x ++ " :named |" ++ concatMap sanitize nm ++ "|)"
where sanitize '|' = "_bar_"
sanitize '\\' = "_backslash_"
sanitize c = [c]
showTimeoutValue :: Int -> String
showTimeoutValue i = case (i `quotRem` 1000000, i `quotRem` 500000) of
((s, 0), _) -> shows s "s"
(_, (hs, 0)) -> shows (fromIntegral hs / (2::Float)) "s"
_ -> shows i "ms"
alignDiagnostic :: String -> String -> String
alignDiagnostic = alignWithPrefix "*** "
alignPlain :: String -> String -> String
alignPlain = alignWithPrefix ""
alignWithPrefix :: String -> String -> String -> String
alignWithPrefix pre tag multi = intercalate "\n" $ zipWith (++) (tag : repeat (pre ++ replicate (length tag - length pre) ' ')) (filter (not . null) (lines multi))
debug :: SMTConfig -> [String] -> IO ()
debug cfg
| not (verbose cfg) = const (return ())
| Just f <- redirectVerbose cfg = mapM_ (appendFile f . (++ "\n"))
| True = mapM_ putStrLn
mergeSExpr :: [String] -> [String]
mergeSExpr [] = []
mergeSExpr (x:xs)
| d == 0 = x : mergeSExpr xs
| True = let (f, r) = grab d xs in unlines (x:f) : mergeSExpr r
where d = parenDiff x
parenDiff :: String -> Int
parenDiff = go 0
where go i "" = i
go i ('(':cs) = let i'= i+1 in i' `seq` go i' cs
go i (')':cs) = let i'= i-1 in i' `seq` go i' cs
go i ('"':cs) = go i (skipString cs)
go i ('|':cs) = go i (skipBar cs)
go i (_ :cs) = go i cs
grab i ls
| i <= 0 = ([], ls)
grab _ [] = ([], [])
grab i (l:ls) = let (a, b) = grab (i+parenDiff l) ls in (l:a, b)
skipString ('\\':'"':cs) = skipString cs
skipString ('"':'"':cs) = skipString cs
skipString ('"':cs) = cs
skipString (_:cs) = skipString cs
skipString [] = []
skipBar ('|':cs) = cs
skipBar (_:cs) = skipBar cs
skipBar [] = []