Cleaning up the system with pseudo-boolean optimization

You can use a PBO solver to clean up your system from unneeded automatically installed packages. First of all, you convert the system state to PB, and add an optimization function telling it to remove as many automatically installed packages as possible. Then you run this thing through a solver (such as clasp, which seems the fastest solver for PBO instances in the Debian archive) and convert its output to human-readable package names.

Code is provided at, under the MPL 2.0. You need to have python-apt and clasp installed to use it. There is potential minisat+ support, but it’s currently a bit broken.

To use, run python, and it will tell you which packages are no longer needed on your system. It ignores Suggests, if you want those in, you have to hack the code and replace {“Recommends”} by {“Recommends”, “Suggests”}. You can also turn of such dependencies by setting Program.hard_softdeps to False.


10 thoughts on “Cleaning up the system with pseudo-boolean optimization

  1. I’m getting:

    > python
    File “”, line 38
    self.softdeps = {“Recommends”}
    SyntaxError: invalid syntax

    1. What’s your problem with that? The MPL includes permission to relicense stuff under GPL-2+, LGPL-2.1+ and AGPL-3+ for combination in a larger work. The code uses apt_pkg which is GPL-2+, so in effect, we’re already GPL-2+ for program_builder (but not for

  2. I’m getting

    $ python
    Namespace(criteria=None, minisat=False, packages=[], recommends=True)
    Traceback (most recent call last):
    File “”, line 313, in
    File “”, line 284, in main
    pb = ProgramBuilder()
    File “”, line 29, in __init__
    self.cache = apt_pkg.Cache(progress=None)
    SystemError: W:Unable to read /dev/null – DirectoryExists (2: No such file or directory), W:Unable to read /dev/null – RealFileExists (2: No such file or directory), W:You may want to run apt-get update to correct these problems, E:The value ‘testing’ is invalid for APT::Default-Release as such a release is not available in the sources

      1. And now I’m getting segfault:

        $ python2.7
        Namespace(criteria=None, minisat=False, packages=[], recommends=True)
        Ошибка сегментирования

      2. More info on null:

        $ lsa /dev/ | grep null
        crw-rw-rw- 1 root root 1, 3 Авг 18 11:11 null

        * lsa=’ls –color=auto -la’

  3. I’m getting a segfault too, here’s the backtrace:

    Program received signal SIGSEGV, Segmentation fault.
    0xb78a1d8b in CnfMapSet (Self=, Arg=’APT::Default-Release’, Val=0x0)
    at python/
    334 python/ No such file or directory.
    (gdb) bt
    #0 0xb78a1d8b in CnfMapSet (Self=, Arg=’APT::Default-Release’, Val=0x0)
    at python/
    #1 0x080bd795 in PyObject_DelItem ()
    #2 0x0813e429 in PyEval_EvalFrameEx ()
    #3 0x0813b79c in PyEval_EvalFrameEx ()
    #4 0x081417f0 in PyEval_EvalCodeEx ()
    #5 0x0819ad51 in PyRun_FileExFlags ()
    #6 0x0819c61a in PyRun_SimpleFileExFlags ()
    #7 0x0819d6a8 in Py_Main ()
    #8 0x0806109b in main ()

Comments are closed.