g2-0.1.0.0: src/G2/Solver/Interface.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module G2.Solver.Interface
( subModel
, subVar
, subVarFuncCall
, SMTConverter (..)
, Solver (..)
) where
import G2.Execution.NormalForms
import G2.Language
import qualified G2.Language.ExprEnv as E
import G2.Solver.Converters
import G2.Solver.Solver
import Data.Maybe (mapMaybe)
import qualified Data.Map as M
subModel :: State t -> Bindings -> ([Expr], Expr, Maybe FuncCall)
subModel (State { expr_env = eenv
, curr_expr = CurrExpr _ cexpr
, assert_ids = ais
, type_classes = tc
, model = m})
(Bindings {input_names = inputNames}) =
let
ais' = fmap (subVarFuncCall m eenv tc) ais
-- We do not inline Lambdas, because higher order function arguments
-- get preinserted into the model.
-- See [Higher-Order Model] in G2.Execution.Reducers
is = mapMaybe (\n -> case E.lookup n eenv of
Just e@(Lam _ _ _) -> Just . Var $ Id n (typeOf e)
Just e -> Just e
Nothing -> Nothing) inputNames
in
filterTC tc $ subVar m eenv tc (is, cexpr, ais')
subVarFuncCall :: Model -> ExprEnv -> TypeClasses -> FuncCall -> FuncCall
subVarFuncCall em eenv tc fc@(FuncCall {arguments = ars}) =
subVar em eenv tc $ fc {arguments = filter (not . isTC tc) ars}
subVar :: (ASTContainer m Expr) => Model -> ExprEnv -> TypeClasses -> m -> m
subVar em eenv tc = modifyContainedASTs (subVar' em eenv tc []) . filterTC tc
subVar' :: Model -> ExprEnv -> TypeClasses -> [Id] -> Expr -> Expr
subVar' em eenv tc is v@(Var i@(Id n _))
| i `notElem` is
, Just e <- M.lookup n em =
subVar' em eenv tc (i:is) $ filterTC tc e
| i `notElem` is
, Just e <- E.lookup n eenv
, (isExprValueForm eenv e && notLam e) || isApp e || isVar e =
subVar' em eenv tc (i:is) $ filterTC tc e
| otherwise = v
subVar' em eenv tc is e = modifyChildren (subVar' em eenv tc is) e
notLam :: Expr -> Bool
notLam (Lam _ _ _) = False
notLam _ = True
isApp :: Expr -> Bool
isApp (App _ _) = True
isApp _ = False
isVar :: Expr -> Bool
isVar (Var _) = True
isVar _ = False
filterTC :: ASTContainer m Expr => TypeClasses -> m -> m
filterTC tc = modifyASTs (filterTC' tc)
filterTC' :: TypeClasses -> Expr -> Expr
filterTC' tc a@(App e e') =
case tcCenter tc $ typeOf e' of
True -> filterTC' tc e
False -> a
filterTC' _ e = e
tcCenter :: TypeClasses -> Type -> Bool
tcCenter tc (TyCon n _) = isTypeClassNamed n tc
tcCenter tc (TyFun t _) = tcCenter tc t
tcCenter _ _ = False
isTC :: TypeClasses -> Expr -> Bool
isTC tc (Var (Id _ (TyCon n _))) = isTypeClassNamed n tc
isTC _ _ = False