Skip to content

feat(sat): add clauses while solving - #16303

Open
art-w wants to merge 3 commits into
ocaml:mainfrom
art-w:sat-incremental
Open

art-w wants to merge 3 commits into
ocaml:mainfrom
art-w:sat-incremental

Conversation

@art-w

@art-w art-w commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

To allow the on-demand loading of opam packages by the opam_solver, we need the SAT solver to support the addition of constraints after the search has started (otherwise we have to build the whole SAT problem upfront, which requires reading every potentially relevant opam files ahead of time).

This is slightly tricky to implement, so the fuzzer was updated to show that clauses added incrementally produce the exact same solution as before.

In particular:

  • The existing clauses assumed that they would be introduced before the search started, which enabled simplifications that are invalid once hypotheses are made (e.g. at_least_one [ a ; ... ] when a is already true is automatically satisfied, but we can't drop the constraint if the solver could backtrack and change a to be false, so we only do those simplifications at the "toplevel").
  • Introducing a new constraint may yield a contradiction, in which case we have to backtrack to the right level before that clause can be added
  • Introducing a new constraint may yield a logical deduction, which may require backtracking to apply (otherwise the SAT undo trail would be wrong as it wouldn't reflect the logical deduction order anymore). A special case here is that toplevel deductions ("facts") do not require backtracking since they are never undone.

I acknowledge that this is going to be hard to review, so you may want to wait on the incremental opam_solver to confirm that this PR actually works.

@art-w
art-w marked this pull request as draft September 2, 2026 15:57
Alizter added a commit that referenced this pull request Sep 2, 2026
In preparation for the on-demand loading of opam packages by the
`opam_solver`, this refactoring introduces a small abstraction
`At_most_group` to represent a (growing) set of SAT variables of which
at most `n` may be true (e.g. for conflict classes with `n=1` or in the
future for minimizing `avoid-version`).

Currently we don't make use of the fact that those groups may grow as
every constraint is preloaded ahead of time (so we only `seal` those
groups once before the SAT solver starts, just like before). With
on-demand parsing of opam files however, we'll have to handle the
incremental discovery of additional elements bounded by these
at-most-size groups.

Growing a group incrementally is possible (e.g. from `[y;z]` to
`[x;y;z]`) because the new constraint `at_most n [x;y;z]` is strictly
stronger than the previous one `at_most n [y;z]` (we could even get rid
of the old clause, but currently this removal operation is not available
nor critical for performances).

It's possible to merge this PR before or after the incremental SAT
clauses (#16303), although it's not
that useful atm (it's just easier to review as an independent
refactoring).
Comment thread src/sat/sat.ml
@art-w
art-w marked this pull request as ready for review September 3, 2026 09:59
@art-w
art-w marked this pull request as draft September 3, 2026 12:38
Signed-off-by: Arthur Wendling <arthur@tarides.com>
Signed-off-by: Arthur Wendling <arthur@tarides.com>
Signed-off-by: Arthur Wendling <arthur@tarides.com>
@art-w

art-w commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

After more testing, I removed the optimization to skip backtracking for toplevel facts: it always backtrack now (when necessary), otherwise the deductions resulting from toplevel facts would be undone at the wrong level. With that correction, the (incoming) incremental opam_solver using this PR produces the exact same solutions for every package.version of the opam repo (about ~19k pkg locks), so I'm pretty confident this PR is working :)

@art-w
art-w marked this pull request as ready for review September 3, 2026 16:51
@Alizter
Alizter self-requested a review September 9, 2026 14:20
@Alizter

Alizter commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

I got a bit lost following the logic last week, and will resume this eventually.

Comment thread src/sat/sat.ml
| Union lits as clause ->
watch_lit (neg lits.(0)) clause;
watch_lit (neg lits.(1)) clause
| At_most _ -> () (* already watched *)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a reminder for myself, I was trying to understand why we aren't tracking watchers here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants