Skip to content

Commit

Permalink
Merge pull request #5918 from grayjay/version-and-goal-conflicts
Browse files Browse the repository at this point in the history
Solver: Pair conflict set variables with more information about conflicts (issue #4805).
  • Loading branch information
grayjay authored Jan 18, 2020
2 parents 0d4ee7b + ac84fa2 commit f6e7cdd
Show file tree
Hide file tree
Showing 29 changed files with 934 additions and 173 deletions.
17 changes: 17 additions & 0 deletions Cabal/doc/nix-local-build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,23 @@ Most users generally won't need these.
The command line variant of this field is
``--(no-)count-conflicts``.

.. cfg-field:: fine-grained-conflicts: boolean
--fine-grained-conflicts
--no-fine-grained-conflicts
:synopsis: Skip a version of a package if it does not resolve any conflicts
encountered in the last version (solver optimization).

:default: True

When enabled, the solver will skip a version of a package if it does not
resolve any of the conflicts encountered in the last version of that
package. For example, if ``foo-1.2`` depended on ``bar``, and the solver
couldn't find consistent versions for ``bar``'s dependencies, then the
solver would skip ``foo-1.1`` if it also depended on ``bar``.

The command line variant of this field is
``--(no-)fine-grained-conflicts``.

.. cfg-field:: minimize-conflict-set: boolean
--minimize-conflict-set
--no-minimize-conflict-set
Expand Down
1 change: 1 addition & 0 deletions cabal-install/Distribution/Client/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ instance Semigroup SavedConfig where
installMaxBackjumps = combine installMaxBackjumps,
installReorderGoals = combine installReorderGoals,
installCountConflicts = combine installCountConflicts,
installFineGrainedConflicts = combine installFineGrainedConflicts,
installMinimizeConflictSet = combine installMinimizeConflictSet,
installIndependentGoals = combine installIndependentGoals,
installShadowPkgs = combine installShadowPkgs,
Expand Down
20 changes: 16 additions & 4 deletions cabal-install/Distribution/Client/Dependency.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module Distribution.Client.Dependency (
setPreferenceDefault,
setReorderGoals,
setCountConflicts,
setFineGrainedConflicts,
setMinimizeConflictSet,
setIndependentGoals,
setAvoidReinstalls,
Expand Down Expand Up @@ -159,6 +160,7 @@ data DepResolverParams = DepResolverParams {
depResolverSourcePkgIndex :: PackageIndex.PackageIndex UnresolvedSourcePackage,
depResolverReorderGoals :: ReorderGoals,
depResolverCountConflicts :: CountConflicts,
depResolverFineGrainedConflicts :: FineGrainedConflicts,
depResolverMinimizeConflictSet :: MinimizeConflictSet,
depResolverIndependentGoals :: IndependentGoals,
depResolverAvoidReinstalls :: AvoidReinstalls,
Expand Down Expand Up @@ -197,6 +199,7 @@ showDepResolverParams p =
++ "\nstrategy: " ++ show (depResolverPreferenceDefault p)
++ "\nreorder goals: " ++ show (asBool (depResolverReorderGoals p))
++ "\ncount conflicts: " ++ show (asBool (depResolverCountConflicts p))
++ "\nfine grained conflicts: " ++ show (asBool (depResolverFineGrainedConflicts p))
++ "\nminimize conflict set: " ++ show (asBool (depResolverMinimizeConflictSet p))
++ "\nindependent goals: " ++ show (asBool (depResolverIndependentGoals p))
++ "\navoid reinstalls: " ++ show (asBool (depResolverAvoidReinstalls p))
Expand Down Expand Up @@ -254,6 +257,7 @@ basicDepResolverParams installedPkgIndex sourcePkgIndex =
depResolverSourcePkgIndex = sourcePkgIndex,
depResolverReorderGoals = ReorderGoals False,
depResolverCountConflicts = CountConflicts True,
depResolverFineGrainedConflicts = FineGrainedConflicts True,
depResolverMinimizeConflictSet = MinimizeConflictSet False,
depResolverIndependentGoals = IndependentGoals False,
depResolverAvoidReinstalls = AvoidReinstalls False,
Expand Down Expand Up @@ -310,6 +314,12 @@ setCountConflicts count params =
depResolverCountConflicts = count
}

setFineGrainedConflicts :: FineGrainedConflicts -> DepResolverParams -> DepResolverParams
setFineGrainedConflicts fineGrained params =
params {
depResolverFineGrainedConflicts = fineGrained
}

setMinimizeConflictSet :: MinimizeConflictSet -> DepResolverParams -> DepResolverParams
setMinimizeConflictSet minimize params =
params {
Expand Down Expand Up @@ -755,7 +765,8 @@ resolveDependencies platform comp pkgConfigDB solver params =

Step (showDepResolverParams finalparams)
$ fmap (validateSolverResult platform comp indGoals)
$ runSolver solver (SolverConfig reordGoals cntConflicts minimize indGoals noReinstalls
$ runSolver solver (SolverConfig reordGoals cntConflicts fineGrained minimize
indGoals noReinstalls
shadowing strFlags allowBootLibs onlyConstrained_ maxBkjumps enableBj
solveExes order verbosity (PruneAfterFirstSuccess False))
platform comp installedPkgIndex sourcePkgIndex
Expand All @@ -769,6 +780,7 @@ resolveDependencies platform comp pkgConfigDB solver params =
sourcePkgIndex
reordGoals
cntConflicts
fineGrained
minimize
indGoals
noReinstalls
Expand Down Expand Up @@ -1015,9 +1027,9 @@ resolveWithoutDependencies :: DepResolverParams
-> Either [ResolveNoDepsError] [UnresolvedSourcePackage]
resolveWithoutDependencies (DepResolverParams targets constraints
prefs defpref installedPkgIndex sourcePkgIndex
_reorderGoals _countConflicts _minimizeConflictSet
_indGoals _avoidReinstalls _shadowing _strFlags
_maxBjumps _enableBj _solveExes
_reorderGoals _countConflicts _fineGrained
_minimizeConflictSet _indGoals _avoidReinstalls
_shadowing _strFlags _maxBjumps _enableBj _solveExes
_allowBootLibInstalls _onlyConstrained _order _verbosity) =
collectEithers $ map selectPackage (Set.toList targets)
where
Expand Down
3 changes: 3 additions & 0 deletions cabal-install/Distribution/Client/Fetch.hs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ planPackages verbosity comp platform fetchFlags

. setCountConflicts countConflicts

. setFineGrainedConflicts fineGrainedConflicts

. setMinimizeConflictSet minimizeConflictSet

. setShadowPkgs shadowPkgs
Expand Down Expand Up @@ -199,6 +201,7 @@ planPackages verbosity comp platform fetchFlags

reorderGoals = fromFlag (fetchReorderGoals fetchFlags)
countConflicts = fromFlag (fetchCountConflicts fetchFlags)
fineGrainedConflicts = fromFlag (fetchFineGrainedConflicts fetchFlags)
minimizeConflictSet = fromFlag (fetchMinimizeConflictSet fetchFlags)
independentGoals = fromFlag (fetchIndependentGoals fetchFlags)
shadowPkgs = fromFlag (fetchShadowPkgs fetchFlags)
Expand Down
3 changes: 3 additions & 0 deletions cabal-install/Distribution/Client/Freeze.hs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ planPackages verbosity comp platform mSandboxPkgInfo freezeFlags

. setCountConflicts countConflicts

. setFineGrainedConflicts fineGrainedConflicts

. setMinimizeConflictSet minimizeConflictSet

. setShadowPkgs shadowPkgs
Expand Down Expand Up @@ -207,6 +209,7 @@ planPackages verbosity comp platform mSandboxPkgInfo freezeFlags

reorderGoals = fromFlag (freezeReorderGoals freezeFlags)
countConflicts = fromFlag (freezeCountConflicts freezeFlags)
fineGrainedConflicts = fromFlag (freezeFineGrainedConflicts freezeFlags)
minimizeConflictSet = fromFlag (freezeMinimizeConflictSet freezeFlags)
independentGoals = fromFlag (freezeIndependentGoals freezeFlags)
shadowPkgs = fromFlag (freezeShadowPkgs freezeFlags)
Expand Down
3 changes: 3 additions & 0 deletions cabal-install/Distribution/Client/Install.hs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ planPackages verbosity comp platform mSandboxPkgInfo solver

. setCountConflicts countConflicts

. setFineGrainedConflicts fineGrainedConflicts

. setMinimizeConflictSet minimizeConflictSet

. setAvoidReinstalls avoidReinstalls
Expand Down Expand Up @@ -463,6 +465,7 @@ planPackages verbosity comp platform mSandboxPkgInfo solver
fromFlag (installReinstall installFlags)
reorderGoals = fromFlag (installReorderGoals installFlags)
countConflicts = fromFlag (installCountConflicts installFlags)
fineGrainedConflicts = fromFlag (installFineGrainedConflicts installFlags)
minimizeConflictSet = fromFlag (installMinimizeConflictSet installFlags)
independentGoals = fromFlag (installIndependentGoals installFlags)
avoidReinstalls = fromFlag (installAvoidReinstalls installFlags)
Expand Down
2 changes: 2 additions & 0 deletions cabal-install/Distribution/Client/ProjectConfig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ resolveSolverSettings ProjectConfig{
| otherwise -> Just n
solverSettingReorderGoals = fromFlag projectConfigReorderGoals
solverSettingCountConflicts = fromFlag projectConfigCountConflicts
solverSettingFineGrainedConflicts = fromFlag projectConfigFineGrainedConflicts
solverSettingMinimizeConflictSet = fromFlag projectConfigMinimizeConflictSet
solverSettingStrongFlags = fromFlag projectConfigStrongFlags
solverSettingAllowBootLibInstalls = fromFlag projectConfigAllowBootLibInstalls
Expand All @@ -271,6 +272,7 @@ resolveSolverSettings ProjectConfig{
projectConfigMaxBackjumps = Flag defaultMaxBackjumps,
projectConfigReorderGoals = Flag (ReorderGoals False),
projectConfigCountConflicts = Flag (CountConflicts True),
projectConfigFineGrainedConflicts = Flag (FineGrainedConflicts True),
projectConfigMinimizeConflictSet = Flag (MinimizeConflictSet False),
projectConfigStrongFlags = Flag (StrongFlags False),
projectConfigAllowBootLibInstalls = Flag (AllowBootLibInstalls False),
Expand Down
7 changes: 5 additions & 2 deletions cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ convertLegacyAllPackageFlags globalFlags configFlags
--installUpgradeDeps = projectConfigUpgradeDeps,
installReorderGoals = projectConfigReorderGoals,
installCountConflicts = projectConfigCountConflicts,
installFineGrainedConflicts = projectConfigFineGrainedConflicts,
installMinimizeConflictSet = projectConfigMinimizeConflictSet,
installPerComponent = projectConfigPerComponent,
installIndependentGoals = projectConfigIndependentGoals,
Expand Down Expand Up @@ -611,6 +612,7 @@ convertToLegacySharedConfig
installUpgradeDeps = mempty, --projectConfigUpgradeDeps,
installReorderGoals = projectConfigReorderGoals,
installCountConflicts = projectConfigCountConflicts,
installFineGrainedConflicts = projectConfigFineGrainedConflicts,
installMinimizeConflictSet = projectConfigMinimizeConflictSet,
installIndependentGoals = projectConfigIndependentGoals,
installShadowPkgs = mempty, --projectConfigShadowPkgs,
Expand Down Expand Up @@ -1004,8 +1006,9 @@ legacySharedConfigFieldDescrs =
, "one-shot", "jobs", "keep-going", "offline", "per-component"
-- solver flags:
, "max-backjumps", "reorder-goals", "count-conflicts"
, "minimize-conflict-set", "independent-goals"
, "strong-flags" , "allow-boot-library-installs", "reject-unconstrained-dependencies", "index-state"
, "fine-grained-conflicts" , "minimize-conflict-set", "independent-goals"
, "strong-flags" , "allow-boot-library-installs"
, "reject-unconstrained-dependencies", "index-state"
]
. commandOptionsToFields
) (installOptions ParseArgs)
Expand Down
2 changes: 2 additions & 0 deletions cabal-install/Distribution/Client/ProjectConfig/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ data ProjectConfigShared
projectConfigMaxBackjumps :: Flag Int,
projectConfigReorderGoals :: Flag ReorderGoals,
projectConfigCountConflicts :: Flag CountConflicts,
projectConfigFineGrainedConflicts :: Flag FineGrainedConflicts,
projectConfigMinimizeConflictSet :: Flag MinimizeConflictSet,
projectConfigStrongFlags :: Flag StrongFlags,
projectConfigAllowBootLibInstalls :: Flag AllowBootLibInstalls,
Expand Down Expand Up @@ -400,6 +401,7 @@ data SolverSettings
solverSettingMaxBackjumps :: Maybe Int,
solverSettingReorderGoals :: ReorderGoals,
solverSettingCountConflicts :: CountConflicts,
solverSettingFineGrainedConflicts :: FineGrainedConflicts,
solverSettingMinimizeConflictSet :: MinimizeConflictSet,
solverSettingStrongFlags :: StrongFlags,
solverSettingAllowBootLibInstalls :: AllowBootLibInstalls,
Expand Down
2 changes: 2 additions & 0 deletions cabal-install/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,8 @@ planPackages verbosity comp platform solver SolverSettings{..}

. setCountConflicts solverSettingCountConflicts

. setFineGrainedConflicts solverSettingFineGrainedConflicts

. setMinimizeConflictSet solverSettingMinimizeConflictSet

--TODO: [required eventually] should only be configurable for
Expand Down
19 changes: 17 additions & 2 deletions cabal-install/Distribution/Client/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,7 @@ data FetchFlags = FetchFlags {
fetchMaxBackjumps :: Flag Int,
fetchReorderGoals :: Flag ReorderGoals,
fetchCountConflicts :: Flag CountConflicts,
fetchFineGrainedConflicts :: Flag FineGrainedConflicts,
fetchMinimizeConflictSet :: Flag MinimizeConflictSet,
fetchIndependentGoals :: Flag IndependentGoals,
fetchShadowPkgs :: Flag ShadowPkgs,
Expand All @@ -1023,6 +1024,7 @@ defaultFetchFlags = FetchFlags {
fetchMaxBackjumps = Flag defaultMaxBackjumps,
fetchReorderGoals = Flag (ReorderGoals False),
fetchCountConflicts = Flag (CountConflicts True),
fetchFineGrainedConflicts = Flag (FineGrainedConflicts True),
fetchMinimizeConflictSet = Flag (MinimizeConflictSet False),
fetchIndependentGoals = Flag (IndependentGoals False),
fetchShadowPkgs = Flag (ShadowPkgs False),
Expand Down Expand Up @@ -1085,6 +1087,7 @@ fetchCommand = CommandUI {
fetchMaxBackjumps (\v flags -> flags { fetchMaxBackjumps = v })
fetchReorderGoals (\v flags -> flags { fetchReorderGoals = v })
fetchCountConflicts (\v flags -> flags { fetchCountConflicts = v })
fetchFineGrainedConflicts (\v flags -> flags { fetchFineGrainedConflicts = v })
fetchMinimizeConflictSet (\v flags -> flags { fetchMinimizeConflictSet = v })
fetchIndependentGoals (\v flags -> flags { fetchIndependentGoals = v })
fetchShadowPkgs (\v flags -> flags { fetchShadowPkgs = v })
Expand All @@ -1106,6 +1109,7 @@ data FreezeFlags = FreezeFlags {
freezeMaxBackjumps :: Flag Int,
freezeReorderGoals :: Flag ReorderGoals,
freezeCountConflicts :: Flag CountConflicts,
freezeFineGrainedConflicts :: Flag FineGrainedConflicts,
freezeMinimizeConflictSet :: Flag MinimizeConflictSet,
freezeIndependentGoals :: Flag IndependentGoals,
freezeShadowPkgs :: Flag ShadowPkgs,
Expand All @@ -1124,6 +1128,7 @@ defaultFreezeFlags = FreezeFlags {
freezeMaxBackjumps = Flag defaultMaxBackjumps,
freezeReorderGoals = Flag (ReorderGoals False),
freezeCountConflicts = Flag (CountConflicts True),
freezeFineGrainedConflicts = Flag (FineGrainedConflicts True),
freezeMinimizeConflictSet = Flag (MinimizeConflictSet False),
freezeIndependentGoals = Flag (IndependentGoals False),
freezeShadowPkgs = Flag (ShadowPkgs False),
Expand Down Expand Up @@ -1177,6 +1182,7 @@ freezeCommand = CommandUI {
freezeMaxBackjumps (\v flags -> flags { freezeMaxBackjumps = v })
freezeReorderGoals (\v flags -> flags { freezeReorderGoals = v })
freezeCountConflicts (\v flags -> flags { freezeCountConflicts = v })
freezeFineGrainedConflicts (\v flags -> flags { freezeFineGrainedConflicts = v })
freezeMinimizeConflictSet (\v flags -> flags { freezeMinimizeConflictSet = v })
freezeIndependentGoals (\v flags -> flags { freezeIndependentGoals = v })
freezeShadowPkgs (\v flags -> flags { freezeShadowPkgs = v })
Expand Down Expand Up @@ -1749,6 +1755,7 @@ data InstallFlags = InstallFlags {
installMaxBackjumps :: Flag Int,
installReorderGoals :: Flag ReorderGoals,
installCountConflicts :: Flag CountConflicts,
installFineGrainedConflicts :: Flag FineGrainedConflicts,
installMinimizeConflictSet :: Flag MinimizeConflictSet,
installIndependentGoals :: Flag IndependentGoals,
installShadowPkgs :: Flag ShadowPkgs,
Expand Down Expand Up @@ -1798,6 +1805,7 @@ defaultInstallFlags = InstallFlags {
installMaxBackjumps = Flag defaultMaxBackjumps,
installReorderGoals = Flag (ReorderGoals False),
installCountConflicts = Flag (CountConflicts True),
installFineGrainedConflicts = Flag (FineGrainedConflicts True),
installMinimizeConflictSet = Flag (MinimizeConflictSet False),
installIndependentGoals= Flag (IndependentGoals False),
installShadowPkgs = Flag (ShadowPkgs False),
Expand Down Expand Up @@ -2028,6 +2036,7 @@ installOptions showOrParseArgs =
installMaxBackjumps (\v flags -> flags { installMaxBackjumps = v })
installReorderGoals (\v flags -> flags { installReorderGoals = v })
installCountConflicts (\v flags -> flags { installCountConflicts = v })
installFineGrainedConflicts (\v flags -> flags { installFineGrainedConflicts = v })
installMinimizeConflictSet (\v flags -> flags { installMinimizeConflictSet = v })
installIndependentGoals (\v flags -> flags { installIndependentGoals = v })
installShadowPkgs (\v flags -> flags { installShadowPkgs = v })
Expand Down Expand Up @@ -2860,6 +2869,7 @@ optionSolverFlags :: ShowOrParseArgs
-> (flags -> Flag Int ) -> (Flag Int -> flags -> flags)
-> (flags -> Flag ReorderGoals) -> (Flag ReorderGoals -> flags -> flags)
-> (flags -> Flag CountConflicts) -> (Flag CountConflicts -> flags -> flags)
-> (flags -> Flag FineGrainedConflicts) -> (Flag FineGrainedConflicts -> flags -> flags)
-> (flags -> Flag MinimizeConflictSet) -> (Flag MinimizeConflictSet -> flags -> flags)
-> (flags -> Flag IndependentGoals) -> (Flag IndependentGoals -> flags -> flags)
-> (flags -> Flag ShadowPkgs) -> (Flag ShadowPkgs -> flags -> flags)
Expand All @@ -2868,8 +2878,8 @@ optionSolverFlags :: ShowOrParseArgs
-> (flags -> Flag OnlyConstrained) -> (Flag OnlyConstrained -> flags -> flags)
-> [OptionField flags]
optionSolverFlags showOrParseArgs getmbj setmbj getrg setrg getcc setcc
getmc setmc getig setig getsip setsip getstrfl setstrfl
getib setib getoc setoc =
getfgc setfgc getmc setmc getig setig getsip setsip
getstrfl setstrfl getib setib getoc setoc =
[ option [] ["max-backjumps"]
("Maximum number of backjumps allowed while solving (default: " ++ show defaultMaxBackjumps ++ "). Use a negative number to enable unlimited backtracking. Use 0 to disable backtracking completely.")
getmbj setmbj
Expand All @@ -2885,6 +2895,11 @@ optionSolverFlags showOrParseArgs getmbj setmbj getrg setrg getcc setcc
(fmap asBool . getcc)
(setcc . fmap CountConflicts)
(yesNoOpt showOrParseArgs)
, option [] ["fine-grained-conflicts"]
"Skip a version of a package if it does not resolve the conflicts encountered in the last version, as a solver optimization (default)."
(fmap asBool . getfgc)
(setfgc . fmap FineGrainedConflicts)
(yesNoOpt showOrParseArgs)
, option [] ["minimize-conflict-set"]
("When there is no solution, try to improve the error message by finding "
++ "a minimal conflict set (default: false). May increase run time "
Expand Down
4 changes: 3 additions & 1 deletion cabal-install/Distribution/Solver/Modular/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ addChildren bs@(BS { rdeps = rdm, open = gs, next = Goals })
-- and then handle each instance in turn.
addChildren bs@(BS { rdeps = rdm, index = idx, next = OneGoal (PkgGoal qpn@(Q _ pn) gr) }) =
case M.lookup pn idx of
Nothing -> FailF (varToConflictSet (P qpn) `CS.union` goalReasonToCS gr) UnknownPackage
Nothing -> FailF
(varToConflictSet (P qpn) `CS.union` goalReasonToConflictSetWithConflict qpn gr)
UnknownPackage
Just pis -> PChoiceF qpn rdm gr (W.fromList (L.map (\ (i, info) ->
([], POption i Nothing, bs { next = Instance qpn info }))
(M.toList pis)))
Expand Down
Loading

0 comments on commit f6e7cdd

Please sign in to comment.