[commit: ghc] wip/ext-solver: Connect with GHC's solver + debugging. (b8693a4)

git at git.haskell.org git at git.haskell.org
Sun May 11 02:36:48 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/ext-solver
Link       : http://ghc.haskell.org/trac/ghc/changeset/b8693a426cd66cc7b470a32e7595d85e11d47efe/ghc

>---------------------------------------------------------------

commit b8693a426cd66cc7b470a32e7595d85e11d47efe
Author: Iavor S. Diatchki <iavor.diatchki at gmail.com>
Date:   Sat May 10 19:35:37 2014 -0700

    Connect with GHC's solver + debugging.


>---------------------------------------------------------------

b8693a426cd66cc7b470a32e7595d85e11d47efe
 compiler/typecheck/TcInteract.lhs | 21 ++++++++++++++-------
 compiler/typecheck/TcTypeNats.hs  | 39 +++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/compiler/typecheck/TcInteract.lhs b/compiler/typecheck/TcInteract.lhs
index 808c108..bad7bf5 100644
--- a/compiler/typecheck/TcInteract.lhs
+++ b/compiler/typecheck/TcInteract.lhs
@@ -85,9 +85,9 @@ solveInteractGiven loc old_fsks givens
   | null givens  -- Shortcut for common case
   = return (True, old_fsks)
   | otherwise
-  = do { implics1 <- solveInteract fsk_bag
+  = do { implics1 <- solveInteractWithExtern True fsk_bag
 
-       ; (no_eqs, more_fsks, implics2) <- getGivenInfo (solveInteract given_bag)
+       ; (no_eqs, more_fsks, implics2) <- getGivenInfo (solveInteractWithExtern True given_bag)
        ; MASSERT( isEmptyBag implics1 && isEmptyBag implics2 )
            -- empty implics because we discard Given equalities between
            -- foralls (see Note [Do not decompose given polytype equalities]
@@ -112,11 +112,16 @@ solveInteractGiven loc old_fsks givens
 
 -- The main solver loop implements Note [Basic Simplifier Plan]
 ---------------------------------------------------------------
+
 solveInteract :: Cts -> TcS (Bag Implication)
+solveInteract = solveInteractWithExtern False
+
+solveInteractWithExtern :: Bool -- ^ Are we in the given stage?
+                        -> Cts -> TcS (Bag Implication)
 -- Returns the final InertSet in TcS
 -- Has no effect on work-list or residual-iplications
-solveInteract cts
-  = {-# SCC "solveInteract" #-}
+solveInteractWithExtern inGivenStage cts
+  = {-# SCC "solveInteractWithExtern" #-}
     withWorkList cts $
     do { dyn_flags <- getDynFlags
        ; solve_loop (maxSubGoalDepth dyn_flags) }
@@ -126,15 +131,17 @@ solveInteract cts
         do { sel <- selectNextWorkItem max_depth
            ; case sel of
               NoWorkRemaining     -- Done, successfuly (modulo frozen)
-                -> return ()
+                -> do moreWork <- interactExternSolver inGivenStage
+                      if moreWork then solve_loop max_depth
+                                  else return ()
               MaxDepthExceeded cnt ct -- Failure, depth exceeded
                 -> wrapErrTcS $ solverDepthErrorTcS cnt (ctEvidence ct)
               NextWorkItem ct     -- More work, loop around!
                 -> do { runSolverPipeline thePipeline ct; solve_loop max_depth } }
 
-inertactExternSolver :: Bool      -- ^ Are we in given stage?
+interactExternSolver :: Bool      -- ^ Are we in given stage?
                      -> TcS Bool  -- ^ Did we generatew new work.
-inertactExternSolver inGivenStage =
+interactExternSolver inGivenStage =
   do iSet <- getTcSInerts
      let iCans  = inert_cans iSet
          feqs   = funEqsToList (inert_funeqs iCans)
diff --git a/compiler/typecheck/TcTypeNats.hs b/compiler/typecheck/TcTypeNats.hs
index 043cb11..0a1757e 100644
--- a/compiler/typecheck/TcTypeNats.hs
+++ b/compiler/typecheck/TcTypeNats.hs
@@ -54,7 +54,8 @@ import           Control.Monad (forever)
 import           Control.Concurrent ( forkIO )
 import qualified Control.Exception as X
 import           System.Process ( runInteractiveProcess, waitForProcess )
-import           System.IO ( hPutStrLn, hFlush, hGetContents, hGetLine )
+import           System.IO ( hPutStrLn, hFlush, hGetContents, hGetLine,
+                             stderr )
 
 {-------------------------------------------------------------------------------
 Built-in type constructors for functions on type-lelve nats
@@ -772,22 +773,28 @@ newExternalSolver exe opts =
      -- See Note [Variable Scopes] for an explanation of this.
      viRef <- newIORef emptyVarInfo
 
+     let dbg = solverDebug proc
+
      return ExternalSolver
-       { extSolPush   = do solverDebug proc "=== PUSH ==="
+       { extSolPush   = do dbg "=== PUSH ==="
                            solverDebugNext proc
                            solverPush proc viRef
 
        , extSolPop    = do solverDebugPrev proc
-                           solverDebug proc "=== POP ==="
+                           dbg "=== POP ==="
                            solverPop proc viRef
 
        , extSolAssert = \cts ->
-          do (_,ours) <- solverPrepare proc viRef cts
+          do dbg "=== ASSERT ==="
+             (_,ours) <- solverPrepare proc viRef cts
              mapM_ (solverAssume proc . snd) ours
+             mapM_ (solverDebug proc . show . snd) ours
 
-       , extSolImprove = solverImprove proc viRef
+       , extSolImprove = \b cts -> do dbg "=== IMPROVE ==="
+                                      solverImprove proc viRef b cts
 
-       , extSolSolve = solverSimplify proc viRef
+       , extSolSolve = \cts -> do dbg "=== SOLVE ==="
+                                  solverSimplify proc viRef cts
 
        , extSolStop = solverStop proc
        }
@@ -871,6 +878,7 @@ solverCheck proc =
 -- Prove something by concluding that a counter-example is impossible.
 solverProve :: SolverProcess -> IORef VarInfo -> SExpr -> IO Bool
 solverProve proc viRef e =
+  debug $
   do solverPush proc viRef
      solverAssume proc $ SList [ SAtom "not", e ]
      res <- solverCheck proc
@@ -879,6 +887,14 @@ solverProve proc viRef e =
        Unsat -> return True
        _     -> return False
 
+  where
+  debug m = do solverDebug proc ("Prove: " ++ show e)
+               solverDebugNext proc
+               res <- m
+               solverDebug proc (show res)
+               solverDebugPrev proc
+               return res
+
 -- Get values for the variables that are in scope.
 solverGetModel :: SolverProcess -> VarInfo -> IO [(String,SExpr)]
 solverGetModel proc vi =
@@ -1091,7 +1107,11 @@ solverSimplify proc viRef cts =
 
   go unsolved solved ((ct,e) : more) =
     do push   -- Temporarily assume everything else.
+       solverDebug proc "Temporary assuming:"
+       solverDebugNext proc
        mapM_ (assume . snd) more
+       mapM_ (solverDebug proc . show . snd) more
+       solverDebugPrev proc
        proved <- solverProve proc viRef e
        pop
        if proved
@@ -1295,6 +1315,9 @@ declareVar tv vi
 data SExpr = SAtom String | SList [SExpr]
              deriving Eq
 
+instance Show SExpr where
+  showsPrec _ = renderSExpr
+
 data SolverProcess = SolverProcess
   { solverDo   :: SExpr -> IO SExpr
   , solverStop :: IO ()
@@ -1310,8 +1333,8 @@ startSolverProcess exe opts =
   do (hIn, hOut, hErr, h) <- runInteractiveProcess exe opts Nothing Nothing
 
      dbgNest <- newIORef (0 :: Int)
-     let dbgMsg x = return () {- do n <- readIORef dbgNest 
-                       putStrLn (replicate n ' ' ++ x) -}
+     let dbgMsg x = do n <- readIORef dbgNest
+                       hPutStrLn stderr (replicate n ' ' ++ x)
          dbgNext  = modifyIORef' dbgNest (+2)
          dbgPrev  = modifyIORef' dbgNest (subtract 2)
 



More information about the ghc-commits mailing list