Using external solvers with apt-get in Wheezy

Thanks to the effort of many wonderful people (see at the end of this post), it is now possible to call an external solver from apt-get, if you use at least version 0.9.5, which will be the case in Wheezy.

It's pretty simple, just install apt-cudf :

apt-get install apt-cudf

but please check that you get version 2.9.16~rc1-1 or later of it!

dpkg -l apt-cudf
======================================
ii  apt-cudf  2.9.16~rc1-1   CUDF solver integration for APT

This package will also install one of the available solvers that support CUDF, for example aspcud.

Then you can simply use the --solver option of apt-get to have the dependency solving delegated to aspcud:

apt-get -s --solver aspcud install totem

On my machine, this gives a solution with these characteristics:

49 upgraded, 47 newly installed, 1 downgraded, 9 to remove and 2551 not upgraded.

Which might be more interesting than what the standard internal solver of apt finds, as it changes and removes quite a few more packages

79 upgraded, 98 newly installed, 15 to remove and 2520 not upgraded.
Specifying optimization criteria to get your preferred solutions

But the real power of using the many CUDF-based solvers that have been developed and improved thanks to the MISC competition comes with the ability to specify a set of user preferences for selecting the kind of changes one accepts on the system to satisfy the installation request.

When you install apt-cudf, you will find in /etc/apt-cudf.conf the following lines

solver: mccs-cbc , mccs-lpsolve
upgrade: -lex[-new,-removed,-notuptodate]
dist-upgrade: -lex[-notuptodate,-new]
install: -lex[-removed,-changed]
remove: -lex[-removed,-changed]
trendy: -lex[-removed,-notuptodate,-unsat_recommends,-new]
paranoid: -lex[-removed,-changed]
solver: *
upgrade: -new,-removed,-notuptodate
dist-upgrade: -notuptodate,-new
install: -removed,-changed
remove: -removed,-changed
trendy: -removed,-notuptodate,-unsat_recommends,-new
paranoid: -removed,-changed

They define names for various lexicographic combinations of optimization criteria that are passed to the different solvers: you can change them as you see fit.

If one name coincide with a standard apt-get action, like install, remove, upgrade or dist-upgrade, the corresponding criterion will be applied by the external solver without further ado.

The other criteria can be passed to the external solver using a (long) option on the apt-get command line like in

 apt-get -s --solver aspcud install totem -o "APT::Solver::aspcud::Preferences=trendy"

and you can use the same option to pass to the solver you choice of criterion, decided on the fly

 apt-get -s --solver aspcud install totem -o "APT::Solver::aspcud::Preferences=-new,-changed"
Relaxing pinning

When a package is available in more than one version, apt-get uses a mechanism known as pinning to decide which version should be installed. So, when you write

apt-get install totem

you are really telling apt-get to look for the version of totem which is determined by the pinning rules, and install that precise version of totem. More generally, when trying to solve the dependencies that are needed to install the specified version of totem, apt-get will also try hard to upgrade or install packages in the version specified for them by pinning.

Sometimes, this strict behaviour may end up in situations where the installation will require huge changes to your machine, or even lead to a failure, if the problem is too constrained.

In such situations, one may want to relax pinning, using the apt-get option

  -o APT::Solver::Strict-Pinning="false"

This tells apt-get to ignore pinning when solving dependencies (but not for choosing the version of packages mentioned on the command line), and this leads to explore a much bigger solution space, where the internal solver for apt-get can get lost easily.

External solvers with relaxed pinning

Here, the external solvers may be extremely useful, as they use algorithms much more powerful, and are ever-improved thanks to the MISC competion.

Unfortunately, because of a missing feature in the extension to apt-get, that is not easy to implement in full generality, and that we will discuss on a later post, you cannot just type

 apt-get -s --solver aspcud install totem \
            -o "APT::Solver::aspcud::Preferences=-new,-changed" \
            -o APT::Solver::Strict-Pinning="false"

Instead, you need to use a simple wrapper script, which is by the way quite useful, as you can forget about some of the long apt-get options.

I use a script named apt-cudf-get that contains the following lines:

#!/bin/sh
export APT_GET_CUDF_CMDLINE="apt-get $* -o APT::Solver::Strict-Pinning=\"false\""
apt-get $* -o APT::Solver::Strict-Pinning="false"

and can simply be used typing

apt-cudf-get -s --solver aspcud install totem \
    -o "APT::Solver::aspcud::Preferences=-new,-changed"

This will give the external solver all the necessary information to find a solution without pinning, and according to your preferences...

Try this out!

Acknowledgements

Let me mention here that this is one of the results of the Mancoosi project, and it would not have been possible without the constant efforts of many wonderful people, among which David, Pietro, Ralf and Stefano really stand out.