packages feed

tip-lib-0.1: executable/Main.hs

module Main where

import System.Environment

import Tip.Parser
import Tip.Pretty.SMT as SMT
import Tip.Pretty.Why3 as Why3
import Tip.Pretty.Isabelle as Isabelle
import Tip.Pretty.Haskell as HS
import Tip.Pretty
import Tip.CallGraph

import Tip.Passes
import Tip.Lint
import Tip.Fresh
import Tip.Core
import Options.Applicative

import Control.Monad

data OutputMode = Haskell | Why3 | CVC4 | Isabelle | TIP

parseOutputMode :: Parser OutputMode
parseOutputMode =
      flag' Haskell (long "haskell" <> help "Haskell output")
  <|> flag' Why3 (long "why" <> help "WhyML output")
  <|> flag' CVC4 (long "smtlib" <> help "SMTLIB output (CVC4-compatible)")
  <|> flag' Isabelle (long "isabelle" <> help "Isabelle output")
  <|> flag  TIP TIP (long "tip" <> help "TIP output (default)")

optionParser :: Parser ([StandardPass], Maybe String, OutputMode)
optionParser =
  (,,) <$> parsePasses <*> parseFile <*> parseOutputMode
  where
    parseFile =
      fmap Just (strArgument (metavar "FILENAME")) <|> pure Nothing

main :: IO ()
main = do
  (passes, files, mode) <-
    execParser $
      info (helper <*> optionParser)
        (fullDesc <>
         progDesc "Transform a TIP problem" <>
         header "tip - a tool for processing TIP problems")
  case files of
    Nothing ->
      handle passes mode =<< getContents
    Just f ->
      handle passes mode =<< readFile f

handle :: [StandardPass] -> OutputMode -> String -> IO ()
handle passes mode s =
  case parse s of
    Left err  -> error $ "Parse failed: " ++ err
    Right thy -> do
      let fmap_pp f = fmap (show . f)
      let show_passes c = fmap (\ s -> c ++ show passes ++ "\n" ++ s)
      let pipeline =
            case mode of
              CVC4 ->
                fmap_pp SMT.ppTheory . runPasses
                  (passes ++
                  [ LambdaLift, AxiomatizeLambdas
                  , CollapseEqual, RemoveAliases
                  , SimplifyGently, RemoveMatch
                  , SimplifyGently, NegateConjecture
                  , SimplifyGently
                  ])
              Haskell ->
                fmap_pp HS.ppTheory . runPasses passes
              Why3 ->
                fmap_pp Why3.ppTheory . runPasses (passes ++ [CSEMatchWhy3])
              Isabelle ->
                fmap_pp Isabelle.ppTheory . runPasses passes
              TIP ->
                show_passes "; " . fmap_pp SMT.ppTheory . runPasses passes
      putStrLn (freshPass pipeline (lint "parse" thy))