packages feed

liquid-fixpoint 0.7.0.5 → 0.7.0.6

raw patch · 29 files changed

+689/−421 lines, 29 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Language.Fixpoint.Types.Constraints: getEqBody :: Equation -> Maybe Expr
+ Language.Fixpoint.Misc: (<<=) :: Monad m => (b -> m a) -> m b -> m b
+ Language.Fixpoint.Misc: (=>>) :: Monad m => m b -> (b -> m a) -> m b
+ Language.Fixpoint.Smt.Theories: mapCup :: Symbol
+ Language.Fixpoint.Smt.Theories: mapDef :: Symbol
+ Language.Fixpoint.Solver: simplifyFInfo :: (NFData a, Fixpoint a, Show a, Loc a) => Config -> FInfo a -> IO (SInfo a)
+ Language.Fixpoint.Solver.Solve: solverInfo :: Config -> SInfo a -> SolverInfo a b
+ Language.Fixpoint.SortCheck: exprSort_maybe :: Expr -> Maybe Sort
+ Language.Fixpoint.SortCheck: instance GHC.Base.Monoid Language.Fixpoint.SortCheck.TVSubst
+ Language.Fixpoint.Types.Constraints: [eqRec] :: Equation -> !Bool
+ Language.Fixpoint.Types.Constraints: [eqSort] :: Equation -> !Sort
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.PrettyPrint.PPrint Language.Fixpoint.Types.Constraints.AxiomEnv
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.PrettyPrint.PPrint Language.Fixpoint.Types.Constraints.Rewrite
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.Refinements.HasGradual (Language.Fixpoint.Types.Constraints.GInfo c a)
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.Refinements.HasGradual (Language.Fixpoint.Types.Constraints.WfC a)
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.Refinements.Subable Language.Fixpoint.Types.Constraints.Equation
+ Language.Fixpoint.Types.Constraints: isSafe :: Result a -> Bool
+ Language.Fixpoint.Types.Constraints: mkEquation :: Symbol -> [(Symbol, Sort)] -> Expr -> Sort -> Equation
+ Language.Fixpoint.Types.Refinements: ECoerc :: !Sort -> !Sort -> !Expr -> Expr
+ Language.Fixpoint.Types.Spans: panicSpan :: String -> SrcSpan
+ Language.Fixpoint.Types.Spans: toSourcePos :: (SourceName, Line, Column) -> SourcePos
- Language.Fixpoint.Parse: class Inputable a where rr' _ = rr rr = rr' ""
+ Language.Fixpoint.Parse: class Inputable a
- Language.Fixpoint.Solver.GradualSolution: init :: (Fixpoint a) => SInfo a -> [(KVar, (GWInfo, [Expr]))]
+ Language.Fixpoint.Solver.GradualSolution: init :: (Fixpoint a) => Config -> SInfo a -> [(KVar, (GWInfo, [Expr]))]
- Language.Fixpoint.Types.Constraints: Equ :: Symbol -> [Symbol] -> Expr -> Equation
+ Language.Fixpoint.Types.Constraints: Equ :: !Symbol -> [(Symbol, Sort)] -> !Expr -> !Sort -> !Bool -> Equation
- Language.Fixpoint.Types.Constraints: [eqArgs] :: Equation -> [Symbol]
+ Language.Fixpoint.Types.Constraints: [eqArgs] :: Equation -> [(Symbol, Sort)]
- Language.Fixpoint.Types.Constraints: [eqBody] :: Equation -> Expr
+ Language.Fixpoint.Types.Constraints: [eqBody] :: Equation -> !Expr
- Language.Fixpoint.Types.Constraints: [eqName] :: Equation -> Symbol
+ Language.Fixpoint.Types.Constraints: [eqName] :: Equation -> !Symbol
- Language.Fixpoint.Types.PrettyPrint: class Fixpoint a where simplify = id
+ Language.Fixpoint.Types.PrettyPrint: class Fixpoint a
- Language.Fixpoint.Types.PrettyPrint: class PPrint a where pprintTidy = pprintPrec 0 pprintPrec _ = pprintTidy
+ Language.Fixpoint.Types.PrettyPrint: class PPrint a
- Language.Fixpoint.Types.Refinements: class (Monoid r, Subable r) => Reftable r where top _ = mempty meet = mappend
+ Language.Fixpoint.Types.Refinements: class (Monoid r, Subable r) => Reftable r
- Language.Fixpoint.Types.Refinements: class Subable a where subst1 y (x, e) = subst (Su $ fromList [(x, e)]) y
+ Language.Fixpoint.Types.Refinements: class Subable a
- Language.Fixpoint.Types.Sorts: type TCEmb a = HashMap a FTycon
+ Language.Fixpoint.Types.Sorts: type TCEmb a = HashMap a Sort
- Language.Fixpoint.Types.Visitor: visit :: (Visitable t, Monoid a) => Visitor a c -> c -> t -> VisitM a t
+ Language.Fixpoint.Types.Visitor: visit :: (Visitable t, (Monoid a)) => Visitor a c -> c -> t -> VisitM a t

Files

liquid-fixpoint.cabal view
@@ -1,5 +1,5 @@ name:                liquid-fixpoint-version:             0.7.0.5+version:             0.7.0.6 Copyright:           2010-17 Ranjit Jhala, University of California, San Diego. synopsis:            Predicate Abstraction-based Horn-Clause/Implication Constraint Solver homepage:            https://github.com/ucsd-progsys/liquid-fixpoint
src/Language/Fixpoint/Minimize.hs view
@@ -13,7 +13,6 @@ import           Control.Monad                      (filterM) import           Language.Fixpoint.Types.Visitor    (mapKVars) import           Language.Fixpoint.Types.Config     (Config (..), queryFile)-import           Language.Fixpoint.Types.Errors import           Language.Fixpoint.Misc             (safeHead) import           Language.Fixpoint.Utils.Files      hiding (Result) import           Language.Fixpoint.Graph@@ -116,10 +115,6 @@ --------------------------------------------------------------------------- -- Helper functions ----------------------------------------------------------------------------isSafe :: Result a -> Bool-isSafe (Result Safe _ _) = True-isSafe _                 = False- addExt :: Ext -> Config -> Config addExt ext cfg = cfg { srcFile = queryFile ext cfg } 
src/Language/Fixpoint/Misc.hs view
@@ -399,6 +399,11 @@ powerset :: [a] -> [[a]] powerset xs = filterM (const [False, True]) xs +(=>>) :: Monad m => m b -> (b -> m a) -> m b+(=>>) m f = m >>= (\x -> f x >> return x)++(<<=) :: Monad m => (b -> m a) -> m b -> m b+(<<=) = flip (=>>)  (<$$>) ::  (Monad m) => (a -> m b) -> [a] -> m [b] _ <$$> []           = return []
src/Language/Fixpoint/Parse.hs view
@@ -158,6 +158,7 @@    -- reserved words used in liquid haskell   , "forall"+  , "coerce"   , "exists"   , "module"   , "spec"@@ -195,6 +196,7 @@   , "type"   , "using"   , "with"+  , "in"   ]  reservedOpNames :: [String]@@ -351,6 +353,7 @@   =  trueP  <|> falseP  <|> (fastIfP EIte exprP)+ <|> (coerceP exprP)  <|> (ESym <$> symconstP)  <|> (ECon <$> constantP)  <|> (reservedOp "_|_" >> return EBot)@@ -383,6 +386,15 @@        b2 <- bodyP        return $ f p b1 b2 +coerceP :: Parser Expr -> Parser Expr+coerceP p = do+  reserved "coerce"+  (s, t) <- parens (pairP sortP (reservedOp "~") sortP)+  e      <- p+  return $ ECoerc s t e+++ {- qmIfP f bodyP   = parens $ do@@ -694,13 +706,14 @@ qualifierP tP = do   pos    <- getPosition   n      <- upperIdP-  params <- parens $ sepBy1 (sortBindP tP) comma+  params <- parens $ sepBy1 (symBindP tP) comma   _      <- colon   body   <- predP   return  $ mkQual n params body pos-  where-    sortBindP = pairP symbolP colon +symBindP :: Parser a -> Parser (Symbol, a)+symBindP = pairP symbolP colon+ pairP :: Parser a -> Parser z -> Parser b -> Parser (a, b) pairP xP sepP yP = (,) <$> xP <* sepP <*> yP @@ -714,7 +727,12 @@ ---------------------------------------------------------------------  defineP :: Parser Equation-defineP = Equ <$> symbolP <*> many symbolP <*> (reserved "=" >> exprP)+defineP = do+  name   <- symbolP+  params <- parens        $ sepBy (symBindP sortP) comma+  sort   <- colon        *> sortP+  body   <- reserved "=" *> predP+  return  $ mkEquation name params body sort  matchP :: Parser Rewrite matchP = SMeasure <$> symbolP <*> symbolP <*> many symbolP <*> (reserved "=" >> exprP)
src/Language/Fixpoint/Smt/Interface.hs view
@@ -80,6 +80,7 @@ import           Data.Char import qualified Data.HashMap.Strict      as M import           Data.Monoid+import           Data.Maybe                  (fromMaybe) import qualified Data.Text                as T import           Data.Text.Format import qualified Data.Text.IO             as TIO@@ -442,9 +443,15 @@     thyXTs     =                    filter (isKind 1) xts     qryXTs     = Misc.mapSnd tx <$> filter (isKind 2) xts     isKind n   = (n ==)  . symKind env . fst-    xts        = F.toListSEnv           (F.seSort env)+    xts        = symbolSorts (F.seSort env) -- F.toListSEnv           (F.seSort env)     tx         = elaborate    "declare" env     ats        = funcSortVars env++symbolSorts :: F.SEnv F.Sort -> [(F.Symbol, F.Sort)]+symbolSorts env = [(x, tx t) | (x, t) <- F.toListSEnv env ]+ where+  tx t@(FObj a) = fromMaybe t (F.lookupSEnv a env)+  tx t          = t  dataDeclarations :: SymEnv -> [DataDecl] dataDeclarations = -- (if True then orderDeclarations else id) .
src/Language/Fixpoint/Smt/Serialize.hs view
@@ -139,6 +139,7 @@   smt2 env (PAll   bs p)    = build "(forall ({}) {})"  (smt2s env bs, smt2 env p)   smt2 env (PAtom r e1 e2)  = mkRel env r e1 e2   smt2 env (ELam b e)       = smt2Lam env b e+  smt2 env (ECoerc _ _ e)   = smt2 env e   smt2 _   e                = panic ("smtlib2 Pred  " ++ show e)  -- | smt2Cast uses the 'as x T' pattern needed for polymorphic ADT constructors
src/Language/Fixpoint/Smt/Theories.hs view
@@ -13,6 +13,7 @@         -- * Convert theory symbols      , smt2Symbol+        -- * Preamble to initialize SMT      , preamble @@ -27,7 +28,7 @@         -- * Theories      , setEmpty, setEmp, setCap, setSub, setAdd, setMem-     , setCom, setCup, setDif, setSng, mapSel, mapSto+     , setCom, setCup, setDif, setSng, mapSel, mapCup, mapSto, mapDef        -- * Query Theories      , isSmt2App@@ -49,16 +50,23 @@ import qualified Data.Text import           Data.String                 (IsString(..)) ------------------------------------------------------------------------------ | Set Theory ------------------------------------------------------------------------------------------------------------------------------------- +{- | [NOTE:Adding-Theories] To add new (SMTLIB supported) theories to+     liquid-fixpoint and upstream, grep for "Map_default" and then add+     your corresponding symbol in all those places.+     This is currently far more complicated than it needs to be.+ -}++--------------------------------------------------------------------------------+-- | Theory Symbols ------------------------------------------------------------+--------------------------------------------------------------------------------+ elt, set, map :: Raw elt  = "Elt" set  = "Set" map  = "Map" -emp, add, cup, cap, mem, dif, sub, com, sel, sto :: Raw+emp, add, cup, cap, mem, dif, sub, com, sel, sto, mcup, mdef :: Raw emp   = "smt_set_emp" add   = "smt_set_add" cup   = "smt_set_cup"@@ -69,8 +77,11 @@ com   = "smt_set_com" sel   = "smt_map_sel" sto   = "smt_map_sto"+mcup  = "smt_map_cup"+mdef  = "smt_map_def" -setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup, setDif, setSng, mapSel, mapSto :: Symbol++setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup, setDif, setSng :: Symbol setEmpty = "Set_empty" setEmp   = "Set_emp" setCap   = "Set_cap"@@ -81,9 +92,12 @@ setCup   = "Set_cup" setDif   = "Set_dif" setSng   = "Set_sng"++mapSel, mapSto, mapCup, mapDef :: Symbol mapSel   = "Map_select" mapSto   = "Map_store"-+mapCup   = "Map_union"+mapDef   = "Map_default"  strLen, strSubstr, strConcat :: (IsString a) => a -- Symbol strLen    = "strLen"@@ -132,6 +146,10 @@         (sel, map, elt, elt)     , format "(define-fun {} ((m {}) (k {}) (v {})) {} (store m k v))"         (sto, map, elt, elt, map)+    , format "(define-fun {} ((m1 {}) (m2 {})) {} ((_ map (+ ({} {}) {})) m1 m2))"+        (mcup, map, map, map, elt, elt, elt)+    , format "(define-fun {} ((v {})) {} ((as const ({})) v))"+        (mdef, elt, map, map)     , format "(define-fun {} ((b Bool)) Int (ite b 1 0))"         (Only (boolToIntName :: T.Text))     , uifDef u (symbolText mulFuncName) ("*"   :: T.Text)@@ -254,10 +272,6 @@  smt2App _ _ _ _    = Nothing --- smt2App env (EVar f) (d:ds)---  | Just s <- {- tracepp ("SYMENVTHEORY: " ++ showpp f) $ -} symEnvTheory f env---  = Just $ build "({} {})" (tsRaw s, d <> mconcat [ " " <> d | d <- ds])- smt2AppArg :: VarAs -> SymEnv -> Expr -> Maybe Builder.Builder smt2AppArg k env (ECst (EVar f) t)   | Just fThy <- symEnvTheory f env@@ -265,10 +279,6 @@             then (k env f (ffuncOut t))             else (build "{}" (Only (tsRaw fThy))) --- // smt2AppArg _ env (EVar f)--- // | Just fThy <- symEnvTheory f env--- //  = Just (build "{}" (Only (tsRaw fThy)))- smt2AppArg _ _ _   = Nothing @@ -308,8 +318,6 @@ --   to avoid duplicate SMT definitions.  `uninterpSEnv` is for uninterpreted --   symbols, and `interpSEnv` is for interpreted symbols. ----------------------------------------------------------------------------------- theorySEnv :: SEnv Sort--- theorySEnv = fromListSEnv . M.toList . fmap tsSort $ theorySymbols  -- | `theorySymbols` contains the list of ALL SMT symbols with interpretations, --   i.e. which are given via `define-fun` (as opposed to `declare-fun`)@@ -333,6 +341,8 @@   , interpSym setCom   com   setCmpSort   , interpSym mapSel   sel   mapSelSort   , interpSym mapSto   sto   mapStoSort+  , interpSym mapCup   mcup  mapCupSort+  , interpSym mapDef   mdef  mapDefSort   , interpSym bvOrName "bvor"   bvBopSort   , interpSym bvAndName "bvand" bvBopSort   , interpSym strLen    strLen    strLenSort@@ -345,62 +355,26 @@     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-    mapSelSort = FAbs 0 $ FAbs 1 $ FFunc (mapSort (FVar 0) (FVar 1)) $ FFunc (FVar 0) (FVar 1)+    mapSelSort = FAbs 0 $ FAbs 1 $ FFunc (mapSort (FVar 0) (FVar 1))+                                 $ FFunc (FVar 0) (FVar 1)+    mapCupSort = FAbs 0          $ FFunc (mapSort (FVar 0) intSort)+                                 $ FFunc (mapSort (FVar 0) intSort)+                                         (mapSort (FVar 0) intSort)     mapStoSort = FAbs 0 $ FAbs 1 $ FFunc (mapSort (FVar 0) (FVar 1))                                  $ FFunc (FVar 0)                                  $ FFunc (FVar 1)                                          (mapSort (FVar 0) (FVar 1))+    mapDefSort = FAbs 0 $ FAbs 1 $ FFunc (FVar 1)+                                         (mapSort (FVar 0) (FVar 1))+     bvBopSort  = FFunc bitVecSort $ FFunc bitVecSort bitVecSort   interpSym :: Symbol -> Raw -> Sort -> (Symbol, TheorySymbol) interpSym x n t = (x, Thy x n t Theory) --- SHIFTLAM _uninterpSymbols :: [(Symbol, TheorySymbol)]--- SHIFTLAM _uninterpSymbols = [ (x, uninterpSym x t) | (x, t) <- _uninterpSymbols']--- SHIFTLAM--- SHIFTLAM ----------------------------------------------------------------------------------- SHIFTLAM _uninterpSym :: Symbol -> Sort -> TheorySymbol--- SHIFTLAM ----------------------------------------------------------------------------------- SHIFTLAM _uninterpSym x t =  Thy x (symbolRaw x) t Uninterp--- SHIFTLAM--- SHIFTLAM _uninterpSymbols' :: [(Symbol, Sort)]--- SHIFTLAM _uninterpSymbols' = [] -- [ (toIntName,  mkFFunc 1 [FVar 0, FInt]) ]--  -- SHIFTLAM  [ (setToIntName,    FFunc (setSort intSort)   intSort)-  -- SHIFTLAM  , (bitVecToIntName, FFunc bitVecSort intSort)-  -- SHIFTLAM  , (mapToIntName,    FFunc (mapSort intSort intSort) intSort)-  -- SHIFTLAM  , (realToIntName,   FFunc realSort   intSort)-  -- SHIFTLAM  , (lambdaName   ,   FFunc intSort (FFunc intSort intSort))-  -- SHIFTLAM  ]-  -- SHIFTLAM  ++ concatMap makeApplies [1..maxLamArg]-  -- SHIFTLAM  ++ [(lamArgSymbol i, s) | i <- [1..maxLamArg], s <- sorts]--- SHIFTLAM--- SHIFTLAM  -- THESE ARE DUPLICATED IN DEFUNCTIONALIZATION- maxLamArg :: Int maxLamArg = 7---- SHIFTLAM sorts :: [Sort]--- SHIFTLAM sorts = [intSort]---- NIKI TODO: allow non integer lambda arguments--- sorts = [setSort intSort, bitVecSort intSort, mapSort intSort intSort, boolSort, realSort, intSort]--- makeLamArg :: Sort -> Int  -> Symbol--- makeLamArg _ = intArgName---- SHIFTLAM makeApplies :: Int -> [(Symbol, Sort)]--- SHIFTLAM makeApplies i =-  -- SHIFTLAM [ (intApplyName i,    go i intSort)-  -- SHIFTLAM , (setApplyName i,    go i (setSort intSort))-  -- SHIFTLAM , (bitVecApplyName i, go i bitVecSort)-  -- SHIFTLAM , (mapApplyName i,    go i $ mapSort intSort intSort)-  -- SHIFTLAM , (realApplyName i,   go i realSort)-  -- SHIFTLAM , (boolApplyName i,   go i boolSort)-  -- SHIFTLAM ]-  -- SHIFTLAM where-    -- SHIFTLAM go 0 s = FFunc intSort s-    -- SHIFTLAM go i s = FFunc intSort $ go (i-1) s  axiomLiterals :: [(Symbol, Sort)] -> [Expr] axiomLiterals lts = catMaybes [ lenAxiom l <$> litLen l | (l, t) <- lts, isString t ]
src/Language/Fixpoint/Solver.hs view
@@ -16,15 +16,19 @@      -- * Parse Qualifiers from File   , parseFInfo++    -- * Simplified Info+  , simplifyFInfo ) where  import           Control.Concurrent import           Data.Binary import           System.Exit                        (ExitCode (..))-import           System.Console.CmdArgs.Verbosity   (whenNormal)+import           System.Console.CmdArgs.Verbosity   (whenNormal, whenLoud) import           Text.PrettyPrint.HughesPJ          (render) import           Control.Monad                      (when) import           Control.Exception                  (catch)+ import           Language.Fixpoint.Solver.Sanitize  (symbolEnv, sanitize) import           Language.Fixpoint.Solver.UniqifyBinds (renameAll) import           Language.Fixpoint.Defunctionalize (defunctionalize)@@ -174,7 +178,9 @@   where     msg           = "fq file after Uniqify & Rename " ++ show i ++ "\n" -solveNative' !cfg !fi0 = do+simplifyFInfo :: (NFData a, Fixpoint a, Show a, Loc a)+               => Config -> FInfo a -> IO (SInfo a)+simplifyFInfo !cfg !fi0 = do   -- writeLoud $ "fq file in: \n" ++ render (toFixpoint cfg fi)   -- rnf fi0 `seq` donePhase Loud "Read Constraints"   -- let qs   = quals fi0@@ -190,17 +196,19 @@   graphStatistics cfg si1   let si2  = {-# SCC "wfcUniqify" #-} wfcUniqify $!! si1   let si3  = {-# SCC "renameAll"  #-} renameAll  $!! si2-  rnf si3 `seq` donePhase Loud "Uniqify & Rename"+  rnf si3 `seq` whenLoud $ donePhase Loud "Uniqify & Rename"   loudDump 1 cfg si3   let si4  = {-# SCC "defunction" #-} defunctionalize cfg $!! si3+  -- putStrLn $ "AXIOMS: " ++ showpp (asserts si4)   loudDump 2 cfg si4-  rnf si4 `seq` donePhase Loud "Defunctionalize"   let si5  = {-# SCC "elaborate"  #-} elaborate "solver" (symbolEnv cfg si4) si4   loudDump 3 cfg si5-  rnf si5 `seq` donePhase Loud "Elaborate"-  si6 <- {-# SCC "Sol.inst"  #-} instantiate cfg $!! si5-  rnf si6 `seq` donePhase Loud "Instantiate"+  instantiate cfg $!! si5++solveNative' !cfg !fi0 = do+  si6 <- simplifyFInfo cfg fi0   res <- {-# SCC "Sol.solve" #-} Sol.solve cfg $!! si6+  -- rnf soln `seq` donePhase Loud "Solve2"   --let stat = resStatus res   saveSolution cfg res   -- when (save cfg) $ saveSolution cfg
src/Language/Fixpoint/Solver/GradualSolution.hs view
@@ -11,6 +11,7 @@ import qualified Data.List                      as L import           Data.Maybe                     (maybeToList, isNothing) import           Data.Monoid                    ((<>))+import           Language.Fixpoint.Types.Config import           Language.Fixpoint.Types.PrettyPrint () import qualified Language.Fixpoint.SortCheck          as So import           Language.Fixpoint.Misc@@ -18,20 +19,26 @@ import qualified Language.Fixpoint.Types.Solutions    as Sol import           Language.Fixpoint.Types.Constraints  hiding (ws, bs) import           Prelude                              hiding (init, lookup)-+import           Language.Fixpoint.Solver.Sanitize  (symbolEnv)+import Language.Fixpoint.SortCheck  -------------------------------------------------------------------------------- -- | Initial Gradual Solution (from Qualifiers and WF constraints) ------------- ---------------------------------------------------------------------------------init :: (F.Fixpoint a) => F.SInfo a -> [(F.KVar, (F.GWInfo, [F.Expr]))]+init :: (F.Fixpoint a) => Config -> F.SInfo a -> [(F.KVar, (F.GWInfo, [F.Expr]))] ---------------------------------------------------------------------------------init si = map (refineG si qs genv) gs `using` parList rdeepseq +init cfg si = map (elab . refineG si qs genv) gs `using` parList rdeepseq    where     qs         = F.quals si     gs         = snd <$> gs0     genv       = instConstants si      gs0        = L.filter (isGWfc . snd) $ M.toList (F.ws si)++    elab (k,(x,es)) = ((k,) . (x,)) $ (elaborate "init" (sEnv (gsym x) (gsort x)) <$> es)+    +    sEnv x s    = isEnv {F.seSort = F.insertSEnv x s (F.seSort isEnv)}+    isEnv       = symbolEnv cfg si   --------------------------------------------------------------------------------
src/Language/Fixpoint/Solver/Instantiate.hs view
@@ -19,6 +19,7 @@ import           Language.Fixpoint.Types.Config  as FC import qualified Language.Fixpoint.Types.Visitor as Vis import qualified Language.Fixpoint.Misc          as Misc -- (mapFst)+import           Language.Fixpoint.Misc          ((<<=)) import qualified Language.Fixpoint.Smt.Interface as SMT import           Language.Fixpoint.Defunctionalize import           Language.Fixpoint.SortCheck@@ -31,15 +32,14 @@ import qualified Data.Text            as T import qualified Data.HashMap.Strict  as M import qualified Data.List            as L-import           Data.Maybe           (catMaybes, fromMaybe)+import           Data.Maybe           (isNothing, catMaybes, fromMaybe) import           Data.Char            (isUpper)--- import           Data.Foldable        (foldlM)+-- import           Text.Printf (printf)  (~>) :: (Expr, String) -> Expr -> EvalST Expr (_e,_str) ~> e' = do-    modify (\st -> st{evId = evId st + 1})-    -- traceM $ showpp _str ++ " : " ++ showpp _e ++ showpp e'-    return (η e')+    modify (\st -> st {evId = evId st + 1})+    return (wtf e')   --------------------------------------------------------------------------------@@ -54,10 +54,11 @@ instantiate' cfg fi = sInfo cfg fi env <$> withCtx cfg file env act   where     act ctx         = forM cstrs $ \(i, c) ->-                        (i,) . notracepp ("INSTANTIATE i = " ++ show i) <$> instSimpC cfg ctx (bs fi) (ae fi) i c+                        (i,) . notracepp ("INSTANTIATE i = " ++ show i) <$> instSimpC cfg ctx (bs fi) aenv i c     cstrs           = M.toList (cm fi)     file            = srcFile cfg ++ ".evals"     env             = symbolEnv cfg fi+    aenv            = {- tracepp "AXIOM-ENV" -} (ae fi)  sInfo :: Config -> GInfo SimpC a -> SymEnv -> [(SubcId, Expr)] -> SInfo a sInfo cfg fi env ips = strengthenHyp fi' (notracepp "ELAB-INST:  " $ zip is ps'')@@ -115,12 +116,8 @@ -------------------------------------------------------------------------------- -- | Knowledge (SMT Interaction) ----------------------------------------------------------------------------------- AT:@TODO: knSels and knEqs should really just be the same thing. In this way,--- we should also unify knSims and knAms, as well as their analogues in AxiomEnv data Knowledge-  = KN { knSels    :: ![(Expr, Expr)]-       , knEqs     :: ![(Expr, Expr)]-       , knSims    :: ![Rewrite]+  = KN { knSims    :: ![Rewrite]        , knAms     :: ![Equation]        , knContext :: IO SMT.Context        , knPreds   :: !([(Symbol, Sort)] -> Expr -> SMT.Context -> IO Bool)@@ -128,17 +125,7 @@        }  emptyKnowledge :: IO SMT.Context -> Knowledge-emptyKnowledge ctx = KN [] [] [] [] ctx (\_ _ _ -> return False) []--lookupKnowledge :: Knowledge -> Expr -> Maybe Expr-lookupKnowledge γ e-  -- Zero argument axioms like `mempty = N`-  | Just e' <- L.lookup e (knEqs γ)-  = Just e'-  | Just e' <- L.lookup e (knSels γ)-  = Just e'-  | otherwise-  = Nothing+emptyKnowledge ctx = KN [] [] ctx (\_ _ _ -> return False) []  isValid :: Knowledge -> Expr -> IO Bool isValid γ b = knPreds γ (knLams γ) b =<< knContext γ@@ -147,9 +134,7 @@                  -> [(Symbol, SortedReft)]                  -> ([(Expr, Expr)], Knowledge) makeKnowledge cfg ctx aenv es = (simpleEqs,) $ (emptyKnowledge context)-                                     { knSels   = sels-                                     , knEqs    = eqs-                                     , knSims   = aenvSimpl aenv+                                     { knSims   = aenvSimpl aenv                                      , knAms    = aenvEqs aenv                                      , knPreds  = \bs e c -> askSMT c bs e                                      }@@ -165,28 +150,13 @@                               ))       return ctx -    -- This creates the rewrite rule e1 -> e2-    -- when should I apply it?+    -- This creates the rewrite rule e1 -> e2. When should I apply it?     -- 1. when e2 is a data con and can lead to further reductions     -- 2. when size e2 < size e1-    -- @TODO: Can this be generalized?-    -- simpleEqs = []-    simpleEqs = {- tracepp "SIMPLEEQS" $ -} _makeSimplifications (aenvSimpl aenv) =<<-               L.nub (catMaybes [_getDCEquality e1 e2 | PAtom Eq e1 e2 <- atms])+    simpleEqs = {- tracepp "SIMPLEEQS" $ -} makeSimplifications (aenvSimpl aenv) =<<+               L.nub (catMaybes [_getDCEquality senv e1 e2 | PAtom Eq e1 e2 <- atms])     atms = splitPAnd =<< (expr <$> filter isProof es)     isProof (_, RR s _) = showpp s == "Tuple"-    sels = (go . expr) =<< es-    go e = let es   = splitPAnd e-               su   = mkSubst [(x, EVar y)  | PAtom Eq (EVar x) (EVar y) <- es ]-               sels = [(EApp (EVar s) x, e) | PAtom Eq (EApp (EVar s) x) e <- es-                                            , isSelector s ]-           in L.nub (sels ++ subst su sels)--    eqs = [(EVar x, ex) | Equ a _ bd <- filter (null . eqArgs) $ aenvEqs aenv-                        , PAtom Eq (EVar x) ex <- splitPAnd bd-                        , x == a-                        ]-     toSMT bs = defuncAny cfg senv . elaborate "makeKnowledge" (elabEnv bs)     elabEnv  = L.foldl' (\env (x, s) -> insertSymEnv x s env) senv @@ -195,7 +165,7 @@     askSMT :: SMT.Context -> [(Symbol, Sort)] -> Expr -> IO Bool     askSMT ctx bs e       | isTautoPred  e = return True-      | isContraPred e = return False+    -- // Why?  | isContraPred e = return False -- Why the f?       | null (Vis.kvars e) = do           SMT.smtPush ctx           b <- SMT.checkValid' ctx [] PTrue (toSMT bs e)@@ -203,13 +173,9 @@           return b       | otherwise      = return False -    -- TODO: Stringy hacks-    isSelector :: Symbol -> Bool-    isSelector  = L.isPrefixOf "select" . symbolString--_makeSimplifications :: [Rewrite] -> (Symbol, [Expr], Expr) -> [(Expr, Expr)]-_makeSimplifications sis (dc, es, e)- = go =<< sis+makeSimplifications :: [Rewrite] -> (Symbol, [Expr], Expr) -> [(Expr, Expr)]+makeSimplifications sis (dc, es, e)+     = go =<< sis  where    go (SMeasure f dc' xs bd)      | dc == dc', length xs == length es@@ -217,8 +183,8 @@    go _      = [] -_getDCEquality :: Expr -> Expr -> Maybe (Symbol, [Expr], Expr)-_getDCEquality e1 e2+_getDCEquality :: SymEnv -> Expr -> Expr -> Maybe (Symbol, [Expr], Expr)+_getDCEquality senv e1 e2     | Just dc1 <- f1     , Just dc2 <- f2     = if dc1 == dc2@@ -231,19 +197,23 @@     | otherwise     = Nothing   where-    (f1, es1) = Misc.mapFst getDC $ splitEApp e1-    (f2, es2) = Misc.mapFst getDC $ splitEApp e2+    (f1, es1) = Misc.mapFst (getDC senv) (splitEApp e1)+    (f2, es2) = Misc.mapFst (getDC senv) (splitEApp e2) -    -- TODO: Stringy hacks-    getDC (EVar x)-      = if isUpper $ head $ symbolString $ dropModuleNames x-          then Just x-          else Nothing-    getDC _-      = Nothing+-- TODO: Stringy hacks+getDC :: SymEnv -> Expr -> Maybe Symbol+getDC senv (EVar x)+  | isUpperSymbol x && isNothing (symEnvTheory x senv)+  = Just x+getDC _ _+  = Nothing -    dropModuleNames = mungeNames (symbol . last) "."+isUpperSymbol :: Symbol -> Bool+isUpperSymbol = isUpper . headSym . dropModuleNames +dropModuleNames :: Symbol -> Symbol+dropModuleNames = mungeNames (symbol . last) "."+  where     mungeNames _ _ ""  = ""     mungeNames f d s'@(symbolText -> s)       | s' == tupConName = tupConName@@ -260,20 +230,58 @@ -------------------------------------------------------------------------------- -- AT@TODO do this for all reflected functions, not just DataCons --- Insert measure info for every constructor--- that appears in the expression e--- required by PMEquivalence.mconcatChunk--- ADTs does this automatically+{- [NOTE:Datacon-Selectors] The 'assertSelectors' function+   insert measure information for every constructor that appears+   in the expression e.++   In theory, this is not required as the SMT ADT encoding takes+   care of it. However, in practice, some constructors, e.g. from+   GADTs cannot be directly encoded in SMT due to the lack of SMTLIB+   support for GADT. Hence, we still need to hang onto this code.++   See tests/proof/ple2.fq for a concrete example.+ -}+ assertSelectors :: Knowledge -> Expr -> EvalST ()-assertSelectors _ _ = return ()+-- assertSelectors _ _ = return ()+{- TODO: HEREHEREHEREHEREHEREHERE+  1. DOES this kill Unification.hs? (Guard under --no-adt)+  2. Use addEquality instead off _addSMTEquality.+-}+assertSelectors γ e = do+    sims <- aenvSimpl <$> gets _evAEnv+    -- cfg  <- gets evCfg+    -- _    <- foldlM (\_ s -> Vis.mapMExpr (go s) e) (tracepp "assertSelector" e) sims+    forM_ sims $ \s -> Vis.mapMExpr (go s) e+    return ()+  where+    go :: Rewrite -> Expr -> EvalST Expr+    go (SMeasure f dc xs bd) e@(EApp _ _)+      | (EVar dc', es) <- splitEApp e+      , dc == dc'+      , length xs == length es+      = do let e1 = (EApp (EVar f) e)+           let e2 = (subst (mkSubst $ zip xs es) bd)+           addEquality γ e1 e2+           return e+    go _ e+      = return e +-- _addSMTEquality :: Knowledge -> Expr -> Expr -> IO ()+-- _addSMTEquality γ e1 e2 = do+  -- ctx <- knContext γ+  -- SMT.smtAssert ctx (tracepp "addSMTEQ" (PAtom Eq (makeLam γ e1) (makeLam γ e2)))+ -------------------------------------------------------------------------------- -- | Symbolic Evaluation with SMT ---------------------------------------------------------------------------------data EvalEnv = EvalEnv { evId        :: Int-                       , evSequence  :: [(Expr,Expr)]-                       , _evAEnv     :: AxiomEnv-                       }+data EvalEnv = EvalEnv+  { evId        :: !Int+  , evSequence  :: [(Expr,Expr)]+  , _evAEnv     :: !AxiomEnv+  , evEnv       :: !SymEnv+  , _evCfg      :: !Config+  }  type EvalST a = StateT EvalEnv IO a @@ -285,13 +293,14 @@     (fmap join . sequence)     (evalOne <$> L.nub (grepTopApps =<< einit))   where-    (eqs, γ) = makeKnowledge cfg ctx aenv facts-    initEvalSt = EvalEnv 0 [] aenv+    (eqs, γ)   = makeKnowledge cfg ctx aenv facts+    senv       = SMT.ctxSymEnv ctx+    initEvalSt = EvalEnv 0 [] aenv senv cfg     -- This adds all intermediate unfoldings into the assumptions     -- no test needs it     -- TODO: add a flag to enable it     evalOne :: Expr -> IO [(Expr, Expr)]-    evalOne e = do+    evalOne e = {- notracepp ("evalOne e = " ++ showpp e) <$> -} do       (e', st) <- runStateT (eval γ e) initEvalSt       if e' == e then return [] else return ((e, e'):evSequence st) @@ -308,27 +317,24 @@ grepTopApps e@(EApp _ _)    = [e] grepTopApps _               = [] --- AT: I think makeLam is the adjoint of splitEApp?+-- makeLam is the adjoint of splitEApp makeLam :: Knowledge -> Expr -> Expr-makeLam γ e = foldl (flip ELam) e (knLams γ)+makeLam γ e = L.foldl' (flip ELam) e (knLams γ)  eval :: Knowledge -> Expr -> EvalST Expr-eval γ e | Just e' <- lookupKnowledge γ e-  = (e, "Knowledge") ~> e' eval γ (ELam (x,s) e)-  -- SHIFTLAM (assuming this shifting is redundant if DEFUNC has already happened)-  -- = do let x' = lamArgSymbol (1 + length (knLams γ))-       -- e'    <- eval γ{knLams = (x',s):knLams γ} (subst1 e (x, EVar x'))-       -- return $ ELam (x,s) $ subst1 e' (x', EVar x)-   = do e'    <- eval γ{knLams = (x, s) : knLams γ} e        return $ ELam (x, s) e'  eval γ e@(EIte b e1 e2)   = do b' <- eval γ b        evalIte γ e b' e1 e2+eval γ (ECoerc s t e)+  = ECoerc s t <$> eval γ e eval γ e@(EApp _ _)   = evalArgs γ e >>= evalApp γ e+eval γ e@(EVar _)+  = evalApp γ e (e,[]) eval γ (PAtom r e1 e2)   = PAtom r <$> eval γ e1 <*> eval γ e2 eval γ (ENeg e)@@ -368,53 +374,136 @@ evalApp :: Knowledge -> Expr -> (Expr, [Expr]) -> EvalST Expr evalApp γ e (EVar f, [ex])   | (EVar dc, es) <- splitEApp ex-  , Just simp <- L.find (\simp -> (smName simp == f) && (smDC simp == dc))-                        (knSims γ)+  , Just simp <- L.find (\simp -> (smName simp == f) && (smDC simp == dc)) (knSims γ)   , length (smArgs simp) == length es-  = do e'    <- eval γ $ η $ substPopIf (zip (smArgs simp) es) (smBody simp)+  = do e'    <- eval γ $ wtf $ substPopIf (zip (smArgs simp) es) (smBody simp)        (e, "Rewrite -" ++ showpp f) ~> e' evalApp γ _ (EVar f, es)+  -- we should move the lookupKnowledge stuff here into kmAms γ   | Just eq <- L.find ((==f) . eqName) (knAms γ)   , Just bd <- getEqBody eq   , length (eqArgs eq) == length es-  , f `notElem` syms bd -- not recursive-  = eval γ $ η $ substPopIf (zip (eqArgs eq) es) bd+  , f `notElem` syms bd               -- non-recursive equations+  = eval γ . wtf =<< assertSelectors γ <<= substEq PopIf eq es bd+ evalApp γ _e (EVar f, es)   | Just eq <- L.find ((==f) . eqName) (knAms γ)   , Just bd <- getEqBody eq-  , length (eqArgs eq) == length es  --  recursive-  = evalRecApplication γ (eApps (EVar f) es) $-    subst (mkSubst $ zip (eqArgs eq) es) bd+  , length (eqArgs eq) == length es   -- recursive equations+  = evalRecApplication γ (eApps (EVar f) es) =<< substEq Normal eq es bd evalApp _ _ (f, es)   = return $ eApps f es +--------------------------------------------------------------------------------+-- | 'substEq' unfolds or instantiates an equation at a particular list of+--   argument values. We must also substitute the sort-variables that appear+--   as coercions. See tests/proof/ple1.fq+--------------------------------------------------------------------------------+substEq :: SubstOp -> Equation -> [Expr] -> Expr -> EvalST Expr+substEq o eq es bd = substEqVal o eq es <$> substEqCoerce eq es bd++data SubstOp = PopIf | Normal++substEqVal :: SubstOp -> Equation -> [Expr] -> Expr -> Expr+substEqVal o eq es bd = case o of+    PopIf  -> substPopIf     xes  bd+    Normal -> subst (mkSubst xes) bd+  where+    xes    =  zip xs es+    xs     =  eqArgNames eq++substEqCoerce :: Equation -> [Expr] -> Expr -> EvalST Expr+substEqCoerce eq es bd = do+  env      <- seSort <$> gets evEnv+  let ts    = snd    <$> eqArgs eq+  let coSub = mkCoSub env es ts+  return    $ applyCoSub coSub bd++-- | @CoSub@ is a map from (coercion) ty-vars represented as 'FObj s'+--   to the ty-vars that they should be substituted with. Note the+--   domain and range are both Symbol and not the Int used for real ty-vars.++type CoSub = M.HashMap Symbol Symbol++mkCoSub :: SEnv Sort -> [Expr] -> [Sort] -> CoSub+mkCoSub env es xTs = Misc.safeFromList "mkCoSub" xys+  where+    eTs            = sortExpr sp env <$> es+    sp             = panicSpan "mkCoSub"+    xys            = concat (zipWith matchSorts xTs eTs)++matchSorts :: Sort -> Sort -> [(Symbol, Symbol)]+matchSorts = go+  where+    go (FObj x)      (FObj y)      = [(x, y)]+    go (FAbs _ t1)   (FAbs _ t2)   = go t1 t2+    go (FFunc s1 t1) (FFunc s2 t2) = go s1 s2 ++ go t1 t2+    go (FApp s1 t1)  (FApp s2 t2)  = go s1 s2 ++ go t1 t2+    go _             _             = []++applyCoSub :: CoSub -> Expr -> Expr+applyCoSub coSub      = Vis.mapExpr fE+  where+    fE (ECoerc s t e) = ECoerc (txS s) (txS t) e+    fE e              = e+    txS               = Vis.mapSort fS+    fS (FObj a)       = FObj   (txV a)+    fS t              = t+    txV a             = M.lookupDefault a a coSub++--------------------------------------------------------------------------------+getEqBody :: Equation -> Maybe Expr+getEqBody (Equ x xts b _ _)+  | Just (fxs, e) <- getEqBodyPred b+  , (EVar f, es)  <- splitEApp fxs+  , f == x+  , es == (EVar . fst <$> xts)+  = Just e+getEqBody _+  = Nothing++getEqBodyPred :: Expr -> Maybe (Expr, Expr)+getEqBodyPred (PAtom Eq fxs e)+  = Just (fxs, e)+getEqBodyPred (PAnd ((PAtom Eq fxs e):_))+  = Just (fxs, e)+getEqBodyPred _+  = Nothing++eqArgNames :: Equation -> [Symbol]+eqArgNames = map fst . eqArgs+ substPopIf :: [(Symbol, Expr)] -> Expr -> Expr-substPopIf xes e = η $ foldl go e xes+substPopIf xes e = wtf $ L.foldl' go e xes   where     go e (x, EIte b e1 e2) = EIte b (subst1 e (x, e1)) (subst1 e (x, e2))     go e (x, ex)           = subst1 e (x, ex)  evalRecApplication :: Knowledge -> Expr -> Expr -> EvalST Expr-evalRecApplication γ e (EIte b e1 e2)-  = do b' <- eval γ b-       b'' <- liftIO (isValid γ b')-       if b''-          then addApplicationEq γ e e1 >>-               ({-# SCC "assertSelectors-1" #-} assertSelectors γ e1) >>-               eval γ e1 >>=-               ((e, "App") ~>)-          else do b''' <- liftIO (isValid γ (PNot b'))-                  if b'''-                     then addApplicationEq γ e e2 >>-                          ({-# SCC "assertSelectors-1" #-} assertSelectors γ e2) >>-                          eval γ e2 >>=-                          ((e, "App") ~>)-                     else return e+evalRecApplication γ e (EIte b e1 e2) = do+  contra <- {- tracepp ("CONTRA? " ++ showpp e) <$> -} liftIO (isValid γ PFalse)+  if contra+    then return e+    else do b' <- eval γ b+            b1 <- liftIO (isValid γ b')+            if b1+              then addEquality γ e e1 >>+                   ({-# SCC "assertSelectors-1" #-} assertSelectors γ e1) >>+                   eval γ e1 >>=+                   ((e, "App") ~>)+              else do+                   b2 <- liftIO (isValid γ (PNot b'))+                   if b2+                      then addEquality γ e e2 >>+                           ({-# SCC "assertSelectors-2" #-} assertSelectors γ e2) >>+                           eval γ e2 >>=+                           ((e, "App") ~>)+                      else return e evalRecApplication _ _ e   = return e -addApplicationEq :: Knowledge -> Expr -> Expr -> EvalST ()-addApplicationEq γ e1 e2 =+addEquality :: Knowledge -> Expr -> Expr -> EvalST ()+addEquality γ e1 e2 =   modify (\st -> st{evSequence = (makeLam γ e1, makeLam γ e2):evSequence st})  evalIte :: Knowledge -> Expr -> Expr -> Expr -> Expr -> EvalST Expr@@ -438,10 +527,14 @@        e2' <- eval γ e2        return $ EIte b e1' e2' +-------------------------------------------------------------------------------- -- normalization required by ApplicativeMaybe.composition-----------------------------------------------------------η :: Expr -> Expr-η = snd . go+--------------------------------------------------------------------------------+-- RJ: What on earth is this function doing?+wtf :: Expr -> Expr+wtf = id+{-+wtf = snd . go   where     go (EIte b t f)       | isTautoPred t && isFalse f@@ -465,5 +558,6 @@               else (False, EApp e1' e2')     go e = (False, e) +-} instance Expression (Symbol, SortedReft) where   expr (x, RR _ (Reft (v, r))) = subst1 (expr r) (v, EVar x)
src/Language/Fixpoint/Solver/Solve.hs view
@@ -8,7 +8,7 @@ -- | Solve a system of horn-clause constraints --------------------------------- -------------------------------------------------------------------------------- -module Language.Fixpoint.Solver.Solve (solve) where+module Language.Fixpoint.Solver.Solve (solve, solverInfo) where  import           Control.Monad (when, filterM) import           Control.Monad.State.Strict (lift)@@ -16,8 +16,6 @@ import qualified Language.Fixpoint.Misc            as Misc import qualified Language.Fixpoint.Types           as F import qualified Language.Fixpoint.Types.Solutions as Sol-import qualified Language.Fixpoint.Types.Graduals  as G-import qualified Language.Fixpoint.Solver.GradualSolution as GS import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Types.Config hiding (stats) import qualified Language.Fixpoint.Solver.Solution  as S@@ -33,22 +31,15 @@ import qualified Data.HashMap.Strict as M import qualified Data.HashSet        as S import qualified Data.List as L-import Control.Concurrent.ParallelIO.Global (parallel) -import qualified Language.Fixpoint.SortCheck       as So-import Language.Fixpoint.Solver.Sanitize (symbolEnv)--- DEBUG--- import           Debug.Trace (trace)- -------------------------------------------------------------------------------- solve :: (NFData a, F.Fixpoint a, Show a, F.Loc a) => Config -> F.SInfo a -> IO (F.Result (Integer, a)) ---------------------------------------------------------------------------------solve cfg fi | gradual cfg- = solveGradual cfg fi  solve cfg fi = do-    donePhase Misc.Loud "Worklist Initialize"-    (res, stat) <- withProgressFI sI $ runSolverM cfg sI act+    whenLoud $ donePhase Misc.Loud "Worklist Initialize"+    vb <- getVerbosity+    (res, stat) <- (if (Quiet == vb || gradual cfg) then id else withProgressFI sI) $ runSolverM cfg sI act     when (solverStats cfg) $ printStats fi wkl stat     -- print (numIter stat)     return res@@ -61,124 +52,10 @@   ---------------------------------------------------------------------------------solveGradual :: (NFData a, F.Fixpoint a, Show a, F.Loc a)-             => Config -> F.SInfo a -> IO (F.Result (Integer, a))----------------------------------------------------------------------------------solveGradual cfg fi = do-  -- graphStatistics cfg $ G.uniquify fi-  let fis = zip [1..] $ partition' Nothing $ G.uniquify fi-  if ginteractive cfg-    then snd . traceShow "FINAL SOLUTION\n"  <$> iSolveGradual cfg fis-    else snd . traceShow "FINAL SOLUTION\n" . mconcat <$> parallel (solveGradualOne cfg <$> fis)---iSolveGradual :: (NFData a, F.Fixpoint a, Show a, F.Loc a) => Config -> [(Int, F.SInfo a)] -> IO (Maybe G.GSol, F.Result (Integer, a))-iSolveGradual cfg fis-  = mconcat <$> parallel (solveGradualOne cfg <$> fis)---solveGradualOne :: (NFData a, F.Fixpoint a, Show a, F.Loc a) => Config -> (Int, F.SInfo a) -> IO (Maybe G.GSol, F.Result (Integer, a))-solveGradualOne cfg (_, fi) = do-  sols   <- makeSolutions cfg fi-  gradualLoop (cfg{gradual = False}) fi sols--gradualLoop :: (NFData a, F.Fixpoint a, Show a, F.Loc a) => Config -> F.SInfo a -> (Maybe [G.GSol]) -> IO (Maybe G.GSol, F.Result (Integer, a))-gradualLoop _ _ Nothing-  = return (Nothing, F.safe)-gradualLoop _ _ (Just [])-  = return (Nothing, F.unsafe)-gradualLoop cfg fi (Just (s:ss))-  = do whenLoud   $ putStrLn ("Solving for " ++ show s)-       whenNormal $ putStr "*"-       v <- getVerbosity-       -- putStr ("Substitution = " ++ show s)-       -- putStr ("BEFORE \n\n"  ++ (show $ F.toFixpoint cfg fi))-       -- putStr ("AFTER \n\n"  ++ (show $ F.toFixpoint cfg $ G.gsubst s fi))-       whenNormal $ setVerbosity Quiet-       r <- solve cfg (G.gsubst s fi)-       setVerbosity v-       whenLoud $ putStrLn ("Solution = " ++ if F.isUnsafe r then "UNSAFE" else "SAFE")-       if F.isUnsafe r-        then gradualLoop cfg fi (Just ss)-        else return (Just s, r)---makeSolutions :: (NFData a, F.Fixpoint a, Show a) => Config -> F.SInfo a -> IO (Maybe [G.GSol])-makeSolutions cfg fi-  = G.makeSolutions cfg fi <$> makeLocalLattice cfg fi (GS.init fi)----makeLocalLattice :: Config -> F.SInfo a-                 -> [(F.KVar, (F.GWInfo, [F.Expr]))]-                 -> IO [(F.KVar, (F.GWInfo, [[F.Expr]]))]-makeLocalLattice cfg fi kes = runSolverM cfg sI (act kes)-  where-    sI  = solverInfo cfg fi-    act = mapM (makeLocalLatticeOne cfg fi)---makeLocalLatticeOne :: Config -> F.SInfo a-            -> (F.KVar, (F.GWInfo, [F.Expr]))-            -> SolveM (F.KVar, (F.GWInfo, [[F.Expr]]))-makeLocalLatticeOne cfg fi (k, (e, es)) = do-   elems0  <- filterM (isLocal e) (map (:[]) es)-   elems   <- sortEquals elems0-   lattice <- makeLattice [] (map (:[]) elems) elems-   return $ ((k,) . (e,)) lattice-  where-    sEnv = symbolEnv cfg fi-    makeLattice acc new elems-      | null new-      = return {- traceShow ("LATTICE FROM ELEMENTS = " ++ showElems elems  ++ showElemss acc) -} acc-      | otherwise-      = do let cands = [e:es | e <- elems, es <- new]-           localCans <- filterM (isLocal e) cands-           newElems  <- filterM (notTrivial (new ++ acc)) localCans-           makeLattice (acc ++ new) newElems elems-    _showElem :: F.Expr -> String-    _showElem e1 = showpp $ F.subst (F.mkSubst [(x, F.EVar $ F.tidySymbol x) | x <- F.syms e1]) e1-    _showElems = unlines . map _showElem-    _showElemss = unlines. map _showElems--    notTrivial [] _     = return True-    notTrivial (x:xs) p = do v <- isValid F.dummySpan (mkPred x) (mkPred p)-                             if v then return False-                                  else notTrivial xs p--    mkPred es = So.elaborate "initBGind.mkPred" sEnv (F.pAnd es)--    isLocal i es = do-      let pp = So.elaborate "filterLocal" sEnv $ F.PExist [(F.gsym i, F.gsort i)] $ F.pAnd (F.gexpr i:es)-      isValid F.dummySpan mempty pp--    root      = mempty-    sortEquals xs = (bfs [0]) <$> makeEdges vs [] vs-      where-       vs        = zip [0..] (root:(head <$> xs))--       bfs []     _  = []-       bfs (i:is) es = (snd $ (vs!!i)) : bfs (is++map snd (filter (\(j,k) ->  (j==i && notElem k is)) es)) es--       makeEdges _   acc []    = return acc-       makeEdges vs acc (x:xs) = do ves  <- concat <$> mapM (makeEdgesOne x) vs-                                    if any (\(i,j) -> elem (j,i) acc) ves-                                      then makeEdges (filter ((/= fst x) . fst) vs) (filter (\(i,j) -> ((i /= fst x) && (j /= fst x))) acc) xs-                                      else makeEdges vs (mergeEdges (ves ++ acc)) xs--    makeEdgesOne (i,_) (j,_) | i == j = return []-    makeEdgesOne (i,x) (j,y) = do-      ij <- isValid F.dummySpan (mkPred [x]) (mkPred [y])-      return (if ij then [(j,i)] else [])--    mergeEdges es = filter (\(i,j) -> (not (any (\k -> ((i,k) `elem` es && (k,j) `elem` es)) (fst <$> es)))) es----------------------------------------------------------------------------------- -- | Progress Bar -------------------------------------------------------------------------------- withProgressFI :: SolverInfo a b -> IO b -> IO b-withProgressFI = withProgress . fromIntegral . cNumScc . siDeps+withProgressFI = withProgress . (+ 1) . fromIntegral . cNumScc . siDeps   --------------------------------------------------------------------------------  printStats :: F.SInfo a ->  W.Worklist a -> Stats -> IO ()
src/Language/Fixpoint/SortCheck.hs view
@@ -28,6 +28,7 @@   , sortExpr   , checkSortExpr   , exprSort+  , exprSort_maybe    -- * Unify   , unifyFast@@ -58,7 +59,7 @@  import qualified Data.HashMap.Strict       as M import qualified Data.List                 as L-import           Data.Maybe                (mapMaybe, fromMaybe)+import           Data.Maybe                (mapMaybe, fromMaybe, catMaybes)  import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Misc@@ -198,13 +199,14 @@     step (PAll   bs p)    = PAll   bs (go p)     step (PAtom r e1 e2)  = PAtom r (go e1) (go e2)     step e@(EApp {})      = go e-    step (ELam b e)       = ELam b (go e)+    step (ELam b e)       = ELam b       (go e)+    step (ECoerc a t e)   = ECoerc a t   (go e)     step (PGrad k su i e) = PGrad k su i (go e)     step e@(PKVar {})     = e     step e@(ESym {})      = e     step e@(ECon {})      = e     step e@(EVar {})      = e-    -- ELam, ETApp, ETAbs, PAll, PExist+    -- ETApp, ETAbs, PAll, PExist     step e                = error $ "TODO elabApply: " ++ showpp e  --------------------------------------------------------------------------------@@ -357,6 +359,7 @@ 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" @@ -379,11 +382,15 @@  elab f (EApp e1@(EApp _ _) e2) = do   (e1', _, e2', s2, s) <- notracepp "ELAB-EAPP" <$> elabEApp f e1 e2-  return (eAppC s e1'          (ECst e2' s2), s)+  let e = eAppC s e1' (ECst e2' s2)+  let θ = unifyExpr (snd f) e+  return (applyExpr θ e, maybe s (`apply` s) θ)  elab f (EApp e1 e2) = do   (e1', s1, e2', s2, s) <- elabEApp f e1 e2-  return (eAppC s (ECst e1' s1) (ECst e2' s2), s)+  let e = eAppC s (ECst e1' s1) (ECst e2' s2)+  let θ = unifyExpr (snd f) e+  return (applyExpr θ e, maybe s (`apply` s) θ)  elab _ e@(ESym _) =   return (e, strSort)@@ -477,6 +484,10 @@   let t' = elaborate "ELam Arg" mempty t   return (ELam (x, t') (ECst e' s), FFunc t s) +elab f (ECoerc s t e) = do+  (e', _) <- elab f e+  return     (ECoerc s t e', t)+ elab _ (ETApp _ _) =   error "SortCheck.elab: TODO: implement ETApp" elab _ (ETAbs _ _) =@@ -629,14 +640,24 @@ -- | Expressions sort  --------------------------------------------------------- -------------------------------------------------------------------------------- exprSort :: String -> Expr -> Sort-exprSort msg = go+exprSort msg e = fromMaybe (panic err) (exprSort_maybe e)   where-    go (ECst _ s) = s-    go (ELam (_, sx) e) = FFunc sx (go e)+    err        = printf "exprSort [%s] on unexpected expression %s" msg (show e)++  -- case exprSort_maybe e of+  --  Nothing -> errorstar ("\nexprSort [" ++ msg ++ "] on unexpected expressions " ++ show e)+  --  Just s  -> s+++exprSort_maybe :: Expr -> Maybe Sort+exprSort_maybe = go+  where+    go (ECst _ s) = Just s+    go (ELam (_, sx) e) = FFunc sx <$> go e     go (EApp e ex)-      | FFunc sx s <- genSort (go e)-      = maybe s (`apply` s) $ unifySorts (go ex) sx-    go e = errorstar ("\nexprSort [" ++ msg ++ "] on unexpected expressions " ++ show e)+      | Just (FFunc sx s) <- genSort <$> go e+      = maybe s (`apply` s) <$> ((`unifySorts` sx) <$> go ex)+    go _ = Nothing  genSort :: Sort -> Sort genSort (FAbs _ t) = genSort t@@ -650,10 +671,9 @@  -- | Helper for checking symbol occurrences checkSym :: Env -> Symbol -> CheckM Sort-checkSym f x-  = case f x of-     Found s -> instantiate s-     Alts xs -> throwError $ errUnboundAlts x xs+checkSym f x = case f x of+  Found s -> instantiate s+  Alts xs -> throwError (errUnboundAlts x xs)  -- | Helper for checking if-then-else expressions checkIte :: Env -> Expr -> Expr -> Expr -> CheckM Sort@@ -754,10 +774,20 @@ checkNumeric :: Env -> Sort -> CheckM () checkNumeric f s@(FObj l)   = do t <- checkSym f l-       unless (t == FNum || t == FFrac) (throwError $ errNonNumeric s)+       unless (t `elem` [FNum, FFrac, intSort, FInt]) (throwError $ errNonNumeric s) checkNumeric _ s   = unless (isNumeric s) (throwError $ errNonNumeric s) +checkEqConstr :: Env -> Maybe Expr -> a -> Symbol -> Sort -> CheckM a+checkEqConstr _ _  θ a (FObj b)+  | a == b+  = return θ+checkEqConstr f e θ a t = do+  case f a of+    Found tA -> do unless (tA == t) (throwError $ errUnify e tA t)+                   return θ+    _        -> throwError $ errUnify e (FObj a) t+ -------------------------------------------------------------------------------- -- | Checking Predicates ------------------------------------------------------- --------------------------------------------------------------------------------@@ -805,7 +835,34 @@  checkRelTy _ e _  t1 t2      = unless (t1 == t2) (throwError $ errRel e t1 t2) ++ --------------------------------------------------------------------------------+-- | Sort Unification on Expressions+--------------------------------------------------------------------------------++unifyExpr :: Env -> Expr -> Maybe TVSubst+unifyExpr f (EApp e1 e2) = Just $ mconcat $ catMaybes [θ1, θ2, θ]+  where+   θ1 = unifyExpr f e1+   θ2 = unifyExpr f e2+   θ  = unifyExprApp f e1 e2+unifyExpr f (ECst e _)+  = unifyExpr f e+unifyExpr _ _+  = Nothing++unifyExprApp :: Env -> Expr -> Expr -> Maybe TVSubst+unifyExprApp f e1 e2 = do+  t1 <- getArg $ exprSort_maybe e1+  t2 <- exprSort_maybe e2+  unify f (Just $ EApp e1 e2) t1 t2+  where+    getArg (Just (FFunc t1 _)) = Just t1+    getArg _                   = Nothing+++-------------------------------------------------------------------------------- -- | Sort Unification -------------------------------------------------------------------------------- unify :: Env -> Maybe Expr -> Sort -> Sort -> Maybe TVSubst@@ -880,12 +937,19 @@ unify1 f e !θ (FFunc !t1 !t2) (FFunc !t1' !t2') = do   unifyMany f e θ [t1, t2] [t1', t2'] +unify1 f e θ (FObj a) !t =+  checkEqConstr f e θ a t++unify1 f e θ !t (FObj a) =+  checkEqConstr f e θ a t+ unify1 _ e θ !t1 !t2   | t1 == t2   = return θ   | otherwise   = throwError $ errUnify e t1 t2 + subst :: Int -> Sort -> Sort -> Sort subst !j !tj !t@(FVar !i)   | i == j                  = tj@@ -944,7 +1008,24 @@     f t@(FVar i) = fromMaybe t (lookupVar i θ)     f t          = t +applyExpr :: Maybe TVSubst -> Expr -> Expr+applyExpr Nothing e  = e+applyExpr (Just θ) e = Vis.mapExpr f e+  where+    f (ECst e s) = ECst e (apply θ s)+    f e          = e+ --------------------------------------------------------------------------------+_applyCoercion :: Symbol -> Sort -> Sort -> Sort+--------------------------------------------------------------------------------+_applyCoercion a t = Vis.mapSort f+  where+    f (FObj b)+      | a == b    = t+    f s           = s+++-------------------------------------------------------------------------------- -- | Deconstruct a function-sort ----------------------------------------------- -------------------------------------------------------------------------------- checkFunSort :: Sort -> CheckM (Sort, Sort, TVSubst)@@ -961,6 +1042,10 @@  newtype TVSubst = Th (M.HashMap Int Sort) deriving (Show) +instance Monoid TVSubst where+  mempty                  = Th mempty+  mappend (Th s1) (Th s2) = Th (mappend s1 s2)+ lookupVar :: Int -> TVSubst -> Maybe Sort lookupVar i (Th m)   = M.lookup i m @@ -979,11 +1064,11 @@  errUnify :: Maybe Expr -> Sort -> Sort -> String errUnify eo t1 t2 = printf "Cannot unify %s with %s %s"-                      (showpp t1) (showpp t2) (unifyExpr eo)+                      (showpp t1) (showpp t2) (errUnifyExpr eo) -unifyExpr :: Maybe Expr -> String-unifyExpr Nothing  = ""-unifyExpr (Just e) = "in expression: " ++ showpp e+errUnifyExpr :: Maybe Expr -> String+errUnifyExpr Nothing  = ""+errUnifyExpr (Just e) = "in expression: " ++ showpp e  errUnifyMany :: [Sort] -> [Sort] -> String errUnifyMany ts ts'  = printf "Cannot unify types with different cardinalities %s and %s"
src/Language/Fixpoint/Types/Config.hs view
@@ -56,41 +56,40 @@ defaultMaxPartSize = 700  -data Config-  = Config {-      srcFile     :: FilePath            -- ^ src file (*.hs, *.ts, *.c, or even *.fq or *.bfq)-    , cores       :: Maybe Int           -- ^ number of cores used to solve constraints-    , minPartSize :: Int                 -- ^ Minimum size of a partition-    , maxPartSize :: Int                 -- ^ Maximum size of a partition. Overrides minPartSize-    , solver      :: SMTSolver           -- ^ which SMT solver to use-    , linear      :: Bool                -- ^ not interpret div and mul in SMT-    , stringTheory :: Bool               -- ^ interpretation of string theory by SMT-    , defunction  :: Bool                -- ^ defunctionalize (use 'apply' for all uninterpreted applications)-    , allowHO     :: Bool                -- ^ allow higher order binders in the logic environment-    , allowHOqs   :: Bool                -- ^ allow higher order qualifiers-    , eliminate   :: Eliminate           -- ^ eliminate non-cut KVars-    , elimBound   :: Maybe Int           -- ^ maximum length of KVar chain to eliminate-    , elimStats   :: Bool                -- ^ print eliminate stats-    , solverStats :: Bool                -- ^ print solver stats-    , metadata    :: Bool                -- ^ print meta-data associated with constraints-    , stats       :: Bool                -- ^ compute constraint statistics-    , parts       :: Bool                -- ^ partition FInfo into separate fq files-    , save        :: Bool                -- ^ save FInfo as .bfq and .fq file-    , minimize    :: Bool                -- ^ min .fq by delta debug (unsat with min constraints)-    , minimizeQs  :: Bool                -- ^ min .fq by delta debug (sat with min qualifiers)-    , minimizeKs  :: Bool                -- ^ min .fq by delta debug (sat with min kvars)-    , minimalSol  :: Bool                -- ^ shrink final solution by pruning redundant qualfiers from fixpoint-    , gradual     :: Bool                -- ^ solve "gradual" constraints-    , ginteractive :: Bool                -- ^ interactive gradual solving-    , extensionality   :: Bool           -- ^ allow function extensionality-    , alphaEquivalence :: Bool           -- ^ allow lambda alpha equivalence axioms-    , betaEquivalence  :: Bool           -- ^ allow lambda beta equivalence axioms-    , normalForm       :: Bool           -- ^ allow lambda normal-form equivalence axioms-    , autoKuts         :: Bool           -- ^ ignore given kut variables-    , nonLinCuts       :: Bool           -- ^ Treat non-linear vars as cuts-    , noslice          :: Bool           -- ^ Disable non-concrete KVar slicing-    , rewriteAxioms    :: Bool           -- ^ allow axiom instantiation via rewriting-    } deriving (Eq,Data,Typeable,Show,Generic)+data Config = Config+  { srcFile     :: FilePath            -- ^ src file (*.hs, *.ts, *.c, or even *.fq or *.bfq)+  , cores       :: Maybe Int           -- ^ number of cores used to solve constraints+  , minPartSize :: Int                 -- ^ Minimum size of a partition+  , maxPartSize :: Int                 -- ^ Maximum size of a partition. Overrides minPartSize+  , solver      :: SMTSolver           -- ^ which SMT solver to use+  , linear      :: Bool                -- ^ not interpret div and mul in SMT+  , stringTheory :: Bool               -- ^ interpretation of string theory by SMT+  , defunction  :: Bool                -- ^ defunctionalize (use 'apply' for all uninterpreted applications)+  , allowHO     :: Bool                -- ^ allow higher order binders in the logic environment+  , allowHOqs   :: Bool                -- ^ allow higher order qualifiers+  , eliminate   :: Eliminate           -- ^ eliminate non-cut KVars+  , elimBound   :: Maybe Int           -- ^ maximum length of KVar chain to eliminate+  , elimStats   :: Bool                -- ^ print eliminate stats+  , solverStats :: Bool                -- ^ print solver stats+  , metadata    :: Bool                -- ^ print meta-data associated with constraints+  , stats       :: Bool                -- ^ compute constraint statistics+  , parts       :: Bool                -- ^ partition FInfo into separate fq files+  , save        :: Bool                -- ^ save FInfo as .bfq and .fq file+  , minimize    :: Bool                -- ^ min .fq by delta debug (unsat with min constraints)+  , minimizeQs  :: Bool                -- ^ min .fq by delta debug (sat with min qualifiers)+  , minimizeKs  :: Bool                -- ^ min .fq by delta debug (sat with min kvars)+  , minimalSol  :: Bool                -- ^ shrink final solution by pruning redundant qualfiers from fixpoint+  , gradual     :: Bool                -- ^ solve "gradual" constraints+  , ginteractive :: Bool                -- ^ interactive gradual solving+  , extensionality   :: Bool           -- ^ allow function extensionality+  , alphaEquivalence :: Bool           -- ^ allow lambda alpha equivalence axioms+  , betaEquivalence  :: Bool           -- ^ allow lambda beta equivalence axioms+  , normalForm       :: Bool           -- ^ allow lambda normal-form equivalence axioms+  , autoKuts         :: Bool           -- ^ ignore given kut variables+  , nonLinCuts       :: Bool           -- ^ Treat non-linear vars as cuts+  , noslice          :: Bool           -- ^ Disable non-concrete KVar slicing+  , rewriteAxioms    :: Bool           -- ^ allow axiom instantiation via rewriting+  } deriving (Eq,Data,Typeable,Show,Generic)  instance Default Config where   def = defConfig
src/Language/Fixpoint/Types/Constraints.hs view
@@ -55,7 +55,7 @@   , FixSolution   , GFixSolution, toGFixSol   , Result (..)-  , unsafe, isUnsafe, safe+  , unsafe, isUnsafe, isSafe ,safe    -- * Cut KVars   , Kuts (..)@@ -69,8 +69,8 @@   -- * Axioms   , AxiomEnv (..)   , Equation (..)+  , mkEquation   , Rewrite  (..)-  , getEqBody    -- * Misc  [should be elsewhere but here due to dependencies]   , substVars@@ -142,6 +142,9 @@ isGWfc (GWfC {}) = True isGWfc (WfC  {}) = False +instance HasGradual (WfC a) where+  isGradual = isGWfc+ type SubcId = Integer  data SubC a = SubC@@ -263,6 +266,10 @@ unsafe = mempty {resStatus = Unsafe []} safe   = mempty {resStatus = Safe} +isSafe :: Result a -> Bool+isSafe (Result Safe _ _) = True+isSafe _                 = False+ isUnsafe :: Result a -> Bool isUnsafe r | Unsafe _ <- resStatus r   = True@@ -602,6 +609,9 @@      }   deriving (Eq, Show, Functor, Generic) +instance HasGradual (GInfo c a) where+  isGradual info = any isGradual (M.elems $ ws info)+ instance Monoid HOInfo where   mempty        = HOI False False   mappend i1 i2 = HOI { hoBinds = hoBinds i1 || hoBinds i2@@ -738,10 +748,11 @@ --------------------------------------------------------------------------- -- | Axiom Instantiation Information -------------------------------------- ----------------------------------------------------------------------------data AxiomEnv = AEnv { aenvEqs     :: ![Equation]-                     , aenvSimpl   :: ![Rewrite]-                     , aenvExpand  :: M.HashMap SubcId Bool-                     }+data AxiomEnv = AEnv+  { aenvEqs     :: ![Equation]+  , aenvSimpl   :: ![Rewrite]+  , aenvExpand  :: M.HashMap SubcId Bool+  }   deriving (Eq, Show, Generic)  instance B.Binary AxiomEnv@@ -756,43 +767,64 @@ instance NFData Eliminate  instance Monoid AxiomEnv where-  mempty = AEnv [] [] (M.fromList [])-  mappend a1 a2 = AEnv aenvEqs' aenvSimpl' aenvExpand'-    where aenvEqs'     = mappend (aenvEqs a1) (aenvEqs a2)-          aenvSimpl'   = mappend (aenvSimpl a1) (aenvSimpl a2)-          aenvExpand'  = mappend (aenvExpand a1) (aenvExpand a2)+  mempty           = AEnv [] [] (M.fromList [])+  mappend a1 a2    = AEnv aenvEqs' aenvSimpl' aenvExpand'+    where+      aenvEqs'     = mappend (aenvEqs a1) (aenvEqs a2)+      aenvSimpl'   = mappend (aenvSimpl a1) (aenvSimpl a2)+      aenvExpand'  = mappend (aenvExpand a1) (aenvExpand a2) -data Equation = Equ { eqName :: Symbol-                    , eqArgs :: [Symbol]-                    , eqBody :: Expr-                    }+instance PPrint AxiomEnv where+  pprintTidy _ = text . show++data Equation = Equ+  { eqName :: !Symbol           -- ^ name of reflected function+  , eqArgs :: [(Symbol, Sort)]  -- ^ names of parameters+  , eqBody :: !Expr             -- ^ definition of body+  , eqSort :: !Sort             -- ^ sort of body+  , eqRec  :: !Bool             -- ^ is this a recursive definition+  }   deriving (Eq, Show, Generic) +mkEquation :: Symbol -> [(Symbol, Sort)] -> Expr -> Sort -> Equation+mkEquation f xts e out = Equ f xts e out (f `elem` syms e)++instance Subable Equation where+  syms   a = syms (eqBody a) -- ++ F.syms (axiomEq a)+  subst su = mapEqBody (subst su)+  substf f = mapEqBody (substf f)+  substa f = mapEqBody (substa f)++mapEqBody :: (Expr -> Expr) -> Equation -> Equation+mapEqBody f a = a { eqBody = f (eqBody a) }+ instance PPrint Equation where-  pprintTidy k (Equ f xs e) = "def" <+> pprint f <+> intersperse " " (pprint <$> xs) <+> ":=" <+> pprintTidy k e+  pprintTidy _ = toFix +ppArgs :: (PPrint a) => [a] -> Doc+ppArgs = parens . intersperse ", " . fmap pprint  -- eg  SMeasure (f D [x1..xn] e) -- for f (D x1 .. xn) = e-data Rewrite  = SMeasure  { smName  :: Symbol         -- eg. f-                          , smDC    :: Symbol         -- eg. D-                          , smArgs  :: [Symbol]       -- eg. xs-                          , smBody  :: Expr           -- eg. e[xs]-                          }+data Rewrite  = SMeasure+  { smName  :: Symbol         -- eg. f+  , smDC    :: Symbol         -- eg. D+  , smArgs  :: [Symbol]       -- eg. xs+  , smBody  :: Expr           -- eg. e[xs]+  }   deriving (Eq, Show, Generic)  instance Fixpoint AxiomEnv where   toFix axe = vcat ((toFix <$> aenvEqs axe) ++ (toFix <$> aenvSimpl axe))               $+$ text "expand" <+> toFix (pairdoc <$> M.toList(aenvExpand axe))-    where pairdoc (x,y) = text $ show x ++ " : " ++ show y+    where+      pairdoc (x,y) = text $ show x ++ " : " ++ show y  instance Fixpoint Doc where   toFix = id  instance Fixpoint Equation where-  toFix (Equ f xs e)  = text "define"-                     <+> toFix f <+> hsep (toFix <$> xs) <+> text " = "-                     <+> lparen <> toFix e <> rparen+  toFix (Equ f xs e _ _) = "define" <+> toFix f <+> ppArgs xs <+> text "=" <+> parens (toFix e)  instance Fixpoint Rewrite where   toFix (SMeasure f d xs e)@@ -800,13 +832,7 @@    <+> toFix f    <+> parens (toFix d <+> hsep (toFix <$> xs))    <+> text " = "-   <+> lparen <> toFix e <> rparen+   <+> parens (toFix e) -getEqBody :: Equation -> Maybe Expr-getEqBody (Equ  x xs (PAnd ((PAtom Eq fxs e):_)))-  | (EVar f, es) <- splitEApp fxs-  , f == x-  , es == (EVar <$> xs)-  = Just e-getEqBody _-  = Nothing+instance PPrint Rewrite where+  pprintTidy _ = toFix
src/Language/Fixpoint/Types/Names.hs view
@@ -214,8 +214,10 @@ instance Fixpoint T.Text where   toFix = text . T.unpack --- RJ: Use `symbolSafeText` if you want it to machine-readable,---     but `symbolText`     if you want it to be human-readable.+{- | [NOTE: SymbolText]+	Use `symbolSafeText` if you want it to machine-readable,+        but `symbolText`     if you want it to be human-readable.+ -}  instance Fixpoint Symbol where   toFix = toFix . checkedText -- symbolSafeText@@ -603,6 +605,8 @@         , mapConName         , "Map_select"         , "Map_store"+        , "Map_union"+        , "Map_default"         , size32Name         , size64Name         , bitVecName
src/Language/Fixpoint/Types/Refinements.hs view
@@ -160,7 +160,9 @@ class HasGradual a where   isGradual :: a -> Bool   gVars     :: a -> [KVar]+  gVars _ = []    ungrad    :: a -> a+  ungrad x = x   instance HasGradual Expr where   isGradual (PGrad {}) = True@@ -278,6 +280,7 @@           | PAll   ![(Symbol, Sort)] !Expr           | PExist ![(Symbol, Sort)] !Expr           | PGrad  !KVar !Subst !GradInfo !Expr+          | ECoerc !Sort !Sort !Expr             deriving (Eq, Show, Data, Typeable, Generic)  type Pred = Expr@@ -339,7 +342,7 @@     go (PExist _ e)    = go e     go (PKVar _ _)     = 1     go (PGrad _ _ _ e) = go e-+    go (ECoerc _ _ e)  = go e  -- | Parsed refinement of @Symbol@ as @Expr@ --   e.g. in '{v: _ | e }' v is the @Symbol@ and e the @Expr@@@ -426,6 +429,7 @@   toFix (ETApp e s)      = text "tapp" <+> toFix e <+> toFix s   toFix (ETAbs e s)      = text "tabs" <+> toFix e <+> toFix s   toFix (PGrad k _ _ e)  = toFix e <+> text "&&" <+> toFix k -- text "??" -- <+> toFix k <+> toFix su+  toFix (ECoerc a t e)   = text "coerce" <+> toFix a <+> text "~" <+> toFix t <+> text "in" <+> toFix e -- text "??" -- <+> toFix k <+> toFix su   toFix (ELam (x,s) e)   = text "lam" <+> toFix x <+> ":" <+> toFix s <+> "." <+> toFix e    simplify (PAnd [])     = PTrue@@ -594,6 +598,7 @@   pprintPrec _ k (PAll xts p)    = pprintQuant k "forall" xts p   pprintPrec _ k (PExist xts p)  = pprintQuant k "exists" xts p   pprintPrec _ k (ELam (x,t) e)  = "lam" <+> toFix x <+> ":" <+> toFix t <+> text "." <+> pprintTidy k e+  pprintPrec _ k (ECoerc a t e)  = parens $ "coerce" <+> toFix a <+> "~" <+> toFix t <+> text "in" <+> pprintTidy k e   pprintPrec _ _ p@(PKVar {})    = toFix p   pprintPrec _ _ (ETApp e s)     = "ETApp" <+> toFix e <+> toFix s   pprintPrec _ _ (ETAbs e s)     = "ETAbs" <+> toFix e <+> toFix s
src/Language/Fixpoint/Types/Sorts.hs view
@@ -53,7 +53,7 @@   , mkFFunc   , bkFFunc -  , isNumeric, isReal, isString, isPolyInst +  , isNumeric, isReal, isString, isPolyInst    -- * User-defined ADTs   , DataField (..)@@ -81,7 +81,10 @@   data FTycon   = TC LocSymbol TCInfo deriving (Ord, Show, Data, Typeable, Generic)-type TCEmb a  = M.HashMap a FTycon+type TCEmb a  = M.HashMap a Sort -- FTycon++-- instance Show FTycon where+--   show (TC s _) = show (val s)  instance Symbolic FTycon where   symbol (TC s _) = symbol s
src/Language/Fixpoint/Types/Spans.hs view
@@ -16,10 +16,12 @@    -- * Constructing spans   , dummySpan+  , panicSpan   , locAt   , dummyLoc   , dummyPos   , atLoc+  , toSourcePos    -- * Destructing spans   , sourcePosElts@@ -173,8 +175,11 @@   srcSpan _ = dummySpan  dummySpan :: SrcSpan-dummySpan = SS l l-  where l = initialPos ""+dummySpan = panicSpan ""++panicSpan :: String -> SrcSpan+panicSpan s = SS l l+  where l = initialPos s  -- atLoc :: Located a -> b -> Located b -- atLoc (Loc l l' _) = Loc l l'
src/Language/Fixpoint/Types/Substitutions.hs view
@@ -39,10 +39,10 @@  mkSubst :: [(Symbol, Expr)] -> Subst -mkSubst = Su . M.fromList . reverse . filter notTrivial +mkSubst = Su . M.fromList . reverse . filter notTrivial   where     notTrivial (x, EVar y) = x /= y-    notTrivial _           = True  +    notTrivial _           = True  isEmptySubst :: Subst -> Bool isEmptySubst (Su xes) = M.null xes@@ -108,6 +108,7 @@   substa f                 = substf (EVar . f)   substf f (EApp s e)      = EApp (substf f s) (substf f e)   substf f (ELam x e)      = substfLam f x e+  substf f (ECoerc a t e)  = ECoerc a t (substf f e)   substf f (ENeg e)        = ENeg (substf f e)   substf f (EBin op e1 e2) = EBin op (substf f e1) (substf f e2)   substf f (EIte p e1 e2)  = EIte (substf f p) (substf f e1) (substf f e2)@@ -127,6 +128,7 @@    subst su (EApp f e)      = EApp (subst su f) (subst su e)   subst su (ELam x e)      = ELam x (subst (removeSubst su (fst x)) e)+  subst su (ECoerc a t e)  = ECoerc a t (subst su e)   subst su (ENeg e)        = ENeg (subst su e)   subst su (EBin op e1 e2) = EBin op (subst su e1) (subst su e2)   subst su (EIte p e1 e2)  = EIte (subst su p) (subst su e1) (subst su e2)@@ -268,6 +270,7 @@     go (EVar x)           = [x]     go (EApp f e)         = go f ++ go e     go (ELam (x,_) e)     = filter (/= x) (go e)+    go (ECoerc _ _ e)     = go e     go (ENeg e)           = go e     go (EBin _ e1 e2)     = go e1 ++ go e2     go (EIte p e1 e2)     = exprSymbols p ++ go e1 ++ go e2
src/Language/Fixpoint/Types/Visitor.hs view
@@ -172,6 +172,7 @@     step !c !(PAtom r e1 e2) = PAtom r     <$> vE c e1 <*> vE c e2     step !c !(PAll xts p)    = PAll   xts  <$> vE c p     step !c !(ELam (x,t) e)  = ELam (x,t)  <$> vE c e+    step !c !(ECoerc a t e)  = ECoerc a t  <$> vE c e     step !c !(PExist xts p)  = PExist xts  <$> vE c p     step !c !(ETApp e s)     = (`ETApp` s) <$> vE c e     step !c !(ETAbs e s)     = (`ETAbs` s) <$> vE c e@@ -220,6 +221,7 @@     go (ECst e t)      = f =<< ((`ECst` t)  <$>  go e                     )     go (PAll xts p)    = f =<< (PAll   xts  <$>  go p                     )     go (ELam (x,t) e)  = f =<< (ELam (x,t)  <$>  go e                     )+    go (ECoerc a t e)  = f =<< (ECoerc a t  <$>  go e                     )     go (PExist xts p)  = f =<< (PExist xts  <$>  go p                     )     go (ETApp e s)     = f =<< ((`ETApp` s) <$>  go e                     )     go (ETAbs e s)     = f =<< ((`ETAbs` s) <$>  go e                     )
+ tests/neg/maps.fq view
@@ -0,0 +1,37 @@++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 m1 10 1) 20 1) } +bind 3 m3 : {v : Map_t Int Int | v = (Map_store (Map_store m1 20 1) 10 1) } +bind 4 m4 : {v : Map_t Int Int | v = (Map_store m1 10 1) } +bind 5 m5 : {v : Map_t Int Int | v = (Map_store m1 20 1) } ++constraint:+  env [ 1 ]+  lhs {v : int | v = Map_select m1 100 }+  rhs {v : int | v = 0 } +  id 1 tag []++constraint:+  env [ 1; 2 ]+  lhs {v : int | v = Map_select m2 100 }+  rhs {v : int | v = 0 } +  id 2 tag []++constraint:+  env [ 1; 2 ]+  lhs {v : int | v = Map_select m2 10 }+  rhs {v : int | v = 1 } +  id 3 tag []++constraint:+  env [ 1; 2; 3 ]+  lhs {v : int | true }+  rhs {v : int | m2 = m3 } +  id 4 tag []++constraint:+  env [ 1; 2; 3; 4; 5 ]+  lhs {v : int | true }+  rhs {v : int | m2 = Map_union m4 m4 } +  id 5 tag []+
+ tests/pos/EqConstr0.fq view
@@ -0,0 +1,10 @@+ +bind 0 a : {v: int | true } +bind 1 x : {v: int | true } +bind 2 y : {v: a   | true } ++constraint:  +  env [0; 1; 2]+  lhs {v: int | x = y }+  rhs {v: Int | y = x }+  id 1 tag []
+ tests/pos/EqConstr1.fq view
@@ -0,0 +1,13 @@+data Thing 0 = [+  | mkCons { head : int } +]+  +bind 0 a : {v: Thing | true } +bind 1 x : {v: Thing | true } +bind 2 y : {v: a     | true } ++constraint:  +  env [0; 1; 2]+  lhs {v: int | x = y }+  rhs {v: Int | y = x }+  id 1 tag []
+ tests/pos/adt_pair_cast.fq view
@@ -0,0 +1,13 @@++data P 2 = [+   | P {pfst : @(0), psnd : @(1)}+   ]++bind 1 pig : {v : int  | true }+bind 2 dog : {v : bool | true }++constraint:+  env [1;2]+  lhs {v : int | psnd (P pig dog) }+  rhs {v:int | 12 = 4 + 8}+  id 1 tag []
+ tests/pos/coerce0.fq view
@@ -0,0 +1,12 @@+constant f : (func(1, [(Foo int); int]))++bind 1 pig : {v : (Foo a) | true }++bind 2 dog : {v : int | v = f (coerce (Foo a ~ Foo int) pig) }+++constraint:+  env [1;2]+  lhs {v : int | v = 10 }+  rhs {v : int | v = 5 + 5}+  id 1 tag []
+ tests/pos/coerce1.fq view
@@ -0,0 +1,11 @@+constant f : (func(1, [(Foo int); int]))++bind 1 pig : {v : (Foo a) | true }++bind 2 dog : {v : int | v = f (coerce (Foo a ~ Foo int) pig) }++constraint:+  env [1;2]+  lhs {v : int | v = 10 }+  rhs {v : int | v = 5 + 5}+  id 1 tag []
+ tests/pos/empty.fq view
@@ -0,0 +1,13 @@+// Config {srcFile = "/Users/rjhala/research/stack/liquidhaskell/tests/pos/lit00.hs", cores = Nothing, minPartSize = 500, maxPartSize = 700, solver = z3, linear = False, stringTheory = False, defunction = False, allowHO = False, allowHOqs = False, eliminate = some, elimBound = Nothing, elimStats = False, solverStats = False, metadata = False, stats = False, parts = False, save = True, minimize = False, minimizeQs = False, minimizeKs = False, minimalSol = False, gradual = False, ginteractive = False, extensionality = False, alphaEquivalence = False, betaEquivalence = False, normalForm = False, autoKuts = False, nonLinCuts = True, noslice = False, rewriteAxioms = True, arithmeticAxioms = False}++constant Zero : (Peano) +constant One  : (Peano) ++distinct Zero : (Peano) +distinct One  : (Peano) +++bind 0 xZero : {v : Peano | v = Zero } +bind 1 xOne  : {v : Peano | v = One  } ++
+ tests/pos/maps.fq view
@@ -0,0 +1,37 @@++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 m1 10 1) 20 1) } +bind 3 m3 : {v : Map_t Int Int | v = (Map_store (Map_store m1 20 1) 10 1) } +bind 4 m4 : {v : Map_t Int Int | v = (Map_store m1 10 1) } +bind 5 m5 : {v : Map_t Int Int | v = (Map_store m1 20 1) } ++constraint:+  env [ 1 ]+  lhs {v : int | v = Map_select m1 100 }+  rhs {v : int | v = 0 } +  id 1 tag []++constraint:+  env [ 1; 2 ]+  lhs {v : int | v = Map_select m2 100 }+  rhs {v : int | v = 0 } +  id 2 tag []++constraint:+  env [ 1; 2 ]+  lhs {v : int | v = Map_select m2 10 }+  rhs {v : int | v = 1 } +  id 3 tag []++constraint:+  env [ 1; 2; 3 ]+  lhs {v : int | true }+  rhs {v : int | m2 = m3 } +  id 4 tag []++constraint:+  env [ 1; 2; 3; 4; 5 ]+  lhs {v : int | true }+  rhs {v : int | m2 = Map_union m4 m5 } +  id 5 tag []+
tests/testParser.hs view
@@ -106,6 +106,10 @@      , testCase "FObj " $         show (doParse' sortP "test" "_foo") @?= "FObj \"_foo\""++    , testCase "Coerce0" $+        show (doParse' predP "test" "v = (coerce (a ~ int) (f x))")+          @?= "PAtom Eq (EVar \"v\") (ECoerc (FObj \"a\") FInt (EApp (EVar \"f\") (EVar \"x\")))"     ]  -- ---------------------------------------------------------------------