module ADP.Multi.Rewriting.YieldSize where
import Data.Map (Map)
import qualified Data.Map as Map
import Control.Monad (liftM2)
import ADP.Multi.Parser
import ADP.Multi.Rewriting.Model
type YieldAnalysisAlgorithm a = a -> [ParserInfo] -> ParserInfo
determineYieldSize1 :: YieldAnalysisAlgorithm Dim1
determineYieldSize1 _ infos =
let elemInfo = buildYieldSizeMap infos
(yieldMin,yieldMax) = combineYields (Map.elems elemInfo)
in ParserInfo1 {
minYield = yieldMin,
maxYield = yieldMax
}
determineYieldSize2 :: YieldAnalysisAlgorithm Dim2
determineYieldSize2 f infos =
let elemInfo = buildYieldSizeMap infos
(left,right) = f (Map.keys elemInfo)
leftYields = map (\(i,j) -> elemInfo Map.! (i,j)) left
rightYields = map (\(i,j) -> elemInfo Map.! (i,j)) right
(leftMin,leftMax) = combineYields leftYields
(rightMin,rightMax) = combineYields rightYields
in ParserInfo2 {
minYield2 = (leftMin,rightMin),
maxYield2 = (leftMax,rightMax)
}
combineYields :: [YieldSize] -> YieldSize
combineYields = foldl (\(minY1,maxY1) (minY2,maxY2) ->
( minY1+minY2
, liftM2 (+) maxY1 maxY2
) ) (0,Just 0)
type YieldSize = (Int,Maybe Int)
type YieldSizeMap = Map (Int,Int) YieldSize
buildYieldSizeMap :: [ParserInfo] -> YieldSizeMap
buildYieldSizeMap infos =
let parserCount = length infos
list = concatMap (\ (x,info) -> case info of
ParserInfo1 { minYield = minY, maxYield = maxY } ->
[ ((x,1), (minY, maxY) ) ]
ParserInfo2 { minYield2 = minY, maxYield2 = maxY } ->
[ ((x,1), (fst minY, fst maxY) )
, ((x,2), (snd minY, snd maxY) )
]
) $ zip [parserCount,parserCount1..] infos
in Map.fromList list