Nelson-Oppen theory combination#
Scope: the retained dedicated QF_UFLRA route, reviewed 2026-09-09. The N-component QF_UFLIA route is documented separately in N-component combination migration; Current implementation and qualification maps both routes and their revision-scoped qualification.
Primo implements a specialized convex Nelson-Oppen combination for EUF and
rational linear arithmetic in QF_UFLRA. It includes purification, a sparse
shared-equality registry, explained equality exchange, a default model-guided
compatibility check, lazy SAT-visible equality decisions, exact LRA fallback,
and typed mixed model reconstruction. This dedicated engine does not use
the new component collection driver. Neither engine claims the complete
DPLL(T^M) transition system.
The classical basis is Nelson and Oppen’s cooperation by equality sharing. The model-guided parts use de Moura and Bjorner, Model-based Theory Combination, Sections 4, 5.1, and 5.2, DOI https://doi.org/10.1016/j.entcs.2008.04.079. The exact arithmetic checks and their explanations use the existing incremental LRA tableau described in Arithmetic. Detailed readings and the implementation checklist are in Nelson-Oppen Closure Methods and de Moura-Bjorner Model-Based Theory Combination.
Supported combination#
This QF_UFLRA path has two component theories:
EUF owns uninterpreted applications, predicates, congruence, and their explanations;
LRA owns linear comparisons over exact rational values and its tableau;
the SMT layer owns purification, SAT abstraction, the shared Real interface, equality exchange, and coordination of candidate component models.
After purification, the component signatures are disjoint except for equality
and shared constants of sort Real. Both components are stably infinite on
this interface, and EUF and rational LRA are convex: when their conjunction
entails a disjunction of interface equalities, one of those equalities is
entailed. These are the Nelson-Oppen preconditions that let explained equality
sharing replace enumeration of arbitrary equivalence relations in the
implemented fragment.
Only a Real constant that occurs in both an EUF atom and a normalized LRA atom is an interface term. A zero coefficient after LRA normalization does not make a term shared. Real constants used only by EUF or only by LRA stay local to that component. Boolean terms are coordinated through SAT and the Boolean/EUF bridge, not through a Nelson-Oppen arrangement; see Boolean Arguments in EUF.
The mixed solver is selected after preprocessing when a formula has arithmetic
and either an equality or an EUF predicate. With the default
--mixed-dispatch=narrow, a propositional Boolean constant alone does not route
an otherwise pure LRA formula through the mixed solver. Pure UF, LRA and LIA
retain their direct theory paths.
Purification#
purify_mixed_arithmetic_applications() runs before theory dispatch and rewrites
the supported mixed terms into theory-owned atoms. Rewriting is memoized by
TermId, so a repeated source term uses the same proxy.
For a Real-valued uninterpreted application in arithmetic, for example
(<= (+ (f x) 1) y)
Primo creates a fresh Real constant p, gives EUF the definition p = f(x),
and gives LRA p + 1 <= y. For a non-constant arithmetic term used as a Real
argument of an uninterpreted symbol, for example P(x + 1), it creates a fresh
Real constant q, rewrites the EUF atom to P(q), and gives LRA the two bounds
q <= x + 1 and x + 1 <= q.
Nested applications and repeated mixed subterms are handled recursively. A Real equality produced by the ordinary assertion pipeline is lowered to two non-strict arithmetic comparisons before LRA dispatch. The EUF proxy definition remains an equality because it belongs to congruence closure. The postcondition checked by the mixed dispatcher is therefore:
no LRA atom contains an uninterpreted application;
no supported EUF atom contains an unpurified non-constant Real subterm;
communication between the two components is only through shared Real constants and their equalities.
Purification definitions are permanent assertions for the current
check-sat; they are not temporary model guesses. Counters under
:no.purification.* report definitions, reused proxies, memoized rewrites, and
the no-site fast path.
Ownership and lifetime#
Owner |
State |
Lifetime and responsibility |
|---|---|---|
|
The table owns sorts/symbols; the manager owns terms, including fresh purification/equality terms |
Solver context; the table outlives the manager. Stable |
|
SAT literals for Boolean structure and theory atoms |
One mixed solve; maps formula atoms initially and lazily materializes a missing interface equality when the coordinator requests one. |
|
Interface terms, canonical equality entries, a shared assignment view, arrangement values, classifications, shared-model projection, and lazy equality-decision state |
One mixed solve. Arrangement values have their own undo log; SAT truth is read from the shared view. Shared-model data is round-scoped. |
|
Flattened EUF definitions and congruence closure |
EUF-owned structural preparation and assignment/model scopes. The manager stores no congruence closure. |
|
LRA atom mapping, retained prepared/check state, exact rational assignment, and explanations |
LRA-owned component state. The manager stores only its projection on shared terms. |
|
The mixed fixed-point and model-reconciliation control flow |
One |
|
Clauses, assumptions, observed variables, assignments, and failed assumptions |
SAT-owned. It never contains theory terms. |
The manager’s SharedModelState is valid only for its current
shared-model round and generation. It stores LRA value classes, their term-to-
class map, deterministic spanning equalities, explained equalities, equalities
absorbed into the candidate EUF model, and selected LRA separation atoms. A new
round or relevant rollback invalidates it. It deliberately stores neither an
EUF closure nor an LRA tableau.
SharedEqualityDecisionState is solve-scoped. It owns pending, active, and
already-tried lazy equality literals. The manager owns this lifecycle, while
the mixed coordinator performs the IPASIR-UP assumption solves and learns
failed-assumption blocking clauses.
Entailed equality exchange#
An equality may be propagated only with an explanation proving it from the current theory assignment. Accidental equality in one candidate model is not an entailed equality.
EUF projects each shared congruence class as a deterministic spanning set. Its reasons come from congruence-closure explanations. LRA has two producer layers:
the Section 5.1 producers
FixedEq,EqRow,EqOffsetRows, andEqRowsderive cheap equalities and their bound/row explanations;the exact fallback considers unresolved pairs that are equal in the checked LRA model and proves
s = tonly when both strict alternativess < tandt < sconflict with the current LRA assignment.
The feasible LRA model is only a necessary-condition filter for the exact fallback: terms with different values cannot be provably equal, while terms with the same value still require both conflict checks. Exact probes reuse the prepared mixed LRA state when its sparsity guards permit it and fall back to a separate augmented tableau otherwise.
For reasons r1, ..., rn, forcing equality literal e adds the guarded clause
not r1 or ... or not rn or e
and re-enters SAT. A pre-existing true equality needs no clause. A pre-existing false equality turns the explanation into a conflict. A newly selected pair is materialized lazily. Re-entering SAT makes both theory components observe the same equality assignment and drives the convex exchange to a fixed point.
Default model reconciliation#
qf_uflra_model_reconciliation is enabled by default. It specializes de Moura
and Bjorner’s model-based discipline to the convex shared-Real interface; it is
not a generic DPLL(T^M) state machine.
For each feasible mixed round, the coordinator performs these operations:
Check the EUF and LRA assignments. A component conflict is learned as a SAT clause and restarts search.
Build one scratch LRA assignment and greedily diversify the values of shared terms using freedom intervals. Equality literals assigned false by SAT are mandatory disequalities: mutation minimizes these violations before maximizing the number of LRA value classes.
If a mandatory disequality remains violated, search its two strict orientations. Failure of mutation is never treated as proof of equality; unresolved or inconsistent cases use the explained exact fallback.
Publish the resulting LRA value classes and a deterministic spanning set to
SharedModelState.Checkpoint EUF and tentatively merge each spanning edge. A merge is rejected if it directly violates an EUF disequality or if congruence joins terms that belong to different LRA value classes. Successful tentative merges are candidate-model choices, not lemmas.
Roll back the temporary compatibility scope. Materialize the canonical frontier of rejected edges lazily and try the frontier as one positive SAT assumption batch.
If the assumptions fail, learn a blocking clause from IPASIR-UP’s failed assumptions, retain the surviving choices, and continue search. If all spanning edges are compatible, the component models agree on the shared equality relation.
Explained LRA equalities may be absorbed directly into the candidate EUF model only together with their reasons and only when the LRA model agrees. An EUF contradiction returns the composed theory conflict. An unexplained model-equal pair is never inserted into this explained worklist.
The mixed solver retains one MixedLraModelEpoch keyed first by the true
interface equalities used to prepare LRA and then by the complete current LRA
assignment. Matching keys reuse the prepared theory or checked tableau;
different keys invalidate the corresponding cache. This is specialized
component-state reuse, not persistent generic model state.
An unmapped shared term, failure to satisfy a mandatory separation, or another
candidate-model invariant failure activates the conservative exact equality
path. The explicit --nelson-oppen-arrangement-probe-limit can instead stop
temporary LRA probing and return unknown.
Cost boundaries#
Purification visits the reachable term DAG with memo tables, so repeated source subterms do not cause repeated rewrites. Interface discovery scans the EUF atoms and the nonzero terms of normalized LRA polynomials. The manager’s canonical pair index uses expected constant-time hash lookup and stores only pairs that a producer or visible atom requests.
For a shared class of size \(k\), EUF and the LRA model projection publish at most \(k-1\) deterministic spanning edges. Section 5.1 LRA producers use indexed fixed/row signatures rather than probing every shared pair. Model compatibility, however, may project the shared EUF classes after tentative edges, and the conservative exact fallback still has a worst-case quadratic number of same-model-value pairs with up to two strict LRA checks per retained pair. The sparse registry avoids quadratic SAT-variable allocation; it does not remove this worst-case semantic search.
Final validation and models#
Before returning sat, the mixed path validates that the EUF equality relation
and the concrete LRA values can form one arrangement on shared Real terms. EUF
equalities and explained/internal LRA equalities must be preserved. Pairs that
EUF requires to remain distinct receive strict LRA separation atoms when
needed. The default reconciliation path can avoid the broad exact pair scan
after successful compatibility; its exact fallback remains the oracle when an
invariant is not established.
With :produce-models true, Primo composes:
the ground EUF function/predicate table;
values of user-visible nullary Real constants from the validated LRA model;
purification definitions and preprocessing reconstruction assignments;
model-internal shared equalities and selected LRA separation atoms.
An EUF-only Real equivalence class receives a deterministic fresh rational
representative. A class containing a genuine shared term is anchored to its LRA
value. These compatible component inputs feed build_typed_model in
typed_model_builder.cpp. Its private builder freezes the same owning
core::Model used by all other routes, with function tables keyed by evaluated
typed argument tuples. Goal-owned conversions replay backwards, and original
assertions are checked in debug builds or with --check-model. The session’s
printer only serializes this interpretation; it cannot choose another row.
The dedicated engine does not yet export through QF_UFLIA’s new
ComponentModelFragment protocol. See Finalized model interpretations.
Propagation modes#
--nelson-oppen-prop controls LRA equality production, not whether mandatory
combination checks run:
Mode |
Behavior |
|---|---|
|
Keeps mandatory convex closure and exact fallback but disables opportunistic LRA equality producers. |
|
Default. Runs the Section 5.1 producers and model reconciliation at mixed-theory quiescence, with exact fallback. |
|
Adds callback-time paired-bound propagation and still retains final reconciliation and exact fallback. |
In online mode, OnlineLraPropagator publishes s = t only after observing
both true bounds s <= t and t <= s. The reason contains their two blocking
literals. MixedTheoryPropagationDispatcher, CaDiCaL’s one external
propagator, maps the candidate to the shared registry. If no equality atom
exists, it creates the term and a fresh observed SAT variable from
cb_propagate() before returning the propagated literal. No all-pairs equality
preallocation is required.
--qf-uflra-online-euf is a separate default-off experiment that reuses live
incremental EUF callback state. It is not implied by --nelson-oppen-prop=online.
The default-off --model-equality-branching heuristic is also separate from the
default reconciliation frontier. It explores additional LRA-model-equal pairs
under configurable budgets and policies in the explained exact profile selected
with --no-qf-uflra-model-reconciliation.
The propagation mode and reconciliation option are orthogonal axes. In
particular, --nelson-oppen-prop=exact does not by itself disable default model
reconciliation; it disables the opportunistic LRA producer layer.
User options#
Option |
Default |
Effect |
|---|---|---|
|
|
Controls which preprocessed formulas enter the mixed solver. |
|
|
Selects the equality-production schedule described above. |
|
reconciliation on |
Uses the explained exact equality-sharing path instead of default shared-model reconciliation. |
|
mixed fixed elimination on |
Disables the mixed LRA elimination that exposes |
|
off |
Enables the older experimental model-equality assumption heuristic when default reconciliation is disabled. |
|
mutation on when reconciliation or branching is active |
Disables scratch freedom-interval diversification. |
|
|
Restricts mutation variables to all shared terms or EUF care-pair endpoints. |
|
|
Selects the experimental branch heuristic’s queue policy. |
|
|
Caps assumptions made by the experimental branch heuristic. It does not cap default reconciliation. |
|
off |
Enables an experimental candidate-first exact final scan. |
|
off |
Enables experimental live EUF callback reuse. |
|
off |
Routes checked projections through the older |
|
unset |
Returns |
|
off |
Adds the read-only interface and purification diagnostic scan. |
Statistics#
The implementation publishes detailed counters, initialized even when a mechanism does no work. The most useful groups are:
dispatch and interface:
:solver.qf-uflra,:no.mixed.*,:no.interface.shared-real-terms,:no.interface.materialized-*, and:no.interface.sat-equality-atoms;purification:
:no.purification.*;explained closure:
:no.interface.convex-rounds,:no.interface.euf-to-lra-*,:no.interface.lra-to-euf-*,:no.interface.lra-opportunistic-*, and:no.interface.lra-exact-fallback-*;model filtering and mutation:
:no.interface.lra-model-filter-*and:no.interface.lra-model-mutation-*;default reconciliation:
:no.shared-model.*, especiallycompatibility-*,forbidden-*,targeted-separation-*,split-frontier-*,converged-rounds,exact-fallbacks, andvalidation-failures;lazy assumptions:
:no.interface.model-equality-pending-batches,assumption-solve-calls,failed-assumptions, andblocking-clauses;online propagation:
:no.online.*, including lazy equality creation, observed variables, propagations, and reason literals;resource stops:
:no.interface.lra-extra-atom-probe-limit-hitand the arrangement/targeted-separation cap counters.
:no.online.shared-real-pairs is the full diagnostic pair count. It must not be
interpreted as the number of allocated equality atoms. In the lazy online path,
:no.online.precreated-equality-atoms remains zero.
Soundness invariants#
The mixed path relies on these boundaries:
Every atom is theory-pure after purification.
Only constants present in both component atom sets enter the shared Real interface.
Every propagated equality has a theory explanation valid under the current SAT assignment.
Equality in a candidate model is a choice or filter, never an entailment.
Every SAT-visible interface equality has one canonical registry entry and is created lazily.
A candidate EUF merge is accepted only if its congruence consequences agree with the LRA value partition.
Backtracking restores arrangement values and assignments and invalidates round-scoped model projections when required.
Pure-theory solving does not instantiate the mixed dispatcher or shared model state.
Focused assertions for these invariants are in
tests/unit/theory_combination_tests.cpp and the mixed section of
tests/unit/qf_lra_solver_tests.cpp. The tests cover purification and proxy
reuse, bidirectional equality exchange, exact reasons, no propagation of
accidental model equality, model mutation, congruence consequences, lazy split
batches, failed-assumption blocking, online lazy atom creation, model
composition, and pure-theory isolation. Python coverage includes
tests/python/test_qf_uflra_smoke_fuzz.py, finite-domain differential fuzzing,
and model validation.
Implementation map#
src/smt/theory_combination.hppand.cppdefine the interface summary, equality registry, trailed arrangement state, shared-model projection, and lazy equality-decision lifecycle.src/smt/preprocessing.cppowns mixed purification;solver_strategy.cppowns post-preprocessing dispatch.src/smt/solver_engines.cppownssolve_qf_uflra_engine_impl(), component preparation, reconciliation, exact fallback, online dispatcher plumbing and final arrangement validation.typed_model_builder.cppowns the retained typed model adapter;solver_session.cppchecks and serializes its result.check_sat.cppis a thin public wrapper, not the algorithm implementation.src/theory/equality/owns flattened congruence closure and EUF explanations. EUF And Congruence Closure is its theory reference.src/theory/arithmetic/owns the LRA tableau, model diversification, opportunistic equality producers, exact rational checks, and arithmetic explanations. Arithmetic is its theory reference.src/sat/owns the IPASIR-UP adapter, assumptions, observed variables, callback protocol, and failed-assumption queries. SAT backend: IPASIR-UP and CaDiCaL describes that boundary.
Known limitations#
The coordinator is specific to EUF plus rational LRA and shared Real constants. It is not a reusable combination of an arbitrary number of theories.
There is no support for quantifiers, nonlinear arithmetic, integer arrangements, arrays, bit-vectors, finite shared sorts, or non-convex theory combination in this path.
Primo does not carry generic mutable component models in the DPLL(T) state. Its EUF and LRA objects remain theory-owned, while
SharedModelStateis a round-scoped projection.The Section 5.2 mutation implementation is scratch LRA mutation, not a theory-independent
M-Mutatetransition.Online LRA propagation recognizes the paired non-strict-bound shape only. Online EUF reuse remains experimental and default-off.
Exact fallback can still inspect many model-equal shared pairs. The current model partition, opportunistic producers, and reconciliation frontier reduce that work but do not remove the worst-case quadratic pair space.
Component preparation remains specialized and ground. Its output uses the general immutable
core::Model, but the dedicated engine has not migrated to the collection driver’s model-fragment export protocol.
Performance history, rejected experiments, and the current gap to reference solvers belong in QF_UFLRA Model-Guided Performance Plan. The merge history and remaining convex milestones are in Convex Nelson-Oppen Merge Plan. The isolation rule that keeps Nelson-Oppen work off pure LRA’s hot path is documented in The Nelson-Oppen QF_LRA regression: evidence, mechanisms, and how to fix it safely, and the arithmetic equality producers are detailed in What QF_LRA owes Nelson-Oppen: convexity and equality sharing.