walkEqs env te fw (eq:eqs)      = do (eq,eqs1) <- doEq te eq
                                     (eqs,eqs2) <- walkEqs env te (fw \\ [fst eq] ++ dom eqs1) eqs
                                     return (eq:eqs, eqs1++eqs2)
  where doEq te eq@(x,e)
          | null ke             = do (e,eqs) <- doExp e
                                     return ((x,e), eqs)
          | otherwise           = return ((x,e), [])
          where ke              = quant (lookup' te x)
        doAlt (p,e)             = do (e,eqs1) <- doExp e
                                     return ((p,e), eqs1)
        doExp (ESel e l)
          | isCoerceLabel l     = maybeDelay (\e -> ESel e l) e
          | otherwise           = do (e,eqs1) <- doExp e
                                     return (ESel e l, eqs1)
        doExp (ECase e alts)    = do (e,eqs1) <- doExp e
                                     (alts,eqss) <- fmap unzip (mapM doAlt alts)
                                     return (ECase e alts, eqs1++concat eqss)
        doExp (EAp e es)        = do (e,eqs1) <- doExp e
                                     (es,eqss) <- fmap unzip (mapM doExp es)
                                     return (EAp e es, eqs1++concat eqss)
        doExp (ELet (Binds r te eqs) e)
                                = do (eqs',eqss) <- fmap unzip (mapM (doEq te) eqs)
                                     (e,eqs1) <- doExp e
                                     return (ELet (Binds r te eqs') e, eqs1++concat eqss)
        doExp (ERec n eqs)      = do (eqs',eqss) <- fmap unzip (mapM (doEq (sels env)) eqs)
                                     return (ERec n eqs', concat eqss)
        doExp e                 = return (e, [])
        maybeDelay f (ESel e l)
          | isCoerceLabel l     = maybeDelay (\e -> f (ESel e l)) e
        maybeDelay f (EVar x)
          | x `elem` fw         = do y <- newName tempSym
                                     return (EVar y, [(y, f (EVar x))])
        maybeDelay f e          = do (e,eqs1) <- doExp e
                                     return (f e, eqs1)
walkEqs env te fw (eq:eqs)      = do (eq,eqs1) <- doEq te eq
                                     (eqs,eqs2) <- walkEqs env te (fw \\ [fst eq] ++ dom eqs1) eqs
                                     return (eq:eqs, eqs1++eqs2)
  where doEq te eq@(x,e)
          | null ke             = do (e,eqs) <- doExp e
                                     return ((x,e), eqs)
          | otherwise           = return ((x,e), [])
          where ke              = quant (lookup' te x)
        doAlt (p,e)             = do (e,eqs1) <- doExp e
                                     return ((p,e), eqs1)
        doExp (ESel e l)
          | isCoerceLabel l     = maybeDelay (\e -> ESel e l) e
          | otherwise           = do (e,eqs1) <- doExp e
                                     return (ESel e l, eqs1)
        doExp (ECase e alts)    = do (e,eqs1) <- doExp e
                                     (alts,eqss) <- fmap unzip (mapM doAlt alts)
                                     return (ECase e alts, eqs1++concat eqss)
        doExp (EAp e es)        = do (e,eqs1) <- doExp e
                                     (es,eqss) <- fmap unzip (mapM doExp es)
                                     return (EAp e es, eqs1++concat eqss)
        doExp (ELet (Binds r te eqs) e)
                                = do (eqs',eqss) <- fmap unzip (mapM (doEq te) eqs)
                                     (e,eqs1) <- doExp e
                                     return (ELet (Binds r te eqs') e, eqs1++concat eqss)
        doExp (ERec n eqs)      = do (eqs',eqss) <- fmap unzip (mapM (doEq (sels env)) eqs)
                                     return (ERec n eqs', concat eqss)
        doExp e                 = return (e, [])
        maybeDelay f (ESel e l)
          | isCoerceLabel l     = maybeDelay (\e -> f (ESel e l)) e
        maybeDelay f (EVar x)
          | x `elem` fw         = do y <- newName tempSym
                                     return (EVar y, [(y, f (EVar x))])
        maybeDelay f e          = do (e,eqs1) <- doExp e
                                     return (f e, eqs1)
walkEqs env te fw (eq:eqs)      = do (eq,eqs1) <- doEq te eq
                                     (eqs,eqs2) <- walkEqs env te (fw \\ [fst eq] ++ dom eqs1) eqs
                                     return (eq:eqs, eqs1++eqs2)
  where doEq te eq@(x,e)
          | null ke             = do (e,eqs) <- doExp e
                                     return ((x,e), eqs)
          | otherwise           = return ((x,e), [])
          where ke              = quant (lookup' te x)
        doAlt (p,e)             = do (e,eqs1) <- doExp e
                                     return ((p,e), eqs1)
        doExp (ESel e l)
          | isCoerceLabel l     = maybeDelay (\e -> ESel e l) e
          | otherwise           = do (e,eqs1) <- doExp e
                                     return (ESel e l, eqs1)
        doExp (ECase e alts)    = do (e,eqs1) <- doExp e
                                     (alts,eqss) <- fmap unzip (mapM doAlt alts)
                                     return (ECase e alts, eqs1++concat eqss)
        doExp (EAp e es)        = do (e,eqs1) <- doExp e
                                     (es,eqss) <- fmap unzip (mapM doExp es)
                                     return (EAp e es, eqs1++concat eqss)
        doExp (ELet (Binds r te eqs) e)
                                = do (eqs',eqss) <- fmap unzip (mapM (doEq te) eqs)
                                     (e,eqs1) <- doExp e
                                     return (ELet (Binds r te eqs') e, eqs1++concat eqss)
        doExp (ERec n eqs)      = do (eqs',eqss) <- fmap unzip (mapM (doEq (sels env)) eqs)
                                     return (ERec n eqs', concat eqss)
        doExp e                 = return (e, [])
        maybeDelay f (ESel e l)
          | isCoerceLabel l     = maybeDelay (\e -> f (ESel e l)) e
        maybeDelay f (EVar x)
          | x `elem` fw         = do y <- newName tempSym
                                     return (EVar y, [(y, f (EVar x))])
        maybeDelay f e          = do (e,eqs1) <- doExp e
                                     return (f e, eqs1)