module Frenetic.NetCore.Reduce
( reduce
) where
import Frenetic.Common
import Data.Maybe
import qualified Data.MultiSet as MS
import qualified Data.Set as Set
import Frenetic.NetCore.Types
import Frenetic.NetCore.Short
reduce = reducePo
reducePo :: Policy -> Policy
reducePo PoBottom = PoBottom
reducePo (PoBasic pr act) = if pr' == matchNone || act == mempty
then PoBottom
else PoBasic pr' act' where
pr' = reducePr pr
act' = act
reducePo (PoUnion p1 p2) = if p1' == PoBottom then p2'
else if p2' == PoBottom then p1'
else PoUnion p1' p2' where
p1' = reducePo p1
p2' = reducePo p2
reducePr :: Predicate -> Predicate
reducePr p@(PrUnion _ _) = prOr leaves where
leaves = Set.toList . Set.fromList . map reducePr . prUnUnion $ p
reducePr p@(PrIntersect _ _) = result where
leaves = Set.toList . Set.fromList . map reducePr . prUnIntersect $ p
nSwitches = Set.size .Set.fromList . mapMaybe switchOfPred $ leaves
result = if nSwitches > 1 then matchNone
else prAnd leaves
reducePr (PrNegate (PrNegate p)) = reducePr p
reducePr (PrNegate p) = PrNegate (reducePr p)
reducePr p = p
switchOfPred (PrTo s) = Just s
switchOfPred _ = Nothing