Skip to content

Commit 9ea5b41

Browse files
committed
small changes mostly to understand the code
1 parent fc02e2f commit 9ea5b41

File tree

7 files changed

+280
-221
lines changed

7 files changed

+280
-221
lines changed

cabal-install-solver/src/Distribution/Solver/Modular.hs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ import qualified Data.Map as M
1919
import Data.Set (isSubsetOf)
2020
import Distribution.Compat.Graph
2121
( IsNode(..) )
22-
import Distribution.Compiler
23-
( CompilerInfo )
2422
import Distribution.Solver.Modular.Assignment
2523
( Assignment, toCPs )
24+
import Distribution.Solver.Modular.Configured
25+
( CP (..) )
2626
import Distribution.Solver.Modular.ConfiguredConversion
2727
( convCP )
2828
import qualified Distribution.Solver.Modular.ConflictSet as CS
@@ -40,29 +40,28 @@ import Distribution.Solver.Modular.Solver
4040
( SolverConfig(..), PruneAfterFirstSuccess(..), solve )
4141
import Distribution.Solver.Types.DependencyResolver
4242
import Distribution.Solver.Types.LabeledPackageConstraint
43+
import Distribution.Solver.Types.OptionalStanza (showStanzas, optStanzaSetNull)
4344
import Distribution.Solver.Types.PackageConstraint
4445
import Distribution.Solver.Types.PackagePath
4546
import Distribution.Solver.Types.PackagePreferences
4647
import Distribution.Solver.Types.PkgConfigDb
4748
( PkgConfigDb )
4849
import Distribution.Solver.Types.Progress
4950
import Distribution.Solver.Types.Variable
50-
import Distribution.System
51-
( Platform(..) )
51+
import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps
52+
53+
import Distribution.Simple.Compiler
54+
( CompilerInfo, compilerInfo )
5255
import Distribution.Simple.Setup
5356
( BooleanFlag(..) )
5457
import Distribution.Simple.Utils
5558
( ordNubBy )
5659
import Distribution.Verbosity
57-
import Distribution.Solver.Modular.Configured (CP (..))
58-
import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps
60+
5961
import Distribution.Pretty (Pretty (..))
6062
import Text.PrettyPrint (text, vcat, Doc, nest, ($+$))
61-
import Distribution.Solver.Types.OptionalStanza (showStanzas, optStanzaSetNull)
6263
import Distribution.Types.Flag (nullFlagAssignment)
63-
import Distribution.Solver.Types.Toolchain (Toolchain(..), Staged)
64-
import Distribution.Simple.Compiler (compilerInfo)
65-
import Distribution.Simple.PackageIndex (InstalledPackageIndex)
64+
import Distribution.Solver.Types.Toolchain (Staged, Toolchain (..))
6665

6766

6867
showCP :: CP QPN -> Doc
@@ -83,11 +82,13 @@ showCP (CP qpi fa es ds) =
8382
-- solver. Performs the necessary translations before and after.
8483
modularResolver :: SolverConfig -> DependencyResolver loc
8584
modularResolver sc toolchains pkgConfigDbs iidx sidx pprefs pcs pns = do
86-
(assignment, revdepmap) <- solve' sc toolchains pkgConfigDbs idx pprefs gcs pns
85+
(assignment, revdepmap) <- solve' sc cinfo pkgConfigDbs idx pprefs gcs pns
8786
let cp = toCPs assignment revdepmap
8887
Step (show (vcat (map showCP cp))) $
8988
return $ postprocess assignment revdepmap
9089
where
90+
cinfo = compilerInfo . toolchainCompiler <$> toolchains
91+
9192
-- Indices have to be converted into solver-specific uniform index.
9293
idx = convPIs toolchains gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx
9394

@@ -140,21 +141,21 @@ modularResolver sc toolchains pkgConfigDbs iidx sidx pprefs pcs pns = do
140141
-- complete, i.e., it shows the whole chain of dependencies from the user
141142
-- targets to the conflicting packages.
142143
solve' :: SolverConfig
143-
-> Staged Toolchain
144+
-> Staged CompilerInfo
144145
-> Staged (Maybe PkgConfigDb)
145146
-> Index
146147
-> (PN -> PackagePreferences)
147148
-> Map PN [LabeledPackageConstraint]
148149
-> Set PN
149150
-> Progress String String (Assignment, RevDepMap)
150-
solve' sc toolchains pkgConfigDb idx pprefs gcs pns =
151+
solve' sc cinfo pkgConfigDb idx pprefs gcs pns =
151152
toProgress $ retry (runSolver printFullLog sc) createErrorMsg
152153
where
153154
runSolver :: Bool -> SolverConfig
154155
-> RetryLog String SolverFailure (Assignment, RevDepMap)
155156
runSolver keepLog sc' =
156157
displayLogMessages keepLog $
157-
solve sc' toolchains pkgConfigDb idx pprefs gcs pns
158+
solve sc' cinfo pkgConfigDb idx pprefs gcs pns
158159

159160
createErrorMsg :: SolverFailure
160161
-> RetryLog String String (Assignment, RevDepMap)

cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,6 @@ convPIs
6666
-> Index
6767
convPIs toolchains' constraints sip strfl solveExes iidx sidx =
6868
mkIndex $ convIPI' sip iidx ++ convSPI' toolchains' constraints strfl solveExes sidx
69-
-- [ foldMap
70-
-- (\(stage, idx) -> convIPI' stage sip idx)
71-
-- (tabulate iidx)
72-
-- , foldMap
73-
-- (\(stage, Toolchain{toolchainCompiler = comp, toolchainPlatform = Platform arch os}) ->
74-
-- convSPI' stage os arch comp constraints strfl solveExes sidx
75-
-- )
76-
-- toolchains'
77-
-- ]
7869

7970
-- | Convert a Cabal installed package index to the simpler,
8071
-- more uniform index format of the solver.
@@ -173,6 +164,11 @@ convIPId stage dr comp idx ipid =
173164

174165
-- | Convert a cabal-install source package index to the simpler,
175166
-- more uniform index format of the solver.
167+
-- NOTE: The package description of source package can depent on the platform
168+
-- and compiler version. Here we decide to convert a single source package
169+
-- into multiple index entries, one for each stage, where the conditionals are
170+
-- resolved. This choice might incour in high memory consumption and it might
171+
-- be worth looking for a different approach.
176172
convSPI'
177173
:: Staged Toolchain
178174
-> Map PN [LabeledPackageConstraint]

cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import Distribution.Solver.Types.Stage (Staged)
4949
#ifdef DEBUG_TRACETREE
5050
import qualified Distribution.Solver.Modular.ConflictSet as CS
5151
import qualified Distribution.Solver.Modular.WeightedPSQ as W
52-
import qualified Distribution.Deprecated.Text as T
52+
import Distribution.Solver.Modular.Version (showVer)
5353

5454
import Debug.Trace.Tree (gtraceJson)
5555
import Debug.Trace.Tree.Simple
@@ -211,7 +211,7 @@ instance GSimpleTree (Tree d c) where
211211

212212
-- Show package choice
213213
goP :: QPN -> POption -> Tree d c -> (String, SimpleTree)
214-
goP _ (POption (I ver _loc) Nothing) subtree = (T.display ver, go subtree)
214+
goP _ (POption (I _stage ver _loc) Nothing) subtree = (showVer ver, go subtree)
215215
goP (Q _ pn) (POption _ (Just pp)) subtree = (showQPN (Q pp pn), go subtree)
216216

217217
-- Show flag or stanza choice

cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs

Lines changed: 97 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import Distribution.Solver.Types.PackagePath
3535
import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb, pkgConfigPkgIsPresent)
3636
import Distribution.Types.LibraryName
3737
import Distribution.Types.PkgconfigVersionRange
38-
import Distribution.Solver.Types.Stage (Staged (..), Stage)
38+
import Distribution.Solver.Types.Stage (Staged (..), Stage (..))
3939

4040
-- In practice, most constraints are implication constraints (IF we have made
4141
-- a number of choices, THEN we also have to ensure that). We call constraints
@@ -91,7 +91,7 @@ import Distribution.Solver.Types.Stage (Staged (..), Stage)
9191
data ValidateState = VS {
9292
supportedExt :: Stage -> Extension -> Bool,
9393
supportedLang :: Stage -> Language -> Bool,
94-
presentPkgs :: Maybe (PkgconfigName -> PkgconfigVersionRange -> Bool),
94+
presentPkgs :: Stage -> Maybe (PkgconfigName -> PkgconfigVersionRange -> Bool),
9595
index :: Index,
9696

9797
-- Saved, scoped, dependencies. Every time 'validate' makes a package choice,
@@ -157,31 +157,48 @@ validate = go
157157
where
158158
go :: Tree d c -> Validate (Tree d c)
159159

160-
go (PChoice qpn rdm gr ts) = PChoice qpn rdm gr <$> W.traverseWithKey (\k -> goP qpn k . go) ts
161-
go (FChoice qfn rdm gr b m d ts) =
162-
do
163-
-- Flag choices may occur repeatedly (because they can introduce new constraints
164-
-- in various places). However, subsequent choices must be consistent. We thereby
165-
-- collapse repeated flag choice nodes.
166-
PA _ pfa _ <- asks pa -- obtain current flag-preassignment
167-
case M.lookup qfn pfa of
168-
Just rb -> -- flag has already been assigned; collapse choice to the correct branch
169-
case W.lookup rb ts of
170-
Just t -> goF qfn rb (go t)
171-
Nothing -> return $ Fail (varToConflictSet (F qfn)) (MalformedFlagChoice qfn)
172-
Nothing -> -- flag choice is new, follow both branches
173-
FChoice qfn rdm gr b m d <$> W.traverseWithKey (\k -> goF qfn k . go) ts
174-
go (SChoice qsn rdm gr b ts) =
175-
do
176-
-- Optional stanza choices are very similar to flag choices.
177-
PA _ _ psa <- asks pa -- obtain current stanza-preassignment
178-
case M.lookup qsn psa of
179-
Just rb -> -- stanza choice has already been made; collapse choice to the correct branch
180-
case W.lookup rb ts of
181-
Just t -> goS qsn rb (go t)
182-
Nothing -> return $ Fail (varToConflictSet (S qsn)) (MalformedStanzaChoice qsn)
183-
Nothing -> -- stanza choice is new, follow both branches
184-
SChoice qsn rdm gr b <$> W.traverseWithKey (\k -> goS qsn k . go) ts
160+
-- A package version node
161+
go (PChoice qpn rdm gr ts) =
162+
PChoice qpn rdm gr <$> W.traverseWithKey g ts
163+
where
164+
g :: POption -> Tree d c -> Validate (Tree d c)
165+
g popt = goP qpn popt . go
166+
167+
-- A package flag node
168+
go (FChoice qfn rdm gr b m d ts) = do
169+
-- Flag choices may occur repeatedly (because they can introduce new
170+
-- constraints in various places). However, subsequent choices must be
171+
-- consistent. We thereby collapse repeated flag choice nodes.
172+
PA _ pfa _ <- asks pa -- obtain current flag-preassignment
173+
case M.lookup qfn pfa of
174+
Just rb ->
175+
-- flag has already been assigned; collapse choice to the correct branch
176+
case W.lookup rb ts of
177+
Just t -> goF qfn rb (go t)
178+
Nothing -> return $ Fail (varToConflictSet (F qfn)) (MalformedFlagChoice qfn)
179+
Nothing ->
180+
-- flag choice is new, follow both branches
181+
FChoice qfn rdm gr b m d <$> W.traverseWithKey g ts
182+
where
183+
g :: Bool -> Tree d c -> Validate (Tree d c)
184+
g k = goF qfn k . go
185+
186+
-- A package stanza node
187+
go (SChoice qsn rdm gr b ts) = do
188+
-- Optional stanza choices are very similar to flag choices.
189+
PA _ _ psa <- asks pa -- obtain current stanza-preassignment
190+
case M.lookup qsn psa of
191+
Just rb ->
192+
-- stanza choice has already been made; collapse choice to the correct branch
193+
case W.lookup rb ts of
194+
Just t -> goS qsn rb (go t)
195+
Nothing -> return $ Fail (varToConflictSet (S qsn)) (MalformedStanzaChoice qsn)
196+
Nothing ->
197+
-- stanza choice is new, follow both branches
198+
SChoice qsn rdm gr b <$> W.traverseWithKey g ts
199+
where
200+
g :: Bool -> Tree d c -> Validate (Tree d c)
201+
g k = goS qsn k . go
185202

186203
-- We don't need to do anything for goal choices or failure nodes.
187204
go (GoalChoice rdm ts) = GoalChoice rdm <$> traverse go ts
@@ -190,7 +207,7 @@ validate = go
190207

191208
-- What to do for package nodes ...
192209
goP :: QPN -> POption -> Validate (Tree d c) -> Validate (Tree d c)
193-
goP qpn@(Q _pp pn) (POption i _) r = do
210+
goP qpn@(Q _pp pn) (POption i _mpp) r = do
194211
PA ppa pfa psa <- asks pa -- obtain current preassignment
195212
extSupported <- asks supportedExt -- obtain the supported extensions
196213
langSupported <- asks supportedLang -- obtain the supported languages
@@ -207,7 +224,7 @@ validate = go
207224
-- plus the dependency information we have for that instance
208225
let newactives = extractAllDeps pfa psa qdeps
209226
-- We now try to extend the partial assignment with the new active constraints.
210-
let mnppa = extend extSupported langSupported pkgPresent newactives
227+
let mnppa = extend ({- FIXME -} extSupported Host) ({- FIXME -} langSupported Host) ({- FIXME -} pkgPresent Host) newactives
211228
=<< extendWithPackageChoice (PI qpn i) ppa
212229
-- In case we continue, we save the scoped dependencies
213230
let nsvd = M.insert qpn qdeps svd
@@ -233,7 +250,7 @@ validate = go
233250

234251
-- What to do for flag nodes ...
235252
goF :: QFN -> Bool -> Validate (Tree d c) -> Validate (Tree d c)
236-
goF qfn@(FN qpn _f) b r = do
253+
goF qfn@(FN qpn _f) flagValue r = do
237254
PA ppa pfa psa <- asks pa -- obtain current preassignment
238255
extSupported <- asks supportedExt -- obtain the supported extensions
239256
langSupported <- asks supportedLang -- obtain the supported languages
@@ -249,13 +266,13 @@ validate = go
249266
-- correct scope.
250267
--
251268
-- Extend the flag assignment
252-
let npfa = M.insert qfn b pfa
269+
let npfa = M.insert qfn flagValue pfa
253270
-- We now try to get the new active dependencies we might learn about because
254271
-- we have chosen a new flag.
255-
let newactives = extractNewDeps (F qfn) b npfa psa qdeps
272+
let newactives = extractNewDeps (F qfn) flagValue npfa psa qdeps
256273
mNewRequiredComps = extendRequiredComponents qpn aComps rComps newactives
257274
-- As in the package case, we try to extend the partial assignment.
258-
let mnppa = extend extSupported langSupported pkgPresent newactives ppa
275+
let mnppa = extend ({- FIXME -} extSupported Host) ({- FIXME -} langSupported Host) ({- FIXME -} pkgPresent Host) newactives ppa
259276
case liftM2 (,) mnppa mNewRequiredComps of
260277
Left (c, fr) -> return (Fail c fr) -- inconsistency found
261278
Right (nppa, rComps') ->
@@ -285,7 +302,7 @@ validate = go
285302
let newactives = extractNewDeps (S qsn) b pfa npsa qdeps
286303
mNewRequiredComps = extendRequiredComponents qpn aComps rComps newactives
287304
-- As in the package case, we try to extend the partial assignment.
288-
let mnppa = extend extSupported langSupported pkgPresent newactives ppa
305+
let mnppa = extend ({- FIXME -} extSupported Host) ({- FIXME -} langSupported Host) ({- FIXME -} pkgPresent Host) newactives ppa
289306
case liftM2 (,) mnppa mNewRequiredComps of
290307
Left (c, fr) -> return (Fail c fr) -- inconsistency found
291308
Right (nppa, rComps') ->
@@ -329,7 +346,14 @@ checkComponentsInNewPackage required qpn providedComps =
329346
-- | We try to extract as many concrete dependencies from the given flagged
330347
-- dependencies as possible. We make use of all the flag knowledge we have
331348
-- already acquired.
332-
extractAllDeps :: FAssignment -> SAssignment -> FlaggedDeps QPN -> [LDep QPN]
349+
extractAllDeps
350+
:: FAssignment
351+
-- ^ current flag assignments
352+
-> SAssignment
353+
-- ^ current stanza assignments
354+
-> FlaggedDeps QPN
355+
-- ^ conditional dependencies
356+
-> [LDep QPN]
333357
extractAllDeps fa sa deps = do
334358
d <- deps
335359
case d of
@@ -346,22 +370,38 @@ extractAllDeps fa sa deps = do
346370
-- | We try to find new dependencies that become available due to the given
347371
-- flag or stanza choice. We therefore look for the choice in question, and then call
348372
-- 'extractAllDeps' for everything underneath.
349-
extractNewDeps :: Var QPN -> Bool -> FAssignment -> SAssignment -> FlaggedDeps QPN -> [LDep QPN]
373+
extractNewDeps
374+
:: Var QPN
375+
-- ^ the variable (package, flag or stanza)
376+
-> Bool
377+
-- ^ the variable value
378+
-> FAssignment
379+
-- ^ current flag assignments
380+
-> SAssignment
381+
-- ^ current stanza assignments
382+
-> FlaggedDeps QPN
383+
-- ^ conditional dependencies
384+
-> [LDep QPN]
385+
-- ^ dependencies with a reason
350386
extractNewDeps v b fa sa = go
351387
where
352388
go :: FlaggedDeps QPN -> [LDep QPN]
353389
go deps = do
354390
d <- deps
355391
case d of
356392
Simple _ _ -> mzero
357-
Flagged qfn' _ td fd
358-
| v == F qfn' -> if b then extractAllDeps fa sa td else extractAllDeps fa sa fd
393+
Flagged qfn' _finfo td fd
394+
| v == F qfn' -> if b
395+
then extractAllDeps fa sa td
396+
else extractAllDeps fa sa fd
359397
| otherwise -> case M.lookup qfn' fa of
360398
Nothing -> mzero
361399
Just True -> go td
362400
Just False -> go fd
363401
Stanza qsn' td
364-
| v == S qsn' -> if b then extractAllDeps fa sa td else []
402+
| v == S qsn' -> if b
403+
then extractAllDeps fa sa td
404+
else []
365405
| otherwise -> case M.lookup qsn' sa of
366406
Nothing -> mzero
367407
Just True -> go td
@@ -565,17 +605,27 @@ extendRequiredComponents eqpn available = foldM extendSingle
565605

566606

567607
-- | Interface.
568-
validateTree :: Staged CompilerInfo -> Maybe PkgConfigDb -> Index -> Tree d c -> Tree d c
569-
validateTree cinfo pkgConfigDb idx t = runValidate (validate t) VS {
570-
supportedExt = -- if compiler has no list of extensions, we assume everything is supported
571-
let extSet = fmap (fmap S.fromList . compilerInfoExtensions) cinfo
572-
in maybe (const True) (flip S.member) . getStage extSet
573-
, supportedLang = let langSet = fmap (fmap S.fromList . compilerInfoLanguages) cinfo
574-
in maybe (const True) (flip S.member) . getStage langSet
575-
, presentPkgs = pkgConfigPkgIsPresent <$> pkgConfigDb
608+
validateTree
609+
:: Staged CompilerInfo
610+
-> Staged (Maybe PkgConfigDb)
611+
-> Index
612+
-> Tree d c
613+
-> Tree d c
614+
validateTree cinfo pkgConfigDb idx t = runValidate (validate t) VS
615+
{ -- if compiler has no list of extensions, we assume everything is supported
616+
supportedExt = maybe (const True) (flip S.member) . getStage extSet
617+
, -- if compiler has no list of extensions, we assume everything is supported
618+
supportedLang = maybe (const True) (flip S.member) . getStage langSet
619+
, presentPkgs = fmap pkgConfigPkgIsPresent . getStage pkgConfigDb
576620
, index = idx
577621
, saved = M.empty
578622
, pa = PA M.empty M.empty M.empty
579623
, availableComponents = M.empty
580624
, requiredComponents = M.empty
581625
}
626+
where
627+
extSet :: Staged (Maybe (S.Set Extension))
628+
extSet = fmap (fmap S.fromList . compilerInfoExtensions) cinfo
629+
630+
langSet :: Staged (Maybe (S.Set Language))
631+
langSet = fmap (fmap S.fromList . compilerInfoLanguages) cinfo

cabal-install-solver/src/Distribution/Solver/Modular/WeightedPSQ.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,15 @@ mapWeightsWithKey :: Ord w2
6666
=> (k -> w1 -> w2)
6767
-> WeightedPSQ w1 k v
6868
-> WeightedPSQ w2 k v
69-
mapWeightsWithKey f (WeightedPSQ xs) = fromList $
70-
L.map (\ (w, k, v) -> (f k w, k, v)) xs
69+
mapWeightsWithKey f (WeightedPSQ xs) =
70+
fromList $ L.map (\ (w, k, v) -> (f k w, k, v)) xs
7171

7272
-- | /O(N)/. Update the values.
73-
mapWithKey :: (k -> v1 -> v2) -> WeightedPSQ w k v1 -> WeightedPSQ w k v2
74-
mapWithKey f (WeightedPSQ xs) = WeightedPSQ $
75-
L.map (\ (w, k, v) -> (w, k, f k v)) xs
73+
mapWithKey :: (k -> v1 -> v2)
74+
-> WeightedPSQ w k v1
75+
-> WeightedPSQ w k v2
76+
mapWithKey f (WeightedPSQ xs) =
77+
WeightedPSQ $ L.map (\ (w, k, v) -> (w, k, f k v)) xs
7678

7779
-- | /O(N)/. Traverse and update values in some applicative functor.
7880
traverseWithKey

0 commit comments

Comments
 (0)