{-# LANGUAGE TupleSections #-}
-- module Main where
import Language.Haskell.Liquid.Liquid (liquidConstraints)
import Language.Haskell.Liquid.Types (GhcInfo(..), Cinfo)
import Language.Haskell.Liquid.Constraint.Types (CGInfo(..)) -- , FixWfC, SubC(..), CGEnv(..))
import Language.Haskell.Liquid.UX.Config (Config(..))
import Language.Haskell.Liquid.UX.CmdLine (getOpts)
import Language.Haskell.Liquid.Constraint.ToFixpoint (cgInfoFInfo, fixConfig)
import qualified Language.Fixpoint.Types as F
import qualified Language.Fixpoint.Types.Config as F
import Language.Fixpoint.Solver (simplifyFInfo)
import Language.Fixpoint.Solver.Solve (solve)
import qualified Language.Fixpoint.Solver.GradualSolution as GS
import Language.Fixpoint.Misc (mapSnd)
import Language.Fixpoint.Graph.Partition (partition')
import System.Exit (exitWith, exitSuccess, exitFailure)
import System.Environment (getArgs)
import System.Console.CmdArgs.Verbosity
import Control.Monad (when)
import qualified Data.List as L
import Gradual.Concretize
import Gradual.Types
import Gradual.Misc (mapSndM, mapMWithLog)
import Gradual.Uniquify
import Gradual.Refinements
import Gradual.PrettyPrinting
import qualified Gradual.GUI as GUI
import qualified Gradual.Trivial as T
main :: IO a
main = do
cfg <- getArgs >>= getOpts
css <- quietly $ liquidConstraints (cfg{gradual=True})
case css of
Left cgis -> mapM (runGradual (cfg{gradual=True})) cgis >> exitSuccess
Right e -> exitWith e
runGradual :: Config -> CGInfo -> IO [(GSub F.GWInfo,F.Result (Integer, Cinfo))]
runGradual cfg cgi = do
let fname = target (ghcI cgi)
let fcfg = fixConfig fname cfg
finfo <- quietly $ cgInfoFInfo (ghcI cgi) cgi
sinfo <- (uniquify . T.simplify) <$> (quietly $ simplifyFInfo fcfg finfo)
let (gsis, sis) = L.partition F.isGradual $ partition' Nothing (snd sinfo)
let gcfg = (makeGConfig cfg) {pNumber = length gsis}
sol <- mconcat <$> (quietly $ mapM (solve fcfg) sis)
let gcfgs = setPId gcfg <$> [1..(length gsis)]
when (not $ F.isSafe sol) $ do
putStrLn "The static part cannot be satisfied: UNSAFE"
exitFailure
whenLoud $ putStrLn ("\nNumber of Gradual Partitions : " ++ show (length gsis) ++"\n")
solss <- mapMWithLog "Running Partition" (uncurry $ solveSInfo fcfg) (zip gcfgs gsis)
GUI.render gcfg (fst sinfo) solss
exitSuccess
solveSInfo :: F.Config -> GConfig -> F.SInfo Cinfo -> IO [GSub F.GWInfo]
solveSInfo fcfg gcfg sinfo = do
gmap <- makeGMap gcfg fcfg sinfo $ GS.init fcfg sinfo
let allgs = concretize gmap sinfo
putStrLn ("Total number of concretizations: " ++ show (length $ map snd allgs))
res <- quietly $ mapM (mapSndM (solve fcfg)) allgs
case filter (F.isSafe . snd) res of
(x:xs) -> do putStrLn ( "["++ show (1 + length xs) ++ "/" ++ (show $ length res) ++ "] Solutions Found!" ++ if length xs > 0 then " e.g.," else "")
putStrLn (pretty $ (map (mapSnd snd) $ fromGSub $ fst x))
return (fst <$> (x:xs))
_ -> do putStrLn ("[0/" ++ (show $ length res) ++ "] Solutions. UNSAFE!\n")
whenLoud $ putStrLn ("UNSAFE PARTITION: " ++ show sinfo)
return [mempty]
quietly :: IO a -> IO a
quietly act = do
vb <- getVerbosity
setVerbosity Quiet
r <- act
setVerbosity vb
return r