Skip to content
  • 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