It looks like the problem is a bug in the new code to fix
conflicts/provides/replaces. This tries to force the resolver to
resolve conflicts between a package and its replacement in favor of the
replacement by giving a rather large bonus to the score of solutions
that do so. You can verify that this is the cause of the problem by
passing "-o Aptitude::ProblemResolver::FullReplacementScore=0" and
"-o Aptitude::ProblemResolver::UndoFullReplacement=0" to the program at
the command-line: it will avoid the downgrades and produce the solution
that keeps the packages at the current version first instead.
What's happening is that apparently I forgot to screen out self-conflicts
from this test. So the resolver thinks that, since hpijs-ppds
conflicts, provides, and replaces the virtual package "hplip-ppds", some
arbitrary versions of hpijs-ppds are treated as "full replacements"
of the current version in the sense of Policy 7.5.2, and hence get the
bonus. Obviously this is not correct.
The attached patch should fix this problem for good and has been
committed to aptitude head. I may want to take a look at the rest of
this scoring code tomorrow, there are some things that look a little
suspicious and should either be fixed or get comments explaining why
they're the right thing to do.
Although I haven't had any other complaints about this, I think it's
probably serious enough to warrant another bugfix upload if I can
squeeze the current one into lenny, since it will cause the resolver to
randomly do inexplicably stupid things.
Daniel
diff -r b6977ddc3622 src/generic/apt/aptitude_resolver.cc
--- a/src/generic/apt/aptitude_resolver.cc Sat May 31 09:38:43 2008 -0700
+++ b/src/generic/apt/aptitude_resolver.cc Mon Jun 02 21:38:23 2008 -0700
@@ -85,6 +85,21 @@
int full_replacement_score,
int undo_full_replacement_score)
{
+ // Drop literal and indirect self-provides: allowing these would
+ // have the effect of giving a bonus to a random version of packages
+ // that "replace" themselves, which distorts the solutions produced
+ // by the resolver (Debian bug #483920).
+ if(provider.end())
+ {
+ if(src.ParentPkg() == real_target)
+ return;
+ }
+ else
+ {
+ if(src.ParentPkg() == provider.ParentPkg())
+ return;
+ }
+
pkgCache::PkgIterator src_pkg = src.ParentPkg();
bool src_installed = (src_pkg->CurrentState != pkgCache::State::NotInstalled &&
src_pkg->CurrentState != pkgCache::State::ConfigFiles) &&