3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-05-17 07:29:28 +00:00
Commit graph

4592 commits

Author SHA1 Message Date
Can Cebeci
2c7b256db2
Use the minimum generation number among matching enodes (#9405)
* Compute term generations based on minimal match

* Tidy up get_*_f_app

* Update euf_mam to the minimum generation number among matches

* Update euf_mam.cpp

* Move the UNREACHABLE() test to smt_mam.cpp

* Enforce stickiness of max-generation

* Add current generation tracking to bind structure

* Fix build error

---------

Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-07 18:32:31 -04:00
Nikolaj Bjorner
e09964096e add continue as an option to breaking loop at level
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-01 16:15:46 -07:00
Copilot
b9be33bb06
Reorder null check before side effect in linearise_multi_pattern (#9427)
* Initial plan

* Move null check before side effect in linearise_multi_pattern

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/cc69d451-b5a7-414d-9154-2cda3286fe40

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-04-29 17:18:45 -07:00
Copilot
7c4c709708
Fix static analysis issues: null dereferences, unsafe casts, branch clones, uninitialized members (#9424)
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/6e64242e-78e5-4807-8369-02baaf405a70

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-04-29 13:37:11 -07:00
Arie
6d38d5ed41
NLA tracing: emit varmap and grobner-linear-eq for trace analysis (#9415)
Two TRACE blocks under the existing nla_solver tag:

1. theory_lra::false_case_of_check_nla emits a "varmap:" line for each
   NLA lemma, listing j-var → SMT-name mappings for variables in the
   lemma's collect_vars set. Lets lemur nla resolve the LP-internal
   j-numbering back to the original SMT term names when displaying
   lemmas. Without this, lemma-level analysis has to either guess at
   variable identities (and j-numbers are reused across nlsat
   invocations under backtracking — see j-vars-unstable note) or use a
   different trace tag entirely (-tr:nra) for stable algebraic-number
   IDs.

2. nla_grobner emits a "grobner-linear-eq:" line at each call to
   add_term + update_column_type_and_bound that produces a Linear
   Propagation row from completion. Lets us count Gröbner's effective
   contribution to the LP tableau independently of the lemma stream.
   Useful when investigating Gröbner-deficit hypotheses in NLA cascade
   diagnosis.

Both are pure trace emission, behind TRACE(nla_solver, ...). Zero
runtime cost when tracing is off; no semantic change.
2026-04-28 17:31:11 -07:00
Lev Nachmanson
c40f8a200e
smt: reset give-up state when escalating final_check level (#9408)
theory_lra reports num_final_check_levels()==2: full nlsat (m_nra.check)
only runs at level >= 2. When a level-1 round-trip ends with FC_GIVEUP
and the loop escalates to level 2, the previously accumulated 'result',
'f', and 'm_incomplete_theories' were retained, so a subsequent
successful (FC_DONE) round at level 2 was still reported as
(incomplete (theory arithmetic)). Reset that state on each level
escalation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 03:33:28 +02:00
Nikolaj Bjorner
6420bff843 skip other tseitin literals 2026-04-26 11:52:46 -07:00
Nikolaj Bjorner
cd6fad428b code review updates
1. unit extraction could skip some units
2. create a shared method to check satisfiability that handles exception cases. They are the same among different workers, so shared in the batch manager.
2026-04-25 17:34:09 -07:00
Copilot
f37f87422a
[code-simplifier] Simplify backbone/parallel code from PR #9343 (#9357)
* Initial plan

* Simplify backbone and parallel code paths from PR #9343

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/5bcd7f31-c5cc-4d1f-9ef1-6647950bab25

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-04-23 16:17:42 +02:00
Nikolaj Bjorner
abd378e9d8 assert backbone to local context in backbone worker
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-22 18:40:44 -07:00
Nikolaj Bjorner
725772dfec add failed literal backbone variant
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-22 17:30:10 -07:00
Ilana Shapiro
19e95f40af
Add global backbones to parallel architecture (#9343)
* setting up new backbone experiment

* fix phase scores bug

* debug crash from negated atoms

* backbone thread/global backbones in progress, does NOT compile yet

* debug, still need to add backbones worker as a new thread

* setting up complicated condition variable thing for backbones worker thread

* debug

* debug lock contention

* it's a little messy, but change how i'm checking backbones by initiating with batch check

* don't split on global backbones, share global backbones once detected. still need to prune search tree with backbones

* close global backbone branches in search tree

* fix backbone ranking (take average of bb age over cubes and incorporate hits/num cubes the bb appears in

* add stats to backbone experiment

* gate the backbones experiment by local vs global

* update stats and fix bug about unsat core size=1 means global backbone

* phase negation ablation

* unforce phase ablation

* reset ablations

* add todo notes

* fix backbone aging

* first draft of Janota Alg 7

* process exactly 10 bb candidates in each batch

* fixing the Janota algorithm

* add backbone stats for Janota algorithm

* fix bug about global backbones not being checked unless local is also true

* hopefully fix bug about closing global backbones in search tree

* fix another bug in janota alg

* report random seed for debug

* print random seed for debug

* refactor janota alg code, still can't repro the crash

* fix some bugs in the janota algorithm

* try to fix weird memory leak thing with ramon/linux

* revert fix, it didn't work

* add second backbones thread

* increase chunk size when undef

* fix how the 2 backbone threads work on batches (they each race to finish the same batch). this was very complicated to code due to thread synchronization and while it runs there may be bugs

* update how we report stats for backbones

* first draft of doing the bb threads in neg and pos mode, needs revising

* fix some bugs in the positive version of the bb check, still need to review

* debug some more things in the positive bb worker

* keep bb candidates sorted, increase batch and chunk size

* try to resolve a couple of bugs

* fix very bad bug about backbones workers not doing anything

* ablate positive backbone thread

* fix how we record backbones in positive mode (shouldn't impact previous run)

* clarify code about adding found backbones

* add back the positive bb thread

* try to fix the random segfault bug + ablate the postiive bb thread again

* clean up logs

* share clauses with bb threads

* fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* resolve deadlock

* add comment about SAT bb case

* todo comments

* complete TODOs in code, still need to debug bb threads

* debug bb threads, add bb_positive thread back in

* ablate bb_positive thread

* style

* configure num bb threads as param

* enable sat and unsat mode

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updates

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove while true

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updates

* try to fix rewriter_exception bug

* possibly reduce code under lock when only 1 bb thread

* add some copilot-suggested optimizations

* add copilot suggestions to fix condition variable synchronization with bb threads

* revert changes that are too messy with the code

* ablate collect clauses

* ablate condition variable logic changes

* ablate reset batch

* revert ablation

* remove m_batch_in_progress that makes the bb threads wait until both have exited the batch after one signals cancel (can be long if one is stuck in ctx check)

* sharing theory lemmas

* finish setup for search tree thread modes, and fix local bb setup to pull from the global pool

* variable renames

* update bb hyperparams after copilot (hopefully??) ran tuning experiments

* fix possible AST manager bug

* ablate collect clauses

* remove bb collect shared clauses

* fix local bb experiment bug and reinstate collect clauses for global bb

* local bb cands are thread-local ablation

* remove thread-local local bb ablation

* fix bug in nonthread-local bb experiment

* fix more nonthreadlocal bb bugs

* try to fix local bb bug

* AST manager mismatch bugfix

* attempt to fix another canonicalization bug

* try another bugfix

* try another bugfix

* try yet another bugfix

* thread local bb ablation

* ablate force phase

* ablate set activity

* undo ablations since apparently it's not forcing phase or boosting activities

* remove old experiments

* try guarding m_birthdate size

* try to fix several bugs including with m_birthdate initialization and how we're storing original phases

* one more bugfix

* remove local bb experiment after negative signals on experiments, and change bb ranking to VSIDS scores as opposed to phase

* select bb polarity based on phase, not VSIDS

* first attempt with codex. Codex notes:
What changed:

  - Each tree node now tracks:
      - active worker count
      - lease epoch
      - cancel epoch
  - get_cube() now hands each worker an explicit lease: (node, epoch, cancel_epoch).
  - try_split() and backtrack() now operate on that lease, and the batch manager releases the worker’s lease under the tree lock before mutating the
    node.
  - If another worker closes the leased node or subtree, the batch manager cancels only the workers whose current leased nodes are now closed.
  - Workers detect canceled leases after check(), reset their local cancel flag, abandon the stale lease, and continue instead of turning that into a
    global exception.
  - The “reopen immediately into the open queue” policy is preserved. I did not add a barrier waiting for all workers on a node to finish.
  - Active-worker accounting is now separate from the open/active/closed scheduling status, so reopening a node no longer erases the fact that other
    workers are still on it.

  I also updated search_tree bookkeeping so:

  - closure bumps node cancel/lease epochs
  - active-node counting uses actual active-worker presence, not just status == active

* fix smts bugfix git merge issues with backtrack

* fix(parallel-smt): gate split/backtrack by lease epoch

What it changes:

  - util/search_tree.h
      - bumps node epoch on split
      - threads epoch through should_split(...) and try_split(...)
      - always records effort, but only split/reopen if the lease epoch still matches
  - smt/smt_parallel.cpp
      - requires is_lease_valid(..., lease.epoch) before backtrack(...)
      - passes lease.epoch into m_search_tree.try_split(...)

* clean up code and add some comments

* fix bug about backtracking condition being too strict: The epoch guard should not block backtrack(...) the same way it blocks try_split(...). A stale worker that proves UNSAT for n should still be able to
  close n, and that closure should then cancel the other workers on n and its subtree.

  I changed smt/smt_parallel.cpp accordingly:

  - try_split(...) still uses epoch to reject stale structural splits
  - backtrack(...) no longer requires is_lease_valid(..., epoch); it only requires that the lease is not already canceled

  So the intended asymmetry is now restored:

  - stale split: reject
  - stale unsat/backtrack: allow closure, then cancel affected workers

* ablate to no backtracking on stale leases

* fix merge

* revert codex change about exception handling

* fix linux bugs

* ablate backtrack gating

* attempt to fix linux crashes

* ablate backtracking on global bb

* the rare bb bug appears to be from creating the synthetic lease for a bb node and then backtracking on the synthetic lease. this is an attempt to fix it

* clean up code

* try to fix bug about active worker counts/lease accounting. current policy should hold: - stale leases: release/decrement
  - canceled leases: do not release/decrement (just ignore since we have an invariant that canceled leases mean closed nodes that are never revisited

* delay premature root activation

* fix major semantic bug about threads continually choosing the root if their lease is reset

* fix cancellation to unknown status

* fix very bad bug about all threads needing to start at the root

* ablate active ranking: now nodes are only reopened if they are truly inactive (active worker count is 0)

* fix some bugs about leases

* ablate adding static effort only

* fix some bugs about leases

* don't explode effort for portfolio nodes

* fix: still accumulate per-node effort, but don't over-accumulate on portfolio solves

* restore dynamically scaled effort

* clean up merge from cherry pick

* tighten which nodes we detect for proven global bb closure (only detect nonclosed nodes)

* fix cancel to unknown exception on bb code

* lease cancellation doens't touch rlimit now, it just sets max conflicts to 0. also fix a VERY BAD BUG about effort never being updated until all leases are done on a node, which meant we never left the root

* cross-thread modification of max conflicts is unsafe, so create an atomic lease canceled variable that's ch
ecked in ctx where max conflicts is also checked

* move atomic lease check in the context to the more global get_cancel_flag function

* Fix new SIGSEV. issue: The root cause: get_cancel_flag() is called from within propagation loops (mid-BCP, mid-equality-propagation, mid-atom-propagation). When it returns true there, the solver exits early and leaves the context in an intermediate state —
  propagation queues partially processed, theory state potentially inconsistent with boolean state.

  For the global cancel (m.limit().cancel()), this is harmless: the worker exits entirely and the context is destroyed. Intermediate state doesn't matter.

  For a lease cancel, the context is reused — the worker gets a new cube and calls ctx->check() again on the same context object. Re-entering check() on a context interrupted mid-propagation causes it to access that corrupted intermediate
  state → SIGSEGV.

  The m_max_conflicts check is the only checkpoint that's safe for re-entry: it only fires post-conflict-resolution, pre-decision, when propagation queues are empty and theory state is consistent.

  Fix: Remove m_lease_canceled from get_cancel_flag(). Keep it only at safe, between-phase checkpoints where the context is in a known-consistent state. The result is two safe checkpoints for m_lease_canceled: after each conflict (post-resolution, queues empty) and before each theory final check (not yet entered the theory). Neither interrupts the solver mid-mutation. The SIGSEGV should be
   gone, and NIA performance should improve because long theory final checks (where NIA burns most time) are now preemptable before they start.

* fix new inconsistent theory bug: The problem is returning FC_GIVEUP from inside final_check() after some theories have already run final_check_eh() and pushed propagations into the queue. Those pending propagations reference context state that gets invalidated on the next check() call → SIGSEGV. The fix: check m_lease_canceled before entering final_check() in bounded_search(), never from inside it. That way the context is always in a clean pre-final-check state when we bail out. This is safe: decide() returned false (all variables assigned, no pending propagations), theories haven't been touched yet, context is in a fully consistent state. For NIA, this is still a meaningful win — we avoid entering expensive arithmetic final checks entirely when the lease is already canceled.

* ablate lease cancel check in ctx final theory check due to crash (??)

* gate bb-specific code behind param

* try some possible bugfixes for the sigsev

* ablate some bugfixes

* remove second lease cancel check in smt_context, not sure it's safe. only check where we do the max conflicts check

* restore exception handling logic to master branch

* restore reslimit cancels since the bug appears to be latent

* add bookkeeping for race condition of multiple lease cancels on a single node (messes with reslimit)

* restore unrelated code to master

---------

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MacBook-Pro.local>
Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MBP.lan1>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Ilana Shapiro <ilanashapiro@Mac.localdomain>
Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MBP.localdomain>
Co-authored-by: Ilana Shapiro <ilanashapiro@Mac.lan1>
2026-04-20 18:22:07 +02:00
Ilana Shapiro
44966e1733
Terminate on Demand and some algorithmic bugfixes in the search tree (#9336)
* first attempt with codex. Codex notes:
What changed:

  - Each tree node now tracks:
      - active worker count
      - lease epoch
      - cancel epoch
  - get_cube() now hands each worker an explicit lease: (node, epoch, cancel_epoch).
  - try_split() and backtrack() now operate on that lease, and the batch manager releases the worker’s lease under the tree lock before mutating the
    node.
  - If another worker closes the leased node or subtree, the batch manager cancels only the workers whose current leased nodes are now closed.
  - Workers detect canceled leases after check(), reset their local cancel flag, abandon the stale lease, and continue instead of turning that into a
    global exception.
  - The “reopen immediately into the open queue” policy is preserved. I did not add a barrier waiting for all workers on a node to finish.
  - Active-worker accounting is now separate from the open/active/closed scheduling status, so reopening a node no longer erases the fact that other
    workers are still on it.

  I also updated search_tree bookkeeping so:

  - closure bumps node cancel/lease epochs
  - active-node counting uses actual active-worker presence, not just status == active

* fix(parallel-smt): gate split/backtrack by lease epoch

What it changes:

  - util/search_tree.h
      - bumps node epoch on split
      - threads epoch through should_split(...) and try_split(...)
      - always records effort, but only split/reopen if the lease epoch still matches
  - smt/smt_parallel.cpp
      - requires is_lease_valid(..., lease.epoch) before backtrack(...)
      - passes lease.epoch into m_search_tree.try_split(...)

* clean up code and add some comments

* fix bug about backtracking condition being too strict: The epoch guard should not block backtrack(...) the same way it blocks try_split(...). A stale worker that proves UNSAT for n should still be able to
  close n, and that closure should then cancel the other workers on n and its subtree.

  I changed smt/smt_parallel.cpp accordingly:

  - try_split(...) still uses epoch to reject stale structural splits
  - backtrack(...) no longer requires is_lease_valid(..., epoch); it only requires that the lease is not already canceled

  So the intended asymmetry is now restored:

  - stale split: reject
  - stale unsat/backtrack: allow closure, then cancel affected workers

* ablate to no backtracking on stale leases

* revert codex change about exception handling

* remove old code

* ablate backtracking gate

* attempt to fix linux crashes

* try to fix bug about active worker counts/lease accounting. current policy should hold: - stale leases: release/decrement
  - canceled leases: do not release/decrement (just ignore since we have an invariant that canceled leases mean closed nodes that are never revisited

* delay premature root activation

* fix major semantic bug about threads continually choosing the root if their lease is reset

* fix cancellation to unknown status

* fix very bad bug about all threads needing to start at the root

* ablate active ranking: now nodes are only reopened if they are truly inactive (active worker count is 0)

* fix some bugs about leases

* ablate adding static effort only

* fix some bugs about leases

* don't explode effort for portfolio nodes

* fix: still accumulate per-node effort, but don't over-accumulate on portfolio solves

* restore dynamically scaled effort

* lease cancellation doens't touch rlimit now, it just sets max conflicts to 0. also fix a VERY BAD BUG about effort never being updated until all leases are done on a node, which meant we never left the root

* cross-thread modification of max conflicts is unsafe, so create an atomic lease canceled variable that's ch
ecked in ctx where max conflicts is also checked

* move atomic lease check in the context to the more global get_cancel_flag function

* Fix new SIGSEV. issue: The root cause: get_cancel_flag() is called from within propagation loops (mid-BCP, mid-equality-propagation, mid-atom-propagation). When it returns true there, the solver exits early and leaves the context in an intermediate state —
  propagation queues partially processed, theory state potentially inconsistent with boolean state.

  For the global cancel (m.limit().cancel()), this is harmless: the worker exits entirely and the context is destroyed. Intermediate state doesn't matter.

  For a lease cancel, the context is reused — the worker gets a new cube and calls ctx->check() again on the same context object. Re-entering check() on a context interrupted mid-propagation causes it to access that corrupted intermediate
  state → SIGSEGV.

  The m_max_conflicts check is the only checkpoint that's safe for re-entry: it only fires post-conflict-resolution, pre-decision, when propagation queues are empty and theory state is consistent.

  Fix: Remove m_lease_canceled from get_cancel_flag(). Keep it only at safe, between-phase checkpoints where the context is in a known-consistent state. The result is two safe checkpoints for m_lease_canceled: after each conflict (post-resolution, queues empty) and before each theory final check (not yet entered the theory). Neither interrupts the solver mid-mutation. The SIGSEGV should be
   gone, and NIA performance should improve because long theory final checks (where NIA burns most time) are now preemptable before they start.

* fix new inconsistent theory bug: The problem is returning FC_GIVEUP from inside final_check() after some theories have already run final_check_eh() and pushed propagations into the queue. Those pending propagations reference context state that gets invalidated on the next check() call → SIGSEGV. The fix: check m_lease_canceled before entering final_check() in bounded_search(), never from inside it. That way the context is always in a clean pre-final-check state when we bail out. This is safe: decide() returned false (all variables assigned, no pending propagations), theories haven't been touched yet, context is in a fully consistent state. For NIA, this is still a meaningful win — we avoid entering expensive arithmetic final checks entirely when the lease is already canceled.

* remove second lease cancel check in smt_context, not sure it's safe. only check where we do the max conflicts check

* check epoch match in release_lease_unlocked

* restore exception handling logic to master branch

* restore reslimit cancels since the bug appears to be latent

---------

Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MacBook-Pro.local>
Co-authored-by: Ilana Shapiro <ilanashapiro@Mac.lan1>
2026-04-19 16:21:41 +02:00
Arie
58ad1f0918
Fix scaled_min test failure from #9235 mod-factor-propagation (#9260)
The is_mod handler in theory_lra called ensure_nla(), which
unnecessarily created the NLA solver for pure linear problems, causing
the optimizer to return a finite value instead of -infinity.

Fix: check `m_nla` instead of calling `ensure_nla()`, matching the
pattern used by the is_idiv handler. The mod division is only registered
when NLA is already active due to nonlinear terms.

Update mod_factor tests to use QF_NIA logic and assert the mul term
before the mod term so that internalize_mul triggers ensure_nla() before
mod internalization.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:52:42 -07:00
Ilana Shapiro
ceb363d35d
SMTS tree algorithms (#9250)
* Refactor parallel search tree to use global node selection (SMTS-style) instead of DFS traversal.
Introduce effort-based prioritization, allow activation of any open node, and add controlled/gated
expansion to prevent over-partitioning and improve load balancing.

* clean up code

* ablations

* ablations2: effort

* ablations2: activation

* ablations3: more activations

* ablations4: visit all nodes before splitting

* throttle tree size min is based on workers not activated nodes

* ablate random throttling

* ablate nonlinear effort

* clean up code

* ablate throttle

* ablate where add_effort is

* reset

* clean up a function and add comment

---------

Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MBP.localdomain>
Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MacBook-Pro.local>
Co-authored-by: Ilana Shapiro <ilanashapiro@Ilanas-MBP.lan1>
2026-04-09 09:46:47 -07:00
Nikolaj Bjorner
c7879ed5ad fix #9254
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-09 09:19:40 -07:00
Arie
477a1d817d
Add mod-factor-propagation lemma to NLA divisions solver (#9235)
When a monic x*y has a factor x with mod(x, p) = 0 (fixed), propagate
mod(x*y, p) = 0. This enables Z3 to prove divisibility properties like
x mod p = 0 => (x*y) mod p = 0, which previously timed out even for
p = 2. The lemma fires in the NLA divisions check and allows Gröbner
basis and LIA to subsequently derive distributivity of div over addition.

Extends division tuples from (q, x, y) to (q, x, y, r) to track the
mod lpvar. Also registers bounded divisions from the mod internalization
path in theory_lra, not just the idiv path.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:34:11 -07:00
Lev Nachmanson
b5bf4be87e fix: move m_fixed insertion after check_long_strings guard
m_fixed.insert(e) was placed before the check_long_strings guard,
causing check_fixed_length(false, false) to mark variables with
len > 20 as processed without actually decomposing them. The
subsequent check_fixed_length(false, true) then skipped them.

Move the insertion after the guard so variables are only marked
as fixed once they are actually decomposed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-17 20:19:12 -10:00
copilot-swe-agent[bot]
960ab8e67a perf: move check_fixed_length(false,true) before check_contains in final_check_eh
Co-authored-by: levnach <5377127+levnach@users.noreply.github.com>
2026-03-17 20:19:12 -10:00
Lev Nachmanson
09c13a75e3 fix #8023: don't skip axiom clauses with non-base-level satisfying literals
The add_axiom optimization that skips adding clauses when a literal is
already true was unsound: the satisfying literal could be retracted by
backtracking, leaving the axiom clause missing. This caused the solver
to miss propagations, e.g., not propagating indexof(a,s) = -1 when
contains(a,s) becomes false after backtracking.

Fix: only skip the clause if the satisfying literal is assigned at
base level (scope 0), where it can never be retracted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-17 15:05:41 -10:00
copilot-swe-agent[bot]
3745bdd43b fix: reduce verbose lock contention in theory_diff_logic (issue #8019)
In multi-threaded solving, IF_VERBOSE(0, ...) in found_non_diff_logic_expr
was always acquiring the global g_verbose_mux mutex (since verbosity >= 0 is
always true) while holding it for potentially expensive mk_pp() calls. This
caused catastrophic lock contention when multiple threads internalized atoms.

Change IF_VERBOSE(0, ...) to IF_VERBOSE(2, ...) in both theory_diff_logic_def.h
and theory_dense_diff_logic_def.h. The diagnostic message is still available at
verbosity level 2 (-v:2), but is no longer printed (or locked) at the default
verbosity level, eliminating the contention.

Co-authored-by: levnach <5377127+levnach@users.noreply.github.com>
2026-03-17 13:07:20 -10:00
Lev Nachmanson
6fb68ac010
Nl2lin - integrate a linear under approximation of a CAD cell by Valentin Promies. (#8982)
* outline of signature for assignment based conflict generation

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* outline of interface contract

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove confusing construction

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add material in nra-solver to interface

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add marshaling from nlsat lemmas into core solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* tidy

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add call to check-assignment

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Nl2lin (#7795)

* add linearized projection in nlsat

* implement nlsat check for given assignment

* add some comments

* fixup loop

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updates

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* debug nl2lin

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* Nl2lin (#7827)

* fix linear projection

* fix linear projection

* use an explicit cell description in check_assignment

* clean up (#7844)

* Simplify no effect checks in nla_core.cpp

Move up linear nlsat call to replace bounded nlsat.

* t

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* t

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* detangle mess

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove the too early return

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* do not set use_nra_model to true

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* remove a comment

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* add a hook to add new multiplication definitions in nla_core

* add internalization routine that uses macro-expanded polynomial representation

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add internalization routine that uses macro-expanded polynomial representation

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fixup backtranslation to not use roots

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* call setup_assignment_solver instead of setup_solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* debug the setup, still not working

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* updated clang format

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* simplify

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* create polynomials with integer coefficients, use the hook to create new monomials

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* integrating changes from master related to work with polynomials

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* add forgotten files

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* Update nlsat_explain.cpp

Remove a duplicate call

* fix

* move linear cell construction to levelwise

* fix

* fix

* Port throttle and soundness fixes from master

- Fix soundness: pop incomplete lemma from m_lemmas on add_lemma failure
- Gracefully handle root atoms in add_lemma
- Throttle check_assignment with failure counter (decrement on success)
- Add arith.nl.nra_check_assignment parameter

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add arith.nl.nra_check_assignment_max_fail parameter

Replace hardcoded failure threshold with configurable parameter (default 10).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add cha_abort_on_fail parameter to control failure counter decrement

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* abort nla check_assignment after a set number of allowed failures

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* Add missing AST query methods to Java API (#8977)

* add Expr.isGround() to Java API

Expose Z3_is_ground as a public method on Expr. Returns true when the
expression contains no free variables.

* add Expr.isLambda() to Java API

Expose Z3_is_lambda as a public method on Expr. Returns true when the
expression is a lambda quantifier.

* add AST.getDepth() to Java API

Expose Z3_get_depth as a public method on AST. Returns the maximum
number of nodes on any path from root to leaf.

* add ArraySort.getArity() to Java API

Expose Z3_get_array_arity as a public method on ArraySort. Returns
the number of dimensions of a multi-dimensional array sort.

* add DatatypeSort.isRecursive() to Java API

Expose Z3_is_recursive_datatype_sort as a public method on
DatatypeSort. Returns true when the datatype refers to itself.

* add FPExpr.isNumeral() to Java API

Expose Z3_fpa_is_numeral as a public method on FPExpr. Returns true
when the expression is a concrete floating-point value.

* add isGroundExample test to JavaExample

Test Expr.isGround() on constants, variables, and compound
expressions.

* add astDepthExample test to JavaExample

Test AST.getDepth() on leaf nodes and nested expressions to verify
the depth computation.

* add arrayArityExample test to JavaExample

Test ArraySort.getArity() on single-domain and multi-domain array
sorts.

* add recursiveDatatypeExample test to JavaExample

Test DatatypeSort.isRecursive() on a recursive list datatype and a
non-recursive pair datatype.

* add fpNumeralExample test to JavaExample

Test FPExpr.isNumeral() on a floating point constant and a symbolic
variable.

* add isLambdaExample test to JavaExample

Test Expr.isLambda() on a lambda expression and a plain variable.

* change the default number of failures in check_assignment to 7

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* Fix high and medium priority API coherence issues (Go, Java, C++, TypeScript) (#8983)

* Initial plan

* Add missing API functions to Go, Java, C++, and TypeScript bindings

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* qf-s-benchmark: debug build + seq tracing + seq-fast/nseq-slow trace analysis (#8988)

* Initial plan

* Update qf-s-benchmark: debug build, seq tracing, trace analysis

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* disable linear approximation by default to check the merge

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* set check_assignment to true

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* fix restore_x by recalulating new column values

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* fix restore_x by recalulating new column values

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* fix a memory leak

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

---------

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: ValentinPromies <44966217+ValentinPromies@users.noreply.github.com>
Co-authored-by: Valentin Promies <valentin.promies@rwth-aachen.de>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Angelica Moreira <48168649+angelica-moreira@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-03-15 06:13:04 -10:00
Lev Nachmanson
6d890fb026 Fix NLA optimization regression and relax restore_x
- Relax restore_x() to handle backup/current size mismatches: when
  backup is shorter (new columns added), call
  move_non_basic_columns_to_bounds() to find a feasible solution.
- Fix 100x performance regression in nonlinear optimization: save LP
  optimum before check_nla and return it as bound regardless of NLA
  result, so opt_solver::check_bound() can validate via full re-solve
  with accumulated NLA lemmas.
- Refactor theory_lra::maximize() into three helpers: max_with_lp(),
  max_with_nl(), and max_result().
- Add mk_gt(theory_var, impq const&) overload for building blockers
  from saved LP optimum values.
- Add BNH multi-objective optimization test (7/7 sat in <1s vs 1/7
  in 30s before fix).
- Add restore_x test for backup size mismatch handling.

Fixes #8890

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-10 16:38:08 -10:00
Lev Nachmanson
78fa6d5ee8 allow calling lp().restore_x() only in case the number of column in lp() remained the same: it might grow
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
2026-03-09 10:51:31 -10:00
copilot-swe-agent[bot]
391febed3b Fix null pointer dereferences and uninitialized variables from discussion #8891
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-03-09 16:51:12 +00:00
Lev Nachmanson
6ec40153cc fix #7677: treat FC_CONTINUE from check_nla as FEASIBLE in maximize
When check_nla returns FC_CONTINUE it means NLA found constraint
violations and added lemmas. The current LP value is a valid lower
bound, so the status should be FEASIBLE, not UNBOUNDED.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-27 12:29:14 -10:00
copilot-swe-agent[bot]
4860d57ae9 Fix intblast ubv_to_int bug: add bv2int axioms for compound expressions
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-25 00:46:13 +00:00
copilot-swe-agent[bot]
46daa160ed Fix FPA soundness issue: reset rewriter cache in pop_scope_eh (issue #8345)
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-21 03:35:47 +00:00
Nikolaj Bjorner
38ce0882db remove lattice component
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-02-19 15:49:45 -08:00
copilot-swe-agent[bot]
866f352ea9 Fix ambiguous svector constructor calls in theory_finite_set_lattice_refutation.cpp
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-19 17:57:04 +00:00
Nikolaj Bjorner
86dc55691d add extra parameter
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-02-18 21:34:29 -08:00
Nikolaj Bjorner
7fe9b1f873
Merge branch 'master' into finite-sets 2026-02-18 21:11:44 -08:00
Nikolaj Bjorner
07d8971ef9 add sketch for incremental algorithm
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-02-18 21:10:17 -08:00
Nikolaj Bjorner
69b73c64cf enable post setup parameter tweaking in theory solvers, update azure-pipeline
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-02-18 21:08:24 -08:00
Nikolaj Bjorner
c32b213a20 add finite sets to datatype recursion, delay initialize finite_set plugin, fix bugs in are_distinct and equality simplification
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-02-18 21:07:40 -08:00
Nikolaj Bjorner
534361dee4 fix #8563 - align indices for flat quantifiers with sks vector layout, and also guard creating instantiation equalities with sort checks
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-02-18 21:02:29 -08:00
copilot-swe-agent[bot]
eedade141c Restore defensive SASSERT in smt_conflict_resolution
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-18 21:02:26 -08:00
copilot-swe-agent[bot]
d958036711 Add initializer_list overloads and update all call sites
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-18 21:02:26 -08:00
Copilot
d9c6da215f Eliminate unnecessary copies with std::move for ref-counted types (#8591) 2026-02-18 21:02:24 -08:00
Nikolaj Bjorner
c031058978 small update to testing on p.m_sls_worker instead of should_run_sls 2026-02-18 21:02:22 -08:00
Nuno Lopes
f6f8beaf78 Remove copies (#8583) 2026-02-18 21:02:22 -08:00
Nuno Lopes
23a0a529fb revert swap changes to fix CI 2026-02-18 21:02:18 -08:00
Nuno Lopes
bbb29911f3 fix crash 2026-02-18 21:02:17 -08:00
Nuno Lopes
9152013fbd remove a few copies 2026-02-18 21:02:17 -08:00
Nikolaj Bjorner
6b28d65487 set random seed directly on m_smt_params before context initialization
updates to random seed on ctx does not get propagated to arithmetic solver, preventing diversity within arithmetic solver.
2026-02-18 21:02:17 -08:00
Copilot
58431ec158 Replace user-defined swap with C++11 move semantics for covert move patterns (#8543) 2026-02-18 21:02:17 -08:00
copilot-swe-agent[bot]
119008b46f Fix all build warnings with surgical changes
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-18 20:58:05 -08:00
Copilot
adf72f2a66 Modern C++: Add std::span overload for mk_or, adopt std::clamp, optimize stream output (#8507)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-18 20:58:05 -08:00
Copilot
73f6dae095 Refactor mk_concat call sites to use std::initializer_list (#8494)
* Initial plan

* Refactor mk_concat call sites to use std::initializer_list

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-02-18 20:58:03 -08:00
Copilot
17c8958d70 Remove redundant default constructors when they're the only constructor (#8461)
* Initial plan

* Modernize C++ constructors to use C++11 default member initialization - Phase 1

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

* Fix theory_pb.h struct definition - move reset() back inside struct

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

* Modernize C++ constructors to use C++11 default member initialization - Phase 2

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

* Fix opt_solver.h - revert rational initialization (complex type)

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

* Modernize C++ constructors to use C++11 default member initialization - Phase 3

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

* Fix sparse_matrix.h - explicitly initialize union member in default constructor

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

* Remove unnecessary default constructors when they're the only constructor

Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>
2026-02-18 20:58:01 -08:00