-- | Returns the set of all labels which are reachable from the start path.
usedPaths :: (Ord c) => System c b e a -> Set.Set c
usedPaths sys = go (systemStart sys) `execState` Set.empty where
  go g = case g of
    _ :>> x -> go x
    Branch _ x y -> go x >> go y
    Continue label -> gets (Set.member label) >>= \b -> unless b $ do
      modify $ Set.insert label
      maybe missingPath go $ Map.lookup label paths
    End _ -> return ()
  missingPath = error "usedPaths: missing continue"
  paths = systemPaths sys

-- | Removes all unused continuations from the map.
usedPaths :: (Ord c) => System c b e a -> Set.Set c
usedPaths sys = go (systemStart sys) `execState` Set.empty where
  go g = case g of
    _ :>> x -> go x
    Branch _ x y -> go x >> go y
    Continue label -> gets (Set.member label) >>= \b -> unless b $ do
      modify $ Set.insert label
      maybe missingPath go $ Map.lookup label paths
    End _ -> return ()
  missingPath = error "usedPaths: missing continue"
  paths = systemPaths sys

-- | Removes all unused continuations from the map.
usedPaths sys = go (systemStart sys) `execState` Set.empty where
  go g = case g of
    _ :>> x -> go x
    Branch _ x y -> go x >> go y
    Continue label -> gets (Set.member label) >>= \b -> unless b $ do
      modify $ Set.insert label
      maybe missingPath go $ Map.lookup label paths
    End _ -> return ()
  missingPath = error "usedPaths: missing continue"
  paths = systemPaths sys

-- | Removes all unused continuations from the map.