Three different optimization criteria will be used. All three are lexicographic combinations of different integer-valued utility functions of a solution, which we describe below.
Note that each of these utility functions calculates a value only from the initial and the final installation status, that is the user request to install or remove a certain package is not used here. The reason for this that each proposed solution must first of all satisfy the user request, otherwise it will be discarded and the solver will obtain a penalty value. Only those proposed solutions that actually are solutions will be compared by the optimization criteria defined below, yielding a score according to the ranking obtained. This is more precisely described in the ranking rules.
For the second ("trendy") and third ("user") criterion we will make use of an extra package property which is not among the mandatory package properties. This additional property is recommends, and it has values of type vpkgformula (that is the same type as the mandatory property depends). The idea is that recommended packages are non-mandatory dependencies.
For that reason, the CUDF documents will contain a specification of that property in the document preamble, like this:
preamble:
property: recommends: vpkgformula = [ true! ]
Suppose that a solver tool outputs for the initial universe I a proposed solution S. We write V(X,name) the set of versions in which name (the name of a package) is installed in X, where X may be I or S. That set may be empty (name is not installed), contain one element (name is installed in exactly that version), or even contain multiple elements in case a package is installed in multiple versions.
We write
removed(I,S) = #{name | V(I,name) nonempty and V(S,name) empty}
new(I,S) = #{name| V(I,name) empty and V(S,name) nonempty}
changed(I,S) = #{name | V(I,name) ≠ V(S,name) }
notuptodate(I,S) = #{name| V(S,name) nonempty and does not contain the most recent version of name in S}
unsat_recommends(I,S) = #{ (name,v,c) | v ∈ V(S,name) and (name,v) recommends ..., c, ... and c is not satisfied by S }
For instance, if package a recommends
b, c|d|e, e|f|g, b|g, h
and if S installs a, e, f, and h, but neither of b, c, d, or g, then one would obtain for the package a alone a value of 2 for unsat_recommends since the 2nd, 3rd and 5th disjunct of the recommendation are satisfied, and the others are not. If no other package contains recommendations that means that, in that case, unsat_recommends(I,S)=2. Note that in any case the value of unsat_recommends(I,S) only depends on S but not on I.
sum(name)(I,S) = ∑(p ∈ S) p.name
where p.name denotes the value of package p for property name.
A typical example of this would be sum(size), where size is an additional integer-valued property of packages indicating their size.
The three optimization criteria are
lex( min removed, min changed)
Hence, two solutions S1 and S2 will be compared as follows:
lex( min removed, min notuptodate,
min unsat_recommends, min new)
-removed,-changed
the trendy criterion could be written as-removed,-notuptodate,-unsat_recommends,-new
and a user of a machine with a small disk might write-removed,-sum(installed_size),-notuptodate,-unsat_recommends,-new