keiro-dsl-0.11.0.0: src/Keiro/Dsl/AggregateGenerationPlan.hs
module Keiro.Dsl.AggregateGenerationPlan
( TransitionLayoutEntry (..),
transitionLayout,
groupTransitionLayoutBySource,
transitionLayoutForSource,
)
where
import Data.List (mapAccumL)
import Data.Map.Strict qualified as Map
import Keiro.Dsl.Grammar (Name, Transition (..))
data TransitionLayoutEntry = TransitionLayoutEntry
{ layoutDeclarationIndex :: !Int,
layoutOutgoingIndex :: !Int,
layoutTransition :: !Transition
}
deriving stock (Eq, Show)
transitionLayout :: [Transition] -> [TransitionLayoutEntry]
transitionLayout transitions = snd (mapAccumL buildEntry Map.empty (zip [1 ..] transitions))
where
buildEntry counts (declarationIndex, transition) =
let source = tSource transition
outgoingIndex = Map.findWithDefault 0 source counts
counts' = Map.insert source (outgoingIndex + 1) counts
entry = TransitionLayoutEntry declarationIndex outgoingIndex transition
in (counts', entry)
groupTransitionLayoutBySource :: [TransitionLayoutEntry] -> [(Name, [TransitionLayoutEntry])]
groupTransitionLayoutBySource entries =
[ (source, transitionLayoutForSource source entries)
| source <- firstOccurrences (map (tSource . layoutTransition) entries)
]
where
firstOccurrences = foldl appendNew []
appendNew seen value
| value `elem` seen = seen
| otherwise = seen ++ [value]
transitionLayoutForSource :: Name -> [TransitionLayoutEntry] -> [TransitionLayoutEntry]
transitionLayoutForSource source = filter ((== source) . tSource . layoutTransition)