EPRelation.hs revision 6eb8da957984db853831a600c1cd81620855246e
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian Maeder{-# LANGUAGE TypeSynonymInstances #-}
5ba323da9f037264b4a356085e844889aedeac23Christian MaederModule : $Header$
10397bcc134edbcfbe3ae2c7ea4c6080036aae22Christian MaederDescription : Handling of extended parameter relations
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu ProdescuCopyright : (c) Ewaryst Schulz, DFKI Bremen 2010
23f2c59644866aa82e90de353e77f9f1d1b51b9aChristian MaederLicense : GPLv2 or higher, see LICENSE.txt
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian MaederMaintainer : ewaryst.schulz@dfki.de
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian MaederStability : experimental
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian MaederPortability : non-portable
23f2c59644866aa82e90de353e77f9f1d1b51b9aChristian MaederThis module defines an ordering on extended parameters and provides analysis tools.
f8f78a2c8796a387a4348cc672ae08e8d9f69315Christian Maederimport qualified Data.Map as Map
af621d0066770895fd79562728e93099c8c52060Christian Maederimport qualified Data.Set as Set
79d11c2e3ad242ebb241f5d4a5e98a674c0b986fChristian Maederimport Data.Traversable (fmapDefault)
c0ef189e724dfd960074248c97fb01dfa5842a5cChristian Maeder (toBoolRep, showEP, toEPExp, EPExp, compareEP)
c0ef189e724dfd960074248c97fb01dfa5842a5cChristian Maeder-- ----------------------------------------------------------------------
f8f78a2c8796a387a4348cc672ae08e8d9f69315Christian Maeder-- * Datatypes for efficient Extended Parameter comparison
024621f43239cfe9629e35d35a8669fad7acbba2Christian Maeder-- ----------------------------------------------------------------------
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maeder-- | A more efficient representation of a list of extended parameters,
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maeder-- particularly for comparison
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maedertype EPExps = Map.Map String EPExp
afa6848d579d235c9677e1ab477916df8e5ae11aChristian MaederprettyEPs :: EPExps -> Doc
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder | Map.null eps = text "*"
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder | otherwise = brackets $ sepByCommas $ map (text . showEP) $ Map.toList eps
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian MaedershowEPs :: EPExps -> String
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedershowEPs = show . prettyEPs
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder-- | A star expression is the unconstrained expression corresponding to the
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder-- whole space of extended parameter values
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederisStarEP :: EPExps -> Bool
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maeder-- | 'isStarEP' lifted for Range expressions.
afa6848d579d235c9677e1ab477916df8e5ae11aChristian MaederisStarRange :: EPRange -> Bool
afa6848d579d235c9677e1ab477916df8e5ae11aChristian MaederisStarRange (Atom e) = isStarEP e
afa6848d579d235c9677e1ab477916df8e5ae11aChristian MaederisStarRange _ = False
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | The star range.
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederstarRange :: EPRange
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederstarRange = Atom Map.empty
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder-- | Conversion function into the more efficient representation.
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian MaedertoEPExps :: [EXTPARAM] -> EPExps
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian MaedertoEPExps = Map.fromList . mapMaybe toEPExp
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder-- | Sets representing the Parameters for which there is a propagation break
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder-- (filtered) and for which there is a constraint (constrained)
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederfilteredConstrainedParams :: [EXTPARAM] -> (Set.Set String, Set.Set String)
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederfilteredConstrainedParams = foldl f (Set.empty, Set.empty)
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder where f (fs, cs) (EP t "-|" _) = (Set.insert (tokStr t) fs, cs)
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder f (fs, cs) (EP t _ _) = (fs, Set.insert (tokStr t) cs)
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederdata EPRange = Union [EPRange] | Intersection [EPRange]
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maeder | Complement EPRange | Atom EPExps | Empty
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian MaederprettyEPRange :: EPRange -> Doc
792df0347edab377785d98c63e2be8e2ce0a8bdeChristian MaederprettyEPRange re =
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder let f s a b = parens $ hsep [prettyEPRange a, text s, prettyEPRange b]
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder g s l = parens $ hsep $ text s : map prettyEPRange l
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder in case re of
d976ba42e9d48c289f9c73147669c7e57b7aa98eChristian Maeder Union [r1, r2] -> f "Un" r1 r2
d976ba42e9d48c289f9c73147669c7e57b7aa98eChristian Maeder Intersection [r1, r2] -> f "In" r1 r2
986e0e9cf8c2358f455460b3fc75ce7c5dcf0973Christian Maeder Complement r -> g "C" [r]
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian Maeder Union l -> g "Union" l
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian Maeder Intersection l -> g "Intersection" l
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder Empty -> text "Empty"
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder Atom eps -> prettyEPs eps
167b6ed8639bce096380defb7311ded501ebb5daChristian MaedershowEPRange :: EPRange -> String
167b6ed8639bce096380defb7311ded501ebb5daChristian MaedershowEPRange = show . prettyEPRange
167b6ed8639bce096380defb7311ded501ebb5daChristian Maederinstance Show EPRange where
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder show = showEPRange
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder-- | Behaves as a map on the list of leafs of the range expression
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder-- (from left to right)
167b6ed8639bce096380defb7311ded501ebb5daChristian MaedermapRangeLeafs :: (EPExps -> b) -> EPRange -> [b]
167b6ed8639bce096380defb7311ded501ebb5daChristian MaedermapRangeLeafs f re =
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder Union l -> g l
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder Intersection l -> g l
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder Complement r -> mapRangeLeafs f r
167b6ed8639bce096380defb7311ded501ebb5daChristian Maeder Atom eps -> [f eps]
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian Maeder where g = concatMap (mapRangeLeafs f)
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder-- | Maps an EP expression transformer over the given range expression
59c301c268f79cfde0a4c30a2c572a368db98da5Christian MaedermapRange :: (EPExps -> EPExps) -> EPRange -> EPRange
59c301c268f79cfde0a4c30a2c572a368db98da5Christian MaedermapRange f re =
964d1dce6aa88a14e240a4f2fb81c539d2f834fcChristian Maeder Union l -> Union $ g l
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maeder Intersection l -> Intersection $ g l
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maeder Complement r -> Complement $ mapRange f r
0a320bc4cdbf38f480b75ac15a54db1c4885b497Christian Maeder Atom eps -> Atom $ f eps
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maeder where g = map (mapRange f)
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maederclass RangeUtils a where
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder rangeNames :: a -> Set.Set String
167b6ed8639bce096380defb7311ded501ebb5daChristian Maederinstance RangeUtils EPExps where
167b6ed8639bce096380defb7311ded501ebb5daChristian Maederinstance RangeUtils EPRange where
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder rangeNames = Set.unions . mapRangeLeafs rangeNames
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian MaedernamesInList :: RangeUtils a => [a] -> Set.Set String
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian MaedernamesInList = Set.unions . map rangeNames
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder-- TODO: check the todos at the end for projection-fix
997c56f3bc74a703043010978e5013fdb074d659Christian Maeder (1) If the arguments are disjoint -> 'Nothing'
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder (2) If all extended parameter constraints from the first argument are
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder subsumed by the second argument -> second argument with deleted entries for
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder these extended parameters
8485da94b57d8b5135ee685b55c982b037ed4140Christian Maeder (3) Otherwise -> error: the first argument must be subsumed by or disjoint
8485da94b57d8b5135ee685b55c982b037ed4140Christian Maeder with the second one.
e76e6a43f51438215737d6fc176c89da05bb86daChristian MaederprojectEPs :: EPExps -> EPExps -> Maybe EPExps
e76e6a43f51438215737d6fc176c89da05bb86daChristian MaederprojectEPs e1 e2
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder | isStarEP e1 = Just e2
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder | otherwise =
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder -- take first element from e1 delete it from e1 and proceed with it
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder let ((k, v), e1') = Map.deleteFindMin e1
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder in case Map.lookup k e2 of
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maeder Nothing -> projectEPs e1' e2
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder case compareEP v v2 of
53301de22afd7190981b363b57c48df86fcb50f7Christian Maeder Incomparable Disjoint -> Nothing
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian Maeder Comparable x -> if x /= GT then projectEPs e1' e2'
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder else error $ "projectEPs: e1 > e2 "
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder ++ show (e1,e2)
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder _ -> error $ "projectEPs: overlap " ++ show (e1,e2)
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder Given a range predicate, e.g, A x y z (here with three extended
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder parameters), we instantiate it partially with the given
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder instantiation, e.g., x=1, and obtain A 1 y z. The new predicate
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder does not depend on x anymore and can be built by replacing all
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder atomic subexpressions in A which talk about x (1) by the subexpression
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder where the constraint for x is removed if the given instantiation
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder satisfies this subexpression (e.g., x<10) or (2) by 'Empty' if this
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder constraint is not satisfied (e.g., x>1)
62ecb1e7f8fd9573eea8369657de12c7bf9f4f25Christian MaederprojectRange :: EPExps -> EPRange -> EPRange
f6f2955769bfe80dbb4cca3b3ee33c5a8a0f5355Christian MaederprojectRange e re = simplifyRange $ f re
c1031ac42b3f3d7d0fe7d9d6b54423a092d473a0Christian Maeder where f rexp =
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder Union l -> Union $ map f l
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder Intersection l -> Intersection $ map f l
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder Complement r -> Complement $ f r
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder Atom eps -> case projectEPs e eps of
ac19566dc64536c38b5d1d3ae510fb8a07784c2fChristian Maeder Nothing -> Empty
039b7a8265baaeab2ded2a3e3826c04f13364d87Christian Maeder Just eps' -> Atom eps'
fe5dbb45b6a8abf34375b4bc5f2a81cda664c0e4Christian Maeder Empty -> Empty
039b7a8265baaeab2ded2a3e3826c04f13364d87Christian Maeder{- | Removes all star- and empty-entries from inside of the range expression.
3cafc73a998493f9ed3d5e934c0ab80bcfb465c2Christian Maeder Union [,*,] -> * (top element)
7bf6d421b0ea31ae63f1fe04919942b931abda47Christian Maeder Intersection [,*,] -> Intersection [,] (neutral element)
021d7137df04ec1834911d99d90243a092841cedChristian Maeder Complement * -> Empty (bottom element)
7c554e9d4a39b8eb3b0881f20807c95dd8e793aeChristian Maeder For Empty its the dual behaviour
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedersimplifyRange :: EPRange -> EPRange
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian MaedersimplifyRange re =
7c554e9d4a39b8eb3b0881f20807c95dd8e793aeChristian Maeder Union l -> f [] l
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder Intersection l -> g [] l
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder Complement r ->
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder case simplifyRange r of
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder Empty -> starRange
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder r' | isStarRange r' -> Empty
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder | otherwise -> Complement r'
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder where -- returns either a simplified list or a new expression
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder f acc [] = if null acc then Empty else Union acc
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder f acc (r:l) =
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder case simplifyRange r of
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder Empty -> f acc l
bb3bdd4a260606a6184b5f5a5774ca6632ca597aChristian Maeder r' | isStarRange r' -> r'
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder | otherwise -> f (acc++[r']) l
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder g acc [] = if null acc then starRange else Intersection acc
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder g acc (r:l) =
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder case simplifyRange r of
7946f81bdc77b0790ac47ccaf2912a1d55c8336dChristian Maeder Empty -> Empty
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder r' | isStarRange r' -> g acc l
case Map.lookup k eps' of
(epc, cnt) = Map.foldWithKey f
epc' = if Map.size eps' > cnt
type VarMap = Map.Map String Int
varMapFromList l = Map.fromList $ zip l $ [1 .. length l]
varMapFromSet :: Set.Set String -> VarMap
varMapFromSet = varMapFromList . Set.toList
| otherwise = And $ map f $ Map.assocs eps where
f (k, v) = toBoolRep ("x" ++ show (Map.findWithDefault err k m)) v
smtVars m s = map ((s++) . show) [1 .. Map.size m]