3 -- Intended for double import
5 -- > import Distribution.Solver.Modular.ConflictSet (ConflictSet)
6 -- > import qualified Distribution.Solver.Modular.ConflictSet as CS
7 module Distribution
.Solver
.Modular
.ConflictSet
(
11 , OrderedVersionRange
(..)
13 , showCSSortedByFrequency
15 -- Set-like operations
24 , singletonWithConflict
32 import Prelude
hiding (lookup)
33 import Data
.List
(intercalate
, sortBy)
36 import Data
.Function
(on
)
37 import qualified Data
.Map
.Strict
as M
38 import qualified Data
.Set
as S
40 import Distribution
.Solver
.Modular
.Var
41 import Distribution
.Solver
.Modular
.Version
42 import Distribution
.Solver
.Types
.PackagePath
44 -- | The set of variables involved in a solver conflict, each paired with
45 -- details about the conflict.
46 newtype ConflictSet
= CS
{
47 -- | The set of variables involved in the conflict
48 conflictSetToMap
:: Map
(Var QPN
) (Set Conflict
)
52 -- | More detailed information about how a conflict set variable caused a
53 -- conflict. This information can be used to determine whether a second value
54 -- for that variable would lead to the same conflict.
56 -- TODO: Handle dependencies under flags or stanzas.
59 -- | The conflict set variable represents a package which depends on the
60 -- specified problematic package. For example, the conflict set entry
61 -- '(P x, GoalConflict y)' means that package x introduced package y, and y
65 -- | The conflict set variable represents a package with a constraint that
66 -- excluded the specified package and version. For example, the conflict set
67 -- entry '(P x, VersionConstraintConflict y (mkVersion [2, 0]))' means that
68 -- package x's constraint on y excluded y-2.0.
69 | VersionConstraintConflict QPN Ver
71 -- | The conflict set variable represents a package that was excluded by a
72 -- constraint from the specified package. For example, the conflict set
73 -- entry '(P x, VersionConflict y (orLaterVersion (mkVersion [2, 0])))'
74 -- means that package y's constraint 'x >= 2.0' excluded some version of x.
75 | VersionConflict QPN OrderedVersionRange
77 -- | Any other conflict.
79 deriving (Eq
, Ord
, Show)
81 -- | Version range with an 'Ord' instance.
82 newtype OrderedVersionRange
= OrderedVersionRange VR
85 -- TODO: Avoid converting the version ranges to strings.
86 instance Ord OrderedVersionRange
where
87 compare = compare `on`
show
89 showConflictSet
:: ConflictSet
-> String
90 showConflictSet
= intercalate
", " . map showVar
. toList
92 showCSSortedByFrequency
:: ConflictMap
-> ConflictSet
-> String
93 showCSSortedByFrequency
= showCS
False
95 showCSWithFrequency
:: ConflictMap
-> ConflictSet
-> String
96 showCSWithFrequency
= showCS
True
98 showCS
:: Bool -> ConflictMap
-> ConflictSet
-> String
100 intercalate
", " . map showWithFrequency
. indexByFrequency
102 indexByFrequency
= sortBy (flip compare `on`
snd) . map (\c
-> (c
, M
.lookup c cm
)) . toList
103 showWithFrequency
(conflict
, maybeFrequency
) = case maybeFrequency
of
105 | showCount
-> showVar conflict
++ " (" ++ show frequency
++ ")"
106 _
-> showVar conflict
108 {-------------------------------------------------------------------------------
110 -------------------------------------------------------------------------------}
112 toSet
:: ConflictSet
-> Set
(Var QPN
)
113 toSet
= M
.keysSet
. conflictSetToMap
115 toList
:: ConflictSet
-> [Var QPN
]
116 toList
= M
.keys
. conflictSetToMap
118 union :: ConflictSet
-> ConflictSet
-> ConflictSet
120 conflictSetToMap
= M
.unionWith S
.union (conflictSetToMap cs
) (conflictSetToMap cs
')
123 unions
:: [ConflictSet
] -> ConflictSet
125 conflictSetToMap
= M
.unionsWith S
.union (map conflictSetToMap css
)
128 insert :: Var QPN
-> ConflictSet
-> ConflictSet
130 conflictSetToMap
= M
.insert var
(S
.singleton OtherConflict
) (conflictSetToMap cs
)
133 delete :: Var QPN
-> ConflictSet
-> ConflictSet
135 conflictSetToMap
= M
.delete var
(conflictSetToMap cs
)
140 conflictSetToMap
= M
.empty
143 singleton
:: Var QPN
-> ConflictSet
144 singleton var
= singletonWithConflict var OtherConflict
146 singletonWithConflict
:: Var QPN
-> Conflict
-> ConflictSet
147 singletonWithConflict var conflict
= CS
{
148 conflictSetToMap
= M
.singleton var
(S
.singleton conflict
)
151 size
:: ConflictSet
-> Int
152 size
= M
.size
. conflictSetToMap
154 member
:: Var QPN
-> ConflictSet
-> Bool
155 member var
= M
.member var
. conflictSetToMap
157 lookup :: Var QPN
-> ConflictSet
-> Maybe (Set Conflict
)
158 lookup var
= M
.lookup var
. conflictSetToMap
160 fromList
:: [Var QPN
] -> ConflictSet
162 conflictSetToMap
= M
.fromList
[(var
, S
.singleton OtherConflict
) | var
<- vars
]
165 type ConflictMap
= Map
(Var QPN
) Int