This project is mirrored from https://github.com/haskell/Cabal. Pull mirroring updated .
  1. 09 May, 2018 1 commit
    • kristenk's avatar
      Solver: Enforce dependencies on libraries (fixes #779). · 6efb5e23
      kristenk authored
      This commit generalizes the fix for issue #4781
      (e86f8389) by tracking dependencies on
      components instead of dependencies on executables.  That means that the solver
      always checks whether a package contains a library before using it to satisfy a
      build-depends dependency.  If a version of a package doesn't contain a library,
      the solver can try other versions.  Associating each dependency with a component
      also moves towards the design for component-based dependency solving described
      in issue #4087.
      6efb5e23
  2. 10 Jan, 2018 1 commit
    • kristenk's avatar
      Rerun dependency solver to generate a better error message (issue #4823). · 5d3618a1
      kristenk authored
      This commit changes the way that the solver generates the summarized log that it
      displays at normal verbosity.
      
      Previously, the solver saved the full log from the start to the first backjump.
      Then it filtered the log using the conflict set from the node where the first
      backjump occurred, i.e., it removed all lines from the log that did not relate
      to variables in the conflict set.  The solver also printed the final conflict
      set at the end of the log.
      
      This approach had several problems:
      
      1. It was possible for the conflicts at the first backjump to be unrelated to
         the final conflict set (issue #941).  The conflicts in the summarized log
         could be irrelevant to the failure, for example, if they were caused by only
         a single version of a dependency, which the solver could skip, and the real
         problem was a different dependency that was missing from the index.  Even if
         the summarized log was relevant, showing two different explanations for the
         same failure could be confusing.
      
      2. Filtering the full log was error prone and could remove the wrong lines.  It
         caused bugs mentioned in #2853 and #4154.
      
      3. The conflict set at the first backjump contains the variables directly
         involved in the conflicts at that level and the variables that introduced
         them, but it doesn't contain the whole chain of variables starting with the
         user targets (issue #4792).  When the log is filtered with that conflict set,
         it can be unclear why the solver needed to choose the conflicting packages in
         the first place.
      
      This commit creates the summarized log by rerunning the solver with a backjump
      limit of zero and using the full log.  Using an unfiltered log avoids (2) and
      (3).  However, it is also important to shorten the log by only showing choices
      that are relevant to conflicts.  This commit uses different approaches for the
      two types of solver failures.
      
      No solution:
      
      This commit makes the solver prefer variables from the first run's final
      conflict set when choosing goals in the second run.  This means that the log to
      the first backjump is more likely to be relevant to the final failure, because
      it only mentions packages, flags, and stanzas from the final conflict set.
      
      Backjump limit reached:
      
      There is no final conflict set in this case, since the solver did not traverse
      the whole tree.  This commit tries to create a final conflict set by rerunning
      the solver with a subtree of the original search tree that contains the path to
      the first backjump.  Then it uses the final conflict set from that run to
      generate a log message, as in the case where the solver found that there was no
      solution.
      
      Here is an example of the differences between the new and old logs, using the
      command from issue #4792 and GHC 8.2.1:
      
      Before:
      
      $ cabal install --dry-run --index-state=2018-01-04T21:05:55Z thorn
      Resolving dependencies...
      cabal: Could not resolve dependencies:
      trying: base-4.10.0.0/installed-4.1... (dependency of thorn)
      next goal: profunctors (dependency of thorn)
      rejecting: profunctors-5.2.1, profunctors-5.2, profunctors-5.1.2,
      profunctors-5.1.1, profunctors-5.1, profunctors-5.0.1, profunctors-5.0.0.1,
      profunctors-5 (conflict: thorn => profunctors<5)
      trying: profunctors-4.4.1
      next goal: transformers (dependency of profunctors)
      rejecting: transformers-0.5.2.0/installed-0.5..., transformers-0.5.5.0,
      transformers-0.5.4.0, transformers-0.5.2.0, transformers-0.5.1.0,
      transformers-0.5.0.1, transformers-0.5.0.0 (conflict: profunctors =>
      transformers>=0.2 && <0.5)
      rejecting: transformers-0.4.3.0, transformers-0.4.2.0 (conflict:
      base==4.10.0.0/installed-4.1..., transformers => base>=2 && <4.9)
      rejecting: transformers-0.4.1.0, transformers-0.3.0.0, transformers-0.2.2.1
      (conflict: base==4.10.0.0/installed-4.1..., transformers +/-applicativeinbase
      => base>=1.0 && <4.8)
      rejecting: transformers-0.2.1.0, transformers-0.2.0.0 (conflict:
      base==4.10.0.0/installed-4.1..., transformers +/-applicativeinbase =>
      base>=1.0 && <4.3)
      rejecting: transformers-0.1.4.0, transformers-0.1.3.0, transformers-0.1.1.0,
      transformers-0.1.0.1, transformers-0.0.1.0, transformers-0.0.0.0,
      transformers-0.5.3.1, transformers-0.5.3.0, transformers-0.5.0.2 (conflict:
      profunctors => transformers>=0.2 && <0.5)
      rejecting: transformers-0.4.0.0 (conflict: base==4.10.0.0/installed-4.1...,
      transformers +/-applicativeinbase => base>=1.0 && <4.8)
      rejecting: transformers-0.2.2.0 (conflict: base==4.10.0.0/installed-4.1...,
      transformers +/-applicativeinbase => base>=1.0 && <4.6)
      rejecting: transformers-0.1.0.0 (conflict: profunctors => transformers>=0.2 &&
      <0.5)
      After searching the rest of the dependency tree exhaustively, these were the
      goals I've had most trouble fulfilling: transformers, contravariant, base,
      thorn
      
      After:
      
      $ cabal install --dry-run --index-state=2018-01-04T21:05:55Z thorn
      Resolving dependencies...
      cabal: Could not resolve dependencies:
      [__0] trying: thorn-0.2 (user goal)
      [__1] next goal: contravariant (dependency of thorn)
      [__1] rejecting: contravariant-1.4, contravariant-1.3.3, contravariant-1.3.2,
      contravariant-1.3.1.1, contravariant-1.3.1, contravariant-1.3,
      contravariant-1.2.2.1, contravariant-1.2.2, contravariant-1.2.1,
      contravariant-1.2.0.1, contravariant-1.2, contravariant-1.1, contravariant-1.0
      (conflict: thorn => contravariant<1)
      [__1] trying: contravariant-0.6.1.1
      [__2] next goal: transformers (dependency of contravariant)
      [__2] rejecting: transformers-0.5.2.0/installed-0.5..., transformers-0.5.5.0,
      transformers-0.5.4.0, transformers-0.5.2.0, transformers-0.5.1.0,
      transformers-0.5.0.1, transformers-0.5.0.0 (conflict: contravariant =>
      transformers>=0.2 && <0.5)
      [__2] trying: transformers-0.4.3.0
      [__3] next goal: base (dependency of thorn)
      [__3] rejecting: base-4.10.0.0/installed-4.1... (conflict: transformers =>
      base>=2 && <4.9)
      [__3] rejecting: base-4.10.1.0, base-4.10.0.0, base-4.9.1.0, base-4.9.0.0,
      base-4.8.2.0, base-4.8.1.0, base-4.8.0.0, base-4.7.0.2, base-4.7.0.1,
      base-4.7.0.0, base-4.6.0.1, base-4.6.0.0, base-4.5.1.0, base-4.5.0.0,
      base-4.4.1.0, base-4.4.0.0, base-4.3.1.0, base-4.3.0.0, base-4.2.0.2,
      base-4.2.0.1, base-4.2.0.0, base-4.1.0.0, base-4.0.0.0, base-3.0.3.2,
      base-3.0.3.1 (constraint from non-upgradeable package requires installed
      instance)
      After searching the rest of the dependency tree exhaustively, these were the
      goals I've had most trouble fulfilling: transformers, contravariant, base,
      thorn
      
      Differences:
      
      - The new summary has level numbers, like the full log.
      - The conflicts are different.  The old log mentions thorn, base, profunctors,
        and transformers, and the new log mentions the four packages from the conflict
        set: thorn, contravariant, transformers, and base.
      - The new log starts with the solver choosing a user goal, thorn.
      
      The solver continues to display the conflicts at the first backjump when it
      reaches the backjump limit, i.e, it shows profunctors instead of contravariant:
      
      Before:
      
      $ cabal install --dry-run --index-state=2018-01-04T21:05:55Z thorn --max-backjumps=10
      Resolving dependencies...
      cabal: Could not resolve dependencies:
      trying: base-4.10.0.0/installed-4.1... (dependency of thorn)
      next goal: profunctors (dependency of thorn)
      rejecting: profunctors-5.2.1, profunctors-5.2, profunctors-5.1.2,
      profunctors-5.1.1, profunctors-5.1, profunctors-5.0.1, profunctors-5.0.0.1,
      profunctors-5 (conflict: thorn => profunctors<5)
      trying: profunctors-4.4.1
      next goal: transformers (dependency of profunctors)
      rejecting: transformers-0.5.2.0/installed-0.5..., transformers-0.5.5.0,
      transformers-0.5.4.0, transformers-0.5.2.0, transformers-0.5.1.0,
      transformers-0.5.0.1, transformers-0.5.0.0 (conflict: profunctors =>
      transformers>=0.2 && <0.5)
      rejecting: transformers-0.4.3.0, transformers-0.4.2.0 (conflict:
      base==4.10.0.0/installed-4.1..., transformers => base>=2 && <4.9)
      rejecting: transformers-0.4.1.0, transformers-0.3.0.0, transformers-0.2.2.1
      (conflict: base==4.10.0.0/installed-4.1..., transformers +/-applicativeinbase
      => base>=1.0 && <4.8)
      rejecting: transformers-0.2.1.0, transformers-0.2.0.0 (conflict:
      base==4.10.0.0/installed-4.1..., transformers +/-applicativeinbase =>
      base>=1.0 && <4.3)
      rejecting: transformers-0.1.4.0, transformers-0.1.3.0, transformers-0.1.1.0,
      transformers-0.1.0.1, transformers-0.0.1.0, transformers-0.0.0.0,
      transformers-0.5.3.1, transformers-0.5.3.0, transformers-0.5.0.2 (conflict:
      profunctors => transformers>=0.2 && <0.5)
      rejecting: transformers-0.4.0.0 (conflict: base==4.10.0.0/installed-4.1...,
      transformers +/-applicativeinbase => base>=1.0 && <4.8)
      rejecting: transformers-0.2.2.0 (conflict: base==4.10.0.0/installed-4.1...,
      transformers +/-applicativeinbase => base>=1.0 && <4.6)
      rejecting: transformers-0.1.0.0 (conflict: profunctors => transformers>=0.2 &&
      <0.5)
      Backjump limit reached (currently 10, change with --max-backjumps or try to
      run with --reorder-goals).
      
      After:
      
      $ cabal install --dry-run --index-state=2018-01-04T21:05:55Z thorn --max-backjumps=10
      Resolving dependencies...
      cabal: Could not resolve dependencies:
      [__0] trying: thorn-0.2 (user goal)
      [__1] next goal: profunctors (dependency of thorn)
      [__1] rejecting: profunctors-5.2.1, profunctors-5.2, profunctors-5.1.2,
      profunctors-5.1.1, profunctors-5.1, profunctors-5.0.1, profunctors-5.0.0.1,
      profunctors-5 (conflict: thorn => profunctors<5)
      [__1] trying: profunctors-4.4.1
      [__2] next goal: transformers (dependency of profunctors)
      [__2] rejecting: transformers-0.5.2.0/installed-0.5..., transformers-0.5.5.0,
      transformers-0.5.4.0, transformers-0.5.2.0, transformers-0.5.1.0,
      transformers-0.5.0.1, transformers-0.5.0.0 (conflict: profunctors =>
      transformers>=0.2 && <0.5)
      [__2] trying: transformers-0.4.3.0
      [__3] next goal: base (dependency of thorn)
      [__3] rejecting: base-4.10.0.0/installed-4.1... (conflict: transformers =>
      base>=2 && <4.9)
      [__3] rejecting: base-4.10.1.0, base-4.10.0.0, base-4.9.1.0, base-4.9.0.0,
      base-4.8.2.0, base-4.8.1.0, base-4.8.0.0, base-4.7.0.2, base-4.7.0.1,
      base-4.7.0.0, base-4.6.0.1, base-4.6.0.0, base-4.5.1.0, base-4.5.0.0,
      base-4.4.1.0, base-4.4.0.0, base-4.3.1.0, base-4.3.0.0, base-4.2.0.2,
      base-4.2.0.1, base-4.2.0.0, base-4.1.0.0, base-4.0.0.0, base-3.0.3.2,
      base-3.0.3.1 (constraint from non-upgradeable package requires installed
      instance)
      Backjump limit reached (currently 10, change with --max-backjumps or try to
      run with --reorder-goals).
      
      One downside of this change is that the solver may reach the backjump limit when
      generating the summarized log, if the backjump limit is very low:
      
      $ cabal install --dry-run --index-state=2018-01-04T21:05:55Z thorn --max-backjumps=1
      Resolving dependencies...
      cabal: Backjump limit reached (currently 1, change with --max-backjumps or try
      to run with --reorder-goals).
      Failed to generate a summarized dependency solver log due to low backjump
      limit.
      
      Another downside is the performance impact of rerunning the solver.  It looks
      like there isn't a big change in run time when the solver finds a solution or
      fails after an exhaustive search.  However, rerunning the solver to the first
      backjump after it reaches the backjump limit can take a significant amount of
      time.  The worst case I could find was acme-everything with GHC 7.10.3, where
      that step took 13 seconds.  The difference was normally small, though.
      
      I ran hackage-benchmark on packages from Hackage to try to find packages where
      the run time changed by more than a few percent.  I stopped it after all
      packages starting with "b" (That includes all uppercase packages).
      
      compiler: GHC 8.2.1
      index state: 2018-01-04T21:05:55Z
      parameters: --min-run-time-percentage-difference-to-rerun=1 --pvalue=0.01 --trials=20 --print-skipped-packages
      
      Out of 2219 packages, 1064 were skipped because the run times in the first trial
      were within 1%, 1065 differed by more than 1% in the first trial but did not
      show a significant difference in run time in 20 trials, and 90 did show a
      significant difference in run time.  Here are the counts of packages for
      different ranges of speedup, for those 90 packages:
      
      speedup (master avg. run time / branch avg. run time)     package count
      [0.93, 0.94)                                              1
      [0.94, 0.95)                                              0
      [0.95, 0.96)                                              0
      [0.96, 0.97)                                              1
      [0.97, 0.98)                                              7
      [0.98, 0.99)                                              29
      [0.99, 1.00)                                              47
      [1.00, 1.01)                                              3
      [1.01, 1.02)                                              2
      
      The package with the biggest percentage change was bittorrent, which ran for
      3.85 seconds on master and 4.12 seconds on this branch.  It reached the backjump
      limit.
      5d3618a1
  3. 25 Nov, 2017 1 commit
    • Herbert Valerio Riedel's avatar
      Have the solver reject packages with a too-new/unsupported spec-version · 97155ecd
      Herbert Valerio Riedel authored
      This compares the request spec-version to the lib:Cabal's version in order to
      determine whether cabal is able to properly understand the package. If it's
      newer than the currently linked lib:Cabal version it's turned into a global
      `FailResult` which the solver treats as desired in terms of backtracking and
      error reporting.
      
      This is related to the new spec-version forward-compat scheme (see #4899).
      
      This is a forward-port of #4907 to the `master` branch
      97155ecd
  4. 12 Nov, 2017 4 commits
    • kristenk's avatar
      Solver: Enforce dependencies on executables (fixes #4781). · e86f8389
      kristenk authored
      This commit adds two checks to the validation phase of the solver:
      
      1. It checks that each newly chosen package instance contains all executables
         that are required from that package so far.
      
      2. It checks that each new build tool dependency that refers to a previously
         chosen package can be satisfied by the executables in that package.
      
      This commit also fixes a TODO related to solver log messages. Previously, it was
      possible for the log to associate an incorrect executable name with a
      dependency.
      e86f8389
    • kristenk's avatar
      Solver: Store names of required executables for build-tool-depends dependencies. · 77125050
      kristenk authored
      This commit changes the field of type 'IsExe' in the 'Dep' data type to
      type 'Maybe UnqualComponentName'.  It also adds the executable name to error
      messages that previously just contained "(exe)".
      77125050
    • kristenk's avatar
      Solver: Use more specific failure reasons for dependency conflicts. · cc95def1
      kristenk authored
      This commit splits the 'Conflicting' constructor of 'FailReason' into five
      different constructors, for different types of dependency conflicts.  This
      change makes it easier to print different error messages for different
      conflicts, though it doesn't change any of the error messages yet.
      
      The refactoring caused a small change to the error message for conflicts caused
      by self-dependencies.
      cc95def1
    • kristenk's avatar
      Solver: Remove unused FailReason constructor. · 3c637fb7
      kristenk authored
      3c637fb7
  5. 17 Jun, 2017 1 commit
    • kristenk's avatar
      Solver: Add individual flags to conflict sets. · 1d016574
      kristenk authored
      This commit changes the way that the solver tracks the variables that introduce
      dependencies, in order to fix some bugs that prevented the solver from tracking
      individual flags.  I refactored Dep, the type that represents a build-depends or
      build-tool-depends dependency, so that it stores the package, flag, and stanza
      choices that introduced the dependency.  That information is stored in a field
      of type DependencyReason.  The DependencyReason is available to any solver phase
      that needs to create conflict sets, such as "build" or "validation".  Whenever
      there is a conflict involving a dependency, the solver creates a conflict set
      and a log message using the dependency's DependencyReason.  This means that the
      solver only needs to calculate the dependency reasons once, in
      IndexConversion.hs, rather than every time they are used, i.e., in Builder.hs
      (for goal reasons), Validate.hs, and Linking.hs.
      
      Another difference between this commit and master is the dependencies between
      solver variables.  On master, each dependency or variable is introduced by
      exactly one other variable.  For example, if package x has a flag y, which
      controls a dependency on package z, then the three variables depend on each
      other in a chain, x -> y -> z.  If z can't be satisfied, the solver backjumps
      to its cause, y, and if flipping y doesn't help, it continues backjumping to y's
      cause, which is x.  In contrast, this commit allows each dependency to be
      introduced by a package and any number of flags and stanzas.  So z's
      DependencyReason would contain both x and y.
      
      Storing all flags that introduced a dependency allows the solver to correctly
      calculate conflict sets when there are nested conditionals.  We no longer need
      to combine each package's flags into a single conflict set variable.  This
      commit removes the 'simplifyVar' function and adds flag variables directly to
      conflict sets.  See issue #4391.
      
      This commit makes another minor change.  In this commit and master, if a
      dependency appears in the if and else blocks of a conditional, the solver lifts
      it out of the conditional.  Previously, the solver behaved as if the flag did
      not introduce the dependency.  This commit adds the flag variable to the
      conflict set or error message if the dependency is involved in a conflict.  This
      change doesn't affect correctness, but I think it improves the error messages,
      since it gives the whole reason that each dependency was introduced.
      1d016574
  6. 01 Apr, 2017 1 commit
    • kristenk's avatar
      Refactor solver goal types. · 2245c9d9
      kristenk authored
      This commit should have no effect on behavior.  It splits the OpenGoal type into
      OpenGoal and PotentialGoal.  Both types are only used when building the search
      tree.  While PotentialGoal can represent any dependency or constraint, OpenGoal
      only represents dependencies that introduce goals (solver variables).  Limiting
      OpenGoal to only represent goals simplifies the code.
      
      This commit also removes OpenGoal and FlaggedDep's 'comp' type variables.  The
      two types had only been used with 'comp' equal to () or Component.  Now
      FlaggedDep always uses Component, and OpenGoal does not need a Component.
      2245c9d9
  7. 20 Feb, 2017 1 commit
    • kristenk's avatar
      Allow the solver to toggle manual flags to match constraints that have any qualifier. · f7f63ab4
      kristenk authored
      This fixes #4299. The change gives the dependency solver the flexibility to link
      dependencies when the user has only set a manual flag on one of them.
      Previously, the solver would force the constrained dependency to have the
      flag value from the constraint and force the unconstrained dependency to have
      the default flag value. In cases where the single instance restriction required
      the dependencies to be linked, the solver couldn't find a solution.
      
      Qualified constraints can still be used to force different dependencies on a
      package to use different flag values. For example,
      "--constraint 'pkg +flag' --constraint 'pkg2:setup.pkg -flag'" turns the flag on
      for the top-level dependency and off for the setup dependency.
      
      I also stored flag default values in the search tree to simplify the code.
      f7f63ab4
  8. 12 Feb, 2017 1 commit
  9. 27 Dec, 2016 1 commit
    • kristenk's avatar
      Solver: Check for cycles after every step. · f4f57f24
      kristenk authored
      Previously, the solver only checked for cycles after it had already found a
      solution. That reduced the number of times that it performed the check in the
      common case where there were no cycles. However, when there was a cycle, the
      solver could spend a lot of time searching subtrees that already had a cyclic
      dependency and therefore could not lead to a solution. This is part of
      https://github.com/haskell/cabal/issues/3824.
      
      Changes in this commit:
      - Store the reverse dependency map on all choice nodes in the search tree, so
        that 'detectCyclesPhase' can access it at every step.
      - Check for cycles incrementally at every step. Any new cycle must contain the
        current package, so we just check whether the current package is reachable
        from its neighbors.
      - If there is a cycle, we convert the map to a graph and find a strongly
        connected component, as before.
      - Instead of using the whole strongly connected component as the conflict set,
        we select one cycle. Smaller conflict sets are better for backjumping.
      - The incremental cycle detection automatically fixes a bug where the solver
        filtered out the message about cyclic dependencies when it summarized the full
        log. The bug occurred when the failure message was not immediately after the
        line where the solver chose one of the packages involved in the conflict. See
        https://github.com/haskell/cabal/issues/4154.
      
      I tried several approaches and compared performance when solving for
      packages with different numbers of dependencies. Here are the results. None of
      these runs involved any cycles, so they should have only tested the overhead of
      cycle checking. I turned off assertions when building cabal.
      
      Index state: index-state(hackage.haskell.org) = 2016-12-03T17:22:05Z
      GHC 8.0.1
      
      Runtime in seconds:
      Packages                    Search tree depth   Trials   master   This PR   #1      #2
      yesod                       343                 3        2.00     2.00      2.13    2.02
      yesod gi-glib leksah        744                 3        3.21     3.31      4.10    3.48
      phooey                      66                  3        3.48     3.54      3.56    3.57
      Stackage nightly snapshot   6791                1        186      193       357     191
      
      Total memory usage in MB, with '+RTS -s':
      Packages                                        Trials   master    This PR   #1     #2
      yesod                                           1         189       188       188     198
      yesod gi-glib leksah                            1         257       257       263     306
      Stackage nightly snapshot                       1        1288      1338      1432   12699
      
      #1 - Same as master, but with cycle checking (Data.Graph.stronglyConnComp) after
           every step.
      #2 - Store dependencies in Distribution.Compat.Graph in the search tree, and
           check for cycles containing the current package at every step.
      f4f57f24
  10. 04 Dec, 2016 1 commit
  11. 18 Sep, 2016 2 commits
  12. 04 Sep, 2016 5 commits
  13. 26 Jun, 2016 1 commit
  14. 05 Jun, 2016 1 commit
  15. 04 May, 2016 2 commits
    • Edsko de Vries's avatar
      Improve documentation of `Tree` · cbfd24e2
      Edsko de Vries authored
      This commit looks somewhat bigger than it is because I moved some comments
      around so we can have longer comments for the constructors. The most important
      change is the documentation of the `QGoalReason` invariant on 'GoalChoice'.
      
      This commit doesn't change any actual code.
      cbfd24e2
    • Edsko de Vries's avatar
      Replace OpenGoal with Goal in GoalChoice · febf9530
      Edsko de Vries authored
      OpenGoal contains a FlaggedDep which contains a lot more information than we
      actually need in the tree; we just need to know, which choice are we
      introducing: package, flag, or stanza? We don't need the full FlaggedDep tree.
      febf9530
  16. 27 Apr, 2016 1 commit
  17. 26 Apr, 2016 1 commit
  18. 21 Apr, 2016 1 commit
    • Edsko de Vries's avatar
      Use empty POption for unknown packages · 5a4149f4
      Edsko de Vries authored
      and fix the error message in showMessages; this keeps the construction of
      conflict sets uniform.
      
      This still isn't quite right though. If we remove B from db21 as well, we don't see a line "unknown package B" appearing in the log. I have no idea why.
      
      Also, @kosmikus says:
      
      > ok, so first problem: we still need to add C to the conflict set
      > one way to do this now is to change the "initial" conflict set in the backjump calls to be the node + the goal reason again
      > I was assuming that the initial set is only ever added to an existing conflict set that we already have
      > but this is now no longer true
      
      I have no idea what that means :)
      5a4149f4
  19. 05 Apr, 2016 1 commit
  20. 03 Mar, 2016 1 commit
    • Andres Löh's avatar
      Improve goal reorder heuristics. · 150d6ca9
      Andres Löh authored
      This change primarily does two things:
      
      1. For `--reorder-goals`, we use a dedicated datatype `Degree`
         rather than an `Int` to compute the approximate branching
         degree. We map 0 and 1 to the same value. We then use a
         lazy ordering and a shortcutting minimum function to look
         for the "best" goal.
      
         The motivation here is that we do not want to spend
         unnecessary work. Following any goal that has 0 or 1 as degree
         cannot really be "wrong", so we should not look at any others
         and waste time.
      
         This will still not always make the use of `--reorder-goals`
         better than not using it, but it will reduce the overhead
         introduced by it.
      
      2. We use partitioning rather than sorting for most of the other
         goal reordering heuristics that are active in all situations.
         I think this is slightly more straightforward and also slightly
         more efficient, whether `--reorder-goals` is used or not.
      
      I have run some preliminary performance comparisons and they
      seem to confirm that in both cases separately (with or without
      `--reorder-goals`), these changes are a relative improvement
      over the status quo. I will run additional tests before
      merging this into master.
      150d6ca9
  21. 20 Feb, 2016 1 commit
  22. 17 Dec, 2015 2 commits
  23. 31 Jul, 2015 2 commits
  24. 01 Jun, 2015 2 commits
  25. 31 Mar, 2015 1 commit
    • Edsko de Vries's avatar
      Fine-grained dependencies in solver input · a5a823d4
      Edsko de Vries authored
      The modular solver has its own representation for a package (PInfo). In this
      commit we modify PInfo to keep track of the different kinds of dependencies.
      
      This is a bit intricate because the solver also regards top-level goals as
      dependencies, but of course those dependencies are not part of any 'component'
      as such, unlike "real" dependencies. We model this by adding a type parameter
      to FlaggedDeps and go which indicates whether or not we have component
      information; crucially, underneath flag choices we _always_ have component
      information available.
      
      Consequently, the modular solver itself will not make use of the ComponentDeps
      datatype (but only using the Component type, classifying components); we will
      use ComponentDeps when we translate out of the results from the modular solver
      into cabal-install's main datatypes.
      
      We don't yet _return_ fine-grained dependencies from the solver; this will be
      the subject of the next commit.
      a5a823d4
  26. 27 Mar, 2015 3 commits