Commit e7a50ba0 authored by Mikhail Glushenkov's avatar Mikhail Glushenkov
Browse files

Merge pull request #3399 from edsko/pr/simplifyGoalChoice

Simplify `GoalChoice`
parents 1dd14ccb cbfd24e2
......@@ -111,8 +111,9 @@ build = ana go
-- it from the queue of open goals.
go bs@(BS { rdeps = rds, open = gs, next = Goals })
| P.null gs = DoneF rds
| otherwise = GoalChoiceF (P.mapWithKey (\ g (_sc, gs') -> bs { next = OneGoal g, open = gs' })
(P.splits gs))
| otherwise = GoalChoiceF $ P.mapKeys close
$ P.mapWithKey (\ g (_sc, gs') -> bs { next = OneGoal g, open = gs' })
$ P.splits gs
-- If we have already picked a goal, then the choice depends on the kind
-- of goal.
......
......@@ -90,7 +90,7 @@ exploreLog enableBj = cata go
go (GoalChoiceF ts) a =
P.casePSQ ts
(failWith (Failure CS.empty EmptyGoalChoice) CS.empty) -- empty goal choice is an internal error
(\ k v _xs -> continueWith (Next (close k)) (v a)) -- commit to the first goal choice
(\ k v _xs -> continueWith (Next k) (v a)) -- commit to the first goal choice
-- | Build a conflict set corresponding to the (virtual) option not to
-- choose a solution for a goal at all.
......
......@@ -295,9 +295,9 @@ preferBaseGoalChoice = trav go
go (GoalChoiceF xs) = GoalChoiceF (P.preferByKeys isBase xs)
go x = x
isBase :: OpenGoal comp -> Bool
isBase (OpenGoal (Simple (Dep (Q _pp pn) _) _) _) | unPN pn == "base" = True
isBase _ = False
isBase :: Goal QPN -> Bool
isBase (Goal (P (Q _pp pn)) _) = unPN pn == "base"
isBase _ = False
-- | Deal with setup dependencies after regular dependencies, so that we can
-- will link setup depencencies against package dependencies when possible
......@@ -307,9 +307,9 @@ deferSetupChoices = trav go
go (GoalChoiceF xs) = GoalChoiceF (P.preferByKeys noSetup xs)
go x = x
noSetup :: OpenGoal comp -> Bool
noSetup (OpenGoal (Simple (Dep (Q (PP _ns (Setup _)) _) _) _) _) = False
noSetup _ = True
noSetup :: Goal QPN -> Bool
noSetup (Goal (P (Q (PP _ns (Setup _)) _)) _) = False
noSetup _ = True
-- | Transformation that tries to avoid making weak flag choices early.
-- Weak flags are trivial flags (not influencing dependencies) or such
......
......@@ -30,21 +30,49 @@ import Distribution.Solver.Types.ConstraintSource
-- | Type of the search tree. Inlining the choice nodes for now.
data Tree a =
PChoice QPN a (PSQ POption (Tree a))
| FChoice QFN a Bool Bool (PSQ Bool (Tree a)) -- Bool indicates whether it's weak/trivial, second Bool whether it's manual
| SChoice QSN a Bool (PSQ Bool (Tree a)) -- Bool indicates whether it's trivial
| GoalChoice (PSQ (OpenGoal ()) (Tree a)) -- PSQ should never be empty
| Done RevDepMap
| Fail (ConflictSet QPN) FailReason
-- | Choose a version for a package (or choose to link)
PChoice QPN a (PSQ POption (Tree a))
-- | Choose a value for a flag
--
-- The first Bool indicates whether it's weak/trivial,
-- the second Bool whether it's manual.
--
-- A choice is called trivial if it clearly does not matter. The
-- special case of triviality we actually consider is if there are no new
-- dependencies introduced by this node.
--
-- A (flag) choice is called weak if we do want to defer it. This is the
-- case for flags that should be implied by what's currently installed on
-- the system, as opposed to flags that are used to explicitly enable or
-- disable some functionality.
| FChoice QFN a Bool Bool (PSQ Bool (Tree a))
-- | Choose whether or not to enable a stanza
--
-- The Bool indicates whether it's trivial (see 'FChoice' for a discussion
-- of triviality).
| SChoice QSN a Bool (PSQ Bool (Tree a))
-- | Choose which choice to make next
--
-- Invariants:
--
-- * PSQ should never be empty
-- * For each choice we additionally record the 'QGoalReason' why we are
-- introducing that goal into tree. Note that most of the time we are
-- working with @Tree QGoalReason@; in that case, we must have the
-- invariant that the 'QGoalReason' cached in the 'PChoice', 'FChoice'
-- or 'SChoice' directly below a 'GoalChoice' node must equal the reason
-- recorded on that 'GoalChoice' node.
| GoalChoice (PSQ (Goal QPN) (Tree a))
-- | We're done -- we found a solution!
| Done RevDepMap
-- | We failed to find a solution in this path through the tree
| Fail (ConflictSet QPN) FailReason
deriving (Eq, Show, Functor)
-- Above, a choice is called trivial if it clearly does not matter. The
-- special case of triviality we actually consider is if there are no new
-- dependencies introduced by this node.
--
-- A (flag) choice is called weak if we do want to defer it. This is the
-- case for flags that should be implied by what's currently installed on
-- the system, as opposed to flags that are used to explicitly enable or
-- disable some functionality.
-- | A package option is a package instance with an optional linking annotation
--
......@@ -87,10 +115,10 @@ data FailReason = InconsistentInitialConstraints
-- | Functor for the tree type.
data TreeF a b =
PChoiceF QPN a (PSQ POption b)
| FChoiceF QFN a Bool Bool (PSQ Bool b)
| SChoiceF QSN a Bool (PSQ Bool b)
| GoalChoiceF (PSQ (OpenGoal ()) b)
PChoiceF QPN a (PSQ POption b)
| FChoiceF QFN a Bool Bool (PSQ Bool b)
| SChoiceF QSN a Bool (PSQ Bool b)
| GoalChoiceF (PSQ (Goal QPN) b)
| DoneF RevDepMap
| FailF (ConflictSet QPN) FailReason
deriving (Functor, Foldable, Traversable)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment