-- | Command Line Configuration Options ----------------------------------------

{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE DeriveGeneric #-}

module Language.Haskell.Liquid.UX.Config (
     Config (..)
   , HasConfig (..)
   , allowPLE, allowLocalPLE, allowGlobalPLE
   , patternFlag
   , higherOrderFlag
   , pruneFlag
   , maxCaseExpand
   , exactDCFlag
   , hasOpt
   , totalityCheck
   , terminationCheck
   , structuralTerm
   ) where

import Prelude hiding (error)
import Language.Fixpoint.Types.Config hiding (Config)
import GHC.Generics
import System.Console.CmdArgs

-- NOTE: adding strictness annotations breaks the help message
data Config = Config
  { Config -> Verbosity
loggingVerbosity         :: Verbosity  -- ^ the logging verbosity to use (defaults to 'Quiet')
  , Config -> [FilePath]
files                    :: [FilePath] -- ^ source files to check
  , Config -> [FilePath]
idirs                    :: [FilePath] -- ^ path to directory for including specs
  , Config -> Bool
diffcheck                :: Bool       -- ^ check subset of binders modified (+ dependencies) since last check
  , Config -> Bool
linear                   :: Bool       -- ^ uninterpreted integer multiplication and division
  , Config -> Bool
stringTheory             :: Bool       -- ^ interpretation of string theory in the logic
  , Config -> Bool
higherorder              :: Bool       -- ^ allow higher order binders into the logic
  , Config -> Bool
higherorderqs            :: Bool       -- ^ allow higher order qualifiers
  , Config -> Maybe Int
smtTimeout               :: Maybe Int  -- ^ smt timeout
  , Config -> Bool
fullcheck                :: Bool       -- ^ check all binders (overrides diffcheck)
  , Config -> Bool
saveQuery                :: Bool       -- ^ save fixpoint query
  , Config -> [FilePath]
checks                   :: [String]   -- ^ set of binders to check
  , Config -> Bool
noCheckUnknown           :: Bool       -- ^ whether to complain about specifications for unexported and unused values
  , Config -> Bool
notermination            :: Bool       -- ^ disable termination check
  , Config -> Bool
rankNTypes               :: Bool       -- ^ Adds precise reasoning on presence of rankNTypes
  , Config -> Bool
noclasscheck             :: Bool       -- ^ disable checking class instances
  -- , structuralTerm        :: Bool       -- ^ use structural termination checker
  , Config -> Bool
nostructuralterm         :: Bool       -- ^ disable structural termination check
  , Config -> Bool
gradual                  :: Bool       -- ^ enable gradual type checking
  , Config -> Bool
bscope                   :: Bool       -- ^ scope of the outer binders on the inner refinements
  , Config -> Int
gdepth                   :: Int        -- ^ depth of gradual concretization
  , Config -> Bool
ginteractive             :: Bool       -- ^ interactive gradual solving
  , Config -> Bool
totalHaskell             :: Bool       -- ^ Check for termination and totality, Overrides no-termination flags
  , Config -> Bool
nowarnings               :: Bool       -- ^ disable warnings output (only show errors)
  , Config -> Bool
noannotations            :: Bool       -- ^ disable creation of intermediate annotation files
  , Config -> Bool
checkDerived             :: Bool       -- ^ check internal (GHC-derived) binders
  , Config -> Int
caseExpandDepth          :: Int        -- ^ maximum case expand nesting depth.
  , Config -> Bool
notruetypes              :: Bool       -- ^ disable truing top level types
  , Config -> Bool
nototality               :: Bool       -- ^ disable totality check in definitions
  , Config -> Bool
pruneUnsorted            :: Bool       -- ^ enable prunning unsorted Refinements
  , Config -> Maybe Int
cores                    :: Maybe Int  -- ^ number of cores used to solve constraints
  , Config -> Int
minPartSize              :: Int        -- ^ Minimum size of a partition
  , Config -> Int
maxPartSize              :: Int        -- ^ Maximum size of a partition. Overrides minPartSize
  , Config -> Int
maxParams                :: Int        -- ^ the maximum number of parameters to accept when mining qualifiers
  , Config -> Maybe SMTSolver
smtsolver                :: Maybe SMTSolver  -- ^ name of smtsolver to use [default: try z3, cvc4, mathsat in order]
  , Config -> Bool
shortNames               :: Bool       -- ^ drop module qualifers from pretty-printed names.
  , Config -> Bool
shortErrors              :: Bool       -- ^ don't show subtyping errors and contexts.
  , Config -> Bool
cabalDir                 :: Bool       -- ^ find and use .cabal file to include paths to sources for imported modules
  , Config -> [FilePath]
ghcOptions               :: [String]   -- ^ command-line options to pass to GHC
  , Config -> [FilePath]
cFiles                   :: [String]   -- ^ .c files to compile and link against (for GHC)
  , Config -> Eliminate
eliminate                :: Eliminate  -- ^ eliminate (i.e. don't use qualifs for) for "none", "cuts" or "all" kvars
  , Config -> Int
port                     :: Int        -- ^ port at which lhi should listen
  , Config -> Bool
exactDC                  :: Bool       -- ^ Automatically generate singleton types for data constructors
  , Config -> Bool
noADT                    :: Bool       -- ^ Disable ADTs (only used with exactDC)
  , Config -> Bool
scrapeImports            :: Bool       -- ^ scrape qualifiers from imported specifications
  , Config -> Bool
scrapeInternals          :: Bool       -- ^ scrape qualifiers from auto specifications
  , Config -> Bool
scrapeUsedImports        :: Bool       -- ^ scrape qualifiers from used, imported specifications
  , Config -> Bool
elimStats                :: Bool       -- ^ print eliminate stats
  , Config -> Maybe Int
elimBound                :: Maybe Int  -- ^ eliminate upto given depth of KVar chains
  , Config -> Bool
json                     :: Bool       -- ^ print results (safe/errors) as JSON
  , Config -> Bool
counterExamples          :: Bool       -- ^ attempt to generate counter-examples to type errors
  , Config -> Bool
timeBinds                :: Bool       -- ^ check and time each (asserted) type-sig separately
  , Config -> Bool
noPatternInline          :: Bool       -- ^ treat code patterns (e.g. e1 >>= \x -> e2) specially for inference
  , Config -> Bool
untidyCore               :: Bool       -- ^ print full blown core (with untidy names) in verbose mode
  , Config -> Bool
noSimplifyCore           :: Bool       -- ^ simplify GHC core before constraint-generation
  -- PLE-OPT , autoInst      ntiate :: Instantiate -- ^ How to instantiate axioms
  , Config -> Bool
noslice                  :: Bool       -- ^ Disable non-concrete KVar slicing
  , Config -> Bool
noLiftedImport           :: Bool       -- ^ Disable loading lifted specifications (for "legacy" libs)
  , Config -> Bool
proofLogicEval           :: Bool       -- ^ Enable proof-by-logical-evaluation
  , Config -> Bool
oldPLE                   :: Bool       -- ^ Enable proof-by-logical-evaluation
  , Config -> Bool
proofLogicEvalLocal      :: Bool       -- ^ Enable proof-by-logical-evaluation locally, per function
  , Config -> Bool
extensionality           :: Bool       -- ^ Enable extensional interpretation of function equality
  , Config -> Bool
nopolyinfer              :: Bool       -- ^ No inference of polymorphic type application.
  , Config -> Bool
reflection               :: Bool       -- ^ Allow "reflection"; switches on "--higherorder" and "--exactdc"
  , Config -> Bool
compileSpec              :: Bool       -- ^ Only "compile" the spec -- into .bspec file -- don't do any checking.
  , Config -> Bool
noCheckImports           :: Bool       -- ^ Do not check the transitive imports
  , Config -> Bool
typedHoles               :: Bool       -- ^ Warn about "typed-holes"
  , Config -> Int
maxMatchDepth            :: Int
  , Config -> Int
maxAppDepth              :: Int
  , Config -> Int
maxArgsDepth             :: Int
  , Config -> Maybe Int
maxRWOrderingConstraints :: Maybe Int
  , Config -> Bool
rwTerminationCheck       :: Bool
  } deriving ((forall x. Config -> Rep Config x)
-> (forall x. Rep Config x -> Config) -> Generic Config
forall x. Rep Config x -> Config
forall x. Config -> Rep Config x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Config x -> Config
$cfrom :: forall x. Config -> Rep Config x
Generic, Typeable Config
DataType
Constr
Typeable Config
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Config -> c Config)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Config)
-> (Config -> Constr)
-> (Config -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Config))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Config))
-> ((forall b. Data b => b -> b) -> Config -> Config)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Config -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Config -> r)
-> (forall u. (forall d. Data d => d -> u) -> Config -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Config -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Config -> m Config)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Config -> m Config)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Config -> m Config)
-> Data Config
Config -> DataType
Config -> Constr
(forall b. Data b => b -> b) -> Config -> Config
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Config -> c Config
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Config
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Config -> u
forall u. (forall d. Data d => d -> u) -> Config -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Config -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Config -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Config -> m Config
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Config -> m Config
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Config
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Config -> c Config
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Config)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Config)
$cConfig :: Constr
$tConfig :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Config -> m Config
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Config -> m Config
gmapMp :: (forall d. Data d => d -> m d) -> Config -> m Config
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Config -> m Config
gmapM :: (forall d. Data d => d -> m d) -> Config -> m Config
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Config -> m Config
gmapQi :: Int -> (forall d. Data d => d -> u) -> Config -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Config -> u
gmapQ :: (forall d. Data d => d -> u) -> Config -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Config -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Config -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Config -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Config -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Config -> r
gmapT :: (forall b. Data b => b -> b) -> Config -> Config
$cgmapT :: (forall b. Data b => b -> b) -> Config -> Config
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Config)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Config)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Config)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Config)
dataTypeOf :: Config -> DataType
$cdataTypeOf :: Config -> DataType
toConstr :: Config -> Constr
$ctoConstr :: Config -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Config
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Config
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Config -> c Config
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Config -> c Config
$cp1Data :: Typeable Config
Data, Typeable, Int -> Config -> ShowS
[Config] -> ShowS
Config -> FilePath
(Int -> Config -> ShowS)
-> (Config -> FilePath) -> ([Config] -> ShowS) -> Show Config
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Config] -> ShowS
$cshowList :: [Config] -> ShowS
show :: Config -> FilePath
$cshow :: Config -> FilePath
showsPrec :: Int -> Config -> ShowS
$cshowsPrec :: Int -> Config -> ShowS
Show, Config -> Config -> Bool
(Config -> Config -> Bool)
-> (Config -> Config -> Bool) -> Eq Config
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Config -> Config -> Bool
$c/= :: Config -> Config -> Bool
== :: Config -> Config -> Bool
$c== :: Config -> Config -> Bool
Eq)

allowPLE :: Config -> Bool
allowPLE :: Config -> Bool
allowPLE Config
cfg
  =  Config -> Bool
allowGlobalPLE Config
cfg
  Bool -> Bool -> Bool
|| Config -> Bool
allowLocalPLE Config
cfg

allowGlobalPLE :: Config -> Bool
allowGlobalPLE :: Config -> Bool
allowGlobalPLE Config
cfg = Config -> Bool
proofLogicEval  Config
cfg

allowLocalPLE :: Config -> Bool
allowLocalPLE :: Config -> Bool
allowLocalPLE Config
cfg = Config -> Bool
proofLogicEvalLocal  Config
cfg

instance HasConfig  Config where
  getConfig :: Config -> Config
getConfig Config
x = Config
x

class HasConfig t where
  getConfig :: t -> Config

patternFlag :: (HasConfig t) => t -> Bool
patternFlag :: t -> Bool
patternFlag = Bool -> Bool
not (Bool -> Bool) -> (t -> Bool) -> t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Config -> Bool
noPatternInline (Config -> Bool) -> (t -> Config) -> t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Config
forall t. HasConfig t => t -> Config
getConfig

higherOrderFlag :: (HasConfig t) => t -> Bool
higherOrderFlag :: t -> Bool
higherOrderFlag t
x = Config -> Bool
higherorder Config
cfg Bool -> Bool -> Bool
|| Config -> Bool
reflection Config
cfg
  where
    cfg :: Config
cfg           = t -> Config
forall t. HasConfig t => t -> Config
getConfig t
x

exactDCFlag :: (HasConfig t) => t -> Bool
exactDCFlag :: t -> Bool
exactDCFlag t
x = Config -> Bool
exactDC Config
cfg Bool -> Bool -> Bool
|| Config -> Bool
reflection Config
cfg
  where
    cfg :: Config
cfg       = t -> Config
forall t. HasConfig t => t -> Config
getConfig t
x

pruneFlag :: (HasConfig t) => t -> Bool
pruneFlag :: t -> Bool
pruneFlag = Config -> Bool
pruneUnsorted (Config -> Bool) -> (t -> Config) -> t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Config
forall t. HasConfig t => t -> Config
getConfig

maxCaseExpand :: (HasConfig t) => t -> Int
maxCaseExpand :: t -> Int
maxCaseExpand = Config -> Int
caseExpandDepth (Config -> Int) -> (t -> Config) -> t -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Config
forall t. HasConfig t => t -> Config
getConfig

hasOpt :: (HasConfig t) => t -> (Config -> Bool) -> Bool
hasOpt :: t -> (Config -> Bool) -> Bool
hasOpt t
t Config -> Bool
f = Config -> Bool
f (t -> Config
forall t. HasConfig t => t -> Config
getConfig t
t)

totalityCheck :: (HasConfig t) => t -> Bool
totalityCheck :: t -> Bool
totalityCheck = Config -> Bool
totalityCheck' (Config -> Bool) -> (t -> Config) -> t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Config
forall t. HasConfig t => t -> Config
getConfig

terminationCheck :: (HasConfig t) => t -> Bool
terminationCheck :: t -> Bool
terminationCheck = Config -> Bool
terminationCheck' (Config -> Bool) -> (t -> Config) -> t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Config
forall t. HasConfig t => t -> Config
getConfig

totalityCheck' :: Config -> Bool
totalityCheck' :: Config -> Bool
totalityCheck' Config
cfg = (Bool -> Bool
not (Config -> Bool
nototality Config
cfg)) Bool -> Bool -> Bool
|| Config -> Bool
totalHaskell Config
cfg

terminationCheck' :: Config -> Bool
terminationCheck' :: Config -> Bool
terminationCheck' Config
cfg = (Config -> Bool
totalHaskell Config
cfg Bool -> Bool -> Bool
|| Bool -> Bool
not (Config -> Bool
notermination Config
cfg))

structuralTerm :: (HasConfig a) => a -> Bool
structuralTerm :: a -> Bool
structuralTerm = Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Config -> Bool
nostructuralterm (Config -> Bool) -> (a -> Config) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Config
forall t. HasConfig t => t -> Config
getConfig