mios-1.5.4: MultiConflict/utils/pickup.hs
-- | Usage:
-- > mios-summary < average.csv > summary.tbl (for org-mode or github-flavored markdown)
module Main where
import Data.List (intercalate, lookup, maximumBy, minimumBy, nub)
import Data.Maybe (fromMaybe)
import Data.Ord (comparing)
import Numeric (showFFloat)
import System.Console.GetOpt (ArgDescr(..), ArgOrder(..), getOpt, OptDescr(..), usageInfo)
import System.Environment (getArgs)
import SAT.Mios.Types
import SAT.Mios.Util.Stat
data Opt = Opt
{
message :: String
, useLog :: Bool
, help :: Bool
}
optDefault :: Opt
optDefault = Opt "#-*-mode:org-*-" False False
options ::[OptDescr (Opt -> Opt)]
options =
[
Option ['m'] ["message"]
(ReqArg (\v c -> c { message = undecodeNewline v }) "\"string\"") "extra message embeded into output"
, Option ['l'] ["useLog"]
(NoArg (\c -> c { useLog = True })) "use Logarithmic value for propagation"
, Option ['h'] ["help"]
(NoArg (\c -> c { help = True })) "display help message"
]
parseOptions :: String -> [String] -> IO Opt
parseOptions mes argv =
case getOpt Permute options argv of
(o, [], []) -> return $ foldl (flip id) optDefault o
(o, _, []) -> return $ foldl (flip id) optDefault o
(_, _, err) -> ioError (userError (concat err ++ usageInfo mes options))
-- | builds "MiosProgramOption" from a String
parseOptionsFromArgs :: String -> IO Opt
parseOptionsFromArgs mes = parseOptions mes =<< getArgs
undecodeNewline :: String -> String
undecodeNewline [] = []
undecodeNewline [a] = [a]
undecodeNewline ('\\' : 'n' : x) = '\n' : undecodeNewline x
undecodeNewline (a : x) = a : undecodeNewline x
showf :: Double -> String
showf x = showFFloat (Just 2) x ""
showi :: Int -> String
showi x
| 3 <= length s = s
| otherwise = reverse . take 3 . (++ " ") . reverse $ s
where s = show x
showl :: Either Double Int -> String
showl (Left x) = showf x
showl (Right x) = showf (fromIntegral x)
main :: IO ()
main = do
opts <- parseOptionsFromArgs "gp-summary"
if help opts
then putStrLn $ usageInfo "" options
else do let parsers = [ (fst (header :: (String, MiosDump)), toMerge <$> fromCSV)
, (fst (header :: (String, MergedDump)), fromMergedCSV)]
putStrLn $ message opts
putStrLn ""
if useLog opts
then do putStrLn "| n | p1 | p2 | p3 | p4 | log(P) | conflict | learnt | backjump | re-st | rate | extra | pr/bj |"
putStrLn "| --- | ---- | ---- | --- | --- | ------ | -------- | -------- | -------- | ----- | ---- | ----- | ----- |"
else do putStrLn "| n | p1 | p2 | p3 | p4 | propagation | conflict | learnt | backjump | re-st | rate | extra | pr/bj |"
putStrLn "| --- | ---- | ---- | --- | --- | ----------- | -------- | -------- | -------- | ----- | ---- | ----- | ----- |"
d <- parseBy parsers <$> getContents
mapM_ (putStrLn . toSummary (useLog opts)) $ pickup True d
putStrLn ""
mapM_ (putStrLn . toSummary (useLog opts)) $ pickup False d
putStrLn ""
toSummary :: Bool -> MergedDump -> String
toSummary uLog (MergedDump (_, MiosConfiguration _ _ p1 p2 p3 p4) n (MiosStats l) _) =
"| " ++ intercalate " | " [show n, m', s', showf pr] ++ " |"
where
m' = intercalate " | " [showf p1, showf p2, showi p3, showi p4]
s' = intercalate " | " $ map (showl . snd) (convert uLog l) -- (tail . init $ l)
convert :: Bool -> [DumpedValue] -> [DumpedValue]
convert uL ks
| uL = logOf PropagationS : map valOf [ConflictS .. ExtraS]
| otherwise = map valOf [PropagationS .. ExtraS]
where
logOf :: DumpTag -> DumpedValue
logOf key = (key, Left $ logBase 10 (val key))
valOf key = (key, Left $ val key)
val :: DumpTag -> Double
val key
| Just (Left x) <- lookup key ks = x
| Just (Right x) <- lookup key ks = fromIntegral x
| otherwise = 0
pr = fromMaybe 0 $ div' <$> lookup PropagationS l <*> lookup BackjumpS l
div' :: Either Double Int -> Either Double Int -> Double
div' (Right a) (Right b) = fromIntegral a / fromIntegral b
div' (Right a) (Left b) = fromIntegral a / b
div' (Left a) (Right b) = a / fromIntegral b
div' (Left a) (Left b) = a / b
pickup :: Bool -> [MergedDump] -> [MergedDump]
pickup good l = map selectData keys
where
keys = nub $ map (gpParameter1 . snd. _mergedConf) l
selectData :: Double -> MergedDump
selectData key
| good = minimumBy (comparing value) $ filter ((key ==) . gpParameter1 . snd. _mergedConf) l
| otherwise = maximumBy (comparing value) $ filter ((key ==) . gpParameter1 . snd. _mergedConf) l
value :: MergedDump -> Double
value m = case lookup PropagationS . (\(MiosStats s) -> s) . _mergedStat $ m of
Just (Right v) -> fromIntegral v
Just (Left v) -> v
Nothing -> 10000000