summaryrefslogtreecommitdiff
path: root/compiler/deSugar/TmOracle.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/deSugar/TmOracle.hs')
-rw-r--r--compiler/deSugar/TmOracle.hs34
1 files changed, 24 insertions, 10 deletions
diff --git a/compiler/deSugar/TmOracle.hs b/compiler/deSugar/TmOracle.hs
index 5d7a61a460..05966cd858 100644
--- a/compiler/deSugar/TmOracle.hs
+++ b/compiler/deSugar/TmOracle.hs
@@ -10,14 +10,14 @@ module TmOracle (
-- re-exported from PmExpr
PmExpr(..), PmLit(..), SimpleEq, ComplexEq, PmVarEnv, falsePmExpr,
- canDiverge, eqPmLit, filterComplex, isNotPmExprOther, runPmPprM,
- pprPmExprWithParens, lhsExprToPmExpr, hsExprToPmExpr,
+ eqPmLit, filterComplex, isNotPmExprOther, runPmPprM, lhsExprToPmExpr,
+ hsExprToPmExpr, pprPmExprWithParens,
-- the term oracle
- tmOracle, TmState, initialTmState,
+ tmOracle, TmState, initialTmState, solveOneEq, extendSubst, canDiverge,
-- misc.
- exprDeepLookup, pmLitType, flattenPmVarEnv
+ toComplex, exprDeepLookup, pmLitType, flattenPmVarEnv
) where
#include "HsVersions.h"
@@ -25,6 +25,7 @@ module TmOracle (
import PmExpr
import Id
+import Name
import TysWiredIn
import Type
import HsLit
@@ -43,7 +44,7 @@ import qualified Data.Map as Map
-}
-- | The type of substitutions.
-type PmVarEnv = Map.Map Id PmExpr
+type PmVarEnv = Map.Map Name PmExpr
-- | The environment of the oracle contains
-- 1. A Bool (are there any constraints we cannot handle? (PmExprOther)).
@@ -52,7 +53,7 @@ type TmOracleEnv = (Bool, PmVarEnv)
-- | Check whether a constraint (x ~ BOT) can succeed,
-- given the resulting state of the term oracle.
-canDiverge :: Id -> TmState -> Bool
+canDiverge :: Name -> TmState -> Bool
canDiverge x (standby, (_unhandled, env))
-- If the variable seems not evaluated, there is a possibility for
-- constraint x ~ BOT to be satisfiable.
@@ -66,11 +67,11 @@ canDiverge x (standby, (_unhandled, env))
| otherwise = False
where
- isForcedByEq :: Id -> ComplexEq -> Bool
+ isForcedByEq :: Name -> 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 :: Name -> PmExpr -> Bool
varIn x e = case e of
PmExprVar y -> x == y
PmExprCon _ es -> any (x `varIn`) es
@@ -131,7 +132,7 @@ solveComplexEq solver_state@(standby, (unhandled, env)) eq@(e1, e2) = case eq of
_ -> Just (standby, (True, env)) -- I HATE CATCH-ALLS
-- | Extend the substitution and solve the (possibly updated) constraints.
-extendSubstAndSolve :: Id -> PmExpr -> TmState -> Maybe TmState
+extendSubstAndSolve :: Name -> PmExpr -> TmState -> Maybe TmState
extendSubstAndSolve x e (standby, (unhandled, env))
= foldlM solveComplexEq new_incr_state (map simplifyComplexEq changed)
where
@@ -142,6 +143,19 @@ extendSubstAndSolve x e (standby, (unhandled, env))
(changed, unchanged) = partitionWith (substComplexEq x e) standby
new_incr_state = (unchanged, (unhandled, Map.insert x e env))
+-- | When we know that a variable is fresh, we do not actually have to
+-- check whether anything changes, we know that nothing does. Hence,
+-- `extendSubst` simply extends the substitution, unlike what
+-- `extendSubstAndSolve` does.
+extendSubst :: Id -> PmExpr -> TmState -> TmState
+extendSubst y e (standby, (unhandled, env))
+ | isNotPmExprOther simpl_e
+ = (standby, (unhandled, Map.insert x simpl_e env))
+ | otherwise = (standby, (True, env))
+ where
+ x = idName y
+ simpl_e = fst $ simplifyPmExpr $ exprDeepLookup env e
+
-- | Simplify a complex equality.
simplifyComplexEq :: ComplexEq -> ComplexEq
simplifyComplexEq (e1, e2) = (fst $ simplifyPmExpr e1, fst $ simplifyPmExpr e2)
@@ -204,7 +218,7 @@ applySubstComplexEq :: PmVarEnv -> ComplexEq -> ComplexEq
applySubstComplexEq env (e1,e2) = (exprDeepLookup env e1, exprDeepLookup env e2)
-- | Apply an (un-flattened) substitution to a variable.
-varDeepLookup :: PmVarEnv -> Id -> PmExpr
+varDeepLookup :: PmVarEnv -> Name -> PmExpr
varDeepLookup env x
| Just e <- Map.lookup x env = exprDeepLookup env e -- go deeper
| otherwise = PmExprVar x -- terminal