packages feed

liquid-fixpoint 0.9.6.3 → 0.9.6.3.1

raw patch · 50 files changed

+1387/−519 lines, 50 filesdep −typed-processdep ~tastyPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: typed-process

Dependency ranges changed: tasty

API changes (from Hackage documentation)

+ Language.Fixpoint.Horn.Parse: numericDeclP :: Parser Symbol
+ Language.Fixpoint.Horn.SMTParse: exprP :: FParser Expr
+ Language.Fixpoint.Horn.SMTParse: hCstrP :: FParser (Cstr Tag)
+ Language.Fixpoint.Horn.SMTParse: hPredP :: FParser Pred
+ Language.Fixpoint.Horn.SMTParse: hQualifierP :: FParser Qualifier
+ Language.Fixpoint.Horn.SMTParse: hVarP :: FParser (Var Tag)
+ Language.Fixpoint.Horn.SMTParse: hornP :: FParser TagQuery
+ Language.Fixpoint.Horn.SMTParse: instance GHC.Base.Functor Language.Fixpoint.Horn.SMTParse.HThing
+ Language.Fixpoint.Horn.SMTParse: sortP :: FParser Sort
+ Language.Fixpoint.Horn.Types: [qNums] :: Query a -> ![Symbol]
+ Language.Fixpoint.Horn.Types: [qOpts] :: Query a -> ![String]
+ Language.Fixpoint.Horn.Types: class ToHornSMT a
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Horn.Types.Pred
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Horn.Types.Tag
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Language.Fixpoint.Horn.Types.Bind a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Language.Fixpoint.Horn.Types.Cstr a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Language.Fixpoint.Horn.Types.Query a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Language.Fixpoint.Horn.Types.Var a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Horn.Types.Pred
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Horn.Types.Bind a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Horn.Types.Cstr a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Horn.Types.Query a)
+ Language.Fixpoint.Horn.Types: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Horn.Types.Var a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT (Language.Fixpoint.Horn.Types.Bind a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT (Language.Fixpoint.Horn.Types.Cstr a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT (Language.Fixpoint.Horn.Types.Query a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT (Language.Fixpoint.Horn.Types.Var a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Horn.Types.Pred
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Horn.Types.Tag
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Constraints.Equation
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Constraints.QualParam
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Constraints.Qualifier
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Constraints.Rewrite
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Names.Symbol
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Refinements.Expr
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Refinements.KVar
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Refinements.Subst
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Sorts.DataCtor
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Sorts.DataDecl
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Sorts.DataField
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Sorts.FTycon
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT Language.Fixpoint.Types.Sorts.Sort
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT a => Language.Fixpoint.Horn.Types.ToHornSMT (Language.Fixpoint.Types.Names.Symbol, a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT a => Language.Fixpoint.Horn.Types.ToHornSMT (Language.Fixpoint.Types.Spans.Located a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Horn.Types.ToHornSMT a => Language.Fixpoint.Horn.Types.ToHornSMT [a]
+ Language.Fixpoint.Horn.Types: toHornSMT :: ToHornSMT a => a -> Doc
+ Language.Fixpoint.Misc: dbgFalse :: Bool
+ Language.Fixpoint.Parse: fTyConP :: Parser FTycon
+ Language.Fixpoint.Parse: falseP :: Parser Expr
+ Language.Fixpoint.Parse: intP :: Parser Int
+ Language.Fixpoint.Parse: lexeme' :: Parser () -> Parser a -> Parser a
+ Language.Fixpoint.Parse: locLexeme' :: Parser () -> Parser a -> Parser (Located a)
+ Language.Fixpoint.Parse: lowerIdR :: Parser Symbol
+ Language.Fixpoint.Parse: mkFTycon :: LocSymbol -> Parser FTycon
+ Language.Fixpoint.Parse: naturalR :: Parser Integer
+ Language.Fixpoint.Parse: reserved' :: Parser () -> String -> Parser ()
+ Language.Fixpoint.Parse: reservedOp' :: Parser () -> String -> Parser ()
+ Language.Fixpoint.Parse: stringR :: Parser String
+ Language.Fixpoint.Parse: sym :: String -> Parser String
+ Language.Fixpoint.Parse: symbolR :: Parser Symbol
+ Language.Fixpoint.Parse: symconstP :: Parser SymConst
+ Language.Fixpoint.Parse: trueP :: Parser Expr
+ Language.Fixpoint.Parse: tvarP :: Parser Sort
+ Language.Fixpoint.Parse: upperIdR :: Parser Symbol
+ Language.Fixpoint.Smt.Theories: arrConst :: Symbol
+ Language.Fixpoint.Smt.Theories: arrMapAnd :: Symbol
+ Language.Fixpoint.Smt.Theories: arrMapImp :: Symbol
+ Language.Fixpoint.Smt.Theories: arrMapNot :: Symbol
+ Language.Fixpoint.Smt.Theories: arrMapOr :: Symbol
+ Language.Fixpoint.Smt.Theories: arrSelect :: Symbol
+ Language.Fixpoint.Smt.Theories: arrStore :: Symbol
+ Language.Fixpoint.Types.Config: [noSmtHorn] :: Config -> Bool
+ Language.Fixpoint.Types.Constraints: cfgHoInfo :: Config -> HOInfo
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Constraints.Equation
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Constraints.QualParam
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Constraints.QualPattern
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Constraints.Qualifier
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Constraints.Rewrite
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Constraints.Equation
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Constraints.QualParam
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Constraints.QualPattern
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Constraints.Qualifier
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Constraints.Rewrite
+ Language.Fixpoint.Types.Environments: coerceBindEnv :: BindEnv a -> BindEnv a
+ Language.Fixpoint.Types.Names: arrayConName :: Symbol
+ Language.Fixpoint.Types.Names: boolLConName :: Symbol
+ Language.Fixpoint.Types.Names: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Names.Symbol
+ Language.Fixpoint.Types.Names: instance Data.Aeson.Types.FromJSON.FromJSONKey Language.Fixpoint.Types.Names.Symbol
+ Language.Fixpoint.Types.Names: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Names.Symbol
+ Language.Fixpoint.Types.Names: instance Data.Aeson.Types.ToJSON.ToJSONKey Language.Fixpoint.Types.Names.Symbol
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.Bop
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.Brel
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.Constant
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.Expr
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.GradInfo
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.KVar
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.Subst
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.SymConst
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.Bop
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.Brel
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.Constant
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.Expr
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.GradInfo
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.KVar
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.Subst
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.SymConst
+ Language.Fixpoint.Types.Sorts: arraySort :: Sort -> Sort -> Sort
+ Language.Fixpoint.Types.Sorts: coerceSetToArray :: Sort -> Sort
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Sorts.DataCtor
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Sorts.DataDecl
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Sorts.DataField
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Sorts.FTycon
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Sorts.Sort
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Sorts.TCInfo
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Sorts.DataCtor
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Sorts.DataDecl
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Sorts.DataField
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Sorts.FTycon
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Sorts.Sort
+ Language.Fixpoint.Types.Sorts: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Sorts.TCInfo
+ Language.Fixpoint.Types.Sorts: isArray :: Sort -> Bool
+ Language.Fixpoint.Types.Sorts: isBool :: Sort -> Bool
+ Language.Fixpoint.Types.Sorts: isSet :: Sort -> Bool
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Spans.SrcSpan
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.FromJSON.FromJSON Text.Megaparsec.Pos.Pos
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.FromJSON.FromJSON Text.Megaparsec.Pos.SourcePos
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Language.Fixpoint.Types.Spans.Located a)
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Spans.SrcSpan
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.ToJSON.ToJSON Text.Megaparsec.Pos.Pos
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.ToJSON.ToJSON Text.Megaparsec.Pos.SourcePos
+ Language.Fixpoint.Types.Spans: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Types.Spans.Located a)
+ Language.Fixpoint.Types.Theories: SArray :: !SmtSort -> !SmtSort -> SmtSort
+ Language.Fixpoint.Types.Theories: coerceEnv :: SymEnv -> SymEnv
+ Language.Fixpoint.Types.Theories: coerceSortEnv :: SEnv Sort -> SEnv Sort
+ Language.Fixpoint.Utils.Files: HJSON :: Ext
- Language.Fixpoint.Horn.Info: hornFInfo :: Config -> Query a -> FInfo a
+ Language.Fixpoint.Horn.Info: hornFInfo :: (Fixpoint a, PPrint a) => Config -> Query a -> FInfo a
- Language.Fixpoint.Horn.Parse: hornP :: Parser (TagQuery, [String])
+ Language.Fixpoint.Horn.Parse: hornP :: Parser TagQuery
- Language.Fixpoint.Horn.Transformations: solveEbs :: PPrint a => Config -> Query a -> IO (Query a)
+ Language.Fixpoint.Horn.Transformations: solveEbs :: (Fixpoint a, PPrint a) => Config -> Query a -> IO (Query a)
- Language.Fixpoint.Horn.Types: Query :: ![Qualifier] -> ![Var a] -> !Cstr a -> HashMap Symbol Sort -> HashMap Symbol Sort -> ![Equation] -> ![Rewrite] -> ![DataDecl] -> Query a
+ Language.Fixpoint.Horn.Types: Query :: ![Qualifier] -> ![Var a] -> !Cstr a -> HashMap Symbol Sort -> HashMap Symbol Sort -> ![Equation] -> ![Rewrite] -> ![DataDecl] -> ![String] -> ![Symbol] -> Query a
- Language.Fixpoint.Smt.Theories: setAdd :: Symbol
+ Language.Fixpoint.Smt.Theories: setAdd :: IsString a => a
- Language.Fixpoint.Smt.Theories: setCap :: Symbol
+ Language.Fixpoint.Smt.Theories: setCap :: IsString a => a
- Language.Fixpoint.Smt.Theories: setCom :: Symbol
+ Language.Fixpoint.Smt.Theories: setCom :: IsString a => a
- Language.Fixpoint.Smt.Theories: setCup :: Symbol
+ Language.Fixpoint.Smt.Theories: setCup :: IsString a => a
- Language.Fixpoint.Smt.Theories: setDif :: Symbol
+ Language.Fixpoint.Smt.Theories: setDif :: IsString a => a
- Language.Fixpoint.Smt.Theories: setEmp :: Symbol
+ Language.Fixpoint.Smt.Theories: setEmp :: IsString a => a
- Language.Fixpoint.Smt.Theories: setEmpty :: Symbol
+ Language.Fixpoint.Smt.Theories: setEmpty :: IsString a => a
- Language.Fixpoint.Smt.Theories: setMem :: Symbol
+ Language.Fixpoint.Smt.Theories: setMem :: IsString a => a
- Language.Fixpoint.Smt.Theories: setSng :: Symbol
+ Language.Fixpoint.Smt.Theories: setSng :: IsString a => a
- Language.Fixpoint.Smt.Theories: setSub :: Symbol
+ Language.Fixpoint.Smt.Theories: setSub :: IsString a => a
- Language.Fixpoint.Types.Config: Config :: FilePath -> Maybe Int -> Int -> Int -> SMTSolver -> Bool -> Bool -> Bool -> Bool -> Bool -> Eliminate -> Scrape -> Maybe Int -> Maybe Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> [Integer] -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> String -> Config
+ Language.Fixpoint.Types.Config: Config :: FilePath -> Maybe Int -> Int -> Int -> SMTSolver -> Bool -> Bool -> Bool -> Bool -> Bool -> Eliminate -> Scrape -> Maybe Int -> Maybe Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> [Integer] -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> String -> Bool -> Config

Files

CHANGES.md view
@@ -2,6 +2,21 @@  ## NEXT ++## 0.9.6.3.1 (2024-08-21)++- Added support for ghc-9.10.1+- Use `;` for comments in SMTParse (as done in SMTLIB) [#700](https://github.com/ucsd-progsys/liquid-fixpoint/pull/700).+- Extend SMTParser to support lits e.g. for bitvec [#698](https://github.com/ucsd-progsys/liquid-fixpoint/pull/698).+- refactor `Set->Array` elaboration [#696](https://github.com/ucsd-progsys/liquid-fixpoint/pull/696).+- Fixed the polymorphism-related crash caused by a restrictive Set theory encoding [#688](https://github.com/ucsd-progsys/liquid-fixpoint/pull/688).+- Do not constant-fold div by zero [#686](https://github.com/ucsd-progsys/liquid-fixpoint/issue/686).+- Copy over the HOF configuraration options in hornFInfo [#684](https://github.com/ucsd-progsys/liquid-fixpoint/pull/684).+- Use SMTLIB style serialization/deserialization for Horn queries [#683](https://github.com/ucsd-progsys/liquid-fixpoint/pull/683).+- Print SMT preamble to the logfile when constructing context [#681](https://github.com/ucsd-progsys/liquid-fixpoint/pull/681).+- Allow reading/saving horn queries from/to JSON [#680](https://github.com/ucsd-progsys/liquid-fixpoint/pull/680).+- Extend parser to allow boolean function arguments [#678](https://github.com/ucsd-progsys/liquid-fixpoint/pull/678).+ ## 0.9.6.3 (2024-01-29)  - For now we stopped folding constants that contain NaN [#670](https://github.com/ucsd-progsys/liquid-fixpoint/pull/670)@@ -29,27 +44,27 @@ ## 0.8.6.4  - Fix bugs in PLE-- Move to GHC 8.6.4 +- Move to GHC 8.6.4 - Add `fuel` parameter to debug unfolding in PLE -## 0.8.0.1 +## 0.8.0.1  - Support for HORN-NNF format clauses, see `tests/horn/{pos,neg}/*.smt2` - Support for "existential binders", see `tests/pos/ebind-*.fq` for example.   This only works with `--eliminate`.-- Move to GHC 8.4.3 +- Move to GHC 8.4.3  ## 0.7.0.0  - New `eliminate` based solver (see ICFP 2017 paper for algorithm) - Proof by Logical Evaluation see `tests/proof`-- SMTLIB2 ADTs to make data constructors injective +- SMTLIB2 ADTs to make data constructors injective - Uniformly support polymorphic functions via `apply` and elaborate  ## 0.3.0.0  - Make interpreted mul and div the default, when `solver = z3`-- Use `higherorder` flag to allow higher order binders into the environment +- Use `higherorder` flag to allow higher order binders into the environment  ## 0.2.2.0 
bin/Fixpoint.hs view
@@ -24,7 +24,11 @@       | otherwise  = solveFQ  isHorn :: F.Config -> Bool-isHorn cfg = F.isExtFile F.Smt2 (F.srcFile cfg) || F.stdin cfg+isHorn cfg = F.isExtFile F.Smt2 file +          || F.isExtFile F.Json file+          || F.stdin cfg+  where +    file = F.srcFile cfg  errorExit :: F.Error -> IO ExitCode errorExit e = do
liquid-fixpoint.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               liquid-fixpoint-version:            0.9.6.3+version:            0.9.6.3.1 synopsis:           Predicate Abstraction-based Horn-Clause/Implication Constraint Solver description:   This package implements an SMTLIB based Horn-Clause\/Logical Implication constraint@@ -25,7 +25,7 @@ license:            BSD-3-Clause license-file:       LICENSE build-type:         Simple-tested-with:        GHC == 9.6.3, GHC == 9.4.7, GHC == 9.2.3+tested-with:        GHC == 9.10.1, GHC == 9.8.2, GHC == 9.6.5 extra-source-files: tests/neg/*.fq                     tests/pos/*.fq                     unix/Language/Fixpoint/Utils/*.hs@@ -66,6 +66,7 @@                     Language.Fixpoint.Graph.Types                     Language.Fixpoint.Horn.Info                     Language.Fixpoint.Horn.Parse+                    Language.Fixpoint.Horn.SMTParse                     Language.Fixpoint.Horn.Solve                     Language.Fixpoint.Horn.Transformations                     Language.Fixpoint.Horn.Types@@ -152,7 +153,6 @@                   , parser-combinators                   , pretty               >= 1.1.3.1                   , process-                  , typed-process                   , rest-rewrite >= 0.3.0                   , smtlib-backends >= 0.3                   , smtlib-backends-process >= 0.3@@ -174,6 +174,8 @@    if impl(ghc<9.6)     ghc-options: -Wno-unused-imports+  if impl(ghc>9.8)+    ghc-options: -Wno-x-partial   if flag(devel)     ghc-options: -Werror   if !os(windows)@@ -210,10 +212,9 @@                   , mtl           >= 2.2.2                   , optparse-applicative                   , process-                  , typed-process                   , stm           >= 2.4                   , tagged-                  , tasty         >= 0.10 && < 1.5+                  , tasty         ^>= 1.5                   , tasty-ant-xml                   , tasty-hunit   >= 0.9                   , tasty-rerun   >= 1.1.12
src/Language/Fixpoint/Horn/Info.hs view
@@ -6,6 +6,7 @@   ) where  import           Control.Monad (forM)+import           Data.Ord (Down(..), comparing) import qualified Data.HashMap.Strict            as M import qualified Data.List                      as L import qualified Data.Tuple                     as Tuple@@ -17,7 +18,7 @@ import qualified Language.Fixpoint.Horn.Types   as H import qualified Data.Maybe                     as Mb -hornFInfo :: F.Config -> H.Query a -> F.FInfo a+hornFInfo :: (F.Fixpoint a, F.PPrint a) => F.Config -> H.Query a -> F.FInfo a hornFInfo cfg q = mempty   { F.cm        = cs   , F.bs        = be2@@ -28,6 +29,7 @@   , F.dLits     = F.fromMapSEnv $ H.qDis q   , F.ae        = axEnv cfg q cs   , F.ddecls    = H.qData q+  , F.hoInfo    = F.cfgHoInfo cfg   }   where     be0         = F.emptyBindEnv@@ -119,7 +121,7 @@     err1       = F.panic ("Unknown Horn variable: " ++ F.showpp k)  -----------------------------------------------------------------------------------hornWfs :: F.BindEnv a -> [H.Var a] -> (F.BindEnv a, KVEnv a)+hornWfs :: (F.PPrint a) => F.BindEnv a -> [H.Var a] -> (F.BindEnv a, KVEnv a) ---------------------------------------------------------------------------------- hornWfs be vars = (be', kve)   where@@ -127,7 +129,7 @@     (be', is)   = L.mapAccumL kvInfo be vars     kname       = H.hvName . kvVar -kvInfo :: F.BindEnv a -> H.Var a -> (F.BindEnv a, KVInfo a)+kvInfo :: (F.PPrint a) => F.BindEnv a -> H.Var a -> (F.BindEnv a, KVInfo a) kvInfo be k       = (be', KVInfo k (Misc.fst3 <$> xts) wfc)   where     -- make the WfC@@ -224,7 +226,7 @@     ixts <- forM xs $ \x -> do               (t, i) <- lookupBindEnv x env               return (i, x, t)-    return [ (x, t) | (_, x, t) <- reverse . L.sort $ ixts ]+    return [ (x, t) | (_, x, t) <- L.sortBy (comparing Down) ixts ]      -- ixts = [ (i, x, t) | x <- xs, (i, t) <- lookupBindEnv x env ] 
src/Language/Fixpoint/Horn/Parse.hs view
@@ -7,6 +7,7 @@   , hPredP   , hQualifierP   , hVarP+  , numericDeclP ) where  import           Language.Fixpoint.Parse@@ -17,11 +18,11 @@ import qualified Data.HashMap.Strict            as M  --------------------------------------------------------------------------------hornP :: Parser (H.TagQuery, [String])+hornP :: Parser H.TagQuery ------------------------------------------------------------------------------- hornP = do   hThings <- many hThingP-  pure (mkQuery hThings, [ o | HOpt o <- hThings ])+  pure (mkQuery hThings)  mkQuery :: [HThing a] -> H.Query a mkQuery things = H.Query@@ -33,6 +34,8 @@   , H.qEqns  =            [ e     | HDef e  <- things ]   , H.qMats  =            [ m     | HMat m  <- things ]   , H.qData  =            [ dd    | HDat dd <- things ]+  , H.qOpts  =            [ o     | HOpt o  <- things ]+  , H.qNums  =            [ n     | HNum n  <- things ]   }  -- | A @HThing@ describes the kinds of things we may see, in no particular order@@ -50,7 +53,7 @@   | HMat  F.Rewrite   | HDat !F.DataDecl   | HOpt !String-  | HNum ()+  | HNum  F.Symbol   deriving (Functor)  hThingP :: Parser (HThing H.Tag)@@ -67,10 +70,11 @@         <|> HDat  <$> (reserved "data"       *> dataDeclP)         <|> HNum  <$> (reserved "numeric"    *> numericDeclP) -numericDeclP :: Parser ()+numericDeclP :: Parser F.Symbol numericDeclP = do-  sym <- locUpperIdP-  addNumTyCon (F.val sym)+  x <- F.val <$> locUpperIdP+  addNumTyCon x+  pure x  ------------------------------------------------------------------------------- hCstrP :: Parser (H.Cstr H.Tag)
+ src/Language/Fixpoint/Horn/SMTParse.hs view
@@ -0,0 +1,348 @@++{-# LANGUAGE DeriveFunctor #-}++module Language.Fixpoint.Horn.SMTParse (+    hornP+  , hCstrP+  , hPredP+  , hQualifierP+  , hVarP+  , exprP+  , sortP+) where++import qualified Language.Fixpoint.Parse        as FP (Parser, addNumTyCon, lexeme', locLexeme', reserved', reservedOp', symbolR, upperIdR, lowerIdR, stringR, naturalR, mkFTycon)+import qualified Language.Fixpoint.Types        as F+import qualified Language.Fixpoint.Horn.Types   as H+import           Text.Megaparsec                hiding (State)+import           Text.Megaparsec.Char           (space1, string, char)+import qualified Data.HashMap.Strict            as M+import qualified Data.Text as T+import qualified Text.Megaparsec.Char.Lexer  as L++type FParser = FP.Parser++fAddNumTyCon :: F.Symbol -> FP.Parser ()+fAddNumTyCon = FP.addNumTyCon++lexeme :: FParser a -> FParser a+lexeme = FP.lexeme' spaces++locLexeme :: FP.Parser a -> FP.Parser (F.Located a)+locLexeme = FP.locLexeme' spaces++-- | Consumes all whitespace, including LH comments.+--+-- Should not be used directly, but primarily via 'lexeme'.+--+-- The only "valid" use case for spaces is in top-level parsing+-- function, to consume initial spaces.+--+spaces :: FParser ()+spaces =+  L.space+    space1+    lineComment+    blockComment++lineComment :: FParser ()+lineComment = L.skipLineComment ";"++blockComment :: FParser ()+blockComment = L.skipBlockComment "/* " "*/"++reserved :: String -> FParser ()+reserved = FP.reserved' spaces++reservedOp :: String -> FParser ()+reservedOp = FP.reservedOp' spaces++sym :: String -> FParser String+sym x = lexeme (string x)++parens :: FParser a -> FParser a+parens = between (sym "(") (sym ")")++stringLiteral :: FParser String+stringLiteral = lexeme FP.stringR <?> "string literal"++symbolP :: FParser F.Symbol+symbolP = lexeme FP.symbolR <?> "identifier"++fIntP :: FParser Int+fIntP = fromInteger <$> natural++natural :: FParser Integer+natural = lexeme FP.naturalR <?> "nat literal"++double :: FParser Double+double = lexeme L.float <?> "float literal"+++locUpperIdP, locSymbolP :: FParser F.LocSymbol+locUpperIdP = locLexeme FP.upperIdR+locSymbolP  = locLexeme FP.symbolR++upperIdP :: FP.Parser F.Symbol+upperIdP = lexeme FP.upperIdR <?> "upperIdP"++lowerIdP :: FP.Parser F.Symbol+lowerIdP = lexeme FP.lowerIdR <?> "upperIdP"++fTyConP :: FParser F.FTycon+fTyConP+  =   (reserved "int"     >> return F.intFTyCon)+  <|> (reserved "Integer" >> return F.intFTyCon)+  <|> (reserved "Int"     >> return F.intFTyCon)+  <|> (reserved "real"    >> return F.realFTyCon)+  <|> (reserved "bool"    >> return F.boolFTyCon)+  <|> (reserved "num"     >> return F.numFTyCon)+  <|> (reserved "Str"     >> return F.strFTyCon)+  <|> (FP.mkFTycon        =<<  locUpperIdP)+++fTrueP :: FP.Parser F.Expr+fTrueP = reserved "true"  >> return F.PTrue++fFalseP :: FP.Parser F.Expr+fFalseP = reserved "false" >> return F.PFalse++fSymconstP :: FP.Parser F.SymConst+fSymconstP =  F.SL . T.pack <$> stringLiteral++-- | Parser for literal numeric constants: floats or integers without sign.+constantP :: FParser F.Constant+constantP =+     try (F.R <$> double)   -- float literal+ <|> F.I <$> natural        -- nat literal++-------------------------------------------------------------------------------+hornP :: FParser H.TagQuery+-------------------------------------------------------------------------------+hornP = do+  spaces+  hThings <- many hThingP+  pure (mkQuery hThings)++mkQuery :: [HThing a] -> H.Query a+mkQuery things = H.Query+  { H.qQuals =            [ q     | HQual q  <- things ]+  , H.qVars  =            [ k     | HVar  k  <- things ]+  , H.qCstr  = H.CAnd     [ c     | HCstr c  <- things ]+  , H.qCon   = M.fromList [ (x,t) | HCon x t <- things ]+  , H.qDis   = M.fromList [ (x,t) | HDis x t <- things ]+  , H.qEqns  =            [ e     | HDef e   <- things ]+  , H.qMats  =            [ m     | HMat m   <- things ]+  , H.qData  =            [ dd    | HDat dd  <- things ]+  , H.qOpts  =            [ o     | HOpt o   <- things ]+  , H.qNums  =            [ s     | HNum s   <- things ]+  }++-- | A @HThing@ describes the kinds of things we may see, in no particular order+--   in a .smt2 query file.++data HThing a+  = HQual !F.Qualifier+  | HVar  !(H.Var a)+  | HCstr !(H.Cstr a)++  -- for uninterpred functions and ADT constructors+  | HCon  F.Symbol F.Sort+  | HDis  F.Symbol F.Sort+  | HDef  F.Equation+  | HMat  F.Rewrite+  | HDat !F.DataDecl+  | HOpt !String+  | HNum  F.Symbol+  deriving (Functor)++hThingP :: FParser (HThing H.Tag)+hThingP  = spaces >> parens body+  where+    body =  HQual <$> (reserved "qualif"     *> hQualifierP)+        <|> HCstr <$> (reserved "constraint" *> hCstrP)+        <|> HVar  <$> (reserved "var"        *> hVarP)+        <|> HOpt  <$> (reserved "fixpoint"   *> stringLiteral)+        <|> HCon  <$> (reserved "constant"   *> symbolP) <*> sortP+        <|> HDis  <$> (reserved "distinct"   *> symbolP) <*> sortP+        <|> HDef  <$> (reserved "define"     *> defineP)+        <|> HMat  <$> (reserved "match"      *> matchP)+        <|> HDat  <$> (reserved "datatype"   *> dataDeclP)+        <|> HNum  <$> (reserved "numeric"    *> numericDeclP)++numericDeclP :: FParser F.Symbol+numericDeclP = do+  x <- F.val <$> locUpperIdP+  fAddNumTyCon x+  pure x++-------------------------------------------------------------------------------+hCstrP :: FParser (H.Cstr H.Tag)+-------------------------------------------------------------------------------+hCstrP =  try (parens body)+      <|> H.Head <$> hPredP                            <*> pure H.NoTag+  where+    body =  H.CAnd <$> (reserved "and"    *> many hCstrP)+        <|> H.All  <$> (reserved "forall" *> hBindP)  <*> hCstrP+        <|> H.Any  <$> (reserved "exists" *> hBindP)  <*> hCstrP+        <|> H.Head <$> (reserved "tag"    *> hPredP)  <*> (H.Tag <$> stringLiteral)++hBindP :: FParser (H.Bind H.Tag)+hBindP   = parens $ do+  (x, t) <- symSortP+  H.Bind x t <$> hPredP <*> pure H.NoTag++-------------------------------------------------------------------------------+hPredP :: FParser H.Pred+-------------------------------------------------------------------------------+hPredP = parens body+  where+    body =  H.Var  <$> kvSymP <*> some symbolP+        <|> H.PAnd <$> (reserved "and" *> some hPredP)+        <|> H.Reft <$> exprP++kvSymP :: FParser F.Symbol+kvSymP = char '$' *> symbolP++-------------------------------------------------------------------------------+-- | Qualifiers+-------------------------------------------------------------------------------+hQualifierP :: FParser F.Qualifier+hQualifierP = do+  pos    <- getSourcePos+  n      <- upperIdP+  params <- parens (some symSortP)+  body   <- exprP+  return  $ F.mkQual n (mkParam <$> params) body pos++mkParam :: (F.Symbol, F.Sort) -> F.QualParam+mkParam (x, t) = F.QP x F.PatNone t++-------------------------------------------------------------------------------+-- | Horn Variables+-------------------------------------------------------------------------------++hVarP :: FParser (H.Var H.Tag)+hVarP = H.HVar <$> kvSymP <*> parens (some sortP) <*> pure H.NoTag++-------------------------------------------------------------------------------+-- | Helpers+-------------------------------------------------------------------------------+sPairP :: FParser a -> FParser b -> FParser (a, b)+sPairP aP bP = parens ((,) <$> aP <*> bP)++sMany :: FParser a -> FParser [a]+sMany p = parens (many p)+++symSortP :: FParser (F.Symbol, F.Sort)+symSortP = sPairP  symbolP sortP+-- symSortP = fParens ((,) <$> fSymbolP <*> sortP)++dataDeclP :: FParser F.DataDecl+dataDeclP = do+  (tc, n) <- sPairP fTyConP fIntP+  ctors   <- sMany dataCtorP+  pure     $ F.DDecl tc n ctors++dataCtorP :: FParser F.DataCtor+dataCtorP = parens (F.DCtor <$> locSymbolP <*> sMany dataFieldP)++dataFieldP :: FParser F.DataField+dataFieldP = uncurry F.DField <$> sPairP locSymbolP sortP++bindsP :: FParser [(F.Symbol, F.Sort)]+bindsP = sMany bindP++bindP :: FParser (F.Symbol, F.Sort)+bindP = sPairP symbolP sortP++defineP :: FParser F.Equation+defineP = do+  name   <- symbolP+  xts    <- bindsP+  s      <- sortP+  body   <- exprP+  return  $ F.mkEquation name xts body s++matchP :: FParser F.Rewrite+matchP = do+  f    <- symbolP+  d:xs <- parens (some symbolP)+  F.SMeasure f d xs <$> exprP++sortP :: FParser F.Sort+sortP =  (string "@" >> (F.FVar <$> parens fIntP))+     <|> (reserved "Int"  >> return F.FInt)+     <|> (reserved "Real" >> return F.FReal)+     <|> (reserved "Frac" >> return F.FFrac)+     <|> (reserved "num" >> return  F.FNum)+     <|> (F.fAppTC <$> fTyConP <*> pure [])+     <|> (F.FObj . F.symbol <$> lowerIdP)+     <|> try (parens (reserved "func" >> (mkFunc <$> fIntP <*> sMany sortP <*> sortP)))+     <|> try (parens (reserved "list" >> (mkList <$> sortP)))+     <|> parens (F.fAppTC <$> fTyConP <*> many sortP)++mkFunc :: Int -> [F.Sort] -> F.Sort -> F.Sort+mkFunc n ss s = F.mkFFunc n (ss ++ [s])++mkList :: F.Sort -> F.Sort+mkList s = F.fAppTC F.listFTyCon [s]++exprP :: FParser F.Expr+exprP+  =   fTrueP+  <|> fFalseP+  <|> (F.ESym <$> fSymconstP)+  <|> (F.ECon <$> constantP)+  <|> (F.EVar <$> symbolP)+  <|> parens pExprP++pExprP :: FParser F.Expr+pExprP+  =   (reserved   "if"     >> (F.EIte   <$> exprP <*> exprP <*> exprP))+  <|> (reserved   "lit"    >> (mkLit    <$> stringLiteral <*> sortP))+  <|> (reserved   "cast"   >> (F.ECst   <$> exprP <*> sortP))+  <|> (reserved   "not"    >> (F.PNot   <$> exprP))+  <|> (reservedOp "=>"     >> (F.PImp   <$> exprP <*> exprP))+  <|> (reservedOp "<=>"    >> (F.PIff   <$> exprP <*> exprP))+  <|> (reserved   "and"    >> (F.PAnd   <$> many exprP))+  <|> (reserved   "or"     >> (F.POr    <$> many exprP))+  <|> (reserved   "forall" >> (F.PAll   <$> bindsP <*> exprP))+  <|> (reserved   "exists" >> (F.PExist <$> bindsP <*> exprP))+  <|> (reserved   "lam"    >> (F.ELam   <$> bindP <*> exprP))+  <|> (reserved   "coerce" >> (F.ECoerc <$> sortP <*> sortP <*> exprP))+  <|> (reserved   "ETApp"  >> (F.ETApp  <$> exprP <*> sortP))+  <|> (reserved   "ETAbs"  >> (F.ETAbs  <$> exprP <*> symbolP))+  <|> try (F.EBin  <$> bopP <*> exprP <*> exprP)+  <|> try (F.PAtom <$> brelP <*> exprP <*> exprP)+  <|> try (sym "-" >> (F.ENeg <$> exprP))+  <|> (mkApp <$> some exprP)++mkLit :: String -> F.Sort -> F.Expr+mkLit l t = F.ECon (F.L (T.pack l) t)++mkApp :: [F.Expr] -> F.Expr+mkApp (e:es) = F.eApps e es+mkApp _      = error "impossible"++bopP :: FParser F.Bop+bopP+  =  (sym "+"   >> return F.Plus)+ <|> (sym "-"   >> return F.Minus)+ <|> (sym "*"   >> return F.Times)+ <|> (sym "/"   >> return F.Div)+ <|> (sym "mod" >> return F.Mod)+ <|> (sym "*."  >> return F.RTimes)+ <|> (sym "/."  >> return F.RDiv)++brelP :: FParser F.Brel+brelP+  =  (sym "="  >> return F.Eq)+ <|> (sym "!=" >> return F.Ne)+ <|> (sym "~~" >> return F.Ueq)+ <|> (sym "!~" >> return F.Une)+ <|> (sym ">=" >> return F.Ge)+ <|> (sym ">"  >> return F.Gt)+ <|> (sym "<=" >> return F.Le)+ <|> (sym "<"  >> return F.Lt)
src/Language/Fixpoint/Horn/Solve.hs view
@@ -15,47 +15,74 @@ import qualified Language.Fixpoint.Types        as F import qualified Language.Fixpoint.Types.Config as F import qualified Language.Fixpoint.Horn.Types   as H+ import qualified Language.Fixpoint.Horn.Parse   as H+import qualified Language.Fixpoint.Horn.SMTParse   as SH+ import qualified Language.Fixpoint.Horn.Transformations as Tx import Text.PrettyPrint.HughesPJ.Compat ( render ) import Language.Fixpoint.Horn.Info ( hornFInfo )  import System.Console.CmdArgs.Verbosity ( whenLoud )-+import qualified Data.Aeson as Aeson -- import Debug.Trace (traceM)  ---------------------------------------------------------------------------------- solveHorn :: F.Config -> IO ExitCode ---------------------------------------------------------------------------------- solveHorn baseCfg = do-  (q, opts) <- parseQuery baseCfg+  q <- parseQuery baseCfg    -- If you want to set --eliminate=none, you better make it a pragma   cfgElim <- if F.eliminate baseCfg == F.None            then pure (baseCfg { F.eliminate =  F.Some })            else pure baseCfg -  cfgPragmas <- F.withPragmas cfgElim opts+  cfgPragmas <- F.withPragmas cfgElim (H.qOpts q)    when (F.save cfgPragmas) (saveHornQuery cfgPragmas q)    r <- solve cfgPragmas q   Solver.resultExitCode cfgPragmas r -parseQuery :: F.Config -> IO (H.Query H.Tag, [String])+parseQuery :: F.Config -> IO H.TagQuery parseQuery cfg-  | F.stdin cfg = Parse.parseFromStdIn H.hornP-  | otherwise   = Parse.parseFromFile H.hornP (F.srcFile cfg)+  | F.stdin cfg = Parse.parseFromStdIn hornP+  | json        = loadFromJSON file+  | otherwise   = Parse.parseFromFile hornP file+  where+    json  = Files.isExtFile Files.Json file+    file  = F.srcFile cfg+    hornP = if F.noSmtHorn cfg then H.hornP else SH.hornP +loadFromJSON :: FilePath -> IO H.TagQuery+loadFromJSON f = do+  r <- Aeson.eitherDecodeFileStrict f+  case r of+    Right v -> return v+    Left err -> error ("Error in loadFromJSON: " ++ err)+ saveHornQuery :: F.Config -> H.Query H.Tag -> IO () saveHornQuery cfg q = do+  saveHornSMT2 cfg q+  saveHornJSON cfg q++saveHornSMT2 :: H.ToHornSMT a => F.Config -> a -> IO ()+saveHornSMT2 cfg q = do   let hq   = F.queryFile Files.HSmt2 cfg   putStrLn $ "Saving Horn Query: " ++ hq ++ "\n"   Misc.ensurePath hq-  writeFile hq $ render (F.pprint q)+  writeFile hq $ render ({- F.pprint -} H.toHornSMT q) +saveHornJSON :: F.Config -> H.Query H.Tag -> IO ()+saveHornJSON cfg q = do+  let hjson   = F.queryFile Files.HJSON cfg+  putStrLn $ "Saving Horn Query: " ++ hjson ++ "\n"+  Misc.ensurePath hjson+  Aeson.encodeFile hjson q+ -----------------------------------------------------------------------------------eliminate :: (F.PPrint a) => F.Config -> H.Query a -> IO (H.Query a)+eliminate :: (F.Fixpoint a, F.PPrint a) => F.Config -> H.Query a -> IO (H.Query a) ---------------------------------------------------------------------------------- eliminate cfg q   | F.eliminate cfg == F.Existentials = do
src/Language/Fixpoint/Horn/Transformations.hs view
@@ -23,7 +23,11 @@ import qualified Data.HashMap.Strict          as M import           Data.String                  (IsString (..)) import           Data.Either                  (partitionEithers, rights)+#if MIN_VERSION_base(4,20,0)+import           Data.List                    (nub)+#else import           Data.List                    (nub, foldl')+#endif import qualified Data.Set                     as S import qualified Data.HashSet                 as HS import qualified Data.Graph                   as DG@@ -71,16 +75,19 @@ -- can depend on other ks, pis cannot directly depend on other pis -- - predicate for exists binder is `true`. (TODO: is this pre stale?) -solveEbs :: (F.PPrint a) => F.Config -> Query a -> IO (Query a)+solveEbs :: (F.Fixpoint a, F.PPrint a) => F.Config -> Query a -> IO (Query a) -------------------------------------------------------------------------------solveEbs cfg query@(Query qs vs cstr cons dist eqns mats dds) = do+solveEbs cfg query@(Query {}) = do+  let cons = qCon query+  let cstr = qCstr query+  let dist = qDis query   -- clean up   let normalizedC = flatten . pruneTauts $ hornify cstr   whenLoud $ putStrLn "Normalized EHC:"   whenLoud $ putStrLn $ F.showpp normalizedC    -- short circuit if no ebinds are present-  if isNNF cstr then pure $ Query qs vs normalizedC cons dist eqns mats dds else do+  if isNNF cstr then pure $ query{ qCstr = normalizedC } else do   let kvars = boundKvars normalizedC    whenLoud $ putStrLn "Skolemized:"@@ -129,7 +136,7 @@   let solvedSide = substPiSols solvedPiCstrs sideCut   whenLoud $ putStrLn $ F.showpp solvedSide -  pure (Query qs vs (CAnd [solvedHorn, solvedSide]) cons dist eqns mats dds)+  pure (query { qCstr = CAnd [solvedHorn, solvedSide] })  -- | Collects the defining constraint for π -- that is, given `∀ Γ.∀ n.π => c`, returns `((π, n:Γ), c)`@@ -929,10 +936,10 @@ isNNF (All _ c) = isNNF c isNNF Any{} = False -calculateCuts :: F.Config -> Query a -> Cstr a -> S.Set F.Symbol-calculateCuts cfg (Query qs vs _ cons dist eqns mats dds) nnf = convert $ FG.depCuts deps+calculateCuts :: (F.Fixpoint a, F.PPrint a) => F.Config -> Query a -> Cstr a -> S.Set F.Symbol+calculateCuts cfg q@(Query {}) nnf = convert $ FG.depCuts deps   where-    (_, deps) = elimVars cfg (hornFInfo cfg $ Query qs vs nnf cons dist eqns mats dds)+    (_, deps) = elimVars cfg (hornFInfo cfg $ q { qCstr = nnf })     convert hashset = S.fromList $ F.kv <$> HS.toList hashset  forgetPiVars :: S.Set F.Symbol -> Cstr a -> Cstr a@@ -969,13 +976,32 @@   flatten :: a -> a  instance Flatten (Cstr a) where-  flatten (CAnd cstrs) = case flatten cstrs of-                        [c] -> c-                        cs -> CAnd cs-  flatten (Head p a) = Head (flatten p) a-  flatten (All (Bind x t p l) c) = All (Bind x t (flatten p) l) (flatten c)-  flatten (Any (Bind x t p l) c) = Any (Bind x t (flatten p) l) (flatten c)+  flatten c = case flattenCstr c of+                Just c' -> c'+                Nothing -> CAnd [] +  -- flatten (CAnd cstrs) = case flatten cstrs of+  --                       [c] -> c+  --                       cs -> CAnd cs+  -- flatten (Head p a) = Head (flatten p) a+  -- flatten (All (Bind x t p l) c) = All (Bind x t (flatten p) l) (flatten c)+  -- flatten (Any (Bind x t p l) c) = Any (Bind x t (flatten p) l) (flatten c)++flattenCstr :: Cstr a -> Maybe (Cstr a)+flattenCstr = go+  where+    go (Head (PAnd [])  _) = Nothing+    go (Head (Reft p) _)+      | F.isTautoPred p    = Nothing+    go (Head p a)          = Just $ Head (flatten p) a+    go (CAnd cs)           = mk . concatMap splitAnd $ mapMaybe flattenCstr cs+    go (All (Bind x t p l) c) = All (Bind x t (flatten p) l) <$> go c+    go (Any (Bind x t p l) c) = Any (Bind x t (flatten p) l) <$> go c++    mk []  = Nothing+    mk [c] = Just c+    mk cs  = Just (CAnd cs)+ instance Flatten [Cstr a] where   flatten (CAnd cs : xs) = flatten cs ++ flatten xs   flatten (x:xs)@@ -984,6 +1010,12 @@     | otherwise                  = fx:flatten xs     where fx = flatten x   flatten [] = []++++splitAnd :: Cstr a -> [Cstr a]+splitAnd (CAnd cs) = cs+splitAnd c         = [c]  instance Flatten Pred where   flatten (PAnd preds) = case flatten preds of
src/Language/Fixpoint/Horn/Types.hs view
@@ -8,6 +8,9 @@ {-# LANGUAGE DeriveDataTypeable         #-} {-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE DeriveTraversable          #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ViewPatterns #-}  module Language.Fixpoint.Horn.Types   ( -- * Horn Constraints and their components@@ -30,6 +33,9 @@      -- * extract qualifiers   , quals++    -- * SMTLIB style render+  , ToHornSMT (..)   )   where @@ -45,6 +51,7 @@ import qualified Text.PrettyPrint.HughesPJ.Compat as P import qualified Data.HashMap.Strict as M import           Data.Aeson+import           Data.Aeson.Types  ------------------------------------------------------------------------------- -- | @HVar@ is a Horn variable@@ -54,7 +61,7 @@   , hvArgs :: ![F.Sort] {- len hvArgs > 0 -}    -- ^ sorts of its parameters i.e. of the relation defined by the @HVar@   , hvMeta :: a                                 -- ^ meta-data   }-  deriving (Eq, Ord, Data, Typeable, Generic, Functor)+  deriving (Eq, Ord, Data, Typeable, Generic, Functor, ToJSON, FromJSON)  ------------------------------------------------------------------------------- -- | @HPred@ is a Horn predicate that appears as LHS (body) or RHS (head) of constraints@@ -63,7 +70,7 @@   = Reft  !F.Expr                               -- ^ r   | Var   !F.Symbol ![F.Symbol]                 -- ^ $k(y1..yn)   | PAnd  ![Pred]                               -- ^ p1 /\ .../\ pn-  deriving (Data, Typeable, Generic, Eq)+  deriving (Data, Typeable, Generic, Eq, ToJSON, FromJSON)   instance Semigroup Pred where@@ -96,7 +103,7 @@ ------------------------------------------------------------------------------- quals :: Cstr a -> [F.Qualifier] --------------------------------------------------------------------------------quals = F.tracepp "horn.quals" . cstrQuals F.emptySEnv F.vv_+quals = F.notracepp "horn.quals" . cstrQuals F.emptySEnv F.vv_  cstrQuals :: F.SEnv F.Sort -> F.Symbol -> Cstr a -> [F.Qualifier] cstrQuals = go@@ -152,13 +159,12 @@   , bPred :: !Pred   , bMeta :: !a   }-  deriving (Data, Typeable, Generic, Functor, Eq)+  deriving (Data, Typeable, Generic, Functor, Eq, ToJSON, FromJSON)  instance F.Subable (Bind a) where     syms     (Bind x _ p _) = x : F.syms p     substa f (Bind v t p a) = Bind (f v) t (F.substa f p) a     substf f (Bind v t p a) = Bind v t (F.substf (F.substfExcept f [v]) p) a-    -- subst su (Bind x t p) = (Bind x t (F.subst su p))     subst su (Bind v t p a)  = Bind v t (F.subst (F.substExcept su [v]) p) a     subst1 (Bind v t p a) su = Bind v t (F.subst1Except [v] p su) a @@ -168,7 +174,7 @@   | CAnd  ![Cstr a]                 -- ^ c1 /\ ... /\ cn   | All   !(Bind a)  !(Cstr a)      -- ^ \all x:t. p => c   | Any   !(Bind a)  !(Cstr a)      -- ^ \exi x:t. p /\ c or is it \exi x:t. p => c?-  deriving (Data, Typeable, Generic, Functor, Eq)+  deriving (Data, Typeable, Generic, Functor, Eq, ToJSON, FromJSON)  cLabel :: Cstr a -> a cLabel cstr = case go cstr of@@ -196,13 +202,15 @@   { qQuals :: ![F.Qualifier]             -- ^ qualifiers over which to solve cstrs   , qVars  :: ![Var a]                   -- ^ kvars, with parameter-sorts   , qCstr  :: !(Cstr a)                  -- ^ list of constraints-  , qCon   :: M.HashMap F.Symbol F.Sort  -- ^ list of constants (uninterpreted functions-  , qDis   :: M.HashMap F.Symbol F.Sort  -- ^ list of constants (uninterpreted functions+  , qCon   :: M.HashMap F.Symbol F.Sort  -- ^ list of constants (uninterpreted functions)+  , qDis   :: M.HashMap F.Symbol F.Sort  -- ^ list of *distinct* constants (uninterpreted functions)   , qEqns  :: ![F.Equation]              -- ^ list of equations   , qMats  :: ![F.Rewrite]               -- ^ list of match-es-  , qData  :: ![F.DataDecl]            -- ^ list of data-declarations+  , qData  :: ![F.DataDecl]              -- ^ list of data-declarations+  , qOpts  :: ![String]                  -- ^ list of fixpoint options+  , qNums  :: ![F.Symbol]                -- ^ list of numeric TyCon (?)   }-  deriving (Data, Typeable, Generic, Functor)+  deriving (Data, Typeable, Generic, Functor, ToJSON, FromJSON)  -- | Tag each query with a possible string denoting "provenance" @@ -228,23 +236,35 @@   toJSON NoTag   = Null   toJSON (Tag s) = String (T.pack s) +instance FromJSON Tag where+  parseJSON Null       = pure NoTag+  parseJSON (String t) = pure (Tag (T.unpack t))+  parseJSON invalid    = prependFailure "parsing `Tag` failed, " (typeMismatch "Object" invalid)+++++ instance F.PPrint (Query a) where   pprintPrec prec t q = P.vcat $ L.intersperse " "     [ P.vcat   (ppQual <$> qQuals q)     , P.vcat   [ppVar k   | k <- qVars q]-    , P.vcat   [ppCon x sort' | (x, sort') <- M.toList (qCon q)]+    , P.vcat   [ppCon x (F.pprint sort') | (x, sort') <- M.toList (qCon q)]     , ppThings Nothing (qEqns  q)     , ppThings (Just "data ") (qData  q)     , P.parens (P.vcat ["constraint", F.pprintPrec (prec+2) t (qCstr q)])     ] +++ ppThings :: F.PPrint a => Maybe P.Doc -> [a] -> P.Doc ppThings pfx qs = P.vcat [ P.parens $ prefix P.<-> F.pprint q | q <- qs]   where     prefix      = fromMaybe "" pfx -ppCon :: F.Symbol -> F.Sort -> P.Doc-ppCon x t = P.parens ("constant" P.<+> F.pprint x P.<+> P.parens (F.pprint t))+ppCon :: F.Symbol -> P.Doc -> P.Doc+ppCon x td = P.parens ("constant" P.<+> F.pprint x P.<+> P.parens td)  ppQual :: F.Qualifier -> P.Doc ppQual (F.Q n xts p _) =  P.parens ("qualif" P.<+> F.pprint n P.<+> ppBlanks (ppArg <$> xts) P.<+> P.parens (F.pprint p))@@ -301,3 +321,161 @@  instance F.PPrint (Bind a) where   pprintPrec _ _ b = P.ptext $ show b+++-----------------------------------------------------------------------------------------------------------------+-- Human readable but robustly parseable SMT-LIB format pretty printer+-----------------------------------------------------------------------------------------------------------------+class ToHornSMT a where+  toHornSMT :: a -> P.Doc++instance ToHornSMT Tag where+  toHornSMT NoTag   = mempty+  toHornSMT (Tag s) = P.text s++instance ToHornSMT F.Symbol where+  toHornSMT s = F.pprint s++instance ToHornSMT (Var a) where+  toHornSMT (HVar k ts _) = P.parens ("var" P.<+> "$" P.<-> F.pprint k P.<+> toHornSMT ts)++instance ToHornSMT (Query a) where+  toHornSMT q = P.vcat $ L.intersperse " "+    [ P.vcat   (toHornOpt <$> qOpts q)+    , P.vcat   (toHornNum <$> qNums q)+    , P.vcat   (toHornSMT <$> qQuals q)+    , P.vcat   (toHornSMT <$> qVars q)+    , P.vcat   [toHornCon x t | (x, t) <- M.toList (qCon q)]+    , P.vcat   (toHornSMT <$> qEqns q)+    , P.vcat   (toHornSMT <$> qData q)+    , P.vcat   (toHornSMT <$> qMats q)+    , P.parens (P.vcat ["constraint", P.nest 1 (toHornSMT (qCstr q))])+    ]+    where+      toHornNum x   = toHornMany ["numeric", toHornSMT x]+      toHornOpt str = toHornMany ["fixpoint", P.text ("\"" ++ str ++ "\"")]+      toHornCon x t = toHornMany ["constant", toHornSMT x, toHornSMT t]++instance ToHornSMT F.Rewrite where+  toHornSMT (F.SMeasure f d xs e) =  P.parens ("match" P.<+> toHornSMT f P.<+> toHornSMT (d:xs) P.<+> toHornSMT e)++instance ToHornSMT F.Qualifier where+  toHornSMT (F.Q n xts p _) =  P.parens ("qualif" P.<+> F.pprint n P.<+> toHornSMT xts P.<+> toHornSMT p)++instance ToHornSMT F.QualParam where+  toHornSMT qp = toHornSMT (F.qpSym qp, F.qpSort qp)++instance ToHornSMT a => ToHornSMT (F.Symbol, a) where+  toHornSMT (x, t) = P.parens $ F.pprint x P.<+> toHornSMT t++instance ToHornSMT a => ToHornSMT [a] where+  toHornSMT = toHornMany . fmap toHornSMT++toHornMany :: [P.Doc] -> P.Doc+toHornMany = P.parens . P.sep -- Misc.intersperse " "++toHornAnd :: (a -> P.Doc) -> [a] -> P.Doc+toHornAnd f xs = P.parens (P.vcat ("and" : (P.nest 1 . f <$> xs)))++instance ToHornSMT F.Equation where+  toHornSMT (F.Equ f xs e s _) = P.parens ("define" P.<+> F.pprint f P.<+> toHornSMT xs P.<+> toHornSMT s P.<+> toHornSMT e)++instance ToHornSMT F.DataDecl where+  toHornSMT (F.DDecl tc n ctors) =+    P.parens $ P.vcat [+      P.text "datatype" P.<+> P.parens (toHornSMT tc P.<+> P.int n)+    , P.parens (P.vcat (toHornSMT <$> ctors))+    ]++instance ToHornSMT F.FTycon where+  toHornSMT c+    | c == F.listFTyCon = "list"+    | otherwise         = toHornSMT (F.symbol c)++instance ToHornSMT a => ToHornSMT (F.Located a) where+  toHornSMT = toHornSMT . F.val+instance ToHornSMT F.DataCtor where+  toHornSMT (F.DCtor x flds) = P.parens (toHornSMT x P.<+> toHornSMT flds)++instance ToHornSMT F.DataField where+  toHornSMT (F.DField x t) = toHornSMT (F.val x, t)++instance ToHornSMT F.Sort where+  toHornSMT = toHornSort++toHornSort :: F.Sort -> P.Doc+toHornSort (F.FVar i)     = "@" P.<-> P.parens (P.int i)+toHornSort F.FInt         = "Int"+toHornSort F.FReal        = "Real"+toHornSort F.FFrac        = "Frac"+toHornSort (F.FObj x)     = toHornSMT x -- P.parens ("obj" P.<+> toHornSMT x)+toHornSort F.FNum         = "num"+toHornSort t@(F.FAbs _ _) = toHornAbsApp t+toHornSort t@(F.FFunc _ _)= toHornAbsApp t+toHornSort (F.FTC c)      = toHornSMT c+toHornSort t@(F.FApp _ _) = toHornFApp (F.unFApp t)++toHornAbsApp :: F.Sort -> P.Doc+toHornAbsApp (F.functionSort -> Just (vs, ss, s)) = P.parens ("func" P.<+> P.int (length vs) P.<+> toHornSMT ss P.<+> toHornSMT s )+toHornAbsApp _                                    = error "Unexpected nothing function sort"++toHornFApp     :: [F.Sort] -> P.Doc+toHornFApp [t] = toHornSMT t+toHornFApp ts  = toHornSMT ts++instance ToHornSMT F.Subst where+  toHornSMT (F.Su m) = toHornSMT (Misc.hashMapToAscList m)++instance ToHornSMT (Bind a) where+  toHornSMT (Bind x t p _) = P.parens (toHornSMT (x, t) P.<+> toHornSMT p)++instance ToHornSMT Pred where+  toHornSMT (Reft p)   = P.parens (toHornSMT p)+  toHornSMT (Var k xs) = toHornMany (toHornSMT (F.KV k) : (toHornSMT <$> xs))+  toHornSMT (PAnd ps)  = toHornMany ("and" : (toHornSMT <$> ps))++instance ToHornSMT F.KVar where+  toHornSMT (F.KV k) = "$" P.<-> toHornSMT k++instance ToHornSMT F.Expr where+  toHornSMT = toHornExpr++toHornExpr :: F.Expr -> P.Doc+toHornExpr (F.ESym c)        = F.pprint c+toHornExpr (F.ECon c)        = F.pprint c+toHornExpr (F.EVar s)        = toHornSMT s+toHornExpr (F.ENeg e)        = P.parens ("-" P.<+> toHornExpr e)+toHornExpr (F.EApp e1 e2)    = toHornSMT [e1, e2]+toHornExpr (F.EBin o e1 e2)  = toHornOp   (F.toFix o) [e1, e2]+toHornExpr (F.EIte e1 e2 e3) = toHornOp "if"  [e1, e2, e3]+toHornExpr (F.ECst e t)      = toHornMany ["cast", toHornSMT e, toHornSMT t]+toHornExpr (F.PNot p)        = toHornOp "not"  [p]+toHornExpr (F.PImp e1 e2)    = toHornOp "=>"   [e1, e2]+toHornExpr (F.PIff e1 e2)    = toHornOp "<=>"  [e1, e2]+toHornExpr e@F.PTrue         = F.pprint e+toHornExpr e@F.PFalse        = F.pprint e+toHornExpr (F.PAnd es)       = toHornOp "and" es+toHornExpr (F.POr  es)       = toHornOp "or"  es+toHornExpr (F.PAtom r e1 e2) = toHornOp (F.toFix r) [e1, e2]+toHornExpr (F.PAll xts p)    = toHornMany ["forall", toHornSMT xts, toHornSMT p]+toHornExpr (F.PExist xts p)  = toHornMany ["exists", toHornSMT xts, toHornSMT p]+toHornExpr (F.ELam b e)      = toHornMany ["lam", toHornSMT b, toHornSMT e]+toHornExpr (F.ECoerc a t e)  = toHornMany ["coerce", toHornSMT a, toHornSMT t, toHornSMT e]+toHornExpr (F.PKVar k su)    = toHornMany [toHornSMT k, toHornSMT su]+toHornExpr (F.ETApp e s)     = toHornMany ["ETApp" , toHornSMT e, toHornSMT s]+toHornExpr (F.ETAbs e s)     = toHornMany ["ETAbs" , toHornSMT e, toHornSMT s]+toHornExpr (F.PGrad k _ _ e) = toHornMany ["&&", toHornSMT e, toHornSMT k]++toHornOp :: ToHornSMT a => P.Doc -> [a] -> P.Doc+toHornOp op es = toHornMany (op : (toHornSMT <$> es))++instance ToHornSMT (Cstr a) where+  toHornSMT = toHornCstr++toHornCstr :: Cstr a -> P.Doc+toHornCstr (Head p _) = toHornSMT p+toHornCstr (CAnd cs)  = toHornAnd toHornCstr cs+toHornCstr (All b c)  = P.parens (P.vcat ["forall" P.<+> toHornSMT b+                                         , P.nest 1 (toHornCstr c)])+toHornCstr (Any b c)  = P.parens (P.vcat ["exists" P.<+> toHornSMT b+                                         , P.nest 1 (toHornCstr c)])
src/Language/Fixpoint/Misc.hs view
@@ -334,6 +334,9 @@ isRight (Right _) = True isRight _         = False +dbgFalse :: Bool+dbgFalse = 1 > (2 :: Int)+ componentsWith :: (Ord c) => (a -> [(b, c, [c])]) -> a -> [[b]] componentsWith eF x = map (fst3 . f) <$> vss   where@@ -436,4 +439,3 @@ fold1M _ []         = errorstar "fold1M with empty list" fold1M _ [x]        = return x fold1M f (x1:x2:xs) = do { x <- f x1 x2; fold1M f (x:xs) }-
src/Language/Fixpoint/Parse.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                       #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE FlexibleInstances         #-} {-# LANGUAGE NoMonomorphismRestriction #-}@@ -15,6 +16,7 @@    -- * Some Important keyword and parsers   , reserved, reservedOp+  , reserved', reservedOp'   , locReserved   , parens  , brackets, angles, braces   , semi    , comma@@ -22,18 +24,23 @@   , dot   , pairP   , stringLiteral+  , stringR   , locStringLiteral+  , sym    -- * Parsing basic entities    --   fTyConP  -- Type constructors-  , lowerIdP    -- Lower-case identifiers-  , upperIdP    -- Upper-case identifiers-  -- , infixIdP    -- String Haskell infix Id-  , symbolP     -- Arbitrary Symbols+  , lowerIdP+  , lowerIdR    -- Lower-case identifiers+  , upperIdP+  , upperIdR    -- Upper-case identifiers+  , symbolP+  , symbolR     -- Arbitrary Symbols   , locSymbolP   , constantP   -- (Integer) Constants-  , natural     -- Non-negative integer+  , natural+  , naturalR    -- Non-negative integer   , locNatural   , bindP       -- Binder (lowerIdP <* colon)   , sortP       -- Sort@@ -68,8 +75,10 @@   , condIdR    -- * Lexemes and lexemes with location+  , lexeme'   , lexeme   , located+  , locLexeme'   , locLexeme   , locLowerIdP   , locUpperIdP@@ -98,7 +107,11 @@   , dataFieldP   , dataCtorP   , dataDeclP-+  , fTyConP+  , mkFTycon+  , intP+  , tvarP+  , trueP, falseP, symconstP   ) where  import           Control.Monad (unless, void)@@ -106,7 +119,9 @@ import qualified Data.IntMap.Strict          as IM import qualified Data.HashMap.Strict         as M import qualified Data.HashSet                as S+#if !MIN_VERSION_base(4,20,0) import           Data.List                   (foldl')+#endif import           Data.List.NonEmpty          (NonEmpty(..)) import qualified Data.Text                   as T import qualified Data.Text.IO                as T@@ -320,26 +335,32 @@ -- whether we are in a position permitted by the layout stack. -- After the token, consume whitespace and potentially change state. ---lexeme :: Parser a -> Parser a-lexeme p = do+lexeme' :: Parser () -> Parser a -> Parser a+lexeme' spacesP p = do   after <- guardLayout-  p <* spaces <* after+  p <* spacesP <* after +lexeme :: Parser a -> Parser a+lexeme = lexeme' spaces+ -- | Indentation-aware located lexeme parser. -- -- This is defined in such a way that it determines the actual source range -- covered by the identifier. I.e., it consumes additional whitespace in the -- end, but that is not part of the source range reported for the identifier. ---locLexeme :: Parser a -> Parser (Located a)-locLexeme p = do+locLexeme' :: Parser () -> Parser a -> Parser (Located a)+locLexeme' spacesP p = do   after <- guardLayout   l1 <- getSourcePos   x <- p   l2 <- getSourcePos-  spaces <* after+  spacesP <* after   pure (Loc l1 l2 x) +locLexeme :: Parser a -> Parser (Located a)+locLexeme = locLexeme' spaces+ -- | Make a parser location-aware. -- -- This is at the cost of an imprecise span because we still@@ -554,6 +575,11 @@ reserved x =   void $ lexeme (try (string x <* notFollowedBy identLetter)) +reserved' :: Parser () -> String -> Parser ()+reserved' spacesP x =+  void $ lexeme' spacesP (try (string x <* notFollowedBy identLetter))++ locReserved :: String -> Parser (Located String) locReserved x =   locLexeme (try (string x <* notFollowedBy identLetter))@@ -569,6 +595,11 @@ reservedOp x =   void $ lexeme (try (string x <* notFollowedBy opLetter)) +reservedOp' :: Parser () -> String -> Parser ()+reservedOp' spacesP x =+  void $ lexeme' spacesP (try (string x <* notFollowedBy opLetter))++ -- | Parser that consumes the given symbol. -- -- The difference with 'reservedOp' is that the given symbol is seen@@ -742,6 +773,7 @@ expr0P   =  trueP -- constant "true"  <|> falseP -- constant "false"+ <|> (reservedOp "?" *> predP)  <|> fastIfP EIte exprP -- "if-then-else", starts with "if"  <|> coerceP exprP -- coercion, starts with "coerce"  <|> (ESym <$> symconstP) -- string literal, starts with double-quote@@ -861,19 +893,19 @@ infixSymbolP :: Parser Symbol infixSymbolP = do   ops <- gets infixOps-  choice (reserved' <$> ops)+  choice (resX <$> ops)   where     infixOps st = [s | FInfix _ s _ _ <- fixityOps st]-    reserved' x = reserved x >> return (symbol x)+    resX x = reserved x >> return (symbol x)  -- | Located version of 'infixSymbolP'. locInfixSymbolP :: Parser (Located Symbol) locInfixSymbolP = do   ops <- gets infixOps-  choice (reserved' <$> ops)+  choice (resX <$> ops)   where     infixOps st = [s | FInfix _ s _ _ <- fixityOps st]-    reserved' x = locReserved x >>= \ (Loc l1 l2 _) -> return (Loc l1 l2 (symbol x))+    resX x = locReserved x >>= \ (Loc l1 l2 _) -> return (Loc l1 l2 (symbol x))  -- | Helper function that turns an associativity into the right constructor for 'Operator'. mkInfix :: Assoc -> parser (expr -> expr -> expr) -> Operator parser expr@@ -924,6 +956,18 @@                  , FInfix  (Just 6) "+"   (Just $ EBin Plus)  AssocLeft                  , FInfix  (Just 5) "mod" (Just $ EBin Mod)   AssocLeft -- Haskell gives mod 7                  , FInfix  (Just 9) "."   applyCompose        AssocRight+                --  --+                --  , FInfix  (Just 4) "<"   (Just $ PAtom Lt)  AssocNone+                --  , FInfix  (Just 4) "=="  (Just $ PAtom Eq)  AssocNone+                --  , FInfix  (Just 4) "="   (Just $ PAtom Eq)  AssocNone+                --  , FInfix  (Just 4) "~~"  (Just $ PAtom Ueq) AssocNone+                --  , FInfix  (Just 4) "!="  (Just $ PAtom Ne)  AssocNone+                --  , FInfix  (Just 4) "/="  (Just $ PAtom Ne)  AssocNone+                --  , FInfix  (Just 4) "!~"  (Just $ PAtom Une) AssocNone+                --  , FInfix  (Just 4) "<"   (Just $ PAtom Lt)  AssocNone+                --  , FInfix  (Just 4) "<="  (Just $ PAtom Le)  AssocNone+                --  , FInfix  (Just 4) ">"   (Just $ PAtom Gt)  AssocNone+                --  , FInfix  (Just 4) ">="  (Just $ PAtom Ge)  AssocNone                  ]     applyCompose :: Maybe (Expr -> Expr -> Expr)     applyCompose = (\f x y -> f `eApps` [x,y]) <$> cmpFun@@ -933,7 +977,7 @@ -- Andres, TODO: Why is this so complicated? -- funAppP :: Parser Expr-funAppP            =  litP <|> exprFunP <|> simpleAppP+funAppP      =  litP <|> exprFunP <|> simpleAppP   where     exprFunP = mkEApp <$> funSymbolP <*> funRhsP     funRhsP  =  some expr0P@@ -1016,7 +1060,6 @@   =   (reserved "int"     >> return intFTyCon)   <|> (reserved "Integer" >> return intFTyCon)   <|> (reserved "Int"     >> return intFTyCon)-  -- <|> (reserved "int"     >> return intFTyCon) -- TODO:AZ duplicate?   <|> (reserved "real"    >> return realFTyCon)   <|> (reserved "bool"    >> return boolFTyCon)   <|> (reserved "num"     >> return numFTyCon)
src/Language/Fixpoint/Smt/Interface.hs view
@@ -245,7 +245,7 @@        hSetBuffering hLog $ BlockBuffering $ Just $ 1024 * 1024 * 64        me   <- makeContext' cfg $ Just hLog        pre  <- smtPreamble cfg (solver cfg) me-       mapM_ (SMTLIB.Backends.command_ (ctxSolver me)) pre+       mapM_ (\l -> SMTLIB.Backends.command_ (ctxSolver me) l >> BS.hPutBuilder hLog l >> LBS.hPutStr hLog "\n") pre        return me     where        smtFile = extFileName Smt2 f
src/Language/Fixpoint/Smt/Theories.hs view
@@ -32,8 +32,12 @@         -- * Theories      , setEmpty, setEmp, setCap, setSub, setAdd, setMem-     , setCom, setCup, setDif, setSng, mapSel, mapCup, mapSto, mapDef+     , setCom, setCup, setDif, setSng +     , mapSel, mapCup, mapSto, mapDef++     , arrConst, arrStore, arrSelect, arrMapNot, arrMapOr, arrMapAnd, arrMapImp+       -- * Query Theories      , isSmt2App      , axiomLiterals@@ -63,6 +67,8 @@ -- | Theory Symbols ------------------------------------------------------------ -------------------------------------------------------------------------------- +-- TODO drop all of Set and Map symbols when Map is handled through arrays+ -- "set" is currently \"LSet\" instead of just \"Set\" because Z3 has its own -- \"Set\" since 4.8.5 elt, set, map :: Raw@@ -70,17 +76,8 @@ set  = "LSet" map  = "Map" -emp, sng, add, cup, cap, mem, dif, sub, com, sel, sto, mcup, mdef, mprj :: Raw+sel, sto, mcup, mdef, mprj :: Raw mToSet, mshift, mmax, mmin :: Raw-emp   = "smt_set_emp"-sng   = "smt_set_sng"-add   = "smt_set_add"-cup   = "smt_set_cup"-cap   = "smt_set_cap"-mem   = "smt_set_mem"-dif   = "smt_set_dif"-sub   = "smt_set_sub"-com   = "smt_set_com" sel   = "smt_map_sel" sto   = "smt_map_sto" mcup  = "smt_map_cup"@@ -146,8 +143,7 @@ bvSGtName  = "bvsgt" bvSGeName  = "bvsge" -setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup :: Symbol-setDif, setSng :: Symbol+setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup, setDif, setSng :: (IsString a) => a -- Symbol setEmpty = "Set_empty" setEmp   = "Set_emp" setCap   = "Set_cap"@@ -159,17 +155,43 @@ setDif   = "Set_dif" setSng   = "Set_sng" -mapSel, mapSto, mapCup, mapDef, mapPrj, mapToSet :: Symbol-mapMax, mapMin, mapShift :: Symbol+--- Array operations+arrConst, arrStore, arrSelect, arrMapNot, arrMapOr, arrMapAnd, arrMapImp :: Symbol+arrConst  = "const"+arrStore  = "store"+arrSelect = "select"+arrMapNot = "arr_map_not"+arrMapOr  = "arr_map_or"+arrMapAnd = "arr_map_and"+arrMapImp = "arr_map_imp"++mapSel, mapSto, mapCup, mapDef, mapMax, mapMin, mapShift :: Symbol mapSel   = "Map_select" mapSto   = "Map_store" mapCup   = "Map_union" mapMax   = "Map_union_max" mapMin   = "Map_union_min" mapDef   = "Map_default"-mapPrj   = "Map_project" mapShift = "Map_shift" -- See [Map key shift]++-- [Map key shift]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Function mapShift: Add an integer to all keys in a map. Type signature:+--   mapShift : Int -> Map Int v -> Map Int v+-- Let's call the first argument (the shift amount) N, the second argument K1,+-- and the result K2. For all indices i, we have K2[i] = K1[i - N].+-- This is implemented with Z3's lambda, which lets us construct an array+-- from a function.+--+-- [Map max and min]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Functions mapMax and mapMin: Union two maps, combining the elements by+-- taking either the greatest (mapMax) or the least (mapMin) of them.+--   mapMax, mapMin : Map v Int -> Map v Int -> Map v Int++mapToSet, mapPrj :: Symbol mapToSet = "Map_to_set"+mapPrj   = "Map_project"  -- [Interaction between Map and Set] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -188,21 +210,6 @@ -- then the key (along with its associated value in the map) are preserved -- in the output. Keys not present in the set are mapped to zero. Keys not -- present in the set are mapped to zero.------ [Map key shift]--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- Function mapShift: Add an integer to all keys in a map. Type signature:---   mapShift : Int -> Map Int v -> Map Int v--- Let's call the first argument (the shift amount) N, the second argument K1,--- and the result K2. For all indices i, we have K2[i] = K1[i - N].--- This is implemented with Z3's lambda, which lets us construct an array--- from a function.------ [Map max and min]--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- Functions mapMax and mapMin: Union two maps, combining the elements by--- taking either the greatest (mapMax) or the least (mapMin) of them.---   mapMax, mapMin : Map v Int -> Map v Int -> Map v Int  strLen, strSubstr, strConcat :: (IsString a) => a -- Symbol strLen    = "strLen"@@ -242,42 +249,6 @@         "Int"     , bSort set         (key2 "Array" (fromText elt) "Bool")-    , bFun emp-        []-        (fromText set)-        (parens (key "as const" (fromText set) <+> "false"))-    , bFun sng-        [("x", fromText elt)]-        (fromText set)-        (key3 "store" (parens (key "as const" (fromText set) <+> "false")) "x" "true")-    , bFun mem-        [("x", fromText elt), ("s", fromText set)]-        "Bool"-        "(select s x)"-    , bFun add-        [("s", fromText set), ("x", fromText elt)]-        (fromText set)-        "(store s x true)"-    , bFun cup-        [("s1", fromText set), ("s2", fromText set)]-        (fromText set)-        "((_ map or) s1 s2)"-    , bFun cap-        [("s1", fromText set), ("s2", fromText set)]-        (fromText set)-        "((_ map and) s1 s2)"-    , bFun com-        [("s", fromText set)]-        (fromText set)-        "((_ map not) s)"-    , bFun dif-        [("s1", fromText set), ("s2", fromText set)]-        (fromText set)-        (key2 (fromText cap) "s1" (key (fromText com) "s2"))-    , bFun sub-        [("s1", fromText set), ("s2", fromText set)]-        "Bool"-        (key2 "=" (fromText emp) (key2 (fromText dif) "s1" "s2"))      -- Maps     , bSort map@@ -366,14 +337,6 @@   = [ bSort elt    "Int"     , bSort set    "Int"     , bSort string "Int"-    , bFun' emp []               (fromText set)-    , bFun' sng [fromText elt]         (fromText set)-    , bFun' add [fromText set, fromText elt] (fromText set)-    , bFun' cup [fromText set, fromText set] (fromText set)-    , bFun' cap [fromText set, fromText set] (fromText set)-    , bFun' dif [fromText set, fromText set] (fromText set)-    , bFun' sub [fromText set, fromText set] "Bool"-    , bFun' mem [fromText elt, fromText set] "Bool"     , bFun boolToIntName [("b", "Bool")] "Int" "(ite b 1 0)"     ] @@ -423,6 +386,7 @@ smt2SmtSort SString      = fromText string smt2SmtSort SSet         = fromText set smt2SmtSort SMap         = fromText map+smt2SmtSort (SArray a b) = key2 "Array" (smt2SmtSort a) (smt2SmtSort b) smt2SmtSort (SBitVec n)  = key "_ BitVec" (bShow n) smt2SmtSort (SVar n)     = "T" <> bShow n smt2SmtSort (SData c []) = symbolBuilder c@@ -437,13 +401,16 @@ -------------------------------------------------------------------------------- smt2App :: VarAs -> SymEnv -> Expr -> [Builder] -> Maybe Builder ---------------------------------------------------------------------------------smt2App _ _ (dropECst -> EVar f) [d]-  | f == setEmpty = Just (fromText emp)-  | f == setEmp   = Just (key2 "=" (fromText emp) d)-  | f == setSng   = Just (key (fromText sng) d) -- Just (key2 (bb add) (bb emp) d)+smt2App _ env ex@(dropECst -> EVar f) [d]+  | f == arrConst = Just (key (key "as const" (getTarget ex)) d)+  where+    getTarget :: Expr -> Builder+    -- const is a function, but SMT expects only the output sort+    getTarget (ECst _ t) = smt2SmtSort $ sortSmtSort True (seData env) (ffuncOut t)+    getTarget e = bShow e -smt2App k env f (builder:builders)-  | Just fb <- smt2AppArg k env f+smt2App k env ex (builder:builders)+  | Just fb <- smt2AppArg k env ex   = Just $ key fb (builder <> mconcat [ " " <> d | d <- builders])  smt2App _ _ _ _    = Nothing@@ -467,12 +434,8 @@ -------------------------------------------------------------------------------- isSmt2App :: SEnv TheorySymbol -> Expr -> Maybe Int ---------------------------------------------------------------------------------isSmt2App g  (dropECst -> EVar f)-  | f == setEmpty = Just 1-  | f == setEmp   = Just 1-  | f == setSng   = Just 1-  | otherwise     = lookupSEnv f g >>= thyAppInfo-isSmt2App _ _     = Nothing+isSmt2App g (dropECst -> EVar f) = lookupSEnv f g >>= thyAppInfo+isSmt2App _  _                   = Nothing  thyAppInfo :: TheorySymbol -> Maybe Int thyAppInfo ti = case tsInterp ti of@@ -507,17 +470,27 @@ interpSymbols :: [(Symbol, TheorySymbol)] -------------------------------------------------------------------------------- interpSymbols =-  [ interpSym setEmp   emp  (FAbs 0 $ FFunc (setSort $ FVar 0) boolSort)-  , interpSym setEmpty emp  (FAbs 0 $ FFunc intSort (setSort $ FVar 0))-  , interpSym setSng   sng  (FAbs 0 $ FFunc (FVar 0) (setSort $ FVar 0))-  , interpSym setAdd   add   setAddSort-  , interpSym setCup   cup   setBopSort-  , interpSym setCap   cap   setBopSort-  , interpSym setMem   mem   setMemSort-  , interpSym setDif   dif   setBopSort-  , interpSym setSub   sub   setCmpSort-  , interpSym setCom   com   setCmpSort+  [+  -- TODO we'll probably need two versions of these - one for sets and one for maps+    interpSym arrConst  "const"       (FAbs 0 $ FFunc boolSort setArrSort)+  , interpSym arrStore  "store"       (FAbs 0 $ FFunc setArrSort $ FFunc (FVar 0) $ FFunc boolSort setArrSort)+  , interpSym arrSelect "select"      (FAbs 0 $ FFunc setArrSort $ FFunc (FVar 0) boolSort)+  , interpSym arrMapNot "(_ map not)" (FFunc setArrSort setArrSort)+  , interpSym arrMapOr  "(_ map or)"  (FFunc setArrSort $ FFunc setArrSort setArrSort)+  , interpSym arrMapAnd "(_ map and)" (FFunc setArrSort $ FFunc setArrSort setArrSort)+  , interpSym arrMapImp "(_ map =>)"  (FFunc setArrSort $ FFunc setArrSort setArrSort) +  , interpSym setEmp   setEmp   (FAbs 0 $ FFunc (setSort $ FVar 0) boolSort)+  , interpSym setEmpty setEmpty (FAbs 0 $ FFunc intSort (setSort $ FVar 0))+  , interpSym setSng   setSng   (FAbs 0 $ FFunc (FVar 0) (setSort $ FVar 0))+  , interpSym setAdd   setAdd   setAddSort+  , interpSym setCup   setCup   setBopSort+  , interpSym setCap   setCap   setBopSort+  , interpSym setMem   setMem   setMemSort+  , interpSym setDif   setDif   setBopSort+  , interpSym setSub   setSub   setCmpSort+  , interpSym setCom   setCom   setCmpSort+   , interpSym mapSel   sel   mapSelSort   , interpSym mapSto   sto   mapStoSort   , interpSym mapCup   mcup  mapCupSort@@ -527,6 +500,7 @@   , interpSym mapPrj   mprj  mapPrjSort   , interpSym mapShift mshift mapShiftSort   , interpSym mapToSet mToSet mapToSetSort+   -- , interpSym bvOrName  "bvor"  bvBopSort   -- , interpSym bvAndName "bvand" bvBopSort   -- , interpSym bvAddName "bvadd" bvBopSort@@ -589,14 +563,17 @@    ]   where+    setArrSort = arraySort (FVar 0) boolSort     -- (sizedBitVecSort "Size1")     bv32       = sizedBitVecSort "Size32"     bv64       = sizedBitVecSort "Size64"     boolInt    = boolToIntName+     setAddSort = FAbs 0 $ FFunc (setSort $ FVar 0) $ FFunc (FVar 0)           (setSort $ FVar 0)     setBopSort = FAbs 0 $ FFunc (setSort $ FVar 0) $ FFunc (setSort $ FVar 0) (setSort $ FVar 0)     setMemSort = FAbs 0 $ FFunc (FVar 0) $ FFunc (setSort $ FVar 0) boolSort     setCmpSort = FAbs 0 $ FFunc (setSort $ FVar 0) $ FFunc (setSort $ FVar 0) boolSort+     -- select :: forall i a. Map i a -> i -> a     mapSelSort = FAbs 0 $ FAbs 1 $ FFunc (mapSort (FVar 0) (FVar 1))                                  $ FFunc (FVar 0) (FVar 1)
src/Language/Fixpoint/Solver.hs view
@@ -28,6 +28,7 @@ import qualified Data.HashMap.Strict              as HashMap import qualified Data.Store                       as S import           Data.Aeson                         (ToJSON, encode)+import qualified Data.List as L import qualified Data.Text.Lazy.IO                as LT import qualified Data.Text.Lazy.Encoding          as LT import           System.Exit                        (ExitCode (..))@@ -189,10 +190,17 @@ crashResult m err' = Result res mempty mempty mempty   where     res           = Crash es msg-    es            = catMaybes [ findError m e | e <- errs err' ]-    msg | null es = showpp err'-        | otherwise = "Sorry, unexpected panic in liquid-fixpoint!" -- ++ showpp e+    es            = catMaybes [ findError m e | e <- ers ]+    ers           = errs err'+    msg | null ers = "Sorry, unexpected panic in liquid-fixpoint!"+        --  {-dbgFalse-} True  = "Sorry, unexpected panic in liquid-fixpoint!\n" ++ crashMessage es+        | otherwise = showpp err' +_crashMessage :: [((Integer, a), Maybe String) ] -> String+_crashMessage es = L.intercalate "\n" [ msg i s | ((i,_), Just s) <- es ]+  where+    msg i s = "Error in constraint " ++ show i ++ ":\n" ++ s+ -- | Unpleasant hack to save meta-data that can be recovered from SrcSpan type ErrorMap a = HashMap.HashMap SrcSpan a @@ -234,13 +242,16 @@   -- rnf si1 `seq` donePhase Loud "Validated Constraints"   graphStatistics cfg si1   let si2  = {- SCC "wfcUniqify" -} wfcUniqify $!! si1+  -- writeLoud $ "fq file after wfcUniqify: \n" ++ render (toFixpoint cfg si2)   let si3  = {- SCC "renameAll"  -} renameAll  $!! si2   rnf si3 `seq` whenLoud $ donePhase Loud "Uniqify & Rename"   loudDump 1 cfg si3   let si4  = {- SCC "defunction" -} defunctionalize cfg $!! si3+  -- writeLoud $ "fq file after defunc: \n" ++ render (toFixpoint cfg si4)   -- putStrLn $ "AXIOMS: " ++ showpp (asserts si4)   loudDump 2 cfg si4   let si5  = {- SCC "elaborate" -} elaborate (atLoc dummySpan "solver") (symbolEnv cfg si4) si4+  -- writeLoud $ "fq file after elaborate: \n" ++ render (toFixpoint cfg si5)   loudDump 3 cfg si5   let si6 = if extensionality cfg then {- SCC "expand" -} expand cfg si5 else si5   if rewriteAxioms cfg && noLazyPLE cfg
src/Language/Fixpoint/Solver/EnvironmentReduction.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE PatternSynonyms #-}@@ -30,7 +30,11 @@ import qualified Data.HashMap.Strict as HashMap.Strict import           Data.HashSet (HashSet) import qualified Data.HashSet as HashSet+#if MIN_VERSION_base(4,20,0)+import           Data.List (nub, partition)+#else import           Data.List (foldl', nub, partition)+#endif import           Data.Maybe (fromMaybe) import           Data.ShareMap (ShareMap) import qualified Data.ShareMap as ShareMap
src/Language/Fixpoint/Solver/Extensionality.hs view
@@ -10,7 +10,9 @@ import           Control.Monad.State import qualified Data.HashMap.Strict       as M import           Data.Maybe  (fromMaybe)+#if !MIN_VERSION_base(4,20,0) import           Data.List (foldl')+#endif  import           Language.Fixpoint.Types.Config import           Language.Fixpoint.SortCheck@@ -201,7 +203,7 @@   where     -- NV: hardcore Haskell pairs because they do not appear in DataDecl (why?)     d = mytracepp "Tuple DataDecl" $ DDecl (symbolFTycon (dummyLoc tupConName)) 2 [ct]-#if MIN_TOOL_VERSION_ghc(9,6,0)+#if MIN_TOOL_VERSION_ghc(9,6,0) && !MIN_TOOL_VERSION_ghc(9,10,0)     ct = DCtor (dummyLoc (symbol "GHC.Tuple.Prim.(,)")) [             DField (dummyLoc (symbol "lqdc$select$GHC.Tuple.Prim.(,)$1")) (FVar 0)           , DField (dummyLoc (symbol "lqdc$select$GHC.Tuple.Prim.(,)$2")) (FVar 1)
src/Language/Fixpoint/Solver/Interpreter.hs view
@@ -17,8 +17,6 @@ {-# LANGUAGE RecordWildCards           #-} {-# LANGUAGE ExistentialQuantification #-} -{-# OPTIONS_GHC -Wno-name-shadowing    #-}- module Language.Fixpoint.Solver.Interpreter   ( instInterpreter @@ -62,25 +60,25 @@ instInterpreter cfg fi' subcIds = do     let cs = M.filterWithKey                (\i c -> isPleCstr aEnv i c && maybe True (i `L.elem`) subcIds)-               (cm fi)+               (cm info)     let t  = mkCTrie (M.toList cs)                      -- 1. BUILD the Trie     res   <- withProgress (1 + M.size cs) $-               pleTrie t $ instEnv fi cs sEnv           -- 2. TRAVERSE Trie to compute InstRes-    return $ resSInfo cfg sEnv fi res                   -- 3. STRENGTHEN SInfo using InstRes+               pleTrie t $ instEnv info cs sEnv         -- 2. TRAVERSE Trie to compute InstRes+    return $ resSInfo cfg sEnv info res                 -- 3. STRENGTHEN SInfo using InstRes   where-    sEnv   = symbolEnv cfg fi-    aEnv   = ae fi-    fi     = normalize fi'+    sEnv   = symbolEnv cfg info+    aEnv   = ae info+    info   = normalize fi'  ------------------------------------------------------------------------------- -- | Step 1a: @instEnv@ sets up the incremental-PLE environment instEnv :: (Loc a) => SInfo a -> CMap (SimpC a) -> SymEnv -> InstEnv a-instEnv fi cs sEnv = InstEnv bEnv aEnv cs γ s0+instEnv info cs sEnv = InstEnv bEnv aEnv cs γ s0   where     csBinds           = M.foldl' (\acc c -> unionIBindEnv acc (senv c)) emptyIBindEnv cs-    bEnv              = filterBindEnv (\i _ _ -> memberIBindEnv i csBinds) (bs fi)-    aEnv              = ae fi-    γ                 = knowledge fi+    bEnv              = filterBindEnv (\i _ _ -> memberIBindEnv i csBinds) (bs info)+    aEnv              = ae info+    γ                 = knowledge info     s0                = EvalEnv sEnv mempty  ----------------------------------------------------------------------------------------------@@ -180,7 +178,7 @@ ----------------------------------------------------------------------------------------------  resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> SInfo a-resSInfo cfg env fi res = strengthenBinds fi res'+resSInfo cfg env info res = strengthenBinds info res'   where     res'     = M.fromList $ zip is ps''     ps''     = zipWith (\i -> elaborate (atLoc dummySpan ("PLE1 " ++ show i)) env) is ps'@@ -288,12 +286,12 @@                            , EVar x /= c ]  makeCandidates :: Knowledge -> ICtx -> Expr -> [Expr]-makeCandidates γ ctx expr+makeCandidates k ctx exprs   = mytracepp ("\n" ++ show (length cands) ++ " New Candidates") cands   where     cands =-      filter (\e -> isRedex γ e && not (e `S.member` icSolved ctx)) (notGuardedApps expr) ++-      filter (\e -> hasConstructors γ e && not (e `S.member` icSolved ctx)) (largestApps expr)+      filter (\e -> isRedex k e && not (e `S.member` icSolved ctx)) (notGuardedApps exprs) +++      filter (\e -> hasConstructors k e && not (e `S.member` icSolved ctx)) (largestApps exprs)      -- Constructor occurrences need to be considered as candidadates since     -- they identify relevant measure equations. The function 'rewrite'@@ -323,7 +321,7 @@ getCstr env cid = Misc.safeLookup "Instantiate.getCstr" cid env  isPleCstr :: AxiomEnv -> SubcId -> SimpC a -> Bool-isPleCstr aenv sid c = isTarget c && M.lookupDefault False sid (aenvExpand aenv)+isPleCstr aenv subid c = isTarget c && M.lookupDefault False subid (aenvExpand aenv)  type EvAccum = S.HashSet (Expr, Expr) @@ -432,14 +430,14 @@ mkCoSub :: SEnv Sort -> [Sort] -> [Sort] -> Vis.CoSub mkCoSub env eTs xTs = M.fromList [ (x, unite ys) | (x, ys) <- Misc.groupList xys ]   where-    unite ts    = Mb.fromMaybe (uError ts) (unifyTo1 senv ts)-    senv        = mkSearchEnv env+    unite ts    = Mb.fromMaybe (uError ts) (unifyTo1 symToSearch ts)+    symToSearch = mkSearchEnv env     uError ts   = panic ("mkCoSub: cannot build CoSub for " ++ showpp xys ++ " cannot unify " ++ showpp ts)     xys         = Misc.sortNub $ concat $ zipWith matchSorts _xTs _eTs     (_xTs,_eTs) = (xTs, eTs)  matchSorts :: Sort -> Sort -> [(Symbol, Sort)]-matchSorts s1 s2 = go s1 s2+matchSorts = go   where     go (FObj x)      {-FObj-} y    = [(x, y)]     go (FAbs _ t1)   (FAbs _ t2)   = go t1 t2@@ -465,18 +463,18 @@ interpret ie γ ctx env   (EApp e1 e2)   | isSetPred e1                        = let e2' = interpret' ie γ ctx env e2 in                                              applySetFolding e1 e2'-interpret ie γ ctx env e@(EApp _ _)     = case splitEApp e of-  (f, es) -> let g = interpret' ie γ ctx env in-    interpretApp ie γ ctx env (g f) (map g es)+interpret cmap know ictx ssenv e@(EApp _ _)     = case splitEApp e of+  (exprs, exprses) -> let g = interpret' cmap know ictx ssenv in+    interpretApp cmap know ictx ssenv (g exprs) (map g exprses)     where       interpretApp ie γ ctx env (EVar f) es         | Just eq <- M.lookup f (knAms γ)         , length (eqArgs eq) <= length es         = let (es1,es2) = splitAt (length (eqArgs eq)) es               ges       = substEq env eq es1-              exp       = unfoldExpr ie γ ctx env ges-              exp'      = eApps exp es2 in  --exp' -- TODO undo-            if eApps (EVar f) es == exp' then exp' else interpret' ie γ ctx env exp'+              exp1       = unfoldExpr ie γ ctx env ges+              exp2      = eApps exp1 es2 in  --exp' -- TODO undo+            if eApps (EVar f) es == exp2 then exp2 else interpret' ie γ ctx env exp2        interpretApp ie γ ctx env (EVar f) (e1:es)         | (EVar dc, as) <- splitEApp e1@@ -511,7 +509,7 @@                                             ELam (x, s) e' interpret ie γ ctx env   (ETApp e1 t)   = let e1' = interpret' ie γ ctx env e1 in ETApp e1' t interpret ie γ ctx env   (ETAbs e1 sy)  = let e1' = interpret' ie γ ctx env e1 in ETAbs e1' sy-interpret ie γ ctx env   (PAnd es)      = let es' = map (interpret' ie γ ctx env) es in go [] (reverse es')+interpret ie γ ctx env   (PAnd exprses) = let es' = map (interpret' ie γ ctx env) exprses in go [] (reverse es')   where     go []  []         = PTrue     go [p] []         = interpret' ie γ ctx env p@@ -519,7 +517,7 @@     go acc (PTrue:es) = go acc es     go _   (PFalse:_) = PFalse     go acc (e:es)     = go (e:acc) es-interpret ie γ ctx env (POr es)         = let es' = map (interpret' ie γ ctx env) es in go [] (reverse es')+interpret ie γ ctx env (POr exprses)      = let es' = map (interpret' ie γ ctx env) exprses in go [] (reverse es')   where     go []  []          = PFalse     go [p] []          = interpret' ie γ ctx env p@@ -575,20 +573,20 @@   }  knowledge :: SInfo a -> Knowledge-knowledge si = KN+knowledge info = KN   { knSims                     = M.fromList $ (\r -> ((smName r, smDC r), r)) <$> sims   , knAms                      = M.fromList $ (\a -> (eqName a, a)) <$> aenvEqs aenv   , knLams                     = []   , knSummary                  =    ((\s -> (smName s, 1)) <$> sims)                                  ++ ((\s -> (eqName s, length (eqArgs s))) <$> aenvEqs aenv)-  , knDCs                      = S.fromList (smDC <$> sims)  <> constNames si-  , knAllDCs                   = S.fromList $ val . dcName <$> concatMap ddCtors (ddecls si)+  , knDCs                      = S.fromList (smDC <$> sims)  <> constNames info+  , knAllDCs                   = S.fromList $ val . dcName <$> concatMap ddCtors (ddecls info)   , knSels                     = M.fromList $ Mb.mapMaybe makeSel  sims   , knConsts                   = M.fromList $ Mb.mapMaybe makeCons sims   }   where     sims = aenvSimpl aenv-    aenv = ae si+    aenv = ae info      makeCons rw       | null (syms $ smBody rw)@@ -631,9 +629,9 @@   instance Simplifiable Expr where-  simplify γ ictx e = mytracepp ("simplification of " ++ show e) $ fix (Vis.mapExpr tx) e+  simplify γ ictx exprs = mytracepp ("simplification of " ++ show exprs) $ fix' (Vis.mapExpr tx) exprs     where-      fix f e = if e == e' then e else fix f e' where e' = f e+      fix' f e = if e == e' then e else fix' f e' where e' = f e       tx e         | Just e' <- M.lookup e (icSimpl ictx)         = e'@@ -660,7 +658,7 @@         , (EVar dc', es) <- splitEApp a         , dc == dc'         = es!!i-      tx (PAnd es)         = go [] (reverse es)+      tx (PAnd exprses)         = go [] (reverse exprses)         where           go []  []     = PTrue           go [p] []     = p@@ -669,7 +667,7 @@             | e == PTrue = go acc es             | e == PFalse = PFalse             | otherwise = go (e:acc) es-      tx (POr es)          = go [] (reverse es)+      tx (POr exprses)          = go [] (reverse exprses)         where           go []  []     = PFalse           go [p] []     = p
src/Language/Fixpoint/Solver/Monad.hs view
@@ -89,7 +89,7 @@     file     = C.srcFile cfg     -- only linear arithmentic when: linear flag is on or solver /= Z3     -- lar     = linear cfg || Z3 /= solver cfg-    fi       = (siQuery sI) {F.hoInfo = F.HOI (C.allowHO cfg) (C.allowHOqs cfg)}+    fi       = (siQuery sI) {F.hoInfo = F.cfgHoInfo cfg }   --------------------------------------------------------------------------------
src/Language/Fixpoint/Solver/PLE.hs view
@@ -16,8 +16,6 @@ {-# LANGUAGE RecordWildCards           #-} {-# LANGUAGE ExistentialQuantification #-} -{-# OPTIONS_GHC -Wno-name-shadowing    #-}- module Language.Fixpoint.Solver.PLE   ( instantiate @@ -78,31 +76,31 @@ instantiate cfg fi' subcIds = do     let cs = M.filterWithKey                (\i c -> isPleCstr aEnv i c && maybe True (i `L.elem`) subcIds)-               (cm fi)+               (cm info)     let t  = mkCTrie (M.toList cs)                                          -- 1. BUILD the Trie     res   <- withRESTSolver $ \solver -> withProgress (1 + M.size cs) $                withCtx cfg file sEnv $ \ctx -> do-                  env <- instEnv cfg fi cs solver ctx+                  env <- instEnv cfg info cs solver ctx                   pleTrie t env                                             -- 2. TRAVERSE Trie to compute InstRes-    savePLEEqualities cfg fi sEnv res-    return $ resSInfo cfg sEnv fi res                                       -- 3. STRENGTHEN SInfo using InstRes+    savePLEEqualities cfg info sEnv res+    return $ resSInfo cfg sEnv info res                                     -- 3. STRENGTHEN SInfo using InstRes   where     withRESTSolver :: (Maybe SolverHandle -> IO a) -> IO a     withRESTSolver f | all null (M.elems $ aenvAutoRW aEnv) = f Nothing     withRESTSolver f = withZ3 (f . Just)      file   = srcFile cfg ++ ".evals"-    sEnv   = symbolEnv cfg fi-    aEnv   = ae fi-    fi     = normalize fi'+    sEnv   = symbolEnv cfg info+    aEnv   = ae info+    info   = normalize fi'  savePLEEqualities :: Config -> SInfo a -> SymEnv -> InstRes -> IO ()-savePLEEqualities cfg fi sEnv res = when (save cfg) $ do+savePLEEqualities cfg info sEnv res = when (save cfg) $ do     let fq   = queryFile Files.Fq cfg ++ ".ple"     putStrLn $ "\nSaving PLE equalities: "   ++ fq ++ "\n"     Misc.ensurePath fq     let constraint_equalities =-          map equalitiesPerConstraint $ Misc.hashMapToAscList $ cm fi+          map equalitiesPerConstraint $ Misc.hashMapToAscList $ cm info     writeFile fq $ render $ vcat $       map renderConstraintRewrite constraint_equalities   where@@ -123,12 +121,12 @@ ------------------------------------------------------------------------------- -- | Step 1a: @instEnv@ sets up the incremental-PLE environment instEnv :: (Loc a) => Config -> SInfo a -> CMap (SimpC a) -> Maybe SolverHandle -> SMT.Context -> IO (InstEnv a)-instEnv cfg fi cs restSolver ctx = do+instEnv cfg info cs restSolver ctx = do     refRESTCache <- newIORef mempty     refRESTSatCache <- newIORef mempty     let-        restOC = FC.restOC cfg-        oc0 = ordConstraints restOC $ Mb.fromJust restSolver+        restOrd = FC.restOC cfg+        oc0 = ordConstraints restOrd $ Mb.fromJust restSolver         oc :: OCAlgebra OCType RuntimeTerm IO         oc = oc0              { OC.isSat = cachedIsSat refRESTSatCache oc0@@ -150,16 +148,16 @@               , evFuel = defFuelCount cfg               , explored = Just et               , restSolver = restSolver-              , restOCA = restOC+              , restOCA = restOrd               , evOCAlgebra = oc               }     return $ InstEnv        { ieCfg = cfg        , ieSMT = ctx-       , ieBEnv = bs fi-       , ieAenv = ae fi+       , ieBEnv = bs info+       , ieAenv = ae info        , ieCstrs = cs-       , ieKnowl = knowledge cfg ctx fi+       , ieKnowl = knowledge cfg ctx info        , ieEvEnv = s0        }   where@@ -342,7 +340,7 @@ ----------------------------------------------------------------------------------------------  resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> SInfo a-resSInfo cfg env fi res = strengthenBinds fi res'+resSInfo cfg env info res = strengthenBinds info res'   where     res'     = M.fromList $ zip is ps''     ps''     = zipWith (\i -> elaborate (atLoc dummySpan ("PLE1 " ++ show i)) env) is ps'@@ -447,7 +445,7 @@ getCstr env cid = Misc.safeLookup "Instantiate.getCstr" cid env  isPleCstr :: AxiomEnv -> SubcId -> SimpC a -> Bool-isPleCstr aenv sid c = isTarget c && M.lookupDefault False sid (aenvExpand aenv)+isPleCstr aenv subid c = isTarget c && M.lookupDefault False subid (aenvExpand aenv)  type EvEqualities = S.HashSet (Expr, Expr) @@ -576,9 +574,9 @@           -- Just evaluate the arguments first, to give rewriting a chance to step in           -- if necessary           do-            (es', fe) <- feSeq <$> mapM (eval γ ctx et) es+            (es', finalExpand) <- feSeq <$> mapM (eval γ ctx et) es             if es /= es'-              then return (eApps f es', fe)+              then return (eApps f es', finalExpand)               else do                 (f', fe)  <- eval γ ctx et f                 (me', fe') <- evalApp γ ctx f' es et@@ -679,7 +677,7 @@ evalRESTWithCache cacheRef γ ctx acc rp =   do     Just exploredTerms <- gets explored-    se <- liftIO (shouldExploreTerm exploredTerms e)+    se <- liftIO (shouldExploreTerm exploredTerms exprs)     if se then do       possibleRWs <- getRWs       rws <- notVisitedFirst exploredTerms <$> filterM (liftIO . allowed) possibleRWs@@ -688,10 +686,10 @@        -- liftIO $ putStrLn $ (show $ length possibleRWs) ++ " rewrites allowed at path length " ++ (show $ (map snd $ path rp))       (e', FE fe) <- do-        r@(ec, _) <- eval γ ctx FuncNormal e-        if ec /= e+        r@(ec, _) <- eval γ ctx FuncNormal exprs+        if ec /= exprs           then return r-          else eval γ ctx RWNormal e+          else eval γ ctx RWNormal exprs        let evalIsNewExpr = e' `L.notElem` pathExprs       let exprsToAdd    = [e' | evalIsNewExpr]  ++ map (\(_, e, _) -> e) rws@@ -704,7 +702,7 @@              st { evNewEqualities  = foldr S.insert (S.union newEqualities oldEqualities) eqnToAdd                 , evSMTCache = smtCache                 , explored = Just $ ExploredTerms.insert-                  (Rewrite.convert e)+                  (Rewrite.convert exprs)                   (c rp)                   (S.insert (Rewrite.convert e') $ S.fromList (map (Rewrite.convert . (\(_, e, _) -> e)) possibleRWs))                   (Mb.fromJust $ explored st)@@ -712,8 +710,8 @@        acc'' <- if evalIsNewExpr         then if fe && any isRW (path rp)-          then (:[]) . fst <$> eval γ (addConst (e, e')) NoRW e'-          else evalRESTWithCache cacheRef γ (addConst (e, e')) acc' (rpEval newEqualities e')+          then (:[]) . fst <$> eval γ (addConst (exprs, e')) NoRW e'+          else evalRESTWithCache cacheRef γ (addConst (exprs, e')) acc' (rpEval newEqualities e')         else return acc'        foldM (\r rw -> evalRESTWithCache cacheRef γ ctx r (rpRW rw)) acc'' rws@@ -753,7 +751,7 @@     rpRW (_, e', c') = rp{path = path rp ++ [(e', RW)], c = c' }      pathExprs       = map fst (mytracepp "EVAL2: path" $ path rp)-    e               = last pathExprs+    exprs           = last pathExprs     autorws         = getAutoRws γ ctx      rwArgs = RWArgs (isValid cacheRef γ) $ knRWTerminationOpts γ@@ -769,7 +767,7 @@         if ok           then             do-              let e'         = deANF ctx e+              let e'         = deANF ctx exprs               let getRW e ar = Rewrite.getRewrite (oc rp) rwArgs (c rp) e ar               let getRWs' s  = Mb.catMaybes <$> mapM (liftIO . runMaybeT . getRW s) autorws               concat <$> mapM getRWs' (subExprs e')@@ -909,13 +907,13 @@ mkCoSub :: SEnv Sort -> [Sort] -> [Sort] -> Vis.CoSub mkCoSub env eTs xTs = M.fromList [ (x, unite ys) | (x, ys) <- Misc.groupList xys ]   where-    unite ts    = Mb.fromMaybe (uError ts) (unifyTo1 senv ts)-    senv        = mkSearchEnv env+    unite ts    = Mb.fromMaybe (uError ts) (unifyTo1 symToSearch ts)+    symToSearch = mkSearchEnv env     uError ts   = panic ("mkCoSub: cannot build CoSub for " ++ showpp xys ++ " cannot unify " ++ showpp ts)     xys         = Misc.sortNub $ concat $ zipWith matchSorts xTs eTs  matchSorts :: Sort -> Sort -> [(Symbol, Sort)]-matchSorts s1 s2 = go s1 s2+matchSorts = go   where     go (FObj x)      {-FObj-} y    = [(x, y)]     go (FAbs _ t1)   (FAbs _ t2)   = go t1 t2@@ -1024,9 +1022,9 @@     inRewrites :: Symbol -> Bool     inRewrites e =       let-        syms = Mb.mapMaybe (lhsHead . arLHS) (concat $ M.elems $ aenvAutoRW aenv)+        symbs = Mb.mapMaybe (lhsHead . arLHS) (concat $ M.elems $ aenvAutoRW aenv)       in-        e `L.elem` syms+        e `L.elem` symbs      lhsHead :: Expr -> Maybe Symbol     lhsHead e | (ef, _) <- splitEAppThroughECst e, EVar f <- dropECst ef = Just f@@ -1111,9 +1109,9 @@ isConstant dcs e = S.null (S.difference (exprSymbolsSet e) dcs)  simplify :: Knowledge -> ICtx -> Expr -> Expr-simplify γ ictx e = mytracepp ("simplification of " ++ showpp e) $ fix (Vis.mapExprOnExpr tx) e+simplify γ ictx exprs = mytracepp ("simplification of " ++ showpp exprs) $ fix' (Vis.mapExprOnExpr tx) exprs     where-      fix f e = if e == e' then e else fix f e' where e' = f e+      fix' f e = if e == e' then e else fix' f e' where e' = f e       tx e         | Just e' <- M.lookup e (icSimpl ictx)         = e'@@ -1179,7 +1177,7 @@  -- | Normalize the given named expression if it is recursive. normalizeBody :: Symbol -> Expr -> Expr-normalizeBody f e | f `elem` syms e = go e+normalizeBody f exprs | f `elem` syms exprs = go exprs   where     -- @go@ performs this simplification:     --     (c => e1) /\ ((not c) => e2) --> if c then e1 else e2
src/Language/Fixpoint/Solver/Prettify.hs view
@@ -3,8 +3,6 @@ {-# LANGUAGE PatternSynonyms            #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-}- -- | Functions to make environments easier to read module Language.Fixpoint.Solver.Prettify (savePrettifiedQuery) where @@ -62,18 +60,18 @@   savePrettifiedQuery :: Fixpoint a => Config -> FInfo a -> IO ()-savePrettifiedQuery cfg fi = do+savePrettifiedQuery cfg info = do   let fq   = queryFile Files.Fq cfg `addExtension` "prettified"   putStrLn $ "Saving prettified Query: "   ++ fq ++ "\n"   ensurePath fq-  writeFile fq $ render (prettyConstraints fi)+  writeFile fq $ render (prettyConstraints info)  prettyConstraints :: Fixpoint a => FInfo a -> Doc-prettyConstraints fi =+prettyConstraints info =   vcat $   map-    (prettyConstraint (bs fi) . snd)-    (sortOn fst $ HashMap.toList (cm fi))+    (prettyConstraint (bs info) . snd)+    (sortOn fst $ HashMap.toList (cm info))  prettyConstraint   :: Fixpoint a@@ -163,11 +161,11 @@   :: HashMap Symbol SortedReft   -> SubC a   -> ([(Symbol, SortedReft)], SubC a)-shortenVarNames env c =+shortenVarNames env subc =   let bindsRenameMap = proposeRenamings $ HashMap.keys env       env' = map (renameBind bindsRenameMap) (HashMap.toList env)    in-      (env', renameSubC bindsRenameMap c)+      (env', renameSubC bindsRenameMap subc)   where     renameSubC :: HashMap Symbol Symbol -> SubC a -> SubC a     renameSubC symMap c =@@ -255,7 +253,7 @@       [(_sfx, ss)] -> renameWithAppendages pfx ("", ss)       sfxs -> concatMap (renameWithAppendages pfx) sfxs -    renameWithAppendages pfx (sfx, ss) = zip ss $ case ss of+    renameWithAppendages pfx (sfx, xs) = zip xs $ case xs of       [_s] -> [pfx `suffixIfNotNull` sfx]       ss -> zipWith (rename pfx sfx) [1 :: Integer ..] ss 
src/Language/Fixpoint/Solver/Rewrite.hs view
@@ -4,8 +4,6 @@ {-# LANGUAGE PatternGuards             #-} {-# LANGUAGE ScopedTypeVariables       #-} -{-# OPTIONS_GHC -Wno-name-shadowing    #-}- module Language.Fixpoint.Solver.Rewrite   ( getRewrite   , subExprs@@ -85,7 +83,7 @@     asLPO (LPO t) = t     asLPO _       = undefined -ordConstraints (RESTFuel n) _      = bimapConstraints Fuel asFuel $ fuelOC n+ordConstraints (RESTFuel m) _      = bimapConstraints Fuel asFuel $ fuelOC m   where     asFuel (Fuel n) = n     asFuel _        = undefined
src/Language/Fixpoint/Solver/Sanitize.hs view
@@ -4,8 +4,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternGuards     #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-}- module Language.Fixpoint.Solver.Sanitize   ( -- * Transform FInfo to enforce invariants     sanitize@@ -41,10 +39,7 @@ -------------------------------------------------------------------------------- sanitize :: Config -> F.SInfo a -> SanitizeM (F.SInfo a) ---------------------------------------------------------------------------------sanitize cfg =    -- banIllScopedKvars-        --      Misc.fM dropAdtMeasures-        --      >=>-                     banIrregularData+sanitize cfg =       banIrregularData          >=> Misc.fM dropFuncSortedShadowedBinders          >=> Misc.fM sanitizeWfC          >=> Misc.fM replaceDeadKvars@@ -335,14 +330,14 @@     prims = Thy.theorySymbols . F.ddecls $ fi  cNoFreeVars :: F.SInfo a -> (F.Symbol -> Bool) -> F.SimpC a -> Maybe [F.Symbol]-cNoFreeVars fi known c = if S.null fv then Nothing else Just (S.toList fv)+cNoFreeVars fi knownSym c = if S.null fv then Nothing else Just (S.toList fv)   where     be   = F.bs fi     ids  = F.elemsIBindEnv $ F.senv c     cDom = [Misc.fst3 $ F.lookupBindEnv i be | i <- ids]     cRng = concat [S.toList . F.reftFreeVars . F.sr_reft . Misc.snd3 $ F.lookupBindEnv i be | i <- ids]         ++ F.syms (F.crhs c)-    fv   = (`Misc.nubDiff` cDom) . filter (not . known) $ cRng+    fv   = (`Misc.nubDiff` cDom) . filter (not . knownSym) $ cRng  badCs :: Misc.ListNE (F.SimpC a, [F.Symbol]) -> E.Error badCs = E.catErrors . map (E.errFreeVarInConstraint . Misc.mapFst F.subcId)@@ -410,7 +405,7 @@     tEnv         = Thy.theorySymbols ds     ds           = F.ddecls si     ts           = Misc.setNub (applySorts si ++ [t | (_, t) <- F.toListSEnv sEnv])-    sEnv         = (F.tsSort <$> tEnv) `mappend` F.fromListSEnv xts+    sEnv         = F.coerceSortEnv $ (F.tsSort <$> tEnv) `mappend` F.fromListSEnv xts     xts          = symbolSorts cfg si ++ alits     lits         = F.dLits si `F.unionSEnv'` F.fromListSEnv alits     alits        = litsAEnv $ F.ae si
src/Language/Fixpoint/Solver/Simplify.hs view
@@ -8,8 +8,6 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ViewPatterns              #-} -{-# OPTIONS_GHC -Wno-name-shadowing    #-}- module Language.Fixpoint.Solver.Simplify (applyBooleanFolding, applyConstantFolding, applySetFolding, isSetPred) where  import           Language.Fixpoint.Types hiding (simplify)@@ -20,20 +18,20 @@   applyBooleanFolding :: Brel -> Expr -> Expr -> Expr-applyBooleanFolding brel e1 e2 =+applyBooleanFolding brel' e1 e2 =   case (e1, e2) of     (ECon (R left), ECon (R right)) ->-      Mb.fromMaybe e (bfR brel left right)+      Mb.fromMaybe e (bfR brel' left right)     (ECon (R left), ECon (I right)) ->-      Mb.fromMaybe e (bfR brel left (fromIntegral right))+      Mb.fromMaybe e (bfR brel' left (fromIntegral right))     (ECon (I left), ECon (R right)) ->-      Mb.fromMaybe e (bfR brel (fromIntegral left) right)+      Mb.fromMaybe e (bfR brel' (fromIntegral left) right)     (ECon (I left), ECon (I right)) ->-      Mb.fromMaybe e (bfI brel left right)+      Mb.fromMaybe e (bfI brel' left right)     _ -> if isTautoPred e then PTrue else            if isContraPred e then PFalse else e   where-    e = PAtom brel e1 e2+    e = PAtom brel' e1 e2      getOp :: Ord a => Brel -> (a -> a -> Bool)     getOp Gt   =  (>)@@ -55,28 +53,28 @@ -- | Replace constant integer and floating point expressions by constant values -- where possible. applyConstantFolding :: Bop -> Expr -> Expr -> Expr-applyConstantFolding bop e1 e2 =+applyConstantFolding bop' e1 e2 =   case (dropECst e1, dropECst e2) of     (ECon (R left), ECon (R right)) ->-      Mb.fromMaybe e (cfR bop left right)+      Mb.fromMaybe e (cfR bop' left right)     (ECon (R left), ECon (I right)) ->-      Mb.fromMaybe e (cfR bop left (fromIntegral right))+      Mb.fromMaybe e (cfR bop' left (fromIntegral right))     (ECon (I left), ECon (R right)) ->-      Mb.fromMaybe e (cfR bop (fromIntegral left) right)+      Mb.fromMaybe e (cfR bop' (fromIntegral left) right)     (ECon (I left), ECon (I right)) ->-      Mb.fromMaybe e (cfI bop left right)+      Mb.fromMaybe e (cfI bop' left right)     (EBin Mod  _   _              , _)  -> e     (EBin bop1 e11 (dropECst -> ECon (R left)), ECon (R right))-      | bop == bop1 -> maybe e (EBin bop e11) (cfR (rop bop) left right)+      | bop' == bop1 -> maybe e (EBin bop' e11) (cfR (rop bop') left right)       | otherwise   -> e     (EBin bop1 e11 (dropECst -> ECon (R left)), ECon (I right))-      | bop == bop1 -> maybe e (EBin bop e11) (cfR (rop bop) left (fromIntegral right))+      | bop' == bop1 -> maybe e (EBin bop' e11) (cfR (rop bop') left (fromIntegral right))       | otherwise   -> e     (EBin bop1 e11 (dropECst -> ECon (I left)), ECon (R right))-      | bop == bop1 -> maybe e (EBin bop e11) (cfR (rop bop) (fromIntegral left) right)+      | bop' == bop1 -> maybe e (EBin bop' e11) (cfR (rop bop') (fromIntegral left) right)       | otherwise   -> e     (EBin bop1 e11 (dropECst -> ECon (I left)), ECon (I right))-      | bop == bop1 -> maybe e (EBin bop e11) (cfI (rop bop) left right)+      | bop' == bop1 -> maybe e (EBin bop' e11) (cfI (rop bop') left right)       | otherwise   -> e     _ -> e   where@@ -90,7 +88,7 @@     rop RDiv   = RTimes     rop Mod    = Mod -    e = EBin bop e1 e2+    e = EBin bop' e1 e2      getOp :: Num a => Bop -> Maybe (a -> a -> a)     getOp Minus    = Just (-)@@ -108,16 +106,16 @@               else Nothing         go Nothing = Nothing -        getOp' Div      = Just (/)-        getOp' RDiv     = Just (/)-        getOp' op       = getOp op+        getOp' Div  | right /= 0 = Just (/)+        getOp' RDiv | right /= 0 = Just (/)+        getOp' op = getOp op      cfI :: Bop -> Integer -> Integer -> Maybe Expr     cfI bop left right = fmap go (getOp' bop)       where         go f = ECon $ I $ f left right -        getOp' Mod = Just mod+        getOp' Mod | right /= 0 = Just mod         getOp' op  = getOp op  isSetPred :: Expr -> Bool@@ -129,18 +127,18 @@  -- Note: this is currently limited to sets of integer constants applySetFolding :: Expr -> Expr -> Expr-applySetFolding e1 e2   = case e1 of+applySetFolding expr1 expr2   = case expr1 of     (EVar s) | s == setEmp-      -> maybe e (fromBool . S.null) (evalSetI e2)+      -> maybe e (fromBool . S.null) (evalSetI expr2)     (EApp (EVar s) e1') | s == setMem-      -> maybe e fromBool (S.member <$> getInt e1' <*> evalSetI e2)+      -> maybe e fromBool (S.member <$> getInt e1' <*> evalSetI expr2)                         | s == setEmp-      -> maybe e (fromBool . S.null) (S.difference <$> evalSetI e1' <*> evalSetI e2)+      -> maybe e (fromBool . S.null) (S.difference <$> evalSetI e1' <*> evalSetI expr2)                         | otherwise       -> e     _                   -> e   where-    e = EApp e1 e2+    e = EApp expr1 expr2      fromBool True  = PTrue     fromBool False = PFalse
src/Language/Fixpoint/Solver/Solution.hs view
@@ -3,8 +3,6 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE PatternGuards     #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-}- module Language.Fixpoint.Solver.Solution   ( -- * Create Initial Solution     init@@ -48,7 +46,7 @@ -------------------------------------------------------------------------------- init :: (F.Fixpoint a) => Config -> F.SInfo a -> S.HashSet F.KVar -> Sol.Solution ---------------------------------------------------------------------------------init cfg si ks_ = Sol.fromList senv mempty keqs [] mempty ebs xEnv+init cfg si ks_ = Sol.fromList symEnv mempty keqs [] mempty ebs xEnv   where     keqs       = map (refine si qcs genv) ws `using` parList rdeepseq     qcs        = {- trace ("init-qs-size " ++ show (length ws, length qs_, M.keys qcs_)) $ -} qcs_@@ -57,7 +55,7 @@     ws         = [ w | (k, w) <- M.toList (F.ws si), not (isGWfc w), k `S.member` ks ]     ks         = {- trace ("init-ks-size" ++ show (S.size ks_)) $ -} ks_     genv       = instConstants si-    senv       = symbolEnv cfg si+    symEnv     = symbolEnv cfg si     ebs        = ebindInfo si     xEnv       = F.fromListSEnv [ (x, (i, F.sr_sort sr)) | (i,(x,sr,_)) <- F.bindEnvToList (F.bs si)] @@ -83,10 +81,10 @@ --------------------------------------------------------------------------------  refine :: F.SInfo a -> QCluster -> F.SEnv F.Sort -> F.WfC a -> (F.KVar, Sol.QBind)-refine fi qs genv w = refineK (allowHOquals fi) env qs (F.wrft w)+refine info qs genv w = refineK (allowHOquals info) env qs (F.wrft w)   where-    env             = wenv <> genv-    wenv            = F.sr_sort <$> F.fromListSEnv (F.envCs (F.bs fi) (F.wenv w))+    env             = wenvSort <> genv+    wenvSort        = F.sr_sort <$> F.fromListSEnv (F.envCs (F.bs info) (F.wenv w))  instConstants :: F.SInfo a -> F.SEnv F.Sort instConstants = F.fromListSEnv . filter notLit . F.toListSEnv . F.gLits@@ -126,16 +124,14 @@          -> QCSig          -> [[F.Symbol]] instKSig _  _   _ _ [] = error "Empty qsig in Solution.instKSig"-instKSig ho env v t (qp:qps) = do-  (su0, i0, qs0) <- candidatesP senv [(0, t, [v])] qp-  ixs       <- matchP senv tyss [(i0, qs0)] (applyQPP su0 <$> qps)-  -- return     $ F.notracepp msg (reverse ixs)+instKSig ho env v sort' (qp:qps) = do+  (su0, i0, qs0) <- candidatesP symToSrch [(0, sort', [v])] qp+  ixs       <- matchP symToSrch tyss [(i0, qs0)] (applyQPP su0 <$> qps)   ys        <- instSymbol tyss (tail $ reverse ixs)   return (v:ys)   where-    -- msg        = "instKSig " ++ F.showpp qsig     tyss       = zipWith (\i (t, ys) -> (i, t, ys)) [1..] (instCands ho env)-    senv       = (`F.lookupSEnvWithDistance` env)+    symToSrch  = (`F.lookupSEnvWithDistance` env)  instSymbol :: [(SortIdx, a, [F.Symbol])] -> [(SortIdx, QualPattern)] -> [[F.Symbol]] instSymbol tyss = go@@ -149,22 +145,6 @@       ys  <- go [ (i', applyQPSubst qsu  qp') | (i', qp') <- is]       return (y:ys) --- instKQ :: Bool---        -> F.SEnv F.Sort---        -> F.Symbol---        -> F.Sort---        -> F.Qualifier---        -> [Sol.EQual]--- instKQ ho env v t q = do---   (su0, qsu0, v0) <- candidates senv [(t, [v])] qp---   xs              <- match senv tyss [v0] (applyQP su0 qsu0 <$> qps)---   return           $ Sol.eQual q (F.notracepp msg (reverse xs))---   where---     msg        = "instKQ " ++ F.showpp (F.qName q) ++ F.showpp (F.qParams q)---     qp : qps   = F.qParams q---     tyss       = instCands ho env---     senv       = (`F.lookupSEnvWithDistance` env)- instCands :: Bool -> F.SEnv F.Sort -> [(F.Sort, [F.Symbol])] instCands ho env = filter isOk tyss   where@@ -323,19 +303,19 @@       (x, sr, _)              = F.lookupBindEnv i (ceBEnv g)  ebSol :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.BindId -> Maybe F.Expr-ebSol g s i = case  M.lookup i sebds of+ebSol g sol bindId = case  M.lookup bindId sebds of   Just (Sol.EbSol p)    -> Just p   Just (Sol.EbDef cs _) -> Just $ F.PAnd (cSol <$> cs)   _                     -> Nothing   where-    sebds = Sol.sEbd s+    sebds = Sol.sEbd sol      ebReft s (i,c) = exElim (Sol.sxEnv s) (senv c) i (ebindReft g s c)     cSol c = if sid c == ceCid g                 then F.PFalse-                else ebReft s' (i, c)+                else ebReft s' (bindId, c) -    s' = s { Sol.sEbd = M.insert i Sol.EbIncr sebds }+    s' = sol { Sol.sEbd = M.insert bindId Sol.EbIncr sebds }  ebindReft :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.SimpC () -> F.Pred ebindReft g s c = F.pAnd [ fst $ apply g' s bs, F.crhs c ]@@ -495,7 +475,7 @@     sp     = F.srcSpan g  substSort :: F.SEnv F.Sort -> S.HashSet F.Symbol -> F.Symbol -> F.Sort -> F.Sort-substSort sEnv _frees x _t = fromMaybe (err x) $ F.lookupSEnv x sEnv+substSort sEnv _frees sym _t = fromMaybe (err sym) $ F.lookupSEnv sym sEnv   where     err x            = error $ "Solution.mkSubst: unknown binder " ++ F.showpp x 
src/Language/Fixpoint/Solver/Solve.hs view
@@ -40,7 +40,7 @@ --import Debug.Trace                      (trace)  mytrace :: String -> a -> a-mytrace _ x = {- trace -} x+mytrace _ x = {- trace s -} x  -------------------------------------------------------------------------------- solve :: (NFData a, F.Fixpoint a, Show a, F.Loc a) => Config -> F.SInfo a -> IO (F.Result (Integer, a))@@ -54,11 +54,11 @@     -- print (numIter stat)     return res   where-    act  = solve_ cfg fi s0 ks  wkl-    sI   = solverInfo cfg fi-    wkl  = W.init sI-    s0   = siSol  sI-    ks   = siVars sI+    act = solve_ cfg fi s0 ks  wkl+    sI  = solverInfo cfg fi+    wkl = W.init sI+    s0  = siSol  sI+    ks  = siVars sI   --------------------------------------------------------------------------------@@ -118,7 +118,7 @@        -> SolveM a (F.Result (Integer, a), Stats) -------------------------------------------------------------------------------- solve_ cfg fi s0 ks wkl = do-  let s1   = {-# SCC "sol-init" #-} S.init cfg fi ks+  let s1   = F.notracepp "solve_ " $ {-# SCC "sol-init" #-} S.init cfg fi ks   let s2   = mappend s0 s1   (s3, res0) <- sendConcreteBindingsToSMT F.emptyIBindEnv $ \bindingsInSmt -> do     -- let s3   = solveEbinds fi s2@@ -178,14 +178,14 @@   | Just (c, w', newScc, rnk) <- W.pop w = do      i       <- tickIter newScc      (b, s') <- refineC bindingsInSmt i s c-     lift $ writeLoud $ refineMsg i c b rnk+     lift $ writeLoud $ refineMsg i c b rnk (showpp s')      let w'' = if b then W.push c w' else w'      refine bindingsInSmt s' w''   | otherwise = return s   where     -- DEBUG-    refineMsg i c b rnk = printf "\niter=%d id=%d change=%s rank=%d\n"-                            i (F.subcId c) (show b) rnk+    refineMsg i c b rnk s = printf "\niter=%d id=%d change=%s rank=%d s=%s\n"+                             i (F.subcId c) (show b) rnk s  --------------------------------------------------------------------------- -- | Single Step Refinement -----------------------------------------------@@ -311,7 +311,7 @@   -- lift   $ printf "isUnsat %s" (show (F.subcId c))   _     <- tickIter True -- newScc   be    <- getBinds-  let lp = S.lhsPred bindingsInSmt be s c+  let lp = S.lhsPred bindingsInSmt (F.coerceBindEnv be) s c   let rp = rhsPred        c   res   <- not <$> isValid (cstrSpan c) lp rp   lift   $ whenLoud $ showUnsat res (F.subcId c) lp rp
src/Language/Fixpoint/Solver/TrivialSort.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP           #-} {-# LANGUAGE DeriveGeneric #-}  {-# OPTIONS_GHC -Wno-name-shadowing #-}@@ -14,7 +15,9 @@ import qualified Data.HashSet            as S import           Data.Hashable import qualified Data.HashMap.Strict     as M+#if !MIN_VERSION_base(4,20,0) import           Data.List (foldl')+#endif import qualified Data.Graph              as G import           Data.Maybe import           Text.Printf
src/Language/Fixpoint/Solver/UniqifyBinds.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP           #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PatternGuards #-} @@ -14,7 +15,9 @@ import qualified Data.HashMap.Strict as M import qualified Data.HashSet        as S import qualified Data.List           as L+#if !MIN_VERSION_base(4,20,0) import           Data.Foldable       (foldl')+#endif import           Data.Maybe          (catMaybes, mapMaybe, fromJust, isJust) import           Data.Hashable       (Hashable) import           GHC.Generics        (Generic)
src/Language/Fixpoint/Solver/UniqifyKVars.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                    #-} {-# OPTIONS_GHC -Wno-name-shadowing #-}  {- | This module creates new bindings for each argument of each kvar.@@ -38,7 +39,9 @@ import           Language.Fixpoint.Types import           Language.Fixpoint.Types.Visitor (mapKVarSubsts) import qualified Data.HashMap.Strict as M+#if !MIN_VERSION_base(4,20,0) import           Data.Foldable       (foldl')+#endif  -------------------------------------------------------------------------------- wfcUniqify    :: SInfo a -> SInfo a
src/Language/Fixpoint/SortCheck.hs view
@@ -123,24 +123,24 @@   instance (Loc a) => Elaborate (SInfo a) where-  elaborate x senv si = si-    { F.cm      = elaborate x senv <$> F.cm      si-    , F.bs      = elaborate x senv  $  F.bs      si-    , F.asserts = elaborate x senv <$> F.asserts si+  elaborate msg senv si = si+    { F.cm      = elaborate msg senv <$> F.cm      si+    , F.bs      = elaborate msg senv  $  F.bs      si+    , F.asserts = elaborate msg senv <$> F.asserts si     }   instance (Elaborate e) => (Elaborate (Triggered e)) where-  elaborate x env t = fmap (elaborate x env) t+  elaborate msg env t = fmap (elaborate msg env) t  instance (Elaborate a) => (Elaborate (Maybe a)) where-  elaborate x env t = fmap (elaborate x env) t+  elaborate msg env t = fmap (elaborate msg env) t  instance Elaborate Sort where   elaborate _ _ = go    where       go s | isString s = strSort-      go (FAbs i s)    = FAbs i   (go s)+      go (FAbs i s)    = FAbs i  (go s)       go (FFunc s1 s2) = funSort (go s1) (go s2)       go (FApp s1 s2)  = FApp    (go s1) (go s2)       go s             = s@@ -164,13 +164,15 @@       env' = insertsSymEnv env (eqArgs eq)  instance Elaborate Expr where-  elaborate msg env = elabNumeric . elabApply env . elabExpr msg env-+  elaborate msg env =+    elabNumeric . elabApply env' . elabExpr msg env' . elabFSet+      where+        env' = coerceEnv env  skipElabExpr :: Located String -> SymEnv -> Expr -> Expr skipElabExpr msg env e = case elabExprE msg env e of   Left _   -> e-  Right e' ->  elabNumeric . elabApply env $ e'+  Right e' -> elabNumeric . elabApply env $ e'  instance Elaborate (Symbol, Sort) where   elaborate msg env (x, s) = (x, elaborate msg env s)@@ -193,20 +195,60 @@       = e  instance Elaborate SortedReft where-  elaborate x env (RR s (Reft (v, e))) = RR s (Reft (v, e'))+  elaborate msg env (RR s (Reft (v, e))) = RR s (Reft (v, e'))     where-      e'   = elaborate x env' e+      e'   = elaborate msg env' e       env' = insertSymEnv v s env  instance (Loc a) => Elaborate (BindEnv a) where   elaborate msg env = mapBindEnv (\i (x, sr, l) -> (x, elaborate (msg' l i x sr) env sr, l))     where-      msg' l i x sr = atLoc l (val msg ++ unwords [" elabBE",  show i, show x, show sr])+      msg' l i x sr = atLoc l (val msg ++ unwords [" elabBE", show i, show x, show sr])  instance (Loc a) => Elaborate (SimpC a) where   elaborate msg env c = c {_crhs = elaborate msg' env (_crhs c) }     where msg'        = atLoc c (val msg) ++---------------------------------------------------------------------------------+-- | 'elabFSet' replaces all finset theory operations with array-based encodings.+---------------------------------------------------------------------------------+elabFSet :: Expr -> Expr+elabFSet (EApp h@(EVar f) e)+  | f == Thy.setEmpty      = EApp (EVar Thy.arrConst) PFalse+  | f == Thy.setEmp        = PAtom Eq (EApp (EVar Thy.arrConst) PFalse) (elabFSet e)+  | f == Thy.setSng        = EApp (EApp (EApp (EVar Thy.arrStore) (EApp (EVar Thy.arrConst) PFalse)) (elabFSet e)) PTrue+  | f == Thy.setCom        = EApp (EVar Thy.arrMapNot) (elabFSet e)+  | otherwise              = EApp (elabFSet h) (elabFSet e)+elabFSet (EApp (EApp h@(EVar f) e1) e2)+  | f == Thy.setMem        = EApp (EApp (EVar Thy.arrSelect) (elabFSet e2)) (elabFSet e1)+  | f == Thy.setCup        = EApp (EApp (EVar Thy.arrMapOr) (elabFSet e1)) (elabFSet e2)+  | f == Thy.setCap        = EApp (EApp (EVar Thy.arrMapAnd) (elabFSet e1)) (elabFSet e2)+  | f == Thy.setAdd        = EApp (EApp (EApp (EVar Thy.arrStore) (elabFSet e1)) (elabFSet e2)) PTrue+  -- A \ B == A /\ ~B == ~(A => B)+  | f == Thy.setDif        = EApp (EApp (EVar Thy.arrMapAnd) (elabFSet e1)) (EApp (EVar Thy.arrMapNot) (elabFSet e2))+  | f == Thy.setSub        = PAtom Eq (EApp (EVar Thy.arrConst) PTrue) (EApp (EApp (EVar Thy.arrMapImp) (elabFSet e1)) (elabFSet e2))+  | otherwise              = EApp (EApp (elabFSet h) (elabFSet e1)) (elabFSet e2)+elabFSet (EApp e1 e2)      = EApp (elabFSet e1) (elabFSet e2)+elabFSet (ENeg e)          = ENeg (elabFSet e)+elabFSet (EBin b e1 e2)    = EBin b (elabFSet e1) (elabFSet e2)+elabFSet (EIte e1 e2 e3)   = EIte (elabFSet e1) (elabFSet e2) (elabFSet e3)+elabFSet (ECst e t)        = ECst (elabFSet e) t+elabFSet (ELam b e)        = ELam b (elabFSet e)+elabFSet (ETApp e t)       = ETApp (elabFSet e) t+elabFSet (ETAbs e t)       = ETAbs (elabFSet e) t+elabFSet (PAnd es)         = PAnd (elabFSet <$> es)+elabFSet (POr es)          = POr (elabFSet <$> es)+elabFSet (PNot e)          = PNot (elabFSet e)+elabFSet (PImp e1 e2)      = PImp (elabFSet e1) (elabFSet e2)+elabFSet (PIff e1 e2)      = PIff (elabFSet e1) (elabFSet e2)+elabFSet (PAtom r e1 e2)   = PAtom r (elabFSet e1) (elabFSet e2)+elabFSet (PAll   bs e)     = PAll bs (elabFSet e)+elabFSet (PExist bs e)     = PExist bs (elabFSet e)+elabFSet (PGrad  k su i e) = PGrad k su i (elabFSet e)+elabFSet (ECoerc a t e)    = ECoerc a t (elabFSet e)+elabFSet e                 = e+ -------------------------------------------------------------------------------- -- | 'elabExpr' adds "casts" to decorate polymorphic instantiation sites. --------------------------------------------------------------------------------@@ -422,11 +464,10 @@  instance Checkable Expr where   check γ e = void $ checkExpr f e-   where f =  (`lookupSEnvWithDistance` γ)+   where f = (`lookupSEnvWithDistance` coerceSortEnv γ) -  checkSort γ s e = void $ checkExpr f (ECst e s)-    where-      f           =  (`lookupSEnvWithDistance` γ)+  checkSort γ s e = void $ checkExpr f (ECst e (coerceSetToArray s))+   where f = (`lookupSEnvWithDistance` coerceSortEnv γ)  instance Checkable SortedReft where   check γ (RR s (Reft (v, ra))) = check γ' ra@@ -436,32 +477,32 @@ -------------------------------------------------------------------------------- -- | Checking Expressions ------------------------------------------------------ ---------------------------------------------------------------------------------checkExpr                  :: Env -> Expr -> CheckM Sort-checkExpr _ (ESym _)       = return strSort-checkExpr _ (ECon (I _))   = return FInt-checkExpr _ (ECon (R _))   = return FReal-checkExpr _ (ECon (L _ s)) = return s-checkExpr f (EVar x)       = checkSym f x-checkExpr f (ENeg e)       = checkNeg f e-checkExpr f (EBin o e1 e2) = checkOp f e1 o e2-checkExpr f (EIte p e1 e2) = checkIte f p e1 e2-checkExpr f (ECst e t)     = checkCst f t e-checkExpr f (EApp g e)     = checkApp f Nothing g e-checkExpr f (PNot p)       = checkPred f p >> return boolSort-checkExpr f (PImp p p')    = mapM_ (checkPred f) [p, p'] >> return boolSort-checkExpr f (PIff p p')    = mapM_ (checkPred f) [p, p'] >> return boolSort-checkExpr f (PAnd ps)      = mapM_ (checkPred f) ps >> return boolSort-checkExpr f (POr ps)       = mapM_ (checkPred f) ps >> return boolSort-checkExpr f (PAtom r e e') = checkRel f r e e' >> return boolSort-checkExpr _ PKVar{}        = return boolSort-checkExpr f (PGrad _ _ _ e)  = checkPred f e >> return boolSort+checkExpr                   :: Env -> Expr -> CheckM Sort+checkExpr _ (ESym _)        = return strSort+checkExpr _ (ECon (I _))    = return FInt+checkExpr _ (ECon (R _))    = return FReal+checkExpr _ (ECon (L _ s))  = return s+checkExpr f (EVar x)        = checkSym f x+checkExpr f (ENeg e)        = checkNeg f e+checkExpr f (EBin o e1 e2)  = checkOp f e1 o e2+checkExpr f (EIte p e1 e2)  = checkIte f p e1 e2+checkExpr f (ECst e t)      = checkCst f t e+checkExpr f (EApp g e)      = checkApp f Nothing g e+checkExpr f (PNot p)        = checkPred f p >> return boolSort+checkExpr f (PImp p p')     = mapM_ (checkPred f) [p, p'] >> return boolSort+checkExpr f (PIff p p')     = mapM_ (checkPred f) [p, p'] >> return boolSort+checkExpr f (PAnd ps)       = mapM_ (checkPred f) ps >> return boolSort+checkExpr f (POr ps)        = mapM_ (checkPred f) ps >> return boolSort+checkExpr f (PAtom r e e')  = checkRel f r e e' >> return boolSort+checkExpr _ PKVar{}         = return boolSort+checkExpr f (PGrad _ _ _ e) = checkPred f e >> return boolSort -checkExpr f (PAll  bs e )  = checkExpr (addEnv f bs) e-checkExpr f (PExist bs e)  = checkExpr (addEnv f bs) e-checkExpr f (ELam (x,t) e) = FFunc t <$> checkExpr (addEnv f [(x,t)]) e-checkExpr f (ECoerc s t e) = checkExpr f (ECst e s) >> return t-checkExpr _ (ETApp _ _)    = error "SortCheck.checkExpr: TODO: implement ETApp"-checkExpr _ (ETAbs _ _)    = error "SortCheck.checkExpr: TODO: implement ETAbs"+checkExpr f (PAll  bs e )   = checkExpr (addEnv f bs) e+checkExpr f (PExist bs e)   = checkExpr (addEnv f bs) e+checkExpr f (ELam (x,t) e)  = FFunc t <$> checkExpr (addEnv f [(x,t)]) e+checkExpr f (ECoerc s t e)  = checkExpr f (ECst e s) >> return t+checkExpr _ (ETApp _ _)     = error "SortCheck.checkExpr: TODO: implement ETApp"+checkExpr _ (ETAbs _ _)     = error "SortCheck.checkExpr: TODO: implement ETAbs"  addEnv :: Eq a => (a -> SESearch b) -> [(a, b)] -> a -> SESearch b addEnv f bs x@@ -562,12 +603,12 @@ elab f@(_,g) e@(PAtom eq e1 e2) | eq == Eq || eq == Ne = do   t1        <- checkExpr g e1   t2        <- checkExpr g e2-  (t1',t2') <- unite g e  t1 t2 `withError` errElabExpr e+  (t1',t2') <- unite g e t1 t2 `withError` errElabExpr e   e1'       <- elabAs f t1' e1   e2'       <- elabAs f t2' e2   e1''      <- eCstAtom f e1' t1'   e2''      <- eCstAtom f e2' t2'-  return (PAtom eq  e1'' e2'' , boolSort)+  return (PAtom eq e1'' e2'' , boolSort)  elab f (PAtom r e1 e2)   | r == Ueq || r == Une = do@@ -623,11 +664,11 @@ elabAddEnv (g, f) bs = (g, addEnv f bs)  elabAs :: ElabEnv -> Sort -> Expr -> CheckM Expr-elabAs f t e = notracepp _msg <$>  go e+elabAs f t e = notracepp _msg <$> go e   where-    _msg  = "elabAs: t = " ++ showpp t ++ " e = " ++ showpp e-    go (EApp e1 e2)   = elabAppAs f t e1 e2-    go e'              = fst    <$> elab f e'+    _msg  = "elabAs: t = " ++ showpp t ++ "; e = " ++ showpp e+    go (EApp e1 e2) = elabAppAs f t e1 e2+    go e'           = fst <$> elab f e'  -- DUPLICATION with `checkApp'` elabAppAs :: ElabEnv -> Sort -> Expr -> Expr -> CheckM Expr@@ -641,11 +682,11 @@   g'       <- elabAs env tg g   let te    = apply su eT   e'       <- elabAs env te e-  return    $ EApp (ECst g' tg) (ECst e' te)+  pure     $ EApp (ECst g' tg) (ECst e' te)  elabEApp  :: ElabEnv -> Expr -> Expr -> CheckM (Expr, Sort, Expr, Sort, Sort) elabEApp f@(_, g) e1 e2 = do-  (e1', s1)     <- notracepp ("elabEApp1: e1 = " ++ showpp e1) <$> elab f e1+  (e1', s1)     <- {- notracepp ("elabEApp: e1 = " ++ showpp e1) <$> -} elab f e1   (e2', s2)     <- elab f e2   (e1'', e2'', s1', s2', s) <- elabAppSort g e1' e2' s1 s2   return           (e1'', s1', e2'', s2', s)@@ -655,14 +696,14 @@   let e            = Just (EApp e1 e2)   (sIn, sOut, su) <- checkFunSort s1   su'             <- unify1 f e su sIn s2-  return (applyExpr (Just su') e1, applyExpr (Just su') e2, apply su' s1, apply su' s2, apply su' sOut)+  return (applyExpr (Just su') e1 , applyExpr (Just su') e2, apply su' s1, apply su' s2, apply su' sOut)   -------------------------------------------------------------------------------- -- | defuncEApp monomorphizes function applications. -------------------------------------------------------------------------------- defuncEApp :: SymEnv -> Expr -> [(Expr, Sort)] -> Expr-defuncEApp _env e [] = e+defuncEApp _   e [] = e defuncEApp env e es = eCst (L.foldl' makeApplication e' es') (snd $ last es)   where     (e', es')       = takeArgs (seTheory env) e es@@ -676,7 +717,8 @@  -- 'e1' is the function, 'e2' is the argument, 's' is the OUTPUT TYPE makeApplication :: Expr -> (Expr, Sort) -> Expr-makeApplication e1 (e2, s) = ECst (EApp (EApp f e1) e2) s+makeApplication e1 (e2, s) =+  ECst (EApp (EApp f e1) e2) s   where     f                      = {- notracepp ("makeApplication: " ++ showpp (e2, t2)) $ -} applyAt t2 s     t2                     = exprSort "makeAppl" e2@@ -751,7 +793,7 @@       are represented, in SMTLIB, as -        (Eapp (EApp apply e1) e2)+        (EApp (EApp apply e1) e2)       where 'apply' is 'ECst (EVar "apply") t' and            't'     is 'FFunc a b'@@ -782,7 +824,7 @@                FBool -> not b ``` -## The Problem+**The Problem**  The problem is you cannot encode the body of `proj` as a well-sorted refinement: @@ -795,7 +837,7 @@ The catch is that `x` is being used BOTH as `Int` and as `Bool` which is not supported in SMTLIB. -## Approach: Uninterpreted Functions+**Approach: Uninterpreted Functions**  We encode `coerce` as an explicit **uninterpreted function**: @@ -833,7 +875,7 @@  and the UIF nature of `coerce_int_int` renders the VC invalid. -## Solution: Eliminate Trivial Coercions+**Solution: Eliminate Trivial Coercions**  HOWEVER, the solution here, may simply be to use UIFs when the coercion is non-trivial (e.g. `a ~ int`) but to eschew them when@@ -851,7 +893,7 @@ -------------------------------------------------------------------------------- applySorts :: Vis.Visitable t => t -> [Sort] ---------------------------------------------------------------------------------applySorts = {- tracepp "applySorts" . -} (defs ++) . Vis.fold vis () []+applySorts = {- notracepp "applySorts" . -} (defs ++) . Vis.fold vis () []   where     defs   = [FFunc t1 t2 | t1 <- basicSorts, t2 <- basicSorts]     vis    = (Vis.defaultVisitor :: Vis.Visitor [KVar] t) { Vis.accExpr = go }@@ -877,7 +919,7 @@     go (ELam (_, sx) e) = FFunc sx <$> go e     go (EApp e ex)       | Just (FFunc sx s) <- genSort <$> go e-      = maybe s (`apply` s) <$> ((`unifySorts` sx) <$> go ex)+      = maybe s (`apply` s) . (`unifySorts` sx) <$> go ex     go _ = Nothing  genSort :: Sort -> Sort@@ -891,7 +933,7 @@  throwErrorAt :: String -> CheckM a throwErrorAt ~err' = do -- Lazy pattern needed because we use LANGUAGE Strict in this module-                       -- See Note [Lazy error messages]+                        -- See Note [Lazy error messages]   sp <- asks chSpan   liftIO $ throwIO (ChError (\_ -> atLoc sp err')) @@ -922,8 +964,8 @@   (`apply` t1) <$> unifys f Nothing [t1] [t2]  checkIteTy :: Env -> Expr -> Expr -> Expr -> Sort -> Sort -> CheckM Sort-checkIteTy f p e1 e2 t1 t2-  = ((`apply` t1) <$> unifys f e' [t1] [t2]) `withError` errIte e1 e2 t1 t2+checkIteTy f p e1 e2 t1 t2 =+  ((`apply` t1) <$> unifys f e' [t1] [t2]) `withError` errIte e1 e2 t1 t2   where     e' = Just (EIte p e1 e2) @@ -933,7 +975,8 @@   = checkApp f (Just t) g e checkCst f t e   = do t' <- checkExpr f e-       ((`apply` t) <$> unifys f (Just e) [t] [t']) `withError` errCast e t' t+       su <- unifys f (Just e) [t] [t'] `withError` errCast e t' t+       pure (apply su t)  checkApp :: Env -> Maybe Sort -> Expr -> Expr -> CheckM Sort checkApp f to g es@@ -945,7 +988,7 @@ checkExprAs f t e   = do t' <- checkExpr f e        θ  <- unifys f (Just e) [t'] [t]-       return $ apply θ t+       pure $ apply θ t  -- | Helper for checking uninterpreted function applications -- | Checking function application should be curried, e.g.
src/Language/Fixpoint/Types/Config.hs view
@@ -113,6 +113,7 @@   , noLazyPLE           :: Bool   , fuel                :: Maybe Int   -- ^ Maximum PLE "fuel" (unfold depth) (default=infinite)   , restOrdering        :: String      -- ^ Term ordering for use in REST+  , noSmtHorn           :: Bool        -- ^ Do not use (new) SMTLIB horn parser   } deriving (Eq,Data,Typeable,Show,Generic)  instance Default Config where@@ -227,13 +228,13 @@   , eliminate                = None    &= help "Eliminate KVars [none = quals for all-kvars, cuts = quals for cut-kvars, all = eliminate all-kvars (TRUE for cuts)]"   , scrape                   = def     &= help "Scrape qualifiers from constraint (Horn format only) [ no = do not, head = scrape from heads, both = scrape from everywhere ]"   , elimBound                = Nothing &= name "elimBound"   &= help "(alpha) Maximum eliminate-chain depth"-  , smtTimeout               = Nothing &= name "smtTimeout"  &= help "smt timeout in msec"+  , smtTimeout               = Nothing &= name "smtTimeout"  &= help "SMT timeout in msec"   , elimStats                = False   &= help "(alpha) Print eliminate stats"   , solverStats              = False   &= help "Print solver stats"   , save                     = False   &= help "Save Query as .fq and .bfq files"   , metadata                 = False   &= help "Print meta-data associated with constraints"   , stats                    = False   &= help "Compute constraint statistics"-  , etaElim                  = False   &= help "eta elimination in function definition"+  , etaElim                  = False   &= help "Eta elimination in function definition"   , parts                    = False   &= help "Partition constraints into indepdendent .fq files"   , cores                    = def     &= help "(numeric) Number of threads to use"   , minPartSize              = defaultMinPartSize &= help "(numeric) Minimum partition size when solving in parallel"@@ -247,7 +248,7 @@   , autoKuts                 = False &= help "Ignore given Kut vars, compute from scratch"   , nonLinCuts               = False &= help "Treat non-linear kvars as cuts"   , noslice                  = False &= help "Disable non-concrete KVar slicing"-  , rewriteAxioms            = False &= help "allow axiom instantiation via rewriting (PLE)"+  , rewriteAxioms            = False &= name "ple" &= help "Allow axiom instantiation via rewriting (PLE)"   , pleWithUndecidedGuards   =       False         &= name "ple-with-undecided-guards"@@ -281,6 +282,7 @@   , restOrdering             = "rpo"         &= name "rest-ordering"         &= help "Ordering Constraint Algebra to use for REST"+  , noSmtHorn                = False &= help "Do not use SMTLIB horn format"   }   &= verbosity   &= program "fixpoint"
src/Language/Fixpoint/Types/Constraints.hs view
@@ -74,6 +74,7 @@   , HOInfo (..)   , allowHO   , allowHOquals+  , cfgHoInfo    -- * Axioms   , AxiomEnv (..)@@ -99,9 +100,9 @@ import qualified Data.List                 as L -- (sort, nub, delete) import           Data.Maybe                (catMaybes) import           Control.DeepSeq-import           Control.Monad             (void)+import           Control.Monad             (when, void) import           Language.Fixpoint.Types.PrettyPrint-import           Language.Fixpoint.Types.Config hiding (allowHO)+import qualified Language.Fixpoint.Types.Config as C import           Language.Fixpoint.Types.Triggers import           Language.Fixpoint.Types.Names import           Language.Fixpoint.Types.Errors@@ -118,6 +119,8 @@ import qualified Data.HashMap.Strict       as M import qualified Data.HashSet              as S import qualified Data.ByteString           as B+import qualified Data.Text as T+import qualified Data.Text.IO as T import qualified Data.Binary as B  --------------------------------------------------------------------------------@@ -503,6 +506,18 @@   | PatExact  !Symbol       -- ^ str       i.e. exactly match 'str'   deriving (Eq, Ord, Show, Data, Typeable, Generic) +instance ToJSON   Qualifier   where+instance FromJSON Qualifier   where+instance ToJSON   QualParam   where+instance FromJSON QualParam   where+instance ToJSON   QualPattern where+instance FromJSON QualPattern where+instance ToJSON   Equation    where+instance FromJSON Equation    where+instance ToJSON   Rewrite     where+instance FromJSON Rewrite     where++ trueQual :: Qualifier trueQual = Q (symbol ("QTrue" :: String)) [] mempty (dummyPos "trueQual") @@ -542,7 +557,6 @@  instance PPrint Qualifier where   pprintTidy k q = "qualif" <+> pprintTidy k (qName q) <+> "defined at" <+> pprintTidy k (qPos q)-  -- pprintTidy _ q = pprQual q  pprQual :: Qualifier -> Doc pprQual (Q n xts p l) = text "qualif" <+> text (symbolString n) <-> parens args <-> colon <+> parens (toFix p) <+> text "//" <+> toFix l@@ -698,6 +712,9 @@   }   deriving (Eq, Show, Generic) +cfgHoInfo :: C.Config -> HOInfo+cfgHoInfo cfg = HOI (C.allowHO cfg) (C.allowHOqs cfg)+ allowHO, allowHOquals :: GInfo c a -> Bool allowHO      = hoBinds . hoInfo allowHOquals = hoQuals . hoInfo@@ -771,7 +788,7 @@ -------------------------------------------------------------------------- -- | Rendering Queries ---------------------------------------------------------------------------toFixpoint :: (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> Doc+toFixpoint :: (Fixpoint a, Fixpoint (c a)) => C.Config -> GInfo c a -> Doc -------------------------------------------------------------------------- toFixpoint cfg x' =    cfgDoc   cfg                   $++$ declsDoc x'@@ -801,7 +818,7 @@     qualsDoc      = vcat     . map toFix . L.sort . quals     aeDoc         = toFix    . ae     metaDoc (i,d) = toFixMeta (text "bind" <+> toFix i) (toFix d)-    mdata         = metadata cfg+    mdata         = C.metadata cfg     binfoDoc       | mdata     = vcat     . map metaDoc . M.toList . bindInfo       | otherwise = \_ -> text "\n"@@ -815,7 +832,7 @@   where     kvD (c, so) = d <+> toFix c <+> ":" <+> parens (toFix so) -writeFInfo :: (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> FilePath -> IO ()+writeFInfo :: (Fixpoint a, Fixpoint (c a)) => C.Config -> GInfo c a -> FilePath -> IO () writeFInfo cfg fq f = writeFile f (render $ toFixpoint cfg fq)  --------------------------------------------------------------------------------@@ -876,30 +893,29 @@ --------------------------------------------------------------------------- -- | Top level Solvers ---------------------------------------------------- ----------------------------------------------------------------------------type Solver a = Config -> FInfo a -> IO (Result (Integer, a))+type Solver a = C.Config -> FInfo a -> IO (Result (Integer, a))  ---------------------------------------------------------------------------------saveQuery :: (Fixpoint a) => Config -> FInfo a -> IO ()+saveQuery :: (Fixpoint a) => C.Config -> FInfo a -> IO () ---------------------------------------------------------------------------------saveQuery cfg fi = {- when (save cfg) $ -} do+saveQuery cfg fi = when (C.save cfg) $ do   let fi'  = void fi   saveBinaryQuery cfg fi'   saveTextQuery cfg   fi -saveBinaryQuery :: Config -> FInfo () -> IO ()+saveBinaryQuery :: C.Config -> FInfo () -> IO () saveBinaryQuery cfg fi = do-  let bfq  = queryFile Files.BinFq cfg+  let bfq  = C.queryFile Files.BinFq cfg   putStrLn $ "Saving Binary Query: " ++ bfq ++ "\n"   ensurePath bfq   B.writeFile bfq (S.encode fi)-  -- B.encodeFile bfq fi -saveTextQuery :: Fixpoint a => Config -> FInfo a -> IO ()+saveTextQuery :: Fixpoint a => C.Config -> FInfo a -> IO () saveTextQuery cfg fi = do-  let fq   = queryFile Files.Fq cfg+  let fq   = C.queryFile Files.Fq cfg   putStrLn $ "Saving Text Query: "   ++ fq ++ "\n"   ensurePath fq-  writeFile fq $ render (toFixpoint cfg fi)+  T.writeFile fq $ T.pack $ render (toFixpoint cfg fi)  --------------------------------------------------------------------------- -- | Axiom Instantiation Information --------------------------------------
src/Language/Fixpoint/Types/Environments.hs view
@@ -49,6 +49,8 @@   , bindEnvFromList, bindEnvToList, deleteBindEnv, elemsBindEnv   , EBindEnv, splitByQuantifiers +  , coerceBindEnv+   -- * Information needed to lookup and update Solutions   -- , SolEnv (..) @@ -73,6 +75,7 @@  import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Types.Names+import           Language.Fixpoint.Types.Sorts import           Language.Fixpoint.Types.Refinements import           Language.Fixpoint.Types.Substitutions () import           Language.Fixpoint.Misc@@ -360,3 +363,6 @@   where     kIs       = [ (k, i) | (i, ks) <- kPacks, k <- ks ]     kPacks    = zip [0..] . coalesce . fmap S.toList $ kvss++coerceBindEnv :: BindEnv a -> BindEnv a+coerceBindEnv be = be { beBinds = M.map (\(s, sr, a) -> (s, sr { sr_sort = coerceSetToArray (sr_sort sr) } , a)) (beBinds be) }
src/Language/Fixpoint/Types/Names.hs view
@@ -93,12 +93,14 @@   , dummyName   , preludeName   , boolConName+  , boolLConName   , funConName   , listConName   , listLConName   , tupConName   , setConName   , mapConName+  , arrayConName   , strConName   , charConName   , nilName@@ -150,6 +152,8 @@ import           Language.Fixpoint.Utils.Builder as Builder (fromText) import Data.Functor.Contravariant (Contravariant(contramap)) import qualified Data.Binary as B+import qualified Data.Aeson       as Aeson+import qualified Data.Aeson.Types as Aeson  --------------------------------------------------------------- -- | Symbols --------------------------------------------------@@ -176,7 +180,8 @@   = S { _symbolId      :: !Id       , symbolRaw      :: T.Text       , symbolEncoded  :: T.Text-      } deriving (Data, Typeable, Generic)+      }+    deriving (Data, Typeable, Generic)  instance Eq Symbol where   S i _ _ == S j _ _ = i == j@@ -212,9 +217,21 @@   size = contramap symbolText S.size  instance B.Binary Symbol where-   get = textSymbol <$> B.get-   put = B.put . symbolText+  get = textSymbol <$> B.get+  put = B.put . symbolText +instance Aeson.ToJSON Symbol where+  toJSON = Aeson.toJSON . symbolText++instance Aeson.FromJSON Symbol where+  parseJSON = fmap textSymbol . Aeson.parseJSON++instance Aeson.ToJSONKey Symbol where+  toJSONKey = Aeson.toJSONKeyText symbolText++instance Aeson.FromJSONKey Symbol where+  fromJSONKey = Aeson.FromJSONKeyText textSymbol+ sCache :: Cache Symbol sCache = mkCache {-# NOINLINE sCache #-}@@ -624,19 +641,21 @@ coerceName :: Symbol coerceName = "coerce" -preludeName, dummyName, boolConName, funConName :: Symbol+preludeName, dummyName, boolConName, boolLConName, funConName :: Symbol preludeName  = "Prelude" dummyName    = "LIQUID$dummy" boolConName  = "Bool"+boolLConName  = "bool" funConName   = "->"  -listConName, listLConName, tupConName, propConName, _hpropConName, vvName, setConName, mapConName :: Symbol+listConName, listLConName, tupConName, propConName, _hpropConName, vvName, setConName, mapConName, arrayConName:: Symbol listConName  = "[]" listLConName = "List" tupConName   = "Tuple" setConName   = "Set_Set" mapConName   = "Map_t"+arrayConName = "Array_t" vvName       = "VV" propConName  = "Prop" _hpropConName = "HProp"@@ -708,6 +727,7 @@   , "Map_store"   , "Map_union"   , "Map_default"+  , arrayConName   -- Currently we parse X in "SizeX" to get the bitvec size   -- so there is no finite set of names to add here...   -- , size32Name
src/Language/Fixpoint/Types/Refinements.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                        #-} {-# LANGUAGE DeriveDataTypeable         #-} {-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE FlexibleContexts           #-}@@ -116,7 +117,11 @@ import           Data.HashSet              (HashSet) import qualified Data.HashSet              as HashSet import           GHC.Generics              (Generic)+#if MIN_VERSION_base(4,20,0)+import           Data.List                 (partition)+#else import           Data.List                 (foldl', partition)+#endif import qualified Data.Set                  as Set import           Data.String import           Data.Text                 (Text)@@ -131,6 +136,7 @@ import           Language.Fixpoint.Misc import           Text.PrettyPrint.HughesPJ.Compat import qualified Data.Binary as B+import           Data.Aeson  -- import           Text.Printf               (printf) @@ -236,7 +242,7 @@ --------------------------------------------------------------------------------  newtype KVar = KV { kv :: Symbol }-               deriving (Eq, Ord, Data, Typeable, Generic, IsString)+               deriving (Eq, Ord, Data, Typeable, Generic, IsString, ToJSON, FromJSON)  intKvar :: Integer -> KVar intKvar = KV . intSymbol "k_"@@ -258,7 +264,7 @@ -- | Substitutions ------------------------------------------------------------- -------------------------------------------------------------------------------- newtype Subst = Su (M.HashMap Symbol Expr)-                deriving (Eq, Data, Ord, Typeable, Generic)+                deriving (Eq, Data, Ord, Typeable, Generic, ToJSON, FromJSON)  instance Show Subst where   show = showFix@@ -288,7 +294,7 @@ -- | Uninterpreted constants that are embedded as  "constant symbol : Str"  newtype SymConst = SL Text-                   deriving (Eq, Ord, Show, Data, Typeable, Generic)+                   deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  data Constant = I !Integer               | R !Double@@ -302,6 +308,17 @@             deriving (Eq, Ord, Show, Data, Typeable, Generic)             -- NOTE: For "Mod" 2nd expr should be a constant or a var *) +instance ToJSON Constant  where+instance ToJSON Brel      where+instance ToJSON Bop       where+instance ToJSON Expr      where++instance FromJSON Constant  where+instance FromJSON Brel      where+instance FromJSON Bop       where+instance FromJSON Expr      where++ data Expr = ESym !SymConst           | ECon !Constant           | EVar !Symbol@@ -427,6 +444,9 @@ data GradInfo = GradInfo {gsrc :: SrcSpan, gused :: Maybe SrcSpan}           deriving (Eq, Ord, Show, Data, Typeable, Generic) +instance ToJSON   GradInfo+instance FromJSON GradInfo+ srcGradInfo :: SourcePos -> GradInfo srcGradInfo src = GradInfo (SS src src) Nothing @@ -446,12 +466,12 @@ splitEAppThroughECst = go []   where     go acc (dropECst -> (EApp f e)) = go (e:acc) f-    go acc e          = (e, acc)+    go acc e                        = (e, acc)  dropECst :: Expr -> Expr dropECst e = case e of   ECst e' _ -> dropECst e'-  _ -> e+  _         -> e  splitPAnd :: Expr -> [Expr] splitPAnd (PAnd es) = concatMap splitPAnd es@@ -462,7 +482,7 @@  -- | Eliminates redundant casts eCst :: Expr -> Sort -> Expr-eCst e t = ECst (dropECst e) t+eCst e s = ECst (dropECst e) s  -------------------------------------------------------------------------------- debruijnIndex :: Expr -> Int@@ -914,7 +934,7 @@ pExist xts p = PExist xts p  mkProp :: Expr -> Pred-mkProp = id -- EApp (EVar propConName)+mkProp = id  -------------------------------------------------------------------------------- -- | Predicates ----------------------------------------------------------------
src/Language/Fixpoint/Types/Sorts.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE ViewPatterns               #-}  {-# OPTIONS_GHC -Wno-name-shadowing     #-}+{-# LANGUAGE DeriveAnyClass #-}  -- | This module contains the data types, operations and --   serialization functions for representing Fixpoint's@@ -37,6 +38,7 @@   , basicSorts, intSort, realSort, boolSort, strSort, funcSort   -- , bitVec32Sort, bitVec64Sort   , setSort, bitVecSort+  , arraySort   , sizedBitVecSort   , mapSort, charSort   , listFTyCon@@ -63,7 +65,7 @@   , sortSymbols   , substSort -  , isNumeric, isReal, isString, isPolyInst+  , isBool, isNumeric, isReal, isString, isSet, isArray, isPolyInst    -- * User-defined ADTs   , DataField (..)@@ -80,16 +82,23 @@   , tceInsert   , tceInsertWith   , tceMap++  -- * Sort coercion for SMT theory encoding+  , coerceSetToArray   ) where  import qualified Data.Store as S import           Data.Generics             (Data) import           Data.Typeable             (Typeable) import           GHC.Generics              (Generic)+import           Data.Aeson+ import           Data.Hashable import           Data.HashSet (HashSet) import qualified Data.HashSet as HashSet+#if !MIN_VERSION_base(4,20,0) import           Data.List                 (foldl')+#endif import           Control.DeepSeq import           Data.Maybe                (fromMaybe) import           Language.Fixpoint.Types.Names@@ -102,7 +111,7 @@ import qualified Data.Binary as B import Text.Read (readMaybe) -data FTycon   = TC LocSymbol TCInfo deriving (Ord, Show, Data, Typeable, Generic)+data FTycon   = TC LocSymbol TCInfo deriving (Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  -- instance Show FTycon where --   show (TC s _) = show (val s)@@ -114,7 +123,7 @@   (TC s _) == (TC s' _) = val s == val s'  data TCInfo = TCInfo { tc_isNum :: Bool, tc_isReal :: Bool, tc_isString :: Bool }-  deriving (Eq, Ord, Show, Data, Typeable, Generic)+  deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  mappendFTC :: FTycon -> FTycon -> FTycon mappendFTC (TC x i1) (TC _ i2) = TC x (mappend i1 i2)@@ -139,16 +148,16 @@  charFTyCon, intFTyCon, boolFTyCon, realFTyCon, funcFTyCon, numFTyCon :: FTycon strFTyCon, listFTyCon, mapFTyCon, setFTyCon :: FTycon-intFTyCon  = TC (dummyLoc "int"      ) numTcInfo-boolFTyCon = TC (dummyLoc "bool"     ) defTcInfo-realFTyCon = TC (dummyLoc "real"     ) realTcInfo-numFTyCon  = TC (dummyLoc "num"      ) numTcInfo-funcFTyCon = TC (dummyLoc "function" ) defTcInfo-strFTyCon  = TC (dummyLoc strConName ) strTcInfo-listFTyCon = TC (dummyLoc listConName) defTcInfo-charFTyCon = TC (dummyLoc charConName) defTcInfo-setFTyCon  = TC (dummyLoc setConName ) defTcInfo-mapFTyCon  = TC (dummyLoc mapConName ) defTcInfo+intFTyCon  = TC (dummyLoc "int"       ) numTcInfo+boolFTyCon = TC (dummyLoc boolLConName) defTcInfo+realFTyCon = TC (dummyLoc "real"      ) realTcInfo+numFTyCon  = TC (dummyLoc "num"       ) numTcInfo+funcFTyCon = TC (dummyLoc "function"  ) defTcInfo+strFTyCon  = TC (dummyLoc strConName  ) strTcInfo+listFTyCon = TC (dummyLoc listConName ) defTcInfo+charFTyCon = TC (dummyLoc charConName ) defTcInfo+setFTyCon  = TC (dummyLoc setConName  ) defTcInfo+mapFTyCon  = TC (dummyLoc mapConName  ) defTcInfo  isListConName :: LocSymbol -> Bool isListConName x = c == listConName || c == listLConName --"List"@@ -158,6 +167,22 @@ isListTC :: FTycon -> Bool isListTC (TC z _) = isListConName z +isSetConName :: LocSymbol -> Bool+isSetConName x = c == setConName+  where+    c           = val x++isSetTC :: FTycon -> Bool+isSetTC (TC z _) = isSetConName z++isArrayConName :: LocSymbol -> Bool+isArrayConName x = c == arrayConName+  where+    c           = val x++isArrayTC :: FTycon -> Bool+isArrayTC (TC z _) = isArrayConName z+ sizeBv :: FTycon -> Maybe Int sizeBv tc = do   let s = val $ fTyconSymbol tc@@ -260,7 +285,7 @@           | FAbs  !Int !Sort     -- ^ type-abstraction           | FTC   !FTycon           | FApp  !Sort !Sort    -- ^ constructed type-            deriving (Eq, Ord, Show, Data, Typeable, Generic)+            deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  instance PPrint Sort where   pprintTidy _ = toFix@@ -284,18 +309,18 @@ data DataField = DField   { dfName :: !LocSymbol          -- ^ Field Name   , dfSort :: !Sort               -- ^ Field Sort-  } deriving (Eq, Ord, Show, Data, Typeable, Generic)+  } deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  data DataCtor = DCtor   { dcName   :: !LocSymbol        -- ^ Ctor Name   , dcFields :: ![DataField]      -- ^ Ctor Fields-  } deriving (Eq, Ord, Show, Data, Typeable, Generic)+  } deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  data DataDecl = DDecl   { ddTyCon :: !FTycon            -- ^ Name of defined datatype   , ddVars  :: !Int               -- ^ Number of type variables   , ddCtors :: [DataCtor]         -- ^ Datatype Ctors. Invariant: type variables bound in ctors are greater than ddVars-  } deriving (Eq, Ord, Show, Data, Typeable, Generic)+  } deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  instance Loc DataDecl where     srcSpan (DDecl ty _ _) = srcSpan ty@@ -331,6 +356,10 @@ isFunction (FFunc _ _) = True isFunction _           = False +isBool :: Sort -> Bool+isBool (FTC (TC c _)) = val c == boolLConName+isBool _              = False+ isNumeric :: Sort -> Bool isNumeric FInt           = True isNumeric FReal          = True@@ -346,7 +375,6 @@ isReal (FAbs _ s)     = isReal s isReal _              = False - isString :: Sort -> Bool isString (FApp l c)     = (isList l && isChar c) || isString l isString (FTC (TC c i)) = val c == strConName || tc_isString i@@ -357,6 +385,14 @@ isList (FTC c) = isListTC c isList _       = False +isSet :: Sort -> Bool+isSet (FTC c) = isSetTC c+isSet _       = False++isArray :: Sort -> Bool+isArray (FTC c) = isArrayTC c+isArray _       = False+ isChar :: Sort -> Bool isChar (FTC c) = c == charFTyCon isChar _       = False@@ -451,7 +487,7 @@ instance Fixpoint DataDecl where   toFix (DDecl tc n ctors) = vcat ([header] ++ body ++ [footer])     where-      header               = {- text "data" <+> -} toFix tc <+> toFix n <+> text "= ["+      header               = toFix tc <+> toFix n <+> text "= ["       body                 = [nest 2 (text "|" <+> toFix ct) | ct <- ctors]       footer               = text "]" @@ -480,7 +516,7 @@ funcSort = fTyconSort funcFTyCon  setSort :: Sort -> Sort-setSort    = FApp (FTC setFTyCon)+setSort = FApp (FTC setFTyCon)  -- bitVecSort :: Sort -> Sort -- bitVecSort = FApp (FTC $ symbolFTycon' bitVecName)@@ -500,6 +536,9 @@ mapSort :: Sort -> Sort -> Sort mapSort = FApp . FApp (FTC (symbolFTycon' mapConName)) +arraySort :: Sort -> Sort -> Sort+arraySort = FApp . FApp (FTC (symbolFTycon' arrayConName))+ symbolFTycon' :: Symbol -> FTycon symbolFTycon' = symbolFTycon . dummyLoc @@ -625,3 +664,15 @@  tceMember :: (Eq a, Hashable a) => a -> TCEmb a -> Bool tceMember k (TCE m) = M.member k m++-------------------------------------------------------------------------------+-- | Sort coercion for SMT theory encoding+-------------------------------------------------------------------------------++coerceSetToArray :: Sort -> Sort+coerceSetToArray   (FFunc sf sa) = FFunc (coerceSetToArray sf) (coerceSetToArray sa)+coerceSetToArray   (FAbs i sa)   = FAbs i (coerceSetToArray sa)+coerceSetToArray s@(FApp sf sa)+  | isSet sf = arraySort (coerceSetToArray sa) boolSort+  | otherwise = s+coerceSetToArray s = s
src/Language/Fixpoint/Types/Spans.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE ScopedTypeVariables       #-}  {-# OPTIONS_GHC -Wno-orphans           #-}+{-# LANGUAGE DeriveAnyClass #-}  module Language.Fixpoint.Types.Spans ( @@ -56,6 +57,7 @@ import           Text.Printf import Data.Functor.Contravariant (Contravariant(contramap)) import qualified Data.Binary as B+import           Data.Aeson -- import           Debug.Trace  @@ -161,11 +163,16 @@   toFix = text . show  -data Located a = Loc { loc  :: !SourcePos -- ^ Start Position-                     , locE :: !SourcePos -- ^ End Position-                     , val  :: !a-                     } deriving (Data, Typeable, Generic)+data Located a = Loc +  { loc  :: !SourcePos -- ^ Start Position+  , locE :: !SourcePos -- ^ End Position+  , val  :: !a+  } +  deriving (Data, Typeable, Generic, ToJSON, FromJSON) +instance ToJSON SourcePos where+instance FromJSON SourcePos where+ instance Loc (Located a) where   srcSpan (Loc l l' _) = SS l l' @@ -215,6 +222,11 @@  instance (B.Binary a) => B.Binary (Located a) ++instance ToJSON Pos where ++instance FromJSON Pos where+ srcLine :: (Loc a) => a -> Pos srcLine = sourceLine . sp_start . srcSpan @@ -224,7 +236,7 @@  data SrcSpan = SS { sp_start :: !SourcePos                   , sp_stop  :: !SourcePos}-                 deriving (Eq, Ord, Show, Data, Typeable, Generic)+                 deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  instance NFData SrcSpan instance S.Store SrcSpan
src/Language/Fixpoint/Types/Theories.hs view
@@ -33,7 +33,9 @@     , symbolAtName     , symbolAtSmtName -+    -- * Coercing sorts in environments+    , coerceEnv+    , coerceSortEnv     ) where  @@ -228,8 +230,10 @@   | SBool   | SReal   | SString+  -- TODO remove these now that we use SArray directly   | SSet   | SMap+  | SArray !SmtSort !SmtSort   | SBitVec !Int   | SVar    !Int   | SData   !FTycon ![SmtSort]@@ -271,6 +275,8 @@       | setConName == symbol c  = SSet     go (FTC c) _       | mapConName == symbol c  = SMap+    go (FTC c) [a, b]+      | arrayConName == symbol c = SArray (sortSmtSort poly env a) (sortSmtSort poly env b)     go (FTC bv) [FTC s]       | bitVecName == symbol bv       , Just n <- sizeBv s      = SBitVec n@@ -294,6 +300,7 @@   pprintTidy _ SString      = text "Str"   pprintTidy _ SSet         = text "Set"   pprintTidy _ SMap         = text "Map"+  pprintTidy k (SArray a b) = ppParens k (text "Array") [a, b]   pprintTidy _ (SBitVec n)  = text "BitVec" <+> int n   pprintTidy _ (SVar i)     = text "@" <-> int i --  HKT pprintTidy k (SApp ts)    = ppParens k (pprintTidy k tyAppName) ts@@ -301,3 +308,18 @@  ppParens :: (PPrint d) => Tidy -> Doc -> [d] -> Doc ppParens k d ds = parens $ Misc.intersperse (text "") (d : (pprintTidy k <$> ds))++--------------------------------------------------------------------------------+-- | Coercing sorts inside environments for SMT theory encoding+--------------------------------------------------------------------------------++coerceSortEnv :: SEnv Sort -> SEnv Sort+coerceSortEnv ss = coerceSetToArray <$> ss++coerceEnv :: SymEnv -> SymEnv+coerceEnv env = SymEnv { seSort   = coerceSortEnv (seSort env)+                       , seTheory = seTheory env+                       , seData   = seData   env+                       , seLits   = seLits   env+                       , seAppls  = seAppls  env+                       }
src/Language/Fixpoint/Types/Visitor.hs view
@@ -470,9 +470,9 @@ instance (SymConsts (c a)) => SymConsts (GInfo c a) where   symConsts fi = Misc.sortNub $ csLits ++ bsLits ++ qsLits     where-      csLits   = concatMap symConsts $ M.elems  $  cm    fi-      bsLits   = symConsts           $ bs                fi-      qsLits   = concatMap symConsts $ qBody   <$> quals fi+      csLits   = concatMap symConsts $ M.elems $ cm    fi+      bsLits   = symConsts                     $ bs    fi+      qsLits   = concatMap (symConsts . qBody) $ quals fi  instance SymConsts (BindEnv a) where   symConsts    = concatMap (symConsts . Misc.snd3) . M.elems . beBinds
src/Language/Fixpoint/Utils/Files.hs view
@@ -91,6 +91,7 @@          | BinFq    -- ^ Binary representation of .fq / FInfo          | Smt2     -- ^ SMTLIB2 query file          | HSmt2    -- ^ Horn query file+         | HJSON    -- ^ Horn query JSON file          | Min      -- ^ filter constraints with delta debug          | MinQuals -- ^ filter qualifiers with delta debug          | MinKVars -- ^ filter kvars with delta debug@@ -124,6 +125,7 @@     go Cache    = ".err"     go Smt2     = ".smt2"     go HSmt2    = ".horn.smt2"+    go HJSON    = ".horn.json"     go (Auto n) = ".auto." ++ show n     go Dot      = ".dot"     go BinFq    = ".bfq"
tests/pos/literals03.fq view
@@ -12,5 +12,5 @@ constraint:   env [ 1; 2 ]   lhs {v : int | true }-  rhs {v : int | Set_mem a (listElts things)} +  rhs {v : int | Set_mem a (listElts things)}   id 1 tag []
tests/pos/literals04.fq view
@@ -12,5 +12,5 @@ constraint:   env [ 1; 2 ]   lhs {v : int | true }-  rhs {v : int | Set_mem a (listElts things)} +  rhs {v : int | Set_mem a (listElts things)}   id 1 tag []
tests/pos/literals05.fq view
@@ -2,13 +2,13 @@ constant Set_sng : (func(1, [@(0); (Set_Set  @(0))]))  bind 1 a  : {a : Str | a == "director" }-bind 2 things : {v : LLChar | (listElts v == (Set_cup (Set_sng "year") -                                               (Set_cup (Set_sng "star") -                                                 (Set_cup (Set_sng "director") +bind 2 things : {v : LLChar | (listElts v == (Set_cup (Set_sng "year")+                                               (Set_cup (Set_sng "star")+                                                 (Set_cup (Set_sng "director")                                                    (Set_sng "title"))))) }  constraint:   env [ 1; 2 ]   lhs {v : int | true }-  rhs {v : int | Set_mem a (listElts things)} +  rhs {v : int | Set_mem a (listElts things)}   id 1 tag []
tests/pos/maps03.fq view
@@ -1,10 +1,10 @@ bind 1 m1 : {v : Map_t Int Int | v = Map_default 0}-bind 2 m2 : {v : Map_t Int Int | v = (Map_store (Map_store (Map_store m1 30 3) 10 1) 20 2) } +bind 2 m2 : {v : Map_t Int Int | v = (Map_store (Map_store (Map_store m1 30 3) 10 1) 20 2) } bind 3 s1 : {v : Set_Set Int | v = (Set_cup (Set_sng 30) (Set_sng 20))}-bind 4 m3 : {v : Map_t Int Int | v = (Map_store (Map_store m1 20 2) 30 3) } +bind 4 m3 : {v : Map_t Int Int | v = (Map_store (Map_store m1 20 2) 30 3) }  constraint:   env [ 1; 2; 3; 4 ]   lhs {v : Map_t Int Int | v = Map_project s1 m2}-  rhs {v : Map_t Int Int | v = m3 } +  rhs {v : Map_t Int Int | v = m3 }   id 1 tag []
+ tests/pos/polyset.fq view
@@ -0,0 +1,37 @@+data PolySet.Lst 1 = [+       | PolySet.Cons {PolySet.Cons##lqdc##$select##PolySet.Cons##1 : @(0), PolySet.Cons##lqdc##$select##PolySet.Cons##2 : (PolySet.Lst @(0))}+       | PolySet.Emp {}+     ]++constant PolySet.Cons##lqdc##$select##PolySet.Cons##1 : (func(1 , [(PolySet.Lst @(0));+                                                                   @(0)]))+constant PolySet.Cons##lqdc##$select##PolySet.Cons##2 : (func(1 , [(PolySet.Lst @(0));+                                                                   (PolySet.Lst @(0))]))+constant is$PolySet.Cons : (func(1 , [(PolySet.Lst @(0)); bool]))+constant is$PolySet.Emp : (func(1 , [(PolySet.Lst @(0)); bool]))+constant PolySet.Cons : (func(1 , [@(0);+                                   (PolySet.Lst @(0));+                                   (PolySet.Lst @(0))]))+constant PolySet.lstHd : (func(1 , [(PolySet.Lst @(0));+                                    (Set_Set @(0))]))++bind 1 PolySet.Emp : {VV : func(1 , [(PolySet.Lst @(0))]) | []}+bind 2 PolySet.Cons : {VV : func(1 , [@(0);+                                       (PolySet.Lst @(0));+                                       (PolySet.Lst @(0))]) | []}+bind 3 p : {VV : (PolySet.Lst l##a1Uh) | []}++constraint:+  env [1; 2; 3]+  lhs {VV : (PolySet.Lst (PolySet.Lst l##a1Uh)) | [(is$PolySet.Cons VV);+                                                   (~ ((is$PolySet.Emp VV)));+                                                   (VV = (PolySet.Cons p PolySet.Emp));+                                                   ((PolySet.Cons##lqdc##$select##PolySet.Cons##1 VV) =+                                                      p);+                                                   ((PolySet.Cons##lqdc##$select##PolySet.Cons##2 VV) =+                                                      PolySet.Emp);+                                                   ((PolySet.lstHd VV) = (Set_sng p))]}+  rhs {VV : (PolySet.Lst (PolySet.Lst l##a1Uh)) | [(VV =+                                                      (PolySet.Cons p PolySet.Emp))]}+  id 4 tag [4]+
tests/pos/sets01.fq view
@@ -2,38 +2,38 @@ constant Set_sng : (func(1, [@(0); (Set_Set  @(0))]))  bind 1 m1 : {v : Set_Set Int | v = Set_empty 0}-bind 2 m2 : {v : Set_Set Int | v = (Set_cup (Set_cup m1 (Set_sng 10)) (Set_sng 20)) } -bind 3 m3 : {v : Set_Set Int | v = (Set_cup (Set_cup m1 (Set_sng 20)) (Set_sng 10)) } -bind 4 m4 : {v : Set_Set Int | v = (Set_cup m1 (Set_sng 10)) } -bind 5 m5 : {v : Set_Set Int | v = (Set_cup m1 (Set_sng 20)) } +bind 2 m2 : {v : Set_Set Int | v = (Set_cup (Set_cup m1 (Set_sng 10)) (Set_sng 20)) }+bind 3 m3 : {v : Set_Set Int | v = (Set_cup (Set_cup m1 (Set_sng 20)) (Set_sng 10)) }+bind 4 m4 : {v : Set_Set Int | v = (Set_cup m1 (Set_sng 10)) }+bind 5 m5 : {v : Set_Set Int | v = (Set_cup m1 (Set_sng 20)) }  constraint:   env [ 1 ]   lhs {v : int | true }-  rhs {v : int | not (Set_mem 100 m1)  } +  rhs {v : int | not (Set_mem 100 m1)  }   id 1 tag []  constraint:   env [ 1; 2 ]-  lhs {v : int | true } +  lhs {v : int | true }   rhs {v : int | not (Set_mem 100 m2) }   id 2 tag []  constraint:   env [ 1; 2 ]-  lhs {v : int | true } +  lhs {v : int | true }   rhs {v : int | Set_mem 10 m2 }   id 3 tag []  constraint:   env [ 1; 2; 3 ]   lhs {v : int | true }-  rhs {v : int | m2 = m3 } +  rhs {v : int | m2 = m3 }   id 4 tag []  constraint:   env [ 1; 2; 3; 4; 5 ]   lhs {v : int | true }-  rhs {v : int | m2 = Set_cup m4 m5 } +  rhs {v : int | m2 = Set_cup m4 m5 }   id 5 tag [] 
tests/tasty/Arbitrary.hs view
@@ -89,9 +89,7 @@ arbitraryFiniteExpr zeroExprGen n = frequency   [ (1, EApp <$> arbitraryExpr' <*> arbitraryExpr')   , (1, ENeg <$> arbitraryExpr')-  , (1, do-          e <- EBin <$> arbitrary <*> arbitraryExpr' <*> arbitraryExpr'-          return $ if divZero e then discard e else e)+  , (1, EBin <$> arbitrary <*> arbitraryExpr' <*> arbitraryExpr')   , (1, EIte <$> arbitraryExpr' <*> arbitraryExpr' <*> arbitraryExpr')   , (1, ECst <$> arbitraryExpr' <*> arbitrary)   , (1, ELam <$> arbitrary <*> arbitraryExpr')@@ -115,13 +113,6 @@     arbitraryList gen = choose (2, 3) >>= (`vectorOf` gen)     arbitraryExprList = arbitraryList arbitraryExpr' -    divZero :: Expr -> Bool-    divZero (EBin Mod (ECon (I _)) (ECon (I 0))) = True-    divZero (EBin Mod (ECon (R _)) (ECon (R 0.0))) = True-    divZero (EBin Div (ECon (I _)) (ECon (I 0))) = True-    divZero (EBin Div (ECon (R _)) (ECon (R 0.0))) = True-    divZero _ = False- -- | Generates a finite expression, with the logarithm of the Int given -- suggesting the depth of the expression tree. arbitraryExpr :: Int -> Gen Expr@@ -375,7 +366,7 @@     prevSymExpr <- arbitraryExprInvolving prevSym n     pure (sym, RR FInt (reft otherSym (PAtom Eq (EVar otherSym) prevSymExpr)))   where-    pairs xs = zip xs (tail xs)+    pairs xs = zip xs (drop 1 xs)  -- This is not random, but is simplified so that you can make chains more -- easily.
tests/tasty/ParserTests.hs view
@@ -289,6 +289,12 @@     , testCase "funApp 3" $         show (doParse' predP "test" "f ([a; b])") @?= "EApp (EApp (EVar \"f\") (EVar \"a\")) (EVar \"b\")" +    , testCase "funApp 4" $+        show (doParse' funAppP "" "f ?(x > 1)") @?= "EApp (EVar \"f\") (PAtom Gt (EVar \"x\") (ECon (I 1)))"++    , testCase "funApp 5" $+        show (doParse' predP "" "f ?(x > 1)") @?= "EApp (EVar \"f\") (PAtom Gt (EVar \"x\") (ECon (I 1)))"+     , testCase "symbol" $         show (doParse' predP "test" "f") @?= "EVar \"f\"" 
tests/tasty/ShareMapReference.hs view
@@ -71,14 +71,14 @@        | otherwise ->          let v0 = h HashMap.! k0              v1 = maybe v0 (f v0) $ HashMap.lookup k1 h-             keys' = case break (HashSet.member k1) (before0 ++ after0) of+             (kHead, keys') = case break (HashSet.member k1) (before0 ++ after0) of                  (before1, []) ->-                    HashSet.insert k1 keys0 : before1+                    (HashSet.insert k1 keys0, before1)                  (before1, keys1 : after1)->-                    HashSet.union keys0 keys1 : before1 ++ after1+                    (HashSet.union keys0 keys1, before1 ++ after1)           in sm               { toHashMap =-                  HashSet.foldl' (\h' k' -> HashMap.insert k' v1 h') h (head keys')-              , keyPartitions = keys'+                  HashSet.foldl' (\h' k' -> HashMap.insert k' v1 h') h kHead+              , keyPartitions = kHead : keys'               } mergeKeysWith _ _ _ sm = sm
tests/tasty/ShareMapTests.hs view
@@ -1,9 +1,14 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-}  module ShareMapTests where  import Data.HashMap.Lazy (HashMap)+#if MIN_VERSION_base(4,20,0)+import Data.List (nub)+#else import Data.List (foldl', nub)+#endif import qualified Data.ShareMap as ShareMap import qualified ShareMapReference as Reference import Test.Tasty
tests/test.hs view
@@ -10,7 +10,7 @@ import Control.Monad (when) import qualified Control.Monad.State    as State import Control.Monad.Trans.Class (lift)-+import Data.List (isSuffixOf) import Prelude hiding (log) import Data.Maybe (fromMaybe) import Data.Monoid (Sum(..))@@ -76,15 +76,22 @@     , testGroup "elim-crash" <$> dirTests elimCmd   "tests/crash"  []             (ExitFailure 1)     , testGroup "proof"      <$> dirTests elimCmd   "tests/proof"     []          ExitSuccess     , testGroup "rankN"      <$> dirTests elimCmd   "tests/rankNTypes" []         ExitSuccess-    , testGroup "horn-pos-el" <$> dirTests elimCmd   "tests/horn/pos"  []          ExitSuccess-    , testGroup "horn-neg-el" <$> dirTests elimCmd   "tests/horn/neg"  []          (ExitFailure 1)-    , testGroup "horn-pos-na" <$> dirTests nativeCmd "tests/horn/pos"  []          ExitSuccess-    , testGroup "horn-neg-na" <$> dirTests nativeCmd "tests/horn/neg"  []          (ExitFailure 1)--    -- , testGroup "todo"       <$> dirTests elimCmd   "tests/todo"   []            (ExitFailure 1)-    -- , testGroup "todo-crash" <$> dirTests elimCmd   "tests/todo-crash" []        (ExitFailure 2)+    , testGroup "horn-pos-el"      <$> dirTests elimSaveCmd   "tests/horn/pos"  []          ExitSuccess+    , testGroup "horn-neg-el"      <$> dirTests elimSaveCmd   "tests/horn/neg"  []          (ExitFailure 1)+    , testGroup "horn-json-pos-el" <$> dirJsonTests elimCmd   "tests/horn/pos/.liquid"  []  ExitSuccess+    , testGroup "horn-json-neg-el" <$> dirJsonTests elimCmd   "tests/horn/neg/.liquid"  []  (ExitFailure 1)+    , testGroup "horn-smt2-pos-el" <$> dirHornTests elimCmd  "tests/horn/pos/.liquid"  []  ExitSuccess+    , testGroup "horn-smt2-neg-el" <$> dirHornTests elimCmd  "tests/horn/neg/.liquid"  []  (ExitFailure 1)+    , testGroup "horn-pos-na"      <$> dirTests nativeCmd     "tests/horn/pos"  []          ExitSuccess+    , testGroup "horn-neg-na"      <$> dirTests nativeCmd     "tests/horn/neg"  []          (ExitFailure 1)    ]+   where+    dirTests     = dirTests' isTest+    dirJsonTests = dirTests' ("horn.json" `isSuffixOf`)+    dirHornTests = dirTests' ("horn.smt2" `isSuffixOf`) +isTest   :: FilePath -> Bool+isTest f = takeExtension f `elem` [".fq", ".smt2"]  skipNativePos :: [FilePath] skipNativePos = ["NonLinear-pack.fq"]@@ -112,16 +119,15 @@       )  ----------------------------------------------------------------------------dirTests :: TestCmd -> FilePath -> [FilePath] -> ExitCode -> IO [TestTree]+dirTests' :: (FilePath -> Bool) -> TestCmd -> FilePath -> [FilePath] -> ExitCode -> IO [TestTree] ----------------------------------------------------------------------------dirTests testCmd root ignored code = do+dirTests' isT testCmd root ignored code = do   files    <- walkDirectory root-  let tests = [ rel | f <- files, isTest f, let rel = makeRelative root f, rel `notElem` ignored ]+  let tests = [ rel | f <- files, isT f, let rel = makeRelative root f, rel `notElem` ignored ]   return    $ mkTest testCmd code root <$> tests -isTest   :: FilePath -> Bool-isTest f = takeExtension f `elem` [".fq", ".smt2"] + --------------------------------------------------------------------------- mkTest :: TestCmd -> ExitCode -> FilePath -> FilePath -> TestTree ---------------------------------------------------------------------------@@ -160,6 +166,11 @@ elimCmd (LO opts) bin dir file =   printf "cd %s && %s --eliminate=some %s %s" dir bin opts file +elimSaveCmd :: TestCmd+elimSaveCmd (LO opts) bin dir file =+  printf "cd %s && %s --save --eliminate=some %s %s" dir bin opts file++ ---------------------------------------------------------------------------------------- -- Generic Helpers ----------------------------------------------------------------------------------------@@ -174,7 +185,7 @@   = do (ds,fs) <- partitionM doesDirectoryExist . candidates =<< (getDirectoryContents root `catchIOError` const (return []))        (fs++) <$> concatMapM walkDirectory ds   where-    candidates fs = [root </> f | f <- fs, not (isExtSeparator (head f))]+    candidates fs = [root </> f | f@(c:_) <- fs, not (isExtSeparator c)]  partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a],[a]) partitionM f = go [] []@@ -223,7 +234,7 @@         Const summary <$ State.modify (+ 1)      runGroup _ group' children = Traversal $ Functor.Compose $ do-      Const soFar <- Functor.getCompose $ getTraversal children+      Const soFar <- Functor.getCompose $ getTraversal $ mconcat children       pure $ Const $ map (\(n,t,s) -> (group' </> n,t,s)) soFar      computeFailures :: StatusMap -> IO Int