packages feed

liquid-fixpoint 0.9.6.3.3 → 0.9.6.3.4

raw patch · 129 files changed

+4184/−5364 lines, 129 filesdep +gitrevdep −parallelPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: gitrev

Dependencies removed: parallel

API changes (from Hackage documentation)

- Language.Fixpoint.Graph.Types: EBind :: !Symbol -> CVertex
- Language.Fixpoint.Horn.Types: Any :: !Bind a -> !Cstr a -> Cstr a
- Language.Fixpoint.Horn.Types: class ToHornSMT 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.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: type (|->) a b = HashMap a b
- Language.Fixpoint.Parse: instance Language.Fixpoint.Parse.Inputable (Language.Fixpoint.Types.Errors.FixResult GHC.Num.Integer.Integer, Language.Fixpoint.Types.Constraints.FixSolution)
- Language.Fixpoint.Smt.Interface: smtCheckSat :: Context -> Expr -> IO Bool
- Language.Fixpoint.Solver: type Solver a = Config -> FInfo a -> IO (Result (Integer, a))
- Language.Fixpoint.Solver.GradualSolution: init :: Fixpoint a => Config -> SInfo a -> [(KVar, (GWInfo, [Expr]))]
- Language.Fixpoint.Solver.GradualSolve: solveGradual :: (NFData a, Fixpoint a) => Config -> SInfo a -> IO (Result (Integer, a))
- Language.Fixpoint.Solver.Instantiate: instance GHC.Classes.Eq Language.Fixpoint.Solver.Instantiate.Recur
- Language.Fixpoint.Solver.Instantiate: instance GHC.Show.Show Language.Fixpoint.Solver.Instantiate.Recur
- Language.Fixpoint.Solver.Instantiate: instance Language.Fixpoint.Types.PrettyPrint.PPrint Language.Fixpoint.Solver.Instantiate.Recur
- Language.Fixpoint.Solver.Instantiate: instantiate :: Loc a => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)
- Language.Fixpoint.Solver.Monad: [ssBinds] :: SolverState ann -> !BindEnv ann
- Language.Fixpoint.Solver.Monad: checkSat :: Expr -> SolveM ann Bool
- Language.Fixpoint.Solver.Monad: filterValidGradual :: [Expr] -> Cand a -> SolveM ann [a]
- Language.Fixpoint.Solver.Monad: getBinds :: SolveM ann (BindEnv ann)
- Language.Fixpoint.Solver.PLE: [knContext] :: Knowledge -> Context
- Language.Fixpoint.Solver.PLE: instance GHC.Show.Show Language.Fixpoint.Solver.PLE.FinalExpand
- Language.Fixpoint.Solver.Solution: instance Language.Fixpoint.Types.Spans.Loc (Language.Fixpoint.Solver.Solution.CombinedEnv a)
- Language.Fixpoint.Solver.Solve: solverInfo :: Config -> SInfo a -> SolverInfo a b
- Language.Fixpoint.Types.Config: [ginteractive] :: Config -> Bool
- Language.Fixpoint.Types.Config: [gradual] :: Config -> Bool
- Language.Fixpoint.Types.Config: [inlineANFBindings] :: Config -> Bool
- Language.Fixpoint.Types.Config: [noEnvironmentReduction] :: Config -> Bool
- Language.Fixpoint.Types.Config: [noIncrPle] :: Config -> Bool
- Language.Fixpoint.Types.Config: [noLazyPLE] :: Config -> Bool
- Language.Fixpoint.Types.Config: [oldPLE] :: Config -> Bool
- Language.Fixpoint.Types.Config: [pleWithUndecidedGuards] :: Config -> Bool
- Language.Fixpoint.Types.Config: [rwTerminationCheck] :: Config -> Bool
- Language.Fixpoint.Types.Config: [stringTheory] :: Config -> Bool
- Language.Fixpoint.Types.Config: newtype ElabFlags
- Language.Fixpoint.Types.Constraints: GWInfo :: Symbol -> Sort -> Expr -> GradInfo -> GWInfo
- Language.Fixpoint.Types.Constraints: GWfC :: !IBindEnv -> !(Symbol, Sort, KVar) -> !a -> !Expr -> !GradInfo -> WfC a
- Language.Fixpoint.Types.Constraints: [ebinds] :: GInfo c a -> ![BindId]
- Language.Fixpoint.Types.Constraints: [gexpr] :: GWInfo -> Expr
- Language.Fixpoint.Types.Constraints: [ginfo] :: GWInfo -> GradInfo
- Language.Fixpoint.Types.Constraints: [gresSolution] :: Result a -> !GFixSolution
- Language.Fixpoint.Types.Constraints: [gsort] :: GWInfo -> Sort
- Language.Fixpoint.Types.Constraints: [gsym] :: GWInfo -> Symbol
- Language.Fixpoint.Types.Constraints: [wexpr] :: WfC a -> !Expr
- Language.Fixpoint.Types.Constraints: [wloc] :: WfC a -> !GradInfo
- Language.Fixpoint.Types.Constraints: data GWInfo
- Language.Fixpoint.Types.Constraints: gwInfo :: WfC a -> GWInfo
- Language.Fixpoint.Types.Constraints: instance Control.DeepSeq.NFData Language.Fixpoint.Types.Constraints.GFixSolution
- Language.Fixpoint.Types.Constraints: instance Control.DeepSeq.NFData Language.Fixpoint.Types.Constraints.GWInfo
- Language.Fixpoint.Types.Constraints: instance Data.Store.Impl.Store Language.Fixpoint.Types.Constraints.GFixSolution
- Language.Fixpoint.Types.Constraints: instance Data.Store.Impl.Store Language.Fixpoint.Types.Constraints.GWInfo
- Language.Fixpoint.Types.Constraints: instance GHC.Base.Functor Language.Fixpoint.Types.Constraints.GFixSol
- Language.Fixpoint.Types.Constraints: instance GHC.Base.Monoid (Language.Fixpoint.Types.Constraints.GFixSol e)
- Language.Fixpoint.Types.Constraints: instance GHC.Base.Semigroup (Language.Fixpoint.Types.Constraints.GFixSol e)
- Language.Fixpoint.Types.Constraints: instance GHC.Classes.Eq Language.Fixpoint.Types.Constraints.GWInfo
- Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic (Language.Fixpoint.Types.Constraints.GFixSol e)
- Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic Language.Fixpoint.Types.Constraints.GWInfo
- Language.Fixpoint.Types.Constraints: instance GHC.Show.Show Language.Fixpoint.Types.Constraints.GFixSolution
- Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.PrettyPrint.PPrint (Language.Fixpoint.Types.Constraints.QualifierV v)
- Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.PrettyPrint.PPrint Language.Fixpoint.Types.Constraints.GFixSolution
- 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: isGWfc :: WfC a -> Bool
- Language.Fixpoint.Types.Constraints: toGFixSol :: HashMap KVar (e, [e]) -> GFixSol e
- Language.Fixpoint.Types.Constraints: type GFixSolution = GFixSol Expr
- Language.Fixpoint.Types.Constraints: type Solver a = Config -> FInfo a -> IO (Result (Integer, a))
- Language.Fixpoint.Types.Constraints: updateWfCExpr :: (Expr -> Expr) -> WfC a -> WfC a
- Language.Fixpoint.Types.Graduals: class Gradual a
- Language.Fixpoint.Types.Graduals: data GSol
- Language.Fixpoint.Types.Graduals: gsubst :: Gradual a => ElabFlags -> GSol -> a -> a
- Language.Fixpoint.Types.Graduals: instance GHC.Base.Monoid Language.Fixpoint.Types.Graduals.GSol
- Language.Fixpoint.Types.Graduals: instance GHC.Base.Semigroup Language.Fixpoint.Types.Graduals.GSol
- Language.Fixpoint.Types.Graduals: instance GHC.Show.Show Language.Fixpoint.Types.Graduals.GSol
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual (Language.Fixpoint.Types.Constraints.SInfo a)
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual (Language.Fixpoint.Types.Constraints.SimpC a)
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual (Language.Fixpoint.Types.Environments.BindEnv a)
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual Language.Fixpoint.Types.Refinements.Expr
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual Language.Fixpoint.Types.Refinements.Reft
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual Language.Fixpoint.Types.Refinements.SortedReft
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Gradual v => Language.Fixpoint.Types.Graduals.Gradual (Data.HashMap.Internal.HashMap k v)
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Unique ann Language.Fixpoint.Types.Environments.BindId
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Unique ann Language.Fixpoint.Types.Environments.IBindEnv
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Unique ann Language.Fixpoint.Types.Refinements.Expr
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Unique ann Language.Fixpoint.Types.Refinements.Reft
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Unique ann Language.Fixpoint.Types.Refinements.SortedReft
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Graduals.Unique ann a => Language.Fixpoint.Types.Graduals.Unique ann (Data.HashMap.Internal.HashMap Language.Fixpoint.Types.Constraints.SubcId a)
- Language.Fixpoint.Types.Graduals: instance Language.Fixpoint.Types.Spans.Loc a => Language.Fixpoint.Types.Graduals.Unique a (Language.Fixpoint.Types.Constraints.SimpC a)
- Language.Fixpoint.Types.Graduals: makeSolutions :: (NFData a, Fixpoint a, Show a) => Config -> SInfo a -> [(KVar, (GWInfo, [[Expr]]))] -> Maybe [GSol]
- Language.Fixpoint.Types.Graduals: uniquify :: (NFData a, Fixpoint a, Loc a) => SInfo a -> SInfo a
- Language.Fixpoint.Types.Names: gradIntSymbol :: Integer -> Symbol
- Language.Fixpoint.Types.Refinements: GradInfo :: SrcSpan -> Maybe SrcSpan -> GradInfo
- Language.Fixpoint.Types.Refinements: PGrad :: !KVar -> !SubstV v -> !GradInfo -> !ExprV v -> ExprV v
- Language.Fixpoint.Types.Refinements: [gsrc] :: GradInfo -> SrcSpan
- Language.Fixpoint.Types.Refinements: [gused] :: GradInfo -> Maybe SrcSpan
- Language.Fixpoint.Types.Refinements: class HasGradual a
- Language.Fixpoint.Types.Refinements: data GradInfo
- Language.Fixpoint.Types.Refinements: gVars :: HasGradual a => a -> [KVar]
- Language.Fixpoint.Types.Refinements: instance Control.DeepSeq.NFData Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.FromJSON.FromJSON Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Data.Binary.Class.Binary Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Data.Data.Data Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Data.Hashable.Class.Hashable Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Data.Store.Impl.Store Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance GHC.Classes.Eq Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance GHC.Classes.Ord Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance GHC.Generics.Generic Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance GHC.Show.Show Language.Fixpoint.Types.Refinements.GradInfo
- Language.Fixpoint.Types.Refinements: instance Language.Fixpoint.Types.Refinements.HasGradual Language.Fixpoint.Types.Refinements.Expr
- Language.Fixpoint.Types.Refinements: instance Language.Fixpoint.Types.Refinements.HasGradual Language.Fixpoint.Types.Refinements.Reft
- Language.Fixpoint.Types.Refinements: instance Language.Fixpoint.Types.Refinements.HasGradual Language.Fixpoint.Types.Refinements.SortedReft
- Language.Fixpoint.Types.Refinements: isGradual :: HasGradual a => a -> Bool
- Language.Fixpoint.Types.Refinements: pGAnd :: (Fixpoint v, Ord v) => ExprV v -> ExprV v -> ExprV v
- Language.Fixpoint.Types.Refinements: pGAnds :: (Fixpoint v, Ord v) => [ExprV v] -> ExprV v
- Language.Fixpoint.Types.Refinements: srcGradInfo :: SourcePos -> GradInfo
- Language.Fixpoint.Types.Refinements: ungrad :: HasGradual a => a -> a
- Language.Fixpoint.Types.Solutions: EbDef :: [SimpC ()] -> Symbol -> EbindSol
- Language.Fixpoint.Types.Solutions: EbIncr :: EbindSol
- Language.Fixpoint.Types.Solutions: EbSol :: Expr -> EbindSol
- Language.Fixpoint.Types.Solutions: data EbindSol
- Language.Fixpoint.Types.Solutions: data GBind
- Language.Fixpoint.Types.Solutions: data QBind
- Language.Fixpoint.Types.Solutions: emptyGMap :: GSolution -> GSolution
- Language.Fixpoint.Types.Solutions: equalsGb :: [[EQual]] -> GBind
- Language.Fixpoint.Types.Solutions: fromList :: SymEnv -> [(KVar, a)] -> [(KVar, b)] -> [(KVar, Hyp)] -> HashMap KVar IBindEnv -> [(BindId, EbindSol)] -> SEnv (BindId, Sort) -> Sol a b
- Language.Fixpoint.Types.Solutions: gbEquals :: GBind -> [[EQual]]
- Language.Fixpoint.Types.Solutions: gbFilterM :: Monad m => ([EQual] -> m Bool) -> GBind -> m GBind
- Language.Fixpoint.Types.Solutions: gbToQbs :: GBind -> [QBind]
- Language.Fixpoint.Types.Solutions: glookup :: GSolution -> KVar -> Either Hyp (Either QBind (((Symbol, Sort), Expr), GBind))
- Language.Fixpoint.Types.Solutions: instance (Control.DeepSeq.NFData b, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Language.Fixpoint.Types.Solutions.Sol b a)
- Language.Fixpoint.Types.Solutions: instance (Language.Fixpoint.Types.PrettyPrint.PPrint a, Language.Fixpoint.Types.PrettyPrint.PPrint b) => Language.Fixpoint.Types.PrettyPrint.PPrint (Language.Fixpoint.Types.Solutions.Sol a b)
- Language.Fixpoint.Types.Solutions: instance Control.DeepSeq.NFData Language.Fixpoint.Types.Solutions.EbindSol
- Language.Fixpoint.Types.Solutions: instance Control.DeepSeq.NFData Language.Fixpoint.Types.Solutions.GBind
- Language.Fixpoint.Types.Solutions: instance Data.Data.Data Language.Fixpoint.Types.Solutions.GBind
- Language.Fixpoint.Types.Solutions: instance GHC.Base.Functor (Language.Fixpoint.Types.Solutions.Sol a)
- Language.Fixpoint.Types.Solutions: instance GHC.Base.Monoid (Language.Fixpoint.Types.Solutions.Sol a b)
- Language.Fixpoint.Types.Solutions: instance GHC.Base.Semigroup (Language.Fixpoint.Types.Solutions.Sol a b)
- Language.Fixpoint.Types.Solutions: instance GHC.Generics.Generic (Language.Fixpoint.Types.Solutions.Sol b a)
- Language.Fixpoint.Types.Solutions: instance GHC.Generics.Generic Language.Fixpoint.Types.Solutions.EbindSol
- Language.Fixpoint.Types.Solutions: instance GHC.Generics.Generic Language.Fixpoint.Types.Solutions.GBind
- Language.Fixpoint.Types.Solutions: instance GHC.Show.Show Language.Fixpoint.Types.Solutions.EbindSol
- Language.Fixpoint.Types.Solutions: instance GHC.Show.Show Language.Fixpoint.Types.Solutions.GBind
- Language.Fixpoint.Types.Solutions: instance Language.Fixpoint.Types.PrettyPrint.PPrint Language.Fixpoint.Types.Solutions.EbindSol
- Language.Fixpoint.Types.Solutions: qbToGb :: QBind -> GBind
- Language.Fixpoint.Types.Solutions: resultGradual :: GSolution -> HashMap KVar (Expr, [Expr])
- Language.Fixpoint.Types.Solutions: sHyp :: Sol b a -> HashMap KVar Hyp
- Language.Fixpoint.Types.Solutions: sScp :: Sol b a -> HashMap KVar IBindEnv
- Language.Fixpoint.Types.Solutions: type GSolution = Sol (((Symbol, Sort), Expr), GBind) QBind
- Language.Fixpoint.Types.Solutions: updateEbind :: Sol a b -> BindId -> Pred -> Sol a b
- Language.Fixpoint.Types.Solutions: updateGMap :: Sol b a -> HashMap KVar b -> Sol b a
- Language.Fixpoint.Types.Solutions: updateGMapWithKey :: [(KVar, QBind)] -> GSolution -> GSolution
- Language.Fixpoint.Types.Theories: symbolAtSmtName :: PPrint a => Symbol -> SymEnv -> a -> FuncSort -> Text
- Language.Fixpoint.Types.Visitor: mapGVars' :: Visitable t => ((KVar, Subst) -> Maybe Expr) -> t -> t
+ Control.Exception.Compat: ExceptionWithContext :: ExceptionContext -> a -> ExceptionWithContext a
+ Control.Exception.Compat: data ExceptionWithContext a
+ Control.Exception.Compat: displayExceptionContext :: ExceptionContext -> String
+ Control.Exception.Compat: wrapExceptionWithContext :: a -> ExceptionWithContext a
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT (Language.Fixpoint.Horn.Types.Bind a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT (Language.Fixpoint.Horn.Types.Cstr a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT (Language.Fixpoint.Horn.Types.Query a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT (Language.Fixpoint.Horn.Types.Var a)
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Horn.Types.Pred
+ Language.Fixpoint.Horn.Types: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Horn.Types.Tag
+ Language.Fixpoint.Misc: type a |-> b = HashMap a b
+ Language.Fixpoint.Parse: [allowExists] :: PStateV v -> !Bool
+ Language.Fixpoint.Parse: doParse'' :: Bool -> Parser a -> SourceName -> String -> a
+ Language.Fixpoint.Smt.Interface: Comment :: Text -> Command
+ Language.Fixpoint.Smt.Interface: [config] :: Context -> !Config
+ Language.Fixpoint.Smt.Interface: [ctxIxs] :: Context -> ![Int]
+ Language.Fixpoint.Smt.Interface: [ctxLams] :: Context -> !Bool
+ Language.Fixpoint.Smt.Interface: funcSortVars :: Bool -> SymEnv -> [(Text, ([SmtSort], SmtSort))]
+ Language.Fixpoint.Smt.Interface: smtAssertDecl :: HasCallStack => Expr -> SmtM ()
+ Language.Fixpoint.Smt.Interface: smtComment :: Text -> SmtM ()
+ Language.Fixpoint.Smt.Serialize: instance Language.Fixpoint.Smt.Types.SMTLIB2 (Language.Fixpoint.Types.Names.Symbol, Language.Fixpoint.Types.Refinements.Expr)
+ Language.Fixpoint.Smt.Theories: ffAdd :: IsString a => a
+ Language.Fixpoint.Smt.Theories: ffMul :: IsString a => a
+ Language.Fixpoint.Smt.Theories: ffVal :: IsString a => a
+ Language.Fixpoint.Smt.Theories: instance Language.Fixpoint.Types.Theories.TheorySymbols Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Smt.Theories: setCard :: IsString a => a
+ Language.Fixpoint.Smt.Types: Comment :: Text -> Command
+ Language.Fixpoint.Smt.Types: [config] :: Context -> !Config
+ Language.Fixpoint.Smt.Types: [ctxIxs] :: Context -> ![Int]
+ Language.Fixpoint.Smt.Types: [ctxLams] :: Context -> !Bool
+ Language.Fixpoint.Smt.Types: bracketSMT :: SmtM a -> (a -> IO b) -> (a -> SmtM c) -> SmtM c
+ Language.Fixpoint.Smt.Types: catchSMT :: Exception e => SmtM a -> (e -> IO a) -> SmtM a
+ Language.Fixpoint.Smt.Types: liftSym :: SymM a -> SmtM a
+ Language.Fixpoint.Smt.Types: type SmtM = StateT Context IO
+ Language.Fixpoint.Solver.Monad: [ssElabParam] :: SolverState ann -> !ElabParam
+ Language.Fixpoint.Solver.Monad: liftSMT :: SmtM a -> SolveM ann a
+ Language.Fixpoint.Solver.Monad: modifyContext :: (Context -> Context) -> SolveM ann ()
+ Language.Fixpoint.Solver.PLE: [icBindIds] :: ICtx -> IBindEnv
+ Language.Fixpoint.Solver.PLE: [icFreshExistentialCounter] :: ICtx -> Int
+ Language.Fixpoint.Solver.PLE: [icInitialLHSs] :: ICtx -> HashMap ExScope (HashSet Expr)
+ Language.Fixpoint.Solver.Solution: CEnv :: !Cid -> !BindEnv a -> !IBindEnv -> !SrcSpan -> !IBindEnv -> CombinedEnv a
+ Language.Fixpoint.Solver.Solution: [ceBEnv] :: CombinedEnv a -> !BindEnv a
+ Language.Fixpoint.Solver.Solution: [ceBindingsInSmt] :: CombinedEnv a -> !IBindEnv
+ Language.Fixpoint.Solver.Solution: [ceCid] :: CombinedEnv a -> !Cid
+ Language.Fixpoint.Solver.Solution: [ceIEnv] :: CombinedEnv a -> !IBindEnv
+ Language.Fixpoint.Solver.Solution: [ceSpan] :: CombinedEnv a -> !SrcSpan
+ Language.Fixpoint.Solver.Solution: alphaEq :: HashSet Symbol -> Expr -> Expr -> Bool
+ Language.Fixpoint.Solver.Solution: applyInSortedReft :: Config -> CombinedEnv ann -> Sol QBind -> (Symbol, SortedReft) -> (Symbol, SortedReft)
+ Language.Fixpoint.Solver.Solution: data CombinedEnv a
+ Language.Fixpoint.Solver.Solution: simplifyKVar :: HashSet Symbol -> Expr -> Expr
+ Language.Fixpoint.SortCheck: globalEnv :: forall (c :: Type -> Type) a. Config -> GInfo c a -> SEnv Sort
+ Language.Fixpoint.SortCheck: instance Language.Fixpoint.SortCheck.Elaborate Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.SortCheck: theoryEnv :: forall (c :: Type -> Type) a. Config -> GInfo c a -> SEnv TheorySymbol
+ Language.Fixpoint.SortCheck: unElabFSetBagZ3 :: Expr -> Expr
+ Language.Fixpoint.Types.Config: [elabExplicitKvars] :: ElabFlags -> Bool
+ Language.Fixpoint.Types.Config: [explicitKvars] :: Config -> Bool
+ Language.Fixpoint.Types.Config: [inlineANFBinds] :: Config -> Bool
+ Language.Fixpoint.Types.Config: [noEnvReduction] :: Config -> Bool
+ Language.Fixpoint.Types.Config: [noStringTheory] :: Config -> Bool
+ Language.Fixpoint.Types.Config: [pleUndecGuards] :: Config -> Bool
+ Language.Fixpoint.Types.Config: [rwTermination] :: Config -> Bool
+ Language.Fixpoint.Types.Config: data ElabFlags
+ Language.Fixpoint.Types.Config: mkElabFlags :: SMTSolver -> Bool -> ElabFlags
+ Language.Fixpoint.Types.Constraints: Delayed :: a -> Delayed a
+ Language.Fixpoint.Types.Constraints: MkDefinedFuns :: [Equation] -> DefinedFuns
+ Language.Fixpoint.Types.Constraints: [forceDelayed] :: Delayed a -> a
+ Language.Fixpoint.Types.Constraints: [resSorts] :: Result a -> !ResultSorts
+ Language.Fixpoint.Types.Constraints: data Delayed a
+ Language.Fixpoint.Types.Constraints: eqnToHornSMT :: Doc -> Equation -> Doc
+ Language.Fixpoint.Types.Constraints: instance (GHC.Classes.Ord v, Language.Fixpoint.Types.PrettyPrint.Fixpoint v, Language.Fixpoint.Types.PrettyPrint.PPrint v) => Language.Fixpoint.Types.PrettyPrint.PPrint (Language.Fixpoint.Types.Constraints.QualifierV v)
+ Language.Fixpoint.Types.Constraints: instance Control.DeepSeq.NFData Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Language.Fixpoint.Types.Constraints.Delayed a)
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON Language.Fixpoint.Types.Constraints.ScopedExpr
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Types.Constraints.KVarBind a)
+ Language.Fixpoint.Types.Constraints: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Language.Fixpoint.Types.Constraints.KVarMap a)
+ Language.Fixpoint.Types.Constraints: instance Data.Data.Data Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance Data.Store.Impl.Store Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Base.Functor Language.Fixpoint.Types.Constraints.Delayed
+ Language.Fixpoint.Types.Constraints: instance GHC.Base.Monoid Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Base.Semigroup Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Classes.Eq Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Classes.Ord Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic (Language.Fixpoint.Types.Constraints.Delayed a)
+ Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic (Language.Fixpoint.Types.Constraints.KVarBind a)
+ Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic (Language.Fixpoint.Types.Constraints.KVarMap a)
+ Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic Language.Fixpoint.Types.Constraints.ScopedExpr
+ Language.Fixpoint.Types.Constraints: instance GHC.Generics.Generic Language.Fixpoint.Types.Constraints.ScopedResult
+ Language.Fixpoint.Types.Constraints: instance GHC.Show.Show Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance GHC.Show.Show Language.Fixpoint.Types.Constraints.ScopedExpr
+ Language.Fixpoint.Types.Constraints: instance GHC.Show.Show Language.Fixpoint.Types.Constraints.ScopedResult
+ Language.Fixpoint.Types.Constraints: instance GHC.Show.Show a => GHC.Show.Show (Language.Fixpoint.Types.Constraints.Delayed a)
+ Language.Fixpoint.Types.Constraints: instance GHC.Show.Show a => GHC.Show.Show (Language.Fixpoint.Types.Constraints.KVarBind a)
+ Language.Fixpoint.Types.Constraints: instance GHC.Show.Show a => GHC.Show.Show (Language.Fixpoint.Types.Constraints.KVarMap a)
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.PrettyPrint.PPrint Language.Fixpoint.Types.Constraints.DefinedFuns
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Constraints.QualParam
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Constraints.Qualifier
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Constraints.Rewrite
+ Language.Fixpoint.Types.Constraints: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Constraints.ScopedExpr
+ Language.Fixpoint.Types.Constraints: newtype DefinedFuns
+ Language.Fixpoint.Types.Constraints: saveSInfo :: Fixpoint a => Config -> String -> SInfo a -> IO ()
+ Language.Fixpoint.Types.Constraints: type FixDelayedSolution = HashMap KVar Delayed Expr
+ Language.Fixpoint.Types.Constraints: type ResultSorts = HashMap KVar [(Symbol, Sort)]
+ Language.Fixpoint.Types.Names: bv16intName :: Symbol
+ Language.Fixpoint.Types.Names: bv8intName :: Symbol
+ Language.Fixpoint.Types.Names: ffldConName :: Symbol
+ Language.Fixpoint.Types.Names: intbv16Name :: Symbol
+ Language.Fixpoint.Types.Names: intbv8Name :: Symbol
+ Language.Fixpoint.Types.Names: renameSubstSymbol :: Symbol -> Int -> Symbol
+ Language.Fixpoint.Types.Refinements: ELet :: !Symbol -> !ExprV v -> !ExprV v -> ExprV v
+ Language.Fixpoint.Types.Refinements: instance Data.Aeson.Types.ToJSON.ToJSONKey Language.Fixpoint.Types.Refinements.KVar
+ Language.Fixpoint.Types.SMTPrint: class ToHornSMT a
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Names.Symbol
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Refinements.Expr
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Refinements.KVar
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Refinements.Subst
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Sorts.DataCtor
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Sorts.DataDecl
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Sorts.DataField
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Sorts.FTycon
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT Language.Fixpoint.Types.Sorts.Sort
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT a => Language.Fixpoint.Types.SMTPrint.ToHornSMT (Language.Fixpoint.Types.Names.Symbol, a)
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT a => Language.Fixpoint.Types.SMTPrint.ToHornSMT (Language.Fixpoint.Types.Spans.Located a)
+ Language.Fixpoint.Types.SMTPrint: instance Language.Fixpoint.Types.SMTPrint.ToHornSMT a => Language.Fixpoint.Types.SMTPrint.ToHornSMT [a]
+ Language.Fixpoint.Types.SMTPrint: toHornAbsApp :: Sort -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornAnd :: (a -> Doc) -> [a] -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornExpr :: Expr -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornFApp :: [Sort] -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornMany :: [Doc] -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornOp :: ToHornSMT a => Doc -> [a] -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornSMT :: ToHornSMT a => a -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornSort :: Sort -> Doc
+ Language.Fixpoint.Types.SMTPrint: toHornWithBinders :: (ToHornSMT a, ToHornSMT t) => Doc -> [(Symbol, t)] -> a -> Doc
+ Language.Fixpoint.Types.Solutions: QB :: [EQual] -> QBind
+ Language.Fixpoint.Types.Solutions: Sol :: !HashMap KVar a -> !HashMap KVar Hyp -> !HashMap KVar IBindEnv -> Sol a
+ Language.Fixpoint.Types.Solutions: [sHyp] :: Sol a -> !HashMap KVar Hyp
+ Language.Fixpoint.Types.Solutions: [sMap] :: Sol a -> !HashMap KVar a
+ Language.Fixpoint.Types.Solutions: [sScp] :: Sol a -> !HashMap KVar IBindEnv
+ Language.Fixpoint.Types.Solutions: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Language.Fixpoint.Types.Solutions.Sol a)
+ Language.Fixpoint.Types.Solutions: instance GHC.Base.Functor Language.Fixpoint.Types.Solutions.Sol
+ Language.Fixpoint.Types.Solutions: instance GHC.Base.Monoid (Language.Fixpoint.Types.Solutions.Sol a)
+ Language.Fixpoint.Types.Solutions: instance GHC.Base.Semigroup (Language.Fixpoint.Types.Solutions.Sol a)
+ Language.Fixpoint.Types.Solutions: instance GHC.Generics.Generic (Language.Fixpoint.Types.Solutions.Sol a)
+ Language.Fixpoint.Types.Solutions: instance Language.Fixpoint.Types.PrettyPrint.PPrint a => Language.Fixpoint.Types.PrettyPrint.PPrint (Language.Fixpoint.Types.Solutions.Sol a)
+ Language.Fixpoint.Types.Solutions: newtype QBind
+ Language.Fixpoint.Types.Sorts: FNatNum :: !Integer -> Sort
+ Language.Fixpoint.Types.Sorts: ffldFTyCon :: FTycon
+ Language.Fixpoint.Types.Sorts: finfieldSort :: Sort -> Sort
+ Language.Fixpoint.Types.Sorts: isFinfield :: Sort -> Bool
+ Language.Fixpoint.Types.Substitutions: extendSubst :: Subst -> Symbol -> Expr -> Subst
+ Language.Fixpoint.Types.Substitutions: rapierSubstExpr :: HashSet Symbol -> Subst -> Expr -> Expr
+ Language.Fixpoint.Types.Substitutions: substSymbolsSet :: Subst -> HashSet Symbol
+ Language.Fixpoint.Types.Theories: SFFld :: !Integer -> SmtSort
+ Language.Fixpoint.Types.Theories: [seApplsCur] :: SymEnv -> !HashMap FuncSort Int
+ Language.Fixpoint.Types.Theories: [seIx] :: SymEnv -> !Int
+ Language.Fixpoint.Types.Theories: coerceSort :: ElabFlags -> Sort -> Sort
+ Language.Fixpoint.Types.Theories: mergeTopAppls :: HashMap FuncSort Int -> Appls -> Appls
+ Language.Fixpoint.Types.Theories: peekAppls :: Appls -> Maybe (HashMap FuncSort Int)
+ Language.Fixpoint.Types.Theories: popAppls :: Appls -> Appls
+ Language.Fixpoint.Types.Theories: pushAppls :: Appls -> Appls
+ Language.Fixpoint.Types.Theories: symbolAtSortIndex :: Symbol -> Int -> Text
+ Language.Fixpoint.Types.Theories: type FuncSort = (SmtSort, SmtSort)
+ Language.Fixpoint.Types.Theories: type SymM a = State SymEnv a
+ Language.Fixpoint.Utils.Builder: quotes :: Builder -> Builder
+ Language.Fixpoint.Utils.Files: tempFileName :: FilePath -> FilePath
+ Language.Fixpoint.Utils.Progress: withProgressM :: (m a -> IO b) -> Int -> m a -> IO b
- Language.Fixpoint.Graph.Deps: decompose :: TaggedC c a => GInfo c a -> KVComps
+ Language.Fixpoint.Graph.Deps: decompose :: forall (c :: Type -> Type) a. TaggedC c a => GInfo c a -> KVComps
- Language.Fixpoint.Graph.Deps: elimDeps :: TaggedC c a => GInfo c a -> [CEdge] -> HashSet KVar -> HashSet Symbol -> CDeps
+ Language.Fixpoint.Graph.Deps: elimDeps :: forall (c :: Type -> Type) a. TaggedC c a => GInfo c a -> [CEdge] -> HashSet KVar -> CDeps
- Language.Fixpoint.Graph.Deps: elimVars :: TaggedC c a => Config -> GInfo c a -> ([CEdge], Elims KVar)
+ Language.Fixpoint.Graph.Deps: elimVars :: forall (c :: Type -> Type) a. TaggedC c a => Config -> GInfo c a -> ([CEdge], Elims KVar)
- Language.Fixpoint.Graph.Deps: graphStatistics :: TaggedC c a => Config -> GInfo c a -> IO ()
+ Language.Fixpoint.Graph.Deps: graphStatistics :: forall (c :: Type -> Type) a. TaggedC c a => Config -> GInfo c a -> IO ()
- Language.Fixpoint.Graph.Deps: kvEdges :: TaggedC c a => GInfo c a -> [CEdge]
+ Language.Fixpoint.Graph.Deps: kvEdges :: forall (c :: Type -> Type) a. TaggedC c a => GInfo c a -> [CEdge]
- Language.Fixpoint.Graph.Deps: slice :: TaggedC c a => Config -> GInfo c a -> GInfo c a
+ Language.Fixpoint.Graph.Deps: slice :: forall (c :: Type -> Type) a. TaggedC c a => Config -> GInfo c a -> GInfo c a
- Language.Fixpoint.Graph.Partition: CPart :: !HashMap KVar (WfC a) -> !HashMap Integer (c a) -> CPart c a
+ Language.Fixpoint.Graph.Partition: CPart :: !HashMap KVar (WfC a) -> !HashMap Integer (c a) -> CPart (c :: Type -> Type) a
- Language.Fixpoint.Graph.Partition: [pcm] :: CPart c a -> !HashMap Integer (c a)
+ Language.Fixpoint.Graph.Partition: [pcm] :: CPart (c :: Type -> Type) a -> !HashMap Integer (c a)
- Language.Fixpoint.Graph.Partition: [pws] :: CPart c a -> !HashMap KVar (WfC a)
+ Language.Fixpoint.Graph.Partition: [pws] :: CPart (c :: Type -> Type) a -> !HashMap KVar (WfC a)
- Language.Fixpoint.Graph.Partition: data CPart c a
+ Language.Fixpoint.Graph.Partition: data CPart (c :: Type -> Type) a
- Language.Fixpoint.Graph.Partition: dumpPartitions :: (Fixpoint (c a), Fixpoint a) => Config -> [GInfo c a] -> IO ()
+ Language.Fixpoint.Graph.Partition: dumpPartitions :: forall (c :: Type -> Type) a. (Fixpoint (c a), Fixpoint a) => Config -> [GInfo c a] -> IO ()
- Language.Fixpoint.Graph.Partition: partition :: (Fixpoint a, Fixpoint (c a), TaggedC c a) => Config -> GInfo c a -> IO (Result (Integer, a))
+ Language.Fixpoint.Graph.Partition: partition :: forall a (c :: Type -> Type). (Fixpoint a, Fixpoint (c a), TaggedC c a) => Config -> GInfo c a -> IO (Result (Integer, a))
- Language.Fixpoint.Graph.Partition: partition' :: TaggedC c a => Maybe MCInfo -> GInfo c a -> [GInfo c a]
+ Language.Fixpoint.Graph.Partition: partition' :: forall (c :: Type -> Type) a. TaggedC c a => Maybe MCInfo -> GInfo c a -> [GInfo c a]
- Language.Fixpoint.Graph.Partition: partitionN :: MCInfo -> GInfo c a -> [CPart c a] -> [GInfo c a]
+ Language.Fixpoint.Graph.Partition: partitionN :: forall (c :: Type -> Type) a. MCInfo -> GInfo c a -> [CPart c a] -> [GInfo c a]
- Language.Fixpoint.Graph.Reducible: isReducible :: TaggedC c a => GInfo c a -> Bool
+ Language.Fixpoint.Graph.Reducible: isReducible :: forall (c :: Type -> Type) a. TaggedC c a => GInfo c a -> Bool
- Language.Fixpoint.Graph.Types: SI :: !Sol b QBind -> !SInfo a -> !CDeps -> !HashSet KVar -> SolverInfo a b
+ Language.Fixpoint.Graph.Types: SI :: !Sol QBind -> !SInfo a -> !CDeps -> !HashSet KVar -> SolverInfo a
- Language.Fixpoint.Graph.Types: [siDeps] :: SolverInfo a b -> !CDeps
+ Language.Fixpoint.Graph.Types: [siDeps] :: SolverInfo a -> !CDeps
- Language.Fixpoint.Graph.Types: [siQuery] :: SolverInfo a b -> !SInfo a
+ Language.Fixpoint.Graph.Types: [siQuery] :: SolverInfo a -> !SInfo a
- Language.Fixpoint.Graph.Types: [siSol] :: SolverInfo a b -> !Sol b QBind
+ Language.Fixpoint.Graph.Types: [siSol] :: SolverInfo a -> !Sol QBind
- Language.Fixpoint.Graph.Types: [siVars] :: SolverInfo a b -> !HashSet KVar
+ Language.Fixpoint.Graph.Types: [siVars] :: SolverInfo a -> !HashSet KVar
- Language.Fixpoint.Graph.Types: data SolverInfo a b
+ Language.Fixpoint.Graph.Types: data SolverInfo a
- Language.Fixpoint.Horn.Types: Var :: !Symbol -> ![Symbol] -> Pred
+ Language.Fixpoint.Horn.Types: Var :: !Symbol -> ![Expr] -> Pred
- Language.Fixpoint.Parse: PState :: OpTable v -> [Fixity v] -> Maybe (Located () -> ExprV v) -> Maybe (Located () -> ExprV v -> ExprV v) -> !Integer -> LayoutStack -> !HashSet Symbol -> PStateV v
+ Language.Fixpoint.Parse: PState :: OpTable v -> [Fixity v] -> Maybe (Located () -> ExprV v) -> Maybe (Located () -> ExprV v -> ExprV v) -> !Integer -> LayoutStack -> !HashSet Symbol -> !Bool -> PStateV v
- Language.Fixpoint.Parse: type ParserV v = StateT (PStateV v) (Parsec Void String)
+ Language.Fixpoint.Parse: type ParserV v = StateT PStateV v Parsec Void String
- Language.Fixpoint.Smt.Interface: Ctx :: Solver -> ElabFlags -> IO () -> !Maybe Handle -> !Bool -> !SymEnv -> ![Equation] -> Context
+ Language.Fixpoint.Smt.Interface: Ctx :: Solver -> ElabFlags -> IO () -> !Maybe Handle -> !Bool -> !SymEnv -> ![Int] -> DefinedFuns -> !Bool -> !Config -> Context
- Language.Fixpoint.Smt.Interface: [ctxDefines] :: Context -> ![Equation]
+ Language.Fixpoint.Smt.Interface: [ctxDefines] :: Context -> DefinedFuns
- Language.Fixpoint.Smt.Interface: checkValid :: Config -> FilePath -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
+ Language.Fixpoint.Smt.Interface: checkValid :: HasCallStack => Config -> FilePath -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
- Language.Fixpoint.Smt.Interface: checkValid' :: Context -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
+ Language.Fixpoint.Smt.Interface: checkValid' :: HasCallStack => [(Symbol, Sort)] -> Expr -> Expr -> SmtM Bool
- Language.Fixpoint.Smt.Interface: checkValidWithContext :: Context -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool
+ Language.Fixpoint.Smt.Interface: checkValidWithContext :: HasCallStack => [(Symbol, Sort)] -> Expr -> Expr -> SmtM Bool
- Language.Fixpoint.Smt.Interface: command :: Context -> Command -> IO Response
+ Language.Fixpoint.Smt.Interface: command :: HasCallStack => Command -> SmtM Response
- Language.Fixpoint.Smt.Interface: makeContextWithSEnv :: Config -> FilePath -> SymEnv -> [Equation] -> IO Context
+ Language.Fixpoint.Smt.Interface: makeContextWithSEnv :: Config -> FilePath -> SymEnv -> DefinedFuns -> IO Context
- Language.Fixpoint.Smt.Interface: smt2 :: SMTLIB2 a => SymEnv -> a -> Builder
+ Language.Fixpoint.Smt.Interface: smt2 :: SMTLIB2 a => a -> SymM Builder
- Language.Fixpoint.Smt.Interface: smtAssert :: Context -> Expr -> IO ()
+ Language.Fixpoint.Smt.Interface: smtAssert :: Expr -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtAssertAxiom :: Context -> Triggered Expr -> IO ()
+ Language.Fixpoint.Smt.Interface: smtAssertAxiom :: Triggered Expr -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtBracket :: Context -> String -> IO a -> IO a
+ Language.Fixpoint.Smt.Interface: smtBracket :: String -> SmtM a -> SmtM a
- Language.Fixpoint.Smt.Interface: smtBracketAt :: SrcSpan -> Context -> String -> IO a -> IO a
+ Language.Fixpoint.Smt.Interface: smtBracketAt :: SrcSpan -> String -> SmtM a -> SmtM a
- Language.Fixpoint.Smt.Interface: smtCheckUnsat :: Context -> IO Bool
+ Language.Fixpoint.Smt.Interface: smtCheckUnsat :: HasCallStack => SmtM Bool
- Language.Fixpoint.Smt.Interface: smtDecl :: Context -> Symbol -> Sort -> IO ()
+ Language.Fixpoint.Smt.Interface: smtDecl :: Symbol -> Sort -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtDecls :: Context -> [(Symbol, Sort)] -> IO ()
+ Language.Fixpoint.Smt.Interface: smtDecls :: [(Symbol, Sort)] -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtDefineFunc :: Context -> Symbol -> [(Symbol, Sort)] -> Sort -> Expr -> IO ()
+ Language.Fixpoint.Smt.Interface: smtDefineFunc :: Symbol -> [(Symbol, Sort)] -> Sort -> Expr -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtDistinct :: Context -> [Expr] -> IO ()
+ Language.Fixpoint.Smt.Interface: smtDistinct :: [Expr] -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtFuncDecl :: Context -> Text -> ([SmtSort], SmtSort) -> IO ()
+ Language.Fixpoint.Smt.Interface: smtFuncDecl :: Text -> ([SmtSort], SmtSort) -> SmtM ()
- Language.Fixpoint.Smt.Interface: smtPop :: Context -> IO ()
+ Language.Fixpoint.Smt.Interface: smtPop :: SmtM ()
- Language.Fixpoint.Smt.Interface: smtPush :: Context -> IO ()
+ Language.Fixpoint.Smt.Interface: smtPush :: SmtM ()
- Language.Fixpoint.Smt.Interface: smtSetMbqi :: Context -> IO ()
+ Language.Fixpoint.Smt.Interface: smtSetMbqi :: SmtM ()
- Language.Fixpoint.Smt.Serialize: smt2SortMono :: PPrint a => a -> SymEnv -> Sort -> Builder
+ Language.Fixpoint.Smt.Serialize: smt2SortMono :: PPrint a => a -> Sort -> SymM Builder
- Language.Fixpoint.Smt.Theories: axiomLiterals :: [(Symbol, Sort)] -> [Expr]
+ Language.Fixpoint.Smt.Theories: axiomLiterals :: Config -> [(Symbol, Sort)] -> [Expr]
- Language.Fixpoint.Smt.Theories: smt2App :: VarAs -> SymEnv -> Expr -> [Builder] -> Maybe Builder
+ Language.Fixpoint.Smt.Theories: smt2App :: VarAs -> Expr -> [Builder] -> SymM (Maybe Builder)
- Language.Fixpoint.Smt.Types: Ctx :: Solver -> ElabFlags -> IO () -> !Maybe Handle -> !Bool -> !SymEnv -> ![Equation] -> Context
+ Language.Fixpoint.Smt.Types: Ctx :: Solver -> ElabFlags -> IO () -> !Maybe Handle -> !Bool -> !SymEnv -> ![Int] -> DefinedFuns -> !Bool -> !Config -> Context
- Language.Fixpoint.Smt.Types: [ctxDefines] :: Context -> ![Equation]
+ Language.Fixpoint.Smt.Types: [ctxDefines] :: Context -> DefinedFuns
- Language.Fixpoint.Smt.Types: runSmt2 :: SMTLIB2 a => SymEnv -> a -> Builder
+ Language.Fixpoint.Smt.Types: runSmt2 :: SMTLIB2 a => a -> SymM Builder
- Language.Fixpoint.Smt.Types: smt2 :: SMTLIB2 a => SymEnv -> a -> Builder
+ Language.Fixpoint.Smt.Types: smt2 :: SMTLIB2 a => a -> SymM Builder
- Language.Fixpoint.Solver: simplifyFInfo :: (NFData a, Fixpoint a, Show a, Loc a) => Config -> FInfo a -> IO (SInfo a)
+ Language.Fixpoint.Solver: simplifyFInfo :: (NFData a, Fixpoint a, Show a, Loc a) => Config -> FInfo a -> IO (ElabParam, SInfo a)
- Language.Fixpoint.Solver: solve :: (PPrint a, NFData a, Fixpoint a, Show a, Loc a) => Solver a
+ Language.Fixpoint.Solver: solve :: (PPrint a, NFData a, Fixpoint a, Show a, Loc a) => Config -> FInfo a -> IO (Result (Integer, a))
- Language.Fixpoint.Solver.Common: askSMT :: Config -> Context -> [(Symbol, Sort)] -> Expr -> IO Bool
+ Language.Fixpoint.Solver.Common: askSMT :: HasCallStack => Config -> [(Symbol, Sort)] -> [(Symbol, Sort)] -> Expr -> SmtM Bool
- Language.Fixpoint.Solver.Common: toSMT :: String -> Config -> Context -> [(Symbol, Sort)] -> Expr -> Pred
+ Language.Fixpoint.Solver.Common: toSMT :: HasCallStack => String -> Config -> Context -> [(Symbol, Sort)] -> Expr -> Pred
- Language.Fixpoint.Solver.Eliminate: solverInfo :: Config -> SInfo a -> SolverInfo a b
+ Language.Fixpoint.Solver.Eliminate: solverInfo :: Config -> SInfo a -> SolverInfo a
- Language.Fixpoint.Solver.Interpreter: instInterpreter :: Loc a => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)
+ Language.Fixpoint.Solver.Interpreter: instInterpreter :: Loc a => Config -> SInfo a -> Maybe [SubcId] -> IO (BindEnv a)
- Language.Fixpoint.Solver.Monad: SS :: !Context -> !BindEnv ann -> !Stats -> SolverState ann
+ Language.Fixpoint.Solver.Monad: SS :: !Context -> !Stats -> !ElabParam -> SolverState ann
- Language.Fixpoint.Solver.Monad: runSolverM :: Config -> SolverInfo ann c -> SolveM ann a -> IO a
+ Language.Fixpoint.Solver.Monad: runSolverM :: Config -> SolverInfo ann -> ElabParam -> SolveM ann a -> IO a
- Language.Fixpoint.Solver.Monad: sendConcreteBindingsToSMT :: IBindEnv -> (IBindEnv -> SolveM ann a) -> SolveM ann a
+ Language.Fixpoint.Solver.Monad: sendConcreteBindingsToSMT :: IBindEnv -> BindEnv ann -> (IBindEnv -> SolveM ann a) -> SolveM ann a
- Language.Fixpoint.Solver.Monad: type SolveM ann = StateT (SolverState ann) IO
+ Language.Fixpoint.Solver.Monad: type SolveM ann = StateT SolverState ann IO
- Language.Fixpoint.Solver.PLE: ICtx :: HashSet Pred -> HashSet Expr -> EvEqualities -> !ConstMap -> Maybe SubcId -> [[(Symbol, SortedReft)]] -> LocalRewrites -> Bool -> Bool -> Bool -> ICtx
+ Language.Fixpoint.Solver.PLE: ICtx :: HashSet Pred -> HashMap ExScope (HashSet Expr) -> HashMap ExScope EvEqualities -> !ConstMap -> Maybe SubcId -> [[(Symbol, SortedReft)]] -> LocalRewrites -> IBindEnv -> Bool -> Bool -> Bool -> Int -> HashMap ExScope (HashSet Expr) -> ICtx
- Language.Fixpoint.Solver.PLE: KN :: Map Symbol [(Rewrite, IsUserDataSMeasure)] -> Map Symbol Equation -> Context -> (Context -> [(Symbol, Sort)] -> Expr -> IO Bool) -> ![(Symbol, Sort)] -> ![(Symbol, Int)] -> !HashSet Symbol -> !HashMap Symbol DataCtor -> !SelectorMap -> !ConstDCMap -> HashMap SubcId [AutoRewrite] -> RWTerminationOpts -> Knowledge
+ Language.Fixpoint.Solver.PLE: KN :: Map Symbol [(Rewrite, IsUserDataSMeasure)] -> Map Symbol Equation -> ([(Symbol, Sort)] -> [(Symbol, Sort)] -> Expr -> SmtM Bool) -> ![(Symbol, Sort)] -> ![(Symbol, Int)] -> !HashSet Symbol -> !HashMap Symbol DataCtor -> !SelectorMap -> !ConstDCMap -> HashMap SubcId [AutoRewrite] -> RWTerminationOpts -> Knowledge
- Language.Fixpoint.Solver.PLE: [icCands] :: ICtx -> HashSet Expr
+ Language.Fixpoint.Solver.PLE: [icCands] :: ICtx -> HashMap ExScope (HashSet Expr)
- Language.Fixpoint.Solver.PLE: [icEquals] :: ICtx -> EvEqualities
+ Language.Fixpoint.Solver.PLE: [icEquals] :: ICtx -> HashMap ExScope EvEqualities
- Language.Fixpoint.Solver.PLE: [knPreds] :: Knowledge -> Context -> [(Symbol, Sort)] -> Expr -> IO Bool
+ Language.Fixpoint.Solver.PLE: [knPreds] :: Knowledge -> [(Symbol, Sort)] -> [(Symbol, Sort)] -> Expr -> SmtM Bool
- Language.Fixpoint.Solver.PLE: instantiate :: Loc a => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)
+ Language.Fixpoint.Solver.PLE: instantiate :: Loc a => Config -> SInfo a -> Maybe Solution -> Maybe [SubcId] -> SmtM (BindEnv a)
- Language.Fixpoint.Solver.Rewrite: RWArgs :: (Expr -> IO Bool) -> RWTerminationOpts -> RewriteArgs
+ Language.Fixpoint.Solver.Rewrite: RWArgs :: (Expr -> SmtM Bool) -> RWTerminationOpts -> RewriteArgs
- Language.Fixpoint.Solver.Rewrite: [isRWValid] :: RewriteArgs -> Expr -> IO Bool
+ Language.Fixpoint.Solver.Rewrite: [isRWValid] :: RewriteArgs -> Expr -> SmtM Bool
- Language.Fixpoint.Solver.Rewrite: getRewrite :: OCAlgebra oc Expr IO -> RewriteArgs -> oc -> SubExpr -> AutoRewrite -> MaybeT IO ((Expr, Expr), Expr, oc)
+ Language.Fixpoint.Solver.Rewrite: getRewrite :: OCAlgebra oc Expr IO -> RewriteArgs -> oc -> SubExpr -> AutoRewrite -> MaybeT SmtM ((Expr, Expr), Expr, oc)
- Language.Fixpoint.Solver.Sanitize: symbolEnv :: Config -> SInfo a -> SymEnv
+ Language.Fixpoint.Solver.Sanitize: symbolEnv :: HasCallStack => Config -> SInfo a -> SymEnv
- Language.Fixpoint.Solver.Solution: init :: Fixpoint a => Config -> SInfo a -> HashSet KVar -> Solution
+ Language.Fixpoint.Solver.Solution: init :: Fixpoint a => Config -> SInfo a -> HashSet KVar -> HashMap KVar QBind
- Language.Fixpoint.Solver.Solution: lhsPred :: Loc a => IBindEnv -> BindEnv a -> Solution -> SimpC a -> ElabM Expr
+ Language.Fixpoint.Solver.Solution: lhsPred :: Loc a => Config -> IBindEnv -> BindEnv a -> Solution -> SimpC a -> Expr
- Language.Fixpoint.Solver.Solution: nonCutsResult :: BindEnv ann -> Sol a QBind -> ElabM (HashMap KVar Expr)
+ Language.Fixpoint.Solver.Solution: nonCutsResult :: Config -> BindEnv ann -> Sol QBind -> FixDelayedSolution
- Language.Fixpoint.Solver.Solution: update :: Sol a QBind -> [KVar] -> [(KVar, EQual)] -> (Bool, Sol a QBind)
+ Language.Fixpoint.Solver.Solution: update :: Sol QBind -> [(KVar, QBind)] -> (Bool, Sol QBind)
- Language.Fixpoint.Solver.Solve: solve :: (NFData a, Fixpoint a, Show a, Loc a) => Config -> SInfo a -> IO (Result (Integer, a))
+ Language.Fixpoint.Solver.Solve: solve :: (NFData a, Fixpoint a, Show a, Loc a) => Config -> ElabParam -> SInfo a -> IO (Result (Integer, a))
- Language.Fixpoint.Solver.Worklist: init :: SolverInfo a b -> Worklist a
+ Language.Fixpoint.Solver.Worklist: init :: SolverInfo a -> Worklist a
- Language.Fixpoint.SortCheck: elabExpr :: ElabParam -> Maybe Sort -> Expr -> Expr
+ Language.Fixpoint.SortCheck: elabExpr :: HasCallStack => ElabParam -> Maybe Sort -> Expr -> Expr
- 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 -> Bool -> Bool -> [Integer] -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> String -> Bool -> Config
+ Language.Fixpoint.Types.Config: Config :: FilePath -> Maybe Int -> Int -> Int -> SMTSolver -> 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 -> [Integer] -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> String -> Bool -> Bool -> Bool -> Config
- Language.Fixpoint.Types.Config: ElabFlags :: Bool -> ElabFlags
+ Language.Fixpoint.Types.Config: ElabFlags :: Bool -> Bool -> ElabFlags
- Language.Fixpoint.Types.Config: solverFlags :: SMTSolver -> ElabFlags
+ Language.Fixpoint.Types.Config: solverFlags :: Config -> ElabFlags
- Language.Fixpoint.Types.Constraints: FI :: !HashMap SubcId (c a) -> !HashMap KVar (WfC a) -> !BindEnv a -> ![BindId] -> !SEnv Sort -> !SEnv Sort -> !Kuts -> ![Qualifier] -> !HashMap BindId a -> ![DataDecl] -> !HOInfo -> ![Triggered Expr] -> AxiomEnv -> LocalRewritesEnv -> ![Equation] -> GInfo c a
+ Language.Fixpoint.Types.Constraints: FI :: !HashMap SubcId (c a) -> !HashMap KVar (WfC a) -> !BindEnv a -> !SEnv Sort -> !SEnv Sort -> !Kuts -> ![Qualifier] -> !HashMap BindId a -> ![DataDecl] -> !HOInfo -> ![Triggered Expr] -> AxiomEnv -> LocalRewritesEnv -> DefinedFuns -> GInfo (c :: Type -> Type) a
- Language.Fixpoint.Types.Constraints: Result :: !FixResult a -> !FixSolution -> !FixSolution -> !GFixSolution -> Result a
+ Language.Fixpoint.Types.Constraints: Result :: !FixResult a -> !FixSolution -> !FixDelayedSolution -> !ResultSorts -> Result a
- Language.Fixpoint.Types.Constraints: [ae] :: GInfo c a -> AxiomEnv
+ Language.Fixpoint.Types.Constraints: [ae] :: GInfo (c :: Type -> Type) a -> AxiomEnv
- Language.Fixpoint.Types.Constraints: [asserts] :: GInfo c a -> ![Triggered Expr]
+ Language.Fixpoint.Types.Constraints: [asserts] :: GInfo (c :: Type -> Type) a -> ![Triggered Expr]
- Language.Fixpoint.Types.Constraints: [bindInfo] :: GInfo c a -> !HashMap BindId a
+ Language.Fixpoint.Types.Constraints: [bindInfo] :: GInfo (c :: Type -> Type) a -> !HashMap BindId a
- Language.Fixpoint.Types.Constraints: [bs] :: GInfo c a -> !BindEnv a
+ Language.Fixpoint.Types.Constraints: [bs] :: GInfo (c :: Type -> Type) a -> !BindEnv a
- Language.Fixpoint.Types.Constraints: [cm] :: GInfo c a -> !HashMap SubcId (c a)
+ Language.Fixpoint.Types.Constraints: [cm] :: GInfo (c :: Type -> Type) a -> !HashMap SubcId (c a)
- Language.Fixpoint.Types.Constraints: [dLits] :: GInfo c a -> !SEnv Sort
+ Language.Fixpoint.Types.Constraints: [dLits] :: GInfo (c :: Type -> Type) a -> !SEnv Sort
- Language.Fixpoint.Types.Constraints: [ddecls] :: GInfo c a -> ![DataDecl]
+ Language.Fixpoint.Types.Constraints: [ddecls] :: GInfo (c :: Type -> Type) a -> ![DataDecl]
- Language.Fixpoint.Types.Constraints: [defns] :: GInfo c a -> ![Equation]
+ Language.Fixpoint.Types.Constraints: [defns] :: GInfo (c :: Type -> Type) a -> DefinedFuns
- Language.Fixpoint.Types.Constraints: [gLits] :: GInfo c a -> !SEnv Sort
+ Language.Fixpoint.Types.Constraints: [gLits] :: GInfo (c :: Type -> Type) a -> !SEnv Sort
- Language.Fixpoint.Types.Constraints: [hoInfo] :: GInfo c a -> !HOInfo
+ Language.Fixpoint.Types.Constraints: [hoInfo] :: GInfo (c :: Type -> Type) a -> !HOInfo
- Language.Fixpoint.Types.Constraints: [kuts] :: GInfo c a -> !Kuts
+ Language.Fixpoint.Types.Constraints: [kuts] :: GInfo (c :: Type -> Type) a -> !Kuts
- Language.Fixpoint.Types.Constraints: [lrws] :: GInfo c a -> LocalRewritesEnv
+ Language.Fixpoint.Types.Constraints: [lrws] :: GInfo (c :: Type -> Type) a -> LocalRewritesEnv
- Language.Fixpoint.Types.Constraints: [quals] :: GInfo c a -> ![Qualifier]
+ Language.Fixpoint.Types.Constraints: [quals] :: GInfo (c :: Type -> Type) a -> ![Qualifier]
- Language.Fixpoint.Types.Constraints: [resNonCutsSolution] :: Result a -> !FixSolution
+ Language.Fixpoint.Types.Constraints: [resNonCutsSolution] :: Result a -> !FixDelayedSolution
- Language.Fixpoint.Types.Constraints: [wrft] :: WfC a -> !(Symbol, Sort, KVar)
+ Language.Fixpoint.Types.Constraints: [wrft] :: WfC a -> (Symbol, Sort, KVar)
- Language.Fixpoint.Types.Constraints: [ws] :: GInfo c a -> !HashMap KVar (WfC a)
+ Language.Fixpoint.Types.Constraints: [ws] :: GInfo (c :: Type -> Type) a -> !HashMap KVar (WfC a)
- Language.Fixpoint.Types.Constraints: allowHO :: GInfo c a -> Bool
+ Language.Fixpoint.Types.Constraints: allowHO :: forall (c :: Type -> Type) a. GInfo c a -> Bool
- Language.Fixpoint.Types.Constraints: allowHOquals :: GInfo c a -> Bool
+ Language.Fixpoint.Types.Constraints: allowHOquals :: forall (c :: Type -> Type) a. GInfo c a -> Bool
- Language.Fixpoint.Types.Constraints: class TaggedC c a
+ Language.Fixpoint.Types.Constraints: class TaggedC (c :: Type -> Type) a
- Language.Fixpoint.Types.Constraints: data GInfo c a
+ Language.Fixpoint.Types.Constraints: data GInfo (c :: Type -> Type) a
- Language.Fixpoint.Types.Constraints: fi :: [SubC a] -> [WfC a] -> BindEnv a -> SEnv Sort -> SEnv Sort -> Kuts -> [Qualifier] -> HashMap BindId a -> Bool -> Bool -> [Triggered Expr] -> AxiomEnv -> [DataDecl] -> [BindId] -> GInfo SubC a
+ Language.Fixpoint.Types.Constraints: fi :: [SubC a] -> [WfC a] -> BindEnv a -> SEnv Sort -> SEnv Sort -> Kuts -> [Qualifier] -> HashMap BindId a -> Bool -> Bool -> [Triggered Expr] -> AxiomEnv -> [DataDecl] -> GInfo SubC a
- Language.Fixpoint.Types.Constraints: strengthenBinds :: SInfo a -> HashMap BindId Expr -> SInfo a
+ Language.Fixpoint.Types.Constraints: strengthenBinds :: SInfo a -> HashMap BindId Expr -> BindEnv a
- Language.Fixpoint.Types.Constraints: strengthenHyp :: SInfo a -> [(Integer, Expr)] -> SInfo a
+ Language.Fixpoint.Types.Constraints: strengthenHyp :: SInfo a -> [(Integer, Expr)] -> BindEnv a
- Language.Fixpoint.Types.Constraints: toFixpoint :: (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> Doc
+ Language.Fixpoint.Types.Constraints: toFixpoint :: forall a (c :: Type -> Type). (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> Doc
- Language.Fixpoint.Types.Constraints: writeFInfo :: (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> FilePath -> IO ()
+ Language.Fixpoint.Types.Constraints: writeFInfo :: forall a (c :: Type -> Type). (Fixpoint a, Fixpoint (c a)) => Config -> GInfo c a -> FilePath -> IO ()
- Language.Fixpoint.Types.Errors: die :: Error -> a
+ Language.Fixpoint.Types.Errors: die :: HasCallStack => Error -> a
- Language.Fixpoint.Types.Errors: panic :: String -> a
+ Language.Fixpoint.Types.Errors: panic :: HasCallStack => String -> a
- Language.Fixpoint.Types.Solutions: data Sol b a
+ Language.Fixpoint.Types.Solutions: data Sol a
- Language.Fixpoint.Types.Solutions: lookup :: Sol a QBind -> KVar -> Either Hyp QBind
+ Language.Fixpoint.Types.Solutions: lookup :: Sol QBind -> KVar -> Either Hyp QBind
- Language.Fixpoint.Types.Solutions: lookupQBind :: Sol a QBind -> KVar -> QBind
+ Language.Fixpoint.Types.Solutions: lookupQBind :: Sol QBind -> KVar -> QBind
- Language.Fixpoint.Types.Solutions: qbPreds :: String -> Sol a QBind -> Subst -> QBind -> ElabM [(Pred, EQual)]
+ Language.Fixpoint.Types.Solutions: qbPreds :: Subst -> QBind -> [(Pred, EQual)]
- Language.Fixpoint.Types.Solutions: result :: Sol a QBind -> HashMap KVar Expr
+ Language.Fixpoint.Types.Solutions: result :: Sol QBind -> HashMap KVar Expr
- Language.Fixpoint.Types.Solutions: type Solution = Sol () QBind
+ Language.Fixpoint.Types.Solutions: type Solution = Sol QBind
- Language.Fixpoint.Types.Solutions: update :: Sol a QBind -> [KVar] -> [(KVar, EQual)] -> (Bool, Sol a QBind)
+ Language.Fixpoint.Types.Solutions: update :: Sol QBind -> [(KVar, QBind)] -> (Bool, Sol QBind)
- Language.Fixpoint.Types.Spans: data () => Pos
+ Language.Fixpoint.Types.Spans: data Pos
- Language.Fixpoint.Types.Spans: data () => SourcePos
+ Language.Fixpoint.Types.Spans: data SourcePos
- Language.Fixpoint.Types.Theories: SymEnv :: !SEnv Sort -> !SEnv TheorySymbol -> !SEnv DataDecl -> !SEnv Sort -> !HashMap FuncSort Int -> SymEnv
+ Language.Fixpoint.Types.Theories: SymEnv :: !SEnv Sort -> !SEnv TheorySymbol -> !SEnv DataDecl -> !SEnv Sort -> !Appls -> !HashMap FuncSort Int -> !Int -> SymEnv
- Language.Fixpoint.Types.Theories: [seAppls] :: SymEnv -> !HashMap FuncSort Int
+ Language.Fixpoint.Types.Theories: [seAppls] :: SymEnv -> !Appls
- Language.Fixpoint.Types.Theories: symbolAtName :: PPrint a => Symbol -> SymEnv -> a -> Sort -> Text
+ Language.Fixpoint.Types.Theories: symbolAtName :: Symbol -> Sort -> SymM Text
- Language.Fixpoint.Types.Utils: kvarDomain :: SInfo a -> KVar -> [Symbol]
+ Language.Fixpoint.Types.Utils: kvarDomain :: forall (c :: Type -> Type) a. GInfo c a -> KVar -> [Symbol]
- Language.Fixpoint.Types.Utils: sortedReftConcKVars :: Symbol -> SortedReft -> ([Pred], [KVSub], [KVSub])
+ Language.Fixpoint.Types.Utils: sortedReftConcKVars :: Symbol -> SortedReft -> ([Pred], [KVSub])
- Text.PrettyPrint.HughesPJ.Compat: data () => Doc
+ Text.PrettyPrint.HughesPJ.Compat: data Doc
- Text.PrettyPrint.HughesPJ.Compat: data () => Mode
+ Text.PrettyPrint.HughesPJ.Compat: data Mode
- Text.PrettyPrint.HughesPJ.Compat: data () => Style
+ Text.PrettyPrint.HughesPJ.Compat: data Style
- Text.PrettyPrint.HughesPJ.Compat: data () => TextDetails
+ Text.PrettyPrint.HughesPJ.Compat: data TextDetails

Files

CHANGES.md view
@@ -2,6 +2,35 @@  ## NEXT +## 0.9.6.3.4 (2026-01-14)++- Implement `--sortedsolution` to keep elaborated sorts in fqout/solution [#821](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/821)+- Retire old parser for horn queries [#820](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/820)+- Stop the parser from simplifying expressions during parsing [#819](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/819)+- Add `--explicitKvars` option and generalize horn syntax to accept expressions for kvars arguments [#818](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/818)+- Provide more comments in the SMT queries to relate them to the source code [#814](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/814)+- Remove `--no-lazy-ple` [#813](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/813)+- Allow PLE to unfold in kvar solutions  [#811](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/811)+- Remove redundant question marks from expression [#807](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/807)+- Remove distinction of predicates and expressions in the parser [#805](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/805)+- Shrink kvar solutions [#799](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/799) [#809](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/809) [#821](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/821)+- Disable the progress bar when not on a terminal [#798](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/798)+- Retire existential binds [#797](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/797)+- Provide stack traces for more crashes [#794](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/794)+- Support string operators [#793](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/793)+- Apply kvar solutions to constraints before PLE [#792](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/792)+- Retire implementation of gradual refinement types [#789](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/789)+- Retire old PLE variations [#788](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/788)+- Add set cardinality support when using cvc5 [#774](https:://github.com/ucsd-progsys/liquid-fixpoint/pull/774)+- Have `--scrape` consider global constants and ADTs [#772](https://github.com/ucsd-progsys/liquid-fixpoint/pull/772)+- Shorten flags of a few flags and add git-version [#762](https://github.com/ucsd-progsys/liquid-fixpoint/pull/762)+- Add support/conversions for Bitv8 and Bitv16 [#759](https://github.com/ucsd-progsys/liquid-fixpoint/pull/759)+- Support the finite field theory of CVC5 [#755](https://github.com/ucsd-progsys/liquid-fixpoint/pull/755)+- Fix SMT crashes on reflected functions on polymorphic data types [#753](https://github.com/ucsd-progsys/liquid-fixpoint/pull/753)+- Allow function names to start with prefix mod [#751](https://github.com/ucsd-progsys/liquid-fixpoint/pull/751)+- Implement let bindings for Horn queries [#748](https://github.com/ucsd-progsys/liquid-fixpoint/pull/748)+- Fix elaboration of `define_fun` declarations [#747](https://github.com/ucsd-progsys/liquid-fixpoint/pull/747) [#749](https://github.com/ucsd-progsys/liquid-fixpoint/pull/749)+ ## 0.9.6.3.3 (2025-03-22)  - Add support for GHC HEAD (9.13) [#745](https://github.com/ucsd-progsys/liquid-fixpoint/pull/745).
README.md view
@@ -2,7 +2,7 @@ ===============  -[![Hackage](https://img.shields.io/hackage/v/liquid-fixpoint.svg)](https://hackage.haskell.org/package/liquid-fixpoint) [![Hackage-Deps](https://img.shields.io/hackage-deps/v/liquid-fixpoint.svg)](http://packdeps.haskellers.com/feed?needle=liquid-fixpoint) +[![Hackage](https://img.shields.io/hackage/v/liquid-fixpoint.svg)](https://hackage.haskell.org/package/liquid-fixpoint) [![Hackage-Deps](https://img.shields.io/hackage-deps/v/liquid-fixpoint.svg)](http://packdeps.haskellers.com/feed?needle=liquid-fixpoint) [![CircleCI](https://circleci.com/gh/ucsd-progsys/liquid-fixpoint.svg?style=svg)](https://circleci.com/gh/ucsd-progsys/liquid-fixpoint) [![hlint](https://github.com/ucsd-progsys/liquid-fixpoint/actions/workflows/hlint.yml/badge.svg)](https://github.com/ucsd-progsys/liquid-fixpoint/actions/workflows/hlint.yml) [![cabal](https://github.com/ucsd-progsys/liquid-fixpoint/actions/workflows/cabal.yml/badge.svg)](https://github.com/ucsd-progsys/liquid-fixpoint/actions/workflows/cabal.yml)@@ -15,7 +15,13 @@ + [Houdini](https://users.soe.ucsc.edu/~cormac/papers/fme01.pdf) + [Cartesian predicate abstraction](http://swt.informatik.uni-freiburg.de/berit/papers/boolean-and-cartesian-....pdf) +Algorithms implemented in liquid-fixpoint: ++ [FUSION](https://ranjitjhala.github.io/static/local_refinement_typing.pdf) Local refinement typing++ [PLE](https://ranjitjhala.github.io/static/refinement_reflection.pdf) Refinement Reflection: Complete Verification with SMT++ [REST](https://drops.dagstuhl.de/entities/document/10.4230/DARTS.8.2.12) REST: Integrating Term Rewriting with Program Verification++ Requirements ------------ @@ -23,6 +29,7 @@  - [Z3](https://github.com/Z3Prover/z3) - [CVC4](https://cvc4.github.io/)+- [CVC5](https://cvc5.github.io/) - [MathSat](http://mathsat.fbk.eu/download.html)  If on Windows, please make sure to place the binary and any associated DLLs somewhere@@ -60,9 +67,10 @@      * Z3     * CVC4+    * CVC5     * MathSat -"Horn" Format +"Horn" Format -------------  See the examples in `tests/horn/{pos, neg}` eg@@ -73,8 +81,8 @@  For how to write VCs "by hand". -See [this tutorial](https://arxiv.org/abs/2010.07763) -with [accompanying code](https://github.com/ranjitjhala/sprite-lang) +See [this tutorial](https://arxiv.org/abs/2010.07763)+with [accompanying code](https://github.com/ranjitjhala/sprite-lang) for an example of how to generate Horn queries.  The main datatypes are described in [src/Language/Fixpoint/Horn/Types.hs](src/Language/Fixpoint/Horn/Types.hs)@@ -145,7 +153,7 @@ ``` $ more tests/horn/pos/test01.smt2 | fixpoint --stdin -Liquid-Fixpoint Copyright 2013-21 Regents of the University of California.+Liquid-Fixpoint Copyright 2009-25 Regents of the University of California. All Rights Reserved.  Working 166% [===============================================================]@@ -226,15 +234,20 @@   Then a single `IBindEnv` should only mention _at most_   one of `1` or `12`. -* There is also a "tree-shape" property that its a bit hard-  to describe ... TODO     +* [NOTE:TREE-LIKE] There is also a "tree-shape" property required by PLE: +```+  forall constraints c, c'.+    if i in c and i in c' then+      forall 0 <= j < i, j in c and j in c'+```+ ### LHS  Each `slhs` of a constraint is a `SortedReft`.  - Each `SortredReft` is basically a `Reft` -- a logical predicate.-  The important bit is that a `KVar` i.e. terms of the formalized+  The important bit is that a `KVar` i.e. terms of the form  ```      $k1[x1:=y1][x2:=y2]...[xn:=yn]@@ -271,16 +284,35 @@    is not. The exact definition is formalized in `Language.Fixpoint.SortCheck` - ### RHS  Similarly each `rhs` of a `SubC` must either be a single `$k[...]` or an plain `$k`-free `Expr`. +### KVar occurrences++* Each `KVar` that appears in any binding or constraint must have exactly one+  associated wf constraint.++* Each `KVar` that appears in any binding or constraint must have an+  accompanying substitution whose domain has the same symbols as the environment+  of the corresponding wf constraint plus the symbol of its refinement type.++For example, if the wf constraint is+```+    x:int, y: int |- {v:int | $k_##42 }+```++any occurrence of `$k_##42` must be of the form++```+    $k_##42 [x:=e1][y:=e2][v:=e3]+```+ ### Global vs. Distinct Literals  ```      , gLits    :: !(SEnv Sort)               -- ^ Global Constant symbols-     , dLits    :: !(SEnv Sort)       +     , dLits    :: !(SEnv Sort) ```  The _global_ literals `gLits` are symbols that@@ -326,15 +358,10 @@  > What's the difference between an FTC and an FObj? -In early versions of fixpoint, there was support for -three sorts for expressions (`Expr`) that were sent -to the SMT solver:--1. `int`-2. `bool`-3. "other"--The `FObj` sort was introduced to represent essentially _all_ +In early versions of fixpoint, there was support for+three sorts for expressions (`Expr`) that were sent+to the SMT solver: `int`, `bool` and "other". The+`FObj` sort was introduced to represent essentially _all_ non-int and non-bool values (e.g. tuples, lists, trees, pointers...)  However, we later realized that it is valuable to keep _more_@@ -351,17 +378,27 @@ > Does that then make FTC types that the SMT solver does > know about (bools, ints, lists, sets, etc.)? -The SMT solver knows about `bool`, `int` and `set` (also `bitvector` -and `map`) but _all_ other types are _currently_ represented as plain -`Int` inside the SMT solver. However, we _will be_ changing this +The SMT solvers we currently use know about following sorts:++* `bool`+* `int`+* `real`+* `string`+* `array` (aka `map`)+* `bitvector`+* `set` and `bag` (in Z3, they are both also represented internally as `array`s)+* `finitefield` (CVC5 only)++_All_ other types are _currently_ represented as plain+`Int` inside the SMT solver. However, we _will be_ changing this to make use of SMT support for ADTs ... -To sum up: the `FObj` is there for historical reasons; it has been -subsumed by `FTC` which is what I recomend you use. However `FObj` -is there if you want a simple "unitype" / "any" type for terms +To sum up: the `FObj` is there for historical reasons; it has been+subsumed by `FTC` which is what I recomend you use. However `FObj`+is there if you want a simple "unitype" / "any" type for terms that are not "interpreted". -## Qualifier Patterns +## Qualifier Patterns  ```haskell λ> doParse' (qualParamP sortP) "" "z as (mon . $1) : int"
bin/Fixpoint.hs view
@@ -24,10 +24,10 @@       | otherwise  = solveFQ  isHorn :: F.Config -> Bool-isHorn cfg = F.isExtFile F.Smt2 file +isHorn cfg = F.isExtFile F.Smt2 file           || F.isExtFile F.Json file           || F.stdin cfg-  where +  where     file = F.srcFile cfg  errorExit :: F.Error -> IO ExitCode
liquid-fixpoint.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               liquid-fixpoint-version:            0.9.6.3.3+version:            0.9.6.3.4 synopsis:           Predicate Abstraction-based Horn-Clause/Implication Constraint Solver description:   This package implements an SMTLIB based Horn-Clause\/Logical Implication constraint@@ -56,6 +56,7 @@ library   import: warnings   exposed-modules:  Data.ShareMap+                    Control.Exception.Compat                     Language.Fixpoint.Conditional.Z3                     Language.Fixpoint.Defunctionalize                     Language.Fixpoint.Graph@@ -82,9 +83,6 @@                     Language.Fixpoint.Solver.Eliminate                     Language.Fixpoint.Solver.EnvironmentReduction                     Language.Fixpoint.Solver.Extensionality-                    Language.Fixpoint.Solver.GradualSolution-                    Language.Fixpoint.Solver.GradualSolve-                    Language.Fixpoint.Solver.Instantiate                     Language.Fixpoint.Solver.Interpreter                     Language.Fixpoint.Solver.Monad                     Language.Fixpoint.Solver.PLE@@ -105,8 +103,8 @@                     Language.Fixpoint.Types.Constraints                     Language.Fixpoint.Types.Environments                     Language.Fixpoint.Types.Errors-                    Language.Fixpoint.Types.Graduals                     Language.Fixpoint.Types.Names+                    Language.Fixpoint.Types.SMTPrint                     Language.Fixpoint.Types.PrettyPrint                     Language.Fixpoint.Types.Refinements                     Language.Fixpoint.Types.Solutions@@ -144,12 +142,12 @@                   , directory                   , fgl                   , filepath+                  , gitrev              >= 1.3.1                   , hashable                   , intern                   , lens-family                   , megaparsec           >= 7.0.0 && < 10                   , mtl-                  , parallel                   , parser-combinators                   , pretty               >= 1.1.3.1                   , process@@ -194,7 +192,7 @@   autogen-modules:  Paths_liquid_fixpoint   hs-source-dirs:   bin   ghc-options:      -threaded -W -Wno-missing-methods-  build-depends:    base >= 4.9.1.0 && < 5, liquid-fixpoint+  build-depends:    base >= 4.9.1.0 && < 5, liquid-fixpoint, gitrev >= 1.3.1   if flag(devel)     ghc-options: -Werror   default-language: Haskell98@@ -236,10 +234,15 @@                     ShareMapReference                     ShareMapTests                     SimplifyInterpreter+                    SimplifyKVarTests                     SimplifyPLE                     SimplifyTests                     UndoANFTests                     Paths_liquid_fixpoint+  if impl(ghc>=9.12.1)+    hs-source-dirs: tests/tasty/ghc-9.12.1+  else+    hs-source-dirs: tests/tasty/ghc-before-9.12.1   autogen-modules:  Paths_liquid_fixpoint   hs-source-dirs:   tests/tasty   ghc-options:      -threaded
+ src/Control/Exception/Compat.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP #-}+module Control.Exception.Compat+  ( ExceptionWithContext(..)+  , displayExceptionContext+  , wrapExceptionWithContext+  ) where++#if MIN_VERSION_base(4,20,0)++import Control.Exception (ExceptionWithContext(..))+import Control.Exception.Context (displayExceptionContext)++wrapExceptionWithContext :: ExceptionWithContext a -> ExceptionWithContext a+wrapExceptionWithContext = id++#else++data ExceptionWithContext a = ExceptionWithContext ExceptionContext a++data ExceptionContext = ExceptionContext++displayExceptionContext :: ExceptionContext -> String+displayExceptionContext _ = "Exception context not available in this version of ghc."++wrapExceptionWithContext :: a -> ExceptionWithContext a+wrapExceptionWithContext = ExceptionWithContext ExceptionContext+#endif+
src/Language/Fixpoint/Defunctionalize.hs view
@@ -85,6 +85,9 @@                               (i2, e2') = go e2                           in (max i1 i2, EApp e1' e2')     go (ECst e s)       = fmap (`ECst` s) (go e)+    go (ELet x e1 e2)   = let (i1, e1') = go e1+                              (i2, e2') = go e2+                          in (max i1 i2, ELet x e1' e2')     go (EIte e1 e2 e3)  = let (i1, e1') = go e1                               (i2, e2') = go e2                               (i3, e3') = go e3@@ -152,11 +155,6 @@     let (x, t, k) = wrft wf     t' <- defunc t     return $ wf { wrft = (x, t', k) }-  defunc wf@GWfC{} = do-    let (x, t, k) = wrft wf-    t' <- defunc t-    e' <- defunc $ wexpr wf-    return $ wf { wrft = (x, t', k), wexpr = e' }  instance Defunc SortedReft where   defunc (RR s r) = RR s <$> defunc r
src/Language/Fixpoint/Graph/Deps.hs view
@@ -205,12 +205,16 @@ edgeGraph es = KVGraph [(v, v, vs) | (v, vs) <- groupList es ]  -- need to plumb list of ebinds++-- | Compute dependencies between constraints and kvars.+--+-- @(k, c)@ means that constraint @c@ uses kvar @k@ on the LHS.+-- @(c, k)@ means that constraint @c@ uses kvar @k@ on the RHS. {-# SCC kvEdges #-} kvEdges :: (F.TaggedC c a) => F.GInfo c a -> [CEdge]-kvEdges fi = selfes ++ concatMap (subcEdges bs) cs ++ concatMap (ebindEdges ebs bs) cs+kvEdges fi = selfes ++ concatMap (subcEdges bs) cs   where     bs     = F.bs fi-    ebs    = F.ebinds fi     cs     = M.elems (F.cm fi)     ks     = fiKVars fi     selfes =  [(Cstr i , Cstr  i) | c <- cs, let i = F.subcId c]@@ -220,21 +224,6 @@ fiKVars :: F.GInfo c a -> [F.KVar] fiKVars = M.keys . F.ws -ebindEdges :: (F.TaggedC c a) => [F.BindId] -> F.BindEnv a -> c a -> [CEdge]-ebindEdges ebs bs c =  [(EBind k, Cstr i ) | k  <- envEbinds xs bs c ]-                    ++ [(Cstr i, EBind k') | k' <- rhsEbinds xs c ]-  where-    i          = F.subcId c-    xs         = fst3 . flip F.lookupBindEnv bs <$> ebs--envEbinds :: (F.TaggedC c a, Foldable t) =>-             t F.Symbol -> F.BindEnv a -> c a -> [F.Symbol]-envEbinds xs be c = [ x | x <- envBinds , x `elem` xs ]-  where envBinds = fst <$> F.clhs be c-rhsEbinds :: (Foldable t, F.TaggedC c a) =>-             t F.Symbol -> c a -> [F.Symbol]-rhsEbinds xs c = [ x | x <- F.syms (F.crhs c) , x `elem` xs ]- subcEdges :: (F.TaggedC c a) => F.BindEnv a -> c a -> [CEdge] subcEdges bs c =  [(KVar k, Cstr i ) | k  <- V.envKVars bs c]                ++ [(Cstr i, KVar k') | k' <- V.rhsKVars c ]@@ -245,10 +234,10 @@ -- | Eliminated Dependencies -------------------------------------------------------------------------------- {-# SCC elimDeps #-}-elimDeps :: (F.TaggedC c a) => F.GInfo c a -> [CEdge] -> S.HashSet F.KVar -> S.HashSet F.Symbol -> CDeps-elimDeps si es nonKutVs ebs = graphDeps si es'+elimDeps :: (F.TaggedC c a) => F.GInfo c a -> [CEdge] -> S.HashSet F.KVar -> CDeps+elimDeps si es nonKutVs = graphDeps si es'   where-    es'                 = graphElim es nonKutVs ebs+    es'                 = graphElim es nonKutVs     _msg                = "graphElim: " ++ show (length es')  {- | `graphElim` "eliminates" a kvar k by replacing every "path"@@ -259,9 +248,8 @@            ki ------------> c -}-graphElim :: [CEdge] -> S.HashSet F.KVar -> S.HashSet F.Symbol -> [CEdge]-graphElim es ks _ebs = ikvgEdges $ -- elimEs (S.map EBind ebs) $-                                  elimKs (S.map KVar ks)   $ edgesIkvg es+graphElim :: [CEdge] -> S.HashSet F.KVar -> [CEdge]+graphElim es ks = ikvgEdges $ elimKs (S.map KVar ks)   $ edgesIkvg es   where     elimKs      = flip (S.foldl' elimK)     _elimEs      = flip (S.foldl' elimE)@@ -307,8 +295,10 @@ dCut    v = Deps (S.singleton v) S.empty  ----------------------------------------------------------------------------------- | Compute Dependencies and Cuts ------------------------------------------------------------------------------------------------------------------------------+-- | Compute Dependencies and Cuts+--+-- Computes greedily a set of kvars that make the dependency graph acyclic when+-- removed. Also yields the edges of the dependency graph. {-# SCC elimVars #-} elimVars :: (F.TaggedC c a) => Config -> F.GInfo c a -> ([CEdge], Elims F.KVar) --------------------------------------------------------------------------------@@ -581,9 +571,8 @@     nlks          = nonLinearKVars si     d             = snd $ elimVars cfg si ---------------------------------------------------------------------------------+-- | KVars used more than once in the LHS of some constraint nonLinearKVars :: (F.TaggedC c a) => F.GInfo c a -> S.HashSet F.KVar--------------------------------------------------------------------------------- nonLinearKVars fi = S.unions $ nlKVarsC bs <$> cs   where     bs            = F.bs fi
src/Language/Fixpoint/Graph/Types.hs view
@@ -66,13 +66,11 @@  data CVertex = KVar  !KVar    -- ^ real kvar vertex              | DKVar !KVar    -- ^ dummy to ensure each kvar has a successor-             | EBind !F.Symbol  -- ^ existentially bound "ghost paramter" to solve for              | Cstr  !Integer -- ^ constraint-id which creates a dependency                deriving (Eq, Ord, Show, Generic)  instance PPrint CVertex where   pprintTidy _ (KVar k)  = doubleQuotes $ pprint $ kv k-  pprintTidy _ (EBind s)  = doubleQuotes $ pprint s   pprintTidy _ (Cstr i)  = text "id_" <-> pprint i   pprintTidy _ (DKVar k) = pprint k   <-> text "*" @@ -192,8 +190,8 @@ -- | `SolverInfo` contains all the stuff needed to produce a result, and is the --   the essential ingredient of the state needed by solve_ ---------------------------------------------------------------------------------data SolverInfo a b = SI-  { siSol     :: !(F.Sol b F.QBind)             -- ^ the initial solution+data SolverInfo a = SI+  { siSol     :: !(F.Sol F.QBind)             -- ^ the initial solution   , siQuery   :: !(F.SInfo a)                   -- ^ the whole input query   , siDeps    :: !CDeps                         -- ^ dependencies between constraints/ranks etc.   , siVars    :: !(S.HashSet F.KVar)            -- ^ set of KVars to actually solve for
src/Language/Fixpoint/Horn/Info.hs view
@@ -5,12 +5,10 @@     hornFInfo   ) 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-import           Data.Either                    (partitionEithers) import           GHC.Generics                   (Generic) import qualified Language.Fixpoint.Misc         as Misc import qualified Language.Fixpoint.Types        as F@@ -22,7 +20,6 @@ hornFInfo cfg q = mempty   { F.cm        = cs   , F.bs        = be2-  , F.ebinds    = ebs   , F.ws        = kvEnvWfCs kve   , F.quals     = H.qQuals q ++ scrapeCstr (F.scrape cfg) hCst   , F.gLits     = F.fromMapSEnv $ H.qCon q@@ -30,12 +27,12 @@   , F.ae        = axEnv cfg q cs   , F.ddecls    = H.qData q   , F.hoInfo    = F.cfgHoInfo cfg-  , F.defns     = H.qDefs q+  , F.defns     = F.MkDefinedFuns (H.qDefs q)   }   where     be0         = F.emptyBindEnv     (be1, kve)  = hornWfs   be0     (H.qVars q)-    (be2, ebs, cs) = hornSubCs be1 kve hCst+    (be2, cs) = hornSubCs be1 kve hCst     hCst           = H.qCstr q  @@ -48,27 +45,26 @@  ---------------------------------------------------------------------------------- hornSubCs :: F.BindEnv a -> KVEnv a -> H.Cstr a-          -> (F.BindEnv a, [F.BindId], M.HashMap F.SubcId (F.SubC a))+          -> (F.BindEnv a, M.HashMap F.SubcId (F.SubC a)) -----------------------------------------------------------------------------------hornSubCs be kve c = (be', ebs, M.fromList (F.addIds cs))+hornSubCs be kve c = (be', M.fromList (F.addIds cs))   where-    (be', ebs, cs) = goS kve F.emptyIBindEnv be c+    (be', cs) = goS kve F.emptyIBindEnv be c     -- lhs0           = bindSortedReft kve H.dummyBind  -- | @goS@ recursively traverses the NNF constraint to build up a list --   of the vanilla @SubC@ constraints.  goS :: KVEnv a -> F.IBindEnv ->  F.BindEnv a -> H.Cstr a-    -> (F.BindEnv a, [F.BindId], [F.SubC a])+    -> (F.BindEnv a, [F.SubC a]) -goS kve env be c = (be', mEbs, subcs)+goS kve env be c = (be', subcs)   where-    (be', ecs) = goS' kve env Nothing be c-    (mEbs, subcs) = partitionEithers ecs+    (be', subcs) = goS' kve env Nothing be c  goS' :: KVEnv a -> F.IBindEnv -> Maybe F.SortedReft -> F.BindEnv a -> H.Cstr a-    -> (F.BindEnv a, [Either F.BindId (F.SubC a)])-goS' kve env lhs be (H.Head p l) = (be, [Right subc])+    -> (F.BindEnv a, [F.SubC a])+goS' kve env lhs be (H.Head p l) = (be, [subc])   where     subc                        = myMkSubC env lhs rhs Nothing [] l     rhs                         = updSortedReft kve lhs p@@ -84,13 +80,6 @@     bSR                         = bindSortedReft kve b     env'                        = F.insertsIBindEnv [bId] env -goS' kve env _   be (H.Any b c)  = (be'', Left bId : subcs)-  where-    (be'', subcs)               = goS' kve env' (Just bSR) be' c-    (bId, be')                  = F.insertBindEnv (H.bSym b) bSR (H.bMeta b) be-    bSR                         = bindSortedReft kve b-    env'                        = F.insertsIBindEnv [bId] env- myMkSubC :: F.IBindEnv -> Maybe F.SortedReft -> F.SortedReft -> Maybe Integer -> F.Tag -> a -> F.SubC a myMkSubC be lhsMb rhs x y z = F.mkSubC be lhs rhs x y z   where@@ -114,10 +103,10 @@     go (H.Var k ys) = kvApp kve k ys     go (H.PAnd  ps) = F.PAnd (go <$> ps) -kvApp :: KVEnv a -> F.Symbol -> [F.Symbol] -> F.Expr+kvApp :: KVEnv a -> F.Symbol -> [F.Expr] -> F.Expr kvApp kve k ys = F.PKVar (F.KV k) su   where-    su         = F.mkSubst (zip params (F.eVar <$> ys))+    su         = F.mkSubst (zip params ys)     params     = maybe err1 kvParams (M.lookup k kve)     err1       = F.panic ("Unknown Horn variable: " ++ F.showpp k) @@ -176,7 +165,6 @@     go senv (H.Head p _) = scrapePred senv p     go senv (H.CAnd cs)  = concatMap (go senv) cs     go senv (H.All b c)  = scrapeBind m senv' b <> go senv' c where senv' = insertBindEnv b senv-    go senv (H.Any b c)  = scrapeBind m senv' b <> go senv' c where senv' = insertBindEnv b senv  scrapeBind :: F.Scrape -> BindEnv -> H.Bind a -> [F.Qualifier] scrapeBind F.Both senv b = scrapePred senv (H.bPred b)@@ -189,16 +177,17 @@  -- NOTE: Constraints.mkQual will do extra stuff like generalizing the sorts... mkQual :: BindEnv -> F.Expr -> [ F.Qualifier ]-mkQual env e = case qualParams env e of-  Nothing  -> []-  Just xts -> [ mkScrapeQual xts' e | xts' <- shiftCycle xts ]+mkQual env e = [ mkScrapeQual xts' e | xts' <- shiftCycle xts ]+  where+    xts = qualParams env e  mkScrapeQual :: [(F.Symbol, F.Sort)] -> F.Expr -> F.Qualifier-mkScrapeQual xts e = F.mkQual (F.symbol "AUTO") qParams (F.subst su e) (F.dummyPos "")+mkScrapeQual xts e = F.mkQual (F.symbol "AUTO") qParams body (F.dummyPos "")   where     qParams = [ F.QP {F.qpSym = y, F.qpPat = F.PatNone, F.qpSort = t} | (_, y, t) <- xyts ]     xyts    = zipWith (\i (x, t) -> (x, F.bindSymbol i, t)) [0..] xts     su      = F.mkSubst [ (x, F.expr y) | (x, y, _) <- xyts ]+    body    = F.subst su e   shiftCycle :: [(F.Symbol, F.Sort)] -> [[(F.Symbol, F.Sort)]]@@ -221,15 +210,11 @@   2. Permute the args?  -} -qualParams :: BindEnv -> F.Expr -> Maybe [(F.Symbol, F.Sort)]-qualParams env e = do-    let xs = Misc.nubOrd (F.syms e)-    ixts <- forM xs $ \x -> do-              (t, i) <- lookupBindEnv x env-              return (i, x, t)-    return [ (x, t) | (_, x, t) <- L.sortBy (comparing Down) ixts ]--    -- ixts = [ (i, x, t) | x <- xs, (i, t) <- lookupBindEnv x env ]+qualParams :: BindEnv -> F.Expr -> [(F.Symbol, F.Sort)]+qualParams env e = [ (x, t) | (_, x, t) <- L.sortBy (comparing Down) ixts ]+  where+    xs = Misc.nubOrd (F.syms e)+    ixts = [ (i, x, t) | x <- xs, (t, i) <- Mb.maybeToList (lookupBindEnv x env) ]  ------------------------------------------------------------------------------- 
src/Language/Fixpoint/Horn/Parse.hs view
@@ -84,7 +84,6 @@   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)         <|> H.Head <$> hPredP                             <*> pure H.NoTag @@ -98,7 +97,7 @@ ------------------------------------------------------------------------------- hPredP = parens body   where-    body =  H.Var  <$> kvSymP                           <*> some symbolP+    body =  H.Var  <$> kvSymP                           <*> some predP         <|> H.PAnd <$> (reserved "and" *> some hPredP)         <|> H.Reft <$> predP 
src/Language/Fixpoint/Horn/SMTParse.hs view
@@ -187,7 +187,6 @@   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)@@ -200,7 +199,7 @@ ------------------------------------------------------------------------------- hPredP = parens body   where-    body =  H.Var  <$> kvSymP <*> some symbolP+    body =  H.Var  <$> kvSymP <*> some exprP         <|> H.PAnd <$> (reserved "and" *> some hPredP)         <|> H.Reft <$> exprP @@ -260,6 +259,16 @@ bindP :: FParser (F.Symbol, F.Sort) bindP = sPairP symbolP sortP +-- | We only support lets with a single binder, but we parse this as a "singleton list"+-- to be forward compatible with multiple binders. Note that the semantics of multiple+-- binders in smtlib is *simulatenous substitution*, so they cannot be desugared to nested+-- lets.+exprBindsP :: FParser (F.Symbol, F.Expr)+exprBindsP = parens exprBindP++exprBindP :: FParser (F.Symbol, F.Expr)+exprBindP = sPairP symbolP exprP+ defineP :: FParser F.Equation defineP = do   name   <- symbolP@@ -285,6 +294,7 @@      <|> try (parens (reserved "func" >> (mkFunc <$> fIntP <*> sMany sortP <*> sortP)))      <|> try (parens (reserved "list" >> (mkList <$> sortP)))      <|> parens (F.fAppTC <$> fTyConP <*> many sortP)+     <|> (F.FNatNum <$> natural)  mkFunc :: Int -> [F.Sort] -> F.Sort -> F.Sort mkFunc n ss s = F.mkFFunc n (ss ++ [s])@@ -304,6 +314,7 @@ pExprP :: FParser F.Expr pExprP   =   (reserved   "if"     >> (F.EIte   <$> exprP <*> exprP <*> exprP))+  <|> (reserved   "let"    >> (uncurry F.ELet   <$> exprBindsP <*> exprP))   <|> (reserved   "lit"    >> (mkLit    <$> stringLiteral <*> sortP))   <|> (reserved   "cast"   >> (F.ECst   <$> exprP <*> sortP))   <|> (reserved   "not"    >> (F.PNot   <$> exprP))@@ -335,7 +346,7 @@  <|> (sym "-"   >> return F.Minus)  <|> (sym "*"   >> return F.Times)  <|> (sym "/"   >> return F.Div)- <|> (sym "mod" >> return F.Mod)+ <|> (reserved "mod" >> return F.Mod)  <|> (sym "*."  >> return F.RTimes)  <|> (sym "/."  >> return F.RDiv) 
src/Language/Fixpoint/Horn/Solve.hs view
@@ -30,9 +30,9 @@ ---------------------------------------------------------------------------------- solveHorn :: F.Config -> IO ExitCode -----------------------------------------------------------------------------------solveHorn baseCfg = do-  q <- parseQuery baseCfg-+solveHorn baseCfg0 = do+  q <- parseQuery baseCfg0+  let baseCfg = baseCfg0 { F.explicitKvars = True }   -- If you want to set --eliminate=none, you better make it a pragma   let cfgElim = if F.eliminate baseCfg == F.None                   then baseCfg { F.eliminate =  F.Some }@@ -67,12 +67,12 @@   saveHornSMT2 cfg q   saveHornJSON cfg q -saveHornSMT2 :: H.ToHornSMT a => F.Config -> a -> IO ()+saveHornSMT2 :: F.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 -} H.toHornSMT q)+  writeFile hq $ render (F.toHornSMT q)  saveHornJSON :: F.Config -> H.Query H.Tag -> IO () saveHornJSON cfg q = do
src/Language/Fixpoint/Horn/Transformations.hs view
@@ -147,10 +147,12 @@       (ns, formals, Just defC) -> (ns, formals, defC)       (_, _, Nothing) -> error $ "pi variable " <> F.showpp k <> " has no defining constraint." +    -- TODO: generalize the `expectVar` business below to handle arbitrary expressions+    -- https://github.com/ucsd-progsys/liquid-fixpoint/pull/818#discussion_r2643206366     go :: Cstr a -> ([F.Symbol], [[F.Symbol]], Maybe (Cstr a))     go (CAnd cs) = (\(as, bs, mcs) -> (concat as, concat bs, cAndMaybes mcs)) $ unzip3 $ go <$> cs     go (All b@(Bind n _ (Var k' xs) _) c')-      | k == k' = ([n], [S.toList $ S.fromList xs `S.difference` S.singleton n], Just c')+      | k == k' = ([n], [S.toList $ S.fromList (expectVar <$> xs) `S.difference` S.singleton n], Just c')       | otherwise = map3 (fmap (All b)) (go c')     go (All b c') = map3 (fmap (All b)) (go c')     go _ = ([], [], Nothing)@@ -160,6 +162,10 @@       [] -> Nothing       cs -> Just $ CAnd cs +expectVar :: F.Expr -> F.Symbol+expectVar (F.EVar s) = s+expectVar _ = error "expectVar: expected variable"+ map3 :: (c -> d) -> (a, b, c) -> (a, b, d) map3 f (x, y, z) = (x, y, f z) @@ -194,7 +200,6 @@           (eqs' <> eqs'', newVisited')     go visited (All (Bind _ _ p _) c) = let (eqs, visited') = go visited c in       (eqs <> collectEqualities p, visited')-    go _ Any{} = error "exists should not be present in piSols"  ------------------------------------------------------------------------------ {- | pokec skolemizes the EHC into an HC + side condition@@ -248,16 +253,7 @@     go _ (Head c l) = Head c l     go xs (CAnd c)   = CAnd (go xs <$> c)     go xs (All b c2) = All b $ go (bSym b : xs) c2-    go xs (Any b@(Bind x t p ann) c2) = CAnd [All b' $ CAnd [Head p l, go (x:xs) c2], Any b (Head pi' l)]-      -- TODO: actually use the renamer?-      where-        b' = Bind x t pi' ann-        pi' = piVar x xs-        l  = cLabel c2 -piVar :: F.Symbol -> [F.Symbol] -> Pred-piVar x xs = Var (piSym x) (x:xs)- piSym :: F.Symbol -> F.Symbol piSym s = fromString $ "π" ++ F.symbolString s @@ -332,7 +328,6 @@   where (nosides, sides) = unzip $ split <$> cs split (All b c) = (All b <$> c', All b <$> c'')     where (c',c'') = split c-split c@Any{} = (Nothing, Just c) split c@Head{} = (Just c, Nothing)  andMaybes :: [Maybe (Cstr a)] -> Maybe (Cstr a)@@ -407,8 +402,6 @@   = CAnd $ applyPi k bp <$> cs applyPi k bp (All b c)   = All b (applyPi k bp c)-applyPi k bp (Any b c)-  = Any b (applyPi k bp c) applyPi k defCstr (Head (Var k' _xs) a)   | k == k'   -- what happens when pi's appear inside the defs for other pis?@@ -475,18 +468,16 @@   = pure c defs x (All _ c) = defs x c defs _ (Head _ _) = Nothing-defs _ (Any _ _) =  error "defs should be run only after noside and poke"  cstrToExpr :: Cstr a -> F.Expr cstrToExpr (Head p _) = predToExpr p cstrToExpr (CAnd cs) = F.PAnd $ cstrToExpr <$> cs cstrToExpr (All (Bind x t p _) c) = F.PAll [(x,t)] $ F.PImp (predToExpr p) $ cstrToExpr c-cstrToExpr (Any (Bind x t p _) c) = F.PExist [(x,t)] $ F.PImp (predToExpr p) $ cstrToExpr c  predToExpr :: Pred -> F.Expr predToExpr (Reft e) = e predToExpr (Var k xs) = F.PKVar (F.KV k) (F.Su $ M.fromList su)-  where su = zip (kargs k) (F.EVar <$> xs)+  where su = zip (kargs k) xs predToExpr (PAnd ps) = F.PAnd $ predToExpr <$> ps  ------------------------------------------------------------------------------@@ -573,7 +564,6 @@   foldE v c (CAnd cs) = CAnd <$> mapM (foldE v c) cs   foldE v c (Head p a) = Head <$> foldE v c p <*> pure a   foldE v ctx (All (Bind x t p l) c) = All <$> (Bind x t <$> foldE v ctx p <*> pure l) <*> foldE v ctx c-  foldE v ctx (Any (Bind x t p l) c) = All <$> (Bind x t <$> foldE v ctx p <*> pure l) <*> foldE v ctx c  ------------------------------------------------------------------------------ -- | Quantifier elimination for use with implicit solver@@ -700,27 +690,7 @@ substPiSols piSols (All (Bind x t p l) c)   | Var k _ <- p = All (Bind x t (M.lookupDefault p k piSols) l) (substPiSols piSols c)   | otherwise = All (Bind x t p l) (substPiSols piSols c)-substPiSols piSols (Any (Bind n _ p _) c)-  | Head (Var pi' _) label <- c, Just sol <- M.lookup pi' piSols =-    case findSol n sol of-      Just e -> Head (flatten $ PAnd $ (\predFn -> F.subst1 predFn (n, e)) <$> [p, sol]) label-      Nothing -> Head (Reft $ F.PAnd []) label-  | otherwise = error "missing piSol" -findSol :: F.Symbol -> Pred -> Maybe F.Expr-findSol sym = go-  where-    go (Reft e) = findEq e-    go Var{} = Nothing-    go (PAnd ps) = case mapMaybe go ps of-      [] -> Nothing-      x:_ -> Just x--    findEq (F.PAtom F.Eq left right)-      | F.EVar y <- left, y == sym = Just right-      | F.EVar y <- right, y == sym = Just left-    findEq _ = Nothing- ------------------------------------------------------------------------------ -- | uniq makes sure each binder has a unique name ------------------------------------------------------------------------------@@ -737,11 +707,6 @@     c2' <- uniq' c2     modify $ popName x     pure $ All b' c2'-uniq' (Any b@(Bind x _ _ _) c2) = do-    b' <- uBind b-    c2' <- uniq' c2-    modify $ popName x-    pure $ Any b' c2'  popName :: F.Symbol -> RenameMap -> RenameMap popName x m = M.adjust (second tail) x m@@ -764,18 +729,17 @@  rename :: Pred -> RenameMap -> Pred rename e m = substPred (M.mapMaybeWithKey (\k v -> case v of-                                              (_, n:_) -> Just $ numSym k n+                                              (_, n:_) -> Just $ F.EVar $ numSym k n                                               _ -> Nothing) m) e  numSym :: IsString a => F.Symbol -> Integer -> a numSym s 0 = fromString $ F.symbolString s numSym s i = fromString $ F.symbolString s ++ "#" ++ show i -substPred :: M.HashMap F.Symbol F.Symbol -> Pred -> Pred-substPred su (Reft e) = Reft $ F.subst (F.Su $ F.EVar <$> su) e+substPred :: M.HashMap F.Symbol F.Expr -> Pred -> Pred+substPred su (Reft e) = Reft $ F.subst (F.Su su) e substPred su (PAnd ps) = PAnd $ substPred su <$> ps-substPred su (Var k xs) = Var k $ upd <$> xs-  where upd x = M.lookupDefault x x su+substPred su (Var k xs) = Var k $ F.subst (F.Su su) <$> xs  ------------------------------------------------------------------------------ -- | elim solves all of the KVars in a Cstr (assuming no cycles...)@@ -814,8 +778,6 @@     go (Head _ l) = Left l     go c@(All (Bind _ _ p _) c') =       if k `S.member` pKVars p then Right c else go c'-    go Any{} = error "any should not appear after poke"-     -- if kvar doesn't appear, then just return the left     -- if kvar appears in one child, that is the lca     -- but if kvar appear in multiple chlidren, this is the lca@@ -850,10 +812,9 @@ sol1 k (CAnd cs) = sol1 k =<< cs sol1 k (All b c) = first (b :) <$> sol1 k c sol1 k (Head (Var k' ys) _) | k == k'-  = [([], zipWith (F.PAtom F.Eq) (F.EVar <$> xs) (F.EVar <$> ys))]+  = [([], zipWith (F.PAtom F.Eq) (F.EVar <$> xs) ys)]   where xs = zipWith const (kargs k) ys sol1 _ (Head _ _) = []-sol1 _ (Any _ _) =  error "ebinds don't work with old elim"  kargs :: F.Symbol -> [F.Symbol] kargs k = fromString . (("κarg$" ++ F.symbolString k ++ "#") ++) . show <$> [1 :: Integer ..]@@ -871,9 +832,9 @@     Right _ -> All (Bind sym' sort' p l) (doelim sym bss cstr)     Left (kvars, preds) -> demorgan sym' sort' l kvars preds (doelim sym bss cstr) bss   where-    demorgan :: F.Symbol -> F.Sort -> a -> [(F.Symbol, [F.Symbol])] -> [Pred] -> Cstr a -> [([Bind a], [F.Expr])] -> Cstr a+    demorgan :: F.Symbol -> F.Sort -> a -> [(F.Symbol, [F.Expr])] -> [Pred] -> Cstr a -> [([Bind a], [F.Expr])] -> Cstr a     demorgan x t ann kvars preds cstr' bindExprs = mkAnd $ cubeSol <$> bindExprs-      where su = F.Su $ M.fromList $ concatMap (\(k, xs) -> zip (kargs k) (F.EVar <$> xs)) kvars+      where su = F.Su $ M.fromList $ concatMap (\(k, xs) -> zip (kargs k) xs) kvars             mkAnd [c] = c             mkAnd cs = CAnd cs             cubeSol (b:bs, eqs) = All b $ cubeSol (bs, eqs)@@ -883,14 +844,9 @@   = Head (Reft F.PTrue) a doelim _ _ (Head p a) = Head p a -doelim k bss (Any (Bind x t p l) c) =-  case findKVarInGuard k p of-    Right _ -> Any (Bind x t p l) (doelim k bss c)-    Left (_, rights') -> Any (Bind x t (PAnd rights') l) (doelim k bss c) -- TODO: for now we set the kvar to true. not sure if this is correct- -- If k is in the guard then returns a Left list of that k and the remaining preds in the guard -- If k is not in the guard returns a Right of the pred-findKVarInGuard :: F.Symbol -> Pred -> Either ([(F.Symbol, [F.Symbol])], [Pred]) Pred+findKVarInGuard :: F.Symbol -> Pred -> Either ([(F.Symbol, [F.Expr])], [Pred]) Pred findKVarInGuard k (PAnd ps) =   if null lefts     then Right (PAnd ps) -- kvar not found@@ -923,7 +879,6 @@ boundKvars (Head p _)           = pKVars p boundKvars (CAnd c)             = mconcat $ boundKvars <$> c boundKvars (All (Bind _ _ p _) c) = pKVars p <> boundKvars c-boundKvars (Any (Bind _ _ p _) c) = pKVars p <> boundKvars c  pKVars :: Pred -> S.Set F.Symbol pKVars (Var k _) = S.singleton k@@ -935,7 +890,6 @@ isNNF Head{} = True isNNF (CAnd cs) = all isNNF cs isNNF (All _ c) = isNNF c-isNNF Any{} = False  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@@ -949,7 +903,6 @@ forgetPiVars pis (All (Bind x t p l) c)   | Var k _ <- p, k `S.member` pis = All (Bind x t (PAnd []) l) $ forgetPiVars pis c   | otherwise = All (Bind x t p l) $ forgetPiVars pis c-forgetPiVars _ Any{} = error "shouldn't be present"  ----------------------------------------------------------------------------------- -- | Cleanup Horn Constraint@@ -997,7 +950,6 @@     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@@ -1062,7 +1014,6 @@         splitP kacc pacc [] = (kacc,pacc) hornify (Head h a) = Head h a hornify (All b c) = All b $ hornify c-hornify (Any b c) = Any b $ hornify c hornify (CAnd cs) = CAnd $ hornify <$> cs  removeDuplicateBinders :: Cstr a -> Cstr a@@ -1071,7 +1022,6 @@     go _ c@Head{} = c     go xs (CAnd cs) = CAnd $ go xs <$> cs     go xs (All b@(Bind x _ _ _) c) = if x `S.member` xs then go xs c else All b $ go (S.insert x xs) c-    go xs (Any b c) = Any b $ go xs c  pruneTauts :: Cstr a -> Cstr a pruneTauts = fromMaybe (CAnd []) . go@@ -1084,7 +1034,6 @@     go (All b c) = do       c' <- go c       pure (All b c')-    go c@Any{} = Just c      goP (Reft e) = if F.isTautoPred e then Nothing else Just $ Reft e     goP p@Var{} = Just p
src/Language/Fixpoint/Horn/Types.hs view
@@ -10,7 +10,6 @@ {-# LANGUAGE DeriveTraversable          #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ViewPatterns #-}  module Language.Fixpoint.Horn.Types   ( -- * Horn Constraints and their components@@ -34,8 +33,6 @@     -- * extract qualifiers   , quals -    -- * SMTLIB style render-  , ToHornSMT (..)   )   where @@ -63,19 +60,27 @@   }   deriving (Eq, Ord, Data, Typeable, Generic, Functor, ToJSON, FromJSON) ++ ------------------------------------------------------------------------------- -- | @HPred@ is a Horn predicate that appears as LHS (body) or RHS (head) of constraints ------------------------------------------------------------------------------- data Pred   = Reft  !F.Expr                               -- ^ r-  | Var   !F.Symbol ![F.Symbol]                 -- ^ $k(y1..yn)+  | Var   !F.Symbol ![F.Expr]                   -- ^ $k(y1..yn)   | PAnd  ![Pred]                               -- ^ p1 /\ .../\ pn   deriving (Data, Typeable, Generic, Eq, ToJSON, FromJSON) +instance F.ToHornSMT (Var a) where+  toHornSMT (HVar k ts _) = P.parens ("var" P.<+> "$" P.<-> F.pprint k P.<+> F.toHornSMT ts)+instance F.ToHornSMT Pred where+  toHornSMT (Reft p)   = P.parens (F.toHornSMT p)+  toHornSMT (Var k xs) = F.toHornMany (F.toHornSMT (F.KV k) : (F.toHornSMT <$> xs))+  toHornSMT (PAnd ps)  = F.toHornMany ("and" : (F.toHornSMT <$> ps))  instance F.Subable Pred where   syms (Reft e)   = F.syms e-  syms (Var _ xs) = xs+  syms (Var _ xs) = concatMap F.syms xs   syms (PAnd ps)  = concatMap F.syms ps    substa f (Reft e)   = Reft  (F.substa f      e)@@ -105,7 +110,6 @@     go env v (Head p _)  = predQuals env v p     go env v (CAnd   cs) = concatMap (go env v) cs     go env _ (All  b c)  = bindQuals env b c-    go env _ (Any  b c)  = bindQuals env b c  bindQuals  :: F.SEnv F.Sort -> Bind a -> Cstr a -> [F.Qualifier] bindQuals env b c = predQuals env' bx (bPred b) ++ cstrQuals env' bx c@@ -155,6 +159,9 @@   }   deriving (Data, Typeable, Generic, Functor, Eq, ToJSON, FromJSON) +instance F.ToHornSMT (Bind a) where+  toHornSMT (Bind x t p _) = P.parens (F.toHornSMT (x, t) P.<+> F.toHornSMT p)+ 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@@ -167,9 +174,17 @@   = Head  !Pred !a                  -- ^ p   | 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, ToJSON, FromJSON) +instance F.ToHornSMT (Cstr a) where+  toHornSMT = toHornCstr++toHornCstr :: Cstr a -> P.Doc+toHornCstr (Head p _) = F.toHornSMT p+toHornCstr (CAnd cs)  = F.toHornAnd toHornCstr cs+toHornCstr (All b c)  = P.parens (P.vcat ["forall" P.<+> F.toHornSMT b+                                         , P.nest 1 (toHornCstr c)])+ cLabel :: Cstr a -> a cLabel cstr = case go cstr of   [] -> F.panic "everything is true!!!"@@ -178,13 +193,11 @@     go (Head _ l)   = [l]     go (CAnd cs)    = mconcat $ go <$> cs     go (All _ c)    = go c-    go (Any _ c)    = go c  -- We want all valid constraints to start with a binding at the top  okCstr :: Cstr a -> Bool okCstr All {} = True-okCstr Any {} = True okCstr _      = False  @@ -236,7 +249,9 @@   parseJSON (String t) = pure (Tag (T.unpack t))   parseJSON invalid    = prependFailure "parsing `Tag` failed, " (typeMismatch "Object" invalid) -+instance F.ToHornSMT Tag where+  toHornSMT NoTag   = mempty+  toHornSMT (Tag s) = P.text s   @@ -284,13 +299,12 @@  instance Show Pred where   show (Reft p)   = parens $ F.showpp p-  show (Var x xs) = parens $ "$" ++ unwords (F.symbolString <$> x:xs)+  show (Var x xs) = parens $ "$" ++ unwords (F.symbolString x : (parens . F.showpp <$> xs))   show (PAnd ps)  = parens $ unwords $ "and": map show ps  instance Show (Cstr a) where   show (Head p _) = parens $ show p   show (All b c)  = parens $ unwords ["forall" , show b , show c]-  show (Any b c)  = parens $ unwords ["exists" , show b , show c]   show (CAnd cs)  = parens $ unwords $ "and" : map show cs  instance Show (Bind a) where@@ -301,7 +315,7 @@  instance F.PPrint Pred where   pprintPrec k t (Reft p)   = P.parens $ F.pprintPrec k t p-  pprintPrec _ _ (Var x xs) = P.parens $ P.ptext "$" <> P.hsep (P.ptext . F.symbolString <$> x:xs)+  pprintPrec k t (Var x xs) = P.parens $ P.ptext "$" <> P.hsep (P.ptext (F.symbolString x) : (P.parens. F.pprintPrec k t <$> xs))   pprintPrec k t (PAnd ps)  = P.parens $ P.vcat $ P.ptext "and" : map (F.pprintPrec (k+2) t) ps  instance F.PPrint (Cstr a) where@@ -309,170 +323,25 @@   pprintPrec k t (All b c)  = P.parens $ P.vcat [ P.ptext "forall" P.<+> F.pprintPrec (k+2) t b                                                 , F.pprintPrec (k+1) t c                                                 ]-  pprintPrec k t (Any b c)  = P.parens $ P.vcat [P.ptext "exists" P.<+> F.pprintPrec (k+2) t b-                                                , F.pprintPrec (k+1) t c-                                                ]   pprintPrec k t (CAnd cs) = P.parens $ P.vcat  $ P.ptext "and" : map (F.pprintPrec (k+2) t) cs  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+instance F.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   (F.toHornSMT <$> qQuals q)+    , P.vcat   (F.toHornSMT <$> qVars q)     , P.vcat   [toHornCon x t | (x, t) <- M.toList (qCon q)]-    , P.vcat   (eqnToHornSMT "define"     <$> qEqns q)-    , P.vcat   (eqnToHornSMT "define_fun" <$> qDefs q)-    , P.vcat   (toHornSMT <$> qData q)-    , P.vcat   (toHornSMT <$> qMats q)-    , P.parens (P.vcat ["constraint", P.nest 1 (toHornSMT (qCstr q))])+    , P.vcat   (F.eqnToHornSMT "define"     <$> qEqns q)+    , P.vcat   (F.eqnToHornSMT "define_fun" <$> qDefs q)+    , P.vcat   (F.toHornSMT <$> qData q)+    , P.vcat   (F.toHornSMT <$> qMats q)+    , P.parens (P.vcat ["constraint", P.nest 1 (F.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)))--eqnToHornSMT :: P.Doc -> F.Equation -> P.Doc-eqnToHornSMT keyword (F.Equ f xs e s _) = P.parens (keyword 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)])+      toHornNum x   = F.toHornMany ["numeric", F.toHornSMT x]+      toHornOpt str = F.toHornMany ["fixpoint", P.text ("\"" ++ str ++ "\"")]+      toHornCon x t = F.toHornMany ["constant", F.toHornSMT x, F.toHornSMT t]
src/Language/Fixpoint/Minimize.hs view
@@ -21,6 +21,11 @@ import           Control.DeepSeq  ---------------------------------------------------------------------------+-- | Top level Solvers ----------------------------------------------------+---------------------------------------------------------------------------+type Solver a = Config -> FInfo a -> IO (Result (Integer, a))++--------------------------------------------------------------------------- -- polymorphic delta debugging implementation --------------------------------------------------------------------------- deltaDebug :: Bool -> Oracle a c -> Config -> Solver a -> FInfo a -> [c] -> [c] -> IO [c]
src/Language/Fixpoint/Parse.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP                       #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE FlexibleInstances         #-} {-# LANGUAGE NoMonomorphismRestriction #-}@@ -92,6 +91,7 @@    -- * Parsing Function   , doParse'+  , doParse''   , parseTest'   , parseFromFile   , parseFromStdIn@@ -123,9 +123,7 @@ 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 qualified Data.List                   as List import           Data.List.NonEmpty          (NonEmpty(..)) import qualified Data.Text                   as T import qualified Data.Text.IO                as T@@ -231,6 +229,7 @@                      , supply      :: !Integer                      , layoutStack :: LayoutStack                      , numTyCons   :: !(S.HashSet Symbol)+                     , allowExists :: !Bool                      } type PState = PStateV Symbol @@ -476,6 +475,7 @@   , "func"   , "autorewrite"   , "rewrite"+  , "lit"    -- reserved words used in liquid haskell   , "forall"@@ -537,7 +537,7 @@   , "->"   , ":="   , "&", "^", "<<", ">>", "--"-  , "?", "Bexp"+  , "Bexp"   , "'"   , "_|_"   , "|"@@ -677,7 +677,7 @@ -- * an error message to display if the final check fails. -- condIdR :: ParserV v Char -> (Char -> Bool) -> (String -> Bool) -> String -> ParserV v Symbol-condIdR initial okChars condition msg = do+condIdR initial okChars condition msg = try $ do   s <- (:) <$> initial <*> takeWhileP Nothing okChars   if condition s     then pure (symbol s)@@ -789,28 +789,17 @@ -- This parser is reused by Liquid Haskell. -- expr0P :: ParseableV v => ParserV v (ExprV v)-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- <|> (ECon <$> constantP) -- numeric literal, starts with a digit- <|> (reservedOp "_|_" >> return EBot) -- constant bottom, equivalent to "false"- <|> lamP -- lambda abstraction, starts with backslash- <|> try tupleP -- tuple expressions, starts with "("- <|> try (parens exprP) -- parenthesised expression, starts with "("- <|> try (parens exprCastP) -- explicit type annotation, starts with "(", TODO: should be an operator rather than require parentheses?- <|> EVar <$> parseV  -- identifier, starts with any letter or underscore- <|> try (located (brackets (pure ())) >>= emptyListP) -- empty list, start with "["- <|> try (located (brackets exprP) >>= singletonListP) -- singleton list, starts with "["- --- -- Note:- --- -- In the parsers above, it is important that *all* parsers starting with "("- -- are prefixed with "try". This is because expr0P itself is chained with- -- additional parsers in funAppP ...+expr0P =+        botP+    <|> try (reserved "not") *> fmap PNot appliableExprP -- built-in prefix not+    <|> funAppP+    <|> existP+    <|> fastIfP EIte exprP -- "if-then-else", starts with "if"+    <|> try (coerceP exprP) -- coercion, starts with "coerce"+    <|> litP+    <|> lamP -- lambda abstraction, starts with backslash+    <|> (reservedOp "&&" >> PAnd <$> predsP) -- built-in prefix and+    <|> (reservedOp "||" >> POr  <$> predsP) -- built-in prefix or  emptyListP :: Located () -> ParserV v (ExprV v) emptyListP lx = do@@ -836,7 +825,7 @@ fastIfP :: ParseableV v => (ExprV v -> a -> a -> a) -> ParserV v a -> ParserV v a fastIfP f bodyP   = do reserved "if"-       p <- predP+       p <- exprP        reserved "then"        b1 <- bodyP        reserved "else"@@ -848,35 +837,12 @@   (s, t) <- parens (pairP sortP (reservedOp "~") sortP)   ECoerc s t <$> p ---{--qmIfP f bodyP-  = parens $ do-      p  <- predP-      reserved "?"-      b1 <- bodyP-      colon-      b2 <- bodyP-      return $ f p b1 b2--}---- | Parser for atomic expressions plus function applications.------ Base parser used in 'exprP' which adds in other operators.----expr1P :: ParseableV v => ParserV v (ExprV v)-expr1P-  =  try funAppP- <|> expr0P- -- | Expressions  exprP :: ParseableV v => ParserV v (ExprV v)-exprP =-  do+exprP = do     table <- gets fixityTable-    makeExprParser expr1P (flattenOpTable table)+    makeExprParser expr0P (flattenOpTable table)  data Assoc = AssocNone | AssocLeft | AssocRight @@ -968,7 +934,7 @@  -- | Built-in operator table, parameterised over the composition function. bops :: forall v. ParseableV v => Maybe (Located String -> ExprV v) -> OpTable v-bops cmpFun = foldl' (flip addOperator) initOpTable builtinOps+bops cmpFun = List.foldl' (flip addOperator) initOpTable builtinOps   where     -- Built-in Haskell operators, see https://www.haskell.org/onlinereport/decls.html#fixity     builtinOps :: [Fixity v]@@ -980,37 +946,55 @@                  , FInfix  (Just 5) "mod" (Just $ const $ 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+                 , FInfix  (Just 4) "=="  (Just $ const $ PAtom Eq)  AssocNone+                 , FInfix  (Just 4) "="   (Just $ const $ PAtom Eq)  AssocNone+                 , FInfix  (Just 4) "~~"  (Just $ const $ PAtom Ueq) AssocNone+                 , FInfix  (Just 4) "!="  (Just $ const $ PAtom Ne)  AssocNone+                 , FInfix  (Just 4) "/="  (Just $ const $ PAtom Ne)  AssocNone+                 , FInfix  (Just 4) "!~"  (Just $ const $ PAtom Une) AssocNone+                 , FInfix  (Just 4) "<"   (Just $ const $ PAtom Lt)  AssocNone+                 , FInfix  (Just 4) "<="  (Just $ const $ PAtom Le)  AssocNone+                 , FInfix  (Just 4) ">"   (Just $ const $ PAtom Gt)  AssocNone+                 , FInfix  (Just 4) ">="  (Just $ const $ PAtom Ge)  AssocNone++                 , FInfix  (Just 3) "&&"  (Just $ const $ \x y -> PAnd [x,y]) AssocRight+                 , FInfix  (Just 2) "||"  (Just $ const $ \x y -> POr [x,y]) AssocRight+                 , FInfix  (Just 1) "=>"  (Just $ const PImp) AssocRight+                 , FInfix  (Just 1) "==>" (Just $ const PImp) AssocRight+                 , FInfix  (Just 1) "<=>" (Just $ const PIff) AssocRight+                 , FPrefix (Just 9) "~"   (Just $ const PNot)                  ]+     applyCompose :: Maybe (Located String -> ExprV v -> ExprV v -> ExprV v)     applyCompose = (\f lop x y -> f lop `eApps` [x,y]) <$> cmpFun  -- | Parser for function applications.------ Andres, TODO: Why is this so complicated?--- funAppP :: ParseableV v => ParserV v (ExprV v)-funAppP      =  litP <|> exprFunP <|> simpleAppP-  where-    exprFunP = eApps <$> funSymbolP <*> funRhsP-    funRhsP  =  some expr0P-            <|> parens innerP-    innerP   = brackets (sepBy exprP semi)+funAppP = do+    f <- appliableExprP+    foldl EApp f <$> (<|>)+      (try $ parens $ brackets $ sepBy exprP semi)  -- special form: f ([e1; e2; ...; en])+      (many appliableExprP)                   -- normal function application: f e1 e2 ... en -    -- TODO:AZ the parens here should be superfluous, but it hits an infinite loop if removed-    simpleAppP     = EApp <$> parens exprP <*> parens exprP-    funSymbolP     = EVar <$> parseV+appliableExprP :: ParseableV v => ParserV v (ExprV v)+appliableExprP =+       trueP -- constant "true"+   <|> falseP -- constant "false"+   <|> (ESym <$> symconstP) -- string literal, starts with double-quote+   <|> (ECon <$> constantP) -- numeric literal, starts with a digit+   <|> botP+   <|> try tupleP -- tuple expressions, starts with "("+   <|> try (parens exprP) -- parenthesised expression, starts with "("+   <|> try (parens exprCastP) -- explicit type annotation, starts with "(", TODO: should be an operator rather than require parentheses?+   <|> EVar <$> parseV  -- identifier, starts with any letter or underscore+   <|> try (located (brackets (pure ())) >>= emptyListP) -- empty list, start with "["+   <|> try (located (brackets exprP) >>= singletonListP) -- singleton list, starts with "["+   <|> kvarPredP +-- | constant bottom, equivalent to "false"+botP :: ParserV v (ExprV v)+botP = reservedOp "_|_" >> return EBot+ -- | Parser for tuple expressions (two or more components). tupleP :: ParseableV v => ParserV v (ExprV v) tupleP = do@@ -1035,9 +1019,10 @@        t <- sortP        reservedOp "->"        ELam (x, t) <$> exprP+      <?> "lambda abstraction"  varSortP :: ParserV v Sort-varSortP  = FVar  <$> parens intP+varSortP  = FVar  <$> parens (fromInteger <$> integerP)  -- | Parser for function sorts without the "func" keyword. funcSortP :: ParserV v Sort@@ -1072,6 +1057,7 @@   <|> (fAppTC listFTyCon . pure <$> brackets sortP)   <|> (fAppTC <$> fTyConP <*> appArgsP)   <|> (fApp   <$> tvarP   <*> appArgsP)+  <|> (FNatNum <$> natural)  tvarP :: ParserV v Sort tvarP@@ -1100,31 +1086,6 @@ -- | Predicates ---------------------------------------------------------------- -------------------------------------------------------------------------------- --- | Parser for "atomic" predicates.------ This parser is reused by Liquid Haskell.----pred0P :: ParseableV v => ParserV v (ExprV v)-pred0P =  trueP -- constant "true"-      <|> falseP -- constant "false"-      <|> (reservedOp "??" >> makeUniquePGrad)-      <|> kvarPredP-      <|> fastIfP pIte predP -- "if-then-else", starts with "if"-      <|> try predrP -- binary relation, starts with anything that an expr can start with-      <|> parens predP -- parenthesised predicate, starts with "("-      <|> (reservedOp "?" *> exprP)-      <|> try funAppP-      <|> EVar <$> parseV -- identifier, starts with any letter or underscore-      <|> (reservedOp "&&" >> pGAnds <$> predsP) -- built-in prefix and-      <|> (reservedOp "||" >> POr  <$> predsP) -- built-in prefix or--makeUniquePGrad :: ParserV v (ExprV v)-makeUniquePGrad-  = do uniquePos <- getSourcePos-       return $ PGrad (KV $ symbol $ show uniquePos) (Su mempty) (srcGradInfo uniquePos) PTrue---- qmP    = reserved "?" <|> reserved "Bexp"- -- | Parser for the reserved constant "true". trueP :: ParserV v (ExprV v) trueP  = reserved "true"  >> return PTrue@@ -1150,53 +1111,23 @@ -- disjunction. -- predsP :: ParseableV v => ParserV v [ExprV v]-predsP = brackets $ sepBy predP semi+predsP = brackets $ sepBy exprP semi  -- | Parses a predicate. ----- Unlike for expressions, there is a built-in operator list.--- predP  :: ParseableV v => ParserV v (ExprV v)-predP  = makeExprParser pred0P lops-  where-    lops = [ [Prefix (reservedOp "~"    >> return PNot)]-           , [Prefix (reserved   "not"  >> return PNot)]-           , [InfixR (reservedOp "&&"   >> return pGAnd)]-           , [InfixR (reservedOp "||"   >> return (\x y -> POr [x,y]))]-           , [InfixR (reservedOp "=>"   >> return PImp)]-           , [InfixR (reservedOp "==>"  >> return PImp)]-           , [InfixR (reservedOp "="    >> return PIff)]-           , [InfixR (reservedOp "<=>"  >> return PIff)]-           , [InfixR (reservedOp "!="   >> return pNotIff)]-           , [InfixR (reservedOp "/="   >> return pNotIff)]-           ]--pNotIff :: ExprV v -> ExprV v -> ExprV v-pNotIff x y = PNot (PIff x y)---- | Parses a relation predicate.------ Binary relations connect expressions and predicates.----predrP :: ParseableV v => ParserV v (ExprV v)-predrP =-  (\ e1 r e2 -> r e1 e2) <$> exprP <*> brelP <*> exprP+predP  = exprP --- | Parses a relation symbol.------ There is a built-in table of available relations.----brelP ::  ParserV v (ExprV v -> ExprV v -> ExprV v)-brelP =  (reservedOp "==" >> return (PAtom Eq))-     <|> (reservedOp "="  >> return (PAtom Eq))-     <|> (reservedOp "~~" >> return (PAtom Ueq))-     <|> (reservedOp "!=" >> return (PAtom Ne))-     <|> (reservedOp "/=" >> return (PAtom Ne))-     <|> (reservedOp "!~" >> return (PAtom Une))-     <|> (reservedOp "<"  >> return (PAtom Lt))-     <|> (reservedOp "<=" >> return (PAtom Le))-     <|> (reservedOp ">"  >> return (PAtom Gt))-     <|> (reservedOp ">=" >> return (PAtom Ge))+existP :: ParseableV v => ParserV v (ExprV v)+existP = do+    allow <- gets allowExists+    if allow then do+      reserved "exists"+      bs <- brackets $ sepBy ((,) <$> bindP <*> sortP) comma+      _ <- dot+      PExist bs <$> exprP+     else+      empty  -------------------------------------------------------------------------------- -- | BareTypes -----------------------------------------------------------------@@ -1204,8 +1135,8 @@  -- | Refa refaP :: ParseableV v => ParserV v (ExprV v)-refaP =  try (pAnd <$> brackets (sepBy predP semi))-     <|> predP+refaP =  try (PAnd <$> brackets (sepBy exprP semi))+     <|> exprP   -- | (Sorted) Refinements with configurable sub-parsers@@ -1260,8 +1191,7 @@   pos    <- getSourcePos   n      <- upperIdP   params <- parens $ sepBy1 (qualParamP tP) comma-  _      <- colon-  body   <- predP+  body   <- braces exprP   return  $ mkQual n params body pos  qualParamP :: ParserV v Sort -> ParserV v QualParam@@ -1302,8 +1232,10 @@   _          <- spaces   _          <- reserved "="   _          <- spaces-  (lhs, rhs) <- braces $-      pairP exprP (reserved "=") exprP+  e <- braces exprP+  (lhs, rhs) <- case e of+                  PAtom Eq l r -> return (l, r)+                  _ -> error "Expected rewrite rule of the form: LHS = RHS"   return $ AutoRewrite args lhs rhs  @@ -1312,9 +1244,7 @@   name   <- symbolP   params <- parens        $ sepBy (symBindP sortP) comma   sort   <- colon        *> sortP-  body   <- reserved "=" *> braces (-              if sort == boolSort then predP else exprP-               )+  body   <- reserved "=" *> braces exprP   return  $ mkEquation name params body sort  defineLocalP :: Parser (Int, [(Symbol, Expr)])@@ -1331,7 +1261,7 @@         return (x, e)  matchP :: Parser Rewrite-matchP = SMeasure <$> symbolP <*> symbolP <*> many symbolP <*> (reserved "=" >> exprP)+matchP = SMeasure <$> symbolP <*> symbolP <*> many symbolP <*> braces exprP  pairsP :: Parser a -> Parser b -> Parser [(a, b)] pairsP aP bP = brackets $ sepBy (pairP aP (reserved ":") bP) semi@@ -1444,20 +1374,23 @@ intP :: ParserV v Int intP = fromInteger <$> natural +integerP :: ParserV v Integer+integerP =+        (try (char '-') >> negate <$> natural)+    <|> natural+ boolP :: Parser Bool boolP = (reserved "True" >> return True)     <|> (reserved "False" >> return False)  defsFInfo :: [Def a] -> FInfo a-defsFInfo defs = {- SCC "defsFI" -} Types.FI cm ws bs ebs lts dts kts qs binfo adts mempty mempty ae lrws mempty+defsFInfo defs = {- SCC "defsFI" -} Types.FI cm ws bs lts dts kts qs binfo adts mempty mempty ae lrws mempty   where     cm         = Misc.safeFromList                    "defs-cm"        [(cid c, c)         | Cst c       <- defs]     ws         = Misc.safeFromList                    "defs-ws"        [(i, w)              | Wfc w    <- defs, let i = Misc.thd3 (wrft w)]-    bs         = bindEnvFromList  $ exBinds ++ [(n,(x,r,a)) | IBind n x r a <- defs]-    ebs        =                    [ n                  | (n,_) <- exBinds]-    exBinds    =                    [(n, (x, RR t trueReft, a)) | EBind n x t a <- defs]+    bs         = bindEnvFromList    [(n,(x,r,a)) | IBind n x r a <- defs]     lts        = fromListSEnv       [(x, t)             | Con x t     <- defs]     dts        = fromListSEnv       [(x, t)             | Dis x t     <- defs]     kts        = KS $ S.fromList    [k                  | Kut k       <- defs]@@ -1468,7 +1401,7 @@     rews       =                    [r                  | Mat r       <- defs]     autoRWs    = M.fromList         [(arId , s)         | AutoRW arId s <- defs]     rwEntries  =                    [(i, f)             | RWMap fs   <- defs, (i,f) <- fs]-    rwMap      = foldl' insert (M.fromList []) rwEntries+    rwMap      = List.foldl' insert (M.fromList []) rwEntries                  where                    insert map' (cid', arId) =                      case M.lookup arId autoRWs of@@ -1498,28 +1431,6 @@   msg <- takeWhileP Nothing (const True) -- consume the rest of the input   return $ Crash [(i, Nothing)] msg -predSolP :: Parser Expr-predSolP = parens (predP  <* (comma >> iQualP))--iQualP :: Parser [Symbol]-iQualP = upperIdP >> parens (sepBy symbolP comma)--solution1P :: Parser (KVar, Expr)-solution1P = do-  reserved "solution:"-  k  <- kvP-  reservedOp ":="-  ps <- brackets $ sepBy predSolP semi-  return (k, simplify $ PAnd ps)-  where-    kvP = try kvarP <|> (KV <$> symbolP)--solutionP :: Parser (M.HashMap KVar Expr)-solutionP = M.fromList <$> sepBy solution1P spaces--solutionFileP :: Parser (FixResult Integer, M.HashMap KVar Expr)-solutionFileP = (,) <$> fixResultP natural <*> solutionP- --------------------------------------------------------------------------------  -- | Parse via the given parser, and obtain the rest of the input@@ -1547,6 +1458,7 @@                            , supply      = 0                            , layoutStack = Empty                            , numTyCons   = S.empty+                           , allowExists = False                            }  -- | Entry point for parsing, for testing.@@ -1555,8 +1467,11 @@ -- Fails with an exception on a parse error. -- doParse' :: Parser a -> SourceName -> String -> a-doParse' parser fileName input =-  case runParser (evalStateT (spaces *> parser <* eof) (initPState Nothing)) fileName input of+doParse' = doParse'' False++doParse'' :: Bool -> Parser a -> SourceName -> String -> a+doParse'' allowEx parser fileName input =+  case runParser (evalStateT (spaces *> parser <* eof) ((initPState Nothing) { allowExists = allowEx})) fileName input of     Left peb@(ParseErrorBundle errors posState) -> -- parse errors; we extract the first error from the error bundle       let         ((_, pos) :| _, _) = attachSourcePos errorOffset errors posState@@ -1600,7 +1515,7 @@  <|> (reserved "push"     >> return Push)  <|> (reserved "pop"      >> return Pop)  <|> (reserved "check"    >> return CheckSat)- <|> (reserved "assert"   >> (Assert Nothing <$> predP))+ <|> (reserved "assert"   >> (Assert Nothing <$> exprP))  <|> (reserved "distinct" >> (Distinct <$> brackets (sepBy exprP comma)))  cmdVarP :: Parser Command@@ -1632,9 +1547,6 @@ instance Inputable (FixResult Integer) where   rr' = doParse' $ fixResultP natural -instance Inputable (FixResult Integer, FixSolution) where-  rr' = doParse' solutionFileP- instance Inputable (FInfo ()) where   rr' = {- SCC "fInfoP" -} doParse' fInfoP @@ -1647,100 +1559,3 @@ instance Inputable [Command] where   rr' = doParse' commandsP -{--------------------------------------------------------------------------------------------- Testing ----------------------------------------------------------------------------------------------- A few tricky predicates for parsing--- myTest1 = "((((v >= 56320) && (v <= 57343)) => (((numchars a o ((i - o) + 1)) == (1 + (numchars a o ((i - o) - 1)))) && (((numchars a o (i - (o -1))) >= 0) && (((i - o) - 1) >= 0)))) && ((not (((v >= 56320) && (v <= 57343)))) => (((numchars a o ((i - o) + 1)) == (1 + (numchars a o (i - o)))) && ((numchars a o (i - o)) >= 0))))"------ myTest2 = "len x = len y - 1"--- myTest3 = "len x y z = len a b c - 1"--- myTest4 = "len x y z = len a b (c - 1)"--- myTest5 = "x >= -1"--- myTest6 = "(bLength v) = if n > 0 then n else 0"--- myTest7 = "(bLength v) = (if n > 0 then n else 0)"--- myTest8 = "(bLength v) = (n > 0 ? n : 0)"---sa  = "0"-sb  = "x"-sc  = "(x0 + y0 + z0) "-sd  = "(x+ y * 1)"-se  = "_|_ "-sf  = "(1 + x + _|_)"-sg  = "f(x,y,z)"-sh  = "(f((x+1), (y * a * b - 1), _|_))"-si  = "(2 + f((x+1), (y * a * b - 1), _|_))"--s0  = "true"-s1  = "false"-s2  = "v > 0"-s3  = "(0 < v && v < 100)"-s4  = "(x < v && v < y+10 && v < z)"-s6  = "[(v > 0)]"-s6' = "x"-s7' = "(x <=> y)"-s8' = "(x <=> a = b)"-s9' = "(x <=> (a <= b && b < c))"--s7  = "{ v: Int | [(v > 0)] }"-s8  = "x:{ v: Int | v > 0 } -> {v : Int | v >= x}"-s9  = "v = x+y"-s10 = "{v: Int | v = x + y}"--s11 = "x:{v:Int | true } -> {v:Int | true }"-s12 = "y : {v:Int | true } -> {v:Int | v = x }"-s13 = "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}"-s14 = "x:{v:a  | true} -> y:{v:b | true } -> {v:a | (x < v && v < y) }"-s15 = "x:Int -> Bool"-s16 = "x:Int -> y:Int -> {v:Int | v = x + y}"-s17 = "a"-s18 = "x:a -> Bool"-s20 = "forall a . x:Int -> Bool"--s21 = "x:{v : GHC.Prim.Int# | true } -> {v : Int | true }"--r0  = (rr s0) :: Pred-r0' = (rr s0) :: [Refa]-r1  = (rr s1) :: [Refa]---e1, e2  :: Expr-e1  = rr "(k_1 + k_2)"-e2  = rr "k_1"--o1, o2, o3 :: FixResult Integer-o1  = rr "SAT "-o2  = rr "UNSAT [1, 2, 9,10]"-o3  = rr "UNSAT []"---- sol1 = doParse solution1P "solution: k_5 := [0 <= VV_int]"--- sol2 = doParse solution1P "solution: k_4 := [(0 <= VV_int)]"--b0, b1, b2, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13 :: BareType-b0  = rr "Int"-b1  = rr "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y}"-b2  = rr "x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x - y}"-b4  = rr "forall a . x : a -> Bool"-b5  = rr "Int -> Int -> Int"-b6  = rr "(Int -> Int) -> Int"-b7  = rr "({v: Int | v > 10} -> Int) -> Int"-b8  = rr "(x:Int -> {v: Int | v > x}) -> {v: Int | v > 10}"-b9  = rr "x:Int -> {v: Int | v > x} -> {v: Int | v > 10}"-b10 = rr "[Int]"-b11 = rr "x:[Int] -> {v: Int | v > 10}"-b12 = rr "[Int] -> String"-b13 = rr "x:(Int, [Bool]) -> [(String, String)]"---- b3 :: BareType--- b3  = rr "x:Int -> y:Int -> {v:Bool | ((v is True) <=> x = y)}"--m1 = ["len :: [a] -> Int", "len (Nil) = 0", "len (Cons x xs) = 1 + len(xs)"]-m2 = ["tog :: LL a -> Int", "tog (Nil) = 100", "tog (Cons y ys) = 200"]--me1, me2 :: Measure.Measure BareType Symbol-me1 = (rr $ intercalate "\n" m1)-me2 = (rr $ intercalate "\n" m2)--}
src/Language/Fixpoint/Smt/Interface.hs view
@@ -45,13 +45,14 @@     , smtDecls     , smtDefineFunc     , smtAssert+    , smtAssertDecl     , smtFuncDecl     , smtAssertAxiom     , smtCheckUnsat-    , smtCheckSat     , smtBracket, smtBracketAt     , smtDistinct     , smtPush, smtPop+    , smtComment      -- * Check Validity     , checkValid@@ -59,10 +60,12 @@     , checkValidWithContext     , checkValids +    , funcSortVars+     ) where  import           Language.Fixpoint.Types.Config ( SMTSolver (..), solverFlags-                                                , Config (solver, smtTimeout, gradual, stringTheory, save))+                                                , Config (solver, smtTimeout, noStringTheory, save, allowHO)) import qualified Language.Fixpoint.Misc          as Misc import           Language.Fixpoint.Types.Errors import           Language.Fixpoint.Utils.Files@@ -73,6 +76,7 @@ import           Language.Fixpoint.Smt.Serialize () import           Control.Applicative      ((<|>)) import           Control.Monad+import           Control.Monad.State import           Control.Exception import           Data.ByteString.Builder (Builder) import qualified Data.ByteString.Builder as BS@@ -80,6 +84,7 @@ import qualified Data.ByteString.Lazy.Char8 as Char8 import           Data.Char import qualified Data.HashMap.Strict      as M+import           Data.List                (uncons) import           Data.Maybe              (fromMaybe) import qualified Data.Text                as T import qualified Data.Text.Encoding       as TE@@ -102,6 +107,7 @@ import qualified SMTLIB.Backends.Process as Process import qualified Language.Fixpoint.Conditional.Z3 as Conditional.Z3 import Control.Concurrent.Async (async)+import GHC.Stack (HasCallStack)  {- runFile f@@ -117,36 +123,43 @@        return zs -} -checkValidWithContext :: Context -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool-checkValidWithContext me xts p q =-  smtBracket me "checkValidWithContext" $-    checkValid' me xts p q+checkValidWithContext+  :: HasCallStack => [(Symbol, Sort)] -> Expr -> Expr -> SmtM Bool+checkValidWithContext xts p q =+  smtBracket "checkValidWithContext" $+    checkValid' xts p q  -- | type ClosedPred E = {v:Pred | subset (vars v) (keys E) } -- checkValid :: e:Env -> ClosedPred e -> ClosedPred e -> IO Bool-checkValid :: Config -> FilePath -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool+checkValid+  :: HasCallStack+  => Config -> FilePath -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool checkValid cfg f xts p q = do   me <- makeContext cfg f-  checkValid' me xts p q+  evalStateT (checkValid' xts p q) me -checkValid' :: Context -> [(Symbol, Sort)] -> Expr -> Expr -> IO Bool-checkValid' me xts p q = do-  smtDecls me xts-  smtAssert me $ pAnd [p, PNot q]-  smtCheckUnsat me+checkValid' :: HasCallStack => [(Symbol, Sort)] -> Expr -> Expr -> SmtM Bool+checkValid' xts p q = do+  smtDecls xts+  smtAssertDecl $ pAnd [p, PNot q]+  smtCheckUnsat  -- | If you already HAVE a context, where all the variables have declared types --   (e.g. if you want to make MANY repeated Queries)  -- checkValid :: e:Env -> [ClosedPred e] -> IO [Bool] checkValids :: Config -> FilePath -> [(Symbol, Sort)] -> [Expr] -> IO [Bool]-checkValids cfg f xts ps-  = do me <- makeContext cfg f-       smtDecls me xts-       forM ps $ \p ->-          smtBracket me "checkValids" $-            smtAssert me (PNot p) >> smtCheckUnsat me+checkValids cfg f xts ps = do+  me <- makeContext cfg f+  evalStateT (checkValids' xts ps) me +checkValids' :: [(Symbol, Sort)] -> [Expr] -> SmtM [Bool]+checkValids' xts ps = do+  smtDecls xts+  forM ps $ \p ->+     smtBracket "checkValids" $+       smtAssert (PNot p) >> smtCheckUnsat+ -- debugFile :: FilePath -- debugFile = "DEBUG.smt2" @@ -154,42 +167,55 @@ -- | SMT IO -------------------------------------------------------------------- -------------------------------------------------------------------------------- +commandRaw :: Maybe Handle -> SMTLIB.Backends.Solver -> Bool -> Builder -> IO Response+commandRaw ctxLog ctxSolver ctxVerbose cmdBS = do+  resp <- SMTLIB.Backends.command ctxSolver cmdBS+  let respTxt =+        TE.decodeUtf8With (const $ const $ Just ' ') $+        LBS.toStrict resp+  case A.parseOnly responseP respTxt of+    Left e  -> Misc.errorstar $ "SMTREAD:" ++ e+    Right r -> do+      let textResponse = "; SMT Says: " <> T.pack (show r)+      forM_ ctxLog $ \h ->+        Data.Text.IO.hPutStrLn h textResponse+      when ctxVerbose $+        Data.Text.IO.putStrLn textResponse+      return r+ -------------------------------------------------------------------------------- {-# SCC command #-}-command              :: Context -> Command -> IO Response+command  :: HasCallStack => Command -> SmtM Response ---------------------------------------------------------------------------------command Ctx{..} !cmd       = do+command !cmd       = do   -- whenLoud $ do LTIO.appendFile debugFile (s <> "\n")   --               LTIO.putStrLn ("CMD-RAW:" <> s <> ":CMD-RAW:DONE")-  forM_ ctxLog $ \h -> do+  ctxLog <- gets ctxLog+  ctxSolver <- gets ctxSolver+  ctxVerbose <- gets ctxVerbose+  cmdBS <- liftSym $ runSmt2 cmd+  forM_ ctxLog $ \h -> lift $ do     BS.hPutBuilder h cmdBS     LBS.hPutStr h "\n"-  case cmd of-    CheckSat   -> commandRaw-    GetValue _ -> commandRaw+  lift $ case cmd of+    CheckSat   -> commandRaw ctxLog ctxSolver ctxVerbose cmdBS+    GetValue _ -> commandRaw ctxLog ctxSolver ctxVerbose cmdBS     _          -> SMTLIB.Backends.command_ ctxSolver cmdBS >> return Ok-  where-    commandRaw      = do-      resp <- SMTLIB.Backends.command ctxSolver cmdBS-      let respTxt =-            TE.decodeUtf8With (const $ const $ Just ' ') $-            LBS.toStrict resp-      parse respTxt-    cmdBS = {-# SCC "Command-runSmt2" #-} runSmt2 ctxSymEnv cmd-    parse resp      = do-      case A.parseOnly responseP resp of-        Left e  -> Misc.errorstar $ "SMTREAD:" ++ e-        Right r -> do-          let textResponse = "; SMT Says: " <> T.pack (show r)-          forM_ ctxLog $ \h ->-            Data.Text.IO.hPutStrLn h textResponse-          when ctxVerbose $-            Data.Text.IO.putStrLn textResponse-          return r -smtSetMbqi :: Context -> IO ()-smtSetMbqi me = interact' me SetMbqi+-- | A variant of `command` that accepts a pre-built command+commandB :: Builder -> SmtM Response+--------------------------------------------------------------------------------+commandB cmdBS       = do+  ctxLog <- gets ctxLog+  ctxSolver <- gets ctxSolver+  forM_ ctxLog $ \h -> lift $ do+    BS.hPutBuilder h cmdBS+    LBS.hPutStr h "\n"+  lift $ SMTLIB.Backends.command_ ctxSolver cmdBS >> return Ok +smtSetMbqi :: SmtM ()+smtSetMbqi = interact' SetMbqi+ type SmtParser a = Parser T.Text a  responseP :: SmtParser Response@@ -254,12 +280,11 @@     where        smtFile = extFileName Smt2 f -makeContextWithSEnv :: Config -> FilePath -> SymEnv -> [Equation] -> IO Context+makeContextWithSEnv :: Config -> FilePath -> SymEnv -> DefinedFuns -> IO Context makeContextWithSEnv cfg f env defns = do-  ctx     <- makeContext cfg f+  ctx      <- makeContext cfg f   let ctx' = ctx {ctxSymEnv = env, ctxDefines = defns}-  declare ctx'-  return ctx'+  execStateT declare ctx'  makeContextNoLog :: Config -> IO Context makeContextNoLog cfg = do@@ -307,16 +332,22 @@          Cvc5    -> makeProcess ctxLog $                       Process.defaultConfig                              { Process.exe = "cvc5"-                             , Process.args = ["-L", "smtlib2"] }+                             , Process.args = ["-L", "smtlib2", "--arrays-exp"] }        solver <- SMTLIB.Backends.initSolver SMTLIB.Backends.Queuing backend        loud <- isLoud        return Ctx { ctxSolver    = solver-                  , ctxElabF     = solverFlags slv+                  , ctxElabF     = solverFlags cfg                   , ctxClose     = closeIO                   , ctxLog       = ctxLog                   , ctxVerbose   = loud                   , ctxSymEnv    = mempty+                  , ctxIxs       = []                   , ctxDefines   = mempty+                  -- This is a heurstic to avoid generating large sequences of unused `lam_arg` symbols+                  -- when there's no higher-order reasoning. It might require some tuning on larger codebases+                  -- if `unknown function/constant lam_arg$XXX` errors are encountered.+                  , ctxLams      = allowHO cfg+                  , config       = cfg                   }  -- | Close file handles and release the solver backend's resources.@@ -333,9 +364,11 @@   | s == Z3 || s == Z3mem     = do v <- getZ3Version me          checkValidStringFlag Z3 v cfg-         return $ makeMbqi cfg ++ makeTimeout cfg ++ Thy.preamble cfg Z3+         return $ makeMbqi ++ makeTimeout cfg ++ Thy.preamble cfg Z3   | otherwise     = checkValidStringFlag s [] cfg >> return (Thy.preamble cfg s)+  where+    makeMbqi = ["\n(set-option :smt.mbqi false)"]  getZ3Version :: Context -> IO [Int] getZ3Version me@@ -361,58 +394,59 @@  noString :: SMTSolver -> [Int] -> Config -> Bool noString smt v cfg-  =  stringTheory cfg-  && not (smt == Z3 && (v >= [4, 4, 2]))-+  =  not (noStringTheory cfg)+  && not (smt == Cvc5 || (smt == Z3 && (v >= [4, 4, 2]))) ----------------------------------------------------------------------------- -- | SMT Commands ----------------------------------------------------------- ----------------------------------------------------------------------------- -smtPush, smtPop   :: Context -> IO ()-smtPush me        = interact' me Push-smtPop me         = interact' me Pop+smtPush, smtPop :: SmtM ()+smtPush = interact' Push+smtPop  = interact' Pop -smtDecls :: Context -> [(Symbol, Sort)] -> IO ()-smtDecls = mapM_ . uncurry . smtDecl+smtComment :: T.Text -> SmtM ()+smtComment t = interact' (Comment t) -smtDecl :: Context -> Symbol -> Sort -> IO ()-smtDecl me x t = interact' me ({- notracepp msg $ -} Declare (symbolSafeText x) ins' out')+smtDecls :: [(Symbol, Sort)] -> SmtM ()+smtDecls = mapM_ $ uncurry smtDecl++smtDecl :: Symbol -> Sort -> SmtM ()+smtDecl x t = do+  me <- get+  let env = seData (ctxSymEnv me)+  let ins' = sortSmtSort False env <$> ins+  let out' = sortSmtSort False env     out+  interact' (notracepp _msg $ Declare (symbolSafeText x) ins' out')   where-    ins'       = sortSmtSort False env <$> ins-    out'       = sortSmtSort False env     out     (ins, out) = deconSort t-    _msg        = "smtDecl: " ++ showpp (x, t, ins, out)-    env        = seData (ctxSymEnv me)+    _msg       = "smtDecl: " ++ showpp (x, t, ins, out) -smtFuncDecl :: Context -> T.Text -> ([SmtSort],  SmtSort) -> IO ()-smtFuncDecl me x (ts, t) = interact' me (Declare x ts t)+smtFuncDecl :: T.Text -> ([SmtSort],  SmtSort) -> SmtM ()+smtFuncDecl x (ts, t) = interact' (Declare x ts t) -smtDataDecl :: Context -> [DataDecl] -> IO ()-smtDataDecl me ds = interact' me (DeclData ds)+smtDataDecl :: [DataDecl] -> SmtM ()+smtDataDecl ds = interact' (DeclData ds)  deconSort :: Sort -> ([Sort], Sort) deconSort t = case functionSort t of                 Just (_, ins, out) -> (ins, out)                 Nothing            -> ([], t) --- hack now this is used only for checking gradual condition.-smtCheckSat :: Context -> Expr -> IO Bool-smtCheckSat me p- = smtAssert me p >> (ans <$> command me CheckSat)- where-   ans Sat = True-   ans _   = False+smtAssert :: Expr -> SmtM ()+smtAssert p = interact' (Assert Nothing p) -smtAssert :: Context -> Expr -> IO ()-smtAssert me p = interact' me (Assert Nothing p)+-- the following three functions will emit additional `apply`,+-- `coerce`, and `lambda` symbols for fresh function sorts as needed+smtAssertDecl :: HasCallStack => Expr -> SmtM ()+smtAssertDecl p = interactDecl' (Assert Nothing p) -smtDefineEqn :: Context -> Equation -> IO ()-smtDefineEqn me Equ {..} = smtDefineFunc me eqName eqArgs eqSort eqBody+smtDefineEqn :: Equation -> SmtM ()+smtDefineEqn Equ {..} = smtDefineFunc eqName eqArgs eqSort eqBody -smtDefineFunc :: Context -> Symbol -> [(Symbol, F.Sort)] -> F.Sort -> Expr -> IO ()-smtDefineFunc me name symList rsort e =-  let env = seData (ctxSymEnv me)-  in interact' me $+smtDefineFunc :: Symbol -> [(Symbol, F.Sort)] -> F.Sort -> Expr -> SmtM ()+smtDefineFunc name symList rsort e =+  do env <- gets (seData . ctxSymEnv)+     interactDecl' $         DefineFunc           name           (map (sortSmtSort False env <$>) symList)@@ -421,34 +455,60 @@  ----------------------------------------------------------------- -smtAssertAxiom :: Context -> Triggered Expr -> IO ()-smtAssertAxiom me p  = interact' me (AssertAx p)+smtAssertAxiom :: Triggered Expr -> SmtM ()+smtAssertAxiom p  = interact' (AssertAx p) -smtDistinct :: Context -> [Expr] -> IO ()-smtDistinct me az = interact' me (Distinct az)+smtDistinct :: [Expr] -> SmtM ()+smtDistinct az = interact' (Distinct az) -smtCheckUnsat :: Context -> IO Bool-smtCheckUnsat me  = respSat <$> command me CheckSat+smtCheckUnsat :: HasCallStack => SmtM Bool+smtCheckUnsat = respSat <$> command CheckSat -smtBracketAt :: SrcSpan -> Context -> String -> IO a -> IO a-smtBracketAt sp x y z = smtBracket x y z `catch` dieAt sp+smtBracketAt :: SrcSpan -> String -> SmtM a -> SmtM a+smtBracketAt sp _msg a =+  smtBracket _msg a `catchSMT` dieAt sp -smtBracket :: Context -> String -> IO a -> IO a-smtBracket me _msg a   = do-  smtPush me+-- | `smtBracket` adds a new level to the apply stack and saves the last fresh index+--   on the index stack before the action, and reverts these changes after the action.+smtBracket :: String -> SmtM a -> SmtM a+smtBracket msg a = do+  smtComment (T.pack $ "smtBracket - start: " ++ msg)+  smtPush+  modify $ \ctx ->+    let env = ctxSymEnv ctx in+    ctx { ctxSymEnv = env { seAppls = pushAppls (seAppls env) }+        , ctxIxs = seIx env : ctxIxs ctx}   r <- a-  smtPop me+  smtPop+  smtComment (T.pack $ "smtBracket - end: " ++ msg)+  modify $ \ctx ->+    let env = ctxSymEnv ctx+        (i , is) = fromMaybe (0, []) (uncons $ ctxIxs ctx)+      in+    ctx { ctxSymEnv = env {seAppls = popAppls (seAppls env) , seIx = i}+        , ctxIxs = is}   return r -respSat :: Response -> Bool+respSat :: HasCallStack => Response -> Bool respSat Unsat   = True respSat Sat     = False respSat Unknown = False respSat r       = die $ err dummySpan $ text ("crash: SMTLIB2 respSat = " ++ show r) -interact' :: Context -> Command -> IO ()-interact' me cmd  = void $ command me cmd+interact' :: Command -> SmtM ()+interact' cmd  = void $ command cmd +-- | a variant of `interact'` which also emits fresh+--   `apply`, `coerce`, and `lambda` symbols+interactDecl' :: HasCallStack => Command -> SmtM ()+interactDecl' cmd  = do+  cmdBS <- liftSym $ runSmt2 cmd+  ctx <- get+  let env = ctxSymEnv ctx+  let ats = funcSortVars (ctxLams ctx) env+  forM_ ats $ uncurry smtFuncDecl+  put (ctx {ctxSymEnv = env {seAppls = mergeTopAppls (seApplsCur env) (seAppls env), seApplsCur = M.empty} })+  void $ commandB cmdBS  makeTimeout :: Config -> [Builder] makeTimeout cfg@@ -456,36 +516,28 @@   | otherwise                = [""]  -makeMbqi :: Config -> [Builder]-makeMbqi cfg-  | gradual cfg = [""]-  | otherwise   = ["\n(set-option :smt.mbqi false)"]-- ---------------------------------------------------------------------------------declare :: Context -> IO ()+declare :: SmtM () ---------------------------------------------------------------------------------declare me = do-  forM_ dss    $           smtDataDecl me-  forM_ thyXTs $ uncurry $ smtDecl     me-  forM_ qryXTs $ uncurry $ smtDecl     me-  forM_ ats    $ uncurry $ smtFuncDecl me-  forM_ defs   $           smtDefineEqn me-  forM_ ess    $           smtDistinct me-  forM_ axs    $           smtAssert   me-  where-    env        = ctxSymEnv me-    dss        = dataDeclarations          env-    lts        = F.toListSEnv . F.seLits $ env-    ess        = distinctLiterals  lts-    axs        = Thy.axiomLiterals lts-    thyXTs     =             [ (x, t) | (x, t) <- xts, symKind env x == Just F.Uninterp ]-    qryXTs     = fmap tx <$> [ (x, t) | (x, t) <- xts, symKind env x == Nothing ]-    -- isKind n   = (n ==)  . symKind env . fst-    xts        = symbolSorts (F.seSort env)-    tx         = elaborate (ElabParam (ctxElabF me) "declare" env)-    ats        = funcSortVars env-    defs       = ctxDefines me+declare = do+  me <- get+  let env        = ctxSymEnv me+  let xts        = symbolSorts (F.seSort env)+  let tx         = elaborate (ElabParam (ctxElabF me) "declare" env)+  let lts        = F.toListSEnv . F.seLits $ env+  let dss        = dataDeclarations          env+  let thyXTs     =             [ (x, t) | (x, t) <- xts, symKind env x == Just F.Uninterp ]+  let qryXTs     = fmap tx <$> [ (x, t) | (x, t) <- xts, symKind env x == Nothing ]+  -- let isKind n   = (n ==)  . symKind env . fst+  let MkDefinedFuns defs = ctxDefines me+  let ess        = distinctLiterals  lts+  let axs        = Thy.axiomLiterals (config me) lts+  forM_ dss              smtDataDecl+  forM_ thyXTs $ uncurry smtDecl+  forM_ qryXTs $ uncurry smtDecl+  forM_ defs             smtDefineEqn+  forM_ ess              smtDistinct+  forM_ axs              smtAssert  symbolSorts :: F.SEnv F.Sort -> [(F.Symbol, F.Sort)] symbolSorts env = [(x, tx t) | (x, t) <- F.toListSEnv env ]@@ -496,14 +548,24 @@ dataDeclarations :: SymEnv -> [[DataDecl]] dataDeclarations = orderDeclarations . map snd . F.toListSEnv . F.seData -funcSortVars :: F.SymEnv -> [(T.Text, ([F.SmtSort], F.SmtSort))]-funcSortVars env  = [(var applyName  t       , appSort t) | t <- ts]-                 ++ [(var coerceName t       , ([t1],t2)) | t@(t1, t2) <- ts]-                 ++ [(var lambdaName t       , lamSort t) | t <- ts]-                 ++ [(var (lamArgSymbol i) t , argSort t) | t@(_,F.SInt) <- ts, i <- [1..Thy.maxLamArg] ]+-- | See 'F.seApplsCur' for explanation.+funcSortVars :: Bool -> F.SymEnv -> [(T.Text, ([F.SmtSort], F.SmtSort))]+funcSortVars lams env =+    concatMap symbolsForTag $ M.toList $ F.seApplsCur env   where-    var n         = F.symbolAtSmtName n env ()-    ts            = M.keys (F.seAppls env)+    symbolsForTag (t, i) =+      let applySym  = symbolAtSortIndex applyName i+          coerceSym = symbolAtSortIndex coerceName i+          lamSym    = symbolAtSortIndex lambdaName i+          argSyms   = if lams && snd t == F.SInt+                        then [ (symbolAtSortIndex (lamArgSymbol j) i, argSort t)+                             | j <- [1..Thy.maxLamArg] ]+                        else []+      in  (applySym, appSort t)+        : (coerceSym, ([fst t], snd t))+        : (lamSym, lamSort t)+        : argSyms+     appSort (s,t) = ([F.SInt, s], t)     lamSort (s,t) = ([s, t], F.SInt)     argSort (s,_) = ([]    , s)
src/Language/Fixpoint/Smt/Serialize.hs view
@@ -14,6 +14,7 @@  module Language.Fixpoint.Smt.Serialize (smt2SortMono) where +import           Control.Monad.State import           Data.ByteString.Builder (Builder) import           Language.Fixpoint.SortCheck import           Language.Fixpoint.Types@@ -27,47 +28,65 @@ -- import Debug.Trace (trace)  instance SMTLIB2 (Symbol, Sort) where-  smt2 env c@(sym, t) = -- build "({} {})" (smt2 env sym, smt2SortMono c env t)-                        parenSeqs [smt2 env sym, smt2SortMono c env t]+  smt2 c@(sym, t) =+    -- build "({} {})" (smt2 env sym, smt2SortMono c env t)+    do s <- smt2 sym+       ss <- smt2SortMono c t+       pure $ parenSeqs [s , ss] -smt2SortMono, smt2SortPoly :: (PPrint a) => a -> SymEnv -> Sort -> Builder+instance SMTLIB2 (Symbol, Expr) where+  smt2 (sym, e) =+    do s <- smt2 sym+       ss <- smt2 e+       pure $ parenSeqs [s, ss]++smt2SortMono, smt2SortPoly :: (PPrint a) => a -> Sort -> SymM Builder smt2SortMono = smt2Sort False smt2SortPoly = smt2Sort True -smt2Sort :: (PPrint a) => Bool -> a -> SymEnv -> Sort -> Builder-smt2Sort poly _ env t = smt2 env (Thy.sortSmtSort poly (seData env) t)+smt2Sort :: (PPrint a) => Bool -> a -> Sort -> SymM Builder+smt2Sort poly _ t =+  do env <- get+     smt2 (Thy.sortSmtSort poly (seData env) t) -smt2data :: SymEnv -> [DataDecl] -> Builder-smt2data env = smt2data' env . map padDataDecl+smt2data :: [DataDecl] -> SymM Builder+smt2data = smt2data' . map padDataDecl -smt2data' :: SymEnv -> [DataDecl] -> Builder-smt2data' env ds = seqs [ parens $ smt2many (smt2dataname env <$> ds)-                        , parens $ smt2many (smt2datactors env <$> ds)-                        ]+smt2data' :: [DataDecl] -> SymM Builder+smt2data' ds =+  do n <- traverse smt2dataname ds+     d <- traverse smt2datactors ds+     pure $ seqs [ parens $ smt2many n , parens $ smt2many d ]  -smt2dataname :: SymEnv -> DataDecl -> Builder-smt2dataname env (DDecl tc as _) = parenSeqs [name, n]-  where-    name  = smt2 env (symbol tc)-    n     = smt2 env as+smt2dataname :: DataDecl -> SymM Builder+smt2dataname (DDecl tc as _) =+  do name <- smt2 (symbol tc)+     n    <- smt2 as+     pure $ parenSeqs [name, n]  -smt2datactors :: SymEnv -> DataDecl -> Builder-smt2datactors env (DDecl _ as cs)-  | as > 0       = parenSeqs ["par", parens tvars, parens ds]-  | otherwise    =                                 parens ds+smt2datactors :: DataDecl -> SymM Builder+smt2datactors (DDecl _ as cs) =+  do ds <- traverse (smt2ctor as) cs+     if as > 0+      then do tvars <- traverse smt2TV [0..(as-1)]+              pure $ parenSeqs ["par", parens (smt2many tvars), parens (smt2many ds)]+      else pure $                                               parens (smt2many ds)   where-    tvars        = smt2many (smt2TV <$> [0..(as-1)])-    smt2TV       = smt2 env . SVar-    ds           = smt2many (smt2ctor env as <$> cs)--smt2ctor :: SymEnv -> Int -> DataCtor -> Builder+    smt2TV = smt2 . SVar -smt2ctor env as (DCtor c fs)  = parenSeqs (smt2 env c : (smt2field env as <$> fs))+smt2ctor :: Int -> DataCtor -> SymM Builder+smt2ctor as (DCtor c fs) =+  do h <- smt2 c+     t <- traverse (smt2field as) fs+     pure $ parenSeqs (h : t) -smt2field :: SymEnv -> Int -> DataField -> Builder-smt2field env as d@(DField x t) = parenSeqs [smt2 env x, smt2SortPoly d env $ mkPoly as t]+smt2field :: Int -> DataField -> SymM Builder+smt2field as d@(DField x t) =+  do s <- smt2 x+     ss <- smt2SortPoly d $ mkPoly as t+     pure $ parenSeqs [s , ss]  -- | SMTLIB/Z3 don't like "unused" type variables; they get pruned away and --   cause wierd hassles. See tests/pos/adt_poly_dead.fq for an example.@@ -95,120 +114,153 @@     go is _        = is  instance SMTLIB2 Symbol where-  smt2 env s-    | Just t <- Thy.smt2Symbol env s = t-  smt2 _ s                           = symbolBuilder s-+  smt2 s = do env <- get+              case Thy.smt2Symbol env s of+                Just t  -> pure t+                Nothing -> pure $ symbolBuilder s instance SMTLIB2 Int where-  smt2 _ = Builder.fromString . show+  smt2 i = pure $ Builder.fromString $ show i  instance SMTLIB2 LocSymbol where-  smt2 env = smt2 env . val+  smt2 = smt2 . val  instance SMTLIB2 SymConst where-  smt2 env = smt2 env . symbol+  smt2 = smt2 . symbol  instance SMTLIB2 Constant where-  smt2 _ (I n)   = bShow n-  smt2 _ (R d)   = bFloat d-  smt2 _ (L t _) = fromText t+  smt2 (I n)   = pure $ bShow n+  smt2 (R d)   = pure $ bFloat d+  smt2 (L t s)+    | isString s = pure $ quotes $ fromText t+    | otherwise  = pure $ fromText t  instance SMTLIB2 Bop where-  smt2 _ Plus   = "+"-  smt2 _ Minus  = "-"-  smt2 _ Times  = symbolBuilder mulFuncName-  smt2 _ Div    = symbolBuilder divFuncName-  smt2 _ RTimes = "*"-  smt2 _ RDiv   = "/"-  smt2 _ Mod    = "mod"+  smt2 Plus   = pure "+"+  smt2 Minus  = pure "-"+  smt2 Times  = pure $ symbolBuilder mulFuncName+  smt2 Div    = pure $ symbolBuilder divFuncName+  smt2 RTimes = pure "*"+  smt2 RDiv   = pure "/"+  smt2 Mod    = pure "mod"  instance SMTLIB2 Brel where-  smt2 _ Eq    = "="-  smt2 _ Ueq   = "="-  smt2 _ Gt    = ">"-  smt2 _ Ge    = ">="-  smt2 _ Lt    = "<"-  smt2 _ Le    = "<="-  smt2 _ _     = errorstar "SMTLIB2 Brel"+  smt2 Eq  = pure "="+  smt2 Ueq = pure "="+  smt2 Gt  = pure ">"+  smt2 Ge  = pure ">="+  smt2 Lt  = pure "<"+  smt2 Le  = pure "<="+  smt2 _   = errorstar "SMTLIB2 Brel"  -- NV TODO: change the way EApp is printed instance SMTLIB2 Expr where-  smt2 env (ESym z)         = smt2 env z-  smt2 env (ECon c)         = smt2 env c-  smt2 env (EVar x)         = smt2 env x-  smt2 env e@(EApp _ _)     = smt2App env e-  smt2 env (ENeg e)         = parenSeqs ["-", smt2 env e]-  smt2 env (EBin o e1 e2)   = parenSeqs [smt2 env o, smt2 env e1, smt2 env e2]-  smt2 env (EIte e1 e2 e3)  = parenSeqs ["ite", smt2 env e1, smt2 env e2, smt2 env e3]-  smt2 env (ECst e t)       = smt2Cast env e t-  smt2 _   PTrue            = "true"-  smt2 _   PFalse           = "false"-  smt2 _   (PAnd [])        = "true"-  smt2 env (PAnd ps)        = parenSeqs ["and", smt2s env ps]-  smt2 _   (POr [])         = "false"-  smt2 env (POr ps)         = parenSeqs ["or", smt2s env ps]-  smt2 env (PNot p)         = parenSeqs ["not", smt2 env p]-  smt2 env (PImp p q)       = parenSeqs ["=>", smt2 env p, smt2 env q]-  smt2 env (PIff p q)       = parenSeqs ["=", smt2 env p, smt2 env q]-  smt2 env (PExist [] p)    = smt2 env p-  smt2 env (PExist xs p)    = parenSeqs ["exists", parens (smt2s env xs), smt2 env p]-  smt2 env (PAll   [] p)    = smt2 env p-  smt2 env (PAll   xs p)    = parenSeqs ["forall", parens (smt2s env xs), 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 t1 t2 e) = smt2Coerc env t1 t2 e-  smt2 _   e                = panic ("smtlib2 Pred  " ++ show e)--+  smt2 (ESym z)         = smt2 z+  smt2 (ECon c)         = smt2 c+  smt2 (EVar x)         = smt2 x+  smt2 e@(EApp _ _)     = smt2App e+  smt2 (ENeg e)         = do s <- smt2 e+                             pure $ parenSeqs ["-", s]+  smt2 (EBin o e1 e2)   = do so <- smt2 o+                             s1 <- smt2 e1+                             s2 <- smt2 e2+                             pure $ parenSeqs [so, s1, s2]+  smt2 (ELet x e1 e2)   = do s1 <- smt2 (x, e1)+                             s2 <- smt2 e2+                             pure $ parenSeqs ["let", parens s1, s2]+  smt2 (EIte e1 e2 e3)  = do s1 <- smt2 e1+                             s2 <- smt2 e2+                             s3 <- smt2 e3+                             pure $ parenSeqs ["ite", s1, s2, s3]+  smt2 (ECst e t)       = smt2Cast e t+  smt2 PTrue            = pure "true"+  smt2 PFalse           = pure "false"+  smt2 (PAnd [])        = pure "true"+  smt2 (PAnd ps)        = do s <- smt2s ps+                             pure $ parenSeqs ["and", s]+  smt2 (POr [])         = pure "false"+  smt2 (POr ps)         = do s <- smt2s ps+                             pure $ parenSeqs ["or", s]+  smt2 (PNot p)         = do s <- smt2 p+                             pure $ parenSeqs ["not", s]+  smt2 (PImp p q)       = do s1 <- smt2 p+                             s2 <- smt2 q+                             pure $ parenSeqs ["=>", s1, s2]+  smt2 (PIff p q)       = do s1 <- smt2 p+                             s2 <- smt2 q+                             pure $ parenSeqs ["=", s1, s2]+  smt2 (PExist [] p)    = smt2 p+  smt2 (PExist xs p)    = do s <- smt2s xs+                             s1 <- smt2 p+                             pure $ parenSeqs ["exists", parens s, s1]+  smt2 (PAll   [] p)    = smt2 p+  smt2 (PAll   xs p)    = do s <- smt2s xs+                             s1 <- smt2 p+                             pure $ parenSeqs ["forall", parens s, s1]+  smt2 (PAtom r e1 e2)  = mkRel r e1 e2+  smt2 (ELam b e)       = smt2Lam b e+  smt2 (ECoerc t1 t2 e) = smt2Coerc t1 t2 e+  smt2 e                = panic ("smtlib2 Pred  " ++ show e)  -- | smt2Cast uses the 'as x T' pattern needed for polymorphic ADT constructors --   like Nil, see `tests/pos/adt_list_1.fq` -smt2Cast :: SymEnv -> Expr -> Sort -> Builder-smt2Cast env (EVar x) t = smt2Var env x t-smt2Cast env e        _ = smt2    env e--smt2Var :: SymEnv -> Symbol -> Sort -> Builder-smt2Var env x t-  | isLamArgSymbol x            = smtLamArg env x t-  | Just s <- symEnvSort x env-  , isPolyInst s t              = smt2VarAs env x t-  | otherwise                   = smt2 env x+smt2Cast :: Expr -> Sort -> SymM Builder+smt2Cast (EVar x) t = smt2Var x t+smt2Cast e        _ = smt2    e -smtLamArg :: SymEnv -> Symbol -> Sort -> Builder-smtLamArg env x t = Builder.fromText $ symbolAtName x env () (FFunc t FInt)+smt2Var :: Symbol -> Sort -> SymM Builder+smt2Var x t+  | isLamArgSymbol x = smtLamArg x t+  | otherwise        = do env <- get+                          case symEnvSort x env of+                            Just s | isPolyInst s t -> smt2VarAs x t+                            _                       -> smt2 x -smt2VarAs :: SymEnv -> Symbol -> Sort -> Builder-smt2VarAs env x t = parenSeqs ["as", smt2 env x, smt2SortMono x env t]+smt2VarAs :: Symbol -> Sort -> SymM Builder+smt2VarAs x t =+  do s <- smt2 x+     s1 <- smt2SortMono x t+     pure $ parenSeqs ["as", s, s1] -smt2Lam :: SymEnv -> (Symbol, Sort) -> Expr -> Builder-smt2Lam env (x, xT) full@(ECst _ eT) = parenSeqs [Builder.fromText lambda, x', smt2 env full]-  where-    x'     = smtLamArg env x xT-    lambda = symbolAtName lambdaName env () (FFunc xT eT)+-- the next four functions (ones containing a call to `symbolAtName`) can trigger+-- an expansion of the "nursery" tag table ('seApplsCur' in 'SymEnv') when processing+-- a fresh function sort+smtLamArg :: Symbol -> Sort -> SymM Builder+smtLamArg x t =+  do s <- symbolAtName x (FFunc t FInt)+     pure $ Builder.fromText s -smt2Lam _ _ e+smt2Lam :: (Symbol, Sort) -> Expr -> SymM Builder+smt2Lam (x, xT) full@(ECst _ eT) =+  do x' <- smtLamArg x xT+     lambda <- symbolAtName lambdaName (FFunc xT eT)+     f <- smt2 full+     pure $ parenSeqs [Builder.fromText lambda, x', f]+smt2Lam _ e   = panic ("smtlib2: Cannot serialize unsorted lambda: " ++ showpp e) -smt2App :: SymEnv -> Expr -> Builder-smt2App env e@(EApp (EApp f e1) e2)+smt2App :: Expr -> SymM Builder+smt2App (EApp (EApp f e1) e2)   | Just t <- unApplyAt f-  = parenSeqs [Builder.fromText (symbolAtName applyName env e t), smt2s env [e1, e2]]-smt2App env e-  | Just b <- Thy.smt2App smt2VarAs env f (smt2 env <$> es)-  = b-  | otherwise-  = parenSeqs [smt2 env f, smt2s env es]+  = do a <- symbolAtName applyName t+       s <- smt2s [e1, e2]+       pure $ parenSeqs [Builder.fromText a, s]+smt2App e = do s0 <- traverse smt2 es+               s1 <- Thy.smt2App smt2VarAs f s0+               case s1 of+                 Just b -> pure b+                 Nothing -> do s2 <- smt2 f+                               s3 <- smt2s es+                               pure $ parenSeqs [s2, s3]   where-    (f, es)   = splitEApp' e+    (f, es) = splitEApp' e -smt2Coerc :: SymEnv -> Sort -> Sort -> Expr -> Builder-smt2Coerc env t1 t2 e-  | t1 == t2  = smt2 env e-  | otherwise = parenSeqs [Builder.fromText coerceFn , smt2 env e]-  where-    coerceFn  = symbolAtName coerceName env (ECoerc t1 t2 e) t-    t         = FFunc t1 t2+smt2Coerc :: Sort -> Sort -> Expr -> SymM Builder+smt2Coerc t1 t2 e+  | t1 == t2  = smt2 e+  | otherwise = do coerceFn <- symbolAtName coerceName (FFunc t1 t2)+                   s <- smt2 e+                   pure $ parenSeqs [Builder.fromText coerceFn , s]  splitEApp' :: Expr -> (Expr, [Expr]) splitEApp'            = go []@@ -217,50 +269,76 @@   --   go acc (ECst e _) = go acc e     go acc e          = (e, acc) -mkRel :: SymEnv -> Brel -> Expr -> Expr -> Builder-mkRel env Ne  e1 e2 = mkNe env e1 e2-mkRel env Une e1 e2 = mkNe env e1 e2-mkRel env r   e1 e2 = parenSeqs [smt2 env r, smt2 env e1, smt2 env e2]--mkNe :: SymEnv -> Expr -> Expr -> Builder-mkNe env e1 e2      = key "not" (parenSeqs ["=",  smt2 env e1, smt2 env e2])+mkRel :: Brel -> Expr -> Expr -> SymM Builder+mkRel Ne  e1 e2 = mkNe e1 e2+mkRel Une e1 e2 = mkNe e1 e2+mkRel r   e1 e2 = do s <- smt2 r+                     s1 <- smt2 e1+                     s2 <- smt2 e2+                     pure $ parenSeqs [s, s1, s2] +mkNe :: Expr -> Expr -> SymM Builder+mkNe e1 e2 = do s1 <- smt2 e1+                s2 <- smt2 e2+                pure $ key "not" (parenSeqs ["=", s1, s2]) instance SMTLIB2 Command where-  smt2 env (DeclData ds)       = key "declare-datatypes" (smt2data env ds)-  smt2 env (Declare x ts t)    = parenSeqs ["declare-fun", Builder.fromText x, parens (smt2many (smt2 env <$> ts)), smt2 env t]-  smt2 env c@(Define t)        = key "declare-sort" (smt2SortMono c env t)-  smt2 env (DefineFunc name paramxs rsort e) =-    let bParams = [ parenSeqs [smt2 env s, smt2 env t] | (s, t) <- paramxs]-     in parenSeqs ["define-fun", smt2 env name, parenSeqs bParams, smt2 env rsort, smt2 env e]-  smt2 env (Assert Nothing p)  = {-# SCC "smt2-assert" #-} key "assert" (smt2 env p)-  smt2 env (Assert (Just i) p) = {-# SCC "smt2-assert" #-} key "assert" (parens ("!"<+> smt2 env p <+> ":named p-" <> bShow i))-  smt2 env (Distinct az)-    | length az < 2            = ""-    | otherwise                = key "assert" (key "distinct" (smt2s env az))-  smt2 env (AssertAx t)        = key "assert" (smt2 env t)-  smt2 _   Push                = "(push 1)"-  smt2 _   Pop                 = "(pop 1)"-  smt2 _   CheckSat            = "(check-sat)"-  smt2 env (GetValue xs)       = key "key-value" (parens (smt2s env xs))-  smt2 env (CMany cmds)        = smt2many (smt2 env <$> cmds)-  smt2 _   Exit                = "(exit)"-  smt2 _   SetMbqi             = "(set-option :smt.mbqi true)"+  smt2     (DeclData ds)       = do s <- smt2data ds+                                    pure $ key "declare-datatypes" s+  smt2     (Declare x ts t)    = do s <- smt2s ts+                                    s1 <- smt2 t+                                    pure $ parenSeqs ["declare-fun", Builder.fromText x, parens s, s1]+  smt2     c@(Define t)        = do s <- smt2SortMono c t+                                    pure $ key "declare-sort" s+  smt2     (DefineFunc name paramxs rsort e) =+    do n <- smt2 name+       bParams <- traverse (\(s, t) -> do s0 <- smt2 s+                                          s1 <- smt2 t+                                          pure $ parenSeqs [s0 , s1]) paramxs+       r <- smt2 rsort+       e' <- smt2 e+       pure $ parenSeqs ["define-fun", n, parenSeqs bParams, r, e'] +  smt2     (Assert Nothing p)  = {-# SCC "smt2-assert" #-}+                                  do s <- smt2 p+                                     pure $ key "assert" s+  smt2     (Assert (Just i) p) = {-# SCC "smt2-assert" #-}+                                  do s <- smt2 p+                                     pure $ key "assert" (parens ("!"<+> s <+> ":named p-" <> bShow i))+  smt2     (Distinct az)+    | length az < 2            = pure ""+    | otherwise                = do s <- smt2s az+                                    pure $ key "assert" $ key "distinct" s+  smt2     (AssertAx t)        = do s <- smt2 t+                                    pure $ key "assert" s+  smt2     Push                = pure "(push 1)"+  smt2     Pop                 = pure "(pop 1)"+  smt2     CheckSat            = pure "(check-sat)"+  smt2     (GetValue xs)       = do s <- smt2s xs+                                    pure $ key "key-value" (parens s)+  smt2     (CMany cmds)        = smt2s cmds+  smt2     Exit                = pure "(exit)"+  smt2     SetMbqi             = pure "(set-option :smt.mbqi true)"+  smt2     (Comment t)         = pure $ fromText ("; " <> t <> "\n")+ instance SMTLIB2 (Triggered Expr) where-  smt2 env (TR NoTrigger e)       = smt2 env e-  smt2 env (TR _ (PExist [] p))   = smt2 env p-  smt2 env t@(TR _ (PExist xs p)) = smtTr env "exists" xs p t-  smt2 env (TR _ (PAll   [] p))   = smt2 env p-  smt2 env t@(TR _ (PAll   xs p)) = smtTr env "forall" xs p t-  smt2 env (TR _ e)               = smt2 env e+  smt2 (TR NoTrigger e)       = smt2 e+  smt2 (TR _ (PExist [] p))   = smt2 p+  smt2 t@(TR _ (PExist xs p)) = smtTr "exists" xs p t+  smt2 (TR _ (PAll   [] p))   = smt2 p+  smt2 t@(TR _ (PAll   xs p)) = smtTr "forall" xs p t+  smt2 (TR _ e)               = smt2 e  {-# INLINE smtTr #-}-smtTr :: SymEnv -> Builder -> [(Symbol, Sort)] -> Expr -> Triggered Expr -> Builder-smtTr env q xs p t = key q (parens (smt2s env xs) <+> key "!" (smt2 env p <+> ":pattern" <> parens (smt2s env (makeTriggers t))))+smtTr :: Builder -> [(Symbol, Sort)] -> Expr -> Triggered Expr -> SymM Builder+smtTr q xs p t =+  do s <- smt2s xs+     s1 <- smt2 p+     s2 <- smt2s (makeTriggers t)+     pure $ key q (parens s <+> key "!" (s1 <+> ":pattern" <> parens s2))  {-# INLINE smt2s #-}-smt2s    :: SMTLIB2 a => SymEnv -> [a] -> Builder-smt2s env as = smt2many (smt2 env <$> as)+smt2s :: SMTLIB2 a => [a] -> SymM Builder+smt2s as = smt2many <$> traverse smt2 as  {-# INLINE smt2many #-} smt2many :: [Builder] -> Builder
src/Language/Fixpoint/Smt/Theories.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE UndecidableInstances      #-}-{-# LANGUAGE PatternGuards             #-} {-# LANGUAGE ViewPatterns              #-}  {-# OPTIONS_GHC -Wno-orphans           #-}@@ -32,7 +31,7 @@      , dataDeclSymbols         -- * Theories-     , setEmpty, setEmp, setSng, setAdd, setMem+     , setEmpty, setEmp, setSng, setAdd, setMem, setCard      , setCom, setCap, setCup, setDif, setSub       , mapDef, mapSel, mapSto@@ -49,6 +48,9 @@      , arrConstB, arrStoreB, arrSelectB      , arrMapPlusB, arrMapLeB, arrMapGtB, arrMapIteB +     -- * CVC5 finite fields+     , ffVal, ffAdd, ffMul+       -- * Query Theories      , isSmt2App      , axiomLiterals@@ -56,6 +58,7 @@      ) where  import           Prelude hiding (map)+import           Control.Monad.State import           Data.ByteString.Builder (Builder) import           Language.Fixpoint.Types.Sorts import           Language.Fixpoint.Types.Config@@ -139,7 +142,8 @@ mapSel   = "Map_select" mapSto   = "Map_store" -setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup, setDif, setSng :: (IsString a) => a+setCard, setEmpty, setEmp, setCap, setSub, setAdd, setMem, setCom, setCup, setDif, setSng :: (IsString a) => a+setCard  = "Set_card" setEmpty = "Set_empty" setEmp   = "Set_emp" setCap   = "Set_cap"@@ -195,20 +199,34 @@ arrMapGtB   = "arr_map_gt" arrMapIteB   = "arr_map_ite" -strLen, strSubstr, strConcat :: (IsString a) => a -- Symbol+-- Finite field operations+ffVal, ffAdd, ffMul :: (IsString a) => a -- Symbol+ffVal = "FF_val"+ffAdd = "FF_add"+ffMul = "FF_mul"++strLen, strSubstr, strConcat, strConcat', strPrefixOf, strSuffixOf, strContains :: (IsString a) => a -- Symbol strLen    = "strLen" strSubstr = "subString" strConcat = "concatString"+strConcat' = "strConcat"+strPrefixOf  = "strPrefixOf"+strSuffixOf = "strSuffixOf"+strContains = "strContains" -smtlibStrLen, smtlibStrSubstr, smtlibStrConcat :: Raw+smtlibStrLen, smtlibStrSubstr, smtlibStrConcat, smtlibStrPrefixOf, smtlibStrSuffixOf, smtlibStrContains :: Raw smtlibStrLen    = "str.len" smtlibStrSubstr = "str.substr" smtlibStrConcat = "str.++"+smtlibStrPrefixOf = "str.prefixof"+smtlibStrSuffixOf = "str.suffixof"+smtlibStrContains = "str.contains" -strLenSort, substrSort, concatstrSort :: Sort+strLenSort, substrSort, concatstrSort, strCompareSort :: Sort strLenSort    = FFunc strSort intSort substrSort    = mkFFunc 0 [strSort, intSort, intSort, strSort] concatstrSort = mkFFunc 0 [strSort, strSort, strSort]+strCompareSort = mkFFunc 0 [strSort, strSort, boolSort]  string :: Raw string = strConName@@ -256,6 +274,7 @@      , (SOnly [Cvc5],       "(set-logic ALL)")      , (SOnly [Cvc4, Cvc5], "(set-option :incremental true)")      ]+  ++ setPreamble cfg   ++ boolPreamble cfg   ++ arithPreamble cfg   ++ stringPreamble cfg@@ -265,6 +284,10 @@ data PreambleCondition = SAll | SOnly [SMTSolver]   deriving (Eq, Show) +setPreamble :: Config -> [Preamble]+-- Z3 does not support cardinality on sets, which is defined to be uninterpreted function+setPreamble _+  = [ (SOnly [Z3, Z3mem],  bFun' "set.card" ["(Array Int Bool)"] "Int") ]  boolPreamble :: Config -> [Preamble] boolPreamble _@@ -277,7 +300,7 @@  ]  stringPreamble :: Config -> [Preamble]-stringPreamble cfg | stringTheory cfg+stringPreamble cfg | not (noStringTheory cfg)   = [ (SAll, bSort string "String")     , (SAll, bFun strLen [("s", fromText string)] "Int" (key (fromText smtlibStrLen) "s"))     , (SAll, bFun strSubstr [("s", fromText string), ("i", "Int"), ("j", "Int")] (fromText string) (key (fromText smtlibStrSubstr) "s i j"))@@ -298,7 +321,7 @@ smt2Symbol env x = fromText . tsRaw <$> symEnvTheory x env  instance SMTLIB2 SmtSort where-  smt2 _ = smt2SmtSort+  smt2 s = pure $ smt2SmtSort s  smt2SmtSort :: SmtSort -> Builder smt2SmtSort SInt         = "Int"@@ -308,6 +331,7 @@ smt2SmtSort (SSet a)     = key "Set" (smt2SmtSort a) smt2SmtSort (SBag a)     = key "Bag" (smt2SmtSort a) smt2SmtSort (SArray a b) = key2 "Array" (smt2SmtSort a) (smt2SmtSort b)+smt2SmtSort (SFFld n)    = key "_ FiniteField" (bShow n) smt2SmtSort (SBitVec n)  = key "_ BitVec" (bShow n) smt2SmtSort (SVar n)     = "T" <> bShow n smt2SmtSort (SData c []) = symbolBuilder c@@ -318,37 +342,44 @@ smt2SmtSorts :: [SmtSort] -> Builder smt2SmtSorts = seqs . fmap smt2SmtSort -type VarAs = SymEnv -> Symbol -> Sort -> Builder+type VarAs = Symbol -> Sort -> SymM Builder ---------------------------------------------------------------------------------smt2App :: VarAs -> SymEnv -> Expr -> [Builder] -> Maybe Builder+smt2App :: VarAs -> Expr -> [Builder] -> SymM (Maybe Builder) ---------------------------------------------------------------------------------smt2App _ env ex@(dropECst -> EVar f) [d]-  | f == arrConstS = Just (key (key "as const" (getTarget ex)) d)-  | f == arrConstB = Just (key (key "as const" (getTarget ex)) d)-  | f == arrConstM = Just (key (key "as const" (getTarget ex)) d)-  | f == setEmpty  = Just (key "as set.empty" (getTarget ex))-  | f == bagEmpty  = Just (key "as bag.empty" (getTarget ex))+smt2App _ ex@(dropECst -> EVar f) [d]+  | f == arrConstS || f == arrConstB || f == arrConstM =+      do env <- get+         pure $ Just $ key (key "as const" (getTarget env ex)) d+  | f == setEmpty  =+      do env <- get+         pure $ Just $ key "as set.empty" (getTarget env ex)+  | f == bagEmpty  =+      do env <- get+         pure $ Just $ key "as bag.empty" (getTarget env ex)+  | f == ffVal  =+      do env <- get+         pure $ Just $ key ("as ff" <> d) (getTarget env ex)   where-    getTarget :: Expr -> Builder+    getTarget :: SymEnv -> 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 ex (builder:builders)-  | Just fb <- smt2AppArg k env ex-  = Just $ key fb (builder <> mconcat [ " " <> d | d <- builders])--smt2App _ _ _ _    = Nothing+    getTarget env (ECst _ t) = smt2SmtSort $ sortSmtSort True (seData env) (ffuncOut t)+    getTarget _ e = bShow e -smt2AppArg :: VarAs -> SymEnv -> Expr -> Maybe Builder-smt2AppArg k env (ECst (dropECst -> EVar f) t)-  | Just fThy <- symEnvTheory f env-  = Just $ if isPolyCtor fThy t-            then k env f (ffuncOut t)-            else fromText (tsRaw fThy)+smt2App k ex (builder:builders) =+  do a <- smt2AppArg k ex+     pure $ (\fb -> key fb (builder <> mconcat [ " " <> d | d <- builders])) <$> a+smt2App _ _ [] = pure Nothing -smt2AppArg _ _ _-  = Nothing+smt2AppArg :: VarAs -> Expr -> SymM (Maybe Builder)+smt2AppArg k (ECst (dropECst -> EVar f) t)+  = do env <- get+       case symEnvTheory f env of+         Just fThy -> if isPolyCtor fThy t+                           then Just <$> k f (ffuncOut t)+                           else pure $ Just $ fromText (tsRaw fThy)+         Nothing   -> pure Nothing+smt2AppArg _ _+  = pure Nothing  isPolyCtor :: TheorySymbol -> Sort -> Bool isPolyCtor fThy t = isPolyInst (tsSort fThy) t && tsInterp fThy == Ctor@@ -388,9 +419,13 @@   theorySymbols :: [DataDecl] -> SEnv TheorySymbol   theorySymbols = fromListSEnv . concatMap dataDeclSymbols + instance TheorySymbols [Equation] where   theorySymbols = fromListSEnv . fmap equationSymbol +instance TheorySymbols DefinedFuns where+  theorySymbols (MkDefinedFuns eqns) = theorySymbols eqns+ equationSymbol :: Equation -> (Symbol, TheorySymbol) equationSymbol eq = (sym, Thy sym (symbolRaw sym) sort Defined)   where@@ -414,6 +449,7 @@    -- CVC5 sets +  , interpSym setCard  "set.card"       (FAbs 0 $ FFunc (setSort $ FVar 0) intSort)   , interpSym setEmp   "set.is_empty"   (FAbs 0 $ FFunc (setSort $ FVar 0) boolSort)   , interpSym setEmpty "set.empty"      (FAbs 0 $ FFunc intSort (setSort $ FVar 0))   , interpSym setSng   "set.singleton"  (FAbs 0 $ FFunc (FVar 0) (setSort $ FVar 0))@@ -435,14 +471,15 @@   , interpSym bagMin   "bag.inter_min"      bagBopSort   , interpSym bagSub   "bag.subbag"         (FAbs 0 $ FFunc (bagSort $ FVar 0) $ FFunc (bagSort $ FVar 0) boolSort) -  -- , interpSym bvOrName  "bvor"  bvBopSort-  -- , interpSym bvAndName "bvand" bvBopSort-  -- , interpSym bvAddName "bvadd" bvBopSort-  -- , interpSym bvSubName "bvsub" bvBopSort+  -- Strings+  , interpSym strLen     strLen    strLenSort+  , interpSym strSubstr  strSubstr substrSort+  , interpSym strConcat  strConcat concatstrSort+  , interpSym strConcat' smtlibStrConcat concatstrSort+  , interpSym strPrefixOf smtlibStrPrefixOf strCompareSort+  , interpSym strSuffixOf smtlibStrSuffixOf strCompareSort+  , interpSym strContains smtlibStrContains strCompareSort -  , interpSym strLen    strLen    strLenSort-  , interpSym strSubstr strSubstr substrSort-  , interpSym strConcat strConcat concatstrSort   , interpSym boolInt   boolInt   (FFunc boolSort intSort)    -- Function mappings for indexed identifier functions@@ -489,12 +526,18 @@   , interpBvCmp bvSLeName   , interpBvCmp bvSGtName   , interpBvCmp bvSGeName++  -- int to bv Conversions+   , interpSym intbv32Name   "(_ int2bv 32)" (FFunc intSort bv32)   , interpSym intbv64Name   "(_ int2bv 64)" (FFunc intSort bv64)-  , interpSym bv32intName   (bv2i cfg 32) (FFunc bv32    intSort)-  , interpSym bv64intName   (bv2i cfg 64) (FFunc bv64    intSort)-  -- , interpSym bv32intName   "(_ bv2int 32)" (FFunc bv32    intSort)-  -- , interpSym bv64intName   "(_ bv2int 64)" (FFunc bv64    intSort)+  , interpSym bv32intName   (bv2i cfg 32)   (FFunc bv32    intSort)+  , interpSym bv64intName   (bv2i cfg 64)   (FFunc bv64    intSort)++  , interpSym intbv8Name    "(_ int2bv 8)"  (FFunc intSort bv8)+  , interpSym intbv16Name   "(_ int2bv 16)" (FFunc intSort bv16)+  , interpSym bv8intName    (bv2i cfg 32)   (FFunc bv8    intSort)+  , interpSym bv16intName   (bv2i cfg 64)   (FFunc bv16    intSort)   ]   ++   if cfg == Z3 || cfg == Z3mem@@ -521,13 +564,22 @@   , interpSym arrMapLeB   "(_ map (<= (Int Int) Bool))"      (FAbs 0 $ FFunc bagArrSort $ FFunc bagArrSort setArrSort)   , interpSym arrMapGtB   "(_ map (> (Int Int) Bool))"       (FAbs 0 $ FFunc bagArrSort $ FFunc bagArrSort setArrSort)   , interpSym arrMapIteB  "(_ map (ite (Bool Int Int) Int))" (FAbs 0 $ FFunc setArrSort $ FFunc bagArrSort $ FFunc bagArrSort bagArrSort)+  ] else if cfg == Cvc5+  then+  [+    -- CVC5 finite fields++    interpSym ffVal ffVal     (FAbs 0 $ FFunc intSort (finfieldSort (FVar 0)))+  , interpSym ffAdd "ff.add" (FAbs 0 $ FFunc (finfieldSort (FVar 0)) $ FFunc (finfieldSort (FVar 0)) (finfieldSort (FVar 0)))+  , interpSym ffMul "ff.mul" (FAbs 0 $ FFunc (finfieldSort (FVar 0)) $ FFunc (finfieldSort (FVar 0)) (finfieldSort (FVar 0)))   ] else []   where      mapArrSort = arraySort (FVar 0) (FVar 1)     setArrSort = arraySort (FVar 0) boolSort     bagArrSort = arraySort (FVar 0) intSort-    -- (sizedBitVecSort "Size1")+    bv8        = sizedBitVecSort "Size8"+    bv16       = sizedBitVecSort "Size16"     bv32       = sizedBitVecSort "Size32"     bv64       = sizedBitVecSort "Size64"     boolInt    = boolToIntName@@ -630,17 +682,29 @@ interpSym :: Symbol -> Raw -> Sort -> (Symbol, TheorySymbol) interpSym x n t = (x, Thy x n t Theory) --- This variable is uded to generate the lambda names `lam_arg$n` in+-- This variable is used to generate the lambda names `lam_arg$n` in -- `Interface.hs` that will be used during defunctionalization in--- `Defunctionalize.hs`, is a pretty gross hack as if the user typees in the--- program or ple generates a term that has more than `maxLamArg` lambda binders--- one inside the other, the smt will crash complaining that--- `lam_arg${maxLamArg}` was not declared.+-- `Defunctionalize.hs`, is a pretty gross hack as if the user types in the+-- program or PLE generates a term that has more than `maxLamArg` lambda binders+-- one inside the other, the SMT will crash complaining that+-- `lam_arg${maxLamArg + k}` was not declared. maxLamArg :: Int maxLamArg = 20 -axiomLiterals :: [(Symbol, Sort)] -> [Expr]-axiomLiterals lts = catMaybes [ lenAxiom l <$> litLen l | (l, t) <- lts, isString t ]+axiomLiterals :: Config -> [(Symbol, Sort)] -> [Expr]+axiomLiterals cfg+  | noStringTheory cfg = lenAxiomLiterals+  | otherwise          = strAxiomLiterals++strAxiomLiterals :: [(Symbol, Sort)] -> [Expr]+strAxiomLiterals lts = catMaybes [ strAxiom l | (l, t) <- lts, isString t ]+  where+    strAxiom l = do+      sym <- unLitSymbol l+      pure (EEq (expr l) (ECon $ L (symbolText sym) strSort))++lenAxiomLiterals :: [(Symbol, Sort)] -> [Expr]+lenAxiomLiterals lts = catMaybes [ lenAxiom l <$> litLen l | (l, t) <- lts, isString t ]   where     lenAxiom l n  = EEq (EApp (expr (strLen :: Symbol)) (expr l)) (expr n `ECst` intSort)     litLen        = fmap (Data.Text.length .  symbolText) . unLitSymbol
src/Language/Fixpoint/Smt/Types.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE TupleSections             #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE OverloadedStrings         #-}@@ -25,11 +26,18 @@     -- * SMTLIB2 Process Context     , Context (..) -    ) where+    -- * SMT monad+    , SmtM+    , liftSym+    , catchSMT+    , bracketSMT +    ) where+import           Control.Exception+import           Control.Monad.State import           Data.ByteString.Builder (Builder) import           Language.Fixpoint.Types-import           Language.Fixpoint.Types.Config (ElabFlags)+import           Language.Fixpoint.Types.Config (ElabFlags, Config) import qualified Data.Text                as T import           Text.PrettyPrint.HughesPJ import qualified SMTLIB.Backends@@ -59,6 +67,7 @@                   | Distinct [Expr] -- {v:[Expr] | 2 <= len v}                   | GetValue [Symbol]                   | CMany    [Command]+                  | Comment T.Text                   deriving (Eq, Show)  instance PPrint Command where@@ -81,6 +90,7 @@ ppCmd Distinct {} = text "Distinct ..." ppCmd GetValue {} = text "GetValue ..." ppCmd CMany {}    = text "CMany ..."+ppCmd (Comment t) = text ("; " ++ T.unpack t)  -- | Responses received from SMT engine data Response     = Ok@@ -102,15 +112,44 @@   , ctxLog     :: !(Maybe Handle)   , ctxVerbose :: !Bool   , ctxSymEnv  :: !SymEnv-  , ctxDefines :: ![Equation]+  -- | The stack of sort indexes which were fresh at the corresponding level of push/pop stack.+  , ctxIxs     :: ![Int]+  , ctxDefines :: DefinedFuns+  -- | Flag which controls the generation SMT placeholders for lambda arguments+  --   See also `L.F.Smt.Theories.maxLamArg`+  , ctxLams    :: !Bool+  -- | Configuration options+  , config     :: !Config   } +-- | SMT monad, used to communicate with the SMT solver backend.+--   The `SymM` monad embeds into it, as the symbolic state has to be threaded+--   through for gnerating `apply`s and other function sort symbols.+type SmtM = StateT Context IO++liftSym :: SymM a -> SmtM a+liftSym s =+  do ctx <- get+     let (a, env') = runState s (ctxSymEnv ctx)+     put (ctx {ctxSymEnv = env'})+     pure a++catchSMT :: Exception e => SmtM a -> (e -> IO a) -> SmtM a+catchSMT action handler = StateT $ \s -> catch (runStateT action s) (fmap (, s) . handler)++bracketSMT :: SmtM a -> (a -> IO b) -> (a -> SmtM c) -> SmtM c+bracketSMT acquire release use = StateT $ \s ->+  bracket+    (runStateT acquire s)+    (\(resource, _) -> release resource)+    (\(resource, intermediateState) -> runStateT (use resource) intermediateState)+ -------------------------------------------------------------------------------- -- | AST Conversion: Types that can be serialized ------------------------------ --------------------------------------------------------------------------------  class SMTLIB2 a where-  smt2 :: SymEnv -> a -> Builder+  smt2 :: a -> SymM Builder -runSmt2 :: (SMTLIB2 a) => SymEnv -> a -> Builder+runSmt2 :: (SMTLIB2 a) => a -> SymM Builder runSmt2 = smt2
src/Language/Fixpoint/Solver.hs view
@@ -8,7 +8,7 @@  module Language.Fixpoint.Solver (     -- * Invoke Solver on an FInfo-    solve, Solver+    solve      -- * Invoke Solver on a .fq file   , solveFQ@@ -26,26 +26,28 @@  import           Control.Concurrent                 (setNumCapabilities) import qualified Data.HashMap.Strict              as HashMap+import qualified Data.HashSet                     as HashSet 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 (..)) import           System.Console.CmdArgs.Verbosity   (whenNormal, whenLoud)-import           Text.PrettyPrint.HughesPJ          (render)-import           Control.Monad                      (mplus, when)-import           Control.Exception                  (catch)+import           Control.Monad                      (when)+import           Control.Exception                  (SomeException, catch)+import           Control.Exception.Compat+    (ExceptionWithContext(..), displayExceptionContext, wrapExceptionWithContext) import           Language.Fixpoint.Solver.EnvironmentReduction   (reduceEnvironments, simplifyBindings) import           Language.Fixpoint.Solver.Sanitize  (symbolEnv, sanitize) import           Language.Fixpoint.Solver.UniqifyBinds (renameAll) import           Language.Fixpoint.Defunctionalize (defunctionalize)-import           Language.Fixpoint.SortCheck            (ElabParam (..), Elaborate (..), unElab)+import           Language.Fixpoint.SortCheck            (ElabParam (..), Elaborate (..), unElab, unElabFSetBagZ3) import           Language.Fixpoint.Solver.Extensionality (expand) import           Language.Fixpoint.Solver.Prettify (savePrettifiedQuery) import           Language.Fixpoint.Solver.UniqifyKVars (wfcUniqify) import qualified Language.Fixpoint.Solver.Solve     as Sol+import qualified Language.Fixpoint.Solver.Solution  as Sol import           Language.Fixpoint.Types.Config import           Language.Fixpoint.Types.Errors import           Language.Fixpoint.Utils.Files            hiding (Result)@@ -56,10 +58,10 @@ import           Language.Fixpoint.Types hiding (GInfo(..), fi) import qualified Language.Fixpoint.Types as Types (GInfo(..)) import           Language.Fixpoint.Minimize (minQuery, minQuals, minKvars)-import           Language.Fixpoint.Solver.Instantiate (instantiate) import           Control.DeepSeq import qualified Data.ByteString as B-import Data.Maybe (catMaybes, mapMaybe)+import Data.Maybe (catMaybes)+import qualified Text.PrettyPrint.HughesPJ as PJ  --------------------------------------------------------------------------- -- | Solve an .fq file ----------------------------------------------------@@ -86,7 +88,7 @@     jStr    = LT.decodeUtf8 . encode $ r     stat    = resStatus $!! r     eCode   = resultExit . resStatus-    statStr = render . resultDoc+    statStr = PJ.render . resultDoc  ignoreQualifiers :: Config -> FInfo a -> FInfo a ignoreQualifiers cfg fi@@ -97,7 +99,9 @@ -------------------------------------------------------------------------------- -- | Solve FInfo system of horn-clause constraints ----------------------------- ---------------------------------------------------------------------------------solve :: (PPrint a, NFData a, Fixpoint a, Show a, Loc a) => Solver a+solve+  :: (PPrint a, NFData a, Fixpoint a, Show a, Loc a)+  => Config -> FInfo a -> IO (Result (Integer, a)) -------------------------------------------------------------------------------- solve cfg q   | parts cfg      = partition  cfg        $!! q@@ -107,15 +111,16 @@   | minimizeKs cfg = minKvars cfg solve'   $!! q   | otherwise      = solve'     cfg        $!! q -solve' :: (PPrint a, NFData a, Fixpoint a, Show a, Loc a) => Solver a++solve'+  :: (PPrint a, NFData a, Fixpoint a, Show a, Loc a)+  => Config -> FInfo a -> IO (Result (Integer, a)) solve' cfg q = do   when (save cfg) $ saveQuery   cfg q-  configSW  cfg     solveNative cfg q--configSW :: (NFData a, Fixpoint a, Show a, Loc a) => Config -> Solver a -> Solver a-configSW cfg-  | multicore cfg = solveParWith-  | otherwise     = solveSeqWith+  if multicore cfg then+    solvePar cfg q+  else+    solveNative cfg (slice cfg q)  -------------------------------------------------------------------------------- readFInfo :: FilePath -> IO (FInfo (), [String])@@ -140,17 +145,11 @@ -------------------------------------------------------------------------------- -- | Solve in parallel after partitioning an FInfo to indepdendant parts ---------------------------------------------------------------------------------solveSeqWith :: (Fixpoint a) => Solver a -> Solver a-solveSeqWith s c fi0 = {- withProgressFI fi $ -} s c fi-  where-    fi               = slice c fi0------------------------------------------------------------------------------------- | Solve in parallel after partitioning an FInfo to indepdendant parts----------------------------------------------------------------------------------solveParWith :: (Fixpoint a) => Solver a -> Solver a+solvePar+  :: (Loc a, NFData a, PPrint a, Show a, Fixpoint a)+  => Config -> FInfo a -> IO (Result (Integer, a)) ---------------------------------------------------------------------------------solveParWith s c fi0 = do+solvePar c fi0 = do   -- putStrLn "Using Parallel Solver \n"   let fi    = slice c fi0   mci      <- mcInfo c@@ -161,10 +160,10 @@   writeLoud $ "maximum part size    : " ++ show (maxPartSize c)   case fis of     []        -> errorstar "partiton' returned empty list!"-    [onePart] -> s c onePart-    _         -> inParallelUsing (f s c) $ zip [1..] fis+    [onePart] -> solveNative c onePart+    _         -> inParallelUsing (f c) $ zip [1..] fis     where-      f s' c' (j, fi) = s' (c {srcFile = queryFile (Part j) c'}) fi+      f c' (j, fi) = solveNative (c {srcFile = queryFile (Part j) c'}) fi  -------------------------------------------------------------------------------- -- | Solve a list of FInfos using the provided solver function in parallel@@ -180,26 +179,35 @@ -------------------------------------------------------------------------------- -- | Native Haskell Solver ----------------------------------------------------- ---------------------------------------------------------------------------------solveNative, solveNative' :: (NFData a, Fixpoint a, Show a, Loc a, PPrint a) => Solver a+solveNative, solveNative'+  :: (NFData a, Fixpoint a, Show a, Loc a, PPrint a)+  => Config -> FInfo a -> IO (Result (Integer, a)) -------------------------------------------------------------------------------- solveNative !cfg !fi0 = solveNative' cfg fi0                           `catch`-                             (return . crashResult (errorMap fi0))+                             (return . crashResult (errorMap fi0) . wrapExceptionWithContext)+                          `catch`+                             (return . crashResultOther . wrapExceptionWithContext) -crashResult :: (PPrint a) => ErrorMap a -> Error -> Result (Integer, a)-crashResult m err' = Result res mempty mempty mempty+crashResult :: (PPrint a) => ErrorMap a -> ExceptionWithContext Error -> Result (Integer, a)+crashResult m (ExceptionWithContext ectx ex) = Result res mempty mempty mempty   where-    res           = Crash es msg-    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'+    res = Crash es msg+    es  = catMaybes [ findError m e | e <- ers ]+    ers = errs ex+    msg = displayExceptionContext ectx ++ "\n" ++ msg0+    msg0 | null ers = "Sorry, unexpected panic in liquid-fixpoint!\n"+                       ++ showpp ex+         | otherwise = showpp ex -_crashMessage :: [((Integer, a), Maybe String) ] -> String-_crashMessage es = L.intercalate "\n" [ msg i s | ((i,_), Just s) <- es ]+crashResultOther+  :: ExceptionWithContext SomeException -> Result (Integer, a)+crashResultOther (ExceptionWithContext ectx ex) =+    Result res mempty mempty mempty   where-    msg i s = "Error in constraint " ++ show i ++ ":\n" ++ s+    res = Crash [] msg+    msg = displayExceptionContext ectx ++ "\n" ++ msg0+    msg0 = "Sorry, unexpected panic in liquid-fixpoint!\n" ++ show ex  -- | Unpleasant hack to save meta-data that can be recovered from SrcSpan type ErrorMap a = HashMap.HashMap SrcSpan a@@ -207,7 +215,7 @@ findError :: ErrorMap a -> Error1 -> Maybe ((Integer, a), Maybe String) findError m e = do   ann <- HashMap.lookup (errLoc e) m-  let str = render (errMsg e)+  let str = PJ.render (errMsg e)   return ((-1, ann), Just str)  -- The order is important here: we want the "binders" to get the "precedence"@@ -219,13 +227,13 @@             ++ [ a | (_, (_,_, a)) <- bindEnvToList (Types.bs fi) ]  loudDump :: (Fixpoint a) => Int -> Config -> SInfo a -> IO ()-loudDump i cfg si = when False (writeLoud $ msg ++ render (toFixpoint cfg si))+loudDump i cfg si = when False (writeLoud $ msg ++ PJ.render (toFixpoint cfg si))   where     msg           = "fq file after Uniqify & Rename " ++ show i ++ "\n"  {-# SCC simplifyFInfo #-} simplifyFInfo :: (NFData a, Fixpoint a, Show a, Loc a)-               => Config -> FInfo a -> IO (SInfo a)+               => Config -> FInfo a -> IO (ElabParam, SInfo a) simplifyFInfo !cfg !fi0 = do   -- writeLoud $ "fq file in: \n" ++ render (toFixpoint cfg fi)   -- rnf fi0 `seq` donePhase Loud "Read Constraints"@@ -250,13 +258,16 @@   -- writeLoud $ "fq file after defunc: \n" ++ render (toFixpoint cfg si4)   -- putStrLn $ "AXIOMS: " ++ showpp (asserts si4)   loudDump 2 cfg si4-  let si5  = {- SCC "elaborate" -} elaborate (ElabParam (solverFlags $ solver cfg) (atLoc dummySpan "solver") (symbolEnv cfg si4)) si4+  let ef = solverFlags cfg+      elabParam = ElabParam+                     ef+                     (atLoc dummySpan "solver")+                     (coerceEnv ef (symbolEnv cfg si4))+      si5  = elaborate elabParam 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-    then instantiate cfg si6 $!! Nothing-    else return si6+  return (elabParam, si6){- SCC "elaborate" -}  reduceFInfo :: Fixpoint a => Config -> FInfo a -> IO (FInfo a) reduceFInfo cfg fi = do@@ -264,15 +275,15 @@       reducedFi = {- SCC "reduceEnvironments" -} reduceEnvironments simplifiedFi   when (save cfg) $     savePrettifiedQuery cfg reducedFi-  if noEnvironmentReduction cfg then+  if noEnvReduction cfg then     return fi   else     return reducedFi  solveNative' !cfg !fi0 = do-  si6 <- simplifyFInfo cfg fi0-  res0 <- {- SCC "Sol.solve" -} Sol.solve cfg $!! si6-  let res = simplifyResult res0+  (elabParam, si6) <- simplifyFInfo cfg fi0+  res0 <- {- SCC "Sol.solve" -} Sol.solve cfg elabParam $!! si6+  let res = simplifyResult cfg res0   -- rnf soln `seq` donePhase Loud "Solve2"   --let stat = resStatus res   -- saveSolution cfg res@@ -304,119 +315,27 @@   writeFile f $ unlines $     [ ""     , "Solution:"-    , showpp (resSolution  res)+    , scopedRender (resSolution  res)     ] ++-    ( if gradual cfg then-        ["", "", showpp $ gresSolution res]-      else-        []-    ) ++     [ ""     , ""     , "Non-cut kvars:"     , ""-    , showpp (HashMap.map unElab $ resNonCutsSolution res)+    , scopedRender (HashMap.map forceDelayed $ resNonCutsSolution res)     ]+    where+      scopedRender = PJ.render . PJ.vcat . map ncDoc . scoped+      scoped sol = [ (k, scope k, e) | (k, e) <- HashMap.toList sol]+      scope k = HashMap.lookupDefault [] k $ resSorts res+      ncDoc (k, xts, e) = PJ.hsep [ pprint k PJ.<> pprint xts, ":=", pprint e ] -simplifyResult :: Result a -> Result a-simplifyResult res =+simplifyResult :: Config -> Result a -> Result a+simplifyResult cfg res =     res-      { resSolution = HashMap.map simplifyKVar (resSolution res)-      , resNonCutsSolution = HashMap.map simplifyKVar (resNonCutsSolution res)+      { resSolution = HashMap.map simplifyKVar' (resSolution res)+      , resNonCutsSolution = HashMap.map (fmap simplifyKVar') (resNonCutsSolution res)       }---- | Simplifies existential expressions with unused or inconsequential bindings.------ For instance, in the following example, "x" is not used at all.------ > simplifyKVar "exists x y. y == z && y == C" == "exists y. y == z && y == C"------ And in the following example, @x@ is used but in a way that doesn't--- contribute any useful knowledge.------ > simplifyKVar "exists x y. x == C && y == z && y == C"--- >   ==--- > "exists y. y == z && y == C"------ We require that relevant variables occur more than once, or that--- they occur in some other place than as an argument to @==@.----simplifyKVar :: Expr -> Expr-simplifyKVar (POr es) = POr $ map simplifyKVar es-simplifyKVar (PExist bs e@(PAnd es)) =-    let fvs = L.group $ L.sort $ collectFreeVarOccurrences e-        esv = map (isUniqueEq fvs) es-        removed = mapMaybe fst esv-        needed = map head fvs L.\\ removed-        bs' = filter ((`elem` needed) . fst) bs-     in-        PExist bs' $ PAnd $ [ei | (Nothing, ei) <- esv]   where-    -- | Determine if the expression is an equality that sets the value of-    -- a variable that doesn't occur elsewhere.-    ---    -- In @isUniqueEq fvs e@, @fvs@ contains the occurrences of the free-    -- variables, so we can infer if there is more than one occurrence-    -- of a given free variable, and @e@ is the equality to analyze.-    ---    -- Yields @(Just v, e)@ if @v@ doesn't occur elsewhere, and @e@ has-    -- the form @v == e'@.-    isUniqueEq :: [[Symbol]] -> Expr -> (Maybe Symbol, Expr)-    isUniqueEq fvs er = case unElab er of-      PAtom brel e0 e1-        | isEqRel brel ->-          let m = isVarToDrop fvs e0 `mplus` isVarToDrop fvs e1-           in (m, er)-      _ ->-        (Nothing, er)--    -- | Tells if the binary relation is an equality.-    isEqRel Eq = True-    isEqRel Ueq = True-    isEqRel _ = False--    -- | @isVarToDrop fvs s@ yields @Just s@ if the variable @s@ doesn't occur-    -- elsewhere according to @fvs@.-    ---    -- > isVarToDrop fvs (cast_as_int s) == isVarToDrop fvs s-    ---    isVarToDrop fvs (EApp (EVar "cast_as_int") ei) = isVarToDrop fvs ei-    isVarToDrop fvs (EVar s)-      | elem [s] fvs = Just s-    isVarToDrop _fvs _ = Nothing--simplifyKVar e = e---- | Produces the free variables of an expressions as many times as they occur.------ There are no guarantees on the order in which the variables are produced. For--- instance,------ > collectFreeVarOccurrences "z (y x) (y x)" == ["z", "y", "x", "y", "x"]----collectFreeVarOccurrences :: Expr -> [Symbol]-collectFreeVarOccurrences = go []-  where-    go acc e0 = case e0 of-      ESym _ -> acc-      ECon _ -> acc-      EVar v -> v : acc-      PKVar _ (Su m) -> foldr (flip go) acc $ HashMap.elems m-      PGrad _ (Su m) _ e -> foldr (flip go) acc $ e : HashMap.elems m-      ENeg e -> go acc e-      PNot p -> go acc p-      ECst e _t -> go acc e-      PAll _xts p -> go acc p-      ELam (b, _) e -> go acc e L.\\ [b]-      ECoerc _a _t e -> go acc e-      PExist _xts p -> go acc p-      ETApp e _s -> go acc e-      ETAbs e _s -> go acc e-      EApp g e -> go (go acc e) g-      EBin _o e1 e2 -> go (go acc e2) e1-      PImp p1 p2 -> go (go acc p2) p1-      PIff p1 p2 -> go (go acc p2) p1-      PAtom _r e1 e2 -> go (go acc e2) e1-      EIte p e1 e2 -> go (go (go acc e2) e1) p-      PAnd ps -> foldr (flip go) acc ps-      POr ps -> foldr (flip go) acc ps+    simplifyKVar' = unElabSets . unElab . Sol.simplifyKVar HashSet.empty+    sets          = elabSetBag . solverFlags $ cfg+    unElabSets    = if sets then unElabFSetBagZ3 else id
src/Language/Fixpoint/Solver/Common.hs view
@@ -2,30 +2,39 @@  module Language.Fixpoint.Solver.Common (askSMT, toSMT) where -import Language.Fixpoint.Types.Config (Config, solver, solverFlags)+import Control.Monad.State+import Language.Fixpoint.Types.Config (Config, solverFlags) import Language.Fixpoint.Smt.Interface (Context(..), checkValidWithContext)+import Language.Fixpoint.Smt.Types (SmtM) import Language.Fixpoint.Types import Language.Fixpoint.Types.Visitor (kvarsExpr) import Language.Fixpoint.Defunctionalize (defuncAny) import Language.Fixpoint.SortCheck (ElabParam(..), elaborate)+import GHC.Stack (HasCallStack)  mytracepp :: (PPrint a) => String -> a -> a mytracepp = notracepp -askSMT :: Config -> Context -> [(Symbol, Sort)] -> Expr -> IO Bool-askSMT cfg ctx xs e---   | isContraPred e  = return False+askSMT+  :: HasCallStack+  => Config+  -> [(Symbol, Sort)] -- ^ symbols already declared in the SMT solver+  -> [(Symbol, Sort)] -- ^ symbols to declare in the SMT solver+  -> Expr+  -> SmtM Bool+askSMT cfg bsInSMT xs e   | isTautoPred  e     = return True-  | null (kvarsExpr e) = checkValidWithContext ctx xs PTrue e'+  | null (kvarsExpr e) =+      do ctx <- get+         let e' = toSMT "askSMT" cfg ctx (xs ++ bsInSMT) e+         checkValidWithContext xs PTrue e'   | otherwise          = return False-  where-    e' = toSMT "askSMT" cfg ctx xs e -toSMT :: String -> Config -> Context -> [(Symbol, Sort)] -> Expr -> Pred+toSMT :: HasCallStack => String -> Config -> Context -> [(Symbol, Sort)] -> Expr -> Pred toSMT msg cfg ctx xs e =     defuncAny cfg symenv .-        elaborate (ElabParam (solverFlags $ solver cfg) (dummyLoc msg) (elabEnv xs)) .-            mytracepp ("toSMT from " ++ msg ++ showpp e) $+        elaborate (ElabParam (solverFlags cfg) (dummyLoc msg) (elabEnv xs)) .+            mytracepp ("toSMT from " ++ msg ++ " > " ++ showpp e) $                 e   where     elabEnv = insertsSymEnv symenv
src/Language/Fixpoint/Solver/Eliminate.hs view
@@ -16,39 +16,61 @@ import           Language.Fixpoint.Types.Visitor   (kvarsExpr, isConcC) import           Language.Fixpoint.Graph import           Language.Fixpoint.Misc            (safeLookup, group, errorstar)-import           Language.Fixpoint.Solver.Sanitize  -------------------------------------------------------------------------------- -- | `solverInfo` constructs a `SolverInfo` comprising the Solution and various --   indices needed by the worklist-based refinement loop+--+-- Computes the set of cut and non-cut kvars, computes the hypotheses common+-- to all of the usage sites of each kvar, then initializes the solutions of+-- the non-cut KVars (in the sHyp field).+--+-- This is part of the implementation of the FUSION algorithm described in:+--+-- "Local Refinement Typing", ICFP 2017, https://ranjitjhala.github.io/static/local_refinement_typing.pdf+-- -------------------------------------------------------------------------------- {-# SCC solverInfo #-}-solverInfo :: Config -> SInfo a -> SolverInfo a b+solverInfo :: Config -> SInfo a -> SolverInfo a -------------------------------------------------------------------------------- solverInfo cfg sI = SI sHyp sI' cD cKs   where-    cD             = elimDeps     sI es nKs ebs+    cD             = elimDeps     sI es nKs     sI'            = cutSInfo     sI kI cKs-    sHyp           = Sol.fromList sE mempty mempty kHyps kS [] sEnv-    sEnv           = fromListSEnv [ (x, (i, sr_sort sr)) | (i, (x,sr, _)) <- bindEnvToList (bs sI)]+    sHyp = Sol.Sol+      { Sol.sMap = mempty+      , Sol.sHyp = M.fromList kHyps+      , Sol.sScp = kS+      }     kHyps          = nonCutHyps   sI kI nKs     kI             = kIndex       sI     (es, cKs, nKs) = kutVars cfg  sI     kS             = kvScopes     sI es-    sE             = symbolEnv   cfg sI-    ebs            = S.fromList [x | i <- ebinds sI, let (x, _, _) = lookupBindEnv i (bs sI) ] - --------------------------------------------------------------------------------+-- | For each KVar, provide the intersection of the binding environments+--   of all the constraints in which it appears.+--+-- See Section 2.4 of "Local Refinement Typing", ICFP 2017, for the motivation+-- to collect these. kvScopes :: SInfo a -> [CEdge] -> M.HashMap KVar IBindEnv-kvScopes sI es = is2env <$> kiM+kvScopes sI es = commonBindingsOfConstraints <$> kvarUses   where-    is2env = foldr1 intersectionIBindEnv . fmap (senv . getSubC sI)-    kiM    = group $ [(k, i) | (Cstr i, KVar k) <- es ] ++-                     [(k, i) | (KVar k, Cstr i) <- es ]+    -- | The common bindings of a list of constraints+    commonBindingsOfConstraints :: [Integer] -> IBindEnv+    commonBindingsOfConstraints =+      foldr1 intersectionIBindEnv . fmap (senv . getSubC sI) ---------------------------------------------------------------------------------+    -- | The constraints in which each KVar appears+    kvarUses :: M.HashMap KVar [Integer]+    kvarUses =+      group $ [(k, i) | (Cstr i, KVar k) <- es ] +++              [(k, i) | (KVar k, Cstr i) <- es ] +--------------------------------------------------------------------------------+-- | @cutSInfo si kI cKs@ drops well-formed constraints that don't refer to the+-- KVars in @cKs@. Also drops subtyping constraints that don't refer in their+-- RHS to any of the KVars in @cKs@ or which aren't concrete. cutSInfo :: SInfo a -> KIndex -> S.HashSet KVar -> SInfo a cutSInfo si kI cKs = si { ws = ws', cm = cm' }   where@@ -57,13 +79,17 @@     cs    = S.fromList      (concatMap kCs cKs)     kCs k = M.lookupDefault [] k kI +-- | Compute Dependencies and Cuts+--+-- Yields the edges of the dependency graph, then the set of KVars whose removal+-- makes the graph acyclic (cuts), and finally the rest of the KVars. kutVars :: Config -> SInfo a -> ([CEdge], S.HashSet KVar, S.HashSet KVar) kutVars cfg si   = (es, depCuts ds, depNonCuts ds)   where     (es, ds)     = elimVars cfg si  ----------------------------------------------------------------------------------- | Map each `KVar` to the list of constraints on which it appears on RHS+-- | Map each 'KVar' to the list of constraints on which it appears on RHS -------------------------------------------------------------------------------- type KIndex = M.HashMap KVar [Integer] 
src/Language/Fixpoint/Solver/EnvironmentReduction.hs view
@@ -33,9 +33,9 @@ import           Data.HashSet (HashSet) import qualified Data.HashSet as HashSet #if MIN_VERSION_base(4,20,0)-import           Data.List (nub, partition)+import           Data.List (partition) #else-import           Data.List (foldl', nub, partition)+import           Data.List (foldl', partition) #endif import           Data.Maybe (fromMaybe) import           Data.ShareMap (ShareMap)@@ -153,7 +153,6 @@      { bs = bs'      , cm = HashMap.fromList cm'      , ws = ws'-     , ebinds = updateEbinds bs' (ebinds finfo)      , bindInfo = updateBindInfoKeys bs' $ bindInfo finfo      } @@ -170,9 +169,6 @@        in           HashMap.filterWithKey (\bId _ -> memberIBindEnv bId ibindEnv) be -    -- Updates BindIds in an ebinds list-    updateEbinds be = filter (`HashMap.member` beBinds be)-     -- Updates BindId keys in a bindInfos map     updateBindInfoKeys be oldBindInfos =       HashMap.intersection oldBindInfos (beBinds be)@@ -310,10 +306,17 @@   filter relevantBind env   where     allSymbols =-      reachableSymbols (HashSet.union extraSymbols envSymbols) aenvMap+      reachableSymbols (HashSet.unions [extraSymbols, envSymbols, withKVars]) aenvMap     envSymbols =       HashSet.unions $ map (\(_, _, sr,_) -> sortedReftSymbols sr) env +    -- If there are bindings with KVars, we include them to be conservative.+    withKVars =+      HashSet.fromList $+      map fst $+      filter (not . HashMap.null . exprKVars . reftPred . sr_reft . snd) $+      map (\(x, _, sr, _) -> (x, sr)) env+     relevantBind (s, _, sr, _)       | HashSet.member s allSymbols = True       | otherwise = case reftPred (sr_reft sr) of@@ -470,15 +473,9 @@    in finfo         { bs = bs'         , cm = cm'-        , ebinds = updateEbinds oldToNew (ebinds finfo)         , bindInfo = updateBindInfoKeys oldToNew $ bindInfo finfo         }   where-    updateEbinds :: HashMap BindId [BindId] -> [BindId] -> [BindId]-    updateEbinds oldToNew ebs =-      nub $-      concat [ bId : fromMaybe [] (HashMap.lookup bId oldToNew) | bId <- ebs ]-     updateBindInfoKeys       :: HashMap BindId [BindId] -> HashMap BindId a -> HashMap BindId a     updateBindInfoKeys oldToNew infoMap =@@ -516,7 +513,7 @@            mergedEnv = mergeDuplicatedBindings env           undoANFEnv =-            if inlineANFBindings cfg then undoANFOnlyModified mergedEnv else HashMap.empty+            if inlineANFBinds cfg then undoANFOnlyModified mergedEnv else HashMap.empty           boolSimplEnv =             simplifyBooleanRefts $ HashMap.union undoANFEnv mergedEnv @@ -749,7 +746,13 @@ dropLikelyIrrelevantBindings ss env = HashMap.filterWithKey relevant env   where     directlyUses = HashMap.map (exprSymbolsSet . reftPred . sr_reft) env-    relatedSyms = relatedSymbols ss directlyUses+    relatedSyms = relatedSymbols (HashSet.union ss withKVars) directlyUses+    -- If there are bindings with KVars, we include them to be conservative.+    withKVars =+      HashSet.fromList $+      map fst $+      filter (not . HashMap.null . exprKVars . reftPred . sr_reft . snd) $+      HashMap.toList env     relevant s _sr =       (not (capitalizedSym s) || prefixOfSym s /= s) && s `HashSet.member` relatedSyms     capitalizedSym = Text.all isUpper . Text.take 1 . symbolText
src/Language/Fixpoint/Solver/Extensionality.hs view
@@ -24,7 +24,7 @@ mytracepp = notracepp  expand :: Config -> SInfo a -> SInfo a-expand cfg si = evalState (ext si) $ initST (symbolEnv cfg si) (ddecls si) (solverFlags $ solver cfg)+expand cfg si = evalState (ext si) $ initST (symbolEnv cfg si) (ddecls si) (solverFlags cfg)   where     ext :: SInfo a -> Ex a (SInfo a)     ext = extend@@ -148,6 +148,8 @@     go p (PImp p1 p2)    = f p =<< (PImp        <$>  go (negatePos p) p1 <*> go p p2)     go p (PAnd ps)       = f p . PAnd =<< (go p `traverse` ps) +    go p (ELet x e1 e2)  = f p =<< ELet x <$> go p e1 <*> go p e2+     -- The below cannot appear due to normalization     go p (PNot e)        = f p . PNot =<< go p e     go p (PIff p1 p2)    = f p =<< (PIff        <$>  go p p1 <*> go p p2            )@@ -160,7 +162,6 @@     go p (PExist xts e)  = f p . PExist xts =<< go p e     go p (ETApp e s)     = f p . (`ETApp` s) =<< go p e     go p (ETAbs e s)     = f p . (`ETAbs` s) =<< go p e-    go p (PGrad k s i e) = f p . PGrad k s i =<< go p e  normalize :: Expr -> Expr normalize expr' = mytracepp ("normalize: " ++ showpp expr') $ go expr'@@ -181,12 +182,12 @@     go (EIte e e1 e2)    = go $ PAnd [PImp e e1, PImp (PNot e) e2]     go (PAnd ps)         = pAnd (go <$> ps)     go (POr  ps)         = foldl' (\x y -> PImp (PImp (go x) PFalse) y) PFalse ps+    go e@ELet{}          = e     go e@(PAll _ _)      = e -- Cannot appear     go e@(ELam _ _)      = e -- Cannot appear     go e@(PExist _ _)    = e -- Cannot appear     go e@(ETApp _ _)     = e -- Cannot appear     go e@(ETAbs _ _)     = e -- Cannot appear-    go e@PGrad{}         = e -- Cannot appear   type Ex a = State (ExSt a)
− src/Language/Fixpoint/Solver/GradualSolution.hs
@@ -1,135 +0,0 @@-{-# LANGUAGE CPP                #-}-{-# LANGUAGE FlexibleInstances  #-}--module Language.Fixpoint.Solver.GradualSolution-  ( -- * Create Initial Solution-    init-  ) where--import           Control.Parallel.Strategies-import           Control.Monad.Reader-import qualified Data.HashMap.Strict            as M-import qualified Data.List                      as L-import           Data.Maybe                     (maybeToList, isNothing)-import           Language.Fixpoint.Types.Config-import           Language.Fixpoint.Types.PrettyPrint ()-import qualified Language.Fixpoint.SortCheck          as So-import           Language.Fixpoint.Misc-import qualified Language.Fixpoint.Types              as F-import qualified Language.Fixpoint.Types.Solutions    as Sol-import qualified Language.Fixpoint.Types.Constraints  as Cons-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) => Config -> F.SInfo a -> [(F.KVar, (F.GWInfo, [F.Expr]))]----------------------------------------------------------------------------------init cfg si = map elab (runReader (traverse (refineG si qs genv) gs) ef) `using` parList rdeepseq-  where-    qs         = F.quals si-    gs         = snd <$> gs0-    genv       = instConstants si--    gs0        = L.filter (Cons.isGWfc . snd) $ M.toList (F.ws si)--    elab (k, (x,es)) = (k, (x, elaborate (ElabParam ef (F.atLoc F.dummySpan "init") (sEnv (Cons.gsym x) (Cons.gsort x))) <$> es))--    sEnv x s    = isEnv {F.seSort = F.insertSEnv x s (F.seSort isEnv)}-    isEnv       = symbolEnv cfg si-    ef          = solverFlags $ solver cfg------------------------------------------------------------------------------------refineG :: F.SInfo a -> [F.Qualifier] -> F.SEnv F.Sort -> F.WfC a -> ElabM (F.KVar, (F.GWInfo, [F.Expr]))-refineG fi qs genv w =-  do (k, qb) <- refine fi qs genv w-     pure (k, (F.gwInfo w, Sol.qbExprs qb))--refine :: F.SInfo a -> [F.Qualifier] -> F.SEnv F.Sort -> F.WfC a -> ElabM (F.KVar, Sol.QBind)-refine fi qs genv w = refineK (Cons.allowHOquals fi) env qs $ F.wrft w-  where-    env             = wenv <> genv-    wenv            = F.sr_sort <$> F.fromListSEnv (F.envCs (F.bs fi) (F.wenv w))--instConstants :: F.SInfo a -> F.SEnv F.Sort-instConstants = F.fromListSEnv . filter notLit . F.toListSEnv . F.gLits-  where-    notLit    = not . F.isLitSymbol . fst---refineK :: Bool -> F.SEnv F.Sort -> [F.Qualifier] -> (F.Symbol, F.Sort, F.KVar) -> ElabM (F.KVar, Sol.QBind)-refineK ho env qs (v, t, k) =-  do eqs' <- Sol.qbFilterM (okInst env v t) eqs-     pure (k, eqs')-   where-    eqs                     = instK ho env v t qs------------------------------------------------------------------------------------instK :: Bool-      -> F.SEnv F.Sort-      -> F.Symbol-      -> F.Sort-      -> [F.Qualifier]-      -> Sol.QBind----------------------------------------------------------------------------------instK ho env v t = Sol.qb . unique . concatMap (instKQ ho env v t)-  where-    unique       = L.nubBy ((. Sol.eqPred) . (==) . Sol.eqPred)--instKQ :: Bool-       -> F.SEnv F.Sort-       -> F.Symbol-       -> F.Sort-       -> F.Qualifier-       -> [Sol.EQual]-instKQ ho env v t q =-  case Cons.qpSort <$> F.qParams q of-    (qt:qts) -> do-        (su0, v0) <- candidates senv [(t, [v])] qt-        xs        <- match senv tyss [v0] (So.apply su0 <$> qts)-        return     $ Sol.eQual q (reverse xs)-      where-        tyss       = instCands ho env-        senv       = (`F.lookupSEnvWithDistance` env)-    [] -> error "Empty qpSort of qParams q"--instCands :: Bool -> F.SEnv F.Sort -> [(F.Sort, [F.Symbol])]-instCands ho env = filter isOk tyss-  where-    tyss      = groupList [(t, x) | (x, t) <- xts]-    isOk      = if ho then const True else isNothing . F.functionSort . fst-    xts       = F.toListSEnv env--match :: So.Env -> [(F.Sort, [F.Symbol])] -> [F.Symbol] -> [F.Sort] -> [[F.Symbol]]-match env tyss xs (t : ts)-  = do (su, x) <- candidates env tyss t-       match env tyss (x : xs) (So.apply su <$> ts)-match _   _   xs []-  = return xs-----------------------------------------------------------------------------------candidates :: So.Env -> [(F.Sort, [F.Symbol])] -> F.Sort -> [(So.TVSubst, F.Symbol)]----------------------------------------------------------------------------------candidates env tyss tx =-    [(su, y) | (t, ys) <- tyss-             , su      <- maybeToList $ So.unifyFast mono env tx t-             , y       <- ys                                   ]-  where-    mono = So.isMono tx-----------------------------------------------------------------------------------okInst :: F.SEnv F.Sort -> F.Symbol -> F.Sort -> Sol.EQual -> ElabM Bool----------------------------------------------------------------------------------okInst env v t eq =-  do tc <- So.checkSorted F.dummySpan env sr-     pure $ isNothing tc-  where-    sr            = F.RR t (F.Reft (v, p))-    p             = Sol.eqPred eq---
− src/Language/Fixpoint/Solver/GradualSolve.hs
@@ -1,328 +0,0 @@-{-# LANGUAGE FlexibleContexts  #-}------------------------------------------------------------------------------------- | Solve a system of horn-clause constraints --------------------------------------------------------------------------------------------------------------------module Language.Fixpoint.Solver.GradualSolve (solveGradual) where--{- COMMENTING OUT AS IT DOESNT BUILD!-import           Control.Monad (when, filterM, foldM)-import           Control.Monad.State.Strict (lift)-import           Language.Fixpoint.Misc-import qualified Language.Fixpoint.Types.Solutions as Sol-import qualified Language.Fixpoint.SortCheck       as So-import           Language.Fixpoint.Types.PrettyPrint-import qualified Language.Fixpoint.Solver.GradualSolution  as S-import qualified Language.Fixpoint.Solver.Worklist  as W-import qualified Language.Fixpoint.Solver.Eliminate as E-import           Language.Fixpoint.Solver.Monad-import           Language.Fixpoint.Utils.Progress-import           Language.Fixpoint.Graph-import           Text.PrettyPrint.HughesPJ-import           Text.Printf-import           System.Console.CmdArgs.Verbosity (whenNormal, whenLoud)-import qualified Data.HashMap.Strict as M-import qualified Data.HashSet        as S--}--import           Control.DeepSeq-import qualified Language.Fixpoint.Types           as F-import           Language.Fixpoint.Types.Config hiding (stats)--solveGradual :: (NFData a, F.Fixpoint a) => Config -> F.SInfo a -> IO (F.Result (Integer, a))-solveGradual = undefined----{- COMMENTING OUT AS IT DOESNT BUILD!------------------------------------------------------------------------------------- | Progress Bar----------------------------------------------------------------------------------withProgressFI :: SolverInfo a b -> IO b -> IO b-withProgressFI = withProgress . fromIntegral . cNumScc . siDeps-----------------------------------------------------------------------------------printStats :: F.SInfo a ->  W.Worklist a -> Stats -> IO ()-printStats fi w s = putStrLn "\n" >> ppTs [ ptable fi, ptable s, ptable w ]-  where-    ppTs          = putStrLn . showpp . mconcat-----------------------------------------------------------------------------------solverInfo :: Config -> F.SInfo a -> SolverInfo a b----------------------------------------------------------------------------------solverInfo cfg fI-  | useElim cfg = E.solverInfo cfg fI-  | otherwise   = SI mempty fI cD (siKvars fI)-  where-    cD          = elimDeps fI (kvEdges fI) mempty--siKvars :: F.SInfo a -> S.HashSet F.KVar-siKvars = S.fromList . M.keys . F.ws-------------------------------------------------------------------------------------- | tidyResult ensures we replace the temporary kVarArg names introduced to---   ensure uniqueness with the original names in the given WF constraints.----------------------------------------------------------------------------------tidyResult :: F.Result a -> F.Result a-tidyResult r = r { F.resSolution  =  tidySolution  (F.resSolution r)-                 , F.gresSolution =  gtidySolution (F.gresSolution r)-                 }--tidySolution :: F.FixSolution -> F.FixSolution-tidySolution = fmap tidyPred--gtidySolution :: F.GFixSolution -> F.GFixSolution-gtidySolution = fmap tidyPred --  (\(e, es) -> (tidyPred e, tidyPred <$> es))--tidyPred :: F.Expr -> F.Expr-tidyPred = F.substf (F.eVar . F.tidySymbol)---predKs :: F.Expr -> [(F.KVar, F.Subst)]-predKs (F.PAnd ps)    = concatMap predKs ps-predKs (F.PKVar k su) = [(k, su)]-predKs _              = []-------------------------------------------------------------------------------------minimizeResult :: Config -> M.HashMap F.KVar F.Expr-               -> SolveM (M.HashMap F.KVar F.Expr)----------------------------------------------------------------------------------minimizeResult cfg s-  | minimalSol cfg = mapM minimizeConjuncts s-  | otherwise      = return s--minimizeConjuncts :: F.Expr -> SolveM F.Expr-minimizeConjuncts p = F.pAnd <$> go (F.conjuncts p) []-  where-    go []     acc   = return acc-    go (p:ps) acc   = do b <- isValid (F.pAnd (acc ++ ps)) p-                         if b then go ps acc-                              else go ps (p:acc)----showUnsat :: Bool -> Integer -> F.Pred -> F.Pred -> IO ()-showUnsat u i lP rP = {- when u $ -} do-  putStrLn $ printf   "UNSAT id %s %s" (show i) (show u)-  putStrLn $ showpp $ "LHS:" <+> pprint lP-  putStrLn $ showpp $ "RHS:" <+> pprint rP------------------------------------------------------------------------------------- | Predicate corresponding to RHS of constraint in current solution----------------------------------------------------------------------------------rhsPred :: F.SimpC a -> F.Expr----------------------------------------------------------------------------------rhsPred c-  | isTarget c = F.crhs c-  | otherwise  = errorstar $ "rhsPred on non-target: " ++ show (F.sid c)--isValid :: F.Expr -> F.Expr -> SolveM Bool-isValid p q = (not . null) <$> filterValid p [(q, ())]------------------------------------------------------------------------------------- | solve with edits to allow Gradual types --------------------------------------------------------------------------------------------------------------------solveGradual :: (NFData a, F.Fixpoint a) => Config -> F.SInfo a -> IO (F.Result (Integer, a))--- solveGradual = undefined--solveGradual cfg fi = do-    (res, stat) <- withProgressFI sI $ runSolverM cfg sI n act-    when (solverStats cfg) $ printStats fi wkl stat-    return res-  where-    act  = solveGradual_ cfg fi s0 ks  wkl-    sI   = solverInfo cfg fi-    wkl  = W.init sI-    n    = fromIntegral $ W.wRanks wkl-    s0   = siSol  sI-    ks   = siVars sI-----------------------------------------------------------------------------------solveGradual_ :: (NFData a, F.Fixpoint a)-       => Config-       -> F.SInfo a-       -> Sol.GSolution-       -> S.HashSet F.KVar-       -> W.Worklist a-       -> SolveM (F.Result (Integer, a), Stats)----------------------------------------------------------------------------------solveGradual_ cfg fi s0 ks wkl = do-  let s1  = mappend s0 $ {- SCC "sol-init" #-} S.init cfg fi ks-  s2      <- {- SCC "sol-local"  #-} filterLocal s1-  s       <- {- SCC "sol-refine" #-} refine s2 wkl-  res     <- {- SCC "sol-result" #-} result cfg wkl s-  st      <- stats-  let res' = {- SCC "sol-tidy"   #-} tidyResult res-  return $!! (res', st)--filterLocal :: Sol.GSolution -> SolveM Sol.GSolution-filterLocal sol = do-  gs' <- mapM (initGBind sol) gs-  return $ Sol.updateGMap sol $ M.fromList gs'-  where-    gs = M.toList $ Sol.gMap sol--initGBind :: Sol.GSolution -> (F.KVar, (((F.Symbol, F.Sort), F.Expr), Sol.GBind)) -> SolveM (F.KVar, (((F.Symbol, F.Sort), F.Expr), Sol.GBind))-initGBind sol (k, (e, gb)) = do-   elems0  <- filterM (isLocal e) (Sol.gbEquals gb)-   elems   <- sortEquals elems0-   lattice <- makeLattice [] (map (:[]) elems) elems-   return $ ((k,) . (e,) . Sol.equalsGb) lattice-  where-    makeLattice acc new elems-      | null new-      = return 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--    notTrivial [] _     = return True-    notTrivial (x:xs) p = do v <- isValid (mkPred x) (mkPred p)-                             if v then return False-                                  else notTrivial xs p--    mkPred eq = So.elaborate "initBGind.mkPred" (Sol.sEnv sol) (F.pAnd (Sol.eqPred <$> eq))-    isLocal (v, e) eqs = do-      let pp = So.elaborate "filterLocal" (Sol.sEnv sol) $ F.PExist [v] $ F.pAnd (e:(Sol.eqPred <$> eqs))-      isValid mempty pp--    root      = Sol.trueEqual-    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 (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------------------------------------------------------------------------------------refine :: Sol.GSolution -> W.Worklist a -> SolveM Sol.GSolution----------------------------------------------------------------------------------refine s w-  | Just (c, w', newScc, rnk) <- W.pop w = do-     i       <- tickIter newScc-     (b, s') <- refineC i s c-     lift $ writeLoud $ refineMsg i c b rnk-     let w'' = if b then W.push c w' else w'-     refine 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-------------------------------------------------------------------------------- | Single Step Refinement ----------------------------------------------------------------------------------------------------------------------------refineC :: Int -> Sol.GSolution -> F.SimpC a -> SolveM (Bool, Sol.GSolution)-----------------------------------------------------------------------------refineC _i s c-  | null rhs  = return (False, s)-  | otherwise = do be      <- getBinds-                   let lhss = snd <$> S.lhsPred be s c-                   kqs     <- filterValidGradual lhss rhs-                   return   $ S.update s ks kqs-  where-    _ci       = F.subcId c-    (ks, rhs) = rhsCands s c-    -- msg       = printf "refineC: iter = %d, sid = %s, soln = \n%s\n"-    --               _i (show (F.sid c)) (showpp s)-    _msg ks xs ys = printf "refineC: iter = %d, sid = %s, s = %s, rhs = %d, rhs' = %d \n"-                     _i (show _ci) (showpp ks) (length xs) (length ys)---rhsCands :: Sol.GSolution -> F.SimpC a -> ([F.KVar], Sol.Cand (F.KVar, Sol.EQual))-rhsCands s c    = (fst <$> ks, kqs)-  where-    kqs         = [ (p, (k, q)) | (k, su) <- ks, (p, q)  <- cnd k su ]-    ks          = predKs . F.crhs $ c-    cnd k su    = Sol.qbPreds msg s su (Sol.lookupQBind s k)-    msg         = "rhsCands: " ++ show (F.sid c)------------------------------------------------------------------------------------- | Gradual Convert Solution into Result --------------------------------------------------------------------------------------------------------------------------------result :: (F.Fixpoint a) => Config -> W.Worklist a -> Sol.GSolution-       -> SolveM (F.Result (Integer, a))----------------------------------------------------------------------------------result cfg wkl s = do-  lift $ writeLoud "Computing Result"-  stat    <- result_ wkl s-  lift $ whenNormal $ putStrLn $ "RESULT: " ++ show (F.sid <$> stat)-  F.Result (ci <$> stat) <$> solResult cfg s <*> solResultGradual wkl cfg s-  where-    ci c = (F.subcId c, F.sinfo c)--result_ :: Fixpoint a =>  W.Worklist a -> Sol.GSolution -> SolveM (F.FixResult (F.SimpC a))-result_  w s = res <$> filterM (isUnsat s) cs-  where-    cs       = W.unsatCandidates w-    res []   = F.Safe-    res cs'  = F.Unsafe cs'--solResult :: Config -> Sol.GSolution -> SolveM (M.HashMap F.KVar F.Expr)-solResult cfg-  = minimizeResult cfg . Sol.result---solResultGradual :: W.Worklist a -> Config -> Sol.GSolution -> SolveM F.GFixSolution-solResultGradual w _cfg sol-  = F.toGFixSol . Sol.resultGradual <$> updateGradualSolution (W.unsatCandidates w) sol-----------------------------------------------------------------------------------updateGradualSolution :: [F.SimpC a] -> Sol.GSolution -> SolveM (Sol.GSolution)----------------------------------------------------------------------------------updateGradualSolution cs sol = foldM f (Sol.emptyGMap sol) cs-  where-   f s c = do-    be <- getBinds-    let lpi = S.lhsPred be sol c-    let rp  = rhsPred c-    gbs    <- firstValid rp lpi-    return $ Sol.updateGMapWithKey gbs s---firstValid :: Monoid a =>  F.Expr -> [(a, F.Expr)] -> SolveM a-firstValid _   [] = return mempty-firstValid rhs ((y,lhs):xs) = do-  v <- isValid lhs rhs-  if v then return y else firstValid rhs xs------------------------------------------------------------------------------------isUnsat :: Fixpoint a => Sol.GSolution -> F.SimpC a -> SolveM Bool----------------------------------------------------------------------------------isUnsat s c = do-  -- lift   $ printf "isUnsat %s" (show (F.subcId c))-  _     <- tickIter True -- newScc-  be    <- getBinds-  let lpi = S.lhsPred be s c-  let rp = rhsPred        c-  res   <- (not . or) <$> mapM (`isValid` rp) (snd <$> lpi)-  lift   $ whenLoud $ showUnsat res (F.subcId c) (F.pOr (snd <$> lpi)) rp-  return res----}
− src/Language/Fixpoint/Solver/Instantiate.hs
@@ -1,816 +0,0 @@------------------------------------------------------------------------------------ | This module implements "Proof by Logical Evaluation" where we---   unfold function definitions if they *must* be unfolded, to strengthen---   the environments with function-definition-equalities.---   The algorithm is discussed at length in:------     1. "Refinement Reflection", POPL 2018, https://arxiv.org/pdf/1711.03842---     2. "Reasoning about Functions", VMCAI 2018, https://ranjitjhala.github.io/static/reasoning-about-functions.pdf-----------------------------------------------------------------------------------{-# LANGUAGE OverloadedStrings         #-}-{-# LANGUAGE PartialTypeSignatures     #-}-{-# LANGUAGE TupleSections             #-}-{-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE ViewPatterns              #-}-{-# LANGUAGE PatternGuards             #-}-{-# LANGUAGE RecordWildCards           #-}-{-# LANGUAGE ExistentialQuantification #-}--module Language.Fixpoint.Solver.Instantiate (instantiate) where--import           Language.Fixpoint.Types-import           Language.Fixpoint.Types.Config  as FC-import qualified Language.Fixpoint.Types.Visitor as Vis-import qualified Language.Fixpoint.Misc          as Misc -- (mapFst)-import qualified Language.Fixpoint.Smt.Interface as SMT-import           Language.Fixpoint.Defunctionalize-import qualified Language.Fixpoint.Utils.Trie    as T-import           Language.Fixpoint.Utils.Progress -- as T-import           Language.Fixpoint.SortCheck-import           Language.Fixpoint.Graph.Deps             (isTarget)-import           Language.Fixpoint.Solver.Sanitize        (symbolEnv)-import qualified Language.Fixpoint.Solver.PLE as PLE      (instantiate)-import qualified Language.Fixpoint.Solver.Common as Common (toSMT)-import           Language.Fixpoint.Solver.Common          (askSMT)-import           Control.Monad ((>=>), foldM, forM, forM_, join)-import           Control.Monad.State-import           Data.Bifunctor (first, second)-import qualified Data.Text            as T-import qualified Data.HashMap.Strict  as M-import qualified Data.HashSet         as S-import qualified Data.List            as L-import qualified Data.Maybe           as Mb -- (isNothing, catMaybes, fromMaybe)-import           Data.Char            (isDigit, isUpper)--- import           Debug.Trace          (trace)--- import           Text.Printf (printf)--mytracepp :: (PPrint a) => String -> a -> a-mytracepp = notracepp------------------------------------------------------------------------------------- | Strengthen Constraint Environments via PLE----------------------------------------------------------------------------------instantiate :: (Loc a) => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)-instantiate cfg info subcIds-  | not (oldPLE cfg)-  = PLE.instantiate cfg info subcIds--  | noIncrPle cfg-  = instantiate' cfg info subcIds--  | otherwise-  = incrInstantiate' cfg info subcIds------------------------------------------------------------------------------------- | New "Incremental" PLE -- see [NOTE:TREE-LIKE]--{- | [NOTE:TREE-LIKE] incremental PLE relies crucially on the SInfo satisfying-     a "tree like"   invariant:-       forall constraints c, c'.-         if i in c and i in c' then-           forall 0 <= j < i, j in c and j in c'-- -}----------------------------------------------------------------------------------incrInstantiate' :: (Loc a) => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)---------------------------------------------------------------------------------incrInstantiate' cfg info subcIds = do-    let cs = [ (i, c) | (i, c) <- M.toList (cm info), isPleCstr aEnv i c-                      ,  maybe True (i `L.elem`) subcIds ]-    let t  = mkCTrie cs                                               -- 1. BUILD the Trie-    res   <- withProgress (1 + length cs) $-               withCtx cfg file sEnv (defns info) (pleTrie t . instEnv cfg info cs)  -- 2. TRAVERSE Trie to compute InstRes-    return $ resSInfo cfg sEnv info res                                 -- 3. STRENGTHEN SInfo using InstRes-  where-    file   = srcFile cfg ++ ".evals"-    sEnv   = symbolEnv cfg info-    aEnv   = ae info-------------------------------------------------------------------------------------- | Step 1a: @instEnv@ sets up the incremental-PLE environment-instEnv :: (Loc a) => Config -> SInfo a -> [(SubcId, SimpC a)] -> SMT.Context -> InstEnv a-instEnv cfg info cs ctx = InstEnv cfg ctx bEnv aEnv (M.fromList cs) γ s0-  where-    bEnv              = bs info-    aEnv              = ae info-    γ                 = knowledge cfg ctx aEnv-    s0                = EvalEnv 0 [] aEnv (SMT.ctxSymEnv ctx) cfg--------------------------------------------------------------------------------------------------- | Step 1b: @mkCTrie@ builds the @Trie@ of constraints indexed by their environments-mkCTrie :: [(SubcId, SimpC a)] -> CTrie-mkCTrie ics  = mytracepp  "TRIE" $ T.fromList [ (cBinds c, i) | (i, c) <- ics ]-  where-    cBinds   = L.sort . elemsIBindEnv . senv--------------------------------------------------------------------------------------------------- | Step 2: @pleTrie@ walks over the @CTrie@ to actually do the incremental-PLE-pleTrie :: CTrie -> InstEnv a -> IO InstRes-pleTrie t env = loopT env ctx0 diff0 Nothing res0 t-  where-    diff0        = []-    res0         = M.empty-    ctx0         = initCtx es0-    es0          = eqBody <$> L.filter (null . eqArgs) (aenvEqs . ieAenv $ env)--loopT :: InstEnv a -> ICtx -> Diff -> Maybe BindId -> InstRes -> CTrie -> IO InstRes-loopT env ctx delta i res t = case t of-  T.Node []  -> return res-  T.Node [b] -> loopB env ctx delta i res b-  T.Node bs  -> withAssms env ctx delta Nothing $ \ctx' -> do-                  (ctx'', res') <- ple1 env ctx' i Nothing res-                  foldM (loopB env ctx'' [] i) res' bs--loopB :: InstEnv a -> ICtx -> Diff -> Maybe BindId -> InstRes -> CBranch -> IO InstRes-loopB env ctx delta iMb res b = case b of-  T.Bind i t -> loopT env ctx (i:delta) (Just i) res t-  T.Val cid  -> withAssms env ctx delta (Just cid) $ \ctx' -> do-                  progressTick-                  snd <$> ple1 env ctx' iMb (Just cid) res---withAssms :: InstEnv a -> ICtx -> Diff -> Maybe SubcId -> (ICtx -> IO b) -> IO b-withAssms env@InstEnv{..} ctx delta cidMb act = do-  let ctx'  = updCtx env ctx delta cidMb-  let assms = mytracepp  ("ple1-assms: " ++ show (cidMb, delta)) (icAssms ctx')-  SMT.smtBracket ieSMT  "PLE.evaluate" $ do-    forM_ assms (SMT.smtAssert ieSMT)-    act ctx'---- | @ple1@ performs the PLE at a single "node" in the Trie-ple1 :: InstEnv a -> ICtx -> Maybe BindId -> Maybe SubcId -> InstRes -> IO (ICtx, InstRes)-ple1 env@InstEnv{..} ctx i cidMb res = do-  let cands = mytracepp  ("ple1-cands: "  ++ show cidMb) $ S.toList (icCands ctx)-  -- unfolds  <- evalCands ieKnowl ieEvEnv cands-  unfolds  <- evalCandsLoop ieCfg ieSMT ieKnowl ieEvEnv cands-  return    $ updCtxRes env ctx res i cidMb (mytracepp  ("ple1-cands-unfolds: " ++ show cidMb) unfolds)--_evalCands :: Knowledge -> EvalEnv -> [Expr] -> IO [Unfold]-_evalCands _ _  []    = return []-_evalCands γ s0 cands = do eqs <- mapM (evalOne γ s0) cands-                           return $ mkUnfolds (zip (Just <$> cands) eqs)--unfoldPred :: Config -> SMT.Context -> [Unfold] -> Pred-unfoldPred cfg ctx = toSMT cfg ctx [] . pAnd . concatMap snd--evalCandsLoop :: Config -> SMT.Context -> Knowledge -> EvalEnv -> [Expr] -> IO [Unfold]-evalCandsLoop cfg ctx γ s0 = go []-  where-    go acc []    = return acc-    go acc cands = do eqss   <- SMT.smtBracket ctx "PLE.evaluate" $ do-                                  SMT.smtAssert ctx (unfoldPred cfg ctx acc)-                                  mapM (evalOne γ s0) cands-                      let us  = zip (Just <$> cands) eqss-                      case mkUnfolds us of-                        []  -> return acc-                        us' -> do let acc'   = acc ++ us'-                                  let oks    = S.fromList [ e | (Just e, _) <- us' ]-                                  let cands' = [ e | e <- cands, not (S.member e oks) ]-                                  go acc' cands'---------------------------------------------------------------------------------------------------- | Step 3: @resSInfo@ uses incremental PLE result @InstRes@ to produce the strengthened SInfo--resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> SInfo a-resSInfo cfg env info res = strengthenBinds info res'-  where-    res'     = M.fromList $ mytracepp  "ELAB-INST:  " $ zip is ps''-    ps''     = zipWith (\i -> elaborate (ElabParam (solverFlags $ solver cfg) (atLoc dummySpan ("PLE1 " ++ show i)) env)) is ps'-    ps'      = defuncAny cfg env ps-    (is, ps) = unzip (M.toList res)--------------------------------------------------------------------------------------------------- | @InstEnv@ has the global information needed to do PLE-data InstEnv a = InstEnv-  { ieCfg   :: !Config-  , ieSMT   :: !SMT.Context-  , ieBEnv  :: !(BindEnv a)-  , ieAenv  :: !AxiomEnv-  , ieCstrs :: !(M.HashMap SubcId (SimpC a))-  , ieKnowl :: !Knowledge-  , ieEvEnv :: !EvalEnv-  }---- | @ICtx@ is the local information -- at each trie node -- obtained by incremental PLE-data ICtx    = ICtx-  { icAssms  :: ![Pred]          -- ^ Hypotheses, already converted to SMT format-  , icCands  :: S.HashSet Expr   -- ^ "Candidates" for unfolding-  , icEquals :: ![Expr]          -- ^ "Known" equalities-  , icSolved :: S.HashSet Expr   -- ^ Terms that we have already expanded-  }---- | @InstRes@ is the final result of PLE; a map from @BindId@ to the equations "known" at that BindId-type InstRes = M.HashMap BindId Expr---- | @Unfold is the result of running PLE at a single equality;---     (e, [(e1, e1')...]) is the source @e@ and the (possible empty)---   list of PLE-generated equalities (e1, e1') ...--- type Unfold  = (Maybe Expr, [(Expr, Expr)])-type Unfold  = (Maybe Expr, [Expr])-type CTrie   = T.Trie   SubcId-type CBranch = T.Branch SubcId-type Diff    = [BindId]    -- ^ in "reverse" order--initCtx :: [Expr] -> ICtx-initCtx es = ICtx-  { icAssms  = []-  , icCands  = mempty-  , icEquals = mytracepp  "INITIAL-STUFF-INCR" es-  , icSolved = mempty-  }--equalitiesPred :: [(Expr, Expr)] -> [Expr]-equalitiesPred eqs = [ EEq e1 e2 | (e1, e2) <- eqs, e1 /= e2 ]--updCtxRes :: InstEnv a -> ICtx -> InstRes -> Maybe BindId -> Maybe SubcId -> [Unfold] -> (ICtx, InstRes)-updCtxRes env ctx res iMb cidMb us-                       = -- trace _msg-                         ( ctx { {- icCands  = cands', -} icSolved = solved', icEquals = mempty}-                         , res'-                         )-  where-    _msg               = Mb.maybe "nuttin\n" (debugResult env res') cidMb-    res'               = updRes res iMb (pAnd solvedEqs)-    _cands'             = (icCands ctx `S.union` newCands) `S.difference` solved'-    solved'            = S.union (icSolved ctx) solvedCands-    newCands           = S.fromList (concatMap topApps newEqs)-    solvedCands        = S.fromList [ e | (Just e, _) <- okUnfolds ]-    solvedEqs          = icEquals ctx ++ newEqs-    newEqs             = concatMap snd okUnfolds-    okUnfolds          = mytracepp  _str [ (eMb, ps)  | (eMb, ps) <- us, {- let ps = equalitiesPred eqs, -} not (null ps) ]-    _str               = "okUnfolds " ++ showpp (iMb, cidMb)-    -- cands'             = S.difference (icCands ctx) (S.fromList solvedCands)-    -- solvedEqs          = icEquals ctx ++ concatMap snd us-    -- solvedCands        = [ e          | (Just e, _) <- us]--mkUnfolds :: [(a, [(Expr, Expr)])] -> [(a, [Expr])]-mkUnfolds us = [ (eMb, ps)  | (eMb, eqs) <- us-                            , let ps = equalitiesPred eqs-                            , not (null ps)-               ]--debugResult :: InstEnv a -> InstRes -> SubcId -> String-debugResult InstEnv{..} res subId = msg-  where-    msg                          = "INCR-INSTANTIATE i = " ++ show subId ++ ": " ++ showpp cidEqs-    cidEqs                       = pAnd [ e | i <- cBinds, e <- Mb.maybeToList $ M.lookup i res ]-    cBinds                       = L.sort . elemsIBindEnv . senv . getCstr ieCstrs $ subId---updRes :: InstRes -> Maybe BindId -> Expr -> InstRes-updRes res (Just i) e = M.insert i e res-updRes res  Nothing _ = res---- | @updCtx env ctx delta cidMb@ adds the assumptions and candidates from @delta@ and @cidMb@---   to the context.-updCtx :: InstEnv a -> ICtx -> Diff -> Maybe SubcId -> ICtx-updCtx InstEnv {..} ctx delta cidMb-              = ctx { icAssms  = ctxEqs-                    , icCands  = cands   <> icCands  ctx-                    , icEquals = initEqs <> icEquals ctx }-  where-    initEqs   = equalitiesPred (initEqualities ieSMT ieAenv bs)-    cands     = S.fromList (concatMap topApps es0) `S.difference` icSolved ctx-    ctxEqs    = toSMT ieCfg ieSMT [] <$>-                  (initEqs ++-                  [ expr xr-                  | xr@(_, r) <- bs-                  , null (Vis.kvarsExpr $ reftPred $ sr_reft r)-                  ])-    (bs, es0) = (second unElabSortedReft <$> binds, unElab <$> es)-    es        = eRhs : (expr <$> binds)-    eRhs      = maybe PTrue crhs subMb-    binds     = [ (x, y)  | i <- delta, let (x, y, _) = lookupBindEnv i ieBEnv ]-    subMb     = getCstr ieCstrs <$> cidMb--getCstr :: M.HashMap SubcId (SimpC a) -> SubcId -> SimpC a-getCstr env cid = Misc.safeLookup "Instantiate.getCstr" cid env------------------------------------------------------------------------------------- | "Old" GLOBAL PLE----------------------------------------------------------------------------------instantiate' :: (Loc a) => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)-instantiate' cfg info subcIds = sInfo cfg env info <$> withCtx cfg file env (defns info) act-  where-    act ctx         = forM cstrs $ \(i, c) ->-                        ((i,srcSpan c),) . mytracepp  ("INSTANTIATE i = " ++ show i) <$> instSimpC cfg ctx (bs info) aenv i c-    cstrs           = [ (i, c) | (i, c) <- M.toList (cm info) , isPleCstr aenv i c-                               ,  maybe True (i `L.elem`) subcIds ]-    file            = srcFile cfg ++ ".evals"-    env             = symbolEnv cfg info-    aenv            = {- mytracepp  "AXIOM-ENV" -} ae info--sInfo :: Config -> SymEnv -> SInfo a -> [((SubcId, SrcSpan), Expr)] -> SInfo a-sInfo cfg env info ips = strengthenHyp info (mytracepp  "ELAB-INST:  " $ zip (fst <$> is) ps'')-  where-    (is, ps)         = unzip ips-    ps'              = defuncAny cfg env ps-    ps''             = zipWith (\(i, sp) -> elaborate (ElabParam (solverFlags $ solver cfg) (atLoc sp ("PLE1 " ++ show i)) env)) is ps'--instSimpC :: Config -> SMT.Context -> BindEnv a -> AxiomEnv -> SubcId -> SimpC a -> IO Expr-instSimpC cfg ctx bds aenv subId sub-  | isPleCstr aenv subId sub = do-    let is0       = mytracepp  "INITIAL-STUFF" $ eqBody <$> L.filter (null . eqArgs) (aenvEqs aenv)-    let (bs, es0) = cstrExprs bds sub-    equalities   <- evaluate cfg ctx aenv bs es0 subId-    let evalEqs   = [ EEq e1 e2 | (e1, e2) <- equalities, e1 /= e2 ]-    return        $ pAnd (is0 ++ evalEqs)-  | otherwise     = return PTrue--isPleCstr :: AxiomEnv -> SubcId -> SimpC a -> Bool-isPleCstr aenv subId c = isTarget c && M.lookupDefault False subId (aenvExpand aenv)--cstrExprs :: BindEnv a -> SimpC a -> ([(Symbol, SortedReft)], [Expr])-cstrExprs bds sub = (second unElabSortedReft <$> binds, unElab <$> es)-  where-    es            = crhs sub : (expr <$> binds)-    binds         = envCs bds (senv sub)------------------------------------------------------------------------------------- | Symbolic Evaluation with SMT----------------------------------------------------------------------------------evaluate :: Config -> SMT.Context -> AxiomEnv -- ^ Definitions-         -> [(Symbol, SortedReft)]            -- ^ Environment of "true" facts-         -> [Expr]                            -- ^ Candidates for unfolding-         -> SubcId                            -- ^ Constraint Id-         -> IO [(Expr, Expr)]                 -- ^ Newly unfolded equalities----------------------------------------------------------------------------------evaluate cfg ctx aenv facts es subId = do-  let eqs      = initEqualities ctx aenv facts-  let γ        = knowledge cfg ctx aenv-  let cands    = mytracepp  ("evaluate-cands " ++ showpp subId) $ Misc.setNub (concatMap topApps es)-  let s0       = EvalEnv 0 [] aenv (SMT.ctxSymEnv ctx) cfg-  let ctxEqs   = [ toSMT cfg ctx [] (EEq e1 e2) | (e1, e2)  <- eqs ]-              ++ [ toSMT cfg ctx [] (expr xr)   | xr@(_, r) <- facts, null (Vis.kvarsExpr $ reftPred $ sr_reft r) ]-  eqss        <- _evalLoop cfg ctx γ s0 ctxEqs cands-  return       $ eqs ++ eqss----_evalLoop :: Config -> SMT.Context -> Knowledge -> EvalEnv -> [Pred] -> [Expr] -> IO [(Expr, Expr)]-_evalLoop cfg ctx γ s0 ctxEqs = loop 0 []-  where-    loop _ acc []    = return acc-    loop i acc cands = do let eqp = toSMT cfg ctx [] $ pAnd $ equalitiesPred acc-                          eqss <- SMT.smtBracket ctx "PLE.evaluate" $ do-                                    forM_ (eqp : ctxEqs) (SMT.smtAssert ctx)-                                    mapM (evalOne γ s0) cands-                          case concat eqss of-                            []   -> return acc-                            eqs' -> do let acc'   = acc ++ eqs'-                                       let oks    = S.fromList (fst <$> eqs')-                                       let cands' = [ e | e <- cands, not (S.member e oks) ]-                                       loop (i + 1 :: Integer) acc' cands'-------------------------------------------------------------------------------------data EvalEnv = EvalEnv-  { evId        :: !Int-  , evSequence  :: [(Expr,Expr)]-  , _evAEnv     :: !AxiomEnv-  , evEnv       :: !SymEnv-  , _evCfg      :: !Config-  }--type EvalST a = StateT EvalEnv IO a-----------------------------------------------------------------------------------evalOne :: Knowledge -> EvalEnv -> Expr -> IO [(Expr, Expr)]-evalOne γ s0 e = do-  (e', st) <- runStateT (eval γ initCS (mytracepp "evalOne: " e)) s0-  if e' == e then return [] else return ((e, e') : evSequence st)--{- | [NOTE: Eval-Ite]  We should not be doing any PLE/eval under if-then-else where-     the guard condition does not provably hold. For example, see issue #387.-     However, its ok and desirable to `eval` in this case, as long as one is not-     unfolding recursive functions. To permit this, we track the "call-stack" and-     whether or not, `eval` is occurring under an unresolved guard: if so, we do not-     expand under any function that is already on the call-stack.-  -}--data Recur  = Ok | Stop deriving (Eq, Show)-type CStack = ([Symbol], Recur)--instance PPrint Recur where-  pprintTidy _ = Misc.tshow--initCS :: CStack-initCS = ([], Ok)--pushCS :: CStack -> Symbol -> CStack-pushCS (fs, r) f = (f:fs, r)--recurCS :: CStack -> Symbol -> Bool-recurCS (_,  Ok) _ = True--- recurCS (_,  _ ) _ = False -- not (f `elem` fs)-recurCS (fs, _) f  = f `notElem` fs--noRecurCS :: CStack -> CStack-noRecurCS (fs, _) = (fs, Stop)---- Don't evaluate under Lam, App, Ite, or Constants-topApps :: Expr -> [Expr]-topApps = go-  where-    go (PAnd es)       = concatMap go es-    go (POr es)        = concatMap go es-    go (PAtom _ e1 e2) = go e1  ++ go e2-    go (PIff e1 e2)    = go e1  ++ go e2-    go (PImp e1 e2)    = go e1  ++ go e2-    go (EBin  _ e1 e2) = go e1  ++ go e2-    go (PNot e)        = go e-    go (ENeg e)        = go e-    go e@(EApp _ _)    = [e]-    go _               = []---- makeLam is the adjoint of splitEApp-makeLam :: Knowledge -> Expr -> Expr-makeLam γ e = L.foldl' (flip ELam) e (knLams γ)--eval :: Knowledge -> CStack -> Expr -> EvalST Expr-eval γ stk = go-  where-    go (ELam (x,s) e)   = ELam (x, s) <$> eval γ' stk e where γ' = γ { knLams = (x, s) : knLams γ }-    go e@(EIte b e1 e2) = go b        >>= \b' -> evalIte γ stk e b' e1 e2-    go (ECoerc s t e)   = ECoerc s t  <$> go e-    go e@(EApp _ _)     = evalArgs γ stk e >>= evalApp γ stk e-    go e@(EVar _)       = evalApp  γ stk e (e, [])-    go (PAtom r e1 e2)  = PAtom r      <$> go e1 <*> go e2-    go (ENeg e)         = ENeg         <$> go e-    go (EBin o e1 e2)   = EBin o       <$> go e1 <*> go e2-    go (ETApp e t)      = flip ETApp t <$> go e-    go (ETAbs e s)      = flip ETAbs s <$> go e-    go (PNot e)         = PNot         <$> go e-    go (PImp e1 e2)     = PImp         <$> go e1 <*> go e2-    go (PIff e1 e2)     = PIff         <$> go e1 <*> go e2-    go (PAnd es)        = PAnd         <$> (go `traverse` es)-    go (POr es)         = POr          <$> (go `traverse` es)-    go e                = return e---- | `evalArgs` also evaluates all the partial applications for hacky reasons,---   suppose `foo g = id` then we want `foo g 10 = 10` and for that we need---   to `eval` the term `foo g` into `id` to tickle the `eval` on `id 10`.---   This seems a bit of a hack. At any rate, this can lead to divergence.---   TODO: distill a .fq test from the MOSSAKA-hw3 example.--evalArgs :: Knowledge -> CStack -> Expr -> EvalST (Expr, [Expr])-evalArgs γ stk = go []-  where-    go acc (EApp f e)-      = do f' <- evalOk γ stk f-           e' <- eval γ stk e-           go (e':acc) f'-    go acc e-      = (,acc) <$> eval γ stk e---- | Minimal test case illustrating this `evalOk` hack is LH#tests/ple/pos/MossakaBug.hs---   too tired & baffled to generate simple .fq version. TODO:nuke and rewrite PLE!-evalOk :: Knowledge -> CStack -> Expr -> EvalST Expr-evalOk γ stk@(_, Ok) e = eval γ stk e-evalOk _ _           e = pure e--{--evalArgs :: Knowledge -> CStack -> Expr -> EvalST (Expr, [Expr])-evalArgs-  | True  = evalArgsOLD-  | False = evalArgsNEW--evalArgsNEW :: Knowledge -> CStack -> Expr -> EvalST (Expr, [Expr])-evalArgsNEW γ stk e = do-    let (e1, es) = splitEApp e-    e1' <- eval γ stk e1-    es' <- mapM (eval γ stk) es-    return (e1', es')---}--evalApp :: Knowledge -> CStack -> Expr -> (Expr, [Expr]) -> EvalST Expr--- evalApp γ stk e (e1, es) = tracepp ("evalApp:END" ++ showpp (e1,es)) <$> (evalAppAc γ stk e (e1, es))-evalApp γ stk e (e1, es) = do-  res     <- evalAppAc γ stk e (e1, es)-  let diff = res /= eApps e1 es-  return   $ mytracepp ("evalApp:END:" ++ showpp diff) res--evalAppAc :: Knowledge -> CStack -> Expr -> (Expr, [Expr]) -> EvalST Expr--{- MOSSAKA-}-evalAppAc γ stk e (EVar f, [ex])-  | (EVar dc, es) <- splitEApp ex-  , Just simp <- L.find (\simp -> (smName simp == f) && (smDC simp == dc)) (knSims γ)-  , length (smArgs simp) == length es-  = do let msg    = "evalAppAc:ePop: " ++ showpp (f, dc, es)-       let ePopIf = mytracepp msg $ substPopIf (zip (smArgs simp) es) (smBody simp)-       e'    <- eval γ stk ePopIf-       (e, "Rewrite -" ++ showpp f) ~> e'--evalAppAc γ stk _ (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               -- non-recursive equations << HACK! misses MUTUALLY RECURSIVE definitions!-  , recurCS stk f-  = do env   <- gets (seSort . evEnv)-       let ee = substEq env PopIf eq es bd-       assertSelectors γ ee-       eval γ (pushCS stk f) ee--evalAppAc γ stk _e (EVar f, es)-  | Just eq <- L.find ((== f) . eqName) (knAms γ)-  , Just bd <- getEqBody eq-  , length (eqArgs eq) == length es   -- recursive equations-  , recurCS stk f-  = do env      <- gets (seSort . evEnv)-       mytracepp ("EVAL-REC-APP" ++ showpp (stk, _e))-         <$> evalRecApplication γ (pushCS stk f) (eApps (EVar f) es) (substEq env Normal eq es bd)--evalAppAc _ _ _ (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 :: SEnv Sort -> SubstOp -> Equation -> [Expr] -> Expr -> Expr-substEq env o eq es bd = substEqVal o eq es (substEqCoerce env 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 :: SEnv Sort -> Equation -> [Expr] -> Expr -> Expr-substEqCoerce env eq es bd = Vis.applyCoSub coSub bd-  where-    ts    = snd    <$> eqArgs eq-    sp    = panicSpan "mkCoSub"-    eTs   = sortExpr sp env <$> es-    coSub = mytracepp ("substEqCoerce" ++ showpp (eqName eq, es, eTs, ts)) $ mkCoSub env eTs ts--mkCoSub :: SEnv Sort -> [Sort] -> [Sort] -> Vis.CoSub-mkCoSub env eTs xTs = M.fromList [ (x, unite ys) | (x, ys) <- Misc.groupList xys ]-  where-    unite ts    = mytracepp ("UNITE: " ++ showpp 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         = mytracepp "mkCoSubXXX" $ Misc.sortNub $ concat $ zipWith matchSorts _xTs _eTs-    (_xTs,_eTs) = mytracepp "mkCoSub:MATCH" (xTs, eTs)--matchSorts :: Sort -> Sort -> [(Symbol, Sort)]-matchSorts sort1 sort2 = mytracepp  ("matchSorts :" ++ showpp (sort1, sort2)) $ go sort1 sort2-  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 _             _             = []-----------------------------------------------------------------------------------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 expr' = L.foldl' go expr' 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)---- see [NOTE:Eval-Ite] the below is wrong; we need to guard other branches too. sigh.--evalRecApplication :: Knowledge -> CStack -> Expr -> Expr -> EvalST Expr-evalRecApplication γ stk e (EIte b e1 e2) = do-  contra <- {- mytracepp  ("CONTRA? " ++ showpp e) <$> -} liftIO (isValid γ PFalse)-  if contra-    then return e-    else do b' <- eval γ stk (mytracepp "REC-APP-COND" b) -- <<<<<<<<<<<<<<<<<<<<< MOSSAKA-LOOP?-            b1 <- liftIO (isValid γ b')-            if b1-              then addEquality γ e e1 >>-                   {- SCC "assertSelectors-1" -} assertSelectors γ e1 >>-                   eval γ stk (mytracepp ("evalREC-1: " ++ showpp stk) e1) >>=-                   ((e, "App1: ") ~>)-              else do-                   b2 <- liftIO (isValid γ (PNot b'))-                   if b2-                      then addEquality γ e e2 >>-                           {- SCC "assertSelectors-2" -} assertSelectors γ e2 >>-                           eval γ stk (mytracepp ("evalREC-2: " ++ showpp stk) e2) >>=-                           ((e, "App2: " ++ showpp stk ) ~>)-                      else return e-evalRecApplication _ _ _ e-  = return e--addEquality :: Knowledge -> Expr -> Expr -> EvalST ()-addEquality γ e1 e2 =-  modify (\st -> st{evSequence = (makeLam γ e1, makeLam γ e2):evSequence st})--evalIte :: Knowledge -> CStack -> Expr -> Expr -> Expr -> Expr -> EvalST Expr-evalIte γ stk e b e1 e2 = mytracepp "evalIte:END: " <$>-                            evalIteAc γ stk e b e1 (mytracepp msg e2)-  where-    msg = "evalIte:BEGINS: " ++ showpp (stk, e)---evalIteAc :: Knowledge -> CStack -> Expr -> Expr -> Expr -> Expr -> EvalST Expr-evalIteAc γ stk e b e1 e2-  = join $ evalIte' γ stk e b e1 e2 <$> liftIO (isValid γ b) <*> liftIO (isValid γ (PNot b))--evalIte' :: Knowledge -> CStack -> Expr -> Expr -> Expr -> Expr -> Bool -> Bool -> EvalST Expr-evalIte' γ stk e _ e1 _ b _-  | b-  = do e' <- eval γ stk e1-       (e, "If-True of:" ++ showpp b)  ~> e'-evalIte' γ stk e _ _ e2 _ b'-  | b'-  = do e' <- eval γ stk e2-       (e, "If-False") ~> e'-evalIte' γ stk _ b e1 e2 _ _-  -- see [NOTE:Eval-Ite] #387-  = EIte b <$> eval γ stk' e1 <*> eval γ stk' e2-    where stk' = mytracepp "evalIte'" $ noRecurCS stk------------------------------------------------------------------------------------- | Knowledge (SMT Interaction)----------------------------------------------------------------------------------data Knowledge = KN-  { knSims    :: ![Rewrite]           -- ^ Measure info, asserted for each new Ctor ('assertSelectors')-  , knAms     :: ![Equation]          -- ^ (Recursive) function definitions, used for PLE-  , knContext :: SMT.Context-  , knPreds   :: SMT.Context -> [(Symbol, Sort)] -> Expr -> IO Bool-  , knLams    :: [(Symbol, Sort)]-  }--isValid :: Knowledge -> Expr -> IO Bool-isValid γ e = mytracepp ("isValid: " ++ showpp e) <$>-                knPreds γ (knContext γ) (knLams γ) e--isProof :: (a, SortedReft) -> Bool-isProof (_, RR s _) = showpp s == "Tuple"--knowledge :: Config -> SMT.Context -> AxiomEnv -> Knowledge-knowledge cfg ctx aenv = KN-  { knSims    = aenvSimpl aenv-  , knAms     = aenvEqs   aenv-  , knContext = ctx-  , knPreds   = askSMT    cfg-  , knLams    = []-  }---- | This creates the rewrite rule e1 -> e2, applied when:--- 1. when e2 is a DataCon and can lead to further reductions--- 2. when size e2 < size e1-initEqualities :: SMT.Context -> AxiomEnv -> [(Symbol, SortedReft)] -> [(Expr, Expr)]-initEqualities ctx aenv es = concatMap (makeSimplifications (aenvSimpl aenv)) dcEqs-  where-    dcEqs                  = Misc.setNub (Mb.catMaybes [getDCEquality symEnv' e1 e2 | EEq e1 e2 <- atoms])-    atoms                  = splitPAnd . expr =<< filter isProof es-    symEnv'                = SMT.ctxSymEnv ctx---- AT: Non-obvious needed invariant: askSMT True is always the--- totality-effecting one.--- RJ: What does "totality effecting" mean?--toSMT :: Config -> SMT.Context -> [(Symbol, Sort)] -> Expr -> Pred-toSMT = Common.toSMT "Instantiate.toSMT"--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-     = [(EApp (EVar f) e, subst (mkSubst $ zip xs es) bd)]-   go _-     = []--getDCEquality :: SymEnv -> Expr -> Expr -> Maybe (Symbol, [Expr], Expr)-getDCEquality sEnv e1 e2-  | Just dc1 <- f1-  , Just dc2 <- f2-  = if dc1 == dc2-      then Nothing-      else error ("isDCEquality on" ++ showpp e1 ++ "\n" ++ showpp e2)-  | Just dc1 <- f1-  = Just (dc1, es1, e2)-  | Just dc2 <- f2-  = Just (dc2, es2, e1)-  | otherwise-  = Nothing-  where-    (f1, es1) = first (getDC sEnv) (splitEApp e1)-    (f2, es2) = first (getDC sEnv) (splitEApp e2)---- TODO: Stringy hacks-getDC :: SymEnv -> Expr -> Maybe Symbol-getDC sEnv (EVar x)-  | isUpperSymbol x && Mb.isNothing (symEnvTheory x sEnv)-  = Just x-getDC _ _-  = Nothing--isUpperSymbol :: Symbol -> Bool-isUpperSymbol x = (0 < lengthSym x') && isUpper (headSym x')-  where-    x' = dropModuleNames x--dropModuleNames :: Symbol -> Symbol-dropModuleNames = mungeNames (symbol . last) "."-  where-    mungeNames _ _ ""  = ""-    mungeNames f d s'@(symbolText -> s)-      | isTupleSymbol s' = s'-      | otherwise        = f $ T.splitOn d $ stripParens s-    stripParens t = Mb.fromMaybe t ((T.stripPrefix "(" >=> T.stripSuffix ")") t)--    -- TODO: Remove this code which is LH specific-    isTupleSymbol :: Symbol -> Bool-    isTupleSymbol s =-      let t = symbolText s-       in T.isPrefixOf "Tuple" t &&-          T.all isDigit (T.drop 5 t)------------------------------------------------------------------------------------- | Creating Measure Info------------------------------------------------------------------------------------ AT@TODO do this for all reflected functions, not just DataCons--{- [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 γ expr' = do-    sims <- gets (aenvSimpl . _evAEnv)-    -- cfg  <- gets evCfg-    -- _    <- foldlM (\_ s -> Vis.mapMExpr (go s) e) (mytracepp  "assertSelector" e) sims-    forM_ sims $ \s -> Vis.mapMExpr (go s) expr'-  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------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------withCtx :: Config -> FilePath -> SymEnv -> [Equation] -> (SMT.Context -> IO a) -> IO a-withCtx cfg file env defns k = do-  ctx <- SMT.makeContextWithSEnv cfg file env defns-  _   <- SMT.smtPush ctx-  res <- k ctx-  SMT.cleanupContext ctx-  return res--infixl 9 ~>-(~>) :: (Expr, String) -> Expr -> EvalST Expr-(e, _str) ~> e' = do-  let msg = "PLE: " ++ _str ++ showpp (e, e')-  modify (\st -> st {evId = mytracepp msg (evId st) + 1})-  return e'
src/Language/Fixpoint/Solver/Interpreter.hs view
@@ -57,7 +57,7 @@ -------------------------------------------------------------------------------- -- | Strengthen Constraint Environments via PLE ---------------------------------------------------------------------------------instInterpreter :: (Loc a) => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)+instInterpreter :: (Loc a) => Config -> SInfo a -> Maybe [SubcId] -> IO (BindEnv a) instInterpreter cfg fi' subcIds = do     let cs = M.filterWithKey                (\i c -> isPleCstr aEnv i c && maybe True (i `L.elem`) subcIds)@@ -178,11 +178,11 @@ -- | Step 3: @resSInfo@ uses incremental PLE result @InstRes@ to produce the strengthened SInfo ---------------------------------------------------------------------------------------------- -resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> SInfo a+resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> BindEnv a resSInfo cfg env info res = strengthenBinds info res'   where     res'     = M.fromList $ zip is ps''-    ps''     = zipWith (\i -> elaborate (ElabParam (solverFlags $ solver cfg) (atLoc dummySpan ("PLE1 " ++ show i)) env)) is ps'+    ps''     = zipWith (\i -> elaborate (ElabParam (solverFlags cfg) (atLoc dummySpan ("PLE1 " ++ show i)) env)) is ps'     ps'      = defuncAny cfg env ps     (is, ps) = unzip (M.toList res) @@ -358,6 +358,7 @@       EIte b _ _ -> go b $ e0 : acc       ECoerc _ _ e -> go e acc       ECst e _ -> go e acc+      ELet{} -> acc       ESym _ -> acc       ECon _ -> acc       EVar _ -> acc@@ -367,7 +368,6 @@       PKVar _ _ -> acc       PAll _ _ -> acc       PExist _ _ -> acc-      PGrad{} -> acc  largestApps :: Expr -> [Expr] largestApps = flip go []@@ -388,13 +388,13 @@       ESym _ -> acc       ECon _ -> acc       EVar _ -> e0 : acc+      ELet{} -> acc       ELam _ _ -> acc       ETApp _ _ -> acc       ETAbs _ _ -> acc       PKVar _ _ -> acc       PAll _ _ -> acc       PExist _ _ -> acc-      PGrad{} -> acc  fastEval :: ConstMap -> Knowledge -> ICtx -> Expr -> EvalST Expr fastEval ienv γ ctx e@@ -554,9 +554,11 @@ interpret ie γ ctx env e@(PExist xss e1) = case xss of   [] -> interpret' ie γ ctx env e1   _  -> e-interpret _  _ _   _   e@PGrad{}         = e interpret ie γ ctx env (ECoerc s t e)    = let e' = interpret' ie γ ctx env e in                                              if s == t then e' else ECoerc s t e'+interpret ie γ ctx env (ELet x e1 e2)    = let e1' = interpret' ie γ ctx env e1+                                               e2' = interpret' ie γ ctx env e2 in+                                             ELet x e1' e2'   --------------------------------------------------------------------------------
src/Language/Fixpoint/Solver/Monad.hs view
@@ -5,19 +5,16 @@ module Language.Fixpoint.Solver.Monad        ( -- * Type          SolveM+       , liftSMT           -- * Execution        , runSolverM -         -- * Get Binds-       , getBinds        , getContext           -- * SMT Query        , filterRequired        , filterValid-       , filterValidGradual-       , checkSat        , smtEnablembqi        , sendConcreteBindingsToSMT @@ -27,10 +24,12 @@        , stats        , numIter        , SolverState(..)++       , modifyContext        )        where -import           Control.Monad (foldM, forM, forM_, when)+import           Control.Monad (forM, forM_, when) import           Language.Fixpoint.Utils.Progress import qualified Language.Fixpoint.Types.Config  as C import           Language.Fixpoint.Types.Config  (Config)@@ -43,18 +42,20 @@ import           Language.Fixpoint.Smt.Serialize () import           Language.Fixpoint.Types.PrettyPrint () import           Language.Fixpoint.Smt.Interface+import           Language.Fixpoint.Smt.Types (SmtM) -- import qualified Language.Fixpoint.Smt.Theories as Thy import           Language.Fixpoint.Solver.Sanitize import           Language.Fixpoint.Solver.Stats import           Language.Fixpoint.Graph.Types (SolverInfo (..)) -- import           Language.Fixpoint.Solver.Solution -- import           Data.Maybe           (catMaybes)-import           Data.List            (partition) -- import           Data.Char            (isUpper)+import qualified Control.Monad.State as ST import           Control.Monad.State.Strict import qualified Data.HashMap.Strict as M import           Data.Maybe (catMaybes) import           Control.Exception.Base (bracket)+import Language.Fixpoint.SortCheck (ElabParam)  -------------------------------------------------------------------------------- -- | Solver Monadic API --------------------------------------------------------@@ -64,8 +65,8 @@  data SolverState ann = SS   { ssCtx     :: !Context         -- ^ SMT Solver Context-  , ssBinds   :: !(F.BindEnv ann) -- ^ All variables and types   , ssStats   :: !Stats           -- ^ Solver Statistics+  , ssElabParam :: !ElabParam      -- ^ Elaboration Parameters   }  stats0    :: F.GInfo c b -> Stats@@ -74,31 +75,24 @@     nCs   = M.size $ F.cm fi  ---------------------------------------------------------------------------------runSolverM :: Config -> SolverInfo ann c -> SolveM ann a -> IO a+runSolverM :: Config -> SolverInfo ann -> ElabParam -> SolveM ann a -> IO a ---------------------------------------------------------------------------------runSolverM cfg sI act =+runSolverM cfg sI elabParam act =   bracket acquire release $ \ctx -> do     res <- runStateT act' (s0 ctx)     return (fst res)   where-    s0 ctx   = SS ctx be (stats0 fi)+    s0 ctx   = SS ctx (stats0 fi) elabParam     act'     = assumesAxioms (F.asserts fi) >> act     release  = cleanupContext     acquire  = makeContextWithSEnv cfg file initEnv (F.defns fi)     initEnv  = symbolEnv cfg fi-    be       = F.bs fi     file     = C.srcFile cfg     -- only linear arithmetic when: linear flag is on or solver /= Z3     -- lar     = linear cfg || Z3 /= solver cfg     fi       = (siQuery sI) {F.hoInfo = F.cfgHoInfo cfg } - ---------------------------------------------------------------------------------getBinds :: SolveM ann (F.BindEnv ann)----------------------------------------------------------------------------------getBinds = ssBinds <$> get---------------------------------------------------------------------------------- getIter :: SolveM ann Int -------------------------------------------------------------------------------- getIter = numIter . ssStats <$> get@@ -115,8 +109,13 @@ incChck n = modifyStats $ \s -> s {numChck = n + numChck s} incVald n = modifyStats $ \s -> s {numVald = n + numVald s} -withContext :: (Context -> IO a) -> SolveM ann a-withContext k = (lift . k) =<< getContext+liftSMT :: SmtM a -> SolveM ann a+liftSMT k =+  do es <- get+     let ctx = ssCtx es+     (a, ctx') <- lift $ ST.runStateT k ctx+     put (es {ssCtx = ctx'})+     pure a  getContext :: SolveM ann Context getContext = ssCtx <$> get@@ -124,6 +123,9 @@ modifyStats :: (Stats -> Stats) -> SolveM ann () modifyStats f = modify $ \s -> s { ssStats = f (ssStats s) } +modifyContext :: (Context -> Context) -> SolveM ann ()+modifyContext f = modify $ \s -> s { ssCtx = f (ssCtx s) }+ -------------------------------------------------------------------------------- -- | SMT Interface ------------------------------------------------------------- --------------------------------------------------------------------------------@@ -133,9 +135,8 @@ -- -- Yields the ids of bindings known to the SMT sendConcreteBindingsToSMT-  :: F.IBindEnv -> (F.IBindEnv -> SolveM ann a) -> SolveM ann a-sendConcreteBindingsToSMT known act = do-  be <- getBinds+  :: F.IBindEnv -> F.BindEnv ann -> (F.IBindEnv -> SolveM ann a) -> SolveM ann a+sendConcreteBindingsToSMT known be act = do   let concretePreds =         [ (i, F.subst1 p (v, F.EVar s))         | (i, (s, F.RR _ (F.Reft (v, p)),_)) <- F.bindEnvToList be@@ -144,12 +145,16 @@         , not (F.memberIBindEnv i known)         ]   st <- get-  (a, st') <- withContext $ \me -> do-    smtBracket me "" $ do+  (a, st'') <- liftSMT $+    smtBracket "sendConcreteBindingsToSMT" $ do       forM_ concretePreds $ \(i, e) ->-        smtDefineFunc me (F.bindSymbol (fromIntegral i)) [] F.boolSort e-      flip runStateT st $ act $ F.unionIBindEnv known $ F.fromListIBindEnv $ map fst concretePreds-  put st'+        smtDefineFunc (F.bindSymbol (fromIntegral i)) [] F.boolSort e+      ctx <- get+      let st' = st { ssCtx = ctx }+      (a, st'') <- liftIO $ flip runStateT st' $ act $ F.unionIBindEnv known $ F.fromListIBindEnv $ map fst concretePreds+      put (ssCtx st'')+      return (a, st'')+  modify $ \st''' -> st'' { ssCtx = ssCtx st''' }   return a   where     isShortExpr F.PTrue = True@@ -170,9 +175,9 @@ filterValid :: F.SrcSpan -> F.Expr -> F.Cand a -> SolveM ann [a] -------------------------------------------------------------------------------- filterValid sp p qs = do-  qs' <- withContext $ \me ->-           smtBracket me "filterValidLHS" $-             filterValid_ sp p qs me+  qs' <- liftSMT $+           smtBracket "filterValidLHS" $+             filterValid_ sp p qs   -- stats   incBrkt   incChck (length qs)@@ -180,66 +185,23 @@   return qs'  {-# SCC filterValid_ #-}-filterValid_ :: F.SrcSpan -> F.Expr -> F.Cand a -> Context -> IO [a]-filterValid_ sp p qs me = catMaybes <$> do-  smtAssert me p+filterValid_ :: F.SrcSpan -> F.Expr -> F.Cand a -> SmtM [a]+filterValid_ sp p qs = catMaybes <$> do+  smtAssertDecl p   forM qs $ \(q, x) ->-    smtBracketAt sp me "filterValidRHS" $ do-      smtAssert me (F.PNot q)-      valid <- smtCheckUnsat me+    smtBracketAt sp "filterValidRHS" $ do+      smtAssertDecl (F.PNot q)+      valid <- smtCheckUnsat       return $ if valid then Just x else Nothing ------------------------------------------------------------------------------------ | `filterValidGradual ps [(x1, q1),...,(xn, qn)]` returns the list `[ xi | p => qi]`--- | for some p in the list ps----------------------------------------------------------------------------------filterValidGradual :: [F.Expr] -> F.Cand a -> SolveM ann [a]----------------------------------------------------------------------------------filterValidGradual p qs = do-  qs' <- withContext $ \me ->-           smtBracket me "filterValidGradualLHS" $-             filterValidGradual_ p qs me-  -- stats-  incBrkt-  incChck (length qs)-  incVald (length qs')-  return qs'--filterValidGradual_ :: [F.Expr] -> F.Cand a -> Context -> IO [a]-filterValidGradual_ ps qs me-  = map snd . fst <$> foldM partitionCandidates ([], qs) ps-  where-    partitionCandidates :: (F.Cand a, F.Cand a) -> F.Expr -> IO (F.Cand a, F.Cand a)-    partitionCandidates (ok, candidates) p = do-      (valids', invalids')  <- partition snd <$> filterValidOne_ p candidates me-      let (valids, invalids) = (fst <$> valids', fst <$> invalids')-      return (ok ++ valids, invalids)--filterValidOne_ :: F.Expr -> F.Cand a -> Context -> IO [((F.Expr, a), Bool)]-filterValidOne_ p qs me = do-  smtAssert me p-  forM qs $ \(q, x) ->-    smtBracket me "filterValidRHS" $ do-      smtAssert me (F.PNot q)-      valid <- smtCheckUnsat me-      return ((q, x), valid)- smtEnablembqi :: SolveM ann () smtEnablembqi-  = withContext smtSetMbqi-----------------------------------------------------------------------------------checkSat :: F.Expr -> SolveM ann Bool----------------------------------------------------------------------------------checkSat p-  = withContext $ \me ->-      smtBracket me "checkSat" $-        smtCheckSat me p+  = liftSMT smtSetMbqi  -------------------------------------------------------------------------------- assumesAxioms :: [F.Triggered F.Expr] -> SolveM ann () ---------------------------------------------------------------------------------assumesAxioms es = withContext $ \me -> forM_  es $ smtAssertAxiom me+assumesAxioms es = liftSMT $ forM_ es smtAssertAxiom   ---------------------------------------------------------------------------
src/Language/Fixpoint/Solver/PLE.hs view
@@ -8,6 +8,7 @@ --     2. "Reasoning about Functions", VMCAI 2018, https://ranjitjhala.github.io/static/reasoning-about-functions.pdf -------------------------------------------------------------------------------- +{-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE PartialTypeSignatures     #-} {-# LANGUAGE TupleSections             #-}@@ -30,10 +31,11 @@  import           Language.Fixpoint.Types hiding (simplify) import           Language.Fixpoint.Types.Config  as FC-import           Language.Fixpoint.Types.Solutions (CMap)+import           Language.Fixpoint.Types.Solutions (CMap, Solution) import qualified Language.Fixpoint.Types.Visitor as Vis import qualified Language.Fixpoint.Misc          as Misc import qualified Language.Fixpoint.Smt.Interface as SMT+import           Language.Fixpoint.Smt.Types (SmtM) import           Language.Fixpoint.Defunctionalize import           Language.Fixpoint.Solver.EnvironmentReduction (inlineInExpr, undoANF) import qualified Language.Fixpoint.Utils.Files   as Files@@ -44,6 +46,7 @@ import           Language.Fixpoint.Solver.Common          (askSMT, toSMT) import           Language.Fixpoint.Solver.Sanitize        (symbolEnv) import           Language.Fixpoint.Solver.Simplify+import           Language.Fixpoint.Solver.Solution (CombinedEnv(..), applyInSortedReft) import           Language.Fixpoint.Solver.Rewrite as Rewrite  import Language.REST.OCAlgebra as OC@@ -51,7 +54,7 @@ import Language.REST.RuntimeTerm as RT import Language.REST.SMT (withZ3, SolverHandle) -import           Control.Monad (filterM, foldM, forM_, when, replicateM)+import           Control.Monad (filterM, foldM, forM_, when, replicateM, zipWithM) import           Control.Monad.State import           Control.Monad.Trans.Maybe import           Data.Bifunctor (second)@@ -71,26 +74,31 @@  -------------------------------------------------------------------------------- -- | Strengthen Constraint Environments via PLE---------------------------------------------------------------------------------+--+-- @instantiate cfg fi subcIds@ yields @F.bs fi@ strengthened with the+-- unfoldings discovered by PLE on the constraints in @subcIds@ (or all+-- constraints if @subcIds == Nothing@). {-# SCC instantiate #-}-instantiate :: (Loc a) => Config -> SInfo a -> Maybe [SubcId] -> IO (SInfo a)-instantiate cfg fi' subcIds = do+instantiate :: (Loc a) => Config -> SInfo a -> Maybe Solution -> Maybe [SubcId] -> SmtM (BindEnv a)+instantiate cfg fi' mSol subcIds = do     let cs = M.filterWithKey                (\i c -> isPleCstr aEnv i c && maybe True (i `L.elem`) subcIds)                (cm info)     let t  = mkCTrie (M.toList cs)                                          -- 1. BUILD the Trie-    res   <- withRESTSolver $ \solver -> withProgress (1 + M.size cs) $-               withCtx cfg file sEnv (defns fi') $ \ctx -> do-                  env <- instEnv cfg info cs solver ctx-                  pleTrie t env                                             -- 2. TRAVERSE Trie to compute InstRes-    savePLEEqualities cfg info sEnv res+    res   <- withRESTSolver $ \solver -> do+               ctx <- get+               (res, ctx') <- liftIO $ withProgressM (`runStateT` ctx) (1 + M.size cs) $ do+                 env <- instEnv cfg info mSol cs solver+                 pleTrie t env                                              -- 2. TRAVERSE Trie to compute InstRes+               put ctx'+               return res+    liftIO $ 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 :: (Maybe SolverHandle -> SmtM a) -> SmtM a     withRESTSolver f | all null (M.elems $ aenvAutoRW aEnv) = f Nothing     withRESTSolver f = withZ3 (f . Just) -    file = srcFile cfg ++ ".evals"     sEnv = symbolEnv cfg info     aEnv = ae info     info = normalize fi'@@ -107,7 +115,7 @@   where     equalitiesPerConstraint (cid, c) =       (cid, L.sort [ e | i <- elemsIBindEnv (senv c), Just e <- [M.lookup i res] ])-    elabParam = ElabParam (solverFlags $ solver cfg) "savePLEEqualities" sEnv+    elabParam = ElabParam (solverFlags cfg) "savePLEEqualities" sEnv     renderConstraintRewrite (cid, eqs) =       "constraint id" <+> text (show cid ++ ":")       $+$ nest 2@@ -122,10 +130,18 @@  ------------------------------------------------------------------------------- -- | 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 info cs restSolver ctx = do-    refRESTCache <- newIORef mempty-    refRESTSatCache <- newIORef mempty+instEnv+  :: Loc a+  => Config+  -> SInfo a+  -> Maybe Solution+  -> CMap (SimpC a)+  -> Maybe SolverHandle+  -> SmtM (InstEnv a)+instEnv cfg info s cs restSolver = do+    ctx <- get+    refRESTCache <- liftIO $ newIORef mempty+    refRESTSatCache <- liftIO $ newIORef mempty     let         restOrd = FC.restOC cfg         oc0 = ordConstraints restOrd $ Mb.fromJust restSolver@@ -145,6 +161,8 @@         s0 = EvalEnv               { evEnv = SMT.ctxSymEnv ctx               , evElabF = ef+              , evKCtx = ctx+              , evExScope = []               , evPendingUnfoldings = mempty               , evNewEqualities = mempty               , evSMTCache = mempty@@ -157,16 +175,16 @@               }     return $ InstEnv        { ieCfg = cfg-       , ieSMT = ctx-       , ieBEnv = coerceBindEnv ef (bs info)+       , ieBEnv = bs info        , ieAenv = ae info        , ieCstrs = cs-       , ieKnowl = knowledge cfg ctx info+       , ieKnowl = knowledge cfg info        , ieEvEnv = s0        , ieLRWs  = lrws info+       , ieSol  = s        }   where-    ef = solverFlags $ solver cfg+    ef = solverFlags cfg      cachedNotStrongerThan refRESTCache oc a b = do       m <- readIORef refRESTCache@@ -212,7 +230,7 @@  ---------------------------------------------------------------------------------------------- -- | Step 2: @pleTrie@ walks over the @CTrie@ to actually do the incremental-PLE-pleTrie :: CTrie -> InstEnv a -> IO InstRes+pleTrie :: Loc a => CTrie -> InstEnv a -> SmtM InstRes pleTrie t env = loopT env ctx0 diff0 Nothing res0 t   where     diff0        = []@@ -225,42 +243,54 @@       , icSubcId             = Nothing       , icANFs               = []       , icLRWs               = mempty+      , icBindIds            = mempty       , icEtaBetaFlag        = etabeta        $ ieCfg env       , icExtensionalityFlag = extensionality $ ieCfg env       , icLocalRewritesFlag  = localRewrites  $ ieCfg env+      , icFreshExistentialCounter = 0+      , icInitialLHSs  = mempty       }  loopT-  :: InstEnv a+  :: Loc a+  => InstEnv a   -> ICtx   -> Diff         -- ^ The longest path suffix without forks in reverse order   -> Maybe BindId -- ^ bind id of the branch ancestor of the trie if any.                   --   'Nothing' when this is the top-level trie.   -> InstRes   -> CTrie-  -> IO InstRes-loopT env ctx delta i res t = case t of+  -> SmtM InstRes+loopT env ictx delta i res t = case t of   T.Node []  -> return res-  T.Node [b] -> loopB env ctx delta i res b-  T.Node bs  -> withAssms env ctx delta Nothing $ \ctx' -> do-                  (ctx'', env'', res') <- ple1 env ctx' i res-                  foldM (loopB env'' ctx'' [] i) res' bs+  T.Node [b] -> loopB env ictx delta i res b+  T.Node bs  -> withAssms env ictx delta Nothing (Just t) $ \ictx' -> do+                  (ictx'', env'', res') <- ple1 env ictx' i res+                  foldM (loopB env'' ictx'' [] i) res' bs  loopB-  :: InstEnv a+  :: Loc a+  => InstEnv a   -> ICtx   -> Diff         -- ^ The longest path suffix without forks in reverse order   -> Maybe BindId -- ^ bind id of the branch ancestor of the branch if any.                   --   'Nothing' when this is a branch of the top-level trie.   -> InstRes   -> CBranch-  -> IO InstRes-loopB env ctx delta iMb res b = case b of-  T.Bind i t -> loopT env ctx (i:delta) (Just i) res t-  T.Val cid  -> withAssms env ctx delta (Just cid) $ \ctx' -> do-                  progressTick-                  (\(_, _, r) -> r) <$> ple1 env ctx' iMb res+  -> SmtM InstRes+loopB env ictx delta iMb res b = case b of+  T.Bind i t -> loopT env ictx (i:delta) (Just i) res t+  T.Val cid  -> withAssms env ictx delta (Just cid) Nothing $ \ictx' -> do+                  liftIO progressTick+                  (\(_, _, r) -> r) <$> ple1 env ictx' iMb res +collectConstraints :: CTrie -> [SubcId]+collectConstraints = go+  where+    go (T.Node bs) = concatMap goB bs+    goB (T.Bind _ t) = go t+    goB (T.Val cid)  = [cid]+ -- | Adds to @ctx@ candidate expressions to unfold from the bindings in @delta@ -- and the rhs of @cidMb@. --@@ -271,35 +301,59 @@ -- Pushes assumptions from the modified context to the SMT solver, runs @act@, -- and then pops the assumptions. ---withAssms :: InstEnv a -> ICtx -> Diff -> Maybe SubcId -> (ICtx -> IO b) -> IO b-withAssms env@InstEnv{..} ctx delta cidMb act = do-  let ctx' = updCtx env ctx delta cidMb-  let assms = icAssms ctx'+withAssms+  :: Loc a+  => InstEnv a+  -> ICtx+  -> Diff+  -> Maybe SubcId+  -> Maybe CTrie+  -> (ICtx -> SmtM b)+  -> SmtM b+withAssms env ctx delta cidMb mCTrie act = do+  sctx <- get+  let cfg = SMT.config sctx+  let (ictx', bs) = updCtx cfg env sctx ctx delta cidMb mCTrie+  let assms = icAssms ictx' -  SMT.smtBracket ieSMT "PLE.evaluate" $ do-    forM_ assms (SMT.smtAssert ieSMT)-    act ctx' { icAssms = mempty }+  SMT.smtBracket "PLE.withAssms" $ do+    -- See Note [Existential quantification when unfolding]+    SMT.smtDecls $ elabBindings (ieEvEnv env) bs+    forM_ (S.toList assms) SMT.smtAssertDecl+    act $ ictx' { icAssms = mempty } +  where+    elabBindings eenv bs =+      elaborate (ElabParam (evElabF eenv) "withAssms: PExist Args" (evEnv eenv)) bs+ -- | @ple1@ performs the PLE at a single "node" in the Trie -- -- It will generate equalities for all function invocations in the candidates -- in @ctx@ for which definitions are known. The function definitions are in -- @ieKnowl@.-ple1 :: InstEnv a -> ICtx -> Maybe BindId -> InstRes -> IO (ICtx, InstEnv a, InstRes)-ple1 ie@InstEnv{..} ctx i res = do-  (ctx', env) <- runStateT (evalCandsLoop ieCfg ctx ieSMT ieKnowl) ieEvEnv-  let pendings = collectPendingUnfoldings env (icSubcId ctx)-      newEqs = pendings ++ S.toList (S.difference (icEquals ctx') (icEquals ctx))-  return (ctx', ie { ieEvEnv = env }, updCtxRes res i newEqs)+ple1 :: InstEnv a -> ICtx -> Maybe BindId -> InstRes -> SmtM (ICtx, InstEnv a, InstRes)+ple1 ie@InstEnv{..} ictx i res = do+  ctx <- get+  (ictx', env) <- liftIO $ runStateT (evalCandsLoop ieCfg ictx ieKnowl) (ieEvEnv { evKCtx = ctx })+  put $ evKCtx env+  let pendings = collectPendingUnfoldings env (icSubcId ictx)+      newEqs =+        reconstructExistentials+          (M.intersectionWith S.union (icInitialLHSs ictx) $         -- add original predicates+           M.map (S.map equalitiesPred) $                            -- construct equalities+           M.unionWith S.union pendings $                            -- pending unfoldings if any+           M.unionWith S.difference (icEquals ictx') (icEquals ictx) -- new equalities only+          )+  return (ictx', ie { ieEvEnv = env }, updCtxRes res i newEqs)   where     -- Pending unfoldings (i.e. with undecided guards) are collected only     -- when we reach a leaf in the Trie, and only if the user asked for them.-    collectPendingUnfoldings env (Just _) | pleWithUndecidedGuards ieCfg =-      M.toList (evPendingUnfoldings env)-    collectPendingUnfoldings _ _ = []+    collectPendingUnfoldings env (Just _) | pleUndecGuards ieCfg =+      M.map (S.fromList . M.toList) (evPendingUnfoldings env)+    collectPendingUnfoldings _ _ = mempty -evalToSMT :: String -> Config -> SMT.Context -> (Expr, Expr) -> Pred-evalToSMT msg cfg ctx (e1,e2) = toSMT ("evalToSMT:" ++ msg) cfg ctx [] (EEq e1 e2)+evalToSMT :: String -> Config -> SMT.Context -> [(Symbol, Sort)] -> (Expr, Expr) -> Pred+evalToSMT msg cfg ctx bs (e1,e2) = toSMT ("evalToSMT:" ++ msg) cfg ctx bs (EEq e1 e2)  -- | Generate equalities for all function invocations in the candidates -- in @ctx@ for which definitions are known. The function definitions are in@@ -316,44 +370,72 @@ -- > until no new equalities are discovered -- >       or the environment becomes inconsistent ---evalCandsLoop :: Config -> ICtx -> SMT.Context -> Knowledge -> EvalST ICtx-evalCandsLoop cfg ictx0 ctx γ = go ictx0 0+evalCandsLoop :: Config -> ICtx -> Knowledge -> EvalST ICtx+evalCandsLoop cfg ictx0 γ = go ictx0 0   where-    go ictx _ | S.null (icCands ictx) = return ictx+    go :: ICtx -> Int -> EvalST ICtx+    go ictx _ | all null (icCands ictx) = return ictx     go ictx i = do       inconsistentEnv <- testForInconsistentEnvironment       if inconsistentEnv         then return ictx-        else do liftIO $ SMT.smtAssert ctx (pAndNoDedup (S.toList $ icAssms ictx))+        else do liftSMT $ SMT.smtAssertDecl $ pAndNoDedup $ S.toList $ icAssms ictx                 let ictx' = ictx { icAssms = mempty }-                    cands = S.toList $ icCands ictx-                candss <- mapM (evalOne γ ictx' i) cands-                us <- gets evNewEqualities-                modify $ \st -> st { evNewEqualities = mempty }-                let noCandidateChanged = and (zipWith eqCand candss cands)-                    unknownEqs = us `S.difference` icEquals ictx-                if S.null unknownEqs && noCandidateChanged-                      then return ictx-                      else do let eqsSMT = evalToSMT "evalCandsLoop" cfg ctx `S.map` unknownEqs-                              let ictx'' = ictx' { icEquals = icEquals ictx <> unknownEqs-                                                 , icAssms  = S.filter (not . isTautoPred) eqsSMT }-                              go (ictx'' { icCands = S.fromList (concat candss) }) (i + 1)+                    (scopes, candSets) = unzip $ M.toList $ icCands ictx+                    cands = map S.toList candSets+                (candss, uss) <- unzip <$> zipWithM (evalCand ictx' i) scopes cands+                let noCandidateChanged = all and $ zipWith (zipWith eqCand) candss cands+                    unknownEqs = M.unionWith S.difference (M.fromList (zip scopes uss)) (icEquals ictx)+                if all null unknownEqs && noCandidateChanged then+                  return ictx+                else do+                  ctx' <- gets evKCtx+                  let eqsSMT =+                        S.unions $ M.elems $+                          M.mapWithKey+                            (\scope -> S.map $ evalToSMT "evalCandsLoop" cfg ctx' scope)+                            unknownEqs+                      ictx'' = ictx+                        { icEquals = M.unionWith S.union (icEquals ictx) unknownEqs+                        , icAssms  = S.filter (not . isTautoPred) eqsSMT+                        }+                  go (ictx'' { icCands = M.fromList $ zip scopes (map (S.fromList . concat) candss) }) (i + 1) +    testForInconsistentEnvironment :: EvalST Bool     testForInconsistentEnvironment =-      liftIO $ knPreds γ (knContext γ) (knLams γ) PFalse+      knPredsEvalST γ PFalse      eqCand [e0] e1 = e0 == e1     eqCand _ _ = False +    evalCand :: ICtx -> Int -> ExScope -> [Expr] -> EvalST ([[Expr]], S.HashSet (Expr, Expr))+    evalCand ictx i scope es = withExScope scope $ mapM (evalOne γ ictx i) es >>= collectEqs++    collectEqs :: [[Expr]] -> EvalST ([[Expr]], S.HashSet (Expr, Expr))+    collectEqs es = do+      env <- get+      let newEqs = evNewEqualities env+      modify $ \st -> st { evNewEqualities = mempty }+      return (es, newEqs)++    withExScope :: ExScope -> EvalST a -> EvalST a+    withExScope s m = do+      env <- get+      put $ env { evExScope = s }+      r <- m+      modify $ \st -> st { evExScope = evExScope env }+      return r++ ---------------------------------------------------------------------------------------------- -- | Step 3: @resSInfo@ uses incremental PLE result @InstRes@ to produce the strengthened SInfo ---------------------------------------------------------------------------------------------- -resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> SInfo a+resSInfo :: Config -> SymEnv -> SInfo a -> InstRes -> BindEnv a resSInfo cfg env info res = strengthenBinds info res'   where     res'     = M.fromList $ zip is ps''-    ps''     = zipWith (\i -> elaborate (ElabParam (solverFlags $ solver cfg) (atLoc dummySpan ("PLE1 " ++ show i)) env)) is ps'+    ps''     = zipWith (\i -> elaborate (ElabParam (solverFlags cfg) (atLoc dummySpan ("PLE1 " ++ show i)) env)) is ps'     ps'      = defuncAny cfg env ps     (is, ps) = unzip (M.toList res) @@ -363,13 +445,13 @@  data InstEnv a = InstEnv   { ieCfg   :: !Config-  , ieSMT   :: !SMT.Context   , ieBEnv  :: !(BindEnv a)   , ieAenv  :: !AxiomEnv   , ieCstrs :: !(CMap (SimpC a))   , ieKnowl :: !Knowledge   , ieEvEnv :: !EvalEnv   , ieLRWs  :: LocalRewritesEnv+  , ieSol :: Maybe Solution   }  ----------------------------------------------------------------------------------------------@@ -378,18 +460,22 @@  data ICtx    = ICtx   { icAssms              :: S.HashSet Pred           -- ^ Equalities converted to SMT format-  , icCands              :: S.HashSet Expr           -- ^ "Candidates" for unfolding-  , icEquals             :: EvEqualities             -- ^ Accumulated equalities+  , icCands              :: M.HashMap ExScope (S.HashSet Expr)  -- ^ "Candidates" for unfolding+  , icEquals             :: M.HashMap ExScope EvEqualities      -- ^ Accumulated equalities   , icSimpl              :: !ConstMap                -- ^ Map of expressions to constants   , icSubcId             :: Maybe SubcId             -- ^ Current subconstraint ID   , icANFs               :: [[(Symbol, SortedReft)]] -- Hopefully contain only ANF things   , icLRWs               :: LocalRewrites            -- ^ Local rewrites+  , icBindIds            :: IBindEnv                 -- ^ Bind Ids in the current context   , icEtaBetaFlag        :: Bool                     -- ^ True if the etabeta flag is turned on, needed                                                      -- for the eta expansion reasoning as its going to                                                      -- generate ho constraints                                                      -- See Note [Eta expansion].   , icExtensionalityFlag :: Bool                     -- ^ True if the extensionality flag is turned on   , icLocalRewritesFlag  :: Bool                     -- ^ True if the local rewrites flag is turned on+  , icFreshExistentialCounter :: Int                 -- ^ Counter to generate fresh names for existentials+  , icInitialLHSs :: M.HashMap ExScope (S.HashSet Expr)+                                                     -- ^ LHS candidates before any unfoldings   }  ----------------------------------------------------------------------------------------------@@ -408,11 +494,13 @@ type CBranch = T.Branch SubcId type Diff    = [BindId]    -- ^ in "reverse" order -equalitiesPred :: [(Expr, Expr)] -> [Expr]-equalitiesPred eqs = [ EEq e1 e2 | (e1, e2) <- eqs, e1 /= e2 ]+equalitiesPred :: (Expr, Expr) -> Expr+equalitiesPred (e1, e2)+  | e1 /= e2 = EEq e1 e2+  | otherwise = PTrue -updCtxRes :: InstRes -> Maybe BindId -> [(Expr, Expr)] -> InstRes-updCtxRes res iMb = updRes res iMb . pAndNoDedup . equalitiesPred+updCtxRes :: InstRes -> Maybe BindId -> [Expr] -> InstRes+updCtxRes res iMb = updRes res iMb . pAndNoDedup   updRes :: InstRes -> Maybe BindId -> Expr -> InstRes@@ -422,41 +510,91 @@ ---------------------------------------------------------------------------------------------- -- | @updCtx env ctx delta cidMb@ adds the assumptions and candidates from @delta@ and @cidMb@ --   to the context.+--+-- Yields the new context and a list of existential binders found in @delta@.+-- See Note [Existential quantification when unfolding]. ---------------------------------------------------------------------------------------------- -updCtx :: InstEnv a -> ICtx -> Diff -> Maybe SubcId -> ICtx-updCtx InstEnv{..} ctx delta cidMb-            = ctx { icAssms  = S.fromList (filter (not . isTautoPred) ctxEqs)-                  , icCands  = S.fromList deANFedCands <> icCands  ctx-                  , icSimpl  = icSimpl ctx <> econsts-                  , icSubcId = cidMb-                  , icANFs   = anfBinds-                  , icLRWs   = mconcat $ icLRWs ctx : newLRWs-                  }+updCtx+  :: Loc a+  => Config+  -> InstEnv a+  -> SMT.Context+  -> ICtx+  -> Diff+  -> Maybe SubcId+  -> Maybe CTrie+  -> (ICtx, [(Symbol, Sort)])+updCtx cfg InstEnv{..} ieSMT ictx delta cidMb mCTrie =+    ( ictx { icAssms  = S.fromList ctxEqs+           , icCands  = M.unionWith S.union candsPerExScope (icCands ictx)+           , icSimpl  = icSimpl ictx <> econsts+           , icSubcId = cidMb+           , icANFs   = anfBinds+           , icLRWs   = mconcat $ icLRWs ictx : newLRWs+           , icBindIds = ibinds+           , icFreshExistentialCounter = existentialCounter+           , icInitialLHSs = M.unionWith S.union candsPerExScopeNoRHS (icInitialLHSs ictx)+           }+    , ebs+    )   where+    ebs = concat (M.keys candsPerExScope)+    ibinds = insertsIBindEnv delta (icBindIds ictx)     cands     = rhs:es-    anfBinds  = bs : icANFs ctx+    anfBinds  = bs : icANFs ictx     econsts   = M.fromList $ findConstants ieKnowl es-    ctxEqs    = toSMT "updCtx" ieCfg ieSMT [] <$> L.nub-                  [ c | xr <- bs, c <- conjuncts (expr xr), null (Vis.kvarsExpr c) ]+    ctxEqs    = toSMT "updCtx" ieCfg ieSMT ebs <$> L.nub+                  [ c+                  | (_, s) <- drop 1 deANFedCands+                  , e <- S.toList s+                  , c <- conjuncts e+                  , not (isTautoPred c)+                  ]     bs        = second unApplySortedReft <$> binds     rhs       = unApply eRhs     es        = expr <$> bs     eRhs      = maybe PTrue crhs subMb-    binds     = [ (x, y) | i <- delta, let (x, y, _) = lookupBindEnv i ieBEnv]++    (binds, existentialCounter) = renameExistentialsInSortedRefts binds0 (icFreshExistentialCounter ictx)++    binds0    = [ maybeApplyKVarSolutions (x, y)+                | i <- delta+                , let (x, y, _) = lookupBindEnv i ieBEnv+                ]     subMb     = getCstr ieCstrs <$> cidMb     newLRWs   = Mb.mapMaybe (`lookupLocalRewrites` ieLRWs) delta -    deANFedCands =+    candsPerExScopeNoRHS = M.fromListWith S.union $ ([], S.empty) : drop 1 deANFedCands+    -- ebs expects all keys to contain disjoint sets of bindings+    candsPerExScope = M.unionWith S.union candsPerExScopeNoRHS $ M.fromListWith S.union (take 1 deANFedCands)++    deANFedCands = map (second S.singleton . prenexExistentials) $       -- We only call 'deANF' if necessary.       if not (null (getAutoRws ieKnowl cidMb))-         || icExtensionalityFlag ctx-         || icEtaBetaFlag ctx then+         || icExtensionalityFlag ictx+         || icEtaBetaFlag ictx then         deANF anfBinds cands       else         cands +    maybeApplyKVarSolutions xsr =+      case ieSol of+        Just sol -> applyInSortedReft cfg g sol xsr+        Nothing  -> xsr+      where+        gCid = case collectConstraints <$> mCTrie of+          Just (c:_) -> Just c+          _ -> Nothing+        g = CEnv+          { ceCid = gCid+          , ceBEnv = ieBEnv+          , ceIEnv = ibinds+          , ceSpan = maybe dummySpan srcSpan $ gCid >>= (`M.lookup` ieCstrs)+          , ceBindingsInSmt = emptyIBindEnv+          } + findConstants :: Knowledge -> [Expr] -> [(Expr, Expr)] findConstants γ es = [(EVar x, c) | (x,c) <- go [] (concatMap splitPAnd es)]   where@@ -481,8 +619,15 @@ data EvalEnv = EvalEnv   { evEnv      :: !SymEnv   , evElabF    :: ElabFlags-    -- | Equalities where we couldn't evaluate the guards-  , evPendingUnfoldings :: M.HashMap Expr Expr+  , evKCtx     :: SMT.Context+    -- | The current scope of existential variables.+    -- See Note [Existential quantification when unfolding].+  , evExScope  :: ExScope+    -- | Equalities where we couldn't evaluate the guards, in a map which+    -- uses their existential scope as key.+    --+    -- See Note [Existential quantification when unfolding].+  , evPendingUnfoldings :: M.HashMap ExScope (M.HashMap Expr Expr)   , evNewEqualities :: EvEqualities -- ^ Equalities discovered during a traversal of                                     -- an expression   , evSMTCache :: M.HashMap Expr Bool -- ^ Whether an expression is valid or its negation@@ -508,6 +653,15 @@ defFuelCount cfg = FC mempty (fuel cfg)  type EvalST a = StateT EvalEnv IO a++liftSMT :: SmtM a -> EvalST a+liftSMT k =+  do es <- get+     let ctx = evKCtx es+     (a, ctx') <- lift $ runStateT k ctx+     put (es {evKCtx = ctx'})+     pure a+ --------------------------------------------------------------------------------  getAutoRws :: Knowledge -> Maybe SubcId -> [AutoRewrite]@@ -525,7 +679,7 @@ -- way. evalOne :: Knowledge -> ICtx -> Int -> Expr -> EvalST [Expr] evalOne γ ctx i e-  | i > 0 || null (getAutoRws γ (icSubcId ctx)) = (:[]) . fst <$> eval γ ctx NoRW e+  | i > 0 || null (getAutoRws γ (icSubcId ctx)) = (:[]) <$> eval γ ctx NoRW e evalOne γ ctx _ e | isExprRewritable e = do     env <- get     let oc :: OCAlgebra OCType RuntimeTerm IO@@ -555,37 +709,7 @@   | RWNormal   -- REST: Fully Expand Defs in the context of rewriting (similar to NoRW)   deriving (Eq) --- Indicates whether or not the evaluation has expanded a function statement--- into a conditional branch.--- In this case, rewriting should stop--- It's unclear whether or not rewriting in either branch makes sense,--- since one branch could be an ill-formed expression.-newtype FinalExpand = FE Bool deriving (Show) -noExpand :: FinalExpand-noExpand = FE False--expand :: FinalExpand-expand = FE True--mapFE :: (Expr -> Expr) -> (Expr, FinalExpand) -> (Expr, FinalExpand)-mapFE f (e, fe) = (f e, fe)--feVal :: FinalExpand -> Bool-feVal (FE f) = f--feAny :: [FinalExpand] -> FinalExpand-feAny xs = FE $ any feVal xs--infixl 9 <|>-(<|>) :: FinalExpand -> FinalExpand -> FinalExpand-(<|>) (FE True) _ = expand-(<|>) _         f = f---feSeq :: [(Expr, FinalExpand)] -> ([Expr], FinalExpand)-feSeq xs = (map fst xs, feAny (map snd xs))- -- | Unfolds function invocations in expressions. -- -- Also reduces if-then-else when the boolean condition or the negation can be@@ -594,70 +718,55 @@ -- -- Also adds to the monad state all the unfolding equalities that have been -- discovered as necessary.-eval :: Knowledge -> ICtx -> EvalType -> Expr -> EvalST (Expr, FinalExpand)+eval :: Knowledge -> ICtx -> EvalType -> Expr -> EvalST Expr eval γ ctx et = go   where     go (ELam (x,s) e)   = evalELam γ ctx et (x, s) e     go e@EIte{}         = evalIte γ ctx et e-    go (ECoerc s t e)   = mapFE (ECoerc s t)  <$> go e+    go (ECoerc s t e)   = ECoerc s t <$> go e     go e@(EApp _ _)     =       case splitEAppThroughECst e of        (f, es) | et == RWNormal ->           -- Just evaluate the arguments first, to give rewriting a chance to step in           -- if necessary           do-            (es', finalExpand) <- feSeq <$> mapM (eval γ ctx et) es+            es' <- mapM (eval γ ctx et) es             if es /= es'-              then return (eApps f es', finalExpand)+              then return (eApps f es')               else do-                (f', fe) <- case dropECst f of-                  EVar _ -> pure (f, noExpand)+                f' <- case dropECst f of+                  EVar _ -> pure f                   _      -> go f-                (me', fe') <- evalApp γ ctx f' es et-                return (Mb.fromMaybe (eApps f' es') me', fe <|> fe')+                Mb.fromMaybe (eApps f' es') <$> evalApp γ ctx f' es et        (f, es) ->           do-            (f', fe1) <- case dropECst f of-              EVar _ -> pure (f, noExpand)+            f' <- case dropECst f of+              EVar _ -> pure f               _      -> go f-            (es', fe2) <- feSeq <$> mapM (eval γ ctx et) es-            let fe = fe1 <|> fe2-            (me', fe') <- evalApp γ ctx f' es' et-            return (Mb.fromMaybe (eApps f' es') me', fe <|> fe')+            es' <- mapM (eval γ ctx et) es+            Mb.fromMaybe (eApps f' es') <$> evalApp γ ctx f' es' et -    go (PAtom r e1 e2) = binOp (PAtom r) e1 e2-    go (ENeg e)         = do (e', fe)  <- go e-                             return (ENeg e', fe)-    go (EBin o e1 e2)   = do (e1', fe1) <- go e1-                             (e2', fe2) <- go e2-                             return (EBin o e1' e2', fe1 <|> fe2)-    go (ETApp e t)      = mapFE (`ETApp` t) <$> go e-    go (ETAbs e s)      = mapFE (`ETAbs` s) <$> go e-    go (PNot e')        = mapFE PNot <$> go e'-    go (PImp e1 e2)     = binOp PImp e1 e2-    go (PIff e1 e2)     = binOp PIff e1 e2-    go (PAnd es)        = efAll PAnd (go `traverse` es)-    go (POr es)         = efAll POr (go `traverse` es)+    go (PAtom r e1 e2) = PAtom r <$> go e1 <*> go e2+    go (ENeg e)         = ENeg <$> go e+    go (EBin o e1 e2)   = EBin o <$> go e1 <*> go e2+    go (ETApp e t)      = (`ETApp` t) <$> go e+    go (ETAbs e s)      = (`ETAbs` s) <$> go e+    go (PNot e')        = PNot <$> go e'+    go (PImp e1 e2)     = PImp <$> go e1 <*> go e2+    go (PIff e1 e2)     = PIff <$> go e1 <*> go e2+    go (PAnd es)        = PAnd <$> traverse go es+    go (POr es)         = POr <$> traverse go es     go e | EVar _ <- dropECst e = do-      (me', fe) <- evalApp γ ctx e [] et-      return (Mb.fromMaybe e me', fe)-    go (ECst e t)       = do (e', fe) <- go e-                             return (ECst e' t, fe)-    go e                = return (e, noExpand)+      Mb.fromMaybe e <$> evalApp γ ctx e [] et+    go (ECst e t)       = (`ECst` t) <$> go e+    go (ELet x e1 e2)   = ELet x <$> go e1 <*> go e2 -    binOp f e1 e2 = do-      (e1', fe1) <- go e1-      (e2', fe2) <- go e2-      return (f e1' e2', fe1 <|> fe2)+    go e                = return e -    efAll f mes = do-      xs <- mes-      let (xs', fe) = feSeq xs-      return (f xs', fe) --- | 'evalELamb' produces equations that preserve the context of a rewrite+-- | 'evalELam' produces equations that preserve the context of a rewrite -- so equations include any necessary lambda bindings.-evalELam :: Knowledge -> ICtx -> EvalType -> (Symbol, Sort) -> Expr -> EvalST (Expr, FinalExpand)+evalELam :: Knowledge -> ICtx -> EvalType -> (Symbol, Sort) -> Expr -> EvalST Expr evalELam γ ctx et (x, s) e   | not $ isEtaSymbol x = do     -- We need to refresh it as for some reason names bound by lambdas@@ -686,7 +795,7 @@     modify $ \st -> st       { evEnv = insertSymEnv x s $ evEnv st } -    (e', fe) <- eval (γ { knLams = (x, s) : knLams γ }) ctx et e+    e' <- eval (γ { knLams = (x, s) : knLams γ }) ctx et e     let e2' = simplify γ ctx e'         elam = ELam (x, s) e     -- Discard the old equalities which miss the lambda binding@@ -696,7 +805,7 @@       -- Leaving the scope thus we need to get rid of it       , evEnv = deleteSymEnv x $ evEnv st       }-    return (ELam (x, s) e', fe)+    return (ELam (x, s) e')  data RESTParams oc = RP   { oc   :: OCAlgebra oc Expr IO@@ -795,21 +904,22 @@ evalRESTWithCache cacheRef γ ctx acc rp =   do     mexploredTerms <- gets explored+    ebs <- gets evExScope     case mexploredTerms of       Nothing -> return acc       Just exploredTerms -> do-        se <- liftIO (shouldExploreTerm exploredTerms exprs)+        se <- liftIO (shouldExploreTerm ebs exploredTerms exprs)         if se then do-          possibleRWs <- getRWs-          rws <- notVisitedFirst exploredTerms <$> filterM (liftIO . allowed) possibleRWs+          possibleRWs <- liftSMT (getRWs ebs)+          rws <- notVisitedFirst exploredTerms <$> filterM (liftIO . allowed ebs) possibleRWs           oldEqualities <- gets evNewEqualities           modify $ \st -> st { evNewEqualities = mempty }            -- liftIO $ putStrLn $ (show $ length possibleRWs) ++ " rewrites allowed at path length " ++ (show $ (map snd $ path rp))-          (e', FE fe) <- do-            r@(ec, _) <- eval γ ctx FuncNormal exprs+          e' <- do+            ec <- eval γ ctx FuncNormal exprs             if ec /= exprs-              then return r+              then return ec               else eval γ ctx RWNormal exprs            let evalIsNewExpr = e' `L.notElem` pathExprs@@ -834,8 +944,8 @@             }            acc'' <- if evalIsNewExpr-            then if fe && any isRW (path rp)-              then (:[]) . fst <$> eval γ (addConst (exprs, e')) NoRW e'+            then if e' /= exprs && any isRW (path rp)+              then (:[]) <$> eval γ (addConst (exprs, e')) NoRW e'               else evalRESTWithCache cacheRef γ (addConst (exprs, e')) acc' (rpEval newEqualities e')             else return acc' @@ -843,17 +953,17 @@         else           return acc   where-    shouldExploreTerm exploredTerms e | Vis.isConc e =-      case rwTerminationOpts rwArgs of+    shouldExploreTerm ebs exploredTerms e | Vis.isConc e =+      case rwTerminationOpts (rwArgs ebs) of         RWTerminationCheckDisabled ->           return $ not $ ExploredTerms.visited (Rewrite.convert e) exploredTerms         RWTerminationCheckEnabled  ->           ExploredTerms.shouldExplore (Rewrite.convert e) (c rp) exploredTerms-    shouldExploreTerm _ _ = return False+    shouldExploreTerm _ _ _ = return False -    allowed (_, rwE, _) | rwE `elem` pathExprs = return False-    allowed (_, _, c)   = termCheck c-    termCheck c = Rewrite.passesTerminationCheck (oc rp) rwArgs c+    allowed _ebs (_, rwE, _) | rwE `elem` pathExprs = return False+    allowed ebs (_, _, c)   = termCheck ebs c+    termCheck ebs c = Rewrite.passesTerminationCheck (oc rp) (rwArgs ebs) c      notVisitedFirst exploredTerms rws =       let@@ -879,21 +989,21 @@     exprs           = last pathExprs     autorws         = getAutoRws γ (icSubcId ctx) -    rwArgs = RWArgs (isValid cacheRef γ) $ knRWTerminationOpts γ+    rwArgs ebs = RWArgs (isValid cacheRef ebs γ) $ knRWTerminationOpts γ -    getRWs =+    getRWs ebs =       do         -- Optimization: If we got here via rewriting, then the current constraints         -- are satisfiable; otherwise double-check that rewriting is still allowed         ok <-           if isRW $ last (path rp)             then return True-            else liftIO $ termCheck (c rp)+            else liftIO $ termCheck ebs (c rp)         if ok           then             do-              let getRW e ar = Rewrite.getRewrite (oc rp) rwArgs (c rp) e ar-              let getRWs' s  = Mb.catMaybes <$> mapM (liftIO . runMaybeT . getRW s) autorws+              let getRW e ar = Rewrite.getRewrite (oc rp) (rwArgs ebs) (c rp) e ar+              let getRWs' s  = Mb.catMaybes <$> mapM (runMaybeT . getRW s) autorws               concat <$> mapM getRWs' (subExprs exprs)           else return [] @@ -946,7 +1056,7 @@  -- | @evalApp kn ctx e es@ unfolds expressions in @eApps e es@ using rewrites -- and equations-evalApp :: Knowledge -> ICtx -> Expr -> [Expr] -> EvalType -> EvalST (Maybe Expr, FinalExpand)+evalApp :: Knowledge -> ICtx -> Expr -> [Expr] -> EvalType -> EvalST (Maybe Expr) evalApp γ ctx e0 es et   | EVar f <- dropECst e0   , Just eq <- Map.lookup f (knAms γ)@@ -962,7 +1072,7 @@                     then elaborateExpr "EvalApp unfold full: " newE                     else pure newE -         (e', fe) <- evalIte γ ctx et newE'        -- TODO:FUEL this is where an "unfolding" happens, CHECK/BUMP counter+         e' <- evalIte γ ctx et newE'        -- TODO:FUEL this is where an "unfolding" happens, CHECK/BUMP counter          let e2' = stripPLEUnfold e'          let e3' = simplify γ ctx (eApps e2' es2)  -- reduces a bit the equations @@ -972,17 +1082,18 @@            -- If evalIte does any modifications, though, we do unfold in order            -- to allow analysis of the resulting expression            modify $ \st -> st-             { evPendingUnfoldings = M.insert (eApps e0 es) e3' (evPendingUnfoldings st)+             { evPendingUnfoldings =+                 M.insertWith M.union (evExScope st) (M.singleton (eApps e0 es) e3') (evPendingUnfoldings st)              }-           return (Nothing, noExpand)+           return Nothing          else do            useFuel f            modify $ \st -> st              { evNewEqualities = S.insert (eApps e0 es, e3') (evNewEqualities st)-             , evPendingUnfoldings = M.delete (eApps e0 es) (evPendingUnfoldings st)+             , evPendingUnfoldings = M.adjust (M.delete (eApps e0 es)) (evExScope st) (evPendingUnfoldings st)              }-           return (Just $ eApps e2' es2, fe)-       else return (Nothing, noExpand)+           return (Just $ eApps e2' es2)+       else return Nothing   where     -- At the time of writing, any function application wrapping an     -- if-statement would have the effect of unfolding the invocation.@@ -1016,7 +1127,7 @@     when (isUserDataSMeasure == NoUserDataSMeasure) $       modify $ \st -> st         { evNewEqualities = S.insert (eApps e0 args, simplify γ ctx newE) (evNewEqualities st) }-    return (Just newE, noExpand)+    return (Just newE)  evalApp γ ctx e0 es _et   | eqs@(_:_) <- noUserDataMeasureEqs γ (eApps e0 es)@@ -1024,7 +1135,7 @@        let eqs' = map (second $ simplify γ ctx) eqs        modify $ \st ->          st { evNewEqualities = foldr S.insert (evNewEqualities st) eqs' }-       return (Nothing, noExpand)+       return Nothing  evalApp γ ctx e0 es et   | ELam (argName, _) body <- dropECst e0@@ -1037,13 +1148,13 @@           useFuel argName           let argSubst = mkSubst [(argName, lambdaArg)]           let body' = subst argSubst body-          (body'', fe) <- evalIte γ ctx et body'+          body'' <- evalIte γ ctx et body'           let simpBody = simplify γ ctx (eApps body'' remArgs)           modify $ \st ->             st { evNewEqualities = S.insert (eApps e0 es, simpBody) (evNewEqualities st) }-          return (Just $ eApps body'' remArgs, fe)+          return (Just $ eApps body'' remArgs)         else do-          return (Nothing, noExpand)+          return Nothing  evalApp _ ctx e0 es _   | icLocalRewritesFlag ctx@@ -1054,7 +1165,7 @@       let expandedTerm = eApps rw es       modify $ \st -> st         { evNewEqualities = S.insert (eApps e0 es, expandedTerm) (evNewEqualities st) }-      return (Just expandedTerm, expand)+      return (Just expandedTerm)  evalApp _γ ctx e0 es _et   -- We check the annotation instead of the equations in γ for two reasons.@@ -1091,7 +1202,7 @@     -- is already handled by the previous case of evalApp     modify $ \st -> st       { evNewEqualities = S.insert (eApps e0 es, etaExpandedTerm) (evNewEqualities st) }-    return (Just etaExpandedTerm, expand)+    return (Just etaExpandedTerm)   where     unpackFFuncs (FFunc t ts) = t : unpackFFuncs ts     unpackFFuncs _ = []@@ -1099,22 +1210,21 @@     mkLams subject binds = foldr ELam subject binds  evalApp _ _ctx _e0 _es _ = do-  return (Nothing, noExpand)+  return Nothing  -- | Evaluates if-then-else statements until they can't be evaluated anymore -- or some other expression is found.-evalIte :: Knowledge -> ICtx -> EvalType -> Expr -> EvalST (Expr, FinalExpand)+evalIte :: Knowledge -> ICtx -> EvalType -> Expr -> EvalST Expr evalIte γ ctx et (ECst e t) = do-  (e', fe) <- evalIte γ ctx et e-  return (ECst e' t, fe)+  (`ECst` t) <$> evalIte γ ctx et e evalIte γ ctx et (EIte i e1 e2) = do-      (b, _) <- eval γ ctx et i+      b <- eval γ ctx et i       b'  <- mytracepp ("evalEIt POS " ++ showpp (i, b)) <$> isValidCached γ b       case b' of         Just True -> evalIte γ ctx et e1         Just False -> evalIte γ ctx et e2-        _ -> return (EIte b e1 e2, expand)-evalIte _ _ _ e' = return (e', noExpand)+        _ -> return (EIte b e1 e2)+evalIte _ _ _ e' = return e'  -- | Creates equations that explain how to rewrite a given constructor -- application with all measures that aren't user data measures@@ -1180,14 +1290,14 @@   case M.lookup e (evSMTCache env) of     Nothing -> do       let isFreeInE (s, _) = not (S.member s (exprSymbolsSet e))-      b <- liftIO $ knPreds γ (knContext γ) (knLams γ) e+      b <- knPredsEvalST γ e       if b         then do           when (all isFreeInE (knLams γ)) $             put (env { evSMTCache = M.insert e True (evSMTCache env) })           return (Just True)         else do-          b2 <- liftIO $ knPreds γ (knContext γ) (knLams γ) (PNot e)+          b2 <- knPredsEvalST γ (PNot e)           if b2             then do               when (all isFreeInE (knLams γ)) $@@ -1209,8 +1319,10 @@     -- user data declaration.     knSims              :: Map Symbol [(Rewrite, IsUserDataSMeasure)]   , knAms               :: Map Symbol Equation -- ^ All function definitions-  , knContext           :: SMT.Context-  , knPreds             :: SMT.Context -> [(Symbol, Sort)] -> Expr -> IO Bool+    -- | @knPreds γ bsInSMT xs e@ checks whether @e@ is valid under the+    -- assumptions that all variables in @bsInSMT@ are in the SMT solver,+    -- and that all variables in @xs@ need tp be declared in the SMT solver.+  , knPreds             :: [(Symbol, Sort)] -> [(Symbol, Sort)] -> Expr -> SmtM Bool   , knLams              :: ![(Symbol, Sort)]   , knSummary           :: ![(Symbol, Int)]     -- ^ summary of functions to be evaluates (knSims and knAsms) with their arity   , knDCs               :: !(S.HashSet Symbol)  -- ^ data constructors drawn from Rewrite@@ -1226,25 +1338,29 @@ data IsUserDataSMeasure = NoUserDataSMeasure | UserDataSMeasure   deriving (Eq, Show) -isValid :: IORef (M.HashMap Expr Bool) -> Knowledge -> Expr -> IO Bool-isValid cacheRef γ e = do-    smtCache <- readIORef cacheRef+knPredsEvalST :: Knowledge -> Expr -> EvalST Bool+knPredsEvalST γ e = do+    env <- get+    liftSMT $ knPreds γ (evExScope env) (knLams γ) e++isValid :: IORef (M.HashMap Expr Bool) -> [(Symbol, Sort)] -> Knowledge -> Expr -> SmtM Bool+isValid cacheRef bs γ e = do+    smtCache <- liftIO $ readIORef cacheRef     case M.lookup e smtCache of       Nothing -> do-        b <- knPreds γ (knContext γ) (knLams γ) e+        b <- knPreds γ bs (knLams γ) e         when b $-          writeIORef cacheRef (M.insert e True smtCache)+          liftIO $ writeIORef cacheRef (M.insert e True smtCache)         return b-      mb -> return (mb == Just True)+      Just b -> return b -knowledge :: Config -> SMT.Context -> SInfo a -> Knowledge-knowledge cfg ctx si = KN+knowledge :: Config -> SInfo a -> Knowledge+knowledge cfg si = KN   { knSims                     = Map.fromListWith (++) $                                    [ (smDC rw, [(rw, NoUserDataSMeasure)]) | rw <- sims ] ++                                    [ (smDC rw, [(rw, UserDataSMeasure)]) | rw <- dataSims ]   , knAms                      = Map.fromList [(eqName eq, eq) | eq <- aenvEqs aenv]-  , knContext                  = ctx-  , knPreds                    = askSMT  cfg+  , knPreds                    = askSMT cfg   , knLams                     = []   , knSummary                  =    ((\s -> (smName s, 1)) <$> sims)                                  ++ ((\s -> (eqName s, length (eqArgs s))) <$> aenvEqs aenv)@@ -1255,7 +1371,7 @@   , knConsts                   = Mb.mapMaybe makeCons sims   , knAutoRWs                  = aenvAutoRW aenv   , knRWTerminationOpts        =-      if rwTerminationCheck cfg+      if rwTermination cfg       then RWTerminationCheckEnabled       else RWTerminationCheckDisabled   }@@ -1335,15 +1451,6 @@ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -withCtx :: Config -> FilePath -> SymEnv -> [Equation] -> (SMT.Context -> IO a) -> IO a-withCtx cfg file env defns k = do-  ctx <- SMT.makeContextWithSEnv cfg file env defns-  _   <- SMT.smtPush ctx-  res <- k ctx-  SMT.cleanupContext ctx-  return res-- -- (sel_i, D, i), meaning sel_i (D x1 .. xn) = xi, -- i.e., sel_i selects the ith value for the data constructor D type SelectorMap = [(Symbol, (Symbol, Int))]@@ -1466,7 +1573,8 @@ elaborateExpr :: String -> Expr -> EvalST Expr elaborateExpr msg e = do   let elabSpan = atLoc dummySpan msg-  symEnv' <- gets evEnv+  env <- get+  let symEnv' = insertsSymEnv (evEnv env) (evExScope env)   ef <- gets evElabF   pure $ unApply $ elaborate (ElabParam ef elabSpan symEnv') e @@ -1478,3 +1586,128 @@   case (M.lookup f (fcMap fc), fcMax fc) of     (Just fk, Just n) -> pure (fk <= n)     _                 -> pure True+++-- Note [Existential quantification when unfolding]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+--+-- After FUSION is performed, some predicates, which previously used kvars, may+-- contain existential quantifications.+--+-- When the unfoldings are searched by PLE in expressions with existentials,+-- we make sure that the produced unfoldings still have the existential+-- bindings in scope.+--+-- The procedure is as follows:+-- 1. First, we rename the existential variables in the predicates of the bindings+--    to make them unique ('renameExistentialsInSortedRefts').+--+--    @exists x y. f x y || (exists x. g x y)@+--+--    becomes+--+--    @exists v0 v1. f v0 v1 || (exists v2. g v2 v1)@+--+-- 2. We extract the nested existentials to prenex form, and we store the bodies of+--    the existentials in a map with the existential binders as keys+--    ('prenexExistentials' and 'updCtx').+--+--    @exists v0 v1. f v0 v1 || (exists v2. g v2 v1)@+--+--    produces the map+--+--    @[v0, v1, v2] -> f v0 v1 || g v2 v1@+--+-- 3. We declare to the SMT solver the existential variables in every scope+--    (in 'withAssms').+--+-- 4. We then look for unfoldings in each of the subexpressions. Whenever+--    we find an unfolding, we record the scope in which it was found.+--+--    @[v0, v1, v3] -> (f v0 v1 = v0 < v1) && (g v2 = v2 > v1)@+--+-- 5. When PLE is finished, we create for every scope an existential+--    quantification whose body contains all the corresponding unfoldings+--    and the original subexpressions in the scope ('reconstructExistentials').+--+--    @exists v0 v1 v0.+--       (f v0 v 1 = v0 < v1) && (g v2 = v2 > v1) &&+--       (f v0 v1 || g v2 v1)@+--+--    This is the expression that PLE returns.+++-- | Renames existential variables in the predicates of the given bindings to+-- make them unique.+--+-- Rather than looking for all existential bindings, this function only renames+-- the superficial existentials which can be introduced by KVar solutions.+--+-- These superficial existentials appear in conjunctions, disjunctions and in the+-- body of other existentials only.+renameExistentialsInSortedRefts+  :: [(Symbol, SortedReft)]+  -> Int+  -> ([(Symbol, SortedReft)], Int)+renameExistentialsInSortedRefts binds0 existentialCounter =+    let+        binds = [ (x, sr { sr_reft = mapPredReft (const p) (sr_reft sr) }) | ((x, sr), p) <- zip binds0 preds ]+        (preds, existentialCounter') =+          renameKVarExistentials (map (reftPred . sr_reft . snd) binds0) existentialCounter+     in+        (binds, existentialCounter')++renameKVarExistentials :: [Expr] -> Int -> ([Expr], Int)+renameKVarExistentials = runState . mapM go+  where+    go (POr es) = POr <$> mapM go es+    go (PAnd es) = PAnd <$> mapM go es+    go (PExist bs e0) = do+      i1 <- get+      let i2 = i1 + length bs+      put i2+      let vs = map fst bs+          vs' = [ existSymbol v (fromIntegral i) | (v, i) <- zip vs [i1..] ]+          bs' = zip vs' (map snd bs)+          su = mkSubst $ zip vs (map EVar vs')+      PExist bs' <$> go (rapierSubstExpr (S.fromList vs') su e0)+    go e = pure e++-- ^ Scopes of existential binders identifying the location of sub-expressions+type ExScope = [(Symbol, Sort)]+++-- | Extracts nested existentials from an expression.+--+-- For example, the expression+--+-- > exists [x1 : t1]. e1 == e2 &&+-- > exists [x2 : t2]. e3 == 2 &&+-- > exists [x3 : t3]. e3 < e4+--+-- would be flattened into+--+-- > (e1 == e2 && e3 == 2 && e3 < e4, [x1 : t1, x2 : t2, x3 : t3])+--+-- Precondition: the existential binding names are unique.+--+prenexExistentials :: Expr -> (ExScope, Expr)+prenexExistentials = go+  where+    go :: Expr -> (ExScope, Expr)+    go (PExist bs e) =+      let (bs', e') = go e+      in (bs ++ bs', e')+    go (PAnd es) =+      let (bss, es') = unzip (map go es)+      in (concat bss, PAnd es')+    go (POr es) =+      let (bss, es') = unzip (map go es)+      in (concat bss, POr es')+    go e = ([], e)+++-- | Reconstructs expressions with existentials from a map+-- of existential scopes to their bodies.+reconstructExistentials :: M.HashMap ExScope (S.HashSet Expr) -> [Expr]+reconstructExistentials m = [ pExist s (pAndNoDedup $ S.toList es) | (s, es) <- M.toList m, not (null es) ]
src/Language/Fixpoint/Solver/Rewrite.hs view
@@ -30,6 +30,7 @@ import           Text.PrettyPrint (text) import           Language.Fixpoint.Types.Config (RESTOrdering(..)) import           Language.Fixpoint.Types hiding (simplify)+import           Language.Fixpoint.Smt.Types (SmtM) import           Language.REST import           Language.REST.KBO (kbo) import           Language.REST.LPO (lpo)@@ -54,7 +55,7 @@   | RWTerminationCheckDisabled  data RewriteArgs = RWArgs- { isRWValid          :: Expr -> IO Bool+ { isRWValid          :: Expr -> SmtM Bool  , rwTerminationOpts  :: RWTerminationOpts  } @@ -128,7 +129,7 @@   -> oc   -> SubExpr   -> AutoRewrite-  -> MaybeT IO ((Expr, Expr), Expr, oc)+  -> MaybeT SmtM ((Expr, Expr), Expr, oc) getRewrite aoc rwArgs c (subE, toE) (AutoRewrite args lhs rhs) =   do     su <- MaybeT $ return $ unify freeVars lhs subE@@ -145,7 +146,7 @@           (eqn, expr', c')       RWTerminationCheckDisabled -> (eqn, expr', c)   where-    check :: Expr -> MaybeT IO ()+    check :: Expr -> MaybeT SmtM ()     check e = do       valid <- MaybeT $ Just <$> isRWValid rwArgs e       guard valid@@ -225,6 +226,15 @@  subExprs' (POr es) = [ (e, POr . f) | (e, f) <- subs es ] +subExprs' (ELet x e1 e2) = e1'' ++ e2''+  where+    e1' = subExprs e1+    e2' = subExprs e2+    e1'' :: [SubExpr]+    e1'' = map (\(e, f) -> (e, \e' -> ELet x (f e') e2)) e1'+    e2'' :: [SubExpr]+    e2'' = map (\(e, f) -> (e, \e' -> ELet x e1 (f e'))) e2'+ subExprs' _ = []  -- | Computes the subexpressions of a list of expressions.@@ -304,8 +314,8 @@       unify freeVars rw seen     (PExist _ rw, PExist _ seen) ->       unify freeVars rw seen-    (PGrad _ _ _ rw, PGrad _ _ _ seen) ->-      unify freeVars rw seen     (ECoerc _ _ rw, ECoerc _ _ seen) ->       unify freeVars rw seen+    (ELet _ rw1 rw2, ELet _ seen1 seen2) ->+      unifyAll freeVars [rw1, rw2] [seen1, seen2]     _ -> Nothing
src/Language/Fixpoint/Solver/Sanitize.hs view
@@ -2,7 +2,6 @@ --   1. Each binder must be associated with a UNIQUE sort {-# LANGUAGE TupleSections     #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE PatternGuards     #-}  module Language.Fixpoint.Solver.Sanitize   ( -- * Transform FInfo to enforce invariants@@ -17,7 +16,7 @@  import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Types.Visitor-import           Language.Fixpoint.SortCheck     (ElabParam(..), elaborate, applySorts, isFirstOrder)+import           Language.Fixpoint.SortCheck     (ElabParam(..), theoryEnv, elaborate, applySorts, isFirstOrder) -- import           Language.Fixpoint.Defunctionalize import           Language.Fixpoint.Misc ((==>)) import qualified Language.Fixpoint.Misc                            as Misc@@ -34,7 +33,9 @@ import qualified Data.Text                                         as T import           Data.Maybe          (isNothing, mapMaybe, fromMaybe) import           Control.Monad       ((>=>))+import           GHC.Stack           (HasCallStack) import           Text.PrettyPrint.HughesPJ hiding ((<>))+import qualified Language.Fixpoint.SortCheck as SortCheck  type SanitizeM a = Either E.Error a @@ -45,9 +46,9 @@          >=> Misc.fM dropFuncSortedShadowedBinders          >=> Misc.fM sanitizeWfC          >=> Misc.fM replaceDeadKvars-         >=> Misc.fM (dropDeadSubsts . restrictKVarDomain)+         >=> Misc.fM (dropDeadSubsts . restrictKVarDomain cfg)          >=>         banMixedRhs-         >=>         banQualifFreeVars+         >=>         banQualifFreeVars cfg          >=>         banConstraintFreeVars cfg          >=> Misc.fM addLiterals          >=> Misc.fM (eliminateEta cfg)@@ -88,42 +89,12 @@ -------------------------------------------------------------------------------- eliminateEta cfg si   | Cfg.etaElim cfg-  , Cfg.oldPLE  cfg-  = si { F.ae = ae' }-  | Cfg.etaElim cfg   = si { F.ae = (ae {F.aenvEqs = etaElimNEW `fmap` F.aenvEqs ae }) }   | otherwise   = si   where-    ae' = ae {F.aenvEqs = eqs}     ae = F.ae si-    eqs = fmap etaElim (F.aenvEqs ae) -    etaElim eq = F.notracepp "Eliminating" $-                 case body of-                   F.PAtom F.Eq e0 e1 ->-                     let (f0, args0) = fapp e0-                         (f1, args1) = F.notracepp "f1" $ fapp e1 in-                     if reverse args0 == args-                     then let commonArgs = F.notracepp "commonArgs" .-                                           fmap fst .-                                           takeWhile (uncurry (==)) $-                                           zip args0 args1-                              commonLength = length commonArgs-                              (newArgsAndSorts, elimedArgsAndSorts) =-                                splitAt (length args - commonLength) argsAndSorts-                              args0' = F.eVar <$> reverse (drop commonLength args0)-                              args1' = F.eVar <$> reverse (drop commonLength args1) in-                       eq { F.eqArgs = newArgsAndSorts-                          , F.eqSort = foldr F.FFunc sort-                                       (snd <$> elimedArgsAndSorts)-                          , F.eqBody = F.PAtom F.Eq (F.eApps f0 args0') (F.eApps f1 args1')}-                     else eq-                   _ -> eq-      where argsAndSorts = F.eqArgs eq-            args = fst <$> argsAndSorts-            body = F.eqBody eq-            sort = F.eqSort eq     etaElimNEW eq = F.notracepp "Eliminating" $                   let (f1, args1) = fapp (F.eqBody eq) in                   let commonArgs = F.notracepp "commonArgs" .@@ -160,11 +131,6 @@       | otherwise       = Nothing -theoryEnv :: Config -> F.GInfo c a -> F.SEnv F.TheorySymbol-theoryEnv cfg si-  =  Thy.theorySymbols (Cfg.solver cfg)-  <> Thy.theorySymbols (F.defns si)-  <> Thy.theorySymbols (F.ddecls si)  -------------------------------------------------------------------------------- -- | See issue liquid-fixpoint issue #230. This checks that whenever we have,@@ -235,10 +201,12 @@ --   `x` which appear in substitutions of the form `K[x := y]` where `y` --   is not in the env. ---------------------------------------------------------------------------------restrictKVarDomain :: F.SInfo a -> F.SInfo a-restrictKVarDomain si = si { F.ws = M.mapWithKey (restrictWf kvm) (F.ws si) }+restrictKVarDomain :: Config -> F.SInfo a -> F.SInfo a+restrictKVarDomain cfg si+  | Cfg.explicitKvars cfg = si+  | otherwise             = si { F.ws = M.mapWithKey (restrictWf kvm) (F.ws si) }   where-    kvm               = safeKvarEnv si+    kvm                   = safeKvarEnv si  -- | `restrictWf kve k w` restricts the env of `w` to the parameters in `kve k`. restrictWf :: KvDom -> F.KVar -> F.WfC a -> F.WfC a@@ -248,20 +216,21 @@     kis            = S.fromList [ i | (_, i) <- F.toListSEnv kEnv ]     kEnv           = M.lookupDefault mempty k kve +type KvDom     = M.HashMap F.KVar (F.SEnv F.BindId)+type KvBads    = M.HashMap F.KVar [F.Symbol]+ -- | `safeKvarEnv` computes the "real" domain of each kvar, which is --   a SUBSET of the input domain, in which we KILL the parameters --   `x` which appear in substitutions of the form `K[x := y]` --   where `y` is not in the env. -type KvDom     = M.HashMap F.KVar (F.SEnv F.BindId)-type KvBads    = M.HashMap F.KVar [F.Symbol]- safeKvarEnv :: F.SInfo a -> KvDom safeKvarEnv si = L.foldl' (dropKvarEnv si) env0 cs   where     cs         = M.elems  (F.cm si)     env0       = initKvarEnv si + dropKvarEnv :: F.SInfo a -> KvDom -> F.SimpC a -> KvDom dropKvarEnv si kve c = M.mapWithKey (dropBadParams kBads) kve   where@@ -353,15 +322,13 @@ -------------------------------------------------------------------------------- -- | check that no qualifier has free variables ---------------------------------------------------------------------------------banQualifFreeVars :: F.SInfo a -> SanitizeM (F.SInfo a)+banQualifFreeVars :: Config -> F.SInfo a -> SanitizeM (F.SInfo a) ---------------------------------------------------------------------------------banQualifFreeVars fi = Misc.applyNonNull (Right fi) (Left . badQuals) bads+banQualifFreeVars cfg fi = Misc.applyNonNull (Right fi) (Left . badQuals) bads   where     bads    = [ (q, xs) | q <- F.quals fi, let xs = free q, not (null xs) ]-    free q  = filter (not . isLit) (F.syms q)-    isLit x = F.memberSEnv x (F.gLits fi)-    -- lits    = fst <$> F.toListSEnv (F.gLits fi)-    -- free q  = S.toList $ F.syms (F.qBody q) `nubDiff` (lits ++ F.prims ++ F.syms (F.qpSym <$> F.qParams q))+    free q  = filter (not . isGlobal) (F.syms q)+    isGlobal x = F.memberSEnv x (SortCheck.globalEnv cfg fi)  badQuals     :: Misc.ListNE (F.Qualifier, Misc.ListNE F.Symbol) -> E.Error badQuals bqs = E.catErrors [ E.errFreeVarInQual q xs | (q, xs) <- bqs]@@ -393,7 +360,7 @@ --   function definitions inside the `AxiomEnv` which cannot be elaborated as --   it makes it hard to actually find the fundefs within (breaking PLE.) ---------------------------------------------------------------------------------symbolEnv :: Config -> F.SInfo a -> F.SymEnv+symbolEnv :: HasCallStack => Config -> F.SInfo a -> F.SymEnv symbolEnv cfg si = F.symEnv sEnv thyEnv ds lits (ts ++ ts')   where     ts'          = applySorts ae'@@ -403,8 +370,7 @@     ds           = F.ddecls si     ts           = Misc.setNub (applySorts si ++ [t | (_, t) <- F.toListSEnv sEnv])     sEnv         = F.coerceSortEnv ef $ (F.tsSort <$> thyEnv) `mappend` F.fromListSEnv xts-    slv          = Cfg.solver cfg-    ef           = solverFlags slv+    ef           = solverFlags cfg     xts          = symbolSorts cfg si ++ alits     lits         = F.dLits si `F.unionSEnv'` F.fromListSEnv alits     alits        = litsAEnv $ F.ae si@@ -412,7 +378,7 @@ litsAEnv :: F.AxiomEnv -> [(F.Symbol, F.Sort)] litsAEnv ae = zip (F.symbol <$> symConsts ae) (repeat F.strSort) -symbolSorts :: Config -> F.GInfo c a -> [(F.Symbol, F.Sort)]+symbolSorts :: HasCallStack => Config -> F.GInfo c a -> [(F.Symbol, F.Sort)] symbolSorts cfg fi = either E.die id $ symbolSorts' cfg fi  symbolSorts' :: Config -> F.GInfo c a -> SanitizeM [(F.Symbol, F.Sort)]
src/Language/Fixpoint/Solver/Solution.hs view
@@ -1,7 +1,8 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP               #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE PatternGuards     #-}+{-# LANGUAGE TupleSections #-}+{-# OPTIONS_GHC -Wwarn #-}  module Language.Fixpoint.Solver.Solution   ( -- * Create Initial Solution@@ -10,21 +11,27 @@     -- * Update Solution   , Sol.update +    -- * Apply Solution+  , applyInSortedReft+  , CombinedEnv(..)+     -- * Lookup Solution   , lhsPred    , nonCutsResult++    -- * Exported for Testing+  , simplifyKVar+  , alphaEq   ) where -import           Control.Parallel.Strategies import           Control.Arrow (second, (***))-import           Control.Monad (void)+import           Control.Monad                  (guard, mplus) import           Control.Monad.Reader import qualified Data.HashSet                   as S import qualified Data.HashMap.Strict            as M-import qualified Data.List                      as L-import           Data.Maybe                     (fromMaybe, maybeToList, isNothing)-import qualified Data.Bifunctor                 as Bifunctor (second)+import qualified Data.List                      as List+import           Data.Maybe                     (maybeToList, isJust, isNothing) import           Language.Fixpoint.Types.PrettyPrint () import           Language.Fixpoint.Types.Visitor      as V import           Language.Fixpoint.SortCheck          (ElabM)@@ -32,35 +39,30 @@ import qualified Language.Fixpoint.Misc               as Misc import           Language.Fixpoint.Types.Config import qualified Language.Fixpoint.Types              as F-import           Language.Fixpoint.Types                 ((&.&)) 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 --- DEBUG-import Text.Printf (printf)--- import Debug.Trace (trace) - -------------------------------------------------------------------------------- -- | Initial Solution (from Qualifiers and WF constraints) --------------------- ---------------------------------------------------------------------------------init :: (F.Fixpoint a) => Config -> F.SInfo a -> S.HashSet F.KVar -> Sol.Solution+init :: (F.Fixpoint a) => Config -> F.SInfo a -> S.HashSet F.KVar -> M.HashMap F.KVar Sol.QBind ---------------------------------------------------------------------------------init cfg si ks_ = Sol.fromList symEnv mempty keqs [] mempty ebs xEnv+init cfg si ks =+    runReader (traverse (refine si qcs genv) ws) (solverFlags cfg)   where-    keqs       = runReader (traverse (refine si qcs genv) ws) (solverFlags $ solver cfg) `using` parList rdeepseq-    qcs        = {- trace ("init-qs-size " ++ show (length ws, length qs_, M.keys qcs_)) $ -} qcs_-    qcs_       = mkQCluster qs_-    qs_        = F.quals si-    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-    symEnv     = symbolEnv cfg si-    ebs        = ebindInfo si-    xEnv       = F.fromListSEnv [ (x, (i, F.sr_sort sr)) | (i,(x,sr,_)) <- F.bindEnvToList (F.bs si)]+    qcs = mkQCluster (F.quals si)+    ws = M.intersection (F.ws si) (S.toMap ks)+    genv = initQualifierEnv cfg si +initQualifierEnv :: (F.Fixpoint a) => Config -> F.SInfo a -> F.SEnv F.Sort+initQualifierEnv cfg si+  | scraping  = So.globalEnv cfg si <> instConstants si+  | otherwise = instConstants si+  where+    scraping = scrape cfg /= No+ -------------------------------------------------------------------------------- -- | [NOTE:qual-cluster] It is wasteful to perform instantiation *individually* --   on each qualifier, as many qualifiers have "equivalent" parameters, and@@ -82,7 +84,7 @@  -------------------------------------------------------------------------------- -refine :: F.SInfo a -> QCluster -> F.SEnv F.Sort -> F.WfC a -> ElabM (F.KVar, Sol.QBind)+refine :: F.SInfo a -> QCluster -> F.SEnv F.Sort -> F.WfC a -> ElabM Sol.QBind refine info qs genv w = refineK (allowHOquals info) env qs (F.wrft w)   where     env             = wenvSort <> genv@@ -94,14 +96,10 @@     notLit    = not . F.isLitSymbol . fst  -refineK :: Bool -> F.SEnv F.Sort -> QCluster -> (F.Symbol, F.Sort, F.KVar) -> ElabM (F.KVar, Sol.QBind)-refineK ho env qs (v, t, k) =-  do eqs' <- Sol.qbFilterM (okInst env v t) eqs-     pure $ F.notracepp _msg (k, eqs')+refineK :: Bool -> F.SEnv F.Sort -> QCluster -> (F.Symbol, F.Sort, F.KVar) -> ElabM Sol.QBind+refineK ho env qs (v, t, _k) = Sol.qbFilterM (okInst env v t) eqs    where-    eqs                     = instK ho env v t qs--    _msg                    = printf "\n\nrefineK: k = %s, eqs = %s" (F.showpp k) (F.showpp eqs)+    eqs = instK ho env v t qs  -------------------------------------------------------------------------------- instK :: Bool@@ -253,14 +251,15 @@ {-# SCC lhsPred #-} lhsPred   :: (F.Loc a)-  => F.IBindEnv+  => Config+  -> F.IBindEnv   -> F.BindEnv a   -> Sol.Solution   -> F.SimpC a-  -> ElabM F.Expr-lhsPred bindingsInSmt be s c =-  do ap <- apply g s bs-     pure $ F.notracepp _msg $ fst ap+  -> F.Expr+lhsPred cfg bindingsInSmt be s c =+    let ap = apply cfg g s bs+     in F.notracepp _msg $ fst ap   where     g          = CEnv ci be bs (F.srcSpan c) bindingsInSmt     bs         = F.senv c@@ -278,91 +277,67 @@   , ceBindingsInSmt :: !F.IBindEnv   } -instance F.Loc (CombinedEnv a) where-  srcSpan = ceSpan- type Cid         = Maybe Integer type ExprInfo    = (F.Expr, KInfo) -apply :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.IBindEnv -> ElabM ExprInfo-apply g s bs      =-  -- Clear the "known" bindings for applyKVars, since it depends on-  -- using the fully expanded representation of the predicates to bind their-  -- variables with quantifiers.-  do (ps,  ks, _) <- envConcKVars g s bs-     (pks, kI) <- applyKVars g {ceBindingsInSmt = F.emptyIBindEnv} s ks-     pure (F.conj (pks:ps), kI)   -- see [NOTE: pAnd-SLOW]+apply :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> F.IBindEnv -> ExprInfo+apply cfg g s bs =+    -- Clear the "known" bindings for applyKVars, since it depends on+    -- using the fully expanded representation of the predicates to bind their+    -- variables with quantifiers.+    let xrs = map (lookupBindEnvExt g) (F.elemsIBindEnv bs)+        (ps,  ks) = envConcKVars xrs+        (pks, kI) = applyKVars cfg g {ceBindingsInSmt = F.emptyIBindEnv} s ks+     in (F.conj (pks:ps), kI)   -- see [NOTE: pAnd-SLOW] +-- | @applyInSortedReft@ applies the solution to a single sorted reft+applyInSortedReft+  :: Config+  -> CombinedEnv ann+  -> Sol.Sol Sol.QBind+  -> (F.Symbol, F.SortedReft)+  -> (F.Symbol, F.SortedReft)+applyInSortedReft cfg g s xsr@(x, sr) =+    let (ps,  ks) = envConcKVars [xsr]+        (pks, _) = applyKVars cfg g {ceBindingsInSmt = F.emptyIBindEnv} s ks+     in (x, sr { F.sr_reft = F.Reft (x, F.conj (pks : ps)) }) -envConcKVars :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.IBindEnv -> ElabM ([F.Expr], [F.KVSub], [F.KVSub])-envConcKVars g s bs =-  do xrs <- traverse (lookupBindEnvExt g s) is-     let (pss, kss, gss) = unzip3 [ F.notracepp ("sortedReftConcKVars" ++ F.showpp sr) $ F.sortedReftConcKVars x sr | (x, sr) <- xrs ]-     pure (concat pss, concat kss, L.nubBy (\x y -> F.ksuKVar x == F.ksuKVar y) $ concat gss)-  where-    is = F.elemsIBindEnv bs+-- | Produces conjuncts of each sorted reft in the IBindEnv, separated+-- into concrete conjuncts and kvars.+envConcKVars :: [(F.Symbol, F.SortedReft)] -> ([F.Expr], [F.KVSub])+envConcKVars xrs =+  let (pss, kss) = unzip [ F.sortedReftConcKVars x sr | (x, sr) <- xrs ]+   in (concat pss, concat kss) -lookupBindEnvExt :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.BindId -> ElabM (F.Symbol, F.SortedReft)-lookupBindEnvExt g s i =-  do msol <- ebSol (g {ceBindingsInSmt = F.emptyIBindEnv}) s i-     pure (x, case msol of-                Just p -> sr { F.sr_reft = F.Reft (x, p) }-                Nothing -> if F.memberIBindEnv i (ceBindingsInSmt g)-                              then sr { F.sr_reft = F.Reft (x, F.EVar (F.bindSymbol (fromIntegral i)))}-                              else sr)+lookupBindEnvExt+  :: CombinedEnv ann -> F.BindId -> (F.Symbol, F.SortedReft)+lookupBindEnvExt g i =+     (,) x $+       if F.memberIBindEnv i (ceBindingsInSmt g)+       then sr { F.sr_reft = F.Reft (x, F.EVar (F.bindSymbol (fromIntegral i)))}+       else sr    where       (x, sr, _)              = F.lookupBindEnv i (ceBEnv g) -ebSol :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.BindId -> ElabM (Maybe F.Expr)-ebSol g sol bindId = case M.lookup bindId sebds of-  Just (Sol.EbSol p)    -> pure $ Just p-  Just (Sol.EbDef cs _) ->-    do let cSol c = if sid c == ceCid g-                       then pure F.PFalse-                       else do p <- ebindReft g s' c-                               pure $ exElim (Sol.sxEnv s') (senv c) bindId p-       exps <- traverse cSol cs-       pure $ Just $ F.PAnd exps-  _                     -> pure Nothing-  where-    sebds = Sol.sEbd sol-    s' = sol { Sol.sEbd = M.insert bindId Sol.EbIncr sebds }--ebindReft :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.SimpC () -> ElabM F.Pred-ebindReft g s c =-  do a <- apply g' s bs-     pure $ F.pAnd [ fst a , F.crhs c ]-  where-    g'          = g { ceCid = sid c, ceIEnv = bs }-    bs          = F.senv c--exElim :: F.SEnv (F.BindId, F.Sort) -> F.IBindEnv -> F.BindId -> F.Pred -> F.Pred-exElim env ienv xi p = F.notracepp msg (F.pExist yts p)-  where-    msg         = "exElim" -- printf "exElim: ix = %d, p = %s" xi (F.showpp p)-    yts         = [ (y, yt) | y        <- F.syms p-                            , (yi, yt) <- maybeToList (F.lookupSEnv y env)-                            , xi < yi-                            , yi `F.memberIBindEnv` ienv                  ]--applyKVars :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> [F.KVSub] -> ElabM ExprInfo-applyKVars g s ks =-  mrExprInfosM (applyKVar g s) F.pAndNoDedup mconcat ks+applyKVars :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> [F.KVSub] -> ExprInfo+applyKVars cfg g s ks =+  let bcs = map (applyKVar cfg g s) ks+      (es, is) = unzip bcs+   in (F.pAndNoDedup es, mconcat is) -applyKVar :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.KVSub -> ElabM ExprInfo-applyKVar g s ksu = case Sol.lookup s (F.ksuKVar ksu) of-  Left cs   -> hypPred g s ksu cs-  Right eqs -> do qbp <- Sol.qbPreds msg s (F.ksuSubst ksu) eqs-                  pure (F.pAndNoDedup $ fst <$> qbp, mempty) -- TODO: don't initialize kvars that have a hyp solution-  where-    msg     = "applyKVar: " ++ show (ceCid g)+applyKVar :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> F.KVSub -> ExprInfo+applyKVar cfg  g s ksu = case Sol.lookup s (F.ksuKVar ksu) of+  Left cs   -> hypPred cfg g s ksu cs+  Right eqs -> let qbp = Sol.qbPreds (F.ksuSubst ksu) eqs+                in (F.pAndNoDedup $ fst <$> qbp, mempty) -- TODO: don't initialize kvars that have a hyp solution -mkNonCutsExpr :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.KVar -> Sol.Hyp -> ElabM F.Expr-mkNonCutsExpr ce s k cs = do bcps <- traverse (bareCubePred ce s k) cs-                             pure $ F.pOr bcps+mkNonCutsExpr :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> F.KVar -> Sol.Hyp -> F.Expr+mkNonCutsExpr cfg ce s k cs =+  let bcps = map (bareCubePred cfg ce s k) cs+   in F.pOr bcps -nonCutsResult :: F.BindEnv ann -> Sol.Sol a Sol.QBind -> ElabM (M.HashMap F.KVar F.Expr)-nonCutsResult be s = M.traverseWithKey (mkNonCutsExpr g s) $ Sol.sHyp s+nonCutsResult :: Config -> F.BindEnv ann -> Sol.Sol Sol.QBind -> FixDelayedSolution+nonCutsResult cfg be s = M.mapWithKey (\k -> Delayed . mkNonCutsExpr cfg g s k) $ Sol.sHyp s   where     g = CEnv Nothing be F.emptyIBindEnv F.dummySpan F.emptyIBindEnv @@ -373,35 +348,57 @@ -- differences since the result of 'cubePred' is fed to the verification -- pipeline and @bareCubePred@ is meant for human inspection. ----- 1) Only one existential quantifier is introduced at the top of the---    expression.--- 2) @bareCubePred@ doesn't elaborate the expression, so it avoids calling---    'elabExist'. 'apply' is invoked to eliminate other kvars though, and---    apply will invoke 'elabExist', so 'Liquid.Fixpoint.SortCheck.unElab'---    might need to be called on the output to remove the elaboration.--- 3) The expression is created from its defining constraints only, while---    @cubePred@ does expect the caller to supply the substitution at a---    particular use of the KVar. Thus @cubePred@ produces a different---    expression for every use site of the kvar, while here we produce one---    expression for all the uses.-bareCubePred :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.KVar -> Sol.Cube -> ElabM F.Expr-bareCubePred g s k c =-  do (xts, psu) <- substElim (Sol.sEnv s) sEnv g' k su-     (p, _kI) <- apply g' s bs'-     pure $ F.pExist (xts ++ yts) (psu &.& p)+-- The expression is created from its defining constraints only, while+-- @cubePred@ does expect the caller to supply the substitution at a+-- particular use of the KVar. Thus @cubePred@ produces a different+-- expression for every use site of the kvar, while here we produce one+-- expression for all the uses.+--+-- Where the cube rhs is @k[params:=xts]@, we keep the parameters free in the+-- final predicate. e.g. @params == xts && exists yts . ...@+-- That is, we only quantify out the `yts` as we want to make+-- explicit what equalities those parameters have in each cube.+--+-- Issue https://github.com/ucsd-progsys/liquid-fixpoint/issues/808 discusses+-- an example where the equalities are essential to keep.++bareCubePred :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> F.KVar -> Sol.Cube -> F.Expr+bareCubePred cfg g s k c =+    let psu = F.pAnd [ F.EEq (F.expr x) e | (x, e) <- M.toList m ]+        (p, _kI) = apply cfg g' s bs+     in F.pExist yts (p F.&.& psu)   where     bs = Sol.cuBinds c-    su = Sol.cuSubst c+    F.Su m = dropUnsortedExprs cfg g' (Sol.cuSubst c)     g' = addCEnv  g bs-    bs' = delCEnv s k bs+    bs' = F.diffIBindEnv bs (Misc.safeLookup "sScp" k (Sol.sScp s))     yts = symSorts g bs'-    sEnv = F.seSort (Sol.sEnv s) -hypPred :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.KVSub -> Sol.Hyp -> ElabM ExprInfo-hypPred g s ksu hyp =-  do cs <- traverse (cubePred g s ksu) hyp-     pure $ F.pOr *** mconcatPlus $ unzip cs+-- | At the moment, the liquid-fixpoint implementation allows for unsorted+-- expressions in substitutions. See the discussion in+-- https://github.com/ucsd-progsys/liquid-fixpoint/issues/800+-- The `explicitKvars` flag is meant for Horn-style constraints, which must+-- have well-formed (expressions) as arguments, and so we *disable* the+-- filtering of unsorted expressions when that flag is set.+dropUnsortedExprs :: Config -> CombinedEnv ann -> F.Subst -> F.Subst+dropUnsortedExprs cfg g su@(F.Su m)+  | explicitKvars cfg = su+  | otherwise         = F.Su $+    M.filter+      (\e -> isJust $ do+         t <- So.checkSortExpr sp env e+         guard (not (isClass t))+      )+      m+  where+    sp  = ceSpan g+    env = combinedSEnv g +hypPred :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> F.KVSub -> Sol.Hyp -> ExprInfo+hypPred cfg g s ksu hyp =+  let cs = map (cubePred cfg g s ksu) hyp+   in F.pOr *** mconcatPlus $ unzip cs+ {- | `cubePred g s k su c` returns the predicate for          (k . su)@@ -410,120 +407,48 @@          c := [b1,...,bn] |- (k . su') -      in the binder environment `g`.--        bs' := the subset of "extra" binders in [b1...bn] that are *not* in `g`-        p'  := the predicate corresponding to the "extra" binders-+      in the binder environment `g`. The binders in `sScp s k` are not included+      in the final predicate. They are considered redundant conjuncts as per+      section 2.4 of "Local Refinement Typing", ICFP 2017.  -}--elabExist :: F.SrcSpan -> Sol.Sol a Sol.QBind -> [(F.Symbol, F.Sort)] -> F.Expr -> ElabM F.Expr-elabExist sp s xts p =-  do ef <- ask-     let elab = So.elaborate (So.ElabParam ef (F.atLoc sp "elabExist") env)-     let xts' = [ (x, elab t) | (x, t) <- xts]-     pure $ F.pExist xts' p-  where-    env = Sol.sEnv s--cubePred :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.KVSub -> Sol.Cube -> ElabM ExprInfo-cubePred g s ksu c    =-  do ((xts,psu,p), kI) <- cubePredExc g s ksu c bs'-     e <- F.notracepp "cubePred" <$> elabExist sp s xts (psu &.& p)-     pure (e , kI)+cubePred :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> F.KVSub -> Sol.Cube -> ExprInfo+cubePred cfg g s ksu c    =+    let (p, kI) = cubePredExc cfg g s c bs'+        -- Free variables in p should not colide with those generated by+        -- the rapier substitution. If that were the case, perhaps we would+        -- need to include @combinedSEnv g@ in the scope set.+     in (F.rapierSubstExpr (F.substSymbolsSet su) su p, kI)   where-    sp  = F.srcSpan g-    bs' = delCEnv s k bs+    bs' = F.diffIBindEnv bs (Misc.safeLookup "sScp" k (Sol.sScp s))     bs  = Sol.cuBinds c     k   = F.ksuKVar ksu--type Binders = [(F.Symbol, F.Sort)]+    su = dropUnsortedExprs cfg g (F.ksuSubst  ksu)  -- | @cubePredExc@ computes the predicate for the subset of binders bs'.---   The output is a tuple, `(xts, psu, p, kI)` such that the actual predicate---   we want is `Exists xts. (psu /\ p)`.--cubePredExc :: CombinedEnv ann -> Sol.Sol a Sol.QBind -> F.KVSub -> Sol.Cube -> F.IBindEnv-            -> ElabM ((Binders, F.Pred, F.Pred), KInfo)-cubePredExc g s ksu c bs' =-  do (xts, psu)  <- substElim (Sol.sEnv s) sEnv g  k su-     (_  , psu') <- substElim (Sol.sEnv s) sEnv g' k su'-     (p', kI)    <- apply g' s bs'-     cubeE       <- elabExist sp s yts' (F.pAndNoDedup [p', psu'])-     let cubeP = (xts, psu, cubeE)-     pure (cubeP, extendKInfo kI (Sol.cuTag c))-  where--    sp              = F.srcSpan g-    yts'            = symSorts g bs'-    g'              = addCEnv  g bs-    su'             = Sol.cuSubst c-    bs              = Sol.cuBinds c-    k               = F.ksuKVar   ksu-    su              = F.ksuSubst  ksu-    sEnv            = F.insertSEnv (F.ksuVV ksu) (F.ksuSort ksu) (F.seSort $ Sol.sEnv s)---- TODO: SUPER SLOW! Decorate all substitutions with Sorts in a SINGLE pass.--{- | @substElim@ returns the binders that must be existentially quantified,-     and the equality predicate relating the kvar-"parameters" and their-     actual values. i.e. given--        K[x1 := e1]...[xn := en]--     where e1 ... en have types t1 ... tn-     we want to quantify out--       x1:t1 ... xn:tn--     and generate the equality predicate && [x1 ~~ e1, ... , xn ~~ en]-     we use ~~ because the param and value may have different sorts, see:--        tests/pos/kvar-param-poly-00.hs--     Finally, we filter out binders if they are--     1. "free" in e1...en i.e. in the outer environment.-        (Hmm, that shouldn't happen...?)--     2. are binders corresponding to sorts (e.g. `a : num`, currently used-        to hack typeclasses current.)- -}-substElim :: F.SymEnv -> F.SEnv F.Sort -> CombinedEnv a -> F.KVar -> F.Subst -> ElabM ([(F.Symbol, F.Sort)], F.Pred)-substElim syEnv sEnv g _ (F.Su m) =-    do p <- traverse (\(x, e ,t) -> mkSubst sp syEnv x (substSort sEnv x) e t) xets-       pure (xts, F.pAnd p)-  where-    xts    = [ (x, t)    | (x, _, t) <- xets, not (S.member x frees) ]-    xets   = [ (x, e, t) | (x, e)    <- xes, t <- sortOf e, not (isClass t)]-    frees  = S.fromList (concatMap (F.syms . snd) xes)-    sortOf = maybeToList . So.checkSortExpr sp env-    sp     = F.srcSpan g-    xes    = M.toList m-    env    = combinedSEnv g--substSort :: F.SEnv F.Sort -> F.Symbol -> F.Sort-substSort sEnv sym = fromMaybe (err sym) $ F.lookupSEnv sym sEnv-  where-    err x = error $ "Solution.substSort: unknown binder " ++ F.showpp x----- LH #1091-mkSubst :: F.SrcSpan -> F.SymEnv -> F.Symbol -> F.Sort -> F.Expr -> F.Sort -> ElabM F.Expr-mkSubst sp env x tx ey ty-  | tx == ty    = pure $ F.EEq ex ey-  | otherwise   = do ex' <- elabToInt sp env ex tx-                     ey' <- elabToInt sp env ey ty-                     pure $ {- F.tracepp _msg $ -} F.EEq ex' ey'+--+-- Schematically, the result is+--+-- > Exists (bindsOf bs'). (pAnd (predicatesOf bs'))[Sol.cuSubst c]+--+-- but we also preserve the information about which variables are being+-- substituted:+--+-- > Exists (bindsOf bs'). pAnd (predicatesOf bs') && x1=e1 && ... && xn=en+--+-- where @Sol.cuSubst c = [x1:=e1;...;xn:=en]@.+--+cubePredExc :: Config -> CombinedEnv ann -> Sol.Sol Sol.QBind -> Sol.Cube -> F.IBindEnv+            -> (F.Pred, KInfo)+cubePredExc cfg g s c bs' =+    let psu' = F.pAnd [ F.EEq (F.expr x) e | (x, e) <- M.toList m ]+        (p', kI) = apply cfg g' s bs'+        cubeE = F.pExist yts' (F.pAndNoDedup [p', psu'])+     in (cubeE, extendKInfo kI (Sol.cuTag c))   where-    -- _msg        = "mkSubst-DIFF: tx = " ++ F.showpp tx ++ " ty = " ++ F.showpp ty-    --                                     ++ " ex' = " ++ F.showpp ex' ++ " ey' = " ++ F.showpp ey'-    ex          = F.expr x--elabToInt :: F.SrcSpan -> F.SymEnv -> F.Expr -> F.Sort -> ElabM F.Expr-elabToInt sp env e s =-  do ef <- ask-     pure $ So.elaborate (So.ElabParam ef (F.atLoc sp "elabToInt") env) (So.toInt env e s)+    yts' = symSorts g bs'+    g' = addCEnv  g bs+    F.Su m = dropUnsortedExprs cfg g' (Sol.cuSubst c)+    bs = Sol.cuBinds c  isClass :: F.Sort -> Bool isClass F.FNum  = True@@ -539,12 +464,6 @@ addCEnv :: CombinedEnv a -> F.IBindEnv -> CombinedEnv a addCEnv g bs' = g { ceIEnv = F.unionIBindEnv (ceIEnv g) bs' } --delCEnv :: Sol.Sol a Sol.QBind -> F.KVar -> F.IBindEnv -> F.IBindEnv-delCEnv s k bs = F.diffIBindEnv bs _kbs-  where-    _kbs       = Misc.safeLookup "delCEnv" k (Sol.sScp s)- symSorts :: CombinedEnv a -> F.IBindEnv -> [(F.Symbol, F.Sort)] symSorts g bs = second F.sr_sort <$> F.envCs (ceBEnv g) bs @@ -570,11 +489,11 @@   mempty  = KI [] 0 1   mappend = (<>) -mplus :: KInfo -> KInfo -> KInfo-mplus ki ki' = (mappend ki ki') { kiCubes = kiCubes ki + kiCubes ki'}+mplusKInfo :: KInfo -> KInfo -> KInfo+mplusKInfo ki ki' = (mappend ki ki') { kiCubes = kiCubes ki + kiCubes ki'}  mconcatPlus :: [KInfo] -> KInfo-mconcatPlus = foldr mplus mempty+mconcatPlus = foldr mplusKInfo mempty  appendTags :: [Tag] -> [Tag] -> [Tag] appendTags ts ts' = Misc.sortNub (ts ++ ts')@@ -583,48 +502,145 @@ extendKInfo ki t = ki { kiTags  = appendTags [t] (kiTags  ki)                       , kiDepth = 1  +            kiDepth ki } -mrExprInfosM :: Monad m => (a -> m (b, c)) -> ([b] -> b1) -> ([c] -> c1) -> [a] -> m (b1, c1)-mrExprInfosM mF erF irF xs =-  do bcs <- traverse mF xs-     let (es, is) = unzip bcs-     pure (erF es, irF is)+-- | Simplifies existential expressions with unused or inconsequential bindings.+--+-- Simplification is helpful for human readability of solutions. It makes easier+-- reporting errors. Sometimes it can be useful for debugging if run on queries+-- sent to the SMT solver. We don't do that by default because some benchmarks+-- show a slowdown in some cases.+--+-- For instance, in the following example, "x" is not used at all.+--+-- > simplifyKVar "exists x y. y == z && y == C"+-- >   ==+-- > "exists y. y == z && y == C"+--+-- And in the following example, @x@ is used but in a way that doesn't+-- contribute any useful knowledge.+--+-- > simplifyKVar "exists x y. x == C && y == z && y == C"+-- >   ==+-- > "exists y. y == z && y == C"+--+-- Therefore we eliminate variables that appear in equalities via substitutions.+--+-- > simplifyKVar "exists x y. x == C && P && Q y"+-- >   ==+-- > "exists y. (P && Q y)[x:=C]"+--+-- The first parameter is the set of symbols that can appear free in the input+-- expression. At the moment, this only needs to include the free variables that+-- start with the @subst$@ prefix.+--+simplifyKVar :: S.HashSet F.Symbol -> F.Expr -> F.Expr+simplifyKVar s0 = F.conj . dedupByAlphaEq s0 . floatPExistConjuncts . go s0+  where+    go s (F.POr es) = disj $ map (F.conj . floatPExistConjuncts . go s) es+    go s (F.PAnd es) = F.conj $ dedupByAlphaEq S.empty $ concatMap (floatPExistConjuncts . go s) es+    go s (F.PExist bs e0) =+      let es = concatMap (floatPExistConjuncts . go (S.union s $ S.fromList $ map fst bs)) (F.conjuncts e0)+       in elimExistentialBinds (F.PExist bs (F.conj es))+    go _ e = e ------------------------------------------------------------------------------------ | `ebindInfo` constructs the information about the "ebind-definitions".----------------------------------------------------------------------------------ebindInfo :: F.SInfo a -> [(F.BindId, Sol.EbindSol)]-ebindInfo si = group [((bid, x), cons cid) | (bid, cid, x) <- ebindDefs si]-  where cons cid = void (Misc.safeLookup "ebindInfo" cid cs)-        cs = F.cm si-        cmpByFst x y = fst ( fst x ) == fst ( fst y )-        group xs = (\ys -> Bifunctor.second (Sol.EbDef (snd <$> ys)) (fst $ head ys))-                    <$> L.groupBy cmpByFst xs+    dedupByAlphaEq :: S.HashSet F.Symbol -> [F.Expr] -> [F.Expr]+    dedupByAlphaEq s = List.nubBy (\e1 e2 -> alphaEq s e1 e2) -ebindDefs :: F.SInfo a -> [(F.BindId, F.SubcId, F.Symbol)]-ebindDefs si = [ (bid, cid, x) | (cid, x) <- cDefs-                               , bid      <- maybeToList (M.lookup x ebSyms)]-  where-    ebSyms   = ebindSyms si-    cDefs    = cstrDefs  si+    disj :: [F.Expr] -> F.Expr+    disj [] = F.PFalse+    disj [e] = e+    disj es = F.POr es -ebindSyms :: F.SInfo a -> M.HashMap F.Symbol F.BindId-ebindSyms si = M.fromList [ (xi, bi) | bi        <- ebinds si-                                     , let (xi,_,_) = F.lookupBindEnv bi be ]-  where-    be       = F.bs si+    elimExistentialBinds (F.PExist bs0 (F.PExist bs1 p)) =+      let bs0' = filter (\(x,_) -> x `notElem` map fst bs1) bs0+       in elimExistentialBinds (F.PExist (bs0' ++ bs1) p)+    elimExistentialBinds (F.PExist bs e0) =+      let es = F.conjuncts e0+          esv = map (isVarEq (map fst bs)) es+          -- Eliminating multiple variables at once can be difficult if the+          -- equalities define cyclic dependencies, so we only eliminate one+          -- variable at a time.+          esvElim = take 1 [ (x, v) | (Just (x, v), _) <- esv ]+          esvKeep =+            let (xs, ys) = break (isJust . fst) esv+             in map snd (xs ++ drop 1 ys)+          su = F.mkSubst esvElim+          e' = F.rapierSubstExpr (F.substSymbolsSet su) su $ F.conj esvKeep+          bs' = filter ((`S.member` F.exprSymbolsSet e') . fst) bs+          e'' = F.pExist bs' e'+       in+          if null esvElim then e'' else elimExistentialBinds e''+    elimExistentialBinds e = e -cstrDefs :: F.SInfo a -> [(F.SubcId, F.Symbol)]-cstrDefs si = [(cid, x) | (cid, c) <- M.toList (cm si)-                        , x <- maybeToList (cstrDef be c) ]+    -- | Float out conjuncts from an existential expression that does not+    -- depend on the existentially bound variables.+    floatPExistConjuncts :: F.Expr -> [F.Expr]+    floatPExistConjuncts e0@(F.PExist bs es0) =+      let es = F.conjuncts es0+          (floatable, nonFloatable) =+           List.partition (isFloatableConjunct (S.fromList (map fst bs))) es+       in+          if null floatable then+            [e0]+          else+            elimExistentialBinds (F.pExist bs (F.conj nonFloatable)) : floatable+      where+        isFloatableConjunct :: S.HashSet F.Symbol -> F.Expr -> Bool+        isFloatableConjunct s e = S.null $ S.intersection (F.exprSymbolsSet e) s+    floatPExistConjuncts e = [e]++-- | Determine if two expressions are alpha-equivalent.+--+-- Takes as first parameter the set of variables that might appear free+-- in the expressions to compare.+--+-- Doesn't handle all cases, just enough for simplifying KVars which requires+-- alpha-equivalence checking of existentially quantified expressions.+alphaEq :: S.HashSet F.Symbol -> F.Expr -> F.Expr -> Bool+alphaEq s0 = go s0 (F.mkSubst [])   where-    be      = F.bs si+    go :: S.HashSet F.Symbol -> F.Subst -> F.Expr -> F.Expr -> Bool+    go s su (F.PExist bs1 x1) (F.PExist bs2 x2) =+      let su' =+            List.foldl'+              (\su1 (v1, v2) -> F.extendSubst su1 v1 (F.EVar v2))+              su+              (zip (map fst bs1) (map fst bs2))+       in go (S.union s (S.fromList $ map fst bs2)) su' x1 x2+    go s su (F.PAnd es1) (F.PAnd es2) =+      length es1 == length es2 && and (zipWith (go s su) es1 es2)+    go s su (F.POr es1) (F.POr es2) =+      length es1 == length es2 && and (zipWith (go s su) es1 es2)+    go s su e1 e2 =+      F.rapierSubstExpr s su e1 == e2 -cstrDef :: F.BindEnv a -> F.SimpC a -> Maybe F.Symbol-cstrDef be c-  | Just (F.EVar x) <- e = Just x-  | otherwise            = Nothing+-- | Determine if the expression is an equality that sets the value of+-- a variable in the given set.+--+-- @isVarEq fvs e@ yields @(Just (v, e'), e)@ if @v@ is in @fvs@, and @e@ has+-- the form @v == e'@.+isVarEq :: [F.Symbol] -> F.Expr -> (Maybe (F.Symbol, F.Expr), F.Expr)+isVarEq fvs ei0 = case ei0 of+  F.PAtom brel e0 e1+    | isEqRel brel ->+      let m :: Maybe (F.Symbol, F.Expr)+          m = do+            (v, ei) <- ((,e1) <$> isVarIn e0 fvs) `mplus`+                       ((,e0) <$> isVarIn e1 fvs)+            () <- guard (not (S.member v (F.exprSymbolsSet ei)))+            return (v, ei)+       in (m, ei0)+  _ ->+    (Nothing, ei0)   where-    (v,_,_)              = F.lookupBindEnv (cbind c) be-    e                    = F.notracepp _msg $ F.isSingletonExpr v rhs-    _msg                 = "cstrDef: " ++ show (stag c) ++ " crhs = " ++ F.showpp rhs-    rhs                  = V.stripCasts (crhs c)+    -- | Tells if the binary relation is an equality.+    isEqRel :: F.Brel -> Bool+    isEqRel F.Eq = True+    isEqRel F.Ueq = True+    isEqRel _ = False++    -- | @isVarIn s fvs@ yields @Just s@ if @s@ is a variable and it is in+    -- @fvs@.+    isVarIn :: F.Expr -> [F.Symbol] -> Maybe F.Symbol+    isVarIn (F.EVar s) vs+      | elem s vs = Just s+    isVarIn _ _vs = Nothing
src/Language/Fixpoint/Solver/Solve.hs view
@@ -2,6 +2,8 @@ {-# LANGUAGE FlexibleContexts  #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections     #-}  {-# OPTIONS_GHC -Wno-name-shadowing #-} @@ -9,18 +11,18 @@ -- | Solve a system of horn-clause constraints --------------------------------- -------------------------------------------------------------------------------- -module Language.Fixpoint.Solver.Solve (solve, solverInfo) where+module Language.Fixpoint.Solver.Solve (solve) where -import           Control.Monad (when, filterM)+import           Control.Monad (forM, when, filterM) import           Control.Monad.Reader-import           Control.Monad.State.Strict (modify) import           Language.Fixpoint.Misc import qualified Language.Fixpoint.Misc            as Misc import qualified Language.Fixpoint.Types           as F import qualified Language.Fixpoint.Types.Solutions as Sol import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Types.Config hiding (stats)-import           Language.Fixpoint.SortCheck          (ElabM)+import           Language.Fixpoint.SortCheck          (ElabParam(..), elaborate)+import           Language.Fixpoint.Solver.Sanitize (symbolEnv) import qualified Language.Fixpoint.Solver.Solution  as S import qualified Language.Fixpoint.Smt.Types as T import qualified Language.Fixpoint.Solver.Worklist  as W@@ -37,37 +39,67 @@ -- import qualified Data.Maybe          as Mb import qualified Data.List           as L import Language.Fixpoint.Types (resStatus, FixResult(Unsafe))-import qualified Language.Fixpoint.Types.Config as C+import Language.Fixpoint.Smt.Interface (smtComment) import Language.Fixpoint.Solver.Interpreter (instInterpreter)-import Language.Fixpoint.Solver.Instantiate (instantiate)---import Debug.Trace                      (trace)+import qualified Language.Fixpoint.Solver.PLE as PLE      (instantiate)+import Data.Maybe (maybeToList)  mytrace :: String -> a -> a-mytrace _ x = {- trace s -} x+mytrace+  -- s x = trace s x+  _ x = x+{-+solve_ :: (NFData a, F.Fixpoint a, F.Loc a)+       => Config+       -> F.SInfo a+       -> Sol.Solution+       -> W.Worklist a+       -> SolveM a (F.Result (Integer, a), Stats)+       -}+--------------------------------------------------------------------------------  ---------------------------------------------------------------------------------solve :: (NFData a, F.Fixpoint a, Show a, F.Loc a) => Config -> F.SInfo a -> IO (F.Result (Integer, a))+solve+  :: forall a. (NFData a, F.Fixpoint a, Show a, F.Loc a)+  => Config -> ElabParam -> F.SInfo a -> IO (F.Result (Integer, a)) -------------------------------------------------------------------------------- -solve cfg fi = do+solve cfg elabParam fi = do     whenLoud $ donePhase Misc.Loud "Worklist Initialize"     vb <- getVerbosity-    (res, stat) <- (if Quiet == vb || gradual cfg then id else withProgressFI sI) $ runSolverM cfg sI act+    (res, stat) <- (if Quiet == vb then id else withProgressFI sI) $ runSolverM cfg sI elabParam act     when (solverStats cfg) $ printStats fi wkl stat     -- print (numIter stat)     return res   where-    act = solve_ cfg fi s0 ks  wkl+    act :: SolveM a (F.Result (Integer, a), Stats)+    act = do+      ctx <- getContext+      let sEnv = symbolEnv cfg fi+          s1 = s0{Sol.sMap = M.map (elabQBind ctx "solve" sEnv) (Sol.sMap s0)}+      solve_ cfg fi s1 wkl+    -- solverInfo computes the set of cut and non-cut kvars, then initializes+    -- the solutions of the non-cut KVars (in the sHyp field)+    --+    -- S.init provides an initial solution for the cut KVars     sI  = solverInfo cfg fi     wkl = W.init sI-    s0  = siSol  sI+    s0  = (siSol sI) { Sol.sMap = S.init cfg fi ks }     ks  = siVars sI+    elabQBind ctx msg env (Sol.QB xs) = Sol.QB (map elabEQual xs)+      where+        elabEQual eq =+          eq { Sol.eqPred =+                elaborate+                 (ElabParam (T.ctxElabF ctx) (F.atLoc F.dummySpan msg) env)+                 (Sol.eqPred eq)+             }   -------------------------------------------------------------------------------- -- | Progress Bar ---------------------------------------------------------------------------------withProgressFI :: SolverInfo a b -> IO b -> IO b+withProgressFI :: SolverInfo a -> IO b -> IO b withProgressFI = withProgress . (+ 1) . fromIntegral . cNumScc . siDeps -------------------------------------------------------------------------------- @@ -77,38 +109,19 @@     ppTs          = putStrLn . showpp . mconcat  ---------------------------------------------------------------------------------solverInfo :: Config -> F.SInfo a -> SolverInfo a b+solverInfo :: Config -> F.SInfo a -> SolverInfo a -------------------------------------------------------------------------------- solverInfo cfg fI   | useElim cfg = E.solverInfo cfg fI   | otherwise   = SI mempty fI cD (siKvars fI)   where-    cD          = elimDeps fI (kvEdges fI) mempty mempty+    cD          = elimDeps fI (kvEdges fI) mempty  siKvars :: F.SInfo a -> S.HashSet F.KVar siKvars = S.fromList . M.keys . F.ws -doInterpret :: (F.Loc a) =>  Config -> F.SInfo a -> [F.SubcId] -> SolveM a (F.SInfo a)-doInterpret cfg fi0 subcIds = do-  fi <- liftIO $ instInterpreter cfg fi0 (Just subcIds)-  modify $ update' fi-  return fi-  where-    update' fi ss = ss{ssBinds = F.bs fi'}-      where-        fi' = (siQuery sI) {F.hoInfo = F.HOI (C.allowHO cfg) (C.allowHOqs cfg)}-        sI  = solverInfo cfg fi--{-# SCC doPLE #-}-doPLE :: (F.Loc a) =>  Config -> F.SInfo a -> [F.SubcId] -> SolveM a ()-doPLE cfg fi0 subcIds = do-  fi <- liftIO $ instantiate cfg fi0 (Just subcIds)-  modify $ update' fi-  where-    update' fi ss = ss{ssBinds = F.bs fi'}-      where-        fi' = (siQuery sI) {F.hoInfo = F.HOI (C.allowHO cfg) (C.allowHOqs cfg)}-        sI  = solverInfo cfg fi+doInterpret :: (F.Loc a) =>  Config -> F.SInfo a -> [F.SubcId] -> SolveM a (F.BindEnv a)+doInterpret cfg fi subcIds = liftIO $ instInterpreter cfg fi (Just subcIds)  -------------------------------------------------------------------------------- {-# SCC solve_ #-}@@ -116,39 +129,43 @@        => Config        -> F.SInfo a        -> Sol.Solution-       -> S.HashSet F.KVar        -> W.Worklist a        -> SolveM a (F.Result (Integer, a), Stats) ---------------------------------------------------------------------------------solve_ cfg fi s0 ks wkl = do-  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+solve_ cfg fi s2 wkl = do+  liftSMT $ smtComment "solve: start"+  (s3, res0) <- sendConcreteBindingsToSMT F.emptyIBindEnv (F.bs fi) $ \bindingsInSmt -> do     -- let s3   = solveEbinds fi s2-    s3       <- {- SCC "sol-refine" -} refine bindingsInSmt s2 wkl-    res0     <- {- SCC "sol-result" -} result bindingsInSmt cfg wkl s3+    s3       <- {- SCC "sol-refine" -} refine bindingsInSmt (F.bs fi) s2 wkl+    res0     <- {- SCC "sol-result" -} result bindingsInSmt cfg fi (W.unsatCandidates wkl) s3     return (s3, res0) -  (fi1, s4, res1) <- case resStatus res0 of  {- first run the interpreter -}-    Unsafe _ bads | not (noLazyPLE cfg) && rewriteAxioms cfg && interpreter cfg -> do-      fi1 <- doInterpret cfg fi (map fst $ mytrace ("before the Interpreter " ++ show (length bads) ++ " constraints remain") bads)-      (s4, res1) <-  sendConcreteBindingsToSMT F.emptyIBindEnv $ \bindingsInSmt -> do-        s4    <- {- SCC "sol-refine" -} refine bindingsInSmt s3 wkl-        res1  <- {- SCC "sol-result" -} result bindingsInSmt cfg wkl s4-        return (s4, res1)-      return (fi1, s4, res1)-    _ -> return  (fi, s3, mytrace "all checked before interpreter" res0)+  (fi1, res1) <- case resStatus res0 of  {- first run the interpreter -}+    Unsafe _ bads | rewriteAxioms cfg && interpreter cfg -> do+      liftSMT $ smtComment "solve: interpreter"+      bs <- doInterpret cfg fi (map fst $ mytrace ("before the Interpreter " ++ show (length bads) ++ " constraints remain") bads)+      let fi1 = fi { F.bs = bs }+          badCs = lookupCMap (F.cm fi) <$> map fst bads+      liftSMT $ smtComment "solve: pos-interpreter check"+      fmap (fi1,) $ sendConcreteBindingsToSMT F.emptyIBindEnv bs $ \bindingsInSmt ->+        result bindingsInSmt cfg fi1 badCs s3+    _ -> return  (fi, mytrace "all checked before interpreter" res0)    res2  <- case resStatus res1 of  {- then run normal PLE on remaining unsolved constraints -}-    Unsafe _ bads2 | not (noLazyPLE cfg) && rewriteAxioms cfg -> do-      doPLE cfg fi1 (map fst $ mytrace ("before z3 PLE " ++ show (length bads2) ++ " constraints remain") bads2)-      sendConcreteBindingsToSMT F.emptyIBindEnv $ \bindingsInSmt -> do-        s5    <- {- SCC "sol-refine" -} refine bindingsInSmt s4 wkl-        result bindingsInSmt cfg wkl s5+    Unsafe _ bads2 | rewriteAxioms cfg -> do+      liftSMT $ smtComment "solve: ple"+      bs <- liftSMT $ PLE.instantiate cfg fi1 (Just s3) (Just $ map fst bads2)+      -- Check the constraints one last time after PLE+      let fi2 = fi { F.bs = bs }+          badsCs2 = lookupCMap (F.cm fi) <$> map fst bads2+      liftSMT $ smtComment "solve: pos-ple check"+      sendConcreteBindingsToSMT F.emptyIBindEnv bs $ \bindingsInSmt ->+        result bindingsInSmt cfg fi2 badsCs2 s3     _ -> return $ mytrace "all checked with interpreter" res1 +  liftSMT $ smtComment "solve: finished"   st      <- stats-  let res3 = {- SCC "sol-tidy" -} tidyResult res2+  let res3 = {- SCC "sol-tidy" -} tidyResult cfg res2   return $!! (res3, st)  @@ -156,78 +173,103 @@ -- | tidyResult ensures we replace the temporary kVarArg names introduced to --   ensure uniqueness with the original names in the given WF constraints. ---------------------------------------------------------------------------------tidyResult :: F.Result a -> F.Result a-tidyResult r = r+tidyResult :: Config -> F.Result a -> F.Result a+tidyResult _ r = r   { F.resSolution = tidySolution (F.resSolution r)-  , F.resNonCutsSolution = tidySolution (F.resNonCutsSolution r)+  , F.resNonCutsSolution = M.map (fmap tidyPred) (F.resNonCutsSolution r)+  , F.resSorts = fmap tidyBind <$>  F.resSorts r   }  tidySolution :: F.FixSolution -> F.FixSolution tidySolution = fmap tidyPred +tidyBind :: (F.Symbol, F.Sort) -> (F.Symbol, F.Sort)+tidyBind (x, t) = (F.tidySymbol x, t)+ tidyPred :: F.Expr -> F.Expr-tidyPred = F.substf (F.eVar . F.tidySymbol)+tidyPred =  go+  where+    ts = F.tidySymbol+    tb = tidyBind+    go (F.EApp s e)      = F.EApp (go s) (go e)+    go (F.ELam (x,t) e)  = F.ELam (ts x, t) (go e)+    go (F.ECoerc a t e)  = F.ECoerc a t (go e)+    go (F.ENeg e)        = F.ENeg (go e)+    go (F.EBin op e1 e2) = F.EBin op (go e1) (go e2)+    go (F.ELet x e1 e2)  = F.ELet (ts x) (go e1) (go e2)+    go (F.EIte p e1 e2)  = F.EIte (go p) (go e1) (go e2)+    go (F.ECst e so)     = F.ECst (go e) so+    go (F.EVar x)        = F.EVar (ts x)+    go (F.PAnd ps)       = F.PAnd $ map go ps+    go (F.POr  ps)       = F.POr  $ map go ps+    go (F.PNot p)        = F.PNot $ go p+    go (F.PImp p1 p2)    = F.PImp (go p1) (go p2)+    go (F.PIff p1 p2)    = F.PIff (go p1) (go p2)+    go (F.PAtom r e1 e2) = F.PAtom r (go e1) (go e2)+    go (F.PExist xts e)  = F.PExist (tb <$> xts) (go e)+    go (F.PAll xts e)    = F.PAll   (tb <$> xts) (go e)+    go  p                = p  -------------------------------------------------------------------------------- {-# SCC refine #-}+-- | Implementation of the inference algorithm from:+--+-- "Liquid Types", PLDI 2008, https://ranjitjhala.github.io/static/liquid_types.pdf+-- refine-  :: (F.Loc a)+  :: forall a. F.Loc a   => F.IBindEnv+  -> F.BindEnv a   -> Sol.Solution   -> W.Worklist a   -> SolveM a Sol.Solution ---------------------------------------------------------------------------------refine bindingsInSmt s w-  | 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 (showpp s')-     let w'' = if b then W.push c w' else w'-     refine bindingsInSmt s' w''-  | otherwise = return s+refine bindingsInSmt be0 s0 w0 = go be0 s0 w0   where-    -- DEBUG-    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+    go :: F.BindEnv a -> Sol.Solution -> W.Worklist a -> SolveM a Sol.Solution+    go be s w+      | Just (c, w', newScc, rnk) <- W.pop w = do+         i       <- tickIter newScc+         (b, s') <- refineC bindingsInSmt be i s c+         lift $ writeLoud $ refineMsg i c b rnk (showpp s')+         let w'' = if b then W.push c w' else w'+         go be s' w''+      | otherwise = return s+      where+        -- DEBUG+        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 ----------------------------------------------- --------------------------------------------------------------------------- {-# SCC refineC #-} refineC-  :: (F.Loc a)+  :: forall a. (F.Loc a)   => F.IBindEnv+  -> F.BindEnv a   -> Int   -> Sol.Solution   -> F.SimpC a   -> SolveM a (Bool, Sol.Solution) ----------------------------------------------------------------------------refineC bindingsInSmt _i s c =-  do ef <- T.ctxElabF <$> getContext-     let (ks, rhs) = runReader (rhsCands s c) ef-     if null rhs+refineC bindingsInSmt be _i s c =+  do let krhs = rhsCands s+     cfg <- T.config <$> getContext+     if all (null . snd) krhs         then return (False, s)-        else do be     <- getBinds-                let lhs = runReader (S.lhsPred bindingsInSmt (F.coerceBindEnv ef be) s c) ef-                kqs    <- filterValid (cstrSpan c) lhs rhs-                return  $ S.update s ks kqs-  where-    _ci       = F.subcId c-    -- msg       = printf "refineC: iter = %d, sid = %s, soln = \n%s\n"-    --               _i (show (F.sid c)) (showpp s)-    _msg ks xs ys = printf "refineC: iter = %d, sid = %s, s = %s, rhs = %d, rhs' = %d \n"-                     _i (show _ci) (showpp ks) (length xs) (length ys)--rhsCands :: Sol.Solution -> F.SimpC a -> ElabM ([F.KVar], Sol.Cand (F.KVar, Sol.EQual))-rhsCands s c    =-  do pq <- traverse cnd ks-     pure (fst <$> ks, concat pq)+        else do+          let lhs = S.lhsPred cfg bindingsInSmt be s c+          kqs <- forM krhs $ \(k, rhs) ->+            (,) k . Sol.QB <$> filterValid (cstrSpan c) lhs rhs+          return $ S.update s kqs   where-    cnd :: (F.KVar, F.Subst) -> ElabM [(F.Pred, (F.KVar, Sol.EQual))]-    cnd (k, su) = map (\(p , q) -> (p , (k , q))) <$> Sol.qbPreds msg s su (Sol.lookupQBind s k)-    ks          = predKs . F.crhs $ c--    msg         = "rhsCands: " ++ show (F.sid c)+    rhsCands :: Sol.Solution -> [(F.KVar, Sol.Cand Sol.EQual)]+    rhsCands s = M.toList $ M.fromList $ map cnd ks+      where+        ks          = predKs . F.crhs $ c+        cnd :: (F.KVar, F.Subst) -> (F.KVar , Sol.Cand Sol.EQual)+        cnd (k, su) = (k, Sol.qbPreds su (Sol.lookupQBind s k))  predKs :: F.Expr -> [(F.KVar, F.Subst)] predKs (F.PAnd ps)    = concatMap predKs ps@@ -242,42 +284,59 @@   :: (F.Fixpoint a, F.Loc a, NFData a)   => F.IBindEnv   -> Config-  -> W.Worklist a+  -> F.SInfo a+  -> [F.SimpC a]   -> Sol.Solution   -> SolveM a (F.Result (Integer, a)) ---------------------------------------------------------------------------------result bindingsInSmt cfg wkl s =-  sendConcreteBindingsToSMT bindingsInSmt $ \bindingsInSmt2 -> do-    lift $ writeLoud "Computing Result"-    stat    <- result_ bindingsInSmt2 cfg wkl s-    lift $ whenLoud $ putStrLn $ "RESULT: " ++ show (F.sid <$> stat)--    F.Result (ci <$> stat) <$> solResult cfg s <*> solNonCutsResult s <*> return mempty+result bindingsInSmt cfg fi cs s =+  sendConcreteBindingsToSMT bindingsInSmt be $ \bindingsInSmt2 -> do+    lift       $ writeLoud "Computing Result"+    stat      <- result_ bindingsInSmt2 be cfg cs s+    lift       $ whenLoud $ putStrLn $ "RESULT: " ++ show (F.sid <$> stat)+    resCut    <- solResult cfg s+    let resNonCut = S.nonCutsResult cfg be s+        resSorts = resultSorts fi (M.keys resCut ++ M.keys resNonCut) be+    return     $ F.Result (ci <$> stat) resCut resNonCut resSorts   where     ci c = (F.subcId c, F.sinfo c)+    be = F.bs fi +resultSorts :: F.SInfo a -> [F.KVar] -> F.BindEnv a -> F.ResultSorts+resultSorts fi ks be = M.fromList+  [(k, xts)+    | k <- ks+    , xts <- maybeToList (kvarScope fi be k) ]++kvarScope :: F.SInfo a -> F.BindEnv a -> F.KVar -> Maybe [(F.Symbol, F.Sort)]+kvarScope fi be k = do+  w <- M.lookup k (F.ws fi)+  let bs = F.wenv w+  let (v, t, _) = F.wrft w+  return $ (v, t) : [ bindInfo be i | i <- L.sort (F.elemsIBindEnv bs) ]++bindInfo :: F.BindEnv a -> F.BindId -> (F.Symbol, F.Sort)+bindInfo be i = (x, F.sr_sort sr)+  where+    (x, sr, _) = F.lookupBindEnv i be+ solResult :: Config -> Sol.Solution -> SolveM ann (M.HashMap F.KVar F.Expr) solResult cfg = minimizeResult cfg . Sol.result -solNonCutsResult :: Sol.Solution -> SolveM ann (M.HashMap F.KVar F.Expr)-solNonCutsResult s = do-  be <- getBinds-  ef <- T.ctxElabF <$> getContext-  pure $ runReader (S.nonCutsResult be s) ef- result_   :: (F.Loc a, NFData a)   => F.IBindEnv+  -> F.BindEnv a   -> Config-  -> W.Worklist a+  -> [F.SimpC a]   -> Sol.Solution   -> SolveM a (F.FixResult (F.SimpC a))-result_ bindingsInSmt cfg w s = do-  filtered <- filterM (isUnsat bindingsInSmt s) cs+result_ bindingsInSmt be cfg cs0 s = do+  unsatisfiedConstraints <- filterM (isUnsat bindingsInSmt be s) cs   sts      <- stats-  pure $ res sts filtered+  pure $ res sts unsatisfiedConstraints   where-    cs          = isChecked cfg (W.unsatCandidates w)+    cs          = isChecked cfg cs0     res sts []  = F.Safe sts     res sts cs' = F.Unsafe sts cs' @@ -314,15 +373,14 @@  -------------------------------------------------------------------------------- isUnsat-  :: (F.Loc a, NFData a) => F.IBindEnv -> Sol.Solution -> F.SimpC a -> SolveM a Bool+  :: (F.Loc a, NFData a) => F.IBindEnv -> F.BindEnv a -> Sol.Solution -> F.SimpC a -> SolveM a Bool ---------------------------------------------------------------------------------isUnsat bindingsInSmt s c = do+isUnsat bindingsInSmt be s c = do   -- lift   $ printf "isUnsat %s" (show (F.subcId c))   _     <- tickIter True -- newScc-  be    <- getBinds-  ef <- T.ctxElabF <$> getContext-  let lp = runReader (S.lhsPred bindingsInSmt (F.coerceBindEnv ef be) s c) ef-  let rp = rhsPred        c+  cfg <- T.config <$> getContext+  let lp = S.lhsPred cfg bindingsInSmt be s c+      rp = rhsPred c   res   <- not <$> isValid (cstrSpan c) lp rp   lift   $ whenLoud $ showUnsat res (F.subcId c) lp rp   return res@@ -359,49 +417,3 @@   putBlankLn   donePhase Loud msg -}----- NV TODO Move to a new file----------------------------------------------------------------------------------- | Interaction with the user when Solving ---------------------------------------------------------------------------------------------------------------------_iMergePartitions :: [(Int, F.SInfo a)] -> IO [(Int, F.SInfo a)]-_iMergePartitions ifis = do-  putStrLn "Current Partitions are: "-  putStrLn $ unlines (partitionInfo <$> ifis)-  putStrLn "Merge Partitions? Y/N"-  c <- getChar-  if c == 'N'-    then do putStrLn "Solving Partitions"-            return ifis-    else do-      (i, j) <- getMergePartition (length ifis)-      _iMergePartitions (mergePartitions i j ifis)--getMergePartition :: Int -> IO (Int, Int)-getMergePartition n = do-  putStrLn "Which two partition to merge? (i, j)"-  ic <- getLine-  let (i,j) = read ic :: (Int, Int)-  if i < 1 || n < i || j < 1 || n < j-    then do putStrLn ("Invalid Partition numbers, write (i,j) with 1 <= i <= " ++ show n)-            getMergePartition n-    else return (i,j)--mergePartitions :: Int -> Int -> [(Int, F.SInfo a)] -> [(Int, F.SInfo a)]-mergePartitions i j fis-  = zip [1..] ((takei i `mappend` (takei j){F.bs = mempty}):rest)-  where-    takei i = snd (fis L.!! (i - 1))-    rest = snd <$> filter (\(k,_) -> k /= i && k /= j) fis--partitionInfo :: (Int, F.SInfo a) -> String-partitionInfo (i, fi)-  = "Partition number " ++ show i ++ "\n" ++-    "Defined ?? " ++ show defs    ++ "\n" ++-    "Used ?? "    ++ show uses-  where-    gs   = F.wloc . snd <$> L.filter (F.isGWfc . snd) (M.toList (F.ws fi))-    defs = L.nub (F.gsrc <$> gs)-    uses = L.nub (F.gused <$> gs)
src/Language/Fixpoint/Solver/UniqifyKVars.hs view
@@ -39,6 +39,7 @@ import           Language.Fixpoint.Types import           Language.Fixpoint.Types.Visitor (mapKVarSubsts) import qualified Data.HashMap.Strict as M+import qualified Data.List as L #if !MIN_VERSION_base(4,20,0) import           Data.Foldable       (foldl') #endif@@ -78,13 +79,11 @@ updateWfc :: SInfo a -> WfC a -> SInfo a updateWfc fi w    = fi'' { ws = M.insert k w' (ws fi) }   where-    w'            = updateWfCExpr (subst su) w''-    w''           = w { wenv = insertsIBindEnv newIds mempty, wrft = (v', t, k) }+    w'           = w { wenv = insertsIBindEnv newIds mempty, wrft = (v', t, k) }     (_, fi'')     = newTopBind v' (trueSortedReft t) a fi'-    (fi', newIds) = foldl' (accumBindsIfValid k a) (fi, []) (elemsIBindEnv $ wenv w)+    (fi', newIds) = foldl' (accumBindsIfValid k a) (fi, []) (L.sort $ elemsIBindEnv $ wenv w)     (v, t, k)     = wrft w     v'            = kArgSymbol v (kv k)-    su            = mkSubst ((v, EVar v'):[(x, eVar $ kArgSymbol x (kv k)) | x <- kvarDomain fi k])     a             = winfo w  accumBindsIfValid :: KVar -> a -> (SInfo a, [BindId]) -> BindId -> (SInfo a, [BindId])@@ -118,5 +117,6 @@ isValidInRefinements (FVar _)    = True isValidInRefinements (FFunc _ _) = True -- False isValidInRefinements (FAbs  _ t) = isValidInRefinements t-isValidInRefinements (FTC _)     = True --TODO is this true? seems to be required for e.g. ResolvePred.hs+isValidInRefinements (FTC _)     = True -- TODO is this true? seems to be required for e.g. ResolvePred.hs isValidInRefinements (FApp _ _)  = True+isValidInRefinements (FNatNum _) = True -- TODO probably?
src/Language/Fixpoint/Solver/Worklist.hs view
@@ -24,8 +24,8 @@ import           Prelude hiding (init) import           Language.Fixpoint.Types.PrettyPrint import qualified Language.Fixpoint.Types   as F+import           Language.Fixpoint.Types.Visitor (isConcC) import           Language.Fixpoint.Graph.Types-import           Language.Fixpoint.Graph   (isTarget)  import           Control.Arrow             (first) import qualified Data.HashMap.Strict       as M@@ -87,7 +87,7 @@ -------------------------------------------------------------------------------- -- | Initialize worklist and slice out irrelevant constraints ------------------ ---------------------------------------------------------------------------------init :: SolverInfo a b -> Worklist a+init :: SolverInfo a -> Worklist a -------------------------------------------------------------------------------- init sI    = WL { wCs     = items                 , wPend   = addPends M.empty kvarCs@@ -104,9 +104,11 @@     cd        = siDeps sI     rankm     = cRank cd     items     = S.fromList $ workItemsAt rankm 0 <$> kvarCs-    concCs    = fst <$> ics+    concCs    = fst <$> filter (isNonTriv . snd) ics     kvarCs    = fst <$> iks-    (ics,iks) = L.partition (isTarget . snd) (M.toList cm)+    (ics,iks) = L.partition (isConcC . snd) (M.toList cm)++    isNonTriv = not .  F.isTautoPred . F.crhs  --------------------------------------------------------------------------- -- | Candidate Constraints to be checked AFTER computing Fixpoint ---------
src/Language/Fixpoint/SortCheck.hs view
@@ -8,6 +8,7 @@ {-# LANGUAGE PatternGuards         #-} {-# LANGUAGE BangPatterns          #-} {-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE InstanceSigs #-}  -- | This module has the functions that perform sort-checking, and related -- operations on Fixpoint expressions and predicates.@@ -17,6 +18,8 @@     TVSubst   , Env   , mkSearchEnv+  , globalEnv+  , theoryEnv    -- * Checking Well-Formedness   , checkSorted@@ -55,6 +58,7 @@   , elabNumeric   , unApply   , unElab+  , unElabFSetBagZ3   , unElabSortedReft   , unApplySortedReft   , unApplyAt@@ -72,13 +76,13 @@ import           Control.Monad import           Control.Monad.Reader -import           Data.Bifunctor (first)+import           Data.Bifunctor (first, second) import qualified Data.IntMap.Strict       as M import qualified Data.HashSet              as S import           Data.IORef import qualified Data.List                 as L import           Data.Maybe                (mapMaybe, fromMaybe, isJust)-+import qualified Data.HashMap.Strict       as HashMap import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Misc import           Language.Fixpoint.Types hiding   (subst, GInfo(..), senv)@@ -91,6 +95,7 @@ import           GHC.Stack import qualified Language.Fixpoint.Types as F import           System.IO.Unsafe (unsafePerformIO)+import Language.Fixpoint.Types.Config (ElabFlags(elabExplicitKvars))  --import Debug.Trace as Debug @@ -133,14 +138,17 @@   }  class Elaborate a where-  elaborate :: ElabParam -> a -> a+  elaborate :: HasCallStack => ElabParam -> a -> a   instance (Loc a) => Elaborate (SInfo a) where   elaborate ep si = si     { F.cm      = elaborate ep <$> F.cm      si     , F.bs      = elaborate ep  $  F.bs      si+    , F.gLits   = coerceSort (epFlags ep) <$> F.gLits   si+    , F.dLits   = coerceSort (epFlags ep) <$> F.dLits   si     , F.asserts = elaborate ep <$> F.asserts si+    , F.defns   = elaborate ep  $ F.defns    si     , F.ddecls  = coerceDataDecl (epFlags ep) <$> F.ddecls si     } @@ -152,7 +160,7 @@   elaborate ep t = elaborate ep <$> t  instance Elaborate Sort where-  elaborate _ = go+  elaborate ep =  coerceSort (epFlags ep) . go    where       go s | isString s = strSort       go (FAbs i s)    = FAbs i  (go s)@@ -173,19 +181,34 @@     where       ep' = ep { epEnv = insertsSymEnv (epEnv ep) undefined } + instance Elaborate Equation where   elaborate ep eq = eq { eqBody = skipElabExpr ep' (eqBody eq) }     where       ep' = ep { epEnv = insertsSymEnv (epEnv ep) (eqArgs eq) } ++instance Elaborate DefinedFuns where+  elaborate ep (MkDefinedFuns eqs) = MkDefinedFuns (elabDefinedEqn ep <$> eqs)++elabDefinedEqn :: ElabParam -> Equation -> Equation+elabDefinedEqn ep eq = eq { eqBody = elaborateExpr ep' (eqBody eq) (Just t')+                          , eqArgs = [(x, tx t) | (x, t) <- eqArgs eq ]+                          , eqSort = t'+                          }+  where+    ep' = ep { epEnv = insertsSymEnv (epEnv ep) (eqArgs eq) }+    tx  = coerceSort (epFlags ep)+    t'  = tx (eqSort eq)+ instance Elaborate Expr where   elaborate p e = elaborateExpr p e Nothing -elaborateExpr :: ElabParam -> Expr -> Maybe Sort -> Expr+elaborateExpr :: HasCallStack => ElabParam -> Expr -> Maybe Sort -> Expr elaborateExpr (ElabParam ef msg env) e t =-    elabNumeric . elabApply env' . elabExpr (ElabParam ef msg env') t . elabFMap . (if Cfg.elabSetBag ef then elabFSetBagZ3 else id) $ e-      where-        env' = coerceEnv ef env+  elabNumeric . elabApply env' . elabExpr (ElabParam ef msg env') t .  elabSorts ef . elabFMap . (if Cfg.elabSetBag ef then elabFSetBagZ3 else id) $ e+    where+      env' = coerceEnv ef env  skipElabExpr :: ElabParam -> Expr -> Expr skipElabExpr ep e = case elabExprE ep Nothing e of@@ -213,7 +236,7 @@       = e  instance Elaborate SortedReft where-  elaborate ep (RR s (Reft (v, e))) = RR s (Reft (v, e'))+  elaborate ep (RR s (Reft (v, e))) = RR (coerceSort (epFlags ep) s) (Reft (v, e'))     where       e'   = elaborateExpr ep' e (Just boolSort) -- check that a SortedReft is in fact a bool       ep' = ep { epEnv = insertSymEnv v s (epEnv ep) }@@ -248,6 +271,7 @@ elabFMap (EApp e1 e2)      = EApp (elabFMap e1) (elabFMap e2) elabFMap (ENeg e)          = ENeg (elabFMap e) elabFMap (EBin b e1 e2)    = EBin b (elabFMap e1) (elabFMap e2)+elabFMap (ELet x e1 e2)    = ELet x (elabFMap e1) (elabFMap e2) elabFMap (EIte e1 e2 e3)   = EIte (elabFMap e1) (elabFMap e2) (elabFMap e3) elabFMap (ECst e t)        = ECst (elabFMap e) t elabFMap (ELam b e)        = ELam b (elabFMap e)@@ -261,79 +285,184 @@ elabFMap (PAtom r e1 e2)   = PAtom r (elabFMap e1) (elabFMap e2) elabFMap (PAll   bs e)     = PAll bs (elabFMap e) elabFMap (PExist bs e)     = PExist bs (elabFMap e)-elabFMap (PGrad  k su i e) = PGrad k su i (elabFMap e) elabFMap (ECoerc a t e)    = ECoerc a t (elabFMap e)+elabFMap (PKVar k (Su m))  = PKVar k (Su (elabFMap <$> m)) elabFMap e                 = e + elabFSetBagZ3 :: Expr -> Expr-elabFSetBagZ3 (EApp h@(EVar f) e)-  | f == Thy.setEmpty         = EApp (EVar Thy.arrConstS) PFalse-  | f == Thy.setEmp           = PAtom Eq (EApp (EVar Thy.arrConstS) PFalse) (elabFSetBagZ3 e)-  | f == Thy.setSng           = EApp (EApp (EApp (EVar Thy.arrStoreS) (EApp (EVar Thy.arrConstS) PFalse)) (elabFSetBagZ3 e)) PTrue-  | f == Thy.setCom           = EApp (EVar Thy.arrMapNotS) (elabFSetBagZ3 e)-  | f == Thy.bagEmpty         = EApp (EVar Thy.arrConstB) (ECon (I 0))-  | otherwise                 = EApp (elabFSetBagZ3 h) (elabFSetBagZ3 e)-elabFSetBagZ3 (EApp (EApp h@(EVar f) e1) e2)-  | f == Thy.setMem           = EApp (EApp (EVar Thy.arrSelectS) (elabFSetBagZ3 e2)) (elabFSetBagZ3 e1)-  | f == Thy.setCup           = EApp (EApp (EVar Thy.arrMapOrS) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-  | f == Thy.setCap           = EApp (EApp (EVar Thy.arrMapAndS) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-  | f == Thy.setAdd           = EApp (EApp (EApp (EVar Thy.arrStoreS) (elabFSetBagZ3 e2)) (elabFSetBagZ3 e1)) PTrue-  -- A \ B == A /\ ~B == ~(A => B)-  | f == Thy.setDif           = EApp (EApp (EVar Thy.arrMapAndS) (elabFSetBagZ3 e1)) (EApp (EVar Thy.arrMapNotS) (elabFSetBagZ3 e2))-  | f == Thy.setSub           = PAtom Eq (EApp (EVar Thy.arrConstS) PTrue) (EApp (EApp (EVar Thy.arrMapImpS) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2))-  | f == Thy.bagCount         = EApp (EApp (EVar Thy.arrSelectB) (elabFSetBagZ3 e2)) (elabFSetBagZ3 e1)-  | f == Thy.bagSng           = EApp (EApp (EApp (EVar Thy.arrStoreB) (EApp (EVar Thy.arrConstB) (ECon (I 0)))) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-  | f == Thy.bagCup           = EApp (EApp (EVar Thy.arrMapPlusB) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-  | f == Thy.bagSub           = PAtom Eq (EApp (EVar Thy.arrConstS) PTrue) (EApp (EApp (EVar Thy.arrMapLeB) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2))-  | f == Thy.bagMax           = EApp (EApp (EApp (EVar Thy.arrMapIteB) (EApp (EApp (EVar Thy.arrMapGtB) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2))) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-  | f == Thy.bagMin           = EApp (EApp (EApp (EVar Thy.arrMapIteB) (EApp (EApp (EVar Thy.arrMapLeB) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2))) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-  | otherwise                 = EApp (EApp (elabFSetBagZ3 h) (elabFSetBagZ3 e1)) (elabFSetBagZ3 e2)-elabFSetBagZ3 (EApp e1 e2)      = EApp (elabFSetBagZ3 e1) (elabFSetBagZ3 e2)-elabFSetBagZ3 (ENeg e)          = ENeg (elabFSetBagZ3 e)-elabFSetBagZ3 (EBin b e1 e2)    = EBin b (elabFSetBagZ3 e1) (elabFSetBagZ3 e2)-elabFSetBagZ3 (EIte e1 e2 e3)   = EIte (elabFSetBagZ3 e1) (elabFSetBagZ3 e2) (elabFSetBagZ3 e3)-elabFSetBagZ3 (ECst e t)        = ECst (elabFSetBagZ3 e) t-elabFSetBagZ3 (ELam b e)        = ELam b (elabFSetBagZ3 e)-elabFSetBagZ3 (ETApp e t)       = ETApp (elabFSetBagZ3 e) t-elabFSetBagZ3 (ETAbs e t)       = ETAbs (elabFSetBagZ3 e) t-elabFSetBagZ3 (PAnd es)         = PAnd (elabFSetBagZ3 <$> es)-elabFSetBagZ3 (POr es)          = POr (elabFSetBagZ3 <$> es)-elabFSetBagZ3 (PNot e)          = PNot (elabFSetBagZ3 e)-elabFSetBagZ3 (PImp e1 e2)      = PImp (elabFSetBagZ3 e1) (elabFSetBagZ3 e2)-elabFSetBagZ3 (PIff e1 e2)      = PIff (elabFSetBagZ3 e1) (elabFSetBagZ3 e2)-elabFSetBagZ3 (PAtom r e1 e2)   = PAtom r (elabFSetBagZ3 e1) (elabFSetBagZ3 e2)-elabFSetBagZ3 (PAll   bs e)     = PAll bs (elabFSetBagZ3 e)-elabFSetBagZ3 (PExist bs e)     = PExist bs (elabFSetBagZ3 e)-elabFSetBagZ3 (PGrad  k su i e) = PGrad k su i (elabFSetBagZ3 e)-elabFSetBagZ3 (ECoerc a t e)    = ECoerc a t (elabFSetBagZ3 e)-elabFSetBagZ3 e                 = e+elabFSetBagZ3 = go+  where+    go (EApp h@(EVar f) e)+      | f == Thy.setEmpty = EApp (EVar Thy.arrConstS) PFalse+      | f == Thy.setEmp   = PAtom Eq (EApp (EVar Thy.arrConstS) PFalse) (go e)+      | f == Thy.setSng   = EApp (EApp (EApp (EVar Thy.arrStoreS) (EApp (EVar Thy.arrConstS) PFalse)) (go e)) PTrue+      | f == Thy.setCom   = EApp (EVar Thy.arrMapNotS) (go e)+      | f == Thy.bagEmpty = EApp (EVar Thy.arrConstB) (ECon (I 0))+      | otherwise         = EApp (go h) (go e)+    go (EApp (EApp h@(EVar f) e1) e2)+      | f == Thy.setMem   = EApp (EApp (EVar Thy.arrSelectS) (go e2)) (go e1)+      | f == Thy.setCup   = EApp (EApp (EVar Thy.arrMapOrS) (go e1)) (go e2)+      | f == Thy.setCap   = EApp (EApp (EVar Thy.arrMapAndS) (go e1)) (go e2)+      | f == Thy.setAdd   = EApp (EApp (EApp (EVar Thy.arrStoreS) (go e2)) (go e1)) PTrue+      -- A \ B == A /\ ~B == ~(A => B)+      | f == Thy.setDif   = EApp (EApp (EVar Thy.arrMapAndS) (go e1)) (EApp (EVar Thy.arrMapNotS) (go e2))+      | f == Thy.setSub   = PAtom Eq (EApp (EVar Thy.arrConstS) PTrue) (EApp (EApp (EVar Thy.arrMapImpS) (go e1)) (go e2))+      | f == Thy.bagCount = EApp (EApp (EVar Thy.arrSelectB) (go e2)) (go e1)+      | f == Thy.bagSng   = EApp (EApp (EApp (EVar Thy.arrStoreB) (EApp (EVar Thy.arrConstB) (ECon (I 0)))) (go e1)) (go e2)+      | f == Thy.bagCup   = EApp (EApp (EVar Thy.arrMapPlusB) (go e1)) (go e2)+      | f == Thy.bagSub   = PAtom Eq (EApp (EVar Thy.arrConstS) PTrue) (EApp (EApp (EVar Thy.arrMapLeB) (go e1)) (go e2))+      | f == Thy.bagMax   = EApp (EApp (EApp (EVar Thy.arrMapIteB) (EApp (EApp (EVar Thy.arrMapGtB) (go e1)) (go e2))) (go e1)) (go e2)+      | f == Thy.bagMin   = EApp (EApp (EApp (EVar Thy.arrMapIteB) (EApp (EApp (EVar Thy.arrMapLeB) (go e1)) (go e2))) (go e1)) (go e2)+      | otherwise         = EApp (EApp (go h) (go e1)) (go e2)+    go (EApp e1 e2)       = EApp   (go e1) (go e2)+    go (ENeg e)           = ENeg   (go e)+    go (EBin b e1 e2)     = EBin b (go e1) (go e2)+    go (ELet x e1 e2)     = ELet x (go e1) (go e2)+    go (EIte e1 e2 e3)    = EIte   (go e1) (go e2) (go e3)+    go (ECst e t)         = ECst   (go e) t+    go (ELam b e)         = ELam b (go e)+    go (ETApp e t)        = ETApp  (go e) t+    go (ETAbs e t)        = ETAbs  (go e) t+    go (PAnd es)          = PAnd   (go <$> es)+    go (POr es)           = POr    (go <$> es)+    go (PNot e)           = PNot   (go e)+    go (PImp e1 e2)       = PImp   (go e1) (go e2)+    go (PIff e1 e2)       = PIff   (go e1) (go e2)+    go (PAtom r e1 e2)    = PAtom r (go e1) (go e2)+    go (PAll   bs e)      = PAll bs (go e)+    go (PExist bs e)      = PExist bs (go e)+    go (ECoerc a t e)     = ECoerc a t (go e)+    go (PKVar k (Su m))   = PKVar k (Su (go <$> m))+    go e                  = e +-- | Reverse transformation of elabFSetBagZ3: converts array representations back to set/bag operations+unElabFSetBagZ3 :: Expr -> Expr+unElabFSetBagZ3 = go+  where+    -- arr_const_s false -> Set_empty+    go (EApp (EVar f) PFalse)+      | f == Thy.arrConstS = EVar Thy.setEmpty+    -- arr_const_s false == e -> Set_emp e+    go (PAtom Eq (EApp (EVar f) PFalse) e)+      | f == Thy.arrConstS = EApp (EVar Thy.setEmp) (go e)+    -- arr_store_s (arr_const_s false) e true -> Set_sng e+    go (EApp (EApp (EApp (EVar f1) (EApp (EVar f2) PFalse)) e) PTrue)+      | f1 == Thy.arrStoreS && f2 == Thy.arrConstS = EApp (EVar Thy.setSng) (go e)+    -- arr_map_not_s e -> Set_com e+    go (EApp (EVar f) e)+      | f == Thy.arrMapNotS = EApp (EVar Thy.setCom) (go e)+    -- arr_const_b 0 -> Bag_empty+    go (EApp (EVar f) (ECon (I 0)))+      | f == Thy.arrConstB = EVar Thy.bagEmpty+    -- arr_select_s e2 e1 -> Set_mem e1 e2+    go (EApp (EApp (EVar f) e2) e1)+      | f == Thy.arrSelectS = EApp (EApp (EVar Thy.setMem) (go e1)) (go e2)+    -- arr_map_or_s e1 e2 -> Set_cup e1 e2+    go (EApp (EApp (EVar f) e1) e2)+      | f == Thy.arrMapOrS = EApp (EApp (EVar Thy.setCup) (go e1)) (go e2)+    -- arr_map_and_s e1 e2 -> Set_cap e1 e2+    go (EApp (EApp (EVar f) e1) e2)+      | f == Thy.arrMapAndS = EApp (EApp (EVar Thy.setCap) (go e1)) (go e2)+    -- arr_store_s e2 e1 true -> Set_add e1 e2+    go (EApp (EApp (EApp (EVar f) e2) e1) PTrue)+      | f == Thy.arrStoreS = EApp (EApp (EVar Thy.setAdd) (go e1)) (go e2)+    -- arr_map_and_s e1 (arr_map_not_s e2) -> Set_dif e1 e2+    go (EApp (EApp (EVar f1) e1) (EApp (EVar f2) e2))+      | f1 == Thy.arrMapAndS && f2 == Thy.arrMapNotS = EApp (EApp (EVar Thy.setDif) (go e1)) (go e2)+    -- arr_const_s true == arr_map_imp_s e1 e2 -> Set_sub e1 e2+    go (PAtom Eq (EApp (EVar f1) PTrue) (EApp (EApp (EVar f2) e1) e2))+      | f1 == Thy.arrConstS && f2 == Thy.arrMapImpS = EApp (EApp (EVar Thy.setSub) (go e1)) (go e2)+    -- arr_select_b e2 e1 -> Bag_count e1 e2+    go (EApp (EApp (EVar f) e2) e1)+      | f == Thy.arrSelectB = EApp (EApp (EVar Thy.bagCount) (go e1)) (go e2)+    -- arr_store_b (arr_const_b 0) e1 e2 -> Bag_sng e1 e2+    go (EApp (EApp (EApp (EVar f1) (EApp (EVar f2) (ECon (I 0)))) e1) e2)+      | f1 == Thy.arrStoreB && f2 == Thy.arrConstB = EApp (EApp (EVar Thy.bagSng) (go e1)) (go e2)+    -- arr_map_plus_b e1 e2 -> Bag_cup e1 e2+    go (EApp (EApp (EVar f) e1) e2)+      | f == Thy.arrMapPlusB = EApp (EApp (EVar Thy.bagCup) (go e1)) (go e2)+    -- arr_const_s true == arr_map_le_b e1 e2 -> Bag_sub e1 e2+    go (PAtom Eq (EApp (EVar f1) PTrue) (EApp (EApp (EVar f2) e1) e2))+      | f1 == Thy.arrConstS && f2 == Thy.arrMapLeB = EApp (EApp (EVar Thy.bagSub) (go e1)) (go e2)+    -- arr_map_ite_b (arr_map_gt_b e1 e2) e1 e2 -> Bag_max e1 e2+    go (EApp (EApp (EApp (EVar f1) (EApp (EApp (EVar f2) e1a) e2a)) e1b) e2b)+      | f1 == Thy.arrMapIteB && f2 == Thy.arrMapGtB && e1a == e1b && e2a == e2b+      = EApp (EApp (EVar Thy.bagMax) (go e1a)) (go e2a)+    -- arr_map_ite_b (arr_map_le_b e1 e2) e1 e2 -> Bag_min e1 e2+    go (EApp (EApp (EApp (EVar f1) (EApp (EApp (EVar f2) e1a) e2a)) e1b) e2b)+      | f1 == Thy.arrMapIteB && f2 == Thy.arrMapLeB && e1a == e1b && e2a == e2b+      = EApp (EApp (EVar Thy.bagMin) (go e1a)) (go e2a)+    -- Recursive cases+    go (EApp e1 e2)       = EApp   (go e1) (go e2)+    go (ENeg e)           = ENeg   (go e)+    go (EBin b e1 e2)     = EBin b (go e1) (go e2)+    go (ELet x e1 e2)     = ELet x (go e1) (go e2)+    go (EIte e1 e2 e3)    = EIte   (go e1) (go e2) (go e3)+    go (ECst e t)         = ECst   (go e) t+    go (ELam b e)         = ELam b (go e)+    go (ETApp e t)        = ETApp  (go e) t+    go (ETAbs e t)        = ETAbs  (go e) t+    go (PAnd es)          = PAnd   (go <$> es)+    go (POr es)           = POr    (go <$> es)+    go (PNot e)           = PNot   (go e)+    go (PImp e1 e2)       = PImp   (go e1) (go e2)+    go (PIff e1 e2)       = PIff   (go e1) (go e2)+    go (PAtom r e1 e2)    = PAtom r (go e1) (go e2)+    go (PAll   bs e)      = PAll bs (go e)+    go (PExist bs e)      = PExist bs (go e)+    go (ECoerc a t e)     = ECoerc a t (go e)+    go (PKVar k (Su m))   = PKVar k (Su (go <$> m))+    go e                  = e+++elabSorts :: Cfg.ElabFlags -> Expr -> Expr+elabSorts ef (EApp e1 e2)      = EApp (elabSorts ef e1) (elabSorts ef e2)+elabSorts ef (ENeg e)          = ENeg (elabSorts ef e)+elabSorts ef (EBin b e1 e2)    = EBin b (elabSorts ef e1) (elabSorts ef e2)+elabSorts ef (ELet x e1 e2)    = ELet x (elabSorts ef e1) (elabSorts ef e2)+elabSorts ef (EIte e1 e2 e3)   = EIte (elabSorts ef e1) (elabSorts ef e2) (elabSorts ef e3)+elabSorts ef (ECst e s)        = ECst (elabSorts ef e) (coerceSort ef s)+elabSorts ef (ELam b e)        = ELam b (elabSorts ef e)+elabSorts ef (ETApp e s)       = ETApp (elabSorts ef e) (coerceSort ef s)+elabSorts ef (ETAbs e t)       = ETAbs (elabSorts ef e) t+elabSorts ef (PAnd es)         = PAnd (elabSorts ef <$> es)+elabSorts ef (POr es)          = POr (elabSorts ef <$> es)+elabSorts ef (PNot e)          = PNot (elabSorts ef e)+elabSorts ef (PImp e1 e2)      = PImp (elabSorts ef e1) (elabSorts ef e2)+elabSorts ef (PIff e1 e2)      = PIff (elabSorts ef e1) (elabSorts ef e2)+elabSorts ef (PAtom r e1 e2)   = PAtom r (elabSorts ef e1) (elabSorts ef e2)+elabSorts ef (PAll   bs e)     = PAll bs (elabSorts ef e)+elabSorts ef (PExist bs e)     = PExist bs (elabSorts ef e)+elabSorts ef (ECoerc s1 s2 e)  = ECoerc (coerceSort ef s1) (coerceSort ef s2) (elabSorts ef e)+elabSorts ef (PKVar k (Su m))  = PKVar k (Su (elabSorts ef <$> m))+elabSorts _ e                 = e+ -------------------------------------------------------------------------------- -- | 'elabExpr' adds "casts" to decorate polymorphic instantiation sites. ---------------------------------------------------------------------------------elabExpr :: ElabParam -> Maybe Sort -> Expr ->  Expr+elabExpr :: HasCallStack => ElabParam -> Maybe Sort -> Expr -> Expr elabExpr ep t e = case elabExprE ep t e of   Left ex  -> die ex   Right e' -> F.notracepp ("elabExp " ++ showpp e) e' -validateSort :: Sort -> Maybe Sort -> CheckM ()-validateSort t (Just t')-  | t == t'            = return ()-  | otherwise          = throwErrorAt $ printf "unexpected sort: got `%s` but expected `%s`" (showpp t) (showpp t')-validateSort _ Nothing = return ()+validateSort :: Env -> Sort -> Maybe Sort -> CheckM ()+-- validateSort f t (Just t') = void (unifys f (tracepp ("validateSort" ++ show (t, t')) Nothing) [t] [t'])+validateSort f t (Just t') = void (unifys f Nothing [t] [t'])+validateSort _ _ Nothing   = return ()  elabExprE :: ElabParam -> Maybe Sort -> Expr -> Either Error Expr elabExprE (ElabParam ef msg env) t e =   case runCM0 (srcSpan msg) (Just ef) $ do     (!e', eSort) <- elab (env, envLookup) e-    validateSort eSort t+    validateSort envLookup eSort t     finalThetaRef <- asks chTVSubst     finalTheta <- liftIO $ readIORef finalThetaRef     return (applyExpr finalTheta e') of     Left (ChError f') ->       let e' = f' ()       in Left $ err (srcSpan e') (d (val e'))-    Right s  -> Right s+    Right elab_e -> Right elab_e   where     sEnv = seSort env     envLookup = (`lookupSEnvWithDistance` sEnv)@@ -359,6 +488,7 @@     step (POr [])         = PFalse     step (ENeg e)         = ENeg (go  e)     step (EBin o e1 e2)   = EBin o (go e1) (go e2)+    step (ELet x e1 e2)   = ELet x (go e1) (go e2)     step (EIte e1 e2 e3)  = EIte (go e1) (go e2) (go e3)     step (ECst e t)       = ECst (go e) t     step (PAnd ps)        = PAnd (go <$> ps)@@ -372,8 +502,7 @@     step e@EApp {}        = 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 (PKVar k (Su m)) = PKVar k (Su (go <$> m))     step e@ESym{}         = e     step e@ECon{}         = e     step e@EVar{}         = e@@ -465,7 +594,7 @@ runCM0 :: SrcSpan -> Maybe Cfg.ElabFlags -> CheckM a -> Either ChError a runCM0 sp mef act = unsafePerformIO $ do   ref <- newIORef Nothing-  try (runReaderT act (ChS varCounterRef sp (fromMaybe (Cfg.ElabFlags False) mef) ref))+  try (runReaderT act (ChS varCounterRef sp (fromMaybe (Cfg.ElabFlags False False) mef) ref))  fresh :: CheckM Int fresh = do@@ -568,6 +697,7 @@ 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 (ELet x e1 e2)  = checkLet f x e1 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@@ -578,7 +708,6 @@ 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@@ -606,6 +735,10 @@   let !result = EBin o (eCst e1' s1) (eCst e2' s2)   return (result, s) +elab !f (ECst (EApp !e1 !e2) t) = do+   ee <- elabAppAs f t e1 e2+   return (eCst ee t, t)+ elab !f (EApp !e1 !e2) = do   (!e1', !s1, !e2', !s2, !s) <- elabEApp f e1 e2   let !e = eAppC s (eCst e1' s1) (eCst e2' s2)@@ -623,12 +756,19 @@ elab !_ e@(ECon (L _ !s)) =   return (e, s) -elab !_ e@(PKVar _ _) =-  return (e, boolSort)--elab !f (PGrad !k !su !i !e) = do-  (!e', !_) <- elab f e-  return (PGrad k su i e', boolSort)+-- TODO: the guard below is because some LH tests generate PKVar with ill-sorted substitutions.+-- However, a cleaner solution could be to modify `Sanitize.restrictKVarDomain` to simply+-- those ill-sorted substitutions right up at the outset.+elab !f e@(PKVar k (Su m)) = do+  expKvars <- asks (elabExplicitKvars . chElabF)+  if expKvars+    then do+      xargs' <- forM (HashMap.toList m) $ \(x, arg) -> do+        (arg', _) <- elab f arg+        return (x, arg')+      return (PKVar k (Su (HashMap.fromList xargs')), boolSort)+    else+      return (e, boolSort)  elab (!_, !f) e@(EVar !x) = do   !cs <- checkSym f x@@ -653,6 +793,11 @@   !s          <- checkIteTy g p e1' e2' s1 s2   return (EIte p' (eCst e1' s) (eCst e2' s), s) +elab f (ELet !x !e1 !e2) = do+  (!e1', !t1) <- elab f e1+  (!e2', !t2) <- elab (elabAddEnv f [(x, t1)]) e2+  return (ELet x e1' e2', t2)+ elab !f (ECst !e !t) = do   (!e', !_) <- elab f e   return (eCst e' t, t)@@ -729,11 +874,11 @@  -- | 'eCstAtom' is to support tests like `tests/pos/undef00.fq` eCstAtom :: ElabEnv -> Expr -> Sort -> CheckM Expr-eCstAtom f@(sym,g) (EVar x) t+eCstAtom f@(sym,g) (ECst (EVar x) _) t   | Found s <- g x   , isUndef s-  , not (isNum sym t) = (`ECst` t) <$> elabAs f t (EApp (eVar tyCastName) (eVar x))-eCstAtom _ e t = return (ECst e t)+  , not (isNum sym t) = (`eCst` t) <$> elabAppAs f t (eVar tyCastName) (eVar x)+eCstAtom _ e t = return (eCst e t)  isUndef :: Sort -> Bool isUndef s = case bkAbs s of@@ -747,8 +892,8 @@ 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'+    go (EApp e1 e2)    = elabAppAs f t e1 e2+    go e'              = fst <$> elab f (eCst e' t)  -- DUPLICATION with `checkApp'` elabAppAs :: ElabEnv -> Sort -> Expr -> Expr -> CheckM Expr@@ -762,7 +907,7 @@   g'       <- elabAs env tg g   let te    = apply su eT   e'       <- elabAs env te e-  pure     $ 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@@ -845,6 +990,7 @@     go (ECst (EApp (EApp f e1) e2) _)       | Just _ <- unApplyAt f = EApp e1 e2     go (ELam (x,s) e)         = ELam (x, Vis.mapSort go' s) e+    go (PExist bs e)          = PExist (map (second (Vis.mapSort go')) bs) e     go e                      = e      go' (FApp (FApp fs t1) t2) | fs == funcSort@@ -1048,6 +1194,12 @@     negSort (FApp s1 s2)     = negSort s1 `S.union` negSort s2     negSort _                = S.empty +-- | Helper for checking let expressions+checkLet :: Env -> Symbol -> Expr -> Expr -> CheckM Sort+checkLet f x e1 e2 = do+  t <- checkExpr f e1+  checkExpr (addEnv f [(x, t)]) e2+ -- | Helper for checking if-then-else expressions checkIte :: Env -> Expr -> Expr -> Expr -> CheckM Sort checkIte f p e1 e2 = do@@ -1212,6 +1364,19 @@ checkRelTy f e Ne t1 t2      = void (unifys f (Just e) [t1] [t2] `withError` errRel e t1 t2) checkRelTy _ e _  t1 t2      = unless (t1 == t2) (throwErrorAt $ errRel e t1 t2) +-- | @a ~~ b@ is translated to @(= a b)@ when producing SMTLIB.+-- But this is only valid if @a@ and @b@ have the same sort in SMTLIB.+-- It turns out that most types are represented with sort Int, so comparing+-- values of different types is not rejected in general by SMT solvers.+--+-- There are at least two exceptions though. The first of them is the type+-- Bool, which is represented with the sort Bool. Therefore, @a ~~ b@ is fine+-- if both arguments have Bool sort, or if neither of them has.+--+-- The other exception is functions, which have a function sort in SMTLIB.+-- But at the moment no @~~@ equalities are produced with function sorts, so+-- that case isn't considered in this function.+-- checkURel :: Expr -> Sort -> Sort -> CheckM () checkURel e s1 s2 = unless (b1 == b2) (throwErrorAt $ errRel e s1 s2)   where@@ -1544,3 +1709,14 @@  errBoolSort :: Expr -> Sort -> String errBoolSort     e s  = printf "Expressions %s should have bool sort, but has %s" (showpp e) (showpp s)++globalEnv :: Cfg.Config -> F.GInfo c a -> SEnv Sort+globalEnv cfg finfo = F.gLits finfo <> dataEnv+  where+    dataEnv = F.tsSort <$> theoryEnv cfg finfo++theoryEnv :: Cfg.Config -> F.GInfo c a -> F.SEnv F.TheorySymbol+theoryEnv cfg si+  =  Thy.theorySymbols (Cfg.solver cfg)+  <> Thy.theorySymbols (F.defns si)+  <> Thy.theorySymbols (F.ddecls si)
src/Language/Fixpoint/Types.hs view
@@ -5,6 +5,7 @@  module Language.Fixpoint.Types (module X) where +import Language.Fixpoint.Types.SMTPrint      as X import Language.Fixpoint.Types.PrettyPrint      as X import Language.Fixpoint.Types.Names            as X import Language.Fixpoint.Types.Errors           as X
src/Language/Fixpoint/Types/Config.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE UndecidableInstances      #-} {-# LANGUAGE DeriveGeneric             #-}+{-# LANGUAGE TemplateHaskell           #-}  module Language.Fixpoint.Types.Config (     Config  (..)@@ -13,7 +14,7 @@    -- * SMT Solver options   , SMTSolver (..)-  , solverFlags+  , solverFlags, mkElabFlags   , ElabFlags (..)    -- REST Options@@ -45,7 +46,9 @@  import qualified Language.Fixpoint.Conditional.Z3 as Conditional.Z3 import Language.Fixpoint.Utils.Files-+import Development.GitRev (gitHash)+import Data.Version (showVersion)+import Paths_liquid_fixpoint (version)  -------------------------------------------------------------------------------- withPragmas :: Config -> [String] -> IO Config@@ -75,7 +78,6 @@   , 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@@ -94,30 +96,27 @@   , minimizeKs  :: Bool                -- ^ min .fq by delta debug (sat with min kvars)   , minimalSol  :: Bool                -- ^ shrink final solution by pruning redundant qualfiers from fixpoint   , etaElim     :: Bool                -- ^ eta eliminate function definitions-  , gradual     :: Bool                -- ^ solve "gradual" constraints-  , ginteractive :: Bool                -- ^ interactive gradual solving   , 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-  , pleWithUndecidedGuards :: Bool     -- ^ Unfold invocations with undecided guards in PLE+  , pleUndecGuards   :: Bool           -- ^ Unfold invocations with undecided guards in PLE   , etabeta          :: Bool           -- ^ Eta expand and beta reduce terms to aid PLE   , localRewrites    :: Bool           -- ^ Eta expand and beta reduce terms to aid PLE   , interpreter      :: Bool           -- ^ Do not use the interpreter to assist PLE-  , oldPLE           :: Bool           -- ^ Use old version of PLE-  , noIncrPle        :: Bool           -- ^ Use incremental PLE-  , noEnvironmentReduction :: Bool     -- ^ Don't use environment reduction-  , inlineANFBindings :: Bool          -- ^ Inline ANF bindings.+  , noEnvReduction   :: Bool     -- ^ Don't use environment reduction+  , inlineANFBinds   :: Bool          -- ^ Inline ANF bindings.                                        -- Sometimes improves performance and sometimes worsens it.   , checkCstr        :: [Integer]      -- ^ Only check these specific constraints   , extensionality   :: Bool           -- ^ Enable extensional interpretation of function equality-  , rwTerminationCheck  :: Bool        -- ^ Enable termination checking for rewriting+  , rwTermination    :: Bool        -- ^ Enable termination checking for rewriting   , stdin               :: Bool        -- ^ Read input query from stdin   , json                :: Bool        -- ^ Render output in JSON format-  , 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+  , noStringTheory :: Bool             -- ^ disable interpretation of string theory by SMT+  , explicitKvars  :: Bool             -- ^ use explicitly declared kvars (horn style) which disables several "defensive simplifications"   } deriving (Eq,Data,Typeable,Show,Generic)  instance Default Config where@@ -151,13 +150,18 @@ data SMTSolver = Z3 | Z3mem | Cvc4 | Cvc5 | Mathsat                  deriving (Eq, Data, Typeable, Generic) -newtype ElabFlags = ElabFlags { elabSetBag :: Bool }+data ElabFlags = ElabFlags { elabSetBag :: Bool, elabExplicitKvars :: Bool } -solverFlags :: SMTSolver -> ElabFlags-solverFlags Z3    = ElabFlags True-solverFlags Z3mem = ElabFlags True-solverFlags _     = ElabFlags False+mkElabFlags :: SMTSolver -> Bool -> ElabFlags+mkElabFlags slv expKvars = ElabFlags (setBag slv) expKvars+  where+    setBag Z3    = True+    setBag Z3mem = True+    setBag _     = False +solverFlags :: Config -> ElabFlags+solverFlags cfg = mkElabFlags (solver cfg) (explicitKvars cfg)+ instance Default SMTSolver where   def = if Conditional.Z3.builtWithZ3AsALibrary then Z3mem else Z3 @@ -172,9 +176,9 @@  --------------------------------------------------------------------------------------- -- | `Scrape` describes which (Horn) constraints to scrape qualifiers from---   None = do not scrape, only use the supplied qualifiers+--   No   = do not scrape, only use the supplied qualifiers --   Head = scrape only from the constraint heads (i.e. "rhs")---   All  = scrape all concrete predicates (i.e. "rhs" + "lhs")+--   Both = scrape all concrete predicates (i.e. "rhs" + "lhs")  data Scrape = No | Head | Both   deriving (Eq, Data, Typeable, Generic)@@ -234,7 +238,7 @@   , defunction               = False   &= help "Allow higher order binders into fixpoint environment"   , solver                   = def     &= help "Name of SMT Solver"   , linear                   = False   &= help "Use uninterpreted integer multiplication and division"-  , stringTheory             = False   &= help "Interpretation of String Theory by SMT"+  , noStringTheory           = False   &= help "Disable use of string theory by SMT"   , allowHO                  = False   &= help "Allow higher order binders into fixpoint environment"   , allowHOqs                = False   &= help "Allow higher order qualifiers"   , eliminate                = None    &= help "Eliminate KVars [none = quals for all-kvars, cuts = quals for cut-kvars, all = eliminate all-kvars (TRUE for cuts)]"@@ -255,13 +259,11 @@   , minimizeQs               = False &= help "Delta debug to minimize fq file (sat with min qualifiers)"   , minimizeKs               = False &= help "Delta debug to minimize fq file (sat with max kvars replaced by True)"   , minimalSol               = False &= help "Shrink fixpoint by removing implied qualifiers"-  , gradual                  = False &= help "Solve gradual-refinement typing constraints"-  , ginteractive             = False &= help "Interactive Gradual Solving"   , 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 &= name "ple" &= help "Allow axiom instantiation via rewriting (PLE)"-  , pleWithUndecidedGuards   =+  , pleUndecGuards   =       False         &= name "ple-with-undecided-guards"         &= help "Unfold invocations with undecided guards in PLE"@@ -270,44 +272,36 @@       False         &= name "interpreter"         &= help "Use the interpreter to assist PLE"-  , oldPLE                   = False &= help "Use old version of PLE"   , etabeta                  = False &= help "Use eta expansion and beta reduction to aid PLE"-  , localRewrites            = False &= name "local-rewrites" &= help "Perform local rewrites inside PLE"-  , noIncrPle                = False &= help "Don't use incremental PLE"-  , noEnvironmentReduction   =-      False-        &= name "no-environment-reduction"-        &= help "Don't perform environment reduction"-  , inlineANFBindings        =-      False-        &= name "inline-anf-bindings"-        &= help (unwords+  , localRewrites            = False &= help "Perform local rewrites inside PLE"+  , noEnvReduction           = False &= help "Don't perform environment reduction"+  , inlineANFBinds           = False &= help (unwords           [ "Inline ANF bindings."           , "Sometimes improves performance and sometimes worsens it."-          , "Disabled by --no-environment-reduction"+          , "Disabled by --noenvreduction"           ])   , checkCstr                = []    &= help "Only check these specific constraint-ids"   , extensionality           = False &= help "Allow extensional interpretation of extensionality"-  , rwTerminationCheck       = False   &= help "Enable rewrite divergence checker"+  , rwTermination       = False   &= help "Enable rewrite divergence checker"   , stdin                    = False   &= help "Read input query from stdin"   , json                     = False   &= help "Render result in JSON"-  , noLazyPLE                = False   &= help "Don't use lazy PLE"   , fuel                     = Nothing &= help "Maximum fuel (per-function unfoldings) for PLE"-  , restOrdering             = "rpo"-        &= name "rest-ordering"-        &= help "Ordering Constraint Algebra to use for REST"+  , restOrdering             = "rpo"   &= help "Ordering Constraint Algebra to use for REST"   , noSmtHorn                = False &= help "Do not use SMTLIB horn format"+  , explicitKvars            = False &= help "Use explicitly declared kvars (horn style) which disables several defensive simplifications"   }   &= verbosity   &= program "fixpoint"   &= help    "Predicate Abstraction Based Horn-Clause Solver"-  &= summary "fixpoint Copyright 2009-15 Regents of the University of California."+  &= summary summaryInfo   &= details [ "Predicate Abstraction Based Horn-Clause Solver"              , ""              , "To check a file foo.fq type:"              , "  fixpoint foo.fq"              ] +summaryInfo :: String+summaryInfo = "fixpoint " ++ showVersion version ++ " " ++ "("  ++ $(gitHash) ++ ")" config :: Mode (CmdArgs Config) config = cmdArgsMode defConfig @@ -318,7 +312,7 @@   return md  banner :: String-banner =  "\n\nLiquid-Fixpoint Copyright 2013-21 Regents of the University of California.\n"+banner =  "\n\nLiquid-Fixpoint Copyright 2009-25 Regents of the University of California.\n"        ++ "All Rights Reserved.\n"  restOC :: Config -> RESTOrdering
src/Language/Fixpoint/Types/Constraints.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE PatternGuards              #-}  {-# OPTIONS_GHC -Wno-name-shadowing     #-}+{-# LANGUAGE RecordWildCards #-}  -- | This module contains the top-level QUERY data types and elements, --   including (Horn) implication & well-formedness constraints and sets.@@ -22,18 +23,18 @@     FInfo, SInfo, GInfo (..), FInfoWithOpts(..)   , convertFormat   , sinfoToFInfo-  , Solver     -- * Serializing   , toFixpoint   , writeFInfo   , saveQuery+  , saveSInfo     -- * Constructing Queries   , fi    -- * Constraints-  , WfC (..), isGWfc, updateWfCExpr+  , WfC (..)   , SubC, SubcId   , mkSubC, subcId, sid, senv, updateSEnv, slhs, srhs, stag, subC, wfC   , SimpC (..)@@ -47,7 +48,6 @@   , addIds   , sinfo   , shiftVV-  , gwInfo, GWInfo (..)    -- * Qualifiers   , Qualifier@@ -63,8 +63,9 @@    -- * Results   , FixSolution-  , GFixSolution, toGFixSol-  , Result (..)+  , FixDelayedSolution+  , Delayed (..)+  , Result (..), ResultSorts   , unsafe, isUnsafe, isSafe ,safe    -- * Cut KVars@@ -80,6 +81,7 @@   -- * Axioms   , AxiomEnv (..)   , Equation+  , DefinedFuns (..)   , EquationV (..)   , mkEquation   , Rewrite  (..)@@ -90,11 +92,13 @@   , lookupRewrite   , lookupLocalRewrites   , insertRewrites+  , eqnToHornSMT    -- * Misc  [should be elsewhere but here due to dependencies]   , substVars   , sortVars   , gSorts+   ) where  import qualified Data.Store as S@@ -109,6 +113,7 @@ import           Control.DeepSeq import           Control.Monad             (when, void) import           Language.Fixpoint.Types.PrettyPrint+import           Language.Fixpoint.Types.SMTPrint import qualified Language.Fixpoint.Types.Config as C import           Language.Fixpoint.Types.Triggers import           Language.Fixpoint.Types.Names@@ -142,38 +147,8 @@                     , wrft  :: (Symbol, Sort, KVar)                     , winfo :: !a                     }-             | GWfC { wenv  :: !IBindEnv-                    , wrft  :: !(Symbol, Sort, KVar)-                    , winfo :: !a-                    , wexpr :: !Expr-                    , wloc  :: !GradInfo-                    }               deriving (Eq, Generic, Functor) -data GWInfo = GWInfo { gsym  :: Symbol-                     , gsort :: Sort-                     , gexpr :: Expr-                     , ginfo :: GradInfo-                     }-              deriving (Eq, Generic)--gwInfo :: WfC a -> GWInfo-gwInfo (GWfC _ (x,s,_) _ e i)-  = GWInfo x s e i-gwInfo _-  = errorstar "gwInfo"--updateWfCExpr :: (Expr -> Expr) -> WfC a -> WfC a-updateWfCExpr _ w@WfC{}  = w-updateWfCExpr f w@GWfC{} = w{wexpr = f (wexpr w)}--isGWfc :: WfC a -> Bool-isGWfc GWfC{} = True-isGWfc WfC{}  = False--instance HasGradual (WfC a) where-  isGradual = isGWfc- type SubcId = Integer  data SubC a = SubC@@ -199,7 +174,7 @@ instance Loc a => Loc (SimpC a) where   srcSpan = srcSpan . _cinfo -strengthenHyp :: SInfo a -> [(Integer, Expr)] -> SInfo a+strengthenHyp :: SInfo a -> [(Integer, Expr)] -> BindEnv a strengthenHyp si ies = strengthenBinds si bindExprs   where     bindExprs        = safeFromList "strengthenHyp" [ (subcBind si i, e) | (i, e) <- ies ]@@ -212,8 +187,8 @@   = errorstar $ "Unknown subcId in subcBind: " ++ show i  -strengthenBinds :: SInfo a -> M.HashMap BindId Expr -> SInfo a-strengthenBinds si m = si { bs = mapBindEnv f (bs si) }+strengthenBinds :: SInfo a -> M.HashMap BindId Expr -> BindEnv a+strengthenBinds si m = mapBindEnv f (bs si)   where     f i (x, sr, l)   = case M.lookup i m of                          Nothing -> (x, sr, l)@@ -272,37 +247,87 @@ -- | Solutions and Results --------------------------------------------------------------------------- -type GFixSolution = GFixSol Expr+-- | Since some solutions are expensive to compute, we wrap them in a+-- "Delayed" type to compute them only if needed.+{- HLINT ignore Delayed "Use newtype instead of data" -}+data Delayed a = Delayed+  { forceDelayed  :: a+  }+  deriving (Generic, Show, Functor) -type FixSolution  = M.HashMap KVar Expr+instance (NFData a) => NFData (Delayed a) -newtype GFixSol e = GSol (M.HashMap KVar (e, [e]))-  deriving (Generic, Semigroup, Monoid, Functor) -toGFixSol :: M.HashMap KVar (e, [e]) -> GFixSol e-toGFixSol = GSol-+type FixSolution  = M.HashMap KVar Expr+type FixDelayedSolution  = M.HashMap KVar (Delayed Expr)  data Result a = Result   { resStatus    :: !(FixResult a)   , resSolution  :: !FixSolution-  , resNonCutsSolution :: !FixSolution-  , gresSolution :: !GFixSolution+  , resNonCutsSolution :: !FixDelayedSolution+  , resSorts     :: !ResultSorts   }   deriving (Generic, Show, Functor) +type ResultSorts = M.HashMap KVar [(Symbol, Sort)] +data ScopedResult = MkScopedResult+  { scCuts    :: KVarMap ScopedExpr+  , scNonCuts :: KVarMap ScopedExpr+  }+  deriving (Generic, Show) +newtype KVarMap a = MkKVarMap { unKVarMap :: M.HashMap KVar a }+  deriving (Generic, Show)++newtype KVarBind a = MkKVarBind { unKVarBind :: (KVar, a) }+  deriving (Generic, Show)+data ScopedExpr = MkScopedExpr+  { seParams :: [(Symbol, Sort)]+  , seBody :: !Expr+  }+  deriving (Generic, Show)++instance ToHornSMT ScopedExpr where+  toHornSMT (MkScopedExpr xts p) = toHornWithBinders "lambda" xts p+++scopedResult :: Result a -> ScopedResult+scopedResult res = MkScopedResult cuts  nonCuts+  where+    cuts = scoped $ resSolution res+    nonCuts = scoped $ M.map forceDelayed $ resNonCutsSolution res+    scoped sol = MkKVarMap $ M.fromList [ (k, MkScopedExpr (scope k) e) | (k, e) <- M.toList sol]+    scope k = M.lookupDefault [] k $ resSorts res+ instance ToJSON a => ToJSON (Result a) where-  toJSON = toJSON . resStatus+  toJSON r@(Result {..}) = object+    [ "status"            .= resStatus+    , "solution"          .= scCuts scopedSolution+    , "nonCutsSolution"   .= scNonCuts scopedSolution+    ]+    where+      scopedSolution = scopedResult r +instance ToJSON a => ToJSON (KVarBind a) where+  toJSON (MkKVarBind (k, v)) = object+    [ "kvar" .= k+    , "val"  .= v+    ]++instance ToJSON a => ToJSON (KVarMap a) where+  toJSON = toJSON . map MkKVarBind . M.toList . unKVarMap++instance ToJSON ScopedExpr where+  toJSON = toJSON . render . toHornSMT+ instance Semigroup (Result a) where-  r1 <> r2  = Result stat soln nonCutsSoln gsoln+  r1 <> r2  = Result stat soln nonCutsSoln sorts     where       stat  = resStatus r1    <> resStatus r2       soln  = resSolution r1  <> resSolution r2       nonCutsSoln = resNonCutsSolution r1 <> resNonCutsSolution r2-      gsoln = gresSolution r1 <> gresSolution r2+      sorts = M.unionWith L.union (resSorts r1) (resSorts r2)  instance Monoid (Result a) where   mempty        = Result mempty mempty mempty mempty@@ -370,7 +395,6 @@               -- NOTE: this next line is printed this way for compatability with the OCAML solver               $+$ text "reft" <+> toFix (RR t (Reft (v, PKVar k mempty)))               $+$ toFixMeta (text "wf") (toFix (winfo w))-              $+$ if isGWfc w then toFixMeta (text "expr") (toFix (wexpr w)) else mempty           (v, t, k) = wrft w  toFixMeta :: Doc -> Doc -> Doc@@ -380,31 +404,12 @@ pprId (Just i)  = "id" <+> tshow i pprId _         = "" -instance PPrint GFixSolution where-  pprintTidy k (GSol xs) = vcat $ punctuate "\n\n" (pprintTidyGradual k <$> M.toList xs)--pprintTidyGradual :: Tidy -> (KVar, (Expr, [Expr])) -> Doc-pprintTidyGradual _ (x, (e, es)) = ppLocOfKVar x <+> text ":=" <+> (ppNonTauto " && " e <-> pprint es)--ppLocOfKVar :: KVar -> Doc-ppLocOfKVar = text. dropWhile (/='(') . symbolString .kv--ppNonTauto :: Doc -> Expr -> Doc-ppNonTauto d e-  | isTautoPred e = mempty-  | otherwise     = pprint e <-> d--instance Show   GFixSolution where-  show = showpp- ---------------------------------------------------------------- instance S.Store QualPattern instance S.Store QualParam instance S.Store Qualifier instance S.Store Kuts instance S.Store HOInfo-instance S.Store GWInfo-instance S.Store GFixSolution instance (S.Store a) => S.Store (SubC a) instance (S.Store a) => S.Store (WfC a) instance (S.Store a) => S.Store (SimpC a)@@ -415,8 +420,6 @@ instance NFData v => NFData (QualifierV v) instance NFData Kuts instance NFData HOInfo-instance NFData GFixSolution-instance NFData GWInfo  instance (NFData a) => NFData (SubC a) instance (NFData a) => NFData (WfC a)@@ -443,22 +446,16 @@                  -- NV TO RJ This tests fails with [LT:=GHC.Types.LT][EQ:=GHC.Types.EQ][GT:=GHC.Types.GT]]                  -- NV TO RJ looks like a resolution issue                 then [WfC be (v, sr_sort sr, k) x      | k         <- ks ]-                  ++ [GWfC be (v, sr_sort sr, k) x e i | (k, e, i) <- gs ]                 else errorstar msg   where-    msg             = "wfKvar: malformed wfC " ++ show sr ++ "\n" ++ show (sus ++ gsus)+    msg             = "wfKvar: malformed wfC " ++ show sr ++ "\n" ++ show sus     Reft (v, ras)   = sr_reft sr     (ks, sus)       = unzip $ go ras-    (gs, gsus)      = unzip $ go' ras      go (PKVar k su) = [(k, su)]     go (PAnd es)    = [(k, su) | PKVar k su <- es]     go _            = [] -    go' (PGrad k su i e) = [((k, e, i), su)]-    go' (PAnd es)      = concatMap go' es-    go' _              = []- mkSubC :: IBindEnv -> SortedReft -> SortedReft -> Maybe Integer -> Tag -> a -> SubC a mkSubC = SubC @@ -508,6 +505,10 @@   }   deriving (Eq, Ord, Show, Data, Typeable, Generic) +instance ToHornSMT QualParam where+  toHornSMT qp = toHornSMT (qpSym qp, qpSort qp)++ data QualPattern   = PatNone                 -- ^ match everything   | PatPrefix !Symbol !Int  -- ^ str . $i  i.e. match prefix 'str' with suffix bound to $i@@ -526,6 +527,11 @@ instance ToJSON   Rewrite     where instance FromJSON Rewrite     where +instance ToHornSMT Qualifier where+  toHornSMT (Q n qps p _) =  toHornWithBinders name xts p+    where+      name = "qualif" <+> pprint n+      xts =  [(qpSym qp, qpSort qp) | qp <- qps]  trueQual :: Qualifier trueQual = Q (symbol ("QTrue" :: String)) [] PTrue (dummyPos "trueQual")@@ -564,11 +570,15 @@ instance Fixpoint Qualifier where   toFix = pprQual -instance PPrint (QualifierV v) where-  pprintTidy k q = "qualif" <+> pprintTidy k (qName q) <+> "defined at" <+> pprintTidy k (qPos q)+instance (Ord v, Fixpoint v, PPrint v) => PPrint (QualifierV v) where+  pprintTidy k q =+    "qualif" <+> pprintTidy k (qName q) <+>+     parens (hsep $ punctuate comma (pprintTidy k <$> qParams q)) <+>+     braces (pprintTidy k (qBody q)) <+> "//defined at" <+> pprintTidy k (qPos q) + pprQual :: Qualifier -> Doc-pprQual (Q n xts p l) = text "qualif" <+> text (symbolString n) <-> parens args <-> colon <+> parens (toFix p) <+> text "//" <+> toFix l+pprQual (Q n xts p l) = text "qualif" <+> text (symbolString n) <-> parens args <-> braces (toFix p) <+> text "//" <+> toFix l   where     args              = intersperse comma (toFix <$> xts) @@ -681,12 +691,11 @@    -> [Triggered Expr]    -> AxiomEnv    -> [DataDecl]-   -> [BindId]    -> GInfo SubC a-fi cs ws binds ls ds ks qs bi aHO aHOq es axe adts ebs+fi cs ws binds ls ds ks qs bi aHO aHOq es axe adts   = FI { cm       = M.fromList $ addIds cs        , ws       = M.fromListWith err [(k, w) | w <- ws, let (_, _, k) = wrft w]-       , bs       = foldr (adjustBindEnv stripReft) binds ebs+       , bs       = binds        , gLits    = ls        , dLits    = ds        , kuts     = ks@@ -696,14 +705,12 @@        , asserts  = es        , ae       = axe        , ddecls   = adts-       , ebinds   = ebs        , lrws     = mempty        , defns    = mempty        }   where     --TODO handle duplicates gracefully instead (merge envs by intersect?)     err = errorstar "multiple WfCs with same kvar"-    stripReft (sym, reft) = (sym, reft { sr_reft = trueReft })  ------------------------------------------------------------------------ -- | Top-level Queries@@ -733,8 +740,7 @@ data GInfo c a = FI   { cm       :: !(M.HashMap SubcId (c a))  -- ^ cst id |-> Horn Constraint   , ws       :: !(M.HashMap KVar (WfC a))  -- ^ Kvar  |-> WfC defining its scope/args-  , bs       :: !(BindEnv a)               -- ^ Bind  |-> (Symbol, SortedReft)-  , ebinds   :: ![BindId]                  -- ^ Subset of existential binders+  , bs       :: !(BindEnv a)               -- ^ BindId  |-> (Symbol, SortedReft)   , gLits    :: !(SEnv Sort)               -- ^ Global Constant symbols   , dLits    :: !(SEnv Sort)               -- ^ Distinct Constant symbols   , kuts     :: !Kuts                      -- ^ Set of KVars *not* to eliminate@@ -745,13 +751,10 @@   , asserts  :: ![Triggered Expr]          -- ^ TODO: what is this?   , ae       :: AxiomEnv                   -- ^ Information about reflected function defs   , lrws     :: LocalRewritesEnv           -- ^ Local rewrites-  , defns    :: ![Equation]                -- ^ `define_fun` definitions to be passed to SMT+  , defns    :: DefinedFuns                -- ^ `define_fun` definitions to be passed to SMT   }   deriving (Eq, Show, Functor, Generic) -instance HasGradual (GInfo c a) where-  isGradual info = any isGradual (M.elems $ ws info)- instance Semigroup HOInfo where   i1 <> i2 = HOI { hoBinds = hoBinds i1 || hoBinds i2                  , hoQuals = hoQuals i1 || hoQuals i2@@ -764,7 +767,6 @@   i1 <> i2 = FI { cm       = cm i1       <> cm i2                 , ws       = ws i1       <> ws i2                 , bs       = bs i1       <> bs i2-                , ebinds   = ebinds i1   <> ebinds i2                 , gLits    = gLits i1    <> gLits i2                 , dLits    = dLits i1    <> dLits i2                 , kuts     = kuts i1     <> kuts i2@@ -783,7 +785,6 @@   mempty        = FI { cm       = M.empty                      , ws       = mempty                      , bs       = mempty-                     , ebinds   = mempty                      , gLits    = mempty                      , dLits    = mempty                      , kuts     = mempty@@ -830,9 +831,7 @@     kutsDoc       = toFix    . kuts     -- packsDoc      = toFix    . packs     declsDoc      = vcat     . map ((text "data" <+>) . toFix) . L.sort . ddecls-    (ubs, ebs)    = splitByQuantifiers (bs x') (ebinds x')-    bindsDoc      = toFix    ubs-               $++$ toFix    ebs+    bindsDoc      = toFix (bs x')     qualsDoc      = vcat     . map toFix . L.sort . quals     aeDoc         = toFix    . ae     lrwsDoc       = toFix    . lrws@@ -909,11 +908,6 @@   where     (b, sr, _) = lookupBindEnv (cbind s) env ------------------------------------------------------------------------------- | Top level Solvers ---------------------------------------------------------------------------------------------------------------------------------type Solver a = C.Config -> FInfo a -> IO (Result (Integer, a))- -------------------------------------------------------------------------------- saveQuery :: (Fixpoint a) => C.Config -> FInfo a -> IO () --------------------------------------------------------------------------------@@ -936,6 +930,26 @@   ensurePath fq   T.writeFile fq $ T.pack $ render (toFixpoint cfg fi) +-- | Used for debugging to inspect intermediate 'SInfo' files.+--+-- Takes a suffix to put in the name of the written file, whose name+-- is still derived from the input file name in `cfg`.+--+-- Usage example:+--+-- > when (save cfg) $+-- >   saveSInfo cfg ".sinfo" si+--+-- This will write a file like `.liquid/Test.hs.sinfo.fq` when the+-- `--save` flag is used.+--+saveSInfo :: Fixpoint a => C.Config -> String -> SInfo a -> IO ()+saveSInfo cfg sfx si = do+  let fq = Files.tempFileName (C.srcFile cfg ++ sfx ++ ".fq")+  putStrLn $ "Saving Text Query: "   ++ fq ++ "\n"+  ensurePath fq+  T.writeFile fq $ T.pack $ render (toFixpoint cfg si)+ --------------------------------------------------------------------------- -- | Axiom Instantiation Information -------------------------------------- ---------------------------------------------------------------------------@@ -966,10 +980,12 @@ instance S.Store AxiomEnv instance S.Store Rewrite instance S.Store Equation+instance S.Store DefinedFuns instance NFData AutoRewrite instance NFData AxiomEnv instance NFData Rewrite instance NFData Equation+instance NFData DefinedFuns  dedupAutoRewrites :: M.HashMap SubcId [AutoRewrite] -> [AutoRewrite] dedupAutoRewrites = Set.toList . Set.unions . map Set.fromList . M.elems@@ -989,6 +1005,19 @@ instance PPrint AxiomEnv where   pprintTidy _ = text . show ++newtype DefinedFuns = MkDefinedFuns [Equation]+  deriving (Data, Eq, Ord, Show, Generic)++instance Semigroup DefinedFuns where+  MkDefinedFuns eq1 <> MkDefinedFuns eq2 = MkDefinedFuns (eq1 <> eq2)++instance Monoid DefinedFuns where+  mempty = MkDefinedFuns []++instance PPrint DefinedFuns where+  pprintTidy k (MkDefinedFuns eqs) = pprintTidy k eqs+ type Equation = EquationV Symbol data EquationV v = Equ   { eqName :: !Symbol           -- ^ name of reflected function@@ -999,6 +1028,10 @@   }   deriving (Data, Eq, Ord, Show, Generic, Functor) +eqnToHornSMT :: Doc -> Equation -> Doc+eqnToHornSMT keyword (Equ f xs e s _) = parens (keyword <+> pprint f <+> toHornSMT xs <+> toHornSMT s <+> toHornSMT e)++ mkEquation :: Symbol -> [(Symbol, Sort)] -> Expr -> Sort -> Equation mkEquation f xts e out = Equ f xts e out (f `elem` syms e) @@ -1062,6 +1095,11 @@   }   deriving (Data, Eq, Ord, Show, Generic) +instance ToHornSMT Rewrite where+  toHornSMT (SMeasure f d xs e) =  parens ("match" <+> toHornSMT f <+> toHornSMT (d:xs) <+> toHornSMT e)+++ instance Fixpoint AxiomEnv where   toFix axe = vcat ((toFix <$> L.sort (aenvEqs axe)) ++ (toFix <$> L.sort (aenvSimpl axe)))               $+$ renderExpand (pairdoc <$> L.sort (M.toList $ aenvExpand axe))@@ -1086,8 +1124,7 @@     = text "match"    <+> toFix f    <+> toFix d <+> hsep (toFix <$> xs)-   <+> text " = "-   <+> parens (toFix e)+   <+> braces (toFix e)  instance PPrint Rewrite where   pprintTidy _ = toFix
src/Language/Fixpoint/Types/Environments.hs view
@@ -318,7 +318,7 @@   mappend = (<>)  envCs :: BindEnv a -> IBindEnv -> [(Symbol, SortedReft)]-envCs be env = [(x, y) | i <- elemsIBindEnv env, let (x, y, _) = lookupBindEnv i be]+envCs be (FB s) = [(x, y) | (x, y, _) <- M.elems (M.intersection (beBinds be) (S.toMap s))]  instance Fixpoint IBindEnv where   toFix (FB ids) = text "env" <+> toFix ids
src/Language/Fixpoint/Types/Errors.hs view
@@ -62,6 +62,7 @@ -- import           Data.Hashable import qualified Data.Store                   as S import           GHC.Generics                  (Generic)+import           GHC.Stack                     (HasCallStack) import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Types.Spans import           Language.Fixpoint.Misc@@ -137,7 +138,7 @@ err sp d = Error [Error1 sp d]  ----------------------------------------------------------------------panic :: String -> a+panic :: HasCallStack => String -> a --------------------------------------------------------------------- panic = die . err dummySpan . text . (panicMsg ++) @@ -145,7 +146,7 @@ panicMsg = "PANIC: Please file an issue at https://github.com/ucsd-progsys/liquid-fixpoint \n"  ----------------------------------------------------------------------die :: Error -> a+die :: HasCallStack => Error -> a --------------------------------------------------------------------- die = throw 
− src/Language/Fixpoint/Types/Graduals.hs
@@ -1,259 +0,0 @@-{-# LANGUAGE CPP                        #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE NoMonomorphismRestriction  #-}-{-# LANGUAGE OverloadedStrings          #-}-{-# LANGUAGE UndecidableInstances       #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE GADTs                      #-}-{-# LANGUAGE TupleSections              #-}--{-# OPTIONS_GHC -Wno-name-shadowing     #-}---- | This module contains the top-level SOLUTION data types,---   including various indices used for solving.--module Language.Fixpoint.Types.Graduals (-  uniquify,--  makeSolutions,--  GSol,--  Gradual (..)-  ) where--import Language.Fixpoint.Types.Refinements-import Language.Fixpoint.Types.Constraints-import Language.Fixpoint.Types.Config-import Language.Fixpoint.Types.PrettyPrint-import Language.Fixpoint.Types.Environments-import Language.Fixpoint.Types.Substitutions-import Language.Fixpoint.Types.Visitor-import Language.Fixpoint.Types.Spans-import Language.Fixpoint.Types.Theories-import Language.Fixpoint.Types.Names        (gradIntSymbol, tidySymbol)-import Language.Fixpoint.Misc               (allCombinations, errorstar)--import Control.DeepSeq--import qualified Data.HashMap.Strict       as M-import qualified Data.List                 as L--import Control.Monad.State.Lazy-import Data.Maybe (fromMaybe)-import qualified Language.Fixpoint.SortCheck       as So-import Language.Fixpoint.Solver.Sanitize (symbolEnv)---data GSol = GSol !SymEnv !(M.HashMap KVar (Expr, GradInfo))--instance Semigroup GSol where-  (GSol e1 m1) <> (GSol e2 m2) = GSol (e1 <> e2) (m1 <> m2)--instance Monoid GSol where-  mempty = GSol mempty mempty--instance Show GSol where-  show (GSol _ m) = "GSOL = \n" ++ unlines ((\(k,(e, i)) -> showpp k ++ showInfo i ++  " |-> " ++ showpp (tx e)) <$> M.toList m)-    where-      tx e = subst (mkSubst $ [(x, EVar $ tidySymbol x) | x <- syms e]) e-      showInfo i = show i---makeSolutions :: (NFData a, Fixpoint a, Show a)-              => Config -> SInfo a-              -> [(KVar, (GWInfo, [[Expr]]))]-              -> Maybe [GSol]--makeSolutions _ _ []-  = Nothing-makeSolutions cfg fi kes-  = Just $ map (GSol env . M.fromList) (allCombinations (go  <$> kes))-  where-    go (k, (i, es)) = [(k, (pAnd (gexpr i:e'), ginfo i)) | e' <- es]-    env = symbolEnv cfg fi------------------------------------------------------------------------------------- |  Make each gradual appearence unique ----------------------------------------------------------------------------------------------------------------------uniquify :: (NFData a, Fixpoint a, Loc a) => SInfo a -> SInfo a--uniquify fi = fi{cm = cm', ws = ws', bs = bs'}-  where-  (cm', km, bs') = uniquifyCS (bs fi) (cm fi)-  ws'            = expandWF km (ws fi)--uniquifyCS :: (NFData a, Fixpoint a, Loc a)-           => BindEnv a-           -> M.HashMap SubcId (SimpC a)-           -> (M.HashMap SubcId (SimpC a), M.HashMap KVar [(KVar, Maybe SrcSpan)], BindEnv a)-uniquifyCS bs cs-  = (x, km, benv st)-  where-    (x, st) = runState (uniq cs) (initUniqueST bs)-    km      = kmap st---class Unique ann a where-   uniq :: a -> UniqueM ann a--instance Unique ann a => Unique ann (M.HashMap SubcId a) where-  uniq m = M.fromList <$> mapM (\(i,x) -> (i,) <$> uniq x) (M.toList m)--instance Loc a => Unique a (SimpC a) where-  uniq cs = do-    updateLoc $ srcSpan $ _cinfo cs-    rhs <- uniq (_crhs cs)-    env <- uniq (_cenv cs)-    return cs{_crhs = rhs, _cenv = env}--instance Unique ann IBindEnv where-  uniq env = withCache (fromListIBindEnv <$> mapM uniq (elemsIBindEnv env))--instance Unique ann BindId where-  uniq i = do-    bs <- benv <$> get-    let (x, t, ann) = lookupBindEnv i bs-    resetChange-    t' <- uniq t-    hasChanged <- change <$> get-    if hasChanged-      then do let (i', bs') = insertBindEnv x t' ann bs-              updateBEnv i bs'-              return i'-      else return i--instance Unique ann SortedReft where-  uniq (RR s r) = RR s <$> uniq r--instance Unique ann Reft where-  uniq (Reft (x,e)) = Reft . (x,) <$> uniq e--instance Unique ann Expr where-  uniq = mapMExpr go-   where-    go (PGrad k su i e) = do-      k'  <- freshK k-      src <- uloc <$> get-      return $ PGrad k' su (i{gused = src}) e-    go e              = return e------------------------------------------------------------------------------------ | The Unique Monad -------------------------------------------------------------------------------------------------------------------------------------------type UniqueM ann = State (UniqueST ann)-data UniqueST a-  = UniqueST { freshId :: Integer-             , kmap    :: M.HashMap KVar [(KVar, Maybe SrcSpan)]-             , change  :: Bool-             , cache   :: M.HashMap KVar KVar-             , uloc    :: Maybe SrcSpan-             , ubs     :: [BindId]-             , benv    :: BindEnv a-             }--updateLoc :: SrcSpan -> UniqueM ann ()-updateLoc x = modify $ \s -> s{uloc = Just x}--withCache :: UniqueM ann a -> UniqueM ann a-withCache act = do-  emptyCache-  a <- act-  emptyCache-  return a--emptyCache :: UniqueM ann ()-emptyCache = modify $ \s -> s{cache = mempty}--addCache :: KVar -> KVar -> UniqueM ann ()-addCache k k' = modify $ \s -> s{cache = M.insert k k' (cache s)}--updateBEnv :: BindId -> BindEnv a -> UniqueM a ()-updateBEnv i bs = modify $ \s -> s{benv = bs, ubs = i : ubs s}--setChange :: UniqueM ann ()-setChange = modify $ \s -> s{change = True}--resetChange :: UniqueM ann ()-resetChange = modify $ \s -> s{change = False}--initUniqueST :: BindEnv a ->  UniqueST a-initUniqueST = UniqueST 0 mempty False mempty Nothing mempty--freshK, freshK' :: KVar -> UniqueM ann KVar-freshK k  = do-  setChange-  cached <- cache <$> get-  case M.lookup k cached of-    {- OPTIMIZATION: Only create one fresh occurence of ? per constraint environment. -}-    Just k' -> return  k'-    Nothing -> freshK' k--freshK' k = do-  i <- freshId <$> get-  modify (\s -> s{freshId = i + 1})-  let k' = KV $ gradIntSymbol i-  addK k k'-  addCache k k'-  return k'--addK :: KVar -> KVar -> UniqueM ann ()-addK key val =-  modify (\s -> s{kmap = M.insertWith (++) key [(val, uloc s)] (kmap s)})------------------------------------------------------------------------------------ | expandWF ---------------------------------------------------------------------------------------------------------------------------------------------------expandWF :: (NFData a, Fixpoint a)-         => M.HashMap KVar [(KVar, Maybe SrcSpan)]-         -> M.HashMap KVar (WfC a)-         -> M.HashMap KVar (WfC a)-expandWF km ws-  = M.fromList-       ([(k, updateKVar k src w) | (i, w) <- gws, (kw, ks) <- km', kw == i, (k, src) <- ks]-        ++ kws)-  where-    (gws, kws)       = L.partition (isGWfc . snd) $ M.toList ws-    km'              = M.toList km--    updateKVar k src wfc = let wrft' = (\(v,s,_) -> (v,s,k)) $ wrft wfc in-      case wfc of-        GWfC{} -> wfc { wrft = wrft', wloc = (wloc wfc){gused = src} }-        WfC{}  -> wfc { wrft = wrft' }------------------------------------------------------------------------------------ |  Substitute Gradual Solution -------------------------------------------------------------------------------------------------------------------------------class Gradual a where-  gsubst :: ElabFlags -> GSol -> a -> a--instance Gradual Expr where-  gsubst ef (GSol env m) e   = mapGVars' (\(k, _) -> Just (fromMaybe (err k) (mknew k))) e-    where-      mknew k = So.elaborate (So.ElabParam ef "initBGind.mkPred" env) $ fst <$> M.lookup k m-      err   k = errorstar ("gradual substitution: Cannot find " ++ showpp k)--instance Gradual Reft where-  gsubst ef su (Reft (x, e)) = Reft (x, gsubst ef su e)--instance Gradual SortedReft where-  gsubst ef su r = r {sr_reft = gsubst ef su (sr_reft r)}--instance Gradual (SimpC a) where-  gsubst ef su c = c {_crhs = gsubst ef su (_crhs c)}--instance Gradual (BindEnv a) where-  gsubst ef su = mapBindEnv (\_ (x, r, l) -> (x, gsubst ef su r, l))--instance Gradual v => Gradual (M.HashMap k v) where-  gsubst ef su = M.map (gsubst ef su)--instance Gradual (SInfo a) where-  gsubst ef su fi = fi { bs = gsubst ef su (bs fi)-                        , cm = gsubst ef su (cm fi)-                        }
src/Language/Fixpoint/Types/Names.hs view
@@ -72,7 +72,6 @@   , dummySymbol   , intSymbol   , tempSymbol-  , gradIntSymbol   , appendSymbolText   , hvarArgSymbol @@ -81,6 +80,7 @@   , bindSymbol   , testSymbol   , renameSymbol+  , renameSubstSymbol   , kArgSymbol   , existSymbol   , suffixSymbol@@ -101,6 +101,7 @@   , mapConName   , bagConName   , arrayConName+  , ffldConName   , strConName   , charConName   , nilName@@ -108,8 +109,8 @@   , vvName   , sizeName   , bitVecName-  -- , bvAndName, bvOrName, bvSubName, bvAddName   , intbv32Name, intbv64Name, bv32intName, bv64intName+  , intbv8Name, intbv16Name, bv8intName, bv16intName   , propConName    -- HKT , tyAppName@@ -407,9 +408,6 @@ unconsSym :: Symbol -> Maybe (Char, Symbol) unconsSym (symbolText -> s) = second symbol <$> T.uncons s --- singletonSym :: Char -> Symbol -- Yuck--- singletonSym = (`consSym` "")- lengthSym :: Symbol -> Int lengthSym (symbolText -> t) = T.length t @@ -443,7 +441,6 @@ suffixSymbolText  x y = x <> symSepName <> y  vv                  :: Maybe Integer -> Symbol--- vv (Just i)         = symbol $ symbolSafeText vvName `T.snoc` symSepName `mappend` T.pack (show i) vv (Just i)         = intSymbol vvName i vv Nothing          = vvName @@ -454,12 +451,6 @@ vvCon       = vvName `suffixSymbol` "F" dummySymbol = dummyName --- ctorSymbol :: Symbol -> Symbol--- ctorSymbol s = ctorPrefix `mappendSym` s---- isCtorSymbol :: Symbol -> Bool--- isCtorSymbol = isPrefixOfSym ctorPrefix- -- | 'testSymbol c' creates the `is-c` symbol for the adt-constructor named 'c'. testSymbol :: Symbol -> Symbol testSymbol s = testPrefix `mappendSym` s@@ -485,6 +476,9 @@ tempSymbol :: Symbol -> Integer -> Symbol tempSymbol prefix = intSymbol (tempPrefix `mappendSym` prefix) +renameSubstSymbol :: Symbol -> Int -> Symbol+renameSubstSymbol prefix = intSymbol (substPrefix `mappendSym` prefix)+ renameSymbol :: Symbol -> Int -> Symbol renameSymbol prefix = intSymbol (renamePrefix `mappendSym` prefix) @@ -494,9 +488,6 @@ existSymbol :: Symbol -> Integer -> Symbol existSymbol prefix = intSymbol (existPrefix `mappendSym` prefix) -gradIntSymbol :: Integer -> Symbol-gradIntSymbol = intSymbol gradPrefix- hvarArgSymbol :: Symbol -> Int -> Symbol hvarArgSymbol s i = intSymbol (suffixSymbol hvarPrefix s) i @@ -507,20 +498,17 @@ bindSymbol :: Integer -> Symbol bindSymbol = intSymbol bindPrefix -tempPrefix, anfPrefix, renamePrefix, litPrefix, gradPrefix, bindPrefix :: Symbol+tempPrefix, anfPrefix, renamePrefix, substPrefix, litPrefix, bindPrefix :: Symbol tempPrefix   = "lq_tmp$" anfPrefix    = "lq_anf$" renamePrefix = "lq_rnm$"+substPrefix = "subst$" litPrefix    = "lit$"-gradPrefix   = "grad$" bindPrefix   = "b$"  testPrefix  :: Symbol testPrefix   = "is$" --- ctorPrefix  :: Symbol--- ctorPrefix   = "mk$"- kArgPrefix, existPrefix, hvarPrefix :: Symbol kArgPrefix  = "lq_karg$" existPrefix = "lq_ext$"@@ -534,26 +522,42 @@ unKArgSymbol :: Symbol -> Symbol unKArgSymbol = unSuffixSymbol . unSuffixSymbol . unPrefixSymbol kArgPrefix --- | 'tidySymbol' is used to prettify the names of parameters of kvars appearing in solutions.(*)---   For example, if you have a kvar $k0 with two parameters, you may have a solution that looks like---       0 <  lq_karg$nnf_arg$##k0##0##k0+-- | @tidySymbol@ is used to prettify the names of parameters of kvars appearing+-- in solutions.  For example, if you have a kvar $k0 with two parameters, you+-- may have a solution that looks like+--+-- > 0 <  lq_karg$nnf_arg$##k0##0##k0+-- --   where we know it is a kvar-arg because of the---      - `kArgPrefix` (`lq_arg`)---      - `hvarArgPrefix` (`nnf_arg`)---      - `k0` the name of the kvar---      - `0`  the parameter index---      - `k0` again (IDK why?!)---    all of which are separated by `##`---   So `tidySymbol` tests if indeed it is a `kArgPrefix`-ed symbol and if so converts---      `lq_karg$nnf_arg$##k0##0##k0` ----> `$k0##0`+--      - @kArgPrefix@ (@lq_arg@)+--      - @hvarArgPrefix@ (@nnf_arg@)+--      - @k0@ the name of the kvar+--      - @0@  the parameter index+--      - @k0@ again (IDK why?!)+--    all of which are separated by @##@+--+--   So @tidySymbol@ tests if indeed it is a @kArgPrefix@-ed symbol and if so+--   converts+--+-- > lq_karg$nnf_arg$##k0##0##k0 ----> $k0##0+--+--  KArgs from Liquid Haskell come in the form @k_##0@ instead, and parameters+--  are like @lq_karg$param_name##0##k_##0@. In this case, tidySymbol will+--  convert+--+--  > lq_karg$param_name##0##k_##0  ----> $param_name##0##k_  tidySymbol :: Symbol -> Symbol tidySymbol s   | s == s'   = s   | otherwise = s''   where-    s'        = unPrefixSymbol kArgPrefix s-    s''       = consSym '$' . unPrefixSymbol symSepName . unSuffixSymbol . unPrefixSymbol hvarPrefix $ s'+    s' = unPrefixSymbol kArgPrefix s+    s'' =+      consSym '$' $+      unPrefixSymbol symSepName $+      unSuffixSymbol $+      unPrefixSymbol hvarPrefix s'  unPrefixSymbol :: Symbol -> Symbol -> Symbol unPrefixSymbol p s = fromMaybe s (stripPrefix p s)@@ -562,10 +566,6 @@ unSuffixSymbol s@(symbolText -> t)   = maybe s symbol $ T.stripSuffix symSepName $ fst $ T.breakOnEnd symSepName t --- takeWhileSym :: (Char -> Bool) -> Symbol -> Symbol--- takeWhileSym p (symbolText -> t) = symbol $ T.takeWhile p t-- nonSymbol :: Symbol nonSymbol = "" @@ -652,48 +652,41 @@ preludeName  = "Prelude" dummyName    = "LIQUID$dummy" boolConName  = "Bool"-boolLConName  = "bool"+boolLConName = "bool" funConName   = "->"  -listConName, listLConName, propConName, _hpropConName, vvName, setConName, mapConName, bagConName, arrayConName:: Symbol-listConName  = "[]"-listLConName = "List"-setConName   = "Set_Set"-mapConName   = "Map_t"-bagConName   = "Bag_t"-arrayConName = "Array_t"-vvName       = "VV"-propConName  = "Prop"+listConName, listLConName, propConName, _hpropConName, vvName, setConName, mapConName, bagConName, arrayConName, ffldConName :: Symbol+listConName   = "[]"+listLConName  = "List"+setConName    = "Set_Set"+mapConName    = "Map_t"+bagConName    = "Bag_t"+arrayConName  = "Array_t"+ffldConName   = "FFld_t"+vvName        = "VV"+propConName   = "Prop" _hpropConName = "HProp"  strConName, charConName :: (IsString a) => a strConName   = "Str" charConName  = "Char"--- symSepName   :: Char--- symSepName   = '#' -- DO NOT EVER CHANGE THIS  symSepName   :: (IsString a) => a symSepName   = "##" --- nilName, consName, size32Name, size64Name, bitVecName :: Symbol--- nilName      = "nil"--- consName     = "cons"--- size32Name   = "Size32"--- size64Name   = "Size64"--- bitVecName   = "BitVec"---- bvOrName, bvAndName, bvSubName, bvAddName, intbv32Name, intbv64Name, bv32intName, bv64intName :: Symbol--- bvOrName    = "bvor"--- bvAndName   = "bvand"--- bvSubName   = "bvsub"--- bvAddName   = "bvadd" intbv32Name = "int_to_bv32" intbv64Name = "int_to_bv64" bv32intName = "bv32_to_int" bv64intName = "bv64_to_int" +intbv8Name, intbv16Name, bv8intName, bv16intName :: Symbol+intbv8Name  = "int_to_bv8"+intbv16Name = "int_to_bv16"+bv8intName  = "bv8_to_int"+bv16intName = "bv16_to_int"+ nilName, consName, sizeName, bitVecName :: Symbol nilName       = "nil" consName      = "cons"@@ -717,8 +710,6 @@   , "List"   , "[]"   , "bool"-  -- , "int"-  -- , "real"   , setConName   , charConName   , "Set_sng"
src/Language/Fixpoint/Types/Refinements.hs view
@@ -28,7 +28,6 @@   , Brel (..)   , ExprV (..), Pred   , Expr-  , GradInfo (..)   , pattern PTrue, pattern PTop, pattern PFalse, pattern EBot   , pattern ETimes, pattern ERTimes, pattern EDiv, pattern ERDiv   , pattern EEq@@ -104,11 +103,6 @@    , debruijnIndex -  -- * Gradual Type Manipulation-  , pGAnds, pGAnd-  , HasGradual (..)-  , srcGradInfo-   ) where  import           Prelude hiding ((<>))@@ -122,6 +116,7 @@ import           Data.HashSet              (HashSet) import qualified Data.HashSet              as HashSet import           GHC.Generics              (Generic)+import           GHC.Stack                 (HasCallStack) #if MIN_VERSION_base(4,20,0) import           Data.List                 (partition) #else@@ -148,7 +143,6 @@  instance NFData KVar instance NFData v => NFData (SubstV v)-instance NFData GradInfo instance NFData Constant instance NFData SymConst instance NFData Brel@@ -163,7 +157,6 @@  instance S.Store KVar instance S.Store Subst-instance S.Store GradInfo instance S.Store Constant instance S.Store SymConst instance S.Store Brel@@ -175,7 +168,6 @@ instance B.Binary SymConst instance B.Binary Constant instance B.Binary Bop-instance B.Binary GradInfo instance B.Binary Brel instance B.Binary KVar instance (Hashable a, Eq a, B.Binary a) => B.Binary (HashSet a) where@@ -194,54 +186,18 @@ reftConjuncts (Reft (v, ra)) = [Reft (v, ra') | ra' <- ras']   where     ras'                     = if null ps then ks else conj ps : ks  -- see [NOTE:pAnd-SLOW]-    (ps, ks)                 = partition isConc (refaConjuncts ra)+    (ps, ks)                 = partition isConc (conjuncts ra)  isConc :: Expr -> Bool-isConc p = not (isKvar p || isGradual p)+isConc p = not (isKvar p)  concConjuncts :: Expr -> [Expr]-concConjuncts e = filter isConc (refaConjuncts e)+concConjuncts e = filter isConc (conjuncts e)  isKvar :: Expr -> Bool isKvar (PKVar _ _) = True isKvar _           = False -class HasGradual a where-  isGradual :: a -> Bool-  gVars     :: a -> [KVar]-  gVars _ = []-  ungrad    :: a -> a-  ungrad x = x--instance HasGradual Expr where-  isGradual PGrad{} = True-  isGradual (PAnd xs)  = any isGradual xs-  isGradual _          = False--  gVars (PGrad k _ _ _) = [k]-  gVars (PAnd xs)       = concatMap gVars xs-  gVars _               = []--  ungrad PGrad{} = PTrue-  ungrad (PAnd xs)  = PAnd (ungrad <$> xs )-  ungrad e          = e---instance HasGradual Reft where-  isGradual (Reft (_,r)) = isGradual r-  gVars (Reft (_,r))     = gVars r-  ungrad (Reft (x,r))    = Reft(x, ungrad r)--instance HasGradual SortedReft where-  isGradual = isGradual . sr_reft-  gVars     = gVars . sr_reft-  ungrad r  = r {sr_reft = ungrad (sr_reft r)}--refaConjuncts :: Expr -> [Expr]-refaConjuncts p = [p' | p' <- conjuncts p, not $ isTautoPred p']--- -------------------------------------------------------------------------------- -- | Kvars --------------------------------------------------------------------- --------------------------------------------------------------------------------@@ -249,6 +205,8 @@ newtype KVar = KV { kv :: Symbol }                deriving (Eq, Ord, Data, Typeable, Generic, IsString, ToJSON, FromJSON) +instance ToJSONKey KVar+ intKvar :: Integer -> KVar intKvar = KV . intSymbol "k_" @@ -260,7 +218,6 @@ instance Hashable Bop instance Hashable SymConst instance Hashable Constant-instance Hashable GradInfo instance Hashable v => Hashable (SubstV v) instance Hashable v => Hashable (ExprV v) instance Hashable v => Hashable (ReftV v)@@ -337,6 +294,7 @@           | EApp !(ExprV v) !(ExprV v)           | ENeg !(ExprV v)           | EBin !Bop !(ExprV v) !(ExprV v)+          | ELet !Symbol !(ExprV v) !(ExprV v)           | EIte !(ExprV v) !(ExprV v) !(ExprV v)           | ECst !(ExprV v) !Sort           | ELam !(Symbol, Sort)   !(ExprV v)@@ -351,7 +309,6 @@           | PKVar  !KVar !(SubstV v)           | PAll   ![(Symbol, Sort)] !(ExprV v)           | PExist ![(Symbol, Sort)] !(ExprV v)-          | PGrad  !KVar !(SubstV v) !GradInfo !(ExprV v)           | ECoerc !Sort !Sort !(ExprV v)           deriving (Eq, Show, Ord, Data, Typeable, Generic, Functor, Foldable, Traversable) @@ -405,6 +362,7 @@     go (ECoerc _ _ e)     = go e     go (ENeg e)           = go e     go (EBin _ e1 e2)     = gos [e1, e2]+    go (ELet x e1 e2)     = HashSet.union (go e1) (HashSet.delete x $ go e2)     go (EIte p e1 e2)     = gos [p, e1, e2]     go (ECst e _)         = go e     go (PAnd ps)          = gos ps@@ -451,6 +409,7 @@     go (ECoerc _ _ e)     = go e     go (ENeg e)           = go e     go (EBin _ e1 e2)     = gos [e1, e2]+    go (ELet _ e1 e2)     = gos [e1, e2]     go (EIte p e1 e2)     = gos [p, e1, e2]     go (ECst e _)         = go e     go (PAnd ps)          = gos ps@@ -465,15 +424,6 @@     go (PExist _xts p)     = go p     go _                  = HashMap.empty -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- mkEApp :: LocSymbol -> [Expr] -> Expr mkEApp = eApps . EVar . val @@ -520,6 +470,7 @@     go (EVar _)        = 1     go (ENeg e)        = go e     go (EBin _ e1 e2)  = go e1 + go e2+    go (ELet _ e1 e2)  = 1 + go e1 + go e2     go (EIte e e1 e2)  = go e + go e1 + go e2     go (ETAbs e _)     = go e     go (ETApp e _)     = go e@@ -532,7 +483,6 @@     go (PAll _ e)      = go e     go (PExist _ e)    = go e     go (PKVar _ _)     = 1-    go (PGrad _ _ _ e) = go e     go (ECoerc _ _ e)  = go e  type Reft = ReftV Symbol@@ -574,9 +524,6 @@ encodeSymConst        :: SymConst -> Symbol encodeSymConst (SL s) = litSymbol $ symbol s --- _decodeSymConst :: Symbol -> Maybe SymConst--- _decodeSymConst = fmap (SL . symbolText) . unLitSymbol- instance Fixpoint SymConst where   toFix (SL t) = text (show t) @@ -609,6 +556,7 @@   toFix e@(EApp _ _)   = parens $ hcat $ punctuate " " $ toFix <$> (f:es) where (f, es) = splitEApp e   toFix (ENeg e)       = parens $ text "-"  <+> parens (toFix e)   toFix (EBin o e1 e2) = parens $ sep [toFix e1  <+> toFix o, nest 2 (toFix e2)]+  toFix (ELet x e1 e2) = parens $ sep [text "let" <+> toFix x <+> text "=" <+> toFix e1 <+> text "in", nest 2 (toFix e2)]   toFix (EIte p e1 e2) = parens $ sep [text "if" <+> toFix p <+> text "then", nest 2 (toFix e1), text "else", nest 2 (toFix e2)]   -- toFix (ECst e _so)   = toFix e   toFix (ECst e so)    = parens $ toFix e   <+> text " : " <+> toFix so@@ -623,15 +571,14 @@   toFix (POr  ps)      = text "||" <+> toFix ps   toFix (PAtom r e1 e2)  = parens $ sep [ toFix e1 <+> toFix r, nest 2 (toFix e2)]   toFix (PKVar k su)     = toFix k <-> toFix su-  toFix (PAll xts p)     = "forall" <+> (toFix xts+  toFix (PAll xts p)     = parens $ "forall" <+> (toFix xts                                         $+$ ("." <+> toFix p))-  toFix (PExist xts p)   = "exists" <+> (toFix xts+  toFix (PExist xts p)   = parens $ "exists" <+> (toFix xts                                         $+$ ("." <+> toFix p))   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)   = parens (text "coerce" <+> toFix a <+> text "~" <+> toFix t <+> text "in" <+> toFix e)-  toFix (ELam (x,s) e)   = text "lam" <+> toFix x <+> ":" <+> toFix s <+> "." <+> toFix e+  toFix (ELam (x,s) e)   = parens (char '\\' <+> toFix x <+> ":" <+> toFix s <+> "->" <+> toFix e)    simplify = simplifyExpr dedup     where@@ -664,10 +611,6 @@           else if sq == PFalse then PNot sp           else PIff sp sq -    go (PGrad k su i e)-      | isContraPred e      = PFalse-      | otherwise           = PGrad k su i (go e)-     go (PAnd ps)       | any isContraPred ps = PFalse                            -- Note: Performance of some tests is very sensitive to this code. See #480@@ -789,6 +732,10 @@                                    pprintTidy k o         <+>                                    pprintPrec (zo+1) k e2     where zo = opPrec o+  pprintPrec _ k (ELet x e1 e2)  = parens+                                   "let"  <+> toFix x <+> "=" <+> pprintTidy  k e1  <+>+                                   "in"   <+> pprintTidy k e2+   pprintPrec z k (EIte p e1 e2)  = parensIf (z > zi) $                                    "if"   <+> pprintPrec (zi+1) k p  <+>                                    "then" <+> pprintPrec (zi+1) k e1 <+>@@ -824,19 +771,18 @@                                    pprintTidy k r         <+>                                    pprintPrec (za+1) k e2     where za = 4-  pprintPrec _ k (PAll xts p)    = pprintQuant k "forall" xts p-  pprintPrec _ k (PExist xts p)  = pprintQuant k "exists" xts p+  pprintPrec z k (PAll xts p)    = parensIf (z > 0) $ pprintQuant k "forall" xts p+  pprintPrec z k (PExist xts p)  = parensIf (z > 0) $ 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-  pprintPrec z k (PGrad x _ _ e) = pprintPrec z k e <+> "&&" <+> toFix x -- "??"  pprintQuant   :: (Ord v, Fixpoint v, PPrint v)   => Tidy -> Doc -> [(Symbol, Sort)] -> ExprV v -> Doc-pprintQuant k d xts p = (d <+> toFix xts)+pprintQuant k d xts p = (d <+> pprintTidy k xts)                         $+$                         ("  ." <+> pprintTidy k p) @@ -930,7 +876,7 @@  -- | 'conj' is a fast version of 'pAnd' needed for the ebind tests conj :: [Pred] -> Pred-conj []  = PFalse+conj []  = PTrue conj [p] = p conj ps  = PAnd ps @@ -1011,17 +957,6 @@ reftBind (Reft (x, _)) = x  --------------------------------------------------------------- | Gradual Type Manipulation  ------------------------------------------------------------------------------------------pGAnds :: (Fixpoint v, Ord v) => [ExprV v] -> ExprV v-pGAnds = foldl' pGAnd PTrue--pGAnd :: (Fixpoint v, Ord v) => ExprV v -> ExprV v -> ExprV v-pGAnd (PGrad k su i p) q = PGrad k su i (pAnd [p, q])-pGAnd p (PGrad k su i q) = PGrad k su i (pAnd [p, q])-pGAnd p q              = pAnd [p,q]-------------------------------------------------------------- -- | Generally Useful Refinements -------------------------- ------------------------------------------------------------ @@ -1079,7 +1014,7 @@   -- substa f  = substf (EVar . f)    substf :: (Symbol -> Expr) -> a -> a-  subst  :: Subst -> a -> a+  subst  :: HasCallStack => Subst -> a -> a   subst1 :: a -> (Symbol, Expr) -> a   subst1 y (x, e) = subst (Su $ M.fromList [(x,e)]) y 
+ src/Language/Fixpoint/Types/SMTPrint.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE CPP                #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE ViewPatterns #-}++module Language.Fixpoint.Types.SMTPrint where+++import qualified Language.Fixpoint.Misc  as Misc+import qualified Text.PrettyPrint.HughesPJ.Compat as P+import qualified Language.Fixpoint.Types.PrettyPrint as F+import qualified Language.Fixpoint.Types.Names as F+import qualified Language.Fixpoint.Types.Sorts as F+import qualified Language.Fixpoint.Types.Spans as F+import qualified Language.Fixpoint.Types.Refinements as F+-- import qualified Language.Fixpoint.Types.Constraints as F++-----------------------------------------------------------------------------------------------------------------+-- Human readable but robustly parseable SMT-LIB format pretty printer+-----------------------------------------------------------------------------------------------------------------+class ToHornSMT a where+  toHornSMT :: a -> P.Doc+++instance ToHornSMT F.Symbol where+  toHornSMT s = F.pprint s++++toHornWithBinders :: (ToHornSMT a, ToHornSMT t) => P.Doc -> [(F.Symbol, t)] -> a -> P.Doc+toHornWithBinders name xts p =  P.parens (name P.<+> toHornSMT xts P.<+> toHornSMT p)++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++toHornAnd :: (a -> P.Doc) -> [a] -> P.Doc+toHornAnd f xs = P.parens (P.vcat ("and" : (P.nest 1 . f <$> xs)))+++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)+toHornSort (F.FNatNum x)  = P.integer x++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 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.ELet x e1 e2)  = toHornMany ["let", toHornSMT [(x, e1)], toHornSMT 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]++toHornOp :: ToHornSMT a => P.Doc -> [a] -> P.Doc+toHornOp op es = toHornMany (op : (toHornSMT <$> es))
src/Language/Fixpoint/Types/Solutions.hs view
@@ -7,13 +7,11 @@ {-# LANGUAGE MultiParamTypeClasses      #-} {-# LANGUAGE TypeOperators              #-} {-# LANGUAGE GADTs                      #-}-{-# LANGUAGE BangPatterns               #-} {-# LANGUAGE PatternGuards              #-} {-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE DeriveAnyClass             #-} {-# LANGUAGE StandaloneDeriving         #-} {-# LANGUAGE DeriveDataTypeable         #-}-{-# LANGUAGE TupleSections              #-}  {-# OPTIONS_GHC -Wno-name-shadowing     #-} @@ -23,49 +21,39 @@ module Language.Fixpoint.Types.Solutions (    -- * Solution tables-    Solution, GSolution-  , Sol (gMap, sEnv, sEbd, sxEnv)-  , updateGMap, updateGMapWithKey-  , sHyp-  , sScp+    Solution+  , Sol (..)   , CMap    -- * Solution elements-  , Hyp, Cube (..), QBind, GBind+  , Hyp, Cube (..), QBind (..)   , EQual (..)-  , EbindSol (..)    -- * Equal elements   , eQual   , trueEqual -  -- * Gradual Solution elements-  , qbToGb, gbToQbs, gbEquals, equalsGb, emptyGMap, qbExprs+  , qbExprs    -- * Solution Candidates (move to SolverMonad?)   , Cand -  -- * Constructor-  , fromList-   -- * Update   , update-  , updateEbind    -- * Lookup   , lookupQBind-  , lookup, glookup+  , lookup    -- * Manipulating QBind   , qb   , qbPreds   , qbFilter   , qbFilterM-  , gbFilterM     -- * Conversion for client-  , result, resultGradual+  , result     -- * "Fast" Solver (DEPRECATED as unsound)   , Index  (..)@@ -77,7 +65,6 @@ import           Prelude hiding (lookup) import           GHC.Generics import           Control.DeepSeq-import           Control.Monad.Reader import           Data.Hashable import qualified Data.Maybe                 as Mb import qualified Data.HashMap.Strict        as M@@ -87,62 +74,41 @@ import           Control.Monad (filterM) import           Language.Fixpoint.Misc import           Language.Fixpoint.Types.PrettyPrint--- import           Language.Fixpoint.Types.Config  as Cfg import           Language.Fixpoint.Types.Spans import           Language.Fixpoint.Types.Names import           Language.Fixpoint.Types.Sorts-import           Language.Fixpoint.Types.Theories import           Language.Fixpoint.Types.Refinements import           Language.Fixpoint.Types.Environments import           Language.Fixpoint.Types.Constraints import           Language.Fixpoint.Types.Substitutions-import           Language.Fixpoint.SortCheck (ElabM, ElabParam(..), elaborate) import           Text.PrettyPrint.HughesPJ.Compat  ----------------------------------------------------------------------------------- | Update Solution ---------------------------------------------------------------------------------------------------------------------------------------------update :: Sol a QBind -> [KVar] -> [(KVar, EQual)] -> (Bool, Sol a QBind)+-- | Update Solution+--+-- @update s kqs@ sets in @s@ each KVar in @kqs@ to the corresponding QBind.+--+-- Yields a pair @(b, s')@ where @b@ is true if the mapping of any KVar was+-- changed.+--+-- Precondition: @kqs@ contains no duplicate KVars.+--+update :: Sol QBind -> [(KVar, QBind)] -> (Bool, Sol QBind) ---------------------------------------------------------------------------------update s ks kqs = {- tracepp msg -} (or bs, s')-  where-    kqss        = groupKs ks kqs-    (bs, s')    = folds update1 s kqss-    -- msg      = printf "ks = %s, s = %s" (showpp ks) (showpp s)--folds   :: (a -> b -> (c, a)) -> a -> [b] -> ([c], a)-folds f b = L.foldl' step ([], b)-  where-     step (cs, acc) x = (c:cs, x')-       where-         (c, x')      = f acc x--groupKs :: [KVar] -> [(KVar, EQual)] -> [(KVar, QBind)]-groupKs ks kqs = [ (k, QB eqs) | (k, eqs) <- M.toList $ groupBase m0 kqs ]-  where-    m0         = M.fromList $ (,[]) <$> ks--update1 :: Sol a QBind -> (KVar, QBind) -> (Bool, Sol a QBind)-update1 s (k, qs) = (change, updateK k qs s)+update s kqs = L.foldl' step (False, s) kqs   where-    oldQs         = lookupQBind s k-    change        = qbSize oldQs /= qbSize qs-+    step :: (Bool, Sol QBind) -> (KVar, QBind) -> (Bool, Sol QBind)+    step (changed, s) (k, qs) = (changed || distinctSizes, updateK k qs s)+      where+        oldQs = lookupQBind s k+        distinctSizes = qbSize oldQs /= qbSize qs  -------------------------------------------------------------------------------- -- | The `Solution` data type -------------------------------------------------- ---------------------------------------------------------------------------------type Solution  = Sol () QBind-type GSolution = Sol (((Symbol, Sort), Expr), GBind) QBind+type Solution  = Sol QBind newtype QBind  = QB [EQual]   deriving (Show, Data, Typeable, Generic, Eq)-newtype GBind  = GB [[EQual]] deriving (Show, Data, Typeable, Generic) -emptyGMap :: GSolution -> GSolution-emptyGMap sol = mapGMap sol (\(x,_) -> (x, GB []))--updateGMapWithKey :: [(KVar, QBind)] -> GSolution -> GSolution-updateGMapWithKey kqs sol = sol {gMap = L.foldl' (\m (k, QB eq) -> M.adjust (\(x, GB eqs) -> (x, GB (if eq `elem` eqs then eqs else eq:eqs))) k m) (gMap sol) kqs }- qb :: [EQual] -> QBind qb = QB @@ -152,22 +118,6 @@ qbExprs :: QBind -> [Expr] qbExprs (QB xs) = eqPred <$> xs -qbToGb :: QBind -> GBind-qbToGb (QB xs) = GB $ map (:[]) xs--gbToQbs :: GBind -> [QBind]-gbToQbs (GB [])  = [QB [trueEqual]]-gbToQbs (GB ess) = QB <$> ess--gbEquals :: GBind -> [[EQual]]-gbEquals (GB eqs) = eqs--equalsGb :: [[EQual]] -> GBind-equalsGb = GB--gbFilterM :: Monad m => ([EQual] -> m Bool) -> GBind -> m GBind-gbFilterM f (GB eqs) = GB <$> filterM f eqs- qbSize :: QBind -> Int qbSize = length . qbEQuals @@ -178,87 +128,41 @@ qbFilterM f (QB eqs) = QB <$> filterM f eqs  instance NFData QBind-instance NFData GBind  instance PPrint QBind where   pprintTidy k = pprintTidy k . qbEQuals  ----------------------------------------------------------------------------------- | An `EbindSol` contains the relevant information for an existential-binder;---   (See tests/pos/ebind-*.fq for examples.) This is either---   1. the constraint whose HEAD is a singleton that defines the binder, OR---   2. the solved out TERM that we should use in place of the ebind at USES.----------------------------------------------------------------------------------data EbindSol-  = EbDef [SimpC ()] Symbol -- ^ The constraint whose HEAD "defines" the Ebind-                             -- and the @Symbol@ for that EBind-  | EbSol Expr             -- ^ The solved out term that should be used at USES.-  | EbIncr                 -- ^ EBinds not to be solved for (because they're currently being solved for)-   deriving (Show, Generic, NFData)--instance PPrint EbindSol where-  pprintTidy k (EbDef i x) = "EbDef:" <+> pprintTidy k i <+> pprintTidy k x-  pprintTidy k (EbSol e)   = "EbSol:" <+> pprintTidy k e-  pprintTidy _ EbIncr    = "EbIncr"-----------------------------------------------------------------------------------updateEbind :: Sol a b -> BindId -> Pred -> Sol a b----------------------------------------------------------------------------------updateEbind s i !e = case M.lookup i (sEbd s) of-  Nothing         -> errorstar $ "updateEBind: Unknown ebind " ++ show i-  Just (EbSol e0) -> errorstar $ "updateEBind: Re-assigning ebind " ++ show i ++ " with solution: " ++ show e0-  Just _          -> s { sEbd = M.insert i (EbSol e) (sEbd s) }---------------------------------------------------------------------------------- -- | A `Sol` contains the various indices needed to compute a solution, --   in particular, to compute `lhsPred` for any given constraint. ---------------------------------------------------------------------------------data Sol b a = Sol-  { sEnv :: !SymEnv                      -- ^ Environment used to elaborate solutions-  , sMap :: !(M.HashMap KVar a)          -- ^ Actual solution (for cut kvar)-  , gMap :: !(M.HashMap KVar b)          -- ^ Solution for gradual variables+data Sol a = Sol+  { sMap :: !(M.HashMap KVar a)          -- ^ Actual solution (for cut kvar)   , sHyp :: !(M.HashMap KVar Hyp)        -- ^ Defining cubes  (for non-cut kvar)-  , sScp :: !(M.HashMap KVar IBindEnv)   -- ^ Set of allowed binders for kvar-  , sEbd :: !(M.HashMap BindId EbindSol) -- ^ EbindSol for each existential binder-  , sxEnv :: !(SEnv (BindId, Sort))      --   TODO: merge with sEnv? used for sorts of ebinds to solve ebinds in lhsPred+  , sScp :: !(M.HashMap KVar IBindEnv)   -- ^ Set of binders which are in scope for every+                                         -- occurrence of the kvar   } deriving (Generic) -deriving instance (NFData b, NFData a) => NFData (Sol b a)--updateGMap :: Sol b a -> M.HashMap KVar b -> Sol b a-updateGMap sol gmap = sol {gMap = gmap}--mapGMap :: Sol b a -> (b -> b) -> Sol b a-mapGMap sol f = sol {gMap = M.map f (gMap sol)}+deriving instance NFData a => NFData (Sol a) -instance Semigroup (Sol a b) where-  s1 <> s2 = Sol { sEnv  = sEnv s1  <> sEnv s2-                 , sMap  = sMap s1  <> sMap s2-                 , gMap  = gMap s1  <> gMap s2+instance Semigroup (Sol a) where+  s1 <> s2 = Sol { sMap  = sMap s1  <> sMap s2                  , sHyp  = sHyp s1  <> sHyp s2                  , sScp  = sScp s1  <> sScp s2-                 , sEbd  = sEbd s1  <> sEbd s2-                 , sxEnv = sxEnv s1 <> sxEnv s2                  } -instance Monoid (Sol a b) where-  mempty = Sol { sEnv = mempty-               , sMap = mempty-               , gMap = mempty+instance Monoid (Sol a) where+  mempty = Sol { sMap = mempty                , sHyp = mempty                , sScp = mempty-               , sEbd = mempty-               , sxEnv = mempty                }   mappend = (<>) -instance Functor (Sol a) where-  fmap f (Sol e s m1 m2 m3 m4 m5) = Sol e (f <$> s) m1 m2 m3 m4 m5+instance Functor Sol where+  fmap f (Sol s m1 m2) = Sol (f <$> s) m1 m2 -instance (PPrint a, PPrint b) => PPrint (Sol a b) where-  pprintTidy k s = vcat [ "sMap :=" <+> pprintTidy k (sMap s)-                        , "sEbd :=" <+> pprintTidy k (sEbd s)-                        ]+instance PPrint a => PPrint (Sol a) where+  pprintTidy k s = vcat [ "sMap :=" <+> pprintTidy k (sMap s) ]  -------------------------------------------------------------------------------- -- | A `Cube` is a single constraint defining a KVar ---------------------------@@ -278,78 +182,27 @@ instance Show Cube where   show = showpp ---------------------------------------------------------------------------------result :: Sol a QBind -> M.HashMap KVar Expr----------------------------------------------------------------------------------result s = sMap $ pAnd . fmap eqPred . qbEQuals <$> s------------------------------------------------------------------------------------resultGradual :: GSolution -> M.HashMap KVar (Expr, [Expr])+result :: Sol QBind -> M.HashMap KVar Expr ---------------------------------------------------------------------------------resultGradual s = fmap go' (gMap s)-  where-    go' ((_,e), GB eqss)-     = (e, [PAnd $ fmap eqPred eqs | eqs <- eqss])+result s = pAnd . fmap eqPred . qbEQuals <$> sMap s   ----------------------------------------------------------------------------------- | Create a Solution -------------------------------------------------------------------------------------------------------------------------------------------fromList :: SymEnv-         -> [(KVar, a)]-         -> [(KVar, b)]-         -> [(KVar, Hyp)]-         -> M.HashMap KVar IBindEnv-         -> [(BindId, EbindSol)]-         -> SEnv (BindId, Sort)-         -> Sol a b-fromList env kGs kXs kYs z ebs xbs-        = Sol env kXm kGm kYm z ebm xbs-  where-    kXm = M.fromList kXs-    kYm = M.fromList kYs-    kGm = M.fromList kGs-    ebm = M.fromList ebs-----------------------------------------------------------------------------------qbPreds :: String -> Sol a QBind -> Subst -> QBind -> ElabM [(Pred, EQual)]+qbPreds :: Subst -> QBind -> [(Pred, EQual)] ---------------------------------------------------------------------------------qbPreds msg s su (QB eqs) =-  do ef <- ask-     pure [ (elabPred ef eq, eq) | eq <- eqs ]-  where-    elabPred ef eq = elaborate (ElabParam ef (atLoc eq $ "qbPreds:" ++ msg) env)-                   . subst su-                   . eqPred-                   $ eq-    env            = sEnv s+qbPreds su (QB eqs) =  [ (subst su $ eqPred eq, eq) | eq <- eqs ]  -------------------------------------------------------------------------------- -- | Read / Write Solution at KVar --------------------------------------------- ---------------------------------------------------------------------------------lookupQBind :: Sol a QBind -> KVar -> QBind+lookupQBind :: Sol QBind -> KVar -> QBind -------------------------------------------------------------------------------- lookupQBind s k = {- tracepp _msg $ -} Mb.fromMaybe (QB []) (lookupElab s k)   where     _msg        = "lookupQB: k = " ++ show k  ---------------------------------------------------------------------------------glookup :: GSolution -> KVar -> Either Hyp (Either QBind (((Symbol, Sort), Expr), GBind))----------------------------------------------------------------------------------glookup s k-  | Just gbs <- M.lookup k (gMap s)-  = Right (Right gbs)-  | Just cs  <- M.lookup k (sHyp s) -- non-cut variable, return its cubes-  = Left cs-  | Just eqs <- lookupElab s k-  = Right (Left eqs)                 -- TODO: don't initialize kvars that have a hyp solution-  | otherwise-  = errorstar $ "solLookup: Unknown kvar " ++ show k-------------------------------------------------------------------------------------lookup :: Sol a QBind -> KVar -> Either Hyp QBind+lookup :: Sol QBind -> KVar -> Either Hyp QBind -------------------------------------------------------------------------------- lookup s k   | Just cs  <- M.lookup k (sHyp s) -- non-cut variable, return its cubes@@ -359,11 +212,11 @@   | otherwise   = errorstar $ "solLookup: Unknown kvar " ++ show k -lookupElab :: Sol b QBind -> KVar -> Maybe QBind+lookupElab :: Sol QBind -> KVar -> Maybe QBind lookupElab s k = M.lookup k (sMap s)  ---------------------------------------------------------------------------------updateK :: KVar -> a -> Sol b a -> Sol b a+updateK :: KVar -> a -> Sol a -> Sol a -------------------------------------------------------------------------------- updateK k qs s = s { sMap = M.insert k qs (sMap s) --                 , sBot = M.delete k    (sBot s)@@ -381,8 +234,8 @@ -------------------------------------------------------------------------------- data EQual = EQL   { eqQual :: !Qualifier-  , eqPred  :: !Expr-  , _eqArgs :: ![Expr]+  , eqPred  :: !Expr      -- ^ predicate obtained by instantiating the qualifier+  , _eqArgs :: ![Expr]    -- ^ actual arguments used to instantiate the qualifier   } deriving (Eq, Show, Data, Typeable, Generic)  instance Loc EQual where@@ -396,7 +249,7 @@  instance NFData EQual -{- EQL :: q:_ -> p:_ -> ListX F.Expr {q_params q} -> _ @-}+-- | @eQual q xs@ instantiates @q@ with the arguments in @xs@ eQual :: Qualifier -> [Symbol] -> EQual eQual q xs = {- tracepp "eQual" $ -} EQL q p es   where
src/Language/Fixpoint/Types/Sorts.hs view
@@ -34,11 +34,13 @@   , strFTyCon   , setFTyCon   , mapFTyCon -- TODO: hide these+  , ffldFTyCon   , mapFVar   , basicSorts, intSort, realSort, boolSort, strSort, funcSort   -- , bitVec32Sort, bitVec64Sort   , setSort, bitVecSort, bagSort   , arraySort+  , finfieldSort   , sizedBitVecSort   , mapSort, charSort   , listFTyCon@@ -66,7 +68,7 @@   , sortSymbols   , substSort -  , isBool, isNumeric, isReal, isString, isSet, isMap, isBag, isArray, isPolyInst+  , isBool, isNumeric, isReal, isString, isSet, isMap, isBag, isArray, isFinfield, isPolyInst    -- * User-defined ADTs   , DataField (..)@@ -152,7 +154,7 @@ defStrInfo  = False  charFTyCon, intFTyCon, boolFTyCon, realFTyCon, funcFTyCon, numFTyCon :: FTycon-strFTyCon, listFTyCon, mapFTyCon, bagFTyCon, setFTyCon :: FTycon+strFTyCon, listFTyCon, mapFTyCon, bagFTyCon, setFTyCon, ffldFTyCon :: FTycon intFTyCon  = TC (dummyLoc "int"       ) numTcInfo boolFTyCon = TC (dummyLoc boolLConName) defTcInfo realFTyCon = TC (dummyLoc "real"      ) realTcInfo@@ -164,6 +166,7 @@ setFTyCon  = TC (dummyLoc setConName  ) defTcInfo mapFTyCon  = TC (dummyLoc mapConName  ) defTcInfo bagFTyCon  = TC (dummyLoc bagConName  ) defTcInfo+ffldFTyCon = TC (dummyLoc ffldConName ) defTcInfo  isListConName :: LocSymbol -> Bool isListConName x = c == listConName || c == listLConName --"List"@@ -205,6 +208,14 @@ isArrayTC :: FTycon -> Bool isArrayTC (TC z _) = isArrayConName z +isFinfieldConName :: LocSymbol -> Bool+isFinfieldConName x = c == ffldConName+  where+    c           = val x++isFinfieldTC :: FTycon -> Bool+isFinfieldTC (TC z _) = isFinfieldConName z+ sizeBv :: FTycon -> Maybe Int sizeBv tc = do   let s = val $ fTyconSymbol tc@@ -293,6 +304,7 @@         go t@FReal       = t         go t@FNum        = t         go t@FFrac       = t+        go t@(FNatNum _) = t  -------------------------------------------------------------------------------- -- | Sorts ---------------------------------------------------------------------@@ -301,12 +313,13 @@           | FReal           | FNum                 -- ^ numeric kind for Num tyvars           | FFrac                -- ^ numeric kind for Fractional tyvars-          | FObj  !Symbol        -- ^ uninterpreted type-          | FVar  !Int           -- ^ fixpoint type variable-          | FFunc !Sort !Sort    -- ^ function-          | FAbs  !Int !Sort     -- ^ type-abstraction-          | FTC   !FTycon-          | FApp  !Sort !Sort    -- ^ constructed type+          | FObj    !Symbol      -- ^ uninterpreted type+          | FVar    !Int         -- ^ fixpoint type variable+          | FFunc   !Sort !Sort  -- ^ function+          | FAbs    !Int !Sort   -- ^ type-abstraction+          | FTC     !FTycon+          | FApp    !Sort !Sort  -- ^ constructed type+          | FNatNum !Integer     -- ^ typelevel natural numeral             deriving (Eq, Ord, Show, Data, Typeable, Generic, ToJSON, FromJSON)  instance PPrint Sort where@@ -423,6 +436,10 @@ isArray (FTC c) = isArrayTC c isArray _       = False +isFinfield :: Sort -> Bool+isFinfield (FTC c) = isFinfieldTC c+isFinfield _       = False+ isChar :: Sort -> Bool isChar (FTC c) = c == charFTyCon isChar _       = False@@ -490,6 +507,7 @@ toFixSort t@(FFunc _ _)= toFixAbsApp t toFixSort (FTC c)      = toFix c toFixSort t@(FApp _ _) = toFixFApp (unFApp t)+toFixSort (FNatNum x)  = toFix x  toFixAbsApp :: Sort -> Doc toFixAbsApp (functionSort -> Just (vs, ss, s)) =@@ -571,6 +589,9 @@  arraySort :: Sort -> Sort -> Sort arraySort = FApp . FApp (FTC (symbolFTycon' arrayConName))++finfieldSort :: Sort -> Sort+finfieldSort = FApp (FTC ffldFTyCon)  symbolFTycon' :: Symbol -> FTycon symbolFTycon' = symbolFTycon . dummyLoc
src/Language/Fixpoint/Types/Substitutions.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE FlexibleInstances #-}  {-# OPTIONS_GHC -Wno-orphans   #-}+{-# LANGUAGE InstanceSigs #-}  -- | This module contains the various instances for Subable, --   which (should) depend on the visitors, and hence cannot@@ -12,14 +13,18 @@   , substExcept   , substfExcept   , subst1Except+  , substSymbolsSet+  , rapierSubstExpr   , targetSubstSyms   , filterSubst   , catSubst   , exprSymbolsSet+  , extendSubst   , meetReft   , pprReft   ) where +import           Data.List                 as List import           Data.Maybe import qualified Data.HashMap.Strict       as M import qualified Data.HashSet              as S@@ -61,7 +66,8 @@ targetSubstSyms :: Subst -> [Symbol] targetSubstSyms (Su ms) = syms $ M.elems ms -+substSymbolsSet :: Subst -> S.HashSet Symbol+substSymbolsSet (Su m) = S.unions $ map exprSymbolsSet (M.elems m)  instance Subable () where   syms _      = []@@ -120,17 +126,19 @@ subSymbol Nothing         x = x subSymbol a               b = errorstar (printf "Cannot substitute symbol %s with expression %s" (showFix b) (showFix a)) -substfLam :: (Symbol -> Expr) -> (Symbol, Sort) -> Expr -> Expr-substfLam f s@(x, _) e =  ELam s (substf (\y -> if y == x then EVar x else f y) e)+captureAvoiding :: Symbol -> (Symbol -> Expr) -> Symbol -> Expr+captureAvoiding x f y = if y == x then EVar x else f y  instance Subable Expr where   syms                     = exprSymbols   substa f                 = substf (EVar . f)+  substf :: (Symbol -> Expr) -> Expr -> Expr   substf f (EApp s e)      = EApp (substf f s) (substf f e)-  substf f (ELam x e)      = substfLam f x e+  substf f (ELam (x,t) e)  = ELam (x, t) (substf (captureAvoiding x f) 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 (ELet x e1 e2)  = ELet x (substf f e1) (substf (captureAvoiding x f) e2)   substf f (EIte p e1 e2)  = EIte (substf f p) (substf f e1) (substf f e2)   substf f (ECst e so)     = ECst (substf f e) so   substf f (EVar x)        = f x@@ -141,43 +149,154 @@   substf f (PIff p1 p2)    = PIff (substf f p1) (substf f p2)   substf f (PAtom r e1 e2) = PAtom r (substf f e1) (substf f e2)   substf f (PKVar k (Su su)) = PKVar k (Su $ M.map (substf f) su)-  substf _  (PAll _ _)     = errorstar "substf: FORALL"-  substf f (PGrad k su i e)= PGrad k su i (substf f e)+  substf _ (PAll _ _)      = errorstar "substf: FORALL"+  substf f (PExist xts e)  = PExist xts (substf f e)   substf _  p              = p  -  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)-  subst su (ECst e so)     = ECst (subst su e) so-  subst su (EVar x)        = appSubst su x-  subst su (PAnd ps)       = PAnd $ map (subst su) ps-  subst su (POr  ps)       = POr  $ map (subst su) ps-  subst su (PNot p)        = PNot $ subst su p-  subst su (PImp p1 p2)    = PImp (subst su p1) (subst su p2)-  subst su (PIff p1 p2)    = PIff (subst su p1) (subst su p2)-  subst su (PAtom r e1 e2) = PAtom r (subst su e1) (subst su e2)-  subst su (PKVar k su')   = PKVar k $ su' `catSubst` su-  subst su (PGrad k su' i e) = PGrad k (su' `catSubst` su) i (subst su e)-  subst su (PAll bs p)-          | disjoint su bs = PAll bs $ subst su p --(substExcept su (fst <$> bs)) p-          | otherwise      = errorstar "subst: PAll (without disjoint binds)"-  subst su (PExist bs p)-          | disjoint su bs = PExist bs $ subst su p --(substExcept su (fst <$> bs)) p-          | otherwise      = errorstar ("subst: EXISTS (without disjoint binds)" ++ show (bs, su, p))-  subst _  p               = p+  subst = go+    where+      -- The auxiliary go function skips the HasCallStack constraint on every+      -- recursive call. In case of error, the call stack only contains the+      -- point at which subst was first called.+      go su e0 = case e0 of+        EApp f e ->+          EApp (go su f) (go su e)+        ELam x e ->+          let su' = removeSubst su (fst x)+           in ELam x (go su' e)+        ELet x e1 e2 ->+          let su' = removeSubst su x+           in ELet x (go su e1) (go su' e2)+        ECoerc a t e ->+          ECoerc a t (go su e)+        ENeg e ->+          ENeg (go su e)+        EBin op e1 e2 ->+          EBin op (go su e1) (go su e2)+        EIte p e1 e2 ->+          EIte (go su p) (go su e1) (go su e2)+        ECst e so ->+          ECst (go su e) so+        EVar x ->+          appSubst su x+        PAnd ps ->+          PAnd $ map (go su) ps+        POr  ps ->+          POr  $ map (go su) ps+        PNot p ->+          PNot $ go su p+        PImp p1 p2 ->+          PImp (go su p1) (go su p2)+        PIff p1 p2 ->+          PIff (go su p1) (go su p2)+        PAtom r e1 e2 ->+          PAtom r (go su e1) (go su e2)+        PKVar k su' ->+          PKVar k $ su' `catSubst` su+        PAll bs p+          | disjoint su bs ->+            PAll bs $ go su p --(substExcept su (fst <$> bs)) p+          | otherwise ->+            errorstar $ unlines+              [ "subst: FORALL without disjoint binds"+              , "su: " ++ showpp su+              , "expr: " ++ showpp e0+              ]+        PExist bs p+          | disjoint su bs ->+            PExist bs $ go su p --(substExcept su (fst <$> bs)) p+          | otherwise ->+            errorstar $ unlines+              [ "subst: EXISTS without disjoint binds"+              , "su: " ++ showpp su+              , "expr: " ++ showpp e0+              ]+        p ->+          p  removeSubst :: Subst -> Symbol -> Subst removeSubst (Su su) x = Su $ M.delete x su +-- | Rapier style capture-avoiding substitution+--+-- The scope set parameter must contain any symbols that are expected+-- to appear free in the result expression. Typically, this is the set of+-- symbols that are free in the range of the substitution, plus any symbols+-- that are already free in the input expression.+rapierSubstExpr :: S.HashSet Symbol -> Subst -> Expr -> Expr+rapierSubstExpr s su e0 =+  let go = rapierSubstExpr+   in case e0 of+    EApp f e -> EApp (go s su f) (go s su e)+    ELam (x, t) e ->+      if x `S.member` s then+        let x' = fresh x+            su' = extendSubst su x (EVar x')+         in ELam (x', t) (go (S.insert x' s) su' e)+      else+        ELam (x, t) (go (S.insert x s) (removeSubst su x) e)+    ELet x e1 e2 ->+      if x `S.member` s then+        let x' = fresh x+            su' = extendSubst su x (EVar x')+         in ELet x' (go s su e1) (go (S.insert x' s) su' e2)+      else+        let su' = removeSubst su x+         in ELet x (go s su e1) (go (S.insert x s) su' e2)++    ECoerc a t e -> ECoerc a t (go s su e)+    ENeg e -> ENeg (go s su e)+    EBin op e1 e2 -> EBin op (go s su e1) (go s su e2)+    EIte p e1 e2 -> EIte (go s su p) (go s su e1) (go s su e2)+    ECst e so -> ECst (go s su e) so+    EVar x -> appSubst su x+    PAnd ps -> PAnd $ map (go s su) ps+    POr ps -> POr $ map (go s su) ps+    PNot p -> PNot $ go s su p+    PImp p1 p2 -> PImp (go s su p1) (go s su p2)+    PIff p1 p2 -> PIff (go s su p1) (go s su p2)+    PAtom r e1 e2 -> PAtom r (go s su e1) (go s su e2)+    PKVar k su' -> PKVar k $ catSubstGo su' su+    PAll bs p ->+      let mfs = map (maybeFresh . fst) bs+          fs = map (either (\x -> (x, x)) id) mfs+          su' = List.foldl' (\su1 (x, x') -> extendSubst su1 x (EVar x')) su fs+          bs' = zip (map (either id snd) mfs) (map snd bs)+          s' = foldr (S.insert . fst) s bs'+       in+          PAll bs' $ go s' su' p+    PExist bs p ->+      let mfs = map (maybeFresh . fst) bs+          fs = map (either (\x -> (x, x)) id) mfs+          su' = List.foldl' (\su1 (x, x') -> extendSubst su1 x (EVar x')) su fs+          bs' = zip (map (either id snd) mfs) (map snd bs)+          s' = foldr (S.insert . fst) s bs'+       in+          PExist bs' $ go s' su' p+    p -> p+  where+    fresh :: Symbol -> Symbol+    fresh x = head $ dropWhile (`S.member` s) candidates+      where+        candidates = [ renameSubstSymbol x i | i <- [0..] ]++    maybeFresh x =+      if x `S.member` s then Right (x, fresh x) else Left x++    catSubstGo :: Subst -> Subst -> Subst+    catSubstGo (Su s1) su2@(Su s2) = Su $ M.union s1' s2+      where+        s1' = rapierSubstExpr s su2 <$> s1++extendSubst :: Subst -> Symbol -> Expr -> Subst+extendSubst (Su m) x e = Su $ M.insert x e m+ disjoint :: Subst -> [(Symbol, Sort)] -> Bool disjoint (Su su) bs = S.null $ suSyms `S.intersection` bsSyms   where-    suSyms = S.fromList $ syms (M.elems su) ++ syms (M.keys su)-    bsSyms = S.fromList $ syms $ fst <$> bs+    suSyms = S.fromList $ syms (M.elems su) ++ M.keys su+    bsSyms = S.fromList $ fst <$> bs  meetReft :: Reft -> Reft -> Reft meetReft (Reft (v, ra)) (Reft (v', ra'))
src/Language/Fixpoint/Types/Templates.hs view
@@ -46,6 +46,8 @@   = matchesTemplate (xs, t) e matchesTemplate (xs, EBin b t1 t2) (EBin b' e1 e2)   = b == b' && matchesTemplate (xs, t1) e1 && matchesTemplate (xs, t2) e2+matchesTemplate (xs, ELet x t1 t2) (ELet x' e1 e2)+  = x == x' && matchesTemplate (xs, t1) e1 && matchesTemplate (xs, t2) e2 matchesTemplate (xs, EIte t1 t2 t3) (EIte e1 e2 e3)   = matchesTemplate (xs, t1) e1 && matchesTemplate (xs, t2) e2 && matchesTemplate (xs, t3) e3 matchesTemplate (xs, ECst t s) (ECst e s')@@ -72,8 +74,6 @@   = s == s' && matchesTemplate (xs, t) e matchesTemplate (xs, PExist s t) (PExist s' e)   = s == s' && matchesTemplate (xs, t) e-matchesTemplate (xs, PGrad s1 s2 s3 t) (PGrad s1' s2' s3' e)-  = s1 == s1' && s2 == s2' && s3 == s3' && matchesTemplate (xs, t) e matchesTemplate (xs, ECoerc s1 s2 t) (ECoerc s1' s2' e)   = s1 == s1' && s2 == s2' && matchesTemplate (xs, t) e matchesTemplate (_, t) e
src/Language/Fixpoint/Types/Theories.hs view
@@ -20,11 +20,18 @@      -- * Theory Sorts     , SmtSort (..)+    , FuncSort     , sortSmtSort     , isIntSmtSort +    , mergeTopAppls+    , pushAppls+    , popAppls+    , peekAppls+     -- * Symbol Environments     , SymEnv (..)+    , SymM     , symEnv     , symEnvSort     , symEnvTheory@@ -32,9 +39,10 @@     , deleteSymEnv     , insertsSymEnv     , symbolAtName-    , symbolAtSmtName+    , symbolAtSortIndex      -- * Coercing sorts in environments+    , coerceSort     , coerceEnv     , coerceSortEnv     , TheorySymbols(..)@@ -45,12 +53,13 @@ import           Data.Typeable             (Typeable) import           Data.Hashable import           GHC.Generics              (Generic)+import           Control.Applicative+import           Control.Monad.State import           Control.DeepSeq import           Language.Fixpoint.Types.Config import           Language.Fixpoint.Types.PrettyPrint import           Language.Fixpoint.Types.Names import           Language.Fixpoint.Types.Sorts-import           Language.Fixpoint.Types.Errors import           Language.Fixpoint.Types.Environments  import           Text.PrettyPrint.HughesPJ.Compat@@ -69,41 +78,96 @@ -------------------------------------------------------------------------------- -- | 'SymEnv' is used to resolve the 'Sort' and 'Sem' of each 'Symbol' --------------------------------------------------------------------------------++-- | Apply tags already used to declare @apply@ symbols in the SMT solver.+--+-- The tags are organized in a stack because every time we pop the SMT solver+-- state, it forgets the tags declared since the last push.+--+-- Each entry in the stack describes the integer tag corresponding to a+-- particular function sort. Every time we issue a `push` a new level+-- is added to the stack, and correspondingly, a `pop` removes a level.+--+-- See 'seApplsCur' in 'SymEnv' for details about actually declaring the+-- tags to the SMT solver.+type Appls = [M.HashMap FuncSort Int]++lookupAppls :: FuncSort -> Appls -> Maybe Int+lookupAppls fs = foldr (\hm acc -> acc <|> M.lookup fs hm) Nothing++mergeTopAppls :: M.HashMap FuncSort Int -> Appls -> Appls+mergeTopAppls m (top : rest) = (top <> m) : rest+mergeTopAppls m [] = [m]++pushAppls :: Appls -> Appls+pushAppls aps = M.empty : aps++popAppls :: Appls -> Appls+popAppls [] = []+popAppls (_:xs) = xs++peekAppls :: Appls -> Maybe (M.HashMap FuncSort Int)+peekAppls [] = Nothing+peekAppls (x:_) = Just x+ data SymEnv = SymEnv-  { seSort   :: !(SEnv Sort)              -- ^ Sorts of *all* defined symbols-  , seTheory :: !(SEnv TheorySymbol)      -- ^ Information about theory-specific Symbols-  , seData   :: !(SEnv DataDecl)          -- ^ User-defined data-declarations-  , seLits   :: !(SEnv Sort)              -- ^ Distinct Constant symbols-  , seAppls  :: !(M.HashMap FuncSort Int) -- ^ Types at which `apply` was used;-                                           --   see [NOTE:apply-monomorphization]+  { seSort     :: !(SEnv Sort)              -- ^ Sorts of *all* defined symbols+  , seTheory   :: !(SEnv TheorySymbol)      -- ^ Information about theory-specific Symbols+  , seData     :: !(SEnv DataDecl)          -- ^ User-defined data-declarations+  , seLits     :: !(SEnv Sort)              -- ^ Distinct Constant symbols++    -- | Apply tags already declared in the SMT solver.+    --+    -- This is inspected when serializing applications of functions to determine+    -- if a new tag needs to be created for a given function sort+    -- (@funcSortIndex@).+  , seAppls    :: !Appls++    -- | Apply tags that have been created while serializing expressions for the+    -- SMT solver, but which have not been used to declare apply symbols yet in+    -- the SMT solver.+    --+    -- The apply symbols using the tags are declared whenever we need to send+    -- the serialized expressions to the SMT solver (using @funcSortVars@). At+    -- this point, the contents of this map are merged into the top of the+    -- 'seAppls' stack, and @seApplsCur@ is cleared.+  , seApplsCur :: !(M.HashMap FuncSort Int)+  , seIx       :: !Int                      -- ^ Largest unused index for sorts   }   deriving (Eq, Show, Data, Typeable, Generic)  {- type FuncSort = {v:Sort | isFFunc v} @-} type FuncSort = (SmtSort, SmtSort) +-- | Generating SMT expressions is a stateful process because new symbols ('apply', 'coerce',+--   'smt_lambda' and 'lam_arg') need to be emitted with unique ids for each newly encountered+--   function sort. The 'SymM' monad carries the 'SymEnv' state required to track the ids.+--   The state updates are performed in `L.F.Smt.Serialize` (functions `smt2App`, `smt2Coerc`,+--   `smt2Lam` and `smtLamArg`, correspondingly).+type SymM a = State SymEnv a+ instance NFData   SymEnv instance S.Store SymEnv  instance Semigroup SymEnv where-  e1 <> e2 = SymEnv { seSort   = seSort   e1 <> seSort   e2-                    , seTheory = seTheory e1 <> seTheory e2-                    , seData   = seData   e1 <> seData   e2-                    , seLits   = seLits   e1 <> seLits   e2-                    , seAppls  = seAppls  e1 <> seAppls  e2+  e1 <> e2 = SymEnv { seSort     = seSort     e1 <> seSort     e2+                    , seTheory   = seTheory   e1 <> seTheory   e2+                    , seData     = seData     e1 <> seData     e2+                    , seLits     = seLits     e1 <> seLits     e2+                    , seAppls    = zipWith (<>) (seAppls e1) (seAppls e2)+                    , seApplsCur = seApplsCur e1 <> seApplsCur e2+                    , seIx       = seIx       e1 `max` seIx    e2                     }  instance Monoid SymEnv where-  mempty        = SymEnv emptySEnv emptySEnv emptySEnv emptySEnv mempty+  mempty        = SymEnv emptySEnv emptySEnv emptySEnv emptySEnv [] mempty 0   mappend       = (<>)  symEnv :: SEnv Sort -> SEnv TheorySymbol -> [DataDecl] -> SEnv Sort -> [Sort] -> SymEnv-symEnv xEnv fEnv ds ls ts = SymEnv xEnv' fEnv dEnv ls sortMap+symEnv xEnv fEnv ds ls _ = SymEnv xEnv' fEnv dEnv ls [] mempty 0   where     xEnv'   = unionSEnv xEnv wiredInEnv     dEnv    = fromListSEnv [(symbol d, d) | d <- ds]-    sortMap = M.fromList (zip smts [0..])-    smts    = funcSorts dEnv ts  -- | These are "BUILT-in" polymorphic functions which are --   UNINTERPRETED but POLYMORPHIC, hence need to go through@@ -114,88 +178,6 @@   , (tyCastName, FAbs 0 $ FAbs 1 $ FFunc (FVar 0) (FVar 1))   ] ---- | 'funcSorts' attempts to compute a list of all the input-output sorts---   at which applications occur. This is a gross hack; as during unfolding---   we may create _new_ terms with weird new sorts. Ideally, we MUST allow---   for EXTENDING the apply-sorts with those newly created terms.---   the solution is perhaps to *preface* each VC query of the form------      push---      assert p---      check-sat---      pop------   with the declarations needed to make 'p' well-sorted under SMT, i.e.---   change the above to------      declare apply-sorts---      push---      assert p---      check-sat---      pop------   such a strategy would NUKE the entire apply-sort machinery from the CODE base.---   [TODO]: dynamic-apply-declaration--funcSorts :: SEnv DataDecl -> [Sort] -> [FuncSort]-funcSorts dEnv ts = [ (t1, t2) | t1 <- smts, t2 <- smts]-  where-    smts = Misc.sortNub $ concat $ [ tx t1 ++ tx t2 | FFunc t1 t2 <- ts ]-    tx   = inlineArrSetBag False dEnv---- Related to the above, after merging #688, we now allow types other than--- Int to which Arrays/Sets/Bags can be applied.--- However, the `sortSmtSort` function below, previously used in `funcSorts`,--- only instantiates type variables at Ints. This causes the solver to crash--- when PLE generates apply queries for polymorphic sets (see--- https://github.com/ucsd-progsys/liquidhaskell/issues/2438). The following--- pair of functions is a temporary fix for this - it generates additional--- array/set/bag sorts instantiated at all user types for a "polymorphic depth 1"--- (i.e., `Array (Foo Int) Int` but not `Array (Foo (Foo Int)) Int`, to keep--- the applys table from blowing up exponentially). Ultimately, a general--- solution should be implemented for generating ad-hoc sets of applys on the--- fly, as described above.--inlineArrSetBag :: Bool -> SEnv DataDecl -> Sort -> [SmtSort]-inlineArrSetBag isASB env t = go . unAbs $ t-  where-    m = sortAbs t-    go (FFunc _ _)    = [SInt]-    go FInt           = [SInt]-    go FReal          = [SReal]-    go t-      | t == boolSort = [SBool]-      | isString t    = [SString]-    go (FVar _)-      | isASB     = SInt : map (\q -> let dd = snd q in-                                      SData (ddTyCon dd) (replicate (ddVars dd) SInt))-                               (M.toList $ seBinds env)-      | otherwise = [SInt]-    go t-      | (ct:ts) <- unFApp t = inlineArrSetBagFApp m env ct ts-      | otherwise = error "Unexpected empty 'unFApp t'"--inlineArrSetBagFApp :: Int -> SEnv DataDecl -> Sort -> [Sort] -> [SmtSort]-inlineArrSetBagFApp m env = go-  where-    go (FTC c) [a]-      | setConName == symbol c   = SSet <$> inlineArrSetBag True env a-    go (FTC c) [a]-      | bagConName == symbol c   = SBag <$> inlineArrSetBag True env a-    go (FTC c) [a, b]-      | arrayConName == symbol c = SArray <$> inlineArrSetBag True env a <*> inlineArrSetBag True env b-    go (FTC bv) [FTC s]-      | bitVecName == symbol bv-      , Just n <- sizeBv s      = [SBitVec n]-    go s []-      | isString s              = [SString]-    go (FTC c) ts-      | Just n <- tyArgs c env-      , let i = n - length ts   = [SData c ((inlineArrSetBag False env . FAbs m =<< ts) ++ replicate i SInt)]-    go _ _                      = [SInt]-- symEnvTheory :: Symbol -> SymEnv -> Maybe TheorySymbol symEnvTheory x env = lookupSEnv x (seTheory env) @@ -211,20 +193,31 @@ insertsSymEnv :: SymEnv -> [(Symbol, Sort)] -> SymEnv insertsSymEnv = L.foldl' (\env (x, s) -> insertSymEnv x s env) -symbolAtName :: (PPrint a) => Symbol -> SymEnv -> a -> Sort -> Text-symbolAtName mkSym env e = symbolAtSmtName mkSym env e . ffuncSort env-{-# SCC symbolAtName #-}+symbolAtSortIndex :: Symbol -> Int -> Text+symbolAtSortIndex mkSym si = appendSymbolText mkSym . Text.pack . show $ si -symbolAtSmtName :: (PPrint a) => Symbol -> SymEnv -> a -> FuncSort -> Text-symbolAtSmtName mkSym env e =-  -- formerly: intSymbol mkSym . funcSortIndex env e-  appendSymbolText mkSym . Text.pack . show . funcSortIndex env e-{-# SCC symbolAtSmtName #-}+symbolAtName :: Symbol -> Sort -> SymM Text+symbolAtName mkSym s =+  do env <- get+     fsi <- funcSortIndex (ffuncSort env s)+     pure $ symbolAtSortIndex mkSym fsi+{-# SCC symbolAtName #-} -funcSortIndex :: (PPrint a) => SymEnv -> a -> FuncSort -> Int-funcSortIndex env e fs = M.lookupDefault err fs (seAppls env)-  where-    err = panic ("Unknown func-sort: " ++ show fs ++ " for " ++ showpp e)+-- See 'seAppls' and 'seApplsCur' in 'SymEnv' for explanation.+funcSortIndex :: FuncSort -> SymM Int+funcSortIndex fs =+  do env <- get+     let aps = seAppls env+     let apsc = seApplsCur env+     case lookupAppls fs aps of+      Just i  -> pure i+      Nothing ->+        case M.lookup fs apsc of+          Just i  -> pure i+          Nothing ->+           do let i = seIx env+              modify (\env -> env { seApplsCur = M.insert fs i apsc , seIx = 1 + i })+              pure i  ffuncSort :: SymEnv -> Sort -> FuncSort ffuncSort env t      = {- tracepp ("ffuncSort " ++ showpp (t1,t2)) -} (tx t1, tx t2)@@ -292,8 +285,11 @@   | SBool   | SReal   | SString+  --- CVC(5) only   | SSet !SmtSort   | SBag !SmtSort+  | SFFld !Integer+  ---   | SArray !SmtSort !SmtSort   | SBitVec !Int   | SVar    !Int@@ -334,9 +330,11 @@ -- HKT    go t@(FVar _) ts            = SApp (sortSmtSort poly env <$> (t:ts))      go (FTC c) [a]-      | setConName == symbol c  = SSet (sortSmtSort poly env a)+      | setConName == symbol c   = SSet (sortSmtSort poly env a)     go (FTC c) [a]-      | bagConName == symbol c  = SBag (sortSmtSort poly env a)+      | bagConName == symbol c   = SBag (sortSmtSort poly env a)+    go (FTC c) [FNatNum n]+      | ffldConName == symbol c  = SFFld n     go (FTC c) [a, b]       | arrayConName == symbol c = SArray (sortSmtSort poly env a) (sortSmtSort poly env b)     go (FTC bv) [FTC s]@@ -362,6 +360,7 @@   pprintTidy _ SString      = text "Str"   pprintTidy k (SSet a)     = ppParens k (text "Set") [a]   pprintTidy k (SBag a)     = ppParens k (text "Bag") [a]+  pprintTidy _ (SFFld n)    = text "FiniteField" <+> integer n   pprintTidy k (SArray a b) = ppParens k (text "Array") [a, b]   pprintTidy _ (SBitVec n)  = text "BitVec" <+> int n   pprintTidy _ (SVar i)     = text "@" <-> int i@@ -376,13 +375,18 @@ --------------------------------------------------------------------------------  coerceSortEnv :: ElabFlags -> SEnv Sort -> SEnv Sort-coerceSortEnv ef ss = (if elabSetBag ef then coerceSetBagToArray else id) . coerceMapToArray <$> ss+coerceSortEnv ef ss = coerceSort ef <$> ss +coerceSort :: ElabFlags -> Sort -> Sort+coerceSort ef = (if elabSetBag ef then coerceSetBagToArray else id) . coerceMapToArray+ coerceEnv :: ElabFlags -> SymEnv -> SymEnv coerceEnv slv env =-  SymEnv { seSort   = coerceSortEnv slv (seSort env)-         , seTheory = seTheory env-         , seData   = seData   env-         , seLits   = seLits   env-         , seAppls  = seAppls  env+  SymEnv { seSort     = coerceSortEnv slv (seSort env)+         , seTheory   = seTheory env+         , seData     = seData   env+         , seLits     = seLits   env+         , seAppls    = seAppls  env+         , seApplsCur = seApplsCur env+         , seIx       = seIx     env          }
src/Language/Fixpoint/Types/Utils.hs view
@@ -31,14 +31,14 @@ -------------------------------------------------------------------------------- -- | Compute the domain of a kvar ---------------------------------------------------------------------------------kvarDomain :: SInfo a -> KVar -> [Symbol]+kvarDomain :: GInfo c a -> KVar -> [Symbol] -------------------------------------------------------------------------------- kvarDomain si k = domain (bs si) (getWfC si k)  domain :: BindEnv a -> WfC a -> [Symbol] domain be wfc = fst3 (wrft wfc) : map fst (envCs be $ wenv wfc) -getWfC :: SInfo a -> KVar -> WfC a+getWfC :: GInfo c a -> KVar -> WfC a getWfC si k = ws si M.! k  --------------------------------------------------------------------------------@@ -49,19 +49,20 @@ reftFreeVars r@(Reft (v, _)) = S.delete v $ S.fromList $ syms r  ----------------------------------------------------------------------------------- | Split a SortedReft into its concrete and KVar components+-- | Split a SortedReft into its concrete and KVar conjuncts+--+-- Produces @(concrete conjunts, normal kvars)@ ---------------------------------------------------------------------------------sortedReftConcKVars :: Symbol -> SortedReft -> ([Pred], [KVSub], [KVSub])-sortedReftConcKVars x sr = go [] [] [] ves+sortedReftConcKVars :: Symbol -> SortedReft -> ([Pred], [KVSub])+sortedReftConcKVars x sr = go [] [] ves   where     ves                  = [(v, p `subst1` (v, eVar x)) | Reft (v, p) <- rs ]     rs                   = reftConjuncts (sr_reft sr)     t                    = sr_sort sr -    go ps ks gs ((v, PKVar k su    ):xs) = go ps (KVS v t k su:ks) gs xs-    go ps ks gs ((v, PGrad k su _ _):xs) = go ps ks (KVS v t k su:gs) xs-    go ps ks gs ((_, p):xs)              = go (p:ps) ks gs xs-    go ps ks gs []                       = (ps, ks, gs)+    go ps ks ((v, PKVar k su    ):xs) = go ps (KVS v t k su:ks) xs+    go ps ks ((_, p):xs)              = go (p:ps) ks xs+    go ps ks []                       = (ps, ks)   -------------------------------------------------------------------------------
src/Language/Fixpoint/Types/Visitor.hs view
@@ -33,7 +33,7 @@   , envKVars   , envKVarsN   , rhsKVars-  , mapKVars, mapKVars', mapGVars', mapKVarSubsts+  , mapKVars, mapKVars', mapKVarSubsts   , mapExpr, mapExprOnExpr, mapMExpr    -- * Coercion Substitutions@@ -112,6 +112,7 @@       step (EApp e1 e2)       = EApp (vE e1) (vE e2)       step (ENeg e)         = ENeg (vE e)       step (EBin o e1 e2)   = EBin o (vE e1) (vE e2)+      step (ELet x e1 e2)   = ELet x (vE e1) (vE e2)       step (EIte p e1 e2)   = EIte (vE p) (vE e1) (vE e2)       step (ECst e t)       = ECst (vE e) t       step (PAnd ps)        = PAnd (map vE ps)@@ -127,7 +128,6 @@       step (ETApp e s)      = ETApp (vE e) s       step (ETAbs e s)      = ETAbs (vE e) s       step p@(PKVar _ _)    = p-      step (PGrad k su i e) = PGrad k su i (vE e)  instance Visitable Reft where   transE v (Reft (x, ra)) = Reft (x, transE v ra)@@ -164,7 +164,7 @@     aenvEqs = transE v <$> aenvEqs x,     aenvSimpl = transE v <$> aenvSimpl x   }-    + instance Visitable Equation where   transE v eq = eq {     eqBody = transE v (eqBody eq)@@ -180,12 +180,12 @@   rn <- newIORef a   result <- runReaderT (f v c x) rn   finalAcc <- readIORef rn-  return (result, finalAcc) +  return (result, finalAcc)  type FoldM acc = ReaderT (IORef acc) IO  accum :: (Monoid a) => a -> FoldM a ()-accum !z = do +accum !z = do   ref <- ask   liftIO $ modifyIORef' ref (mappend z) @@ -259,6 +259,7 @@     step !c (EApp f e)      = EApp        <$> vE c f  <*> vE c e     step !c (ENeg e)        = ENeg        <$> vE c e     step !c (EBin o e1 e2)  = EBin o      <$> vE c e1 <*> vE c e2+    step !c (ELet x e1 e2)  = ELet x      <$> vE c e1 <*> vE c e2     step !c (EIte p e1 e2)  = EIte        <$> vE c p  <*> vE c e1 <*> vE c e2     step !c (ECst e t)      = (`ECst` t)  <$> vE c e     step !c (PAnd  ps)      = PAnd        <$> (vE c `traverse` ps)@@ -274,7 +275,6 @@     step !c (ETApp e s)     = (`ETApp` s) <$> vE c e     step !c (ETAbs e s)     = (`ETAbs` s) <$> vE c e     step _  p@(PKVar _ _)   = return p-    step !c (PGrad k su i e) = PGrad k su i <$> vE c e  mapKVars :: Visitable t => (KVar -> Maybe Expr) -> t -> t mapKVars f = mapKVars' f'@@ -286,19 +286,9 @@   where     txK (PKVar k su)       | Just p' <- f (k, su) = subst su p'-    txK (PGrad k su _ _)-      | Just p' <- f (k, su) = subst su p'     txK p = p  --mapGVars' :: Visitable t => ((KVar, Subst) -> Maybe Expr) -> t -> t-mapGVars' f            = trans txK-  where-    txK (PGrad k su _ _)-      | Just p' <- f (k, su) = subst su p'-    txK p            = p- mapExpr :: Visitable t => (Expr -> Expr) -> t -> t mapExpr f = trans f @@ -318,6 +308,10 @@         let !e1' = go e1             !e2' = go e2         in EBin o e1' e2'+      ELet x e1 e2 ->+        let !e1' = go e1+            !e2' = go e2+        in ELet x e1' e2'       EIte p e1 e2 ->         let !p' = go p             !e1' = go e1@@ -365,10 +359,7 @@       ETAbs e s ->         let !e' = go e         in ETAbs e' s-      PGrad k su i e ->-        let !e' = go e-        in PGrad k su i e'-      e@PKVar{} -> e+      PKVar k (Su m) -> PKVar k (Su (go <$>m))       e@EVar{} -> e       e@ESym{} -> e       e@ECon{} -> e@@ -408,7 +399,6 @@     go e@(ECon _)      = f e     go e@(EVar _)      = f e     go e@(PKVar _ _)   = f e-    go (PGrad k s i e) = f . PGrad k s i =<< go e     go (ENeg e)        = f . ENeg =<< go e     go (PNot p)        = f . PNot =<< go p     go (ECst e t)      = f . (`ECst` t) =<< go e@@ -423,6 +413,7 @@     go (PImp p1 p2)    = f =<< (PImp        <$>  go p1 <*> go p2          )     go (PIff p1 p2)    = f =<< (PIff        <$>  go p1 <*> go p2          )     go (PAtom r e1 e2) = f =<< (PAtom r     <$>  go e1 <*> go e2          )+    go (ELet x e1 e2)  = f =<< (ELet x      <$>  go e1 <*> go e2          )     go (EIte p e1 e2)  = f =<< (EIte        <$>  go p  <*> go e1 <*> go e2)     go (PAnd ps)       = f . PAnd =<< (go `traverse` ps)     go (POr ps)        = f . POr =<< (go `traverse` ps)@@ -431,7 +422,6 @@ mapKVarSubsts f          = trans txK   where     txK (PKVar k su)   = PKVar k (f k su)-    txK (PGrad k su i e) = PGrad k (f k su) i e     txK p              = p  newtype MInt = MInt Integer -- deriving (Eq, NFData)@@ -475,7 +465,6 @@       ECon _ -> acc       EVar _ -> acc       PKVar k _ -> k : acc-      PGrad k _ _ _ -> k : acc       ENeg e -> go acc e       PNot p -> go acc p       ECst e _t -> go acc e@@ -490,6 +479,7 @@       PImp p1 p2 -> go (go acc p2) p1       PIff p1 p2 -> go (go acc p2) p1       PAtom _r e1 e2 -> go (go acc e2) e1+      ELet _ e1 e2 -> go (go acc e2) e1       EIte p e1 e2 -> go (go (go acc e2) e1) p       PAnd ps -> foldr (flip go) acc ps       POr ps -> foldr (flip go) acc ps@@ -517,7 +507,6 @@  isKvar :: Expr -> Bool isKvar PKVar{} = True-isKvar PGrad{} = True isKvar _       = False  isConc :: Expr -> Bool
src/Language/Fixpoint/Utils/Builder.hs view
@@ -6,6 +6,7 @@   ( fromText   , fromString   , parens+  , quotes   , (<+>)   , parenSeqs   , seqs@@ -31,6 +32,9 @@  parens :: Builder -> Builder parens b = "(" <>  b <> ")"++quotes :: Builder -> Builder+quotes b = "\"" <> b <> "\""  infixl 9 <+> (<+>) :: Builder -> Builder -> Builder
src/Language/Fixpoint/Utils/Files.hs view
@@ -14,6 +14,7 @@   , extFileName   , extFileNameR   , tempDirectory+  , tempFileName   , extModuleName   , withExt   , isExtFile@@ -139,11 +140,10 @@ withExt f ext   =  replaceExtension f (extMap ext)  extFileName     :: Ext -> FilePath -> FilePath-extFileName e f = path </> addExtension file ext-  where-    path        = tempDirectory f-    file        = takeFileName  f-    ext         = extMap e+extFileName e f = tempFileName (addExtension f (extMap e))++tempFileName     :: FilePath -> FilePath+tempFileName f = tempDirectory f </> takeFileName f  tempDirectory   :: FilePath -> FilePath tempDirectory f
− tests/neg/ebind-00.fq
@@ -1,16 +0,0 @@-fixpoint "--eliminate=all"--// bind  0 x1 : {v: int | v = 10 }-ebind 0 x1 : { int }--constraint:-  env [0]-  lhs {v1 : int | v1 = 10}-  rhs {v1 : int | v1 = x1}-  id 1 tag []--constraint:-  env [0]-  lhs {v2 : int | v2 = x1 + 1 }-  rhs {v2 : int | v2 = 110    }-  id 2 tag []
− tests/neg/ebind-01.fq
@@ -1,17 +0,0 @@-fixpoint "--eliminate=all"--bind  1 m  : {v: int | true }-ebind 2 x1 : { int }-// bind  2 x1 : {v: int | v = m + 1 }--constraint:-  env [1; 2]-  lhs {v : int | v = m + 1 }-  rhs {v : int | v = x1    }-  id 1 tag []--constraint:-  env [1; 2]-  lhs {v : int | v = x1 + 1}-  rhs {v : int | v = 20 + m }-  id 2 tag []
− tests/neg/ebind-02.fq
@@ -1,28 +0,0 @@-fixpoint "--eliminate=all"--bind  0 m  : {v: int | true }-bind  1 z  : {v: int | v = m - 1 }-ebind 2 x1 : { int }-// bind  2 x1 : {v: int | v = m + 1 }--constraint:-  env [0; 1]-  lhs {v : int | v = z + 2 }-  rhs {v : int | $k         }-  id 1 tag []--constraint:-  env [0; 2]-  lhs {v : int | $k      }-  rhs {v : int | v = x1 }-  id 2 tag []--constraint:-  env [0; 2]-  lhs {v : int | v = x1 + 1 }-  rhs {v : int | v = m  + 20 }-  id 3 tag []--wf: -  env [0]-  reft {v:int | [$k] }
− tests/neg/ebind-03.fq
@@ -1,45 +0,0 @@-fixpoint "--eliminate=all"--ebind 1 x1 : { int }-ebind 2 x2 : { int }---constraint:-  env [1]-  lhs {v : int | v = 1  }-  rhs {v : int | v = x1 }-  id 1 tag []--constraint:-  env [1]-  lhs {v : int | v = x1 + 1 }-  rhs {v : int | $ka        }-  id 2 tag []--constraint:-  env [2]-  lhs {v : int | $ka    }-  rhs {v : int | v = x2 }-  id 3 tag []--constraint:-  env [2]-  lhs {v : int | v = x2 + 1}-  rhs {v : int | $kb       }-  id 4 tag []--constraint:-  env []-  lhs {v : int | $kb   }-  rhs {v : int | v = 30 } -  id 5 tag []---wf: -  env []-  reft {v:int | [$ka] }--wf: -  env []-  reft {v:int | [$kb] }-
− tests/neg/ebind-04.fq
@@ -1,35 +0,0 @@-fixpoint "--eliminate=all"--ebind 1 x : { int }--constraint:-  env [1]-  lhs {v : int | $k1   }-  rhs {v : int | v = x }-  id 1 tag []--constraint:-  env [1]-  lhs {v : int | v = x + 1 }-  rhs {v : int | $k2       }-  id 2 tag []--constraint:-  env []-  lhs {v : int | v = 3 }-  rhs {v : int | $k1   }-  id 3 tag []--constraint:-  env []-  lhs {v : int | $k2   }-  rhs {v : int | v = 40 }-  id 4 tag []--wf: -  env []-  reft {v:int | [$k1] }--wf: -  env []-  reft {v:int | [$k2] }
− tests/neg/ebind-elim2.fq
@@ -1,26 +0,0 @@-bind  1 a    : { a : int | true }-ebind 2 c    : { int }--wf:-  env [1]-  reft {VV##1 : Tuple | [$k_##1]}--constraint:-  env [1;2]-  lhs {VV##F##4 : int | VV##F##4 = c }-  rhs {VV##F##4 : int | $k_##1[VV##1 := VV##F##4] }-  id 1 tag []--constraint:-  env [1;2]-  lhs {VV##F##5 : int | $k_##1[VV##1:=VV##F##5] }-  rhs {VV##F##5 : int | VV##F##5 = c }-  id 2 tag []--// The following constraint is needed only to prevent eliminate's **sharing** optimization.--constraint:-  env []-  lhs {VV##F##6 : int | $k_##1[VV##1:=VV##F##6] }-  rhs {VV##F##6 : int | VV##F##6 = 0 }-  id 3 tag []
tests/neg/elim-dep-00.fq view
@@ -1,7 +1,7 @@ -qualif False(v:int) : (0 = 1)-qualif Zero(v:int) : (0 = v)-qualif One(v:int) : (1 = v)+qualif False(v:int)  { 0 = 1 }+qualif Zero(v:int)  { 0 = v }+qualif One(v:int)  { 1 = v }  bind 1 x : {v:int | $k2 } 
tests/neg/qualif-template-00.fq view
@@ -1,4 +1,4 @@-qualif Prefix(v:a, z as (moon . $1) : b) : (v = z)+qualif Prefix(v:a, z as (moon . $1) : b)  { v = z }  bind 0  monday  : {v : int | true} bind 10 tuesday : {v : int | true}
tests/neg/qualif-template-01.fq view
@@ -1,6 +1,6 @@ // qualif Goob(v:a, z: b) : (v = z) // qualif Prefix2(v:a, x as (mon . $1) : b, y as (sun . $1)) : (v = x + y)-qualif Prefix(v:a, z as ($1 . sday) : b) : (v = z)+qualif Prefix(v:a, z as ($1 . sday) : b)  { v = z }  bind 0  monday  : {v : int | true} bind 10 tuesday : {v : int | true}
tests/neg/qualif-template-02.fq view
@@ -1,6 +1,6 @@ fixpoint "--eliminate=none" -qualif Prefix2(v:a, x as (sun . $1)  : b, y as (tues . $1) : b) : (v = x + y)+qualif Prefix2(v:a, x as (sun . $1)  : b, y as (tues . $1) : b)  { v = x + y }  bind 0  sunday  : {v : int | v = 6  } bind 1  monday  : {v : int | v = 4  }
tests/neg/test00.fq view
@@ -1,6 +1,6 @@ -qualif Zog(v:a) : (10 <= v)-qualif Bog(v:a, x:a) : (x <= v)+qualif Zog(v:a)  { 10 <= v }+qualif Bog(v:a, x:a)  { x <= v }  bind 0 a : {v: int | $k0} 
tests/neg/test00.hs.fq view
@@ -1,51 +1,51 @@-qualif Fst(v : @(1), y : @(0)): (v = fst([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 29, column 8)-qualif Snd(v : @(1), y : @(0)): (v = snd([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 30, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) > 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 13, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) = 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 14, column 8)-qualif ListZ(v : [@(0)]): (len([v]) = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 16, column 8)-qualif ListZ(v : [@(0)]): (len([v]) >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 17, column 8)-qualif ListZ(v : [@(0)]): (len([v]) > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 18, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 20, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) >= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 21, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) > len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 22, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) <= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 23, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) < len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 24, column 8)-qualif EqLen(v : int, xs : [@(0)]): (v = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 26, column 8)-qualif LenEq(v : [@(0)], x : int): (x = len([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 27, column 8)-qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x + 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 28, column 8)-qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x - 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 29, column 8)-qualif LenAcc(v : int, xs : [@(0)], n : int): (v = (len([xs]) + n)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 30, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 3, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 4, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 5, column 8)-qualif Bot(v : bool): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 6, column 8)-qualif Bot(v : int): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 7, column 8)-qualif CmpZ(v : @(0)): (v < 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 9, column 8)-qualif CmpZ(v : @(0)): (v <= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 10, column 8)-qualif CmpZ(v : @(0)): (v > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 11, column 8)-qualif CmpZ(v : @(0)): (v >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 12, column 8)-qualif CmpZ(v : @(0)): (v = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 13, column 8)-qualif CmpZ(v : @(0)): (v != 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 14, column 8)-qualif Cmp(v : @(0), x : @(0)): (v < x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 16, column 8)-qualif Cmp(v : @(0), x : @(0)): (v <= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 17, column 8)-qualif Cmp(v : @(0), x : @(0)): (v > x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 18, column 8)-qualif Cmp(v : @(0), x : @(0)): (v >= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 19, column 8)-qualif Cmp(v : @(0), x : @(0)): (v = x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 20, column 8)-qualif Cmp(v : @(0), x : @(0)): (v != x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 21, column 8)-qualif One(v : int): (v = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 28, column 8)-qualif True(v : bool): (? v) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 29, column 8)-qualif False(v : bool): (~ ((? v))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 30, column 8)-qualif True1(v : GHC.Types.Bool): (? Prop([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 31, column 8)-qualif False1(v : GHC.Types.Bool): (~ ((? Prop([v])))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 32, column 8)-qualif Papp(v : @(0), p : (Pred  @(0))): (? papp1([p;-                                                   v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 35, column 8)-qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): (? papp2([p;+qualif Fst(v : @(1), y : @(0)) { v = fst([y])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 29, column 8)+qualif Snd(v : @(1), y : @(0)) { v = snd([y])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 30, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { (Prop([v])) <=> (len([xs]) > 0)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 13, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { (Prop([v])) <=> (len([xs]) = 0)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 14, column 8)+qualif ListZ(v : [@(0)]) { len([v]) = 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 16, column 8)+qualif ListZ(v : [@(0)]) { len([v]) >= 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 17, column 8)+qualif ListZ(v : [@(0)]) { len([v]) > 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 18, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) = len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 20, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) >= len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 21, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) > len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 22, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) <= len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 23, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) < len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 24, column 8)+qualif EqLen(v : int, xs : [@(0)]) { v = len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 26, column 8)+qualif LenEq(v : [@(0)], x : int) { x = len([v])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 27, column 8)+qualif LenDiff(v : [@(0)], x : int) { len([v]) = (x + 1)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 28, column 8)+qualif LenDiff(v : [@(0)], x : int) { len([v]) = (x - 1)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 29, column 8)+qualif LenAcc(v : int, xs : [@(0)], n : int) { v = (len([xs]) + n)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 30, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 3, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 4, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 5, column 8)+qualif Bot(v : bool) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 6, column 8)+qualif Bot(v : int) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 7, column 8)+qualif CmpZ(v : @(0)) { v < 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 9, column 8)+qualif CmpZ(v : @(0)) { v <= 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 10, column 8)+qualif CmpZ(v : @(0)) { v > 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 11, column 8)+qualif CmpZ(v : @(0)) { v >= 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 12, column 8)+qualif CmpZ(v : @(0)) { v = 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 13, column 8)+qualif CmpZ(v : @(0)) { v != 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 14, column 8)+qualif Cmp(v : @(0), x : @(0)) { v < x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 16, column 8)+qualif Cmp(v : @(0), x : @(0)) { v <= x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 17, column 8)+qualif Cmp(v : @(0), x : @(0)) { v > x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 18, column 8)+qualif Cmp(v : @(0), x : @(0)) { v >= x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 19, column 8)+qualif Cmp(v : @(0), x : @(0)) { v = x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 20, column 8)+qualif Cmp(v : @(0), x : @(0)) { v != x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 21, column 8)+qualif One(v : int) { v = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 28, column 8)+qualif True(v : bool) { v  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 29, column 8)+qualif False(v : bool) { ~ ((v))  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 30, column 8)+qualif True1(v : GHC.Types.Bool) { Prop([v])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 31, column 8)+qualif False1(v : GHC.Types.Bool) { ~ ((Prop([v])))  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 32, column 8)+qualif Papp(v : @(0), p : (Pred  @(0))) { (papp1([p;+                                                   v])) } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 35, column 8)+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))) { (papp2([p;                                                                     v;-                                                                    x])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 38, column 8)-qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): (? papp3([p;+                                                                    x])) } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 38, column 8)+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))) { (papp3([p;                                                                                     v;                                                                                     x;-                                                                                    y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 41, column 8)+                                                                                    y])) } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 41, column 8)   @@ -137,33 +137,33 @@ bind 3 GHC.Types.EQ$35$6U : {VV$35$167 : GHC.Types.Ordering | [(VV$35$167 = GHC.Types.EQ$35$6U)]} bind 4 GHC.Types.LT$35$6S : {VV$35$168 : GHC.Types.Ordering | [(VV$35$168 = GHC.Types.LT$35$6S)]} bind 5 GHC.Types.GT$35$6W : {VV$35$169 : GHC.Types.Ordering | [(VV$35$169 = GHC.Types.GT$35$6W)]}-bind 6 GHC.Types.True$35$6u : {v$35$4 : GHC.Types.Bool | [(? Prop([v$35$4]))]}-bind 7 GHC.Types.False$35$68 : {v$35$5 : GHC.Types.Bool | [(~ ((? Prop([v$35$5]))))]}-bind 8 GHC.Types.False$35$68 : {v$35$5 : GHC.Types.Bool | [(~ ((? Prop([v$35$5]))))]}+bind 6 GHC.Types.True$35$6u : {v$35$4 : GHC.Types.Bool | [(Prop([v$35$4]))]}+bind 7 GHC.Types.False$35$68 : {v$35$5 : GHC.Types.Bool | [(~ ((Prop([v$35$5]))))]}+bind 8 GHC.Types.False$35$68 : {v$35$5 : GHC.Types.Bool | [(~ ((Prop([v$35$5]))))]} bind 9 GHC.Types.$91$$93$$35$6m : {VV : func(1, [[@(0)]]) | []}-bind 10 GHC.Types.True$35$6u : {v$35$4 : GHC.Types.Bool | [(? Prop([v$35$4]))]}+bind 10 GHC.Types.True$35$6u : {v$35$4 : GHC.Types.Bool | [(Prop([v$35$4]))]} bind 11 GHC.Types.GT$35$6W : {VV$35$214 : GHC.Types.Ordering | [(cmp([VV$35$214]) = GHC.Types.GT$35$6W)]} bind 12 GHC.Types.LT$35$6S : {VV$35$215 : GHC.Types.Ordering | [(cmp([VV$35$215]) = GHC.Types.LT$35$6S)]} bind 13 GHC.Types.EQ$35$6U : {VV$35$216 : GHC.Types.Ordering | [(cmp([VV$35$216]) = GHC.Types.EQ$35$6U)]} bind 14 GHC.Base.Nothing$35$r1d : {VV : func(1, [(GHC.Base.Maybe  @(0))]) | []} bind 15 z$35$a10N : {VV$35$221 : int | [$k_$35$222]} bind 16 lq_anf$36$_d116 : {lq_tmp$36$x$35$229 : int | [(lq_tmp$36$x$35$229 = (100  :  int))]}-bind 17 lq_anf$36$_d117 : {lq_tmp$36$x$35$236 : GHC.Types.Bool | [((? Prop([lq_tmp$36$x$35$236])) <=> (z$35$a10N >= lq_anf$36$_d116))]}+bind 17 lq_anf$36$_d117 : {lq_tmp$36$x$35$236 : GHC.Types.Bool | [((Prop([lq_tmp$36$x$35$236])) <=> (z$35$a10N >= lq_anf$36$_d116))]} bind 18 lq_anf$36$_d118 : {lq_tmp$36$x$35$254 : int | [(lq_tmp$36$x$35$254 = (0  :  int))]} bind 19 Test0.x$35$rYP : {VV$35$250 : int | [$k_$35$251]} bind 20 lq_anf$36$_d119 : {lq_tmp$36$x$35$269 : int | [(lq_tmp$36$x$35$269 = (0  :  int))]}-bind 21 lq_anf$36$_d11a : {lq_tmp$36$x$35$275 : GHC.Types.Bool | [((? Prop([lq_tmp$36$x$35$275])) <=> (Test0.x$35$rYP > lq_anf$36$_d119))]}+bind 21 lq_anf$36$_d11a : {lq_tmp$36$x$35$275 : GHC.Types.Bool | [((Prop([lq_tmp$36$x$35$275])) <=> (Test0.x$35$rYP > lq_anf$36$_d119))]} bind 22 lq_anf$36$_d11b : {lq_tmp$36$x$35$291 : GHC.Types.Bool | [(lq_tmp$36$x$35$291 = lq_anf$36$_d11a)]} bind 23 lq_anf$36$_d11b : {lq_tmp$36$x$35$293 : GHC.Types.Bool | [(lq_tmp$36$x$35$293 = lq_anf$36$_d11a)]} bind 24 lq_anf$36$_d11b : {lq_tmp$36$x$35$293 : GHC.Types.Bool | [(lq_tmp$36$x$35$293 = lq_anf$36$_d11a);-                                                                  (~ ((? Prop([lq_tmp$36$x$35$293]))));-                                                                  (~ ((? Prop([lq_tmp$36$x$35$293]))));-                                                                  (~ ((? Prop([lq_tmp$36$x$35$293]))))]}+                                                                  (~ ((Prop([lq_tmp$36$x$35$293]))));+                                                                  (~ ((Prop([lq_tmp$36$x$35$293]))));+                                                                  (~ ((Prop([lq_tmp$36$x$35$293]))))]} bind 25 lq_anf$36$_d11b : {lq_tmp$36$x$35$299 : GHC.Types.Bool | [(lq_tmp$36$x$35$299 = lq_anf$36$_d11a)]} bind 26 lq_anf$36$_d11b : {lq_tmp$36$x$35$299 : GHC.Types.Bool | [(lq_tmp$36$x$35$299 = lq_anf$36$_d11a);-                                                                  (? Prop([lq_tmp$36$x$35$299]));-                                                                  (? Prop([lq_tmp$36$x$35$299]));-                                                                  (? Prop([lq_tmp$36$x$35$299]))]}+                                                                  (Prop([lq_tmp$36$x$35$299]));+                                                                  (Prop([lq_tmp$36$x$35$299]));+                                                                  (Prop([lq_tmp$36$x$35$299]))]} bind 27 Test0.prop_abs$35$r10h : {VV$35$265 : GHC.Types.Bool | [$k_$35$266]} bind 28 VV$35$310 : {VV$35$310 : GHC.Types.Bool | [$k_$35$226[lq_tmp$36$x$35$307:=Test0.x$35$rYP][lq_tmp$36$x$35$305:=VV$35$310][VV$35$225:=VV$35$310][z$35$a10N:=Test0.x$35$rYP]]} bind 29 VV$35$310 : {VV$35$310 : GHC.Types.Bool | [$k_$35$226[lq_tmp$36$x$35$307:=Test0.x$35$rYP][lq_tmp$36$x$35$305:=VV$35$310][VV$35$225:=VV$35$310][z$35$a10N:=Test0.x$35$rYP]]}@@ -183,8 +183,8 @@ bind 43 VV$35$331 : {VV$35$331 : int | [(VV$35$331 = lq_anf$36$_d118)]} bind 44 VV$35$334 : {VV$35$334 : int | [(VV$35$334 = 0)]} bind 45 VV$35$334 : {VV$35$334 : int | [(VV$35$334 = 0)]}-bind 46 VV$35$337 : {VV$35$337 : GHC.Types.Bool | [(? Prop([VV$35$337]))]}-bind 47 VV$35$337 : {VV$35$337 : GHC.Types.Bool | [(? Prop([VV$35$337]))]}+bind 46 VV$35$337 : {VV$35$337 : GHC.Types.Bool | [(Prop([VV$35$337]))]}+bind 47 VV$35$337 : {VV$35$337 : GHC.Types.Bool | [(Prop([VV$35$337]))]} bind 48 VV$35$340 : {VV$35$340 : GHC.Types.Bool | [(VV$35$340 = lq_anf$36$_d117)]} bind 49 VV$35$340 : {VV$35$340 : GHC.Types.Bool | [(VV$35$340 = lq_anf$36$_d117)]} bind 50 VV$35$343 : {VV$35$343 : int | [(VV$35$343 = lq_anf$36$_d116)]}@@ -260,7 +260,7 @@        14;        15]   lhs {VV$35$F8 : GHC.Types.Bool | [(VV$35$F8 = lq_anf$36$_d117)]}-  rhs {VV$35$F8 : GHC.Types.Bool | [(? Prop([VV$35$F8]))]}+  rhs {VV$35$F8 : GHC.Types.Bool | [(Prop([VV$35$F8]))]}   id 8 tag [1]   // META constraint id 8 : tests/neg/test00.hs:11:23-35 
tests/neg/test00a.fq view
@@ -1,6 +1,6 @@ // This qualifier saves the day; solve constraints WITHOUT IT -qualif Zog(v:a) : (10 <= v)+qualif Zog(v:a)  { 10 <= v }  bind 0 x : {v : int | true} bind 1 y : {v : int | true}
tests/neg/test1.fq view
@@ -1,6 +1,6 @@  // This qualifier saves the day; solve constraints WITHOUT IT-qualif Zog(v:a) : (10 <= v)+qualif Zog(v:a)  { 10 <= v }  bind 0 x : {v : int | v = 9} bind 1 y : {v : int | v = 20}
tests/neg/test2.fq view
@@ -1,9 +1,9 @@  // This qualifier saves the day; solve constraints WITHOUT IT-qualif Zog(v:a): (10 <= v)+qualif Zog(v:a) { 10 <= v }  // But you may use this one-qualif Pog(v:a): (0 <= v)+qualif Pog(v:a) { 0 <= v }  bind 0 x: {v: int | v = 9 } bind 1 a: {v: int | $k1    }
tests/neg/test3.fq view
@@ -1,5 +1,5 @@ -qualif Zog(v:a, z:b) : (v = z)+qualif Zog(v:a, z:b)  { v = z }  bind 0 x : {v : int | true} bind 1 q : {v : int | true}
tests/pos/LogicCurry1.hs.fq view
@@ -1,46 +1,46 @@ fixpoint "--allowho" -qualif Fst(v : @(1), y : @(0)): ((v = (fst y))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.spec" (line 28, column 8)-qualif Snd(v : @(1), y : @(0)): ((v = (snd y))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.spec" (line 29, column 8)-qualif Auto(v##1 : int, n : int, x : int): ((v##1 = (ack n x))) // "/Users/rjhala/research/stack/liquidhaskell/tests/pos/LogicCurry1.hs" (line 10, column 1)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((v <=> ((len xs) > 0))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 13, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((v <=> ((len xs) = 0))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 14, column 8)-qualif ListZ(v : [@(0)]): (((len v) = 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 16, column 8)-qualif ListZ(v : [@(0)]): (((len v) >= 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 17, column 8)-qualif ListZ(v : [@(0)]): (((len v) > 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 18, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) = (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 20, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) >= (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 21, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) > (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 22, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) <= (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 23, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) < (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 24, column 8)-qualif EqLen(v : int, xs : [@(0)]): ((v = (len xs))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 26, column 8)-qualif LenEq(v : [@(0)], x : int): ((x = (len v))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 27, column 8)-qualif LenDiff(v : [@(0)], x : int): (((len v) = (x + 1))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 28, column 8)-qualif LenDiff(v : [@(0)], x : int): (((len v) = (x - 1))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 29, column 8)-qualif LenAcc(v : int, xs : [@(0)], n : int): ((v = ((len xs) + n))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 30, column 8)-qualif Bot(v : @(0)): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 3, column 8)-qualif Bot(v : @(0)): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 4, column 8)-qualif Bot(v : @(0)): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 5, column 8)-qualif Bot(v : bool): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 6, column 8)-qualif Bot(v : int): ((0 = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 7, column 8)-qualif CmpZ(v : @(0)): ((v < 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 9, column 8)-qualif CmpZ(v : @(0)): ((v <= 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 10, column 8)-qualif CmpZ(v : @(0)): ((v > 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 11, column 8)-qualif CmpZ(v : @(0)): ((v >= 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 12, column 8)-qualif CmpZ(v : @(0)): ((v = 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 13, column 8)-qualif CmpZ(v : @(0)): ((v != 0)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 14, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v < x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 16, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v <= x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 17, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 18, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v >= x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 19, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 20, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v != x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 21, column 8)-qualif One(v : int): ((v = 1)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 28, column 8)-qualif True1(v : GHC.Types.Bool): (v) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 29, column 8)-qualif False1(v : GHC.Types.Bool): ((~ (v))) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 30, column 8)-qualif Papp(v : @(0), p : (Pred  @(0))): ((papp1 p v)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 34, column 8)-qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): ((papp2 p v x)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 37, column 8)-qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): ((papp3 p v x y)) // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 39, column 8)+qualif Fst(v : @(1), y : @(0)) { (v = (fst y))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.spec" (line 28, column 8)+qualif Snd(v : @(1), y : @(0)) { (v = (snd y))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.spec" (line 29, column 8)+qualif Auto(v##1 : int, n : int, x : int) { (v##1 = (ack n x))  } // "/Users/rjhala/research/stack/liquidhaskell/tests/pos/LogicCurry1.hs" (line 10, column 1)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { (v <=> ((len xs) > 0))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 13, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { (v <=> ((len xs) = 0))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 14, column 8)+qualif ListZ(v : [@(0)]) { ((len v) = 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 16, column 8)+qualif ListZ(v : [@(0)]) { ((len v) >= 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 17, column 8)+qualif ListZ(v : [@(0)]) { ((len v) > 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 18, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) = (len xs))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 20, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) >= (len xs))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 21, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) > (len xs))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 22, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) <= (len xs))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 23, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) < (len xs))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 24, column 8)+qualif EqLen(v : int, xs : [@(0)]) { (v = (len xs))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 26, column 8)+qualif LenEq(v : [@(0)], x : int) { (x = (len v))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 27, column 8)+qualif LenDiff(v : [@(0)], x : int) { ((len v) = (x + 1))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 28, column 8)+qualif LenDiff(v : [@(0)], x : int) { ((len v) = (x - 1))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 29, column 8)+qualif LenAcc(v : int, xs : [@(0)], n : int) { (v = ((len xs) + n))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/GHC/Base.hquals" (line 30, column 8)+qualif Bot(v : @(0)) { (0 = 1)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 3, column 8)+qualif Bot(v : @(0)) { (0 = 1)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 4, column 8)+qualif Bot(v : @(0)) { (0 = 1)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 5, column 8)+qualif Bot(v : bool) { (0 = 1)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 6, column 8)+qualif Bot(v : int) { (0 = 1)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 7, column 8)+qualif CmpZ(v : @(0)) { (v < 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 9, column 8)+qualif CmpZ(v : @(0)) { (v <= 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 10, column 8)+qualif CmpZ(v : @(0)) { (v > 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 11, column 8)+qualif CmpZ(v : @(0)) { (v >= 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 12, column 8)+qualif CmpZ(v : @(0)) { (v = 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 13, column 8)+qualif CmpZ(v : @(0)) { (v != 0)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 14, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v < x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 16, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v <= x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 17, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v > x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 18, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v >= x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 19, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v = x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 20, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v != x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 21, column 8)+qualif One(v : int) { (v = 1)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 28, column 8)+qualif True1(v : GHC.Types.Bool) { v  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 29, column 8)+qualif False1(v : GHC.Types.Bool) { (~ (v))  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 30, column 8)+qualif Papp(v : @(0), p : (Pred  @(0))) { (papp1 p v)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 34, column 8)+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))) { (papp2 p v x)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 37, column 8)+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))) { (papp3 p v x y)  } // "/Users/rjhala/research/stack/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2016-05-21/7.10.3/share/x86_64-osx-ghc-7.10.3/liquidhaskell-0.6.0.0/include/Prelude.hquals" (line 39, column 8)   
tests/pos/MergeSort.fq view
@@ -1,52 +1,52 @@-qualif Fst(v : @(1), y : @(0)): ((v = (fst y))) // "tests/todo/MergeSort.new.min.fq" (line 1, column 8)-qualif Snd(v : @(1), y : @(0)): ((v = (snd y))) // "tests/todo/MergeSort.new.min.fq" (line 2, column 8)-qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 3, column 8)-qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 4, column 8)-qualif Auto(VV : [@(0)], xs : [@(0)], ys : [@(0)]): (((len VV) = ((len xs) + (len ys)))) // "tests/todo/MergeSort.new.min.fq" (line 5, column 8)-qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 6, column 8)-qualif Auto(VV : [@(0)], xs : [@(0)]): (((len VV) = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 7, column 8)-qualif Auto(VV : @(0), fld##0 : @(0)): ((VV >= fld##0)) // "tests/todo/MergeSort.new.min.fq" (line 8, column 8)-qualif Auto(v##0 : (Tuple  [@(0)]  [@(0)]), xs : [@(0)]): ((((len (fst v##0)) + (len (snd v##0))) = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 9, column 8)-qualif Auto(v##0 : [@(0)], xs : [@(0)]): ((((len v##0) > 1) => ((len v##0) < (len xs)))) // "tests/todo/MergeSort.new.min.fq" (line 10, column 8)-qualif Auto(v##0 : [@(0)], xs : [@(0)]): ((((len v##0) > 1) => ((len v##0) < (len xs)))) // "tests/todo/MergeSort.new.min.fq" (line 11, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): (((Prop v) <=> ((len xs) > 0))) // "tests/todo/MergeSort.new.min.fq" (line 12, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): (((Prop v) <=> ((len xs) = 0))) // "tests/todo/MergeSort.new.min.fq" (line 13, column 8)-qualif ListZ(v : [@(0)]): (((len v) = 0)) // "tests/todo/MergeSort.new.min.fq" (line 14, column 8)-qualif ListZ(v : [@(0)]): (((len v) >= 0)) // "tests/todo/MergeSort.new.min.fq" (line 15, column 8)-qualif ListZ(v : [@(0)]): (((len v) > 0)) // "tests/todo/MergeSort.new.min.fq" (line 16, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 17, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) >= (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 18, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) > (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 19, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) <= (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 20, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (((len v) < (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 21, column 8)-qualif EqLen(v : int, xs : [@(0)]): ((v = (len xs))) // "tests/todo/MergeSort.new.min.fq" (line 22, column 8)-qualif LenEq(v : [@(0)], x : int): ((x = (len v))) // "tests/todo/MergeSort.new.min.fq" (line 23, column 8)-qualif LenDiff(v : [@(0)], x : int): (((len v) = (x + 1))) // "tests/todo/MergeSort.new.min.fq" (line 24, column 8)-qualif LenDiff(v : [@(0)], x : int): (((len v) = (x - 1))) // "tests/todo/MergeSort.new.min.fq" (line 25, column 8)-qualif LenAcc(v : int, xs : [@(0)], n : int): ((v = ((len xs) + n))) // "tests/todo/MergeSort.new.min.fq" (line 26, column 8)-qualif Bot(v : @(0)): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 27, column 8)-qualif Bot(v : @(0)): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 28, column 8)-qualif Bot(v : @(0)): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 29, column 8)-qualif Bot(v : bool): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 30, column 8)-qualif Bot(v : int): ((0 = 1)) // "tests/todo/MergeSort.new.min.fq" (line 31, column 8)-qualif CmpZ(v : @(0)): ((v < 0)) // "tests/todo/MergeSort.new.min.fq" (line 32, column 8)-qualif CmpZ(v : @(0)): ((v <= 0)) // "tests/todo/MergeSort.new.min.fq" (line 33, column 8)-qualif CmpZ(v : @(0)): ((v > 0)) // "tests/todo/MergeSort.new.min.fq" (line 34, column 8)-qualif CmpZ(v : @(0)): ((v >= 0)) // "tests/todo/MergeSort.new.min.fq" (line 35, column 8)-qualif CmpZ(v : @(0)): ((v = 0)) // "tests/todo/MergeSort.new.min.fq" (line 36, column 8)-qualif CmpZ(v : @(0)): ((v != 0)) // "tests/todo/MergeSort.new.min.fq" (line 37, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v < x)) // "tests/todo/MergeSort.new.min.fq" (line 38, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v <= x)) // "tests/todo/MergeSort.new.min.fq" (line 39, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "tests/todo/MergeSort.new.min.fq" (line 40, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v >= x)) // "tests/todo/MergeSort.new.min.fq" (line 41, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "tests/todo/MergeSort.new.min.fq" (line 42, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v != x)) // "tests/todo/MergeSort.new.min.fq" (line 43, column 8)-qualif One(v : int): ((v = 1)) // "tests/todo/MergeSort.new.min.fq" (line 44, column 8)-qualif True1(v : GHC.Types.Bool): ((Prop v)) // "tests/todo/MergeSort.new.min.fq" (line 45, column 8)-qualif False1(v : GHC.Types.Bool): ((~ ((Prop v)))) // "tests/todo/MergeSort.new.min.fq" (line 46, column 8)-qualif Papp(v : @(0), p : (Pred  @(0))): ((papp1 p v)) // "tests/todo/MergeSort.new.min.fq" (line 47, column 8)-qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): ((papp2 p v x)) // "tests/todo/MergeSort.new.min.fq" (line 48, column 8)-qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): ((papp3 p v x y)) // "tests/todo/MergeSort.new.min.fq" (line 49, column 8)+qualif Fst(v : @(1), y : @(0)) { (v = (fst y))  } // "tests/todo/MergeSort.new.min.fq" (line 1, column 8)+qualif Snd(v : @(1), y : @(0)) { (v = (snd y))  } // "tests/todo/MergeSort.new.min.fq" (line 2, column 8)+qualif Auto(VV : @(0), fld##0 : @(0)) { (VV >= fld##0)  } // "tests/todo/MergeSort.new.min.fq" (line 3, column 8)+qualif Auto(VV : @(0), fld##0 : @(0)) { (VV >= fld##0)  } // "tests/todo/MergeSort.new.min.fq" (line 4, column 8)+qualif Auto(VV : [@(0)], xs : [@(0)], ys : [@(0)]) { ((len VV) = ((len xs) + (len ys)))  } // "tests/todo/MergeSort.new.min.fq" (line 5, column 8)+qualif Auto(VV : @(0), fld##0 : @(0)) { (VV >= fld##0)  } // "tests/todo/MergeSort.new.min.fq" (line 6, column 8)+qualif Auto(VV : [@(0)], xs : [@(0)]) { ((len VV) = (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 7, column 8)+qualif Auto(VV : @(0), fld##0 : @(0)) { (VV >= fld##0)  } // "tests/todo/MergeSort.new.min.fq" (line 8, column 8)+qualif Auto(v##0 : (Tuple  [@(0)]  [@(0)]), xs : [@(0)]) { (((len (fst v##0)) + (len (snd v##0))) = (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 9, column 8)+qualif Auto(v##0 : [@(0)], xs : [@(0)]) { (((len v##0) > 1) => ((len v##0) < (len xs)))  } // "tests/todo/MergeSort.new.min.fq" (line 10, column 8)+qualif Auto(v##0 : [@(0)], xs : [@(0)]) { (((len v##0) > 1) => ((len v##0) < (len xs)))  } // "tests/todo/MergeSort.new.min.fq" (line 11, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { ((Prop v) <=> ((len xs) > 0))  } // "tests/todo/MergeSort.new.min.fq" (line 12, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { ((Prop v) <=> ((len xs) = 0))  } // "tests/todo/MergeSort.new.min.fq" (line 13, column 8)+qualif ListZ(v : [@(0)]) { ((len v) = 0)  } // "tests/todo/MergeSort.new.min.fq" (line 14, column 8)+qualif ListZ(v : [@(0)]) { ((len v) >= 0)  } // "tests/todo/MergeSort.new.min.fq" (line 15, column 8)+qualif ListZ(v : [@(0)]) { ((len v) > 0)  } // "tests/todo/MergeSort.new.min.fq" (line 16, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) = (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 17, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) >= (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 18, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) > (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 19, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) <= (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 20, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { ((len v) < (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 21, column 8)+qualif EqLen(v : int, xs : [@(0)]) { (v = (len xs))  } // "tests/todo/MergeSort.new.min.fq" (line 22, column 8)+qualif LenEq(v : [@(0)], x : int) { (x = (len v))  } // "tests/todo/MergeSort.new.min.fq" (line 23, column 8)+qualif LenDiff(v : [@(0)], x : int) { ((len v) = (x + 1))  } // "tests/todo/MergeSort.new.min.fq" (line 24, column 8)+qualif LenDiff(v : [@(0)], x : int) { ((len v) = (x - 1))  } // "tests/todo/MergeSort.new.min.fq" (line 25, column 8)+qualif LenAcc(v : int, xs : [@(0)], n : int) { (v = ((len xs) + n))  } // "tests/todo/MergeSort.new.min.fq" (line 26, column 8)+qualif Bot(v : @(0)) { (0 = 1)  } // "tests/todo/MergeSort.new.min.fq" (line 27, column 8)+qualif Bot(v : @(0)) { (0 = 1)  } // "tests/todo/MergeSort.new.min.fq" (line 28, column 8)+qualif Bot(v : @(0)) { (0 = 1)  } // "tests/todo/MergeSort.new.min.fq" (line 29, column 8)+qualif Bot(v : bool) { (0 = 1)  } // "tests/todo/MergeSort.new.min.fq" (line 30, column 8)+qualif Bot(v : int) { (0 = 1)  } // "tests/todo/MergeSort.new.min.fq" (line 31, column 8)+qualif CmpZ(v : @(0)) { (v < 0)  } // "tests/todo/MergeSort.new.min.fq" (line 32, column 8)+qualif CmpZ(v : @(0)) { (v <= 0)  } // "tests/todo/MergeSort.new.min.fq" (line 33, column 8)+qualif CmpZ(v : @(0)) { (v > 0)  } // "tests/todo/MergeSort.new.min.fq" (line 34, column 8)+qualif CmpZ(v : @(0)) { (v >= 0)  } // "tests/todo/MergeSort.new.min.fq" (line 35, column 8)+qualif CmpZ(v : @(0)) { (v = 0)  } // "tests/todo/MergeSort.new.min.fq" (line 36, column 8)+qualif CmpZ(v : @(0)) { (v != 0)  } // "tests/todo/MergeSort.new.min.fq" (line 37, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v < x)  } // "tests/todo/MergeSort.new.min.fq" (line 38, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v <= x)  } // "tests/todo/MergeSort.new.min.fq" (line 39, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v > x)  } // "tests/todo/MergeSort.new.min.fq" (line 40, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v >= x)  } // "tests/todo/MergeSort.new.min.fq" (line 41, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v = x)  } // "tests/todo/MergeSort.new.min.fq" (line 42, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v != x)  } // "tests/todo/MergeSort.new.min.fq" (line 43, column 8)+qualif One(v : int) { (v = 1)  } // "tests/todo/MergeSort.new.min.fq" (line 44, column 8)+qualif True1(v : GHC.Types.Bool) { (Prop v)  } // "tests/todo/MergeSort.new.min.fq" (line 45, column 8)+qualif False1(v : GHC.Types.Bool) { (~ ((Prop v)))  } // "tests/todo/MergeSort.new.min.fq" (line 46, column 8)+qualif Papp(v : @(0), p : (Pred  @(0))) { (papp1 p v)  } // "tests/todo/MergeSort.new.min.fq" (line 47, column 8)+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))) { (papp2 p v x)  } // "tests/todo/MergeSort.new.min.fq" (line 48, column 8)+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))) { (papp3 p v x y)  } // "tests/todo/MergeSort.new.min.fq" (line 49, column 8)   cut $k_##795
tests/pos/T416.fq view
@@ -7,7 +7,7 @@ ]  define compose (lq1:func(0,[b;c]), lq2:func(0,[a;b]), lq3:a) : c = { lq1 (lq2 lq3) }-define first (lq1:func(0,[a;c]),  lq2:(Pair a b)) : Pair a c = {+define first (lq1:func(0,[a;c]),  lq2:(Pair a b)) : Pair c b = {   Pair (lq1 (pfst lq2)) (psnd lq2) } define plus1 (x:int) : int = { x + 1 }@@ -22,7 +22,7 @@                                  @(1)])) constant first : (func(3 , [func(0 , [@(1); @(2)]);                                            (Pair @(1) @(0));-                                           (Pair @(2) @(0))]))                                 +                                           (Pair @(2) @(0))]))  bind 0 g : {VV : func(0 , [b; c]) | []} bind 1 f : {VV : func(0 , [a; b]) | []}
+ tests/pos/T753A.fq view
@@ -0,0 +1,45 @@+// Config {srcFile = "tests/pos/T2535.hs", cores = Nothing, minPartSize = 500, maxPartSize = 700, solver = z3, linear = False, stringTheory = False, defunction = False, allowHO = True, allowHOqs = False, eliminate = some, scrape = no, elimBound = Nothing, smtTimeout = Nothing, elimStats = False, solverStats = False, metadata = False, stats = False, parts = False, save = True, minimize = False, minimizeQs = False, minimizeKs = False, minimalSol = False, etaElim = False, gradual = False, ginteractive = False, autoKuts = False, nonLinCuts = False, noslice = False, rewriteAxioms = False, pleWithUndecidedGuards = False, etabeta = False, localRewrites = False, interpreter = False, oldPLE = False, noIncrPle = False, noEnvironmentReduction = True, inlineANFBindings = False, checkCstr = [], extensionality = False, rwTerminationCheck = False, stdin = False, json = False, noLazyPLE = False, fuel = Nothing, restOrdering = "rpo", noSmtHorn = False}++data AB 2 = [+       | B {selectB : int}+       | A {selectA : int}+     ]+data T 1 = [+       | T {selectT1 : @(0)}+     ]++match selectA A lq_tmp$x##423   { lq_tmp$x##423 }+match selectB B lq_tmp$x##502   { lq_tmp$x##502 }+match check A lq_tmp$x##423   { true }+match check B lq_tmp$x##502   { false }+match isA A lq_tmp$x##423   { true }+match isA B lq_tmp$x##502   { false }++constant A : (func(2 , [int; (AB @(0) @(1))]))+constant selectA : (func(2 , [(AB @(0) @(1)); int]))+constant B : (func(2 , [int; (AB @(0) @(1))]))+constant selectB : (func(2 , [(AB @(0) @(1)); int]))+constant T : (func(1 , [@(0); (T @(0))]))+distinct A : (func(2 , [int; (AB @(0) @(1))]))+distinct B : (func(2 , [int; (AB @(0) @(1))]))+++bind 1 A : {VV : func(2 , [int; (AB @(0) @(1))]) | []}+bind 2 B : {VV : func(2 , [int; (AB @(0) @(1))]) | []}+bind 3 T : {VV : func(1 , [@(0); (T @(0))]) | []}+bind 4 check : {VV : func(2 , [(AB @(0) @(1)); bool]) | []}+bind 5 x : {v : (AB int (T aFD)) | [(check v)]}++constraint:+  env [1; 2; 3; 4; 5]+  lhs {VV : (AB int (T aFD)) | [(VV = (if (is$A VV) then (A (selectA VV)) else (B (selectB VV))))]}+  rhs {VV : (AB int (T aFD)) | [( 3 = (1 + 2) )]}+  id 24 tag [4]+  // META constraint id 24 : tests/pos/T2535.hs:11:1-9+++// unless the sort of application is propagated in both the function and the argument +// as fixed in PR: https://github.com/ucsd-progsys/liquid-fixpoint/pull/753+// the above query crashes with +// Crash!: :1:1-1:1: Error+//   crash: SMTLIB2 respSat = Error "line 3 column 13267: Sorts (AB Int (T Int)) and (AB Int Int) are incompatible"
tests/pos/adt_qual.fq view
@@ -1,6 +1,6 @@ -qualif Eq(v:@(0), x:@(0)): (v = x)-qualif Leq(v:@(0), x:@(0)): (v <= x)+qualif Eq(v:@(0), x:@(0)) { v = x }+qualif Leq(v:@(0), x:@(0)) { v <= x }  data Zob 0 = [   | boo { choo : int } 
tests/pos/bad-subst00.fq view
@@ -1,5 +1,5 @@-qualif Zog(v:a) : (10 <= v)-qualif Bog(v:a, x:a) : (x <= v)+qualif Zog(v:a)  { 10 <= v }+qualif Bog(v:a, x:a)  { x <= v }  bind 0 a : {v: int | $k0[zogbert := pikachu] } 
tests/pos/bad-subst01.fq view
@@ -1,8 +1,8 @@ // fixpoint "--eliminate=some"  -qualif Zog(v:a) : (10 <= v)-qualif Bog(v:a, x:a) : (x <= v)+qualif Zog(v:a)  { 10 <= v }+qualif Bog(v:a, x:a)  { x <= v }  bind 0 a : {v: int | $k0 } 
tests/pos/bad-subst02.fq view
@@ -1,6 +1,6 @@ fixpoint "--eliminate=none" -qualif Eq(v:a, x:a): (v = x)+qualif Eq(v:a, x:a) { v = x }  bind 0 x0 : {v: a0 | true } bind 1 x1 : {v: a1 | true }
tests/pos/bool00.fq view
@@ -1,5 +1,5 @@-qualif Zog(v:a) : (10 <= v)-qualif Bog(v:a, x:a) : (x <= v)+qualif Zog(v:a)  { 10 <= v }+qualif Bog(v:a, x:a)  { x <= v }  bind 0 a  : {v: int  | $k0} bind 1 tt : {v: bool | v}
tests/pos/bool03.fq view
@@ -1,7 +1,7 @@  // qualif LE(v:a, x:a): (bool_to_int x <= bool_to_int v) -qualif LE(v:a, x:a): (x <= v)+qualif LE(v:a, x:a) { x <= v }  constant lit$36$not$45$the$45$hippopotamus : (Str) constant lit#cat : (Str)
− tests/pos/bool04.fq
@@ -1,20 +0,0 @@-fixpoint "--eliminate=some"--bind 1 bx : {v: int  | true }-bind 2 by : {v: bool | true }--constraint:-  env [ 2 ]-  lhs {v : int | true }-  rhs {v : int | $k1[bx := by] }-  id 1 tag []--constraint:-  env [ 1 ]-  lhs {v : int | $k1    }-  rhs {v : int | v <= v + 1 }-  id 2 tag []--wf:-  env [1]-  reft {v : int | $k1 }
− tests/pos/ebind-00.fq
@@ -1,16 +0,0 @@-fixpoint "--eliminate=all"--// bind  0 x1 : {v: int | v = 10 }-ebind 0 x1 : { int }--constraint:-  env [0]-  lhs {v1 : int | v1 = 10}-  rhs {v1 : int | v1 = x1}-  id 1 tag []--constraint:-  env [0]-  lhs {v2 : int | v2 = x1 + 1 }-  rhs {v2 : int | v2 = 11     }-  id 2 tag []
− tests/pos/ebind-01.fq
@@ -1,17 +0,0 @@-fixpoint "--eliminate=all"--bind  1 m  : {v: int | true }-ebind 2 x1 : { int }-// bind  2 x1 : {v: int | v = m + 1 }--constraint:-  env [1; 2]-  lhs {v : int | v = m + 1 }-  rhs {v : int | v = x1    }-  id 1 tag []--constraint:-  env [1; 2]-  lhs {v : int | v = x1 + 1}-  rhs {v : int | v = 2 + m }-  id 2 tag []
− tests/pos/ebind-02.fq
@@ -1,28 +0,0 @@-fixpoint "--eliminate=all"--bind  0 m  : {v: int | true }-bind  1 z  : {v: int | v = m - 1 }-ebind 2 x1 : { int }-// bind  2 x1 : {v: int | v = m + 1 }--constraint:-  env [0; 1]-  lhs {v : int | v = z + 2 }-  rhs {v : int | $k         }-  id 1 tag []--constraint:-  env [0; 2]-  lhs {v : int | $k      }-  rhs {v : int | v = x1 }-  id 2 tag []--constraint:-  env [0; 2]-  lhs {v : int | v = x1 + 1 }-  rhs {v : int | v = m  + 2 }-  id 3 tag []--wf: -  env [0]-  reft {v:int | [$k] }
− tests/pos/ebind-03.fq
@@ -1,45 +0,0 @@-fixpoint "--eliminate=all"--ebind 1 x1 : { int }-ebind 2 x2 : { int }---constraint:-  env [1]-  lhs {v : int | v = 1  }-  rhs {v : int | v = x1 }-  id 1 tag []--constraint:-  env [1]-  lhs {v : int | v = x1 + 1 }-  rhs {v : int | $ka        }-  id 2 tag []--constraint:-  env [2]-  lhs {v : int | $ka    }-  rhs {v : int | v = x2 }-  id 3 tag []--constraint:-  env [2]-  lhs {v : int | v = x2 + 1}-  rhs {v : int | $kb       }-  id 4 tag []--constraint:-  env []-  lhs {v : int | $kb   }-  rhs {v : int | v = 3 } -  id 5 tag []---wf: -  env []-  reft {v:int | [$ka] }--wf: -  env []-  reft {v:int | [$kb] }-
− tests/pos/ebind-03a.fq
@@ -1,55 +0,0 @@-fixpoint "--eliminate=all"--ebind 1 x1 : { int }-ebind 2 x2 : { int }--constraint:-  env []-  lhs {v : int | v = 1 }-  rhs {v : int | $kone }-  id 10 tag []--constraint:-  env [1]-  lhs {v : int | $kone  }-  rhs {v : int | v = x1 }-  id 1 tag []--constraint:-  env [1]-  lhs {v : int | v = x1 + 1 }-  rhs {v : int | $ka        }-  id 2 tag []--constraint:-  env [2]-  lhs {v : int | $ka    }-  rhs {v : int | v = x2 }-  id 3 tag []--constraint:-  env [2]-  lhs {v : int | v = x2 + 1}-  rhs {v : int | $kb       }-  id 4 tag []--constraint:-  env []-  lhs {v : int | $kb   }-  rhs {v : int | v = 3 } -  id 5 tag []---wf: -  env []-  reft {v:int | [$ka] }--wf: -  env []-  reft {v:int | [$kb] }--wf: -  env []-  reft {v:int | [$kone] }--
− tests/pos/ebind-04.fq
@@ -1,35 +0,0 @@-fixpoint "--eliminate=all"--ebind 1 x : { int }--constraint:-  env [1]-  lhs {v : int | $k1   }-  rhs {v : int | v = x }-  id 1 tag []--constraint:-  env [1]-  lhs {v : int | v = x + 1 }-  rhs {v : int | $k2       }-  id 2 tag []--constraint:-  env []-  lhs {v : int | v = 3 }-  rhs {v : int | $k1   }-  id 3 tag []--constraint:-  env []-  lhs {v : int | $k2   }-  rhs {v : int | v = 4 }-  id 4 tag []--wf: -  env []-  reft {v:int | [$k1] }--wf: -  env []-  reft {v:int | [$k2] }
− tests/pos/ebind-05.fq
@@ -1,31 +0,0 @@-fixpoint "--eliminate=some"--// This file is SAFE with --eliminate=none-// but both qualifiers are needed--bind  16 m    : {VV##131 : int | true }-ebind 19 n    : { int }--constraint:-  env [16; 19]-  lhs {VV##F##4 : int | $k_##137[VV##136:=VV##F##4] }-  rhs {VV##F##4 : int | VV##F##4 = n                }-  id 4 tag []--constraint:-  env [16]-  lhs {VV##F##5 : int | VV##F##5 = m + 1          }-  rhs {VV##F##5 : int | $k_##137[VV##136:=VV##F##5] }-  id 5 tag []--// Constraint 3 is only needed to prevent the *sharing* optimization--constraint:-  env [16; 19]-  lhs {VV##F##3 : int | false     }-  rhs {VV##F##3 : int | $k_##137[VV##136:=VV##F##3] }-  id 3 tag []--wf:-  env [16]-  reft {VV##136 : int   | [$k_##137]}
− tests/pos/ebind-06.fq
@@ -1,27 +0,0 @@-fixpoint "--eliminate=some"--bind  16 m    : {VV##131 : int | true }-ebind 19 n    : { int }--constraint:-  env [16; 19]-  lhs {VV##F##3 : int | VV##F##3 = n                     }-  rhs {VV##F##3 : int | VV##F##3 = m + 1 && VV##F##3 = 3 }-  id 3 tag []--constraint:-  env [16; 19]-  lhs {VV##F##4 : int | VV##F##4 = 3 }-  rhs {VV##F##4 : int | VV##F##4 = n }-  id 4 tag []--constraint:-  env [16; 19]-  lhs {VV##F##5 : int | VV##F##5 = m + 1 }-  rhs {VV##F##5 : int | VV##F##5 = n     }-  id 5 tag []---wf:-  env [16]-  reft {VV##136 : int   | [$k_##137]}
tests/pos/elim00.fq view
@@ -1,8 +1,8 @@ fixpoint "--defunct"  // trick is to do it without these-qualif Cmp(v : @(0), x : @(0)): ((v > x)) // "tests/todo/elim00.hs.fq" (line 1, column 8)-qualif Cmp(v : @(0), x : @(0)): ((v = x)) // "tests/todo/elim00.hs.fq" (line 2, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v > x)  } // "tests/todo/elim00.hs.fq" (line 1, column 8)+qualif Cmp(v : @(0), x : @(0)) { (v = x)  } // "tests/todo/elim00.hs.fq" (line 2, column 8)   constant Control.Exception.Base.irrefutPatError##09 : (func(1, [int;
tests/pos/func00.fq view
@@ -2,7 +2,7 @@ bind 0 f : {v: func(0, [int; int]) | []}  constraint:-  env [ ]+  env [ 0 ]   lhs {v : int | [f = f]}   rhs {v : int | [0 < 7]}   id 1 tag []
tests/pos/gfp00.fq view
@@ -1,7 +1,7 @@-qualif Pos(v:int)  : (0 <= v)-qualif Neg(v:int)  : (v <= 0)-qualif NeqZ(v:int) : (0 != v)-qualif False(v:int) : (66 = 77)+qualif Pos(v:int)   { 0 <= v }+qualif Neg(v:int)   { v <= 0 }+qualif NeqZ(v:int)  { 0 != v }+qualif False(v:int)  { 66 = 77 }  constraint:   env []
tests/pos/hex.ts.fq view
@@ -1,23 +1,23 @@-qualif Bot(v : a): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Bot(v : obj): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Bot(v : Boolean): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Bot(v : int): (0 = 1) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif CmpZ(v : int): (v < 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif CmpZ(v : int): (v <= 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif CmpZ(v : int): (v > 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif CmpZ(v : int): (v >= 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif CmpZ(v : int): (v = 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif CmpZ(v : int): (v != 0) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Cmp(v : int, x : int): (v < x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Cmp(v : int, x : int): (v <= x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Cmp(v : int, x : int): (v > x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Cmp(v : int, x : int): (v >= x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Cmp(v : a, x : a): (v ~~ x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Cmp(v : a, x : a): (v != x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif True1(v : Boolean): (? Prop([v])) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif False1(v : Boolean): (~ ((? Prop([v])))) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Tag(v : a, x : Str): (ttag([v]) = x) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)-qualif Len(v : b, w : a): (v < len([w])) // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Bot(v : a) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Bot(v : obj) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Bot(v : Boolean) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Bot(v : int) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif CmpZ(v : int) { v < 0  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif CmpZ(v : int) { v <= 0  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif CmpZ(v : int) { v > 0  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif CmpZ(v : int) { v >= 0  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif CmpZ(v : int) { v = 0  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif CmpZ(v : int) { v != 0  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Cmp(v : int, x : int) { v < x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Cmp(v : int, x : int) { v <= x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Cmp(v : int, x : int) { v > x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Cmp(v : int, x : int) { v >= x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Cmp(v : a, x : a) { v ~~ x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Cmp(v : a, x : a) { v != x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif True1(v : Boolean) { Prop([v])  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif False1(v : Boolean) { ~ ((Prop([v])))  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Tag(v : a, x : Str) { ttag([v]) = x  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)+qualif Len(v : b, w : a) { v < len([w])  } // "/Users/rjhala/research/stack/liquid/refscript/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/refscript-0.1.0.0/include/prelude.ts" (line 1, column 1)   @@ -74,139 +74,139 @@   bind 0 undefined : {v : Undefined | [(ttag([v]) = lit$36$undefined);-                                     (~ ((? Prop([v]))))]}-bind 1 Object : {VV$35$285 : Object | [(? Prop([VV$35$285]));+                                     (~ ((Prop([v]))))]}+bind 1 Object : {VV$35$285 : Object | [(Prop([VV$35$285]));                                        (ttag([VV$35$285]) = lit$36$object)]}-bind 2 Object.prototype : {VV : (Object  Immutable) | [(? extends_interface([VV;+bind 2 Object.prototype : {VV : (Object  Immutable) | [(extends_interface([VV;                                                                              lit$36$Object]));-                                                       (? Prop([VV]));+                                                       (Prop([VV]));                                                        (ttag([VV]) = lit$36$object);                                                        (VV ~~ offset([Object; lit$36$prototype]))]} bind 3 NaN : {v : int | [(ttag([v]) = lit$36$number);-                         ((? Prop([v])) <=> (v != 0));+                         ((Prop([v])) <=> (v != 0));                          (v = numeric_nan)]}-bind 4 Number : {VV$35$325 : Object | [(? Prop([VV$35$325]));+bind 4 Number : {VV$35$325 : Object | [(Prop([VV$35$325]));                                        (ttag([VV$35$325]) = lit$36$object)]} bind 5 Number.POSITIVE_INFINITY : {v : int | [(ttag([v]) = lit$36$number);-                                              ((? Prop([v])) <=> (v != 0));+                                              ((Prop([v])) <=> (v != 0));                                               (v ~~ offset([Number; lit$36$POSITIVE_INFINITY]))]} bind 6 Number.MIN_VALUE : {v : int | [(ttag([v]) = lit$36$number);-                                      ((? Prop([v])) <=> (v != 0));+                                      ((Prop([v])) <=> (v != 0));                                       (v ~~ offset([Number; lit$36$MIN_VALUE]))]}-bind 7 Number.prototype : {VV : (Number  Immutable) | [(? extends_interface([VV;+bind 7 Number.prototype : {VV : (Number  Immutable) | [(extends_interface([VV;                                                                              lit$36$Number]));-                                                       (? Prop([VV]));+                                                       (Prop([VV]));                                                        (ttag([VV]) = lit$36$object);                                                        (VV ~~ offset([Number; lit$36$prototype]))]} bind 8 Number.NaN : {v : int | [(ttag([v]) = lit$36$number);-                                ((? Prop([v])) <=> (v != 0));+                                ((Prop([v])) <=> (v != 0));                                 (v ~~ offset([Number; lit$36$NaN]))]} bind 9 Number.NEGATIVE_INFINITY : {v : int | [(ttag([v]) = lit$36$number);-                                              ((? Prop([v])) <=> (v != 0));+                                              ((Prop([v])) <=> (v != 0));                                               (v ~~ offset([Number; lit$36$NEGATIVE_INFINITY]))]} bind 10 Number.MAX_VALUE : {v : int | [(ttag([v]) = lit$36$number);-                                       ((? Prop([v])) <=> (v != 0));+                                       ((Prop([v])) <=> (v != 0));                                        (v ~~ offset([Number; lit$36$MAX_VALUE]))]}-bind 11 Math : {VV$35$387 : (Math  Immutable) | [(? extends_interface([VV$35$387;+bind 11 Math : {VV$35$387 : (Math  Immutable) | [(extends_interface([VV$35$387;                                                                        lit$36$Math]));-                                                 (? Prop([VV$35$387]));+                                                 (Prop([VV$35$387]));                                                  (ttag([VV$35$387]) = lit$36$object)]} bind 12 Math.SQRT2 : {v : int | [(ttag([v]) = lit$36$number);-                                 ((? Prop([v])) <=> (v != 0));+                                 ((Prop([v])) <=> (v != 0));                                  (v ~~ offset([Math; lit$36$SQRT2]))]} bind 13 Math.LN2 : {v : int | [(ttag([v]) = lit$36$number);-                               ((? Prop([v])) <=> (v != 0));+                               ((Prop([v])) <=> (v != 0));                                (v ~~ offset([Math; lit$36$LN2]))]} bind 14 Math.PI : {v : int | [(ttag([v]) = lit$36$number);-                              ((? Prop([v])) <=> (v != 0));+                              ((Prop([v])) <=> (v != 0));                               (v ~~ offset([Math; lit$36$PI]))]} bind 15 Math.LOG10E : {v : int | [(ttag([v]) = lit$36$number);-                                  ((? Prop([v])) <=> (v != 0));+                                  ((Prop([v])) <=> (v != 0));                                   (v ~~ offset([Math; lit$36$LOG10E]))]} bind 16 Math.LOG2E : {v : int | [(ttag([v]) = lit$36$number);-                                 ((? Prop([v])) <=> (v != 0));+                                 ((Prop([v])) <=> (v != 0));                                  (v ~~ offset([Math; lit$36$LOG2E]))]} bind 17 Math.E : {v : int | [(ttag([v]) = lit$36$number);-                             ((? Prop([v])) <=> (v != 0));+                             ((Prop([v])) <=> (v != 0));                              (v ~~ offset([Math; lit$36$E]))]} bind 18 Math.SQRT1_2 : {v : int | [(ttag([v]) = lit$36$number);-                                   ((? Prop([v])) <=> (v != 0));+                                   ((Prop([v])) <=> (v != 0));                                    (v ~~ offset([Math; lit$36$SQRT1_2]))]} bind 19 Math.LN10 : {v : int | [(ttag([v]) = lit$36$number);-                                ((? Prop([v])) <=> (v != 0));+                                ((Prop([v])) <=> (v != 0));                                 (v ~~ offset([Math; lit$36$LN10]))]}-bind 20 String : {VV$35$469 : (StringConstructor  Immutable) | [(? extends_interface([VV$35$469;+bind 20 String : {VV$35$469 : (StringConstructor  Immutable) | [(extends_interface([VV$35$469;                                                                                       lit$36$StringConstructor]));-                                                                (? Prop([VV$35$469]));+                                                                (Prop([VV$35$469]));                                                                 (ttag([VV$35$469]) = lit$36$object)]}-bind 21 String.prototype : {VV : (String  Immutable) | [(? extends_interface([VV;+bind 21 String.prototype : {VV : (String  Immutable) | [(extends_interface([VV;                                                                               lit$36$String]));-                                                        (? Prop([VV]));+                                                        (Prop([VV]));                                                         (ttag([VV]) = lit$36$object);                                                         (VV ~~ offset([String; lit$36$prototype]))]}-bind 22 Array : {VV$35$727 : Object | [(? Prop([VV$35$727]));+bind 22 Array : {VV$35$727 : Object | [(Prop([VV$35$727]));                                        (ttag([VV$35$727]) = lit$36$object)]}-bind 23 Array.prototype : {VV : (Array  Mutable  Top) | [(? extends_interface([VV;+bind 23 Array.prototype : {VV : (Array  Mutable  Top) | [(extends_interface([VV;                                                                                lit$36$Array]));-                                                         (? Prop([VV]));+                                                         (Prop([VV]));                                                          (ttag([VV]) = lit$36$object);                                                          (VV ~~ offset([Array; lit$36$prototype]))]}-bind 24 Function : {VV$35$762 : Object | [(? Prop([VV$35$762]));+bind 24 Function : {VV$35$762 : Object | [(Prop([VV$35$762]));                                           (ttag([VV$35$762]) = lit$36$object)]}-bind 25 Function.prototype : {VV : (Function  Immutable) | [(? extends_interface([VV;+bind 25 Function.prototype : {VV : (Function  Immutable) | [(extends_interface([VV;                                                                                   lit$36$Function]));-                                                            (? Prop([VV]));+                                                            (Prop([VV]));                                                             (ttag([VV]) = lit$36$object);                                                             (VV ~~ offset([Function;                                                                            lit$36$prototype]))]}-bind 26 Console : {VV$35$891 : Object | [(? Prop([VV$35$891]));+bind 26 Console : {VV$35$891 : Object | [(Prop([VV$35$891]));                                          (ttag([VV$35$891]) = lit$36$object)]}-bind 27 Console.prototype : {VV : (Console  Immutable) | [(? extends_interface([VV;+bind 27 Console.prototype : {VV : (Console  Immutable) | [(extends_interface([VV;                                                                                 lit$36$Console]));-                                                          (? Prop([VV]));+                                                          (Prop([VV]));                                                           (ttag([VV]) = lit$36$object);                                                           (VV ~~ offset([Console;                                                                          lit$36$prototype]))]}-bind 28 console : {VV$35$893 : (Console  Immutable) | [(? extends_interface([VV$35$893;+bind 28 console : {VV$35$893 : (Console  Immutable) | [(extends_interface([VV$35$893;                                                                              lit$36$Console]));-                                                       (? Prop([VV$35$893]));+                                                       (Prop([VV$35$893]));                                                        (ttag([VV$35$893]) = lit$36$object)]}-bind 29 Error : {VV$35$983 : Object | [(? Prop([VV$35$983]));+bind 29 Error : {VV$35$983 : Object | [(Prop([VV$35$983]));                                        (ttag([VV$35$983]) = lit$36$object)]}-bind 30 Error.prototype : {VV : (Error  Immutable) | [(? extends_interface([VV;+bind 30 Error.prototype : {VV : (Error  Immutable) | [(extends_interface([VV;                                                                             lit$36$Error]));-                                                      (? Prop([VV]));+                                                      (Prop([VV]));                                                       (ttag([VV]) = lit$36$object);                                                       (VV ~~ offset([Error; lit$36$prototype]))]}-bind 31 Event : {VV$35$1025 : Object | [(? Prop([VV$35$1025]));+bind 31 Event : {VV$35$1025 : Object | [(Prop([VV$35$1025]));                                         (ttag([VV$35$1025]) = lit$36$object)]} bind 32 Event.CAPTURING_PHASE : {v : int | [(ttag([v]) = lit$36$number);-                                            ((? Prop([v])) <=> (v != 0));+                                            ((Prop([v])) <=> (v != 0));                                             (v ~~ offset([Event; lit$36$CAPTURING_PHASE]))]} bind 33 Event.AT_TARGET : {v : int | [(ttag([v]) = lit$36$number);-                                      ((? Prop([v])) <=> (v != 0));+                                      ((Prop([v])) <=> (v != 0));                                       (v ~~ offset([Event; lit$36$AT_TARGET]))]}-bind 34 Event.prototype : {VV : (Event  Immutable) | [(? extends_interface([VV;+bind 34 Event.prototype : {VV : (Event  Immutable) | [(extends_interface([VV;                                                                             lit$36$Event]));-                                                      (? Prop([VV]));+                                                      (Prop([VV]));                                                       (ttag([VV]) = lit$36$object);                                                       (VV ~~ offset([Event; lit$36$prototype]))]} bind 35 Event.BUBBLING_PHASE : {v : int | [(ttag([v]) = lit$36$number);-                                           ((? Prop([v])) <=> (v != 0));+                                           ((Prop([v])) <=> (v != 0));                                            (v ~~ offset([Event; lit$36$BUBBLING_PHASE]))]}-bind 36 document : {VV$35$1027 : (Document  Immutable) | [(? extends_interface([VV$35$1027;+bind 36 document : {VV$35$1027 : (Document  Immutable) | [(extends_interface([VV$35$1027;                                                                                 lit$36$Document]));-                                                          (? Prop([VV$35$1027]));+                                                          (Prop([VV$35$1027]));                                                           (ttag([VV$35$1027]) = lit$36$object)]}-bind 37 document.documentElement : {VV : (HTMLElement  Immutable) | [(? extends_interface([VV;+bind 37 document.documentElement : {VV : (HTMLElement  Immutable) | [(extends_interface([VV;                                                                                            lit$36$HTMLElement]));-                                                                     (? Prop([VV]));+                                                                     (Prop([VV]));                                                                      (ttag([VV]) = lit$36$object);                                                                      (VV ~~ offset([document;                                                                                     lit$36$documentElement]))]}-bind 38 window : {VV$35$1031 : (Window  Immutable) | [(? extends_interface([VV$35$1031;+bind 38 window : {VV$35$1031 : (Window  Immutable) | [(extends_interface([VV$35$1031;                                                                             lit$36$Window]));-                                                      (? Prop([VV$35$1031]));+                                                      (Prop([VV$35$1031]));                                                       (ttag([VV$35$1031]) = lit$36$object)]} bind 39 lq_tmp_nano_1 : {VV : (BitVec  Size32) | [(VV = (lit "#x00000008" (BitVec  Size32)))]} bind 40 a_SSA_0 : {VV : (BitVec  Size32) | [(VV ~~ lq_tmp_nano_1);@@ -217,7 +217,7 @@ bind 43 lq_tmp_nano_3 : {v : (BitVec  Size32) | [(v = bvor([a_SSA_0;                                                             a_SSA_0]))]} bind 44 lq_tmp_nano_6 : {v : Boolean | [(ttag([v]) = lit$36$boolean);-                                        ((? Prop([v])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}+                                        ((Prop([v])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]} bind 45 lq_tmp_nano_9 : {VV$35$4 : Void | []}  @@ -272,8 +272,8 @@   lhs {VV$35$F1 : Boolean | [(ttag([VV$35$F1]) = lit$36$boolean);                              (VV$35$F1 ~~ lq_tmp_nano_6);                              (ttag([VV$35$F1]) = lit$36$boolean);-                             ((? Prop([VV$35$F1])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}-  rhs {VV$35$F1 : Boolean | [(? Prop([VV$35$F1]))]}+                             ((Prop([VV$35$F1])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}+  rhs {VV$35$F1 : Boolean | [(Prop([VV$35$F1]))]}   id 1 tag [1]   // META constraint id 1 : /Users/rjhala/research/stack/liquid/refscript/tests/pos/simple/hex.ts:7:1-7:22 @@ -327,8 +327,8 @@   lhs {VV$35$F2 : Boolean | [(ttag([VV$35$F2]) = lit$36$boolean);                              (VV$35$F2 ~~ lq_tmp_nano_6);                              (ttag([VV$35$F2]) = lit$36$boolean);-                             ((? Prop([VV$35$F2])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}-  rhs {VV$35$F2 : Boolean | [(? Prop([VV$35$F2]))]}+                             ((Prop([VV$35$F2])) <=> (b_SSA_1 ~~ lq_tmp_nano_3))]}+  rhs {VV$35$F2 : Boolean | [(Prop([VV$35$F2]))]}   id 2 tag [1]   // META constraint id 2 : /Users/rjhala/research/stack/liquid/refscript/tests/pos/simple/hex.ts:7:1-7:22 
tests/pos/kvar-param-poly-00.fq view
@@ -2,7 +2,7 @@ // a kvar's params can be instantiated / substituted with values of a different // type. Here, K0(v:alpha, x:alpha) but is instantiated with int. -qualif Bog(v:a, x:a) : (x = v)+qualif Bog(v:a, x:a)  { x = v }  bind 1 x : {v: alpha | true} 
tests/pos/len00-rename.fq view
@@ -1,7 +1,7 @@  // This qualifier saves the day; solve constraints WITHOUT IT -qualif ListZ(v : [@(0)]): (len v >= 0)+qualif ListZ(v : [@(0)]) { len v >= 0 }  constant len : (func(2, [(@(0)  @(1)); int])) 
tests/pos/len00.fq view
@@ -1,7 +1,7 @@  // This qualifier saves the day; solve constraints WITHOUT IT -qualif ListZ(v : [@(0)]): (len v >= 0)+qualif ListZ(v : [@(0)]) { len v >= 0 }  constant len : (func(2, [(@(0)  @(1)); int])) 
tests/pos/listqual.hs.fq view
@@ -1,53 +1,53 @@-qualif Append(v : [@(0)], xs : [@(0)], ys : [@(0)]): (len([v]) = (len([xs]) + len([ys]))) // "tests/pos/listqual.hs" (line 3, column 12)-qualif Fst(v : @(1), y : @(0)): (v = fst([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 29, column 8)-qualif Snd(v : @(1), y : @(0)): (v = snd([y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 30, column 8)-qualif Auto(v : [int]): (len([v]) = 2) // "tests/pos/listqual.hs" (line 10, column 1)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) > 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 13, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) = 0)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 14, column 8)-qualif ListZ(v : [@(0)]): (len([v]) = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 16, column 8)-qualif ListZ(v : [@(0)]): (len([v]) >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 17, column 8)-qualif ListZ(v : [@(0)]): (len([v]) > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 18, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 20, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) >= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 21, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) > len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 22, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) <= len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 23, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) < len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 24, column 8)-qualif EqLen(v : int, xs : [@(0)]): (v = len([xs])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 26, column 8)-qualif LenEq(v : [@(0)], x : int): (x = len([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 27, column 8)-qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x + 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 28, column 8)-qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x - 1)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 29, column 8)-qualif LenAcc(v : int, xs : [@(0)], n : int): (v = (len([xs]) + n)) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 30, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 3, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 4, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 5, column 8)-qualif Bot(v : bool): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 6, column 8)-qualif Bot(v : int): (0 = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 7, column 8)-qualif CmpZ(v : @(0)): (v < 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 9, column 8)-qualif CmpZ(v : @(0)): (v <= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 10, column 8)-qualif CmpZ(v : @(0)): (v > 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 11, column 8)-qualif CmpZ(v : @(0)): (v >= 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 12, column 8)-qualif CmpZ(v : @(0)): (v = 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 13, column 8)-qualif CmpZ(v : @(0)): (v != 0) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 14, column 8)-qualif Cmp(v : @(0), x : @(0)): (v < x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 16, column 8)-qualif Cmp(v : @(0), x : @(0)): (v <= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 17, column 8)-qualif Cmp(v : @(0), x : @(0)): (v > x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 18, column 8)-qualif Cmp(v : @(0), x : @(0)): (v >= x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 19, column 8)-qualif Cmp(v : @(0), x : @(0)): (v = x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 20, column 8)-qualif Cmp(v : @(0), x : @(0)): (v != x) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 21, column 8)-qualif One(v : int): (v = 1) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 28, column 8)-qualif True(v : bool): (? v) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 29, column 8)-qualif False(v : bool): (~ ((? v))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 30, column 8)-qualif True1(v : GHC.Types.Bool): (? Prop([v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 31, column 8)-qualif False1(v : GHC.Types.Bool): (~ ((? Prop([v])))) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 32, column 8)-qualif Papp(v : @(0), p : (Pred  @(0))): (? papp1([p;-                                                   v])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 35, column 8)-qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): (? papp2([p;+qualif Append(v : [@(0)], xs : [@(0)], ys : [@(0)]) { len([v]) = (len([xs]) + len([ys]))  } // "tests/pos/listqual.hs" (line 3, column 12)+qualif Fst(v : @(1), y : @(0)) { v = fst([y])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 29, column 8)+qualif Snd(v : @(1), y : @(0)) { v = snd([y])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.spec" (line 30, column 8)+qualif Auto(v : [int]) { len([v]) = 2  } // "tests/pos/listqual.hs" (line 10, column 1)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { Prop([v]) <=> len([xs]) > 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 13, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { Prop([v]) <=> len([xs]) = 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 14, column 8)+qualif ListZ(v : [@(0)]) { len([v]) = 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 16, column 8)+qualif ListZ(v : [@(0)]) { len([v]) >= 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 17, column 8)+qualif ListZ(v : [@(0)]) { len([v]) > 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 18, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) = len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 20, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) >= len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 21, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) > len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 22, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) <= len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 23, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) < len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 24, column 8)+qualif EqLen(v : int, xs : [@(0)]) { v = len([xs])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 26, column 8)+qualif LenEq(v : [@(0)], x : int) { x = len([v])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 27, column 8)+qualif LenDiff(v : [@(0)], x : int) { len([v]) = (x + 1)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 28, column 8)+qualif LenDiff(v : [@(0)], x : int) { len([v]) = (x - 1)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 29, column 8)+qualif LenAcc(v : int, xs : [@(0)], n : int) { v = (len([xs]) + n)  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/GHC/Base.hquals" (line 30, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 3, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 4, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 5, column 8)+qualif Bot(v : bool) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 6, column 8)+qualif Bot(v : int) { 0 = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 7, column 8)+qualif CmpZ(v : @(0)) { v < 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 9, column 8)+qualif CmpZ(v : @(0)) { v <= 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 10, column 8)+qualif CmpZ(v : @(0)) { v > 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 11, column 8)+qualif CmpZ(v : @(0)) { v >= 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 12, column 8)+qualif CmpZ(v : @(0)) { v = 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 13, column 8)+qualif CmpZ(v : @(0)) { v != 0  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 14, column 8)+qualif Cmp(v : @(0), x : @(0)) { v < x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 16, column 8)+qualif Cmp(v : @(0), x : @(0)) { v <= x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 17, column 8)+qualif Cmp(v : @(0), x : @(0)) { v > x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 18, column 8)+qualif Cmp(v : @(0), x : @(0)) { v >= x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 19, column 8)+qualif Cmp(v : @(0), x : @(0)) { v = x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 20, column 8)+qualif Cmp(v : @(0), x : @(0)) { v != x  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 21, column 8)+qualif One(v : int) { v = 1  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 28, column 8)+qualif True(v : bool) {  v  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 29, column 8)+qualif False(v : bool) { ~ v  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 30, column 8)+qualif True1(v : GHC.Types.Bool) {  Prop([v])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 31, column 8)+qualif False1(v : GHC.Types.Bool) { ~ Prop([v])  } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 32, column 8)+qualif Papp(v : @(0), p : (Pred  @(0))) { papp1([p;+                                                   v]) } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 35, column 8)+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))) { papp2([p;                                                                     v;-                                                                    x])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 38, column 8)-qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): (? papp3([p;+                                                                    x]) } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 38, column 8)+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))) { papp3([p;                                                                                     v;                                                                                     x;-                                                                                    y])) // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 41, column 8)+                                                                                    y]) } // "/Users/rjhala/research/stack/liquid/liquidhaskell/.stack-work/install/x86_64-osx/nightly-2015-09-24/7.10.2/share/x86_64-osx-ghc-7.10.2/liquidhaskell-0.5.0.2/include/Prelude.hquals" (line 41, column 8)   cut $k__185@@ -163,10 +163,10 @@ bind 13 lq_anf__dwU : {lq_tmp_x_198 : [a_awA] | [(lq_tmp_x_198 = ds_dwT);                                                  (len([lq_tmp_x_198]) >= 0);                                                  (len([lq_tmp_x_198]) = 0);-                                                 ((? null([lq_tmp_x_198])) <=> true);+                                                 (null([lq_tmp_x_198]) <=> true);                                                  (lq_tmp_x_198 = GHC.Types.$91$$93$$35$6m([]));                                                  (len([lq_tmp_x_198]) = 0);-                                                 ((? null([lq_tmp_x_198])) <=> true);+                                                 (null([lq_tmp_x_198]) <=> true);                                                  (len([lq_tmp_x_198]) >= 0)]} bind 14 lq_anf__dwU : {lq_tmp_x_208 : [a_awA] | [(lq_tmp_x_208 = ds_dwT);                                                  (len([lq_tmp_x_208]) >= 0);@@ -176,13 +176,13 @@ bind 17 lq_anf__dwU : {lq_tmp_x_208 : [a_awA] | [(lq_tmp_x_208 = ds_dwT);                                                  (len([lq_tmp_x_208]) >= 0);                                                  (len([lq_tmp_x_208]) = (1 + len([xs$35$awp])));-                                                 ((? null([lq_tmp_x_208])) <=> false);+                                                 (null([lq_tmp_x_208]) <=> false);                                                  (xsListSelector([lq_tmp_x_208]) = xs$35$awp);                                                  (xListSelector([lq_tmp_x_208]) = x$35$awo);                                                  (lq_tmp_x_208 = GHC.Types.$58$$35$64([x$35$awo;                                                                                        xs$35$awp]));                                                  (len([lq_tmp_x_208]) = (1 + len([xs$35$awp])));-                                                 ((? null([lq_tmp_x_208])) <=> false);+                                                 (null([lq_tmp_x_208]) <=> false);                                                  (xsListSelector([lq_tmp_x_208]) = xs$35$awp);                                                  (xListSelector([lq_tmp_x_208]) = x$35$awo);                                                  (len([lq_tmp_x_208]) >= 0)]}@@ -192,22 +192,22 @@ bind 20 lq_anf__dwW : {lq_tmp_x_264 : int | [(lq_tmp_x_264 = (1  :  int))]} bind 21 lq_tmp_x_278 : {VV$35$279 : int | []} bind 22 lq_anf__dwX : {lq_tmp_x_270 : [int] | [(len([lq_tmp_x_270]) = 0);-                                               ((? null([lq_tmp_x_270])) <=> true);+                                               (null([lq_tmp_x_270]) <=> true);                                                (len([lq_tmp_x_270]) >= 0)]} bind 23 lq_tmp_x_296 : {VV$35$297 : int | []} bind 24 lq_anf__dwY : {lq_tmp_x_284 : [int] | [(len([lq_tmp_x_284]) = (1 + len([lq_anf__dwX])));-                                               ((? null([lq_tmp_x_284])) <=> false);+                                               (null([lq_tmp_x_284]) <=> false);                                                (xsListSelector([lq_tmp_x_284]) = lq_anf__dwX);                                                (xListSelector([lq_tmp_x_284]) = lq_anf__dwW);                                                (len([lq_tmp_x_284]) >= 0)]} bind 25 lq_anf__dwZ : {lq_tmp_x_305 : int | [(lq_tmp_x_305 = (2  :  int))]} bind 26 lq_tmp_x_319 : {VV$35$320 : int | []} bind 27 lq_anf__dx0 : {lq_tmp_x_311 : [int] | [(len([lq_tmp_x_311]) = 0);-                                               ((? null([lq_tmp_x_311])) <=> true);+                                               (null([lq_tmp_x_311]) <=> true);                                                (len([lq_tmp_x_311]) >= 0)]} bind 28 lq_tmp_x_337 : {VV$35$338 : int | []} bind 29 lq_anf__dx1 : {lq_tmp_x_325 : [int] | [(len([lq_tmp_x_325]) = (1 + len([lq_anf__dx0])));-                                               ((? null([lq_tmp_x_325])) <=> false);+                                               (null([lq_tmp_x_325]) <=> false);                                                (xsListSelector([lq_tmp_x_325]) = lq_anf__dx0);                                                (xListSelector([lq_tmp_x_325]) = lq_anf__dwZ);                                                (len([lq_tmp_x_325]) >= 0)]}@@ -269,12 +269,12 @@ bind 72 VV$35$427 : {VV$35$427 : int | [(VV$35$427 = 1)]} bind 73 VV$35$427 : {VV$35$427 : int | [(VV$35$427 = 1)]} bind 74 VV$35$430 : {VV$35$430 : [a_awA] | [(len([VV$35$430]) = (1 + len([lq_anf__dwV])));-                                            ((? null([VV$35$430])) <=> false);+                                            (null([VV$35$430]) <=> false);                                             (xsListSelector([VV$35$430]) = lq_anf__dwV);                                             (xListSelector([VV$35$430]) = x$35$awo);                                             (len([VV$35$430]) >= 0)]} bind 75 VV$35$430 : {VV$35$430 : [a_awA] | [(len([VV$35$430]) = (1 + len([lq_anf__dwV])));-                                            ((? null([VV$35$430])) <=> false);+                                            (null([VV$35$430]) <=> false);                                             (xsListSelector([VV$35$430]) = lq_anf__dwV);                                             (xListSelector([VV$35$430]) = x$35$awo);                                             (len([VV$35$430]) >= 0)]}@@ -384,7 +384,7 @@ constraint:   env [0; 16; 1; 17; 2; 18; 3; 4; 5; 6; 7; 8; 9; 10; 74; 11; 14; 15]   lhs {VV$35$F18 : [a_awA] | [(len([VV$35$F18]) = (1 + len([lq_anf__dwV])));-                              ((? null([VV$35$F18])) <=> false);+                              (null([VV$35$F18]) <=> false);                               (xsListSelector([VV$35$F18]) = lq_anf__dwV);                               (xListSelector([VV$35$F18]) = x$35$awo);                               (len([VV$35$F18]) >= 0)]}
tests/pos/meas02.fq view
@@ -1,7 +1,7 @@ -qualif SumZ(v:[real]): (sumD v = 0.0)+qualif SumZ(v:[real]) { sumD v = 0.0 } -qualif SumZ(v:[real]): (((sumD v) / (sumD v)) = 1.0)+qualif SumZ(v:[real]) { ((sumD v) / (sumD v)) = 1.0 }  constant sumD : (func(0, [[real]; real])) 
tests/pos/min00.fq view
@@ -1,8 +1,8 @@ -qualif Zog(v:a) : (10 <= v)-qualif Zog(v:a) : (9 <= v)-qualif Zog(v:a) : (8 <= v)-qualif Zog(v:a) : (99 <= v)+qualif Zog(v:a)  { 10 <= v }+qualif Zog(v:a)  { 9 <= v }+qualif Zog(v:a)  { 8 <= v }+qualif Zog(v:a)  { 99 <= v }  constraint:   env []
tests/pos/num00.fq view
@@ -1,6 +1,6 @@ // This qualifier saves the day; solve constraints WITHOUT IT -qualif Zog(v:a) : (0 <= v)+qualif Zog(v:a)  { 0 <= v }  bind 0 alpha : {v : num | true} 
tests/pos/numoverload00.fq view
@@ -1,6 +1,6 @@ -qualif Foo(v:real, xiggety:real): (v = xiggety * xiggety)-qualif Bar(v:real): (v = 0.0)+qualif Foo(v:real, xiggety:real) { v = xiggety * xiggety }+qualif Bar(v:real) { v = 0.0 }  bind 0 zero  : {VV : real | VV = 0.0 } bind 1 one   : {VV : real | VV = (1.0 / 1.0) }
tests/pos/qualif-inst.fq view
@@ -1,6 +1,6 @@ // adapted from LH test eqelems.hs -qualif Cmp(v : @(0), fix##126#X : @(0)): (v >= fix##126#X)+qualif Cmp(v : @(0), fix##126#X : @(0)) { v >= fix##126#X }  constant elems : (func(1, [(Goo.T  @(0)); (Set_Set  @(0))])) 
tests/pos/qualif-template-00.fq view
@@ -1,6 +1,6 @@ // qualif Goob(v:a, z: b) : (v = z) // qualif Prefix2(v:a, x as (mon . $1) : b, y as (sun . $1)) : (v = x + y)-qualif Prefix(v:a, z as (mon . $1) : b) : (v = z)+qualif Prefix(v:a, z as (mon . $1) : b)  { v = z }  bind 0  monday  : {v : int | true} bind 10 tuesday : {v : int | true}
tests/pos/qualif-template-01.fq view
@@ -1,6 +1,6 @@ // qualif Goob(v:a, z: b) : (v = z) // qualif Prefix2(v:a, x as (mon . $1) : b, y as (sun . $1)) : (v = x + y)-qualif Prefix(v:a, z as ($1 . nday) : b) : (v = z)+qualif Prefix(v:a, z as ($1 . nday) : b)  { v = z }  bind 0  monday  : {v : int | true} bind 10 tuesday : {v : int | true}
tests/pos/qualif-template-02.fq view
@@ -1,4 +1,4 @@-qualif Prefix2(v:a, x as (sun . $1)  : b, y as (mon . $1) : b) : (v = x + y)+qualif Prefix2(v:a, x as (sun . $1)  : b, y as (mon . $1) : b)  { v = x + y }  bind 0  sunday  : {v : int | v = 6  } bind 1  monday  : {v : int | v = 4  }
tests/pos/sets.fq view
@@ -2,6 +2,6 @@  constraint:   env []-  lhs {v : Set_Set a_aTp | [(? Set_emp([v]))]}+  lhs {v : Set_Set a_aTp | [(Set_emp([v]))]}   rhs {v : Set_Set a_aTp | [(v = Set_empty([0]))]}   id 3 tag [2]
tests/pos/test00.fq view
@@ -1,5 +1,5 @@-qualif Zog(v:a) : (10 <= v)-qualif Bog(v:a, x:a) : (x <= v)+qualif Zog(v:a)  { 10 <= v }+qualif Bog(v:a, x:a)  { x <= v }  bind 0 a : {va: int | $k0[v := va][thing := thang] } bind 1 thing : {v: int | true }
tests/pos/test00.hs.fq view
@@ -1,61 +1,61 @@ -qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (Prop(v) <=> len([xs]) > 0)-qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (Prop(v) <=> len([xs]) = 0)-qualif ListZ(v: [a])          : len([v]) =  0 -qualif ListZ(v: [a])          : len([v]) >= 0 -qualif ListZ(v: [a])          : len([v]) >  0 -qualif CmpLen(v:[a], xs:[b])  : len([v]) =  len([xs]) -qualif CmpLen(v:[a], xs:[b])  : len([v]) >= len([xs]) -qualif CmpLen(v:[a], xs:[b])  : len([v]) >  len([xs]) -qualif CmpLen(v:[a], xs:[b])  : len([v]) <= len([xs]) -qualif CmpLen(v:[a], xs:[b])  : len([v]) <  len([xs]) -qualif EqLen(v:int, xs: [a]): v = len([xs]) -qualif LenEq(v:[a], x: int) :  x = len([v]) -qualif LenDiff(v:[a], x:int): len([v]) = x + 1-qualif LenDiff(v:[a], x:int): len([v]) = x - 1-qualif LenAcc(v:int, xs:[a], n: int): (v = len([xs]) + n)+qualif IsEmp(v:GHC.Types.Bool, xs: [a])  { Prop(v) <=> len([xs]) > 0 }+qualif IsEmp(v:GHC.Types.Bool, xs: [a])  { Prop(v) <=> len([xs]) = 0 }+qualif ListZ(v: [a])           { len([v]) =  0  }+qualif ListZ(v: [a])           { len([v]) >= 0  }+qualif ListZ(v: [a])           { len([v]) >  0  }+qualif CmpLen(v:[a], xs:[b])   { len([v]) =  len([xs])  }+qualif CmpLen(v:[a], xs:[b])   { len([v]) >= len([xs])  }+qualif CmpLen(v:[a], xs:[b])   { len([v]) >  len([xs])  }+qualif CmpLen(v:[a], xs:[b])   { len([v]) <= len([xs])  }+qualif CmpLen(v:[a], xs:[b])   { len([v]) <  len([xs])  }+qualif EqLen(v:int, xs: [a]) { v = len([xs])  }+qualif LenEq(v:[a], x: int)  { x = len([v])  }+qualif LenDiff(v:[a], x:int) { len([v]) = x + 1 }+qualif LenDiff(v:[a], x:int) { len([v]) = x - 1 }+qualif LenAcc(v:int, xs:[a], n: int) { v = len([xs]) + n } -qualif Bot(v:obj): 0 = 1 -qualif Bot(v:a): 0 = 1 -qualif Bot(v:bool): 0 = 1 -qualif Bot(v:int): 0 = 1 -qualif CmpZ(v:a): (v <  0)-qualif CmpZ(v:a): (v <= 0)-qualif CmpZ(v:a): (v >  0)-qualif CmpZ(v:a): (v >= 0)-qualif CmpZ(v:a): (v  = 0)-qualif CmpZ(v:a): (v != 0)+qualif Bot(v:obj) { 0 = 1  }+qualif Bot(v:a) { 0 = 1  }+qualif Bot(v:bool) { 0 = 1  }+qualif Bot(v:int) { 0 = 1  }+qualif CmpZ(v:a) { v <  0 }+qualif CmpZ(v:a) { v <= 0 }+qualif CmpZ(v:a) { v >  0 }+qualif CmpZ(v:a) { v >= 0 }+qualif CmpZ(v:a) { v  = 0 }+qualif CmpZ(v:a) { v != 0 } -qualif Cmp(v:a, x:a): (v <  x)-qualif Cmp(v:a, x:a): (v <= x)-qualif Cmp(v:a, x:a): (v >  x)-qualif Cmp(v:a, x:a): (v >= x)-qualif Cmp(v:a, x:a): (v  = x)-qualif Cmp(v:a, x:a): (v != x)+qualif Cmp(v:a, x:a) { v <  x }+qualif Cmp(v:a, x:a) { v <= x }+qualif Cmp(v:a, x:a) { v >  x }+qualif Cmp(v:a, x:a) { v >= x }+qualif Cmp(v:a, x:a) { v  = x }+qualif Cmp(v:a, x:a) { v != x } -qualif One(v:int)     : v = 1-qualif True(v:bool)   : (? v) -qualif False(v:bool)  : ~ (? v) -qualif True1(v:GHC.Types.Bool): (Prop(v))-qualif False1(v:GHC.Types.Bool): (~ Prop(v))-qualif Papp(v:a, p:Pred a) : (papp1 p v)+qualif One(v:int)      { v = 1 }+qualif True(v:bool)    { v  }+qualif False(v:bool)   { ~ (v)  }+qualif True1(v:GHC.Types.Bool) { Prop(v) }+qualif False1(v:GHC.Types.Bool) { ~ Prop(v) }+qualif Papp(v:a, p:Pred a)  { papp1 p v }  constant papp1 : func(1, [Pred @(0); @(0); bool]) -qualif Papp2(v:a,x:b,p:Pred a b) : (papp2 p v x)+qualif Papp2(v:a,x:b,p:Pred a b)  { papp2 p v x } constant papp2 : func(4, [Pred @(0) @(1); @(2); @(3); bool]) -qualif Papp3(v:a,x:b, y:c, p:Pred a b c) : (papp3 p v x y)+qualif Papp3(v:a,x:b, y:c, p:Pred a b c)  { papp3 p v x y } constant papp3 : func(6, [Pred @(0) @(1) @(2); @(3); @(4); @(5); bool]) -qualif Papp4(v:a,x:b, y:c, z:d, p:Pred a b c d) : (papp4 p v x y z)+qualif Papp4(v:a,x:b, y:c, z:d, p:Pred a b c d)  { papp4 p v x y z } constant papp4 : func(8, [Pred @(0) @(1) @(2) @(6); @(3); @(4); @(5); @(7); bool])    constant Prop : func(0, [GHC.Types.Bool; bool])-qualif Fst(v : @(1), fix##126#Y : @(0)): (v = fst([fix##126#Y])) // "/Users/rjhala/research/liquid/liquidhaskell/.cabal-sandbox/share/x86_64-osx-ghc-7.8.3/liquidhaskell-0.3.1.0/include/GHC/Base.spec" (line 26, column 8)-qualif Snd(v : @(1), fix##126#Y : @(0)): (v = snd([fix##126#Y])) // "/Users/rjhala/research/liquid/liquidhaskell/.cabal-sandbox/share/x86_64-osx-ghc-7.8.3/liquidhaskell-0.3.1.0/include/GHC/Base.spec" (line 27, column 8)+qualif Fst(v : @(1), fix##126#Y : @(0)) { v = fst([fix##126#Y])  } // "/Users/rjhala/research/liquid/liquidhaskell/.cabal-sandbox/share/x86_64-osx-ghc-7.8.3/liquidhaskell-0.3.1.0/include/GHC/Base.spec" (line 26, column 8)+qualif Snd(v : @(1), fix##126#Y : @(0)) { v = snd([fix##126#Y])  } // "/Users/rjhala/research/liquid/liquidhaskell/.cabal-sandbox/share/x86_64-osx-ghc-7.8.3/liquidhaskell-0.3.1.0/include/GHC/Base.spec" (line 27, column 8)  constant Prop : func(0, [GHC.Types.Bool; bool]) constant x_Tuple54 : func(5, [FAppTy (FAppTy (FAppTy (FAppTy (FAppTy fix##40##41#  @(0))  @(1))  @(2))  @(3))  @(4);@@ -138,8 +138,8 @@ bind 7 GHC.Types.EQ#6U : {VV#179 : GHC.Types.Ordering | []} bind 8 GHC.Types.LT#6S : {VV#180 : GHC.Types.Ordering | []} bind 9 GHC.Types.GT#6W : {VV#181 : GHC.Types.Ordering | []}-bind 10 GHC.Types.True#6u : {v : GHC.Types.Bool | [(? Prop([v]))]}-bind 11 GHC.Types.False#68 : {v : GHC.Types.Bool | [(~ ((? Prop([v]))))]}+bind 10 GHC.Types.True#6u : {v : GHC.Types.Bool | [(Prop([v]))]}+bind 11 GHC.Types.False#68 : {v : GHC.Types.Bool | [(~ ((Prop([v]))))]} bind 12 Language.Haskell.Liquid.Prelude.plus#rou : {VV : func(0, [int;                                                                   int;                                                                   int]) | []}@@ -206,25 +206,25 @@ bind 39 gooberding#a15N : {VV#234 : a_a164 | [$k_235]} bind 40 lq_anf__d16w : {lq_tmp_x241 : int | [(lq_tmp_x241 = 0)]} bind 41 lq_anf__d16x : {VV : a_a164 | [(VV = lq_anf__d16w)]}-bind 42 lq_anf__d16y : {lq_tmp_x254 : GHC.Types.Bool | [((? Prop([lq_tmp_x254])) <=> (gooberding#a15N >= lq_anf__d16x))]}+bind 42 lq_anf__d16y : {lq_tmp_x254 : GHC.Types.Bool | [((Prop([lq_tmp_x254])) <=> (gooberding#a15N >= lq_anf__d16x))]} bind 43 lq_anf__d16z : {lq_tmp_x276 : int | [(lq_tmp_x276 = (0  :  int))]} bind 44 Test0.x#r12i : {VV#272 : int | [$k_273]} bind 45 lq_anf__d16A : {lq_tmp_x291 : int | [(lq_tmp_x291 = (0  :  int))]}-bind 46 lq_anf__d16B : {lq_tmp_x297 : GHC.Types.Bool | [((? Prop([lq_tmp_x297])) <=> (Test0.x#r12i > lq_anf__d16A))]}-bind 47 lq_anf__d16C : {lq_tmp_x313 : GHC.Types.Bool | [((? Prop([lq_tmp_x313])) <=> (Test0.x#r12i > lq_anf__d16A));+bind 46 lq_anf__d16B : {lq_tmp_x297 : GHC.Types.Bool | [((Prop([lq_tmp_x297])) <=> (Test0.x#r12i > lq_anf__d16A))]}+bind 47 lq_anf__d16C : {lq_tmp_x313 : GHC.Types.Bool | [((Prop([lq_tmp_x313])) <=> (Test0.x#r12i > lq_anf__d16A));                                                         (lq_tmp_x313 = lq_anf__d16B)]}-bind 48 lq_anf__d16C : {lq_tmp_x315 : GHC.Types.Bool | [((? Prop([lq_tmp_x315])) <=> (Test0.x#r12i > lq_anf__d16A));+bind 48 lq_anf__d16C : {lq_tmp_x315 : GHC.Types.Bool | [((Prop([lq_tmp_x315])) <=> (Test0.x#r12i > lq_anf__d16A));                                                         (lq_tmp_x315 = lq_anf__d16B)]}-bind 49 lq_anf__d16C : {lq_tmp_x315 : GHC.Types.Bool | [((? Prop([lq_tmp_x315])) <=> (Test0.x#r12i > lq_anf__d16A));+bind 49 lq_anf__d16C : {lq_tmp_x315 : GHC.Types.Bool | [((Prop([lq_tmp_x315])) <=> (Test0.x#r12i > lq_anf__d16A));                                                         (lq_tmp_x315 = lq_anf__d16B);-                                                        (~ ((? Prop([lq_tmp_x315]))));-                                                        (~ ((? Prop([lq_tmp_x315]))))]}-bind 50 lq_anf__d16C : {lq_tmp_x321 : GHC.Types.Bool | [((? Prop([lq_tmp_x321])) <=> (Test0.x#r12i > lq_anf__d16A));+                                                        (~ ((Prop([lq_tmp_x315]))));+                                                        (~ ((Prop([lq_tmp_x315]))))]}+bind 50 lq_anf__d16C : {lq_tmp_x321 : GHC.Types.Bool | [((Prop([lq_tmp_x321])) <=> (Test0.x#r12i > lq_anf__d16A));                                                         (lq_tmp_x321 = lq_anf__d16B)]}-bind 51 lq_anf__d16C : {lq_tmp_x321 : GHC.Types.Bool | [((? Prop([lq_tmp_x321])) <=> (Test0.x#r12i > lq_anf__d16A));+bind 51 lq_anf__d16C : {lq_tmp_x321 : GHC.Types.Bool | [((Prop([lq_tmp_x321])) <=> (Test0.x#r12i > lq_anf__d16A));                                                         (lq_tmp_x321 = lq_anf__d16B);-                                                        (? Prop([lq_tmp_x321]));-                                                        (? Prop([lq_tmp_x321]))]}+                                                        (Prop([lq_tmp_x321]));+                                                        (Prop([lq_tmp_x321]))]} bind 52 Test0.prop_abs#r12j : {VV#287 : GHC.Types.Bool | [$k_288]} bind 53 VV#343 : {VV#343 : GHC.Types.Bool | [$k_239[VV#238:=VV#343][fix##36#dOrd_a165:=fix#GHC.Classes.#36#fOrdInt#35#rhx][fix##36#dNum_a166:=fix#GHC.Num.#36#fNumInt#35#rhy][gooberding#a15N:=Test0.x#r12i][lq_tmp_x332:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x333:=fix#GHC.Num.#36#fNumInt#35#rhy][lq_tmp_x334:=Test0.x#r12i][lq_tmp_x328:=VV#343]]} bind 54 VV#343 : {VV#343 : GHC.Types.Bool | [$k_239[VV#238:=VV#343][fix##36#dOrd_a165:=fix#GHC.Classes.#36#fOrdInt#35#rhx][fix##36#dNum_a166:=fix#GHC.Num.#36#fNumInt#35#rhy][gooberding#a15N:=Test0.x#r12i][lq_tmp_x332:=fix#GHC.Classes.#36#fOrdInt#35#rhx][lq_tmp_x333:=fix#GHC.Num.#36#fNumInt#35#rhy][lq_tmp_x334:=Test0.x#r12i][lq_tmp_x328:=VV#343]]}@@ -232,9 +232,9 @@                                   (VV#346 = Test0.x#r12i)]} bind 56 VV#346 : {VV#346 : int | [$k_273[VV#272:=VV#346][lq_tmp_x341:=VV#346];                                   (VV#346 = Test0.x#r12i)]}-bind 57 VV#349 : {VV#349 : GHC.Types.Bool | [(~ ((? Prop([VV#349]))));+bind 57 VV#349 : {VV#349 : GHC.Types.Bool | [(~ ((Prop([VV#349]))));                                              (VV#349 = GHC.Types.False#68)]}-bind 58 VV#349 : {VV#349 : GHC.Types.Bool | [(~ ((? Prop([VV#349]))));+bind 58 VV#349 : {VV#349 : GHC.Types.Bool | [(~ ((Prop([VV#349]))));                                              (VV#349 = GHC.Types.False#68)]} bind 59 VV#352 : {VV#352 : int | [(VV#352 = (0  :  int));                                   (VV#352 = lq_anf__d16A)]}@@ -254,11 +254,11 @@                                   (VV#364 = lq_anf__d16z)]} bind 69 VV#367 : {VV#367 : int | [(VV#367 = 0)]} bind 70 VV#367 : {VV#367 : int | [(VV#367 = 0)]}-bind 71 VV#370 : {VV#370 : GHC.Types.Bool | [(? Prop([VV#370]))]}-bind 72 VV#370 : {VV#370 : GHC.Types.Bool | [(? Prop([VV#370]))]}-bind 73 VV#373 : {VV#373 : GHC.Types.Bool | [((? Prop([VV#373])) <=> (gooberding#a15N >= lq_anf__d16x));+bind 71 VV#370 : {VV#370 : GHC.Types.Bool | [(Prop([VV#370]))]}+bind 72 VV#370 : {VV#370 : GHC.Types.Bool | [(Prop([VV#370]))]}+bind 73 VV#373 : {VV#373 : GHC.Types.Bool | [((Prop([VV#373])) <=> (gooberding#a15N >= lq_anf__d16x));                                              (VV#373 = lq_anf__d16y)]}-bind 74 VV#373 : {VV#373 : GHC.Types.Bool | [((? Prop([VV#373])) <=> (gooberding#a15N >= lq_anf__d16x));+bind 74 VV#373 : {VV#373 : GHC.Types.Bool | [((Prop([VV#373])) <=> (gooberding#a15N >= lq_anf__d16x));                                              (VV#373 = lq_anf__d16y)]} bind 75 VV : {VV : a_a164 | [(VV = lq_anf__d16w);                              (VV = lq_anf__d16x)]}@@ -417,7 +417,7 @@        15;        31;        47]-  lhs {VV#F3 : GHC.Types.Bool | [(~ ((? Prop([VV#F3]))));+  lhs {VV#F3 : GHC.Types.Bool | [(~ ((Prop([VV#F3]))));                                  (VV#F3 = GHC.Types.False#68)]}   rhs {VV#F3 : GHC.Types.Bool | [$k_288[VV#287:=VV#F3][VV#349:=VV#F3][VV#F:=VV#F3]]}   id 3 tag [3]@@ -603,7 +603,7 @@        30;        15;        31]-  lhs {VV#F7 : GHC.Types.Bool | [(? Prop([VV#F7]))]}+  lhs {VV#F7 : GHC.Types.Bool | [(Prop([VV#F7]))]}   rhs {VV#F7 : GHC.Types.Bool | [$k_239[VV#238:=VV#F7][VV#370:=VV#F7][VV#F:=VV#F7]]}   id 7 tag [1] @@ -653,9 +653,9 @@        30;        15;        31]-  lhs {VV#F8 : GHC.Types.Bool | [((? Prop([VV#F8])) <=> (gooberding#a15N >= lq_anf__d16x));+  lhs {VV#F8 : GHC.Types.Bool | [((Prop([VV#F8])) <=> (gooberding#a15N >= lq_anf__d16x));                                  (VV#F8 = lq_anf__d16y)]}-  rhs {VV#F8 : GHC.Types.Bool | [(? Prop([VV#F8]))]}+  rhs {VV#F8 : GHC.Types.Bool | [(Prop([VV#F8]))]}   id 8 tag [1]  
tests/pos/test000.hs.fq view
@@ -1,51 +1,51 @@-qualif Fst(v : @(1), y : @(0)): (v = fst([y])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.spec" (line 29, column 8)-qualif Snd(v : @(1), y : @(0)): (v = snd([y])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.spec" (line 30, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) > 0)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 13, column 8)-qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]): ((? Prop([v])) <=> (len([xs]) = 0)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 14, column 8)-qualif ListZ(v : [@(0)]): (len([v]) = 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 16, column 8)-qualif ListZ(v : [@(0)]): (len([v]) >= 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 17, column 8)-qualif ListZ(v : [@(0)]): (len([v]) > 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 18, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) = len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 20, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) >= len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 21, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) > len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 22, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) <= len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 23, column 8)-qualif CmpLen(v : [@(1)], xs : [@(0)]): (len([v]) < len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 24, column 8)-qualif EqLen(v : int, xs : [@(0)]): (v = len([xs])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 26, column 8)-qualif LenEq(v : [@(0)], x : int): (x = len([v])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 27, column 8)-qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x + 1)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 28, column 8)-qualif LenDiff(v : [@(0)], x : int): (len([v]) = (x - 1)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 29, column 8)-qualif LenAcc(v : int, xs : [@(0)], n : int): (v = (len([xs]) + n)) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 30, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 3, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 4, column 8)-qualif Bot(v : @(0)): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 5, column 8)-qualif Bot(v : bool): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 6, column 8)-qualif Bot(v : int): (0 = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 7, column 8)-qualif CmpZ(v : @(0)): (v < 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 9, column 8)-qualif CmpZ(v : @(0)): (v <= 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 10, column 8)-qualif CmpZ(v : @(0)): (v > 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 11, column 8)-qualif CmpZ(v : @(0)): (v >= 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 12, column 8)-qualif CmpZ(v : @(0)): (v = 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 13, column 8)-qualif CmpZ(v : @(0)): (v != 0) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 14, column 8)-qualif Cmp(v : @(0), x : @(0)): (v < x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 16, column 8)-qualif Cmp(v : @(0), x : @(0)): (v <= x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 17, column 8)-qualif Cmp(v : @(0), x : @(0)): (v > x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 18, column 8)-qualif Cmp(v : @(0), x : @(0)): (v >= x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 19, column 8)-qualif Cmp(v : @(0), x : @(0)): (v = x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 20, column 8)-qualif Cmp(v : @(0), x : @(0)): (v != x) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 21, column 8)-qualif One(v : int): (v = 1) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 28, column 8)-qualif True(v : bool): (? v) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 29, column 8)-qualif False(v : bool): (~ ((? v))) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 30, column 8)-qualif True1(v : GHC.Types.Bool): (? Prop([v])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 31, column 8)-qualif False1(v : GHC.Types.Bool): (~ ((? Prop([v])))) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 32, column 8)-qualif Papp(v : @(0), p : (Pred  @(0))): (? papp1([p;-                                                   v])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 35, column 8)-qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))): (? papp2([p;+qualif Fst(v : @(1), y : @(0)) { v = fst([y])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.spec" (line 29, column 8)+qualif Snd(v : @(1), y : @(0)) { v = snd([y])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.spec" (line 30, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { (Prop([v])) <=> (len([xs]) > 0)  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 13, column 8)+qualif IsEmp(v : GHC.Types.Bool, xs : [@(0)]) { (Prop([v])) <=> (len([xs]) = 0)  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 14, column 8)+qualif ListZ(v : [@(0)]) { len([v]) = 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 16, column 8)+qualif ListZ(v : [@(0)]) { len([v]) >= 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 17, column 8)+qualif ListZ(v : [@(0)]) { len([v]) > 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 18, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) = len([xs])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 20, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) >= len([xs])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 21, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) > len([xs])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 22, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) <= len([xs])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 23, column 8)+qualif CmpLen(v : [@(1)], xs : [@(0)]) { len([v]) < len([xs])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 24, column 8)+qualif EqLen(v : int, xs : [@(0)]) { v = len([xs])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 26, column 8)+qualif LenEq(v : [@(0)], x : int) { x = len([v])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 27, column 8)+qualif LenDiff(v : [@(0)], x : int) { len([v]) = (x + 1)  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 28, column 8)+qualif LenDiff(v : [@(0)], x : int) { len([v]) = (x - 1)  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 29, column 8)+qualif LenAcc(v : int, xs : [@(0)], n : int) { v = (len([xs]) + n)  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/GHC/Base.hquals" (line 30, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 3, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 4, column 8)+qualif Bot(v : @(0)) { 0 = 1  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 5, column 8)+qualif Bot(v : bool) { 0 = 1  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 6, column 8)+qualif Bot(v : int) { 0 = 1  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 7, column 8)+qualif CmpZ(v : @(0)) { v < 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 9, column 8)+qualif CmpZ(v : @(0)) { v <= 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 10, column 8)+qualif CmpZ(v : @(0)) { v > 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 11, column 8)+qualif CmpZ(v : @(0)) { v >= 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 12, column 8)+qualif CmpZ(v : @(0)) { v = 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 13, column 8)+qualif CmpZ(v : @(0)) { v != 0  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 14, column 8)+qualif Cmp(v : @(0), x : @(0)) { v < x  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 16, column 8)+qualif Cmp(v : @(0), x : @(0)) { v <= x  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 17, column 8)+qualif Cmp(v : @(0), x : @(0)) { v > x  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 18, column 8)+qualif Cmp(v : @(0), x : @(0)) { v >= x  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 19, column 8)+qualif Cmp(v : @(0), x : @(0)) { v = x  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 20, column 8)+qualif Cmp(v : @(0), x : @(0)) { v != x  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 21, column 8)+qualif One(v : int) { v = 1  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 28, column 8)+qualif True(v : bool) { v  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 29, column 8)+qualif False(v : bool) { ~ ((v))  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 30, column 8)+qualif True1(v : GHC.Types.Bool) { Prop([v])  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 31, column 8)+qualif False1(v : GHC.Types.Bool) { ~ ((Prop([v])))  } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 32, column 8)+qualif Papp(v : @(0), p : (Pred  @(0))) { (papp1([p;+                                                   v])) } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 35, column 8)+qualif Papp2(v : @(1), x : @(0), p : (Pred  @(1)  @(0))) { (papp2([p;                                                                     v;-                                                                    x])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 38, column 8)-qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))): (? papp3([p;+                                                                    x])) } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 38, column 8)+qualif Papp3(v : @(2), x : @(0), y : @(1), p : (Pred  @(2)  @(0)  @(1))) { (papp3([p;                                                                                     v;                                                                                     x;-                                                                                    y])) // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 41, column 8)+                                                                                    y])) } // "/Users/benjamin/UCSDrepos/liquidhaskell/include/Prelude.hquals" (line 41, column 8)   @@ -138,11 +138,11 @@ bind 4 GHC.Types.EQ$35$6U : {VV$35$180 : GHC.Types.Ordering | [(VV$35$180 = GHC.Types.EQ$35$6U)]} bind 5 GHC.Types.LT$35$6S : {VV$35$181 : GHC.Types.Ordering | [(VV$35$181 = GHC.Types.LT$35$6S)]} bind 6 GHC.Types.GT$35$6W : {VV$35$182 : GHC.Types.Ordering | [(VV$35$182 = GHC.Types.GT$35$6W)]}-bind 7 GHC.Types.True$35$6u : {v_4 : GHC.Types.Bool | [(? Prop([v_4]))]}-bind 8 GHC.Types.False$35$68 : {v_5 : GHC.Types.Bool | [(~ ((? Prop([v_5]))))]}-bind 9 GHC.Types.False$35$68 : {v_5 : GHC.Types.Bool | [(~ ((? Prop([v_5]))))]}+bind 7 GHC.Types.True$35$6u : {v_4 : GHC.Types.Bool | [(Prop([v_4]))]}+bind 8 GHC.Types.False$35$68 : {v_5 : GHC.Types.Bool | [(~ ((Prop([v_5]))))]}+bind 9 GHC.Types.False$35$68 : {v_5 : GHC.Types.Bool | [(~ ((Prop([v_5]))))]} bind 10 GHC.Types.$91$$93$$35$6m : {VV : func(1, [[@(0)]]) | []}-bind 11 GHC.Types.True$35$6u : {v_4 : GHC.Types.Bool | [(? Prop([v_4]))]}+bind 11 GHC.Types.True$35$6u : {v_4 : GHC.Types.Bool | [(Prop([v_4]))]} bind 12 GHC.Types.GT$35$6W : {VV$35$227 : GHC.Types.Ordering | [(cmp([VV$35$227]) = GHC.Types.GT$35$6W)]} bind 13 GHC.Types.LT$35$6S : {VV$35$228 : GHC.Types.Ordering | [(cmp([VV$35$228]) = GHC.Types.LT$35$6S)]} bind 14 GHC.Types.EQ$35$6U : {VV$35$229 : GHC.Types.Ordering | [(cmp([VV$35$229]) = GHC.Types.EQ$35$6U)]}@@ -154,29 +154,29 @@ bind 20 lq_anf__d12s : {lq_tmp_x_275 : GHC.Types.Bool | [(lq_tmp_x_275 = Test0.toss$35$rYP)]} bind 21 lq_anf__d12s : {lq_tmp_x_277 : GHC.Types.Bool | [(lq_tmp_x_277 = Test0.toss$35$rYP)]} bind 22 lq_anf__d12s : {lq_tmp_x_277 : GHC.Types.Bool | [(lq_tmp_x_277 = Test0.toss$35$rYP);-                                                         (~ ((? Prop([lq_tmp_x_277]))));-                                                         (~ ((? Prop([lq_tmp_x_277]))));-                                                         (~ ((? Prop([lq_tmp_x_277]))))]}+                                                         (~ ((Prop([lq_tmp_x_277]))));+                                                         (~ ((Prop([lq_tmp_x_277]))));+                                                         (~ ((Prop([lq_tmp_x_277]))))]} bind 23 lq_anf__d12s : {lq_tmp_x_283 : GHC.Types.Bool | [(lq_tmp_x_283 = Test0.toss$35$rYP)]} bind 24 lq_anf__d12s : {lq_tmp_x_283 : GHC.Types.Bool | [(lq_tmp_x_283 = Test0.toss$35$rYP);-                                                         (? Prop([lq_tmp_x_283]));-                                                         (? Prop([lq_tmp_x_283]));-                                                         (? Prop([lq_tmp_x_283]))]}+                                                         (Prop([lq_tmp_x_283]));+                                                         (Prop([lq_tmp_x_283]));+                                                         (Prop([lq_tmp_x_283]))]} bind 25 lq_anf__d12t : {lq_tmp_x_288 : GHC.Types.Bool | [(lq_tmp_x_288 = lq_anf__d12s)]} bind 26 lq_anf__d12t : {lq_tmp_x_290 : GHC.Types.Bool | [(lq_tmp_x_290 = lq_anf__d12s)]} bind 27 lq_anf__d12t : {lq_tmp_x_290 : GHC.Types.Bool | [(lq_tmp_x_290 = lq_anf__d12s);-                                                         (~ ((? Prop([lq_tmp_x_290]))));-                                                         (~ ((? Prop([lq_tmp_x_290]))));-                                                         (~ ((? Prop([lq_tmp_x_290]))))]}+                                                         (~ ((Prop([lq_tmp_x_290]))));+                                                         (~ ((Prop([lq_tmp_x_290]))));+                                                         (~ ((Prop([lq_tmp_x_290]))))]} bind 28 lq_anf__d12t : {lq_tmp_x_296 : GHC.Types.Bool | [(lq_tmp_x_296 = lq_anf__d12s)]} bind 29 lq_anf__d12t : {lq_tmp_x_296 : GHC.Types.Bool | [(lq_tmp_x_296 = lq_anf__d12s);-                                                         (? Prop([lq_tmp_x_296]));-                                                         (? Prop([lq_tmp_x_296]));-                                                         (? Prop([lq_tmp_x_296]))]}+                                                         (Prop([lq_tmp_x_296]));+                                                         (Prop([lq_tmp_x_296]));+                                                         (Prop([lq_tmp_x_296]))]} bind 30 Test0.prop_abs$35$r10h : {VV$35$272 : GHC.Types.Bool | [$k__273]} bind 31 x$35$a11A : {VV$35$307 : int | [$k__308]} bind 32 lq_anf__d12u : {lq_tmp_x_315 : int | [(lq_tmp_x_315 = (0  :  int))]}-bind 33 lq_anf__d12v : {lq_tmp_x_321 : GHC.Types.Bool | [((? Prop([lq_tmp_x_321])) <=> (x$35$a11A > lq_anf__d12u))]}+bind 33 lq_anf__d12v : {lq_tmp_x_321 : GHC.Types.Bool | [((Prop([lq_tmp_x_321])) <=> (x$35$a11A > lq_anf__d12u))]} bind 34 lq_anf__d12w : {lq_tmp_x_345 : int | [$k__343[lq_tmp_x_340:=lq_anf__d12v][VV$35$342:=lq_tmp_x_345][lq_tmp_x_341:=x$35$a11A]]} bind 35 lq_anf__d12x : {lq_tmp_x_350 : int | [(lq_tmp_x_350 = (1  :  int))]} bind 36 lq_anf__d12y : {lq_tmp_x_373 : int | [(lq_tmp_x_373 = (12  :  int))]}@@ -223,16 +223,16 @@ bind 77 VV$35$477 : {VV$35$477 : int | [(VV$35$477 = x$35$a11A)]} bind 78 VV$35$480 : {VV$35$480 : int | [(VV$35$480 = 0)]} bind 79 VV$35$480 : {VV$35$480 : int | [(VV$35$480 = 0)]}-bind 80 VV$35$483 : {VV$35$483 : GHC.Types.Bool | [(? Prop([VV$35$483]))]}-bind 81 VV$35$483 : {VV$35$483 : GHC.Types.Bool | [(? Prop([VV$35$483]))]}+bind 80 VV$35$483 : {VV$35$483 : GHC.Types.Bool | [(Prop([VV$35$483]))]}+bind 81 VV$35$483 : {VV$35$483 : GHC.Types.Bool | [(Prop([VV$35$483]))]} bind 82 VV$35$486 : {VV$35$486 : GHC.Types.Bool | [(VV$35$486 = lq_anf__d12t)]} bind 83 VV$35$486 : {VV$35$486 : GHC.Types.Bool | [(VV$35$486 = lq_anf__d12t)]} bind 84 VV$35$489 : {VV$35$489 : GHC.Types.Bool | [(VV$35$489 = GHC.Types.False$35$68)]} bind 85 VV$35$489 : {VV$35$489 : GHC.Types.Bool | [(VV$35$489 = GHC.Types.False$35$68)]} bind 86 VV$35$492 : {VV$35$492 : GHC.Types.Bool | [(VV$35$492 = GHC.Types.False$35$68)]} bind 87 VV$35$492 : {VV$35$492 : GHC.Types.Bool | [(VV$35$492 = GHC.Types.False$35$68)]}-bind 88 VV$35$495 : {VV$35$495 : GHC.Types.Bool | [((? Prop([VV$35$495])) <=> (lq_anf__d12q > lq_anf__d12r))]}-bind 89 VV$35$495 : {VV$35$495 : GHC.Types.Bool | [((? Prop([VV$35$495])) <=> (lq_anf__d12q > lq_anf__d12r))]}+bind 88 VV$35$495 : {VV$35$495 : GHC.Types.Bool | [((Prop([VV$35$495])) <=> (lq_anf__d12q > lq_anf__d12r))]}+bind 89 VV$35$495 : {VV$35$495 : GHC.Types.Bool | [((Prop([VV$35$495])) <=> (lq_anf__d12q > lq_anf__d12r))]} bind 90 VV$35$498 : {VV$35$498 : int | [(VV$35$498 = lq_anf__d12r)]} bind 91 VV$35$498 : {VV$35$498 : int | [(VV$35$498 = lq_anf__d12r)]} bind 92 VV$35$501 : {VV$35$501 : int | [(VV$35$501 = lq_anf__d12q)]}@@ -309,7 +309,7 @@        15;        31]   lhs {VV$35$F8 : GHC.Types.Bool | [(VV$35$F8 = lq_anf__d12v)]}-  rhs {VV$35$F8 : GHC.Types.Bool | [(? Prop([VV$35$F8]))]}+  rhs {VV$35$F8 : GHC.Types.Bool | [(Prop([VV$35$F8]))]}   id 8 tag [3]   // META constraint id 8 : tests/pos/test000.hs:14:23-29 @@ -339,7 +339,7 @@        29;        14;        15]-  lhs {VV$35$F11 : GHC.Types.Bool | [(? Prop([VV$35$F11]))]}+  lhs {VV$35$F11 : GHC.Types.Bool | [(Prop([VV$35$F11]))]}   rhs {VV$35$F11 : GHC.Types.Bool | [$k__273[VV$35$272:=VV$35$F11][VV$35$F:=VV$35$F11][VV$35$483:=VV$35$F11]]}   id 11 tag [6]   // META constraint id 11 : tests/pos/test000.hs:10:33-50@@ -371,7 +371,7 @@        14;        15]   lhs {VV$35$F12 : GHC.Types.Bool | [(VV$35$F12 = lq_anf__d12t)]}-  rhs {VV$35$F12 : GHC.Types.Bool | [(? Prop([VV$35$F12]))]}+  rhs {VV$35$F12 : GHC.Types.Bool | [(Prop([VV$35$F12]))]}   id 12 tag [6]   // META constraint id 12 : tests/pos/test000.hs:10:47-50 @@ -456,7 +456,7 @@        13;        14;        15]-  lhs {VV$35$F15 : GHC.Types.Bool | [((? Prop([VV$35$F15])) <=> (lq_anf__d12q > lq_anf__d12r))]}+  lhs {VV$35$F15 : GHC.Types.Bool | [((Prop([VV$35$F15])) <=> (lq_anf__d12q > lq_anf__d12r))]}   rhs {VV$35$F15 : GHC.Types.Bool | [$k__235[VV$35$F:=VV$35$F15][VV$35$495:=VV$35$F15][VV$35$234:=VV$35$F15]]}   id 15 tag [5]   // META constraint id 15 : tests/pos/test000.hs:6:1-22
tests/pos/test00a.fq view
@@ -1,5 +1,5 @@ // This qualifier saves the day; solve constraints WITHOUT IT-qualif Zog(v:a) : (10 <= v)+qualif Zog(v:a)  { 10 <= v }  bind 0 x : {v : int | true} bind 1 y : {v : int | true}
tests/pos/test1.fq view
@@ -1,6 +1,6 @@  // This qualifier saves the day; solve constraints WITHOUT IT-qualif Zog(v:a) : (10 <= v)+qualif Zog(v:a)  { 10 <= v }  bind 0 x : {v : int | v = 10} bind 1 y : {v : int | v = 20}
tests/pos/test2.fq view
@@ -1,9 +1,9 @@  // This qualifier saves the day; solve constraints WITHOUT IT-qualif Zog(v:a): (10 <= v)+qualif Zog(v:a) { 10 <= v }  // But you may use this one-qualif Pog(v:a): (0 <= v)+qualif Pog(v:a) { 0 <= v }  bind 0 x: {v: int | v = 10} bind 1 a: {v: int | $k1    }
tests/pos/test3.fq view
@@ -1,5 +1,5 @@ -qualif Zog(v:a, z:b) : (v = z)+qualif Zog(v:a, z:b)  { v = z }  bind 0 x : {v : int | true} bind 1 q : {v : int | true}
tests/pos/test4.fq view
@@ -1,4 +1,4 @@-qualif Auto(v_2 : a_ax6, A0 : a_ax6): (v_2 = A0)+qualif Auto(v_2 : a_ax6, A0 : a_ax6) { v_2 = A0 }  bind 20 ds_dxx : {VV263 : a_ax6 | []} 
tests/pos/unexpected-ge.fq view
@@ -1,2 +1,2 @@ -qualif Auto(v : int, x : int): (v = (if (x > 0) then 0 else 0))+qualif Auto(v : int, x : int) { v = (if (x > 0) then 0 else 0) }
tests/pos/wl00.fq view
@@ -1,6 +1,6 @@-qualif Nat(v:int) : (0 <= v)-qualif N10(v:int) : (10 = v)-qualif N20(v:int) : (20 = v)+qualif Nat(v:int)  { 0 <= v }+qualif N10(v:int)  { 10 = v }+qualif N20(v:int)  { 20 = v }  bind 0 x0 : {v: int | [$k0]} 
tests/pos/wl01.fq view
@@ -1,4 +1,4 @@-qualif Nat(v:int) : (0 <= v)+qualif Nat(v:int)  { 0 <= v }  bind 0 x : {v: int | [$k0]} bind 1 y : {v: int | [$k0]}
tests/pos/wl02.fq view
@@ -1,4 +1,4 @@-qualif Nat(v:int) : (0 <= v)+qualif Nat(v:int)  { 0 <= v }  bind 0  x0  : {v: int | [$k0]} bind 1  x1  : {v: int | [$k1]}
tests/tasty/Arbitrary.hs view
@@ -22,7 +22,6 @@ import Language.Fixpoint.Types.Refinements as R import Language.Fixpoint.Parse             (isNotReserved) import Language.Fixpoint.Types             as T hiding (Result)-import Language.Fixpoint.Types.Spans       as Spans import Data.Traversable                    (for)  {-@@ -76,8 +75,8 @@ subexprs (PKVar _ _)     = [] subexprs (PAll _ e)      = [e] subexprs (PExist _ e)    = [e]-subexprs (PGrad _ _ _ e) = [e] subexprs (ECoerc _ _ e)  = [e]+subexprs (ELet _ e1 e2)  = [e1, e2]  -- TODO: Adjust frequencies -- | To ensure this reliably terminates we require that `zeroExprGen` generates@@ -105,8 +104,8 @@   , (1, PKVar <$> arbitrary <*> arbitrary)   , (1, PAll <$> arbitraryList arbitrary <*> arbitraryExpr')   , (1, PExist <$> arbitraryList arbitrary <*> arbitraryExpr')-  , (1, PGrad <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitraryExpr')   , (1, ECoerc <$> arbitrary <*> arbitrary <*> arbitraryExpr')+  , (1, ELet <$> arbitrary <*> arbitraryExpr' <*> arbitraryExpr')   ]   where     arbitraryExpr' = arbitraryFiniteExpr zeroExprGen (n `div` 2)@@ -132,12 +131,6 @@  instance Arbitrary KVar where   arbitrary = KV <$> arbitrary---- NOTE: This dummy Arbitrary instance returns a constant GradInfo.-instance Arbitrary GradInfo where-  arbitrary = pure $ GradInfo (SS pos pos) Nothing-    where pos = Spans.dummyPos "<unknown>"-  shrink _ = mempty  instance Arbitrary Subst where   arbitrary = do
tests/tasty/Main.hs view
@@ -5,6 +5,7 @@ import qualified ParserTests import qualified ShareMapTests import qualified SimplifyTests+import qualified SimplifyKVarTests import qualified InterpretTests import qualified UndoANFTests import Test.Tasty@@ -14,6 +15,7 @@   [ ParserTests.tests   , ShareMapTests.tests   , SimplifyTests.tests+  , SimplifyKVarTests.tests   , InterpretTests.tests   , UndoANFTests.tests   ]
tests/tasty/ParserTests.hs view
@@ -131,11 +131,7 @@ testFunAppP :: TestTree testFunAppP =   testGroup "FunAppP"-    [ testCase "ECon (litP)" $-        show (doParse' funAppP "test" "lit \"#x00000008\" (BitVec  Size32)") @?=-          "ECon (L \"#x00000008\" (FApp (FTC (TC \"BitVec\" defined at: test:1:19-1:25 (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))) (FTC (TC \"Size32\" defined at: test:1:27-1:33 (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False})))))"--    , testCase "ECon (exprFunSpacesP)" $+    [ testCase "ECon (exprFunSpacesP)" $         show (doParse' funAppP "test" "fooBar baz qux") @?= "EApp (EApp (EVar \"fooBar\") (EVar \"baz\")) (EVar \"qux\")"      , testCase "ECon (exprFunCommasP)" $@@ -200,54 +196,14 @@         show (doParse' expr0P "test" "1") @?= "ECon (I 1)"     ] --- ----------------------------------------------------------------------{---pred = expressionParse (prefixOp++infixOp) pred0--prefixOp = '~' | 'not'--infixOp  = '&&' | '||' | '=>' | '==>' | '<=>'---- terms are pred0-pred0 = 'true' | 'false'-      | '??'-      | kvarPred-      | fastIfP-      | predr-      | '(' pred ')'-      | '?' expr-      | funApp-      | symbol-      | '&&' preds-      | '||' preds--kvarPred = kvar substs--kvar = '$' symbol--substs = {- empty -}-       | subst substs--subst = '[' symbol ':=' expr ']'--preds = '[' predslist ']'--predslist = pred-          | pred `;` predslist--fastIf = 'if' pred 'then' pred 'else' pred--predr = expr brel expr--brelP = '==' | '=' | '~~' | '!=' | '/=' | '!~' | '<' | '<=' | '>' | '>='---}- testPredP :: TestTree testPredP =-  testGroup "predP"-    [ testCase "PTrue" $+  testGroup "exprP"+    [ testCase "ECon (litP)" $+        show (doParse' exprP "test" "lit \"#x00000008\" (BitVec  Size32)") @?=+          "ECon (L \"#x00000008\" (FApp (FTC (TC \"BitVec\" defined at: test:1:19-1:25 (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False}))) (FTC (TC \"Size32\" defined at: test:1:27-1:33 (TCInfo {tc_isNum = False, tc_isReal = False, tc_isString = False})))))"++    , testCase "PTrue" $         show (doParse' predP "test" "true") @?= "PAnd []" -- pattern for PTrue      , testCase "PFalse" $@@ -268,8 +224,7 @@      , testCase "fastIf" $         show (doParse' predP "test" "if true then true else false" ) @?=-          -- note conversion-          "PAnd [PImp (PAnd []) (PAnd []),PImp (PNot (PAnd [])) (POr [])]"+          "EIte (PAnd []) (PAnd []) (POr [])"      , testCase "brel" $         show (doParse' predP "test" "1 == 2") @?= "PAtom Eq (ECon (I 1)) (ECon (I 2))"@@ -277,9 +232,6 @@     , testCase "parens pred" $         show (doParse' predP "test" "((1 == 2))") @?= "PAtom Eq (ECon (I 1)) (ECon (I 2))" -    , testCase "? expr" $-        show (doParse' predP "test" "? (1+2)") @?= "EBin Plus (ECon (I 1)) (ECon (I 2))"-     , testCase "funApp 1" $         show (doParse' predP "test" "f a b") @?= "EApp (EApp (EVar \"f\") (EVar \"a\")) (EVar \"b\")" @@ -290,10 +242,10 @@         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)))"+        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)))"+        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\""@@ -302,7 +254,7 @@         show (doParse' predP "test" "&& []") @?= "PAnd []"      , testCase "&& 1" $-        show (doParse' predP "test" "&& [x]") @?= "EVar \"x\""+        show (doParse' predP "test" "&& [x]") @?= "PAnd [EVar \"x\"]"      , testCase "&& 2" $         show (doParse' predP "test" "&& [x;y]") @?= "PAnd [EVar \"x\",EVar \"y\"]"
tests/tasty/SimplifyPLE.hs view
@@ -17,7 +17,6 @@       KN         { knSims = M.empty, -- :: Map Symbol [(Rewrite, IsUserDataSMeasure)]           knAms = M.empty, -- :: Map Symbol Equation-          knContext = undefined, -- :: SMT.Context           knPreds = undefined, -- :: SMT.Context -> [(Symbol, Sort)] -> Expr -> IO Bool           knLams = [], -- :: ![(Symbol, Sort)]           knSummary = [], -- :: ![(Symbol, Int)]@@ -33,13 +32,16 @@     emptyICtx =       ICtx         { icAssms = S.empty,      -- S.HashSet Pred-          icCands = S.empty,      -- :: S.HashSet Expr-          icEquals = S.empty,     -- :: EvAccum+          icCands = mempty,      -- :: S.HashSet Expr+          icEquals = mempty,     -- :: EvAccum           icSimpl = SM.empty,     -- :: !ConstMap           icSubcId = Nothing,     -- :: Maybe SubcId           icANFs = [],            -- :: [[(Symbol, SortedReft)]]           icLRWs = mempty,           icEtaBetaFlag        = False,           icExtensionalityFlag = False,-          icLocalRewritesFlag  = False+          icLocalRewritesFlag  = False,+          icBindIds = mempty,+          icFreshExistentialCounter = 0,+          icInitialLHSs = mempty         }
+ tests/tasty/ghc-9.12.1/SimplifyKVarTests.hs view
@@ -0,0 +1,400 @@+{-# LANGUAGE MultilineStrings #-}++module SimplifyKVarTests (tests) where++import Control.Monad (when)+import qualified Data.HashSet as HashSet+import Language.Fixpoint.Parse+import qualified Language.Fixpoint.Types as F+import qualified Language.Fixpoint.Solver.Solution as F+import Test.Tasty+import Test.Tasty.HUnit+++tests :: TestTree+tests =+  testGroup "simplifyKVar" $ map simplificationTest+    [ SimplificationTest+        { name = "single elimination"+        , expected = """+            exists [y : int] . P C y+          """+        , input = """+            exists [x : int, y : int] . x == C && P x y+          """+        }++    , SimplificationTest+        { name = "full elimination"+        , expected = """+            P C D+          """+        , input = """+            exists [x : int, y : int] . x == C && P x y && y == D+          """+        }++    , SimplificationTest+        { name = "alpha equivalence"+        , expected = """+            (exists [w : int, z : int] . Q w z) &&+            (exists [w : int, z : int] . P w z)+          """+        , input = """+            (exists [w : int, z : int] . Q w z) &&+            (exists [w : int, z : int] . P w z) &&+            (exists [x : int, y : int] . P x y)+          """+        }++    , SimplificationTest+        { name = "floating"+        , expected = """+            (exists [x : int, y : int] . P x y) && A == C+          """+        , input = """+            exists [x : int, y : int] . A == C && P x y+          """+        }++    , SimplificationTest+        { name = "inner floating"+        , expected = """+            (exists [x : int] . P x && Q x) && (exists [y : int] . P y)+          """+        , input = """+            exists [x : int] . P x && (exists [ y : int] . P y && Q x)+          """+        }++    , largeSimplificationTest+    ]++data SimplificationTest = SimplificationTest+  { input :: String+  , expected :: String+  , name :: String+  }++simplificationTest :: SimplificationTest -> TestTree+simplificationTest test =+  testCase (name test) $ do+    let actual =+          F.simplifyKVar+            HashSet.empty+            (doParse'' True predP (name test) (input test))+        expectedE = doParse'' True predP (name test) (expected test)+    when (not (F.alphaEq HashSet.empty actual expectedE)) $ do+      assertFailure $ unlines+        [ "output is not as expected"+        , "Expected:"+        , expected test+        , ""+        , "Actual:"+        , F.showpp actual+        ]++largeSimplificationTest :: SimplificationTest+largeSimplificationTest =+  SimplificationTest+    { name = "large simplification"+    , expected = """+        exists [w : int] . Test.gt0xy w i##aS7+      """+    , input = """+        exists [VV##1821##k_ : int,+                i##aS7##k_ : int,+                lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                lq_tmpx##1823##k_ : int,+                lq_tmpx##1824##k_ : int]+              . (exists [w : int,+                         w2 : int,+                         x : int,+                         y : Tuple0,+                         VV##F##13 : int]+                   . VV##1821##k_ == VV##F##13+                     && i##aS7##k_ == i##aS7+                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                     && lq_tmpx##1823##k_ == w+                     && lq_tmpx##1824##k_ == x+                     && (exists [VV##1829 : int,+                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                 lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                 VV##1805##k_ : int,+                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                 i##aS7##k_ : int]+                           . VV##1829 == w+                             && VV##1805##k_ == w+                             && i##aS7##k_ == i##aS7+                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                             && (exists [VV##F##3 : int]+                                   . Test.gt0xy VV##F##3 i##aS7+                                     && VV##1805##k_ == VV##F##3+                                     && i##aS7##k_ == i##aS7+                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                     && (exists [VV##1830 : int,+                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                 i##aS7##k_ : int,+                                 lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                 VV##1807##k_ : int]+                           . VV##1830 == w2+                             && VV##1807##k_ == w2+                             && i##aS7##k_ == i##aS7+                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                             && (exists [w : int,+                                         VV##F##14 : int,+                                         lq_rnmx##255 : Tuple0]+                                   . (exists [VV##1828 : int,+                                              lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                              lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                              VV##1805##k_ : int,+                                              lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                              i##aS7##k_ : int]+                                        . VV##1828 == w+                                          && VV##1805##k_ == w+                                          && i##aS7##k_ == i##aS7+                                          && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                          && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                          && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                          && (exists [VV##F##3 : int]+                                                . Test.gt0xy VV##F##3 i##aS7+                                                  && VV##1805##k_ == VV##F##3+                                                  && i##aS7##k_ == i##aS7+                                                  && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                  && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                  && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                                     && (exists [lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                 i##aS7##k_ : int,+                                                 lq_tmpx##1812##k_ : Tuple0,+                                                 VV##1809##k_ : int,+                                                 lq_tmpx##1811##k_ : int,+                                                 lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int)]+                                           . VV##1809##k_ == VV##F##14+                                             && i##aS7##k_ == i##aS7+                                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                             && lq_tmpx##1811##k_ == w+                                             && lq_tmpx##1812##k_ == lq_rnmx##255+                                             && (exists [VV##F##12 : int,+                                                         lq_tmpx##1811 : int,+                                                         lq_tmpx##1812 : Tuple0,+                                                         lq_tmpdb##43 : int,+                                                         lq_tmpdb##44 : Tuple0]+                                                   . VV##F##12 == i##aS7+                                                     && VV##1809##k_ == VV##F##12+                                                     && i##aS7##k_ == i##aS7+                                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                                     && lq_tmpx##1811##k_ == lq_tmpx##1811+                                                     && lq_tmpx##1812##k_ == lq_tmpx##1812))+                                     && (exists [i##aS7##k_ : int,+                                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                 lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                                 lq_tmpx##1801 : Tuple0,+                                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                 VV##1799##k_ : Tuple0]+                                           . VV##1799##k_ == lq_rnmx##255+                                             && i##aS7##k_ == i##aS7+                                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                             && lq_tmpx##1801 == lq_rnmx##255+                                             && (exists [VV##F##10 : Tuple0]+                                                   . VV##1799##k_ == VV##F##10+                                                     && i##aS7##k_ == i##aS7+                                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                                     && VV##1807##k_ == VV##F##14+                                     && i##aS7##k_ == i##aS7+                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                     && (exists [i##aS7##k_ : int,+                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                 lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                 lq_tmpx##1801 : Tuple0,+                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                 VV##1799##k_ : Tuple0]+                           . VV##1799##k_ == y+                             && i##aS7##k_ == i##aS7+                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                             && lq_tmpx##1801 == y+                             && (exists [VV##F##10 : Tuple0]+                                   . VV##1799##k_ == VV##F##10+                                     && i##aS7##k_ == i##aS7+                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                     && (exists [i##aS7##k_ : int,+                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                 lq_tmpx##1804 : int,+                                 lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                 VV##1802##k_ : int]+                           . VV##1802##k_ == x+                             && i##aS7##k_ == i##aS7+                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                             && lq_tmpx##1804 == x+                             && (exists [VV##F##6 : int]+                                   . (exists [i##aS7##k_ : int,+                                              lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                              lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                              VV##1796##k_ : int]+                                        . VV##1796##k_ == VV##F##6+                                          && i##aS7##k_ == i##aS7+                                          && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                          && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                          && (exists [VV##F##7 : int]+                                                . (exists [lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                           lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                           i##aS7##k_ : int,+                                                           lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                                           VV##1807##k_ : int]+                                                     . VV##1807##k_ == VV##F##7+                                                       && i##aS7##k_ == i##aS7+                                                       && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                       && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                       && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                                       && (exists [w : int,+                                                                   VV##F##14 : int,+                                                                   lq_rnmx##255 : Tuple0]+                                                             . (exists [VV##1828 : int,+                                                                        lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                                        lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                                                        VV##1805##k_ : int,+                                                                        lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                                        i##aS7##k_ : int]+                                                                  . VV##1828 == w+                                                                    && VV##1805##k_ == w+                                                                    && i##aS7##k_ == i##aS7+                                                                    && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                                    && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                                    && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                                                    && (exists [VV##F##3 : int]+                                                                          . Test.gt0xy VV##F##3 i##aS7+                                                                            && VV##1805##k_ == VV##F##3+                                                                            && i##aS7##k_ == i##aS7+                                                                            && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                                            && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                                            && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                                                               && (exists [lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                                           lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                                           i##aS7##k_ : int,+                                                                           lq_tmpx##1812##k_ : Tuple0,+                                                                           VV##1809##k_ : int,+                                                                           lq_tmpx##1811##k_ : int,+                                                                           lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int)]+                                                                     . VV##1809##k_ == VV##F##14+                                                                       && i##aS7##k_ == i##aS7+                                                                       && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                                       && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                                       && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                                                       && lq_tmpx##1811##k_ == w+                                                                       && lq_tmpx##1812##k_ == lq_rnmx##255+                                                                       && (exists [VV##F##12 : int,+                                                                                   lq_tmpx##1811 : int,+                                                                                   lq_tmpx##1812 : Tuple0,+                                                                                   lq_tmpdb##43 : int,+                                                                                   lq_tmpdb##44 : Tuple0]+                                                                             . VV##F##12 == i##aS7+                                                                               && VV##1809##k_ == VV##F##12+                                                                               && i##aS7##k_ == i##aS7+                                                                               && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                                               && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                                               && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                                                               && lq_tmpx##1811##k_ == lq_tmpx##1811+                                                                               && lq_tmpx##1812##k_ == lq_tmpx##1812))+                                                               && (exists [i##aS7##k_ : int,+                                                                           lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                                           lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                                                           lq_tmpx##1801 : Tuple0,+                                                                           lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                                           VV##1799##k_ : Tuple0]+                                                                     . VV##1799##k_ == lq_rnmx##255+                                                                       && i##aS7##k_ == i##aS7+                                                                       && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                                       && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                                       && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                                                       && lq_tmpx##1801 == lq_rnmx##255+                                                                       && (exists [VV##F##10 : Tuple0]+                                                                             . VV##1799##k_ == VV##F##10+                                                                               && i##aS7##k_ == i##aS7+                                                                               && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                                               && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                                               && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                                                               && VV##1807##k_ == VV##F##14+                                                               && i##aS7##k_ == i##aS7+                                                               && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                               && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                                               && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                                                  && VV##1796##k_ == VV##F##7+                                                  && i##aS7##k_ == i##aS7+                                                  && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                  && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb))+                                     && (exists [i##aS7##k_ : int,+                                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                                 VV##1793##k_ : int]+                                           . VV##1793##k_ == VV##F##6+                                             && i##aS7##k_ == i##aS7+                                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                             && (exists [VV##F##5 : int]+                                                   . VV##1793##k_ == VV##F##5+                                                     && i##aS7##k_ == i##aS7+                                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb))+                                     && VV##1802##k_ == VV##F##6+                                     && i##aS7##k_ == i##aS7+                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc))+                     && (exists [lq_anf##7205759403792798200##d1cc##k_ : (Test.State int int),+                                 lq_tmpx##1818##k_ : int,+                                 lq_anf##7205759403792798198##d1ca##k_ : (GHC.Internal.Base.Monad (Test.State int)),+                                 lq_tmpx##1817##k_ : int,+                                 VV##1815##k_ : int,+                                 lq_anf##7205759403792798199##d1cb##k_ : (Test.State int Tuple0),+                                 i##aS7##k_ : int]+                           . VV##1815##k_ == VV##F##13+                             && i##aS7##k_ == i##aS7+                             && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                             && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                             && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                             && lq_tmpx##1817##k_ == w2+                             && lq_tmpx##1818##k_ == x+                             && (exists [VV##F##8 : int,+                                         lq_tmpx##1817 : int,+                                         lq_tmpx##1818 : int,+                                         lq_tmpdb##47 : int,+                                         lq_tmpdb##48 : int]+                                   . lq_tmpx##1818 == VV##F##8+                                     && VV##F##8 == lq_tmpx##1817+                                     && VV##1815##k_ == VV##F##8+                                     && i##aS7##k_ == i##aS7+                                     && lq_anf##7205759403792798198##d1ca##k_ == lq_anf##7205759403792798198##d1ca+                                     && lq_anf##7205759403792798199##d1cb##k_ == lq_anf##7205759403792798199##d1cb+                                     && lq_anf##7205759403792798200##d1cc##k_ == lq_anf##7205759403792798200##d1cc+                                     && lq_tmpx##1817##k_ == lq_tmpx##1817+                                     && lq_tmpx##1818##k_ == lq_tmpx##1818)))+        """+    }
+ tests/tasty/ghc-before-9.12.1/SimplifyKVarTests.hs view
@@ -0,0 +1,12 @@++module SimplifyKVarTests (tests) where++import Test.Tasty+import Test.Tasty.HUnit++tests :: TestTree+tests =+  testGroup "simplifyKVar"+    [ testCase "Disabled because it needs MultilineStrings (ghc >= 9.12.1)" $+        return ()+    ]
tests/test.hs view
@@ -87,26 +87,27 @@ unitTests :: FilePath -> IO TestTree unitTests lfDir   = group "Unit" [-      testGroup "native-pos" <$> dirTests nativeCmd "tests/pos"    skipNativePos  ExitSuccess-    , testGroup "native-neg" <$> dirTests nativeCmd "tests/neg"    ["float.fq"]   (ExitFailure 1)-    , testGroup "elim-crash" <$> dirTests nativeCmd "tests/crash"  []             (ExitFailure 1)-    , testGroup "elim-pos1"  <$> dirTests elimCmd   "tests/pos"    []             ExitSuccess-    , testGroup "elim-pos2"  <$> dirTests elimCmd   "tests/elim"   []             ExitSuccess-    , testGroup "elim-neg"   <$> dirTests elimCmd   "tests/neg"    ["float.fq"]   (ExitFailure 1)-    , testGroup "elim-crash" <$> dirTests elimCmd   "tests/crash"  []             (ExitFailure 1)-    , testGroup "cvc5-pos"   <$> dirTests cvc5Cmd   "tests/pos"    skipNativePos  ExitSuccess-    , testGroup "proof"      <$> dirTests elimCmd   "tests/proof"     []          ExitSuccess-    , testGroup "rankN"      <$> dirTests elimCmd   "tests/rankNTypes" []         ExitSuccess-    , testGroup "horn-pos-el"      <$> dirTests elimSaveCmd   "tests/horn/pos"  []          ExitSuccess-    , testGroup "horn-pos-cvc5"    <$> dirTests cvc5Cmd       "tests/horn/pos"  []          ExitSuccess-    , testGroup "horn-neg-el"      <$> dirTests elimSaveCmd   "tests/horn/neg"  []          (ExitFailure 1)-    , testGroup "horn-neg-cvc5"    <$> dirTests cvc5Cmd       "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)+      testGroup "native-pos"       <$> dirTests     nativeCmd   "tests/pos"              skipNativePos  ExitSuccess+    , testGroup "native-neg"       <$> dirTests     nativeCmd   "tests/neg"              ["float.fq"]  (ExitFailure 1)+    , testGroup "elim-crash"       <$> dirTests     nativeCmd   "tests/crash"            []            (ExitFailure 1)+    , testGroup "elim-pos1"        <$> dirTests     elimCmd     "tests/pos"              []             ExitSuccess+    , testGroup "elim-pos2"        <$> dirTests     elimCmd     "tests/elim"             []             ExitSuccess+    , testGroup "elim-neg"         <$> dirTests     elimCmd     "tests/neg"              ["float.fq"]  (ExitFailure 1)+    , testGroup "elim-crash"       <$> dirTests     elimCmd     "tests/crash"            []            (ExitFailure 1)+    , testGroup "cvc5-pos"         <$> dirTests     cvc5Cmd     "tests/pos"              skipNativePos  ExitSuccess+    , testGroup "cvc5-spec"        <$> dirTests     cvc5Cmd     "tests/cvc5"             skipNativePos  ExitSuccess+    , testGroup "proof"            <$> dirTests     elimCmd     "tests/proof"            []             ExitSuccess+    , testGroup "rankN"            <$> dirTests     elimCmd     "tests/rankNTypes"       []             ExitSuccess+    , testGroup "horn-pos-el"      <$> dirTests     elimSaveCmd "tests/horn/pos"         []             ExitSuccess+    , testGroup "horn-pos-cvc5"    <$> dirTests     cvc5Cmd     "tests/horn/pos"         []             ExitSuccess+    , testGroup "horn-neg-el"      <$> dirTests     elimSaveCmd "tests/horn/neg"         []            (ExitFailure 1)+    , testGroup "horn-neg-cvc5"    <$> dirTests     cvc5Cmd     "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
unix/Language/Fixpoint/Utils/Progress.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE ForeignFunctionInterface #-} -- | Progress Bar API module Language.Fixpoint.Utils.Progress (       withProgress+    , withProgressM     , progressInit     , progressTick     , progressClose@@ -13,21 +15,32 @@ import           System.Console.AsciiProgress -- import           Language.Fixpoint.Misc (traceShow) +foreign import ccall unsafe "unistd.h isatty"+  c_isatty :: Int -> IO Int+ {-# NOINLINE pbRef #-} pbRef :: IORef (Maybe ProgressBar) pbRef = unsafePerformIO (newIORef Nothing)  withProgress :: Int -> IO a -> IO a-withProgress n act = do+withProgress = withProgressM id++withProgressM :: (m a -> IO b) -> Int -> m a -> IO b+withProgressM mToIO n act = do   showBar <- (Quiet /=) <$> getVerbosity-  if showBar+  -- We don't show the progress bar if the output is not a terminal.+  -- Besides improving the output, this also avoids a concurrency+  -- issue:+  -- https://github.com/ucsd-progsys/liquid-fixpoint/issues/782+  isTTY <- (== 1) <$> c_isatty 1+  if showBar && isTTY     then displayConsoleRegions $ do       -- putStrLn $ "withProgress: " ++ show n       progressInit n-      r <- act+      r <- mToIO act       progressClose       return r-    else act+    else mToIO act  progressInit :: Int -> IO () progressInit n = do
win/Language/Fixpoint/Utils/Progress.hs view
@@ -1,6 +1,7 @@ -- | Progress Bar API module Language.Fixpoint.Utils.Progress (       withProgress+    , withProgressM     , progressInit     , progressTick     , progressClose@@ -8,6 +9,9 @@  withProgress :: Int -> IO a -> IO a withProgress _ x = x++withProgressM :: (m a -> IO b) -> Int -> m a -> IO b+withProgressM f _ = f  progressInit :: Int -> IO () progressInit _ = return ()