{-# LANGUAGE BangPatterns, TupleSections #-} import qualified Data.HashMap.Strict as M -- import qualified Control.Exception as Ex -- import Data.Maybe (catMaybes) import Data.Monoid (mconcat) import System.Exit import Control.Applicative ((<$>)) import Control.DeepSeq import Control.Monad (when) import CoreSyn -- import FastString -- import GHC -- import HscMain -- import RdrName import Var import System.Console.CmdArgs.Verbosity (whenLoud) import System.Console.CmdArgs.Default import Language.Fixpoint.Config (Config (..)) import Language.Fixpoint.Files -- import Language.Fixpoint.Names import Language.Fixpoint.Misc -- import Language.Fixpoint.Names (dropModuleNames) import Language.Fixpoint.Interface import Language.Fixpoint.Types (sinfo, showFix, isFalse) import qualified Language.Haskell.Liquid.DiffCheck as DC import Language.Haskell.Liquid.Misc import Language.Haskell.Liquid.Types import Language.Haskell.Liquid.CmdLine import Language.Haskell.Liquid.GhcInterface import Language.Haskell.Liquid.Constraint import Language.Haskell.Liquid.TransformRec main :: IO b main = do cfg0 <- getOpts res <- mconcat <$> mapM (checkOne cfg0) (files cfg0) exitWith $ resultExit res checkOne cfg0 t = getGhcInfo cfg0 t >>= either (exitWithResult t Nothing) (liquidOne t) liquidOne target info = do donePhase Loud "Extracted Core From GHC" let cfg = config $ spec info whenLoud $ do putStrLn $ showpp info putStrLn "*************** Original CoreBinds ***************************" putStrLn $ showpp (cbs info) let cbs' = transformRecExpr (cbs info) whenLoud $ do donePhase Loud "transformRecExpr" putStrLn "*************** Transform Rec Expr CoreBinds *****************" putStrLn $ showpp cbs' putStrLn "*************** Slicing Out Unchanged CoreBinds *****************" (pruned, cbs'') <- prune cfg cbs' target info let cgi = {-# SCC "generateConstraints" #-} generateConstraints $! info {cbs = cbs''} cgi `deepseq` donePhase Loud "generateConstraints" -- whenLoud $ do donePhase Loud "START: Write CGI (can be slow!)" -- {-# SCC "writeCGI" #-} writeCGI target cgi -- donePhase Loud "FINISH: Write CGI" (r, sol) <- solveCs cfg target cgi info _ <- when (diffcheck cfg) $ DC.save target donePhase Loud "solve" let out = Just $ O (checkedNames pruned cbs'') (logWarn cgi) sol (annotMap cgi) exitWithResult target out (result $ sinfo <$> r) checkedNames False _ = Nothing checkedNames True cbs = Just $ concatMap names cbs where names (NonRec v _ ) = [varName v] names (Rec bs) = map (varName . fst) bs prune cfg cbs target info | not (null vs) = return (True, DC.thin cbs vs) | diffcheck cfg = (True,) <$> DC.slice target cbs | otherwise = return (False, cbs) where vs = tgtVars $ spec info solveCs cfg target cgi info | nofalse cfg = do hqBot <- getHqBotPath (_, solBot) <- solve fx target [hqBot] (cgInfoFInfoBot cgi) let falseKvars = M.keys (M.filterWithKey (const isFalse) solBot) putStrLn $ "False KVars" ++ show falseKvars solve fx target (hqFiles info) (cgInfoFInfoKvars cgi falseKvars) | otherwise = solve fx target (hqFiles info) (cgInfoFInfo cgi) where fx = def { solver = smtsolver cfg } writeCGI tgt cgi = {-# SCC "ConsWrite" #-} writeFile (extFileName Cgi tgt) str where str = {-# SCC "PPcgi" #-} showFix cgi