[commit: ghc] wip/ext-solver: A function to simplify a set of constraints. (3c5f574)
git at git.haskell.org
git at git.haskell.org
Sun May 11 02:36:30 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/ext-solver
Link : http://ghc.haskell.org/trac/ghc/changeset/3c5f57440321d8e41379dca015d2d62387fb130c/ghc
>---------------------------------------------------------------
commit 3c5f57440321d8e41379dca015d2d62387fb130c
Author: Iavor S. Diatchki <iavor.diatchki at gmail.com>
Date: Sat May 10 12:35:30 2014 -0700
A function to simplify a set of constraints.
Also, we factor out a common pattern.
>---------------------------------------------------------------
3c5f57440321d8e41379dca015d2d62387fb130c
compiler/typecheck/TcTypeNats.hs | 90 +++++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 25 deletions(-)
diff --git a/compiler/typecheck/TcTypeNats.hs b/compiler/typecheck/TcTypeNats.hs
index 9cad950..4038a54 100644
--- a/compiler/typecheck/TcTypeNats.hs
+++ b/compiler/typecheck/TcTypeNats.hs
@@ -952,6 +952,26 @@ solverNewWork proc viRef loc withEv =
$ mkNewFact loc withEv (mkTyVarTy tv, ty)
return $ ExtSolOk $ mapMaybe toCt imps
+
+--------------------------------------------------------------------------------
+-- Higher level operations on collections of constraints.
+
+
+-- Identify our constraints, and declare their variables in the current scope.
+solverPrepare :: SolverProcess -> IORef VarInfo ->
+ [Ct] -> IO ([Ct], [(Ct,SExpr)])
+solverPrepare proc viRef = go [] []
+ where
+ go others ours [] = return (others, ours)
+ go others ours (ct : cts) =
+ case knownCt ct of
+ Just (vars,e) ->
+ do mapM_ (solverDeclare proc viRef) (eltsUFM vars)
+ go others ((ct,e) : ours) cts
+ Nothing ->
+ go (ct : others) ours cts
+
+
{-
Check a list of constraints for consistency, and computer derived work.
Does not affect set off assertions in the solver.
@@ -962,25 +982,29 @@ Assumes that either:
solverImprove :: SolverProcess -> IORef VarInfo
-> [Ct] -> IO ExtSolRes
solverImprove proc viRef cts =
- do let (ours, ourCts) =
- unzip [ (rep,ct) | ct <- cts, Just rep <- [ knownCt ct ] ]
- case ourCts of
- [] -> return (ExtSolOk [])
- oneOfOurs : _ ->
- do solverPush proc viRef
- mapM_ assume ours
+ do push
+ (_,ours) <- solverPrepare proc viRef cts
+ case ours of
+ [] -> do pop
+ return (ExtSolOk [])
+ (oneOfOurs,_) : _ ->
+ do mapM_ (assume . snd) ours
let loc = ctLoc oneOfOurs -- XXX: What is a better location?
-- XXX: When we compute improvements,
-- we should probably limit ourselves to compute improvements
-- only for the variables in the current scope.
+ -- XXX: This might be a good idea for wanteds, but not givens:
+ -- assumptions in a later scope, may give us facts about
+ -- givens in earlier scopes.
res <- solverNewWork proc viRef loc (isGivenCt oneOfOurs)
- solverPop proc viRef
+ pop
return res
where
- assume (vars,expr) =
- do mapM_ (solverDeclare proc viRef) (eltsUFM vars)
- solverAssume proc expr
+ push = solverPush proc viRef
+ pop = solverPop proc viRef
+ assume = solverAssume proc
+
{- Given a set of constraints, try to split them into:
@@ -992,8 +1016,9 @@ Does not change the assertion state of the solver.
solverFindConstraidction :: SolverProcess -> IORef VarInfo ->
[Ct] -> IO (Maybe ([Ct], [Ct]))
solverFindConstraidction proc viRef cts =
- do push -- scope for `needed`
- prepare [] [] cts -- declare variables, then search.
+ do push -- scope for `needed`
+ (others,ours) <- solverPrepare proc viRef cts -- declare vars
+ minimize others [] ours
where
check = solverCheck proc
@@ -1001,18 +1026,6 @@ solverFindConstraidction proc viRef cts =
pop = solverPop proc viRef
assume = solverAssume proc
- prepare notNeeded maybeNeeded [] =
- minimize notNeeded [] maybeNeeded
-
- prepare notNeeded maybeNeeded (ct : cts) =
- case knownCt ct of
- Just (vars,e) ->
- do mapM_ (solverDeclare proc viRef) (eltsUFM vars)
- prepare notNeeded ((ct,e) : maybeNeeded) cts
- Nothing ->
- prepare (ct : notNeeded) maybeNeeded cts
-
-
minimize notNeeded needed maybeNeeded =
do res <- check
case res of
@@ -1043,6 +1056,33 @@ solverFindConstraidction proc viRef cts =
+solverSimplify :: SolverProcess -> IORef VarInfo ->
+ [Ct] -> IO ([(EvTerm,Ct)], [Ct])
+solverSimplify proc viRef cts =
+ do push -- `unsolved` scope
+ (others,ours) <- solverPrepare proc viRef cts
+ go others [] ours
+ where
+ push = solverPush proc viRef
+ pop = solverPop proc viRef
+ assume = solverAssume proc
+
+ go unsolved solved [] =
+ do pop -- remove `unsolved` scope
+ return (solved, unsolved)
+
+ go unsolved solved ((ct,e) : more) =
+ do push -- Temporarily assume everything else.
+ mapM_ (assume . snd) more
+ proved <- solverProve proc viRef e
+ pop
+ if proved
+ then let ev = evBySMT "SMT" $ getEqPredTys $ ctPred ct
+ in go unsolved ((ev,ct) : solved) more
+ else do assume e -- add to `unsolved`
+ go (ct : unsolved) solved more
+
+
smtTy :: Ty -> SExpr
smtTy ty =
SAtom $
More information about the ghc-commits
mailing list