--
-- == The drive loop ==
--

reduce :: State -> State
reduce = go emptyHistory
  where
    go hist state
      | not eVALUATE_PRIMOPS, (_, _, (_, TaggedTerm (Tagged _ (PrimOp _ _)))) <- state = state
      | otherwise = case step state of
        Nothing -> state
        Just state'
          | intermediate state' -> go hist state'
          | otherwise           -> case terminate hist (stateTagBag state') of
              Stop           -> state'
              Continue hist' -> go hist' state'
    
    intermediate :: State -> Bool
    intermediate (_, _, (_, TaggedTerm (Tagged _ (Var _)))) = False
    intermediate _ = True
reduce :: State -> State
reduce = go emptyHistory
  where
    go hist state
      | not eVALUATE_PRIMOPS, (_, _, (_, TaggedTerm (Tagged _ (PrimOp _ _)))) <- state = state
      | otherwise = case step state of
        Nothing -> state
        Just state'
          | intermediate state' -> go hist state'
          | otherwise           -> case terminate hist (stateTagBag state') of
              Stop           -> state'
              Continue hist' -> go hist' state'
    
    intermediate :: State -> Bool
    intermediate (_, _, (_, TaggedTerm (Tagged _ (Var _)))) = False
    intermediate _ = True
reduce = go emptyHistory
  where
    go hist state
      | not eVALUATE_PRIMOPS, (_, _, (_, TaggedTerm (Tagged _ (PrimOp _ _)))) <- state = state
      | otherwise = case step state of
        Nothing -> state
        Just state'
          | intermediate state' -> go hist state'
          | otherwise           -> case terminate hist (stateTagBag state') of
              Stop           -> state'
              Continue hist' -> go hist' state'
    
    intermediate :: State -> Bool
    intermediate (_, _, (_, TaggedTerm (Tagged _ (Var _)))) = False
    intermediate _ = True