<feed xmlns='http://www.w3.org/2005/Atom'>
<title>apt/apt-pkg/solver3.h, branch 2.9.33</title>
<subtitle>Debians commandline package manager</subtitle>
<id>https://git.kalnischkies.de/apt/atom?h=2.9.33</id>
<link rel='self' href='https://git.kalnischkies.de/apt/atom?h=2.9.33'/>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/'/>
<updated>2025-03-12T17:52:16Z</updated>
<entry>
<title>solver3: Fix Recommends/Suggests vs Enhances confusion</title>
<updated>2025-03-12T17:52:16Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-03-12T17:34:48Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=a4ce187b40f3bbd110a7cc35f9a5af5a8b7b0c9e'/>
<id>urn:sha1:a4ce187b40f3bbd110a7cc35f9a5af5a8b7b0c9e</id>
<content type='text'>
We accidentally considered an Enhances a reason to keep
a package installed, which of course it is not, fix the
determination of "existing soft dependency" to only include
soft dependencies that should keep a package installed in
the autoremover to solve the issue.

This also fixes edsp/mantic-upgrade-rel-to-2024-05-29.edsp
to not install llvm-13-dev for clang-13 which is an installed
package with no upgrade.

Also ensure we stop after the first match; the DependsList()
is ordered by decreasing priority and we don't want to override
Recommends by Suggests in case a package declares both...

LP: #2101800
</content>
</entry>
<entry>
<title>solver3: Do not prefer new installs over manually installed obsoletes</title>
<updated>2025-03-09T13:53:53Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-03-09T13:52:53Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=5daf6dbfd272be2f8e3c59d4bab4be8c119b7aa1'/>
<id>urn:sha1:5daf6dbfd272be2f8e3c59d4bab4be8c119b7aa1</id>
<content type='text'>
Only move obsolete packages last that are automatically installed,
as we don't want to remove manually installed obsolete packages.

Add some missing const annotations to the operator[] arguments as
well that were needed.

LP: #2100247
</content>
</entry>
<entry>
<title>solver3: Verbose error messages</title>
<updated>2025-03-08T22:18:05Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-03-06T19:07:30Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=3967b75ae4a10d0d79560dfecb8eb210aad4f4f2'/>
<id>urn:sha1:3967b75ae4a10d0d79560dfecb8eb210aad4f4f2</id>
<content type='text'>
Introduce a new function, LongWhyStr() that returns a longer
reason for why something is being installed (or not).

This does the same path walk as the other function does, but
it renders the clauses at each level, and one per line, so
the whole output is a lot more informative.

It is a separate function to keep the existing debug messages
use the simple single line implication graph

We remove the other special case in AddWork() for empty solutions
to mke use of the general case in Solve() instead, and then adapt
the case in Solve() to the same case as in Enqueue(). This also
happens to fix the bug that when we encountered an empty clause
we just printed the clause had no solution, but not how we got
to install the package with the clause.

Adapt the test suite for the changes which is an annoying amount
of paperwork.
</content>
</entry>
<entry>
<title>solver3: Support pretty printing clauses</title>
<updated>2025-03-06T19:07:00Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-03-06T19:07:00Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=142d6499b51451d57fc050c71ffcfb8338e02b7e'/>
<id>urn:sha1:142d6499b51451d57fc050c71ffcfb8338e02b7e</id>
<content type='text'>
This will print the underlying dependency which is nicer to
read.
</content>
</entry>
<entry>
<title>solver3: cleanup operators for Var</title>
<updated>2025-03-06T19:06:40Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-03-04T21:23:47Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=7d5fe59c19edf06cbee3e0b34d71032322907ae6'/>
<id>urn:sha1:7d5fe59c19edf06cbee3e0b34d71032322907ae6</id>
<content type='text'>
Particularly, use single line and implement operator!=
</content>
</entry>
<entry>
<title>solver3: refactor: Return inserted Clause in AddWork()</title>
<updated>2025-03-06T19:06:40Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-02-20T11:21:42Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=7194a6b39c2aa6f1006630975a1bf4ffc3c9daf2'/>
<id>urn:sha1:7194a6b39c2aa6f1006630975a1bf4ffc3c9daf2</id>
<content type='text'>
This avoids relying on the inserted clause being at the back
of the clauses vector.
</content>
</entry>
<entry>
<title>solver3: Simplify Var pointer tagging</title>
<updated>2025-03-06T19:06:40Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-02-19T11:30:51Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=56c14eab8f399497295bb74d551dc49a4a763486'/>
<id>urn:sha1:56c14eab8f399497295bb74d551dc49a4a763486</id>
<content type='text'>
Use an integer and tag the lowest bit manually. This makes it
much easier to next convert this into a literal.

Add some constexpr and remove an unnecessary assertion on
CastPkg().
</content>
</entry>
<entry>
<title>Add missing #include &lt;memory&gt;</title>
<updated>2025-02-15T15:54:38Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-02-15T15:50:57Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=2614ff646e812e2d9515e6f0e7be076e97c9ec1a'/>
<id>urn:sha1:2614ff646e812e2d9515e6f0e7be076e97c9ec1a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>solver3: Store clauses as the reasons for decisions</title>
<updated>2025-02-14T18:08:45Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-02-10T22:01:36Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=9b36a29ffebde3088cec2048505b8d644f46c2c3'/>
<id>urn:sha1:9b36a29ffebde3088cec2048505b8d644f46c2c3</id>
<content type='text'>
So far we only stored the last reason why something was decided,
for example, if "A depends B | C" and we assigned B=false, C=false,
we'd store "(not) C" as the reason for "(not) A".

This gives us only a partial implication graph; after all "C" was
not the *sole* reason for not installing A. This has two implications:

1. We cannot do conflict-driven clause learning
2. We cannot print excellent information about why packages cannot be
   installed (or removed)

This commit is incomplete in addressing both; in particular, we always
store a clause as a reason for something that is not a root object;
whereas MiniSAT would only store a clause on propagation. That is,
if A depends B | C, and we install A, then we have to make a choice
between B|C. Let's say we pick B, we store 'A depends B|C' as the
reason whereas MiniSAT would not store a reason (because it picked
the "next best" unassigned literal).

Hopefully this is not going to be an issue. The reason is used to
calculate the assignments that caused the decision in MiniSAT, but
the idea is that we can just treat reason clauses with unassigned
values as "no reason".

The conflict explanation (WhyStr) has been changed to print the
strongest reason; which produces the same result as the previous
solution for the test suite. What does this mean?

If we look at A depends B|C, let's analyse:

    Why not A?
        We return the first assigned value for B|C, likely B.
        We might have returned C here before as it was the
        last assignment, but we might also return C here,
        if B is not assigned.

    Why B? We return A.

If we look at A conflicts B:

    Why not A? Well B
    Why not B? Well A

Thanks to the structure of the implication graph this is quite
simple, but also generalizing this to the CNF format should not
be hard.

A future version will extend clauses with backlinks to
pkgCache::Dependency*, allowing us to print useful information
to uses such as "A Depends B | C | D (&gt;= 2)" in the real form, rather
than the expanded form which may be "A -&gt; B | C | D=3 | D=2".
</content>
</entry>
<entry>
<title>solver3: Remove work rescoring in favor of unit propagation</title>
<updated>2025-02-14T18:08:45Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-02-12T19:39:33Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=2050ecb34a9e18cf1d8edbff8c52d456a7229162'/>
<id>urn:sha1:2050ecb34a9e18cf1d8edbff8c52d456a7229162</id>
<content type='text'>
Instead of expensive rescoring of all outstanding items, use
unit propagation to find new units after conflicts.

We still count the items when adding them; but unless they are
0 or 1, which they should not be, they don't have any effect:
The size field is now effectively static.

If the size of an optional clause changed to 1, it is inserted
a second time, and then moves up to the top of the optional
items per the Work::operator&lt; rules.
</content>
</entry>
</feed>
