[commit: ghc] wip/gadtpm: literals: more expressive laziness oracle (0370621)
git at git.haskell.org
git at git.haskell.org
Sun Nov 29 11:57:52 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/gadtpm
Link : http://ghc.haskell.org/trac/ghc/changeset/0370621c94692fcc881c6b44941e1bb9be312b55/ghc
>---------------------------------------------------------------
commit 0370621c94692fcc881c6b44941e1bb9be312b55
Author: George Karachalias <george.karachalias at gmail.com>
Date: Sun Nov 29 12:57:08 2015 +0100
literals: more expressive laziness oracle
>---------------------------------------------------------------
0370621c94692fcc881c6b44941e1bb9be312b55
compiler/deSugar/Check.hs | 6 ++++--
compiler/deSugar/TmOracle.hs | 37 +++++++++++++++++++++++++++++--------
2 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/compiler/deSugar/Check.hs b/compiler/deSugar/Check.hs
index ecbaed5..188a11c 100644
--- a/compiler/deSugar/Check.hs
+++ b/compiler/deSugar/Check.hs
@@ -763,9 +763,11 @@ pruneVSABound n v = pruneVSABound' n init_cs emptylist v
False -> []
Constraint cs vsa -> case splitConstraints cs of
(new_ty_cs, new_tm_cs, new_bot_ct) -> case tmOracle tm_env new_tm_cs of
- Just (new_tm_env@(residual, (expr_eqs, subst))) ->
+ Just new_tm_env ->
let bot = mergeBotCs new_bot_ct bot_ct
- ans = isNothing bot || notNull residual || expr_eqs || notForced (fromJust bot) subst
+ ans = case bot of
+ Nothing -> True -- covered
+ Just b -> canDiverge b new_tm_env -- divergent
in case ans of
True -> pruneVSABound' n (new_ty_cs++ty_cs, new_tm_env, bot) vec vsa
False -> return []
diff --git a/compiler/deSugar/TmOracle.hs b/compiler/deSugar/TmOracle.hs
index 75aa649..781e4a2 100644
--- a/compiler/deSugar/TmOracle.hs
+++ b/compiler/deSugar/TmOracle.hs
@@ -10,7 +10,7 @@ module TmOracle (
-- re-exported from PmExpr
PmExpr(..), PmLit(..), SimpleEq, ComplexEq, PmVarEnv, falsePmExpr,
- notForced, eqPmLit, filterComplex, isNotPmExprOther, runPmPprM,
+ canDiverge, eqPmLit, filterComplex, isNotPmExprOther, runPmPprM,
pprPmExprWithParens, lhsExprToPmExpr, hsExprToPmExpr,
-- the term oracle
@@ -50,12 +50,33 @@ type PmVarEnv = Map.Map Id PmExpr
-- 2. A substitution we extend with every step and return as a result.
type TmOracleEnv = (Bool, PmVarEnv)
--- | Check whether a variable has been refined to (at least) a WHNF (Could be
--- improved in terms of expressivity. Too conservative at the moment.).
-notForced :: Id -> PmVarEnv -> Bool
-notForced x env = case varDeepLookup env x of
- PmExprVar _ -> True
- _other_expr -> False
+-- | Check whether a constraint (x ~ BOT) can succeed,
+-- given the resulting state of the term oracle.
+canDiverge :: Id -> TmState -> Bool
+canDiverge x (standby, (_unhandled, env))
+ -- If the variable seems not evaluated, there is a possibility for
+ -- constraint x ~ BOT to be satisfiable.
+ | PmExprVar y <- varDeepLookup env x -- seems not forced
+ -- If it is involved (directly or indirectly) in any equality in the
+ -- worklist, we can assume that it is already indirectly evaluated,
+ -- as a side-effect of equality checking. If not, then we can assume
+ -- that the constraint is satisfiable.
+ = not $ any (isForcedByEq x) standby || any (isForcedByEq y) standby
+ -- Variable x is already in WHNF so the constraint is non-satisfiable
+ | otherwise = False
+
+ where
+ isForcedByEq :: Id -> ComplexEq -> Bool
+ isForcedByEq y (e1, e2) = varIn y e1 || varIn y e2
+
+-- | Check whether a variable is in the free variables of an expression
+varIn :: Id -> PmExpr -> Bool
+varIn x e = case e of
+ PmExprVar y -> x == y
+ PmExprCon _ es -> any (x `varIn`) es
+ PmExprLit _ -> False
+ PmExprEq e1 e2 -> (x `varIn` e1) || (x `varIn` e2)
+ PmExprOther _ -> False
-- | Flatten the DAG (Could be improved in terms of performance.).
flattenPmVarEnv :: PmVarEnv -> PmVarEnv
@@ -88,7 +109,7 @@ solveComplexEq solver_state@(standby, (unhandled, env)) eq@(e1, e2) = case eq of
Just False -> Nothing -- we are sure: not equal
-- Maybe just drop. We use this boolean to check also whether something is forced and I know
-- that nothing is if both are literals. Hence, just assume true and give (Just solver_state)?
- Nothing -> Just (standby, (True, env)) -- no clue (and won't get one)!
+ Nothing -> Just (standby, (unhandled, env)) -- no clue (and won't get one)!
(PmExprCon c1 ts1, PmExprCon c2 ts2)
| c1 == c2 -> foldlM solveComplexEq solver_state (zip ts1 ts2)
More information about the ghc-commits
mailing list