3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-21 14:35:50 +00:00
Commit graph

5055 commits

Author SHA1 Message Date
CEisenhofer
ed41c2a09f Implemented some kind of regex range decomposition 2026-07-02 20:23:49 +02:00
CEisenhofer
e8884faa23 Fixed some partial automaton soundness problems 2026-07-02 20:23:48 +02:00
CEisenhofer
d1b0cbee34 Regex factorization needs special care when resuming after finding a sat node in-between 2026-07-01 19:29:29 +02:00
CEisenhofer
b7ef51ca04 Skip factorization in case we already eliminated some cycle 2026-07-01 19:05:38 +02:00
CEisenhofer
706f62286e Merge remote-tracking branch 'origin/master' into c3 2026-07-01 17:18:21 +02:00
CEisenhofer
1f448a10a3 Bug/Performance fixes
Added argument to harvest non-primitive membership constraint benchmarks
2026-07-01 14:47:36 +02:00
CEisenhofer
f5baba1068 Lazy regex factorization via iterator 2026-06-30 22:22:33 +02:00
Nikolaj Bjorner
c85e2ee2bd sort constraint
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-30 12:41:41 -07:00
Clemens Eisenhofer
b3143e759b
Porting seq_split to master (#9840)
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-30 10:18:28 -07:00
CEisenhofer
ccfc355edb Merge remote-tracking branch 'origin/port_seq_split_to_master' into c3 2026-06-30 13:25:27 +02:00
CEisenhofer
bb73558848 Fixed memory corruption 2026-06-30 12:35:06 +02:00
Nikolaj Bjorner
63259d8a43 add missing registration of lambdas with legacy array solver, add missing beta reduction axiom
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-29 19:13:46 -07:00
Nikolaj Bjorner
a1b926fea3 guard update to depth bound to avoid overflow
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-29 12:30:43 -07:00
CEisenhofer
93801ccc8e Minor corrections 2026-06-29 18:25:09 +02:00
CEisenhofer
6f1eafaa5c Better caching/hashing
First try for reintroducting subsumption
2026-06-29 16:52:16 +02:00
Lev Nachmanson
a5454ec375
[snapshot-regression-fix] smt_parallel: report unknown on theory-incomplete cubes instead of hanging (#9999)
## Summary

Fixes a hang (wall-clock timeout) in the native parallel SMT solver when
a cube is incomplete for a reason that cannot change. Originating
discussion: https://github.com/Z3Prover/bench/discussions/2746

Benchmark: `iss-3707/bug-1.smt2` (`QF_NRA`, runs with
`parallel.enable=true`).

## Divergence

The recorded oracle vs. current z3 (`z3 -T:20`):

```diff
-(incomplete (theory difference-logic))
-unknown
+timeout
```

z3 should terminate with `unknown` (incomplete theory) but instead spins
until the 20s timeout.

## Root cause

In `src/smt/smt_parallel.cpp` the per-cube worker handled an `l_undef`
cube by unconditionally calling `update_max_thread_conflicts()` and
re-splitting/re-checking. That only helps when the cube was abandoned at
the per-cube conflict limit (`max-conflicts-reached`). When the cube is
incomplete for a permanent reason (incomplete theory, quantifiers,
resource limits), the verdict never changes, so the worker re-checks the
same cube forever. The `batch_manager` had no `unknown` terminal state,
so `get_result()` could only end as sat/unsat/exception — there was no
way to settle on `unknown`, hence the hang. This is the `smt_parallel`
analogue of the `parallel_tactical.cpp` regression fixed earlier.

## Fix

Minimal, mirroring the tactic-side fix:
- add an `is_unknown` batch-manager state + `m_reason_unknown`;
- a worker reporting `l_undef` whose `last_failure` is not
`max-conflicts-reached` calls `set_unknown(reason)` and stops
re-splitting;
- `set_sat`/`set_unsat` may still override `is_unknown` so a definitive
answer wins;
- `get_result()` maps `is_unknown -> l_undef` and the reason propagates
to the parent context.

## Validation

Rebuilt z3 (`make -C build -j16`) and re-ran the benchmark 5× with
`-T:20`. Every run finished in well under the timeout with output
matching the oracle byte-for-byte:

```
(incomplete (theory difference-logic))
unknown
```

Created as a **draft** for human review.




> Generated by [Fix a Z3 snapshot-regression
divergence](https://github.com/Z3Prover/bench/actions/runs/28358375255)
· 553.9 AIC · ⌖ 27.2 AIC · ⊞ 9K ·
[◷](https://github.com/search?q=repo%3AZ3Prover%2Fz3+%22gh-aw-workflow-id%3A+snapshot-regression-fixer%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: Fix a Z3 snapshot-regression divergence,
engine: copilot, version: 1.0.63, model: claude-opus-4.8, id:
28358375255, workflow_id: snapshot-regression-fixer, run:
https://github.com/Z3Prover/bench/actions/runs/28358375255 -->

<!-- gh-aw-workflow-id: snapshot-regression-fixer -->
<!-- gh-aw-workflow-call-id: Z3Prover/bench/snapshot-regression-fixer
-->

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-29 06:55:24 -07:00
Nikolaj Bjorner
d5cf8e6263 tweaks to string solver
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-28 17:16:52 -07:00
Nikolaj Bjorner
1745d271b4
Modify thread allocation logic in smt_parallel.cpp 2026-06-28 16:33:46 -07:00
Nikolaj Bjorner
ef66acc6b5 change calculation of threads to use total threads indicated by parameter or processor count, subtract from worker threads based on backbone and core threads
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-28 12:43:58 -07:00
Nikolaj Bjorner
dbe0cf9312 disregard skolems in instantiation set?
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-28 12:04:56 -07:00
CEisenhofer
cc42304f60 Different slices of the same variable have the same hash 2026-06-28 14:36:35 +02:00
CEisenhofer
79cdc91a75 Explicit formula for length computation of regexes 2026-06-28 14:14:52 +02:00
CEisenhofer
e983bc76d4 Try to do some processing already during assignments 2026-06-27 12:53:57 +02:00
Nikolaj Bjorner
612fab1c9a
Parallel tactic (#9824) (#9825)
Add new parallel algorithm as a tactic (parallel_tactical2.cpp)
Don't port over old experiments from smt_parallel that we aren't using
(sls, inprocessing, failed_literal_mode for bb detection)
Fix bugs: lease cancellation/reslimit race condition, involves changing
lease epoch to simple boolean flag
Also, now there is a single shared set of params for the tactic and
smt_parallel

**Test runs for the parallel_tactical2 vs old smt_parallel version:**
run-2747-Z3-threads-4-qflia-30s-stats.md
run-2746-Z3-threads-4-qflia-30s-parallel_tactic-stats.md
run-2745-Z3-threads-1-qfbv-30s-stats.md
run-3013-Z3-threads-4-qfbv-30s-parallel_tactic-stats.md --> note this is
indeed run-3013, I reran after a bugfix in inc_sat_solver
run-2743-Z3-threads-4-qfnia-30s-stats.md
run-2742-Z3-threads-4-qfnia-30s-parallel_tactic-stats.md

**Test runs for the new smt_parallel with bugfixes:**
run-2801-Z3-threads-4-qflia-30s-smtparallel-bugfixes-stats.md,
run-2800-Z3-threads-4-qflia-30s-smtparallel-bugfixes-stats.md
run-2797-Z3-threads-4-qfnia-30s-smtparallel-bugfixes-stats.md
compare to old smt_parallel:
run-2747-Z3-threads-4-qflia-30s-stats.md
run-2743-Z3-threads-4-qfnia-30s-stats.md

Note that there is a slight regression on lia in run-2800. The source of
this appears to be the new new LP largest-cube LIA heuristic param,
which is enabled by default. disabling this param in run-2801 restored
performance (I didn't change this in this PR though, just something to
note)

http://mtzguido.tplinkdns.com:8081/z3/compare_stats.html

---------

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.localdomain>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-26 10:36:15 -06:00
CEisenhofer
a88dfa64ac Lazy decomposition
Test-cases
2026-06-26 17:37:40 +02:00
Nikolaj Bjorner
15f33f458d
Derive with ranges (#9965)
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Margus Veanes <margus@microsoft.com>
Co-authored-by: Margus Veanes <veanes@users.noreply.github.com>
2026-06-26 08:44:13 -06:00
CEisenhofer
fc2124890e Guard for powers at unwinding regexes seems to got lost 2026-06-26 15:38:50 +02:00
CEisenhofer
63a668a71f Give up with we have nasty replace_all or friends (otw. we would be unsound due to Nielsen saturation) 2026-06-26 15:14:44 +02:00
CEisenhofer
ff7cbe9406 Copy elements from propagation queue before propagating them. The memory might get invalidated inbetween 2026-06-26 11:08:54 +02:00
CEisenhofer
d2db79e1a7 For whatever reason int-extraction got moved into an assertion
Cleanup
2026-06-26 10:38:08 +02:00
Nikolaj Bjorner
f034616950
Revert "Derive with ranges" (#9964)
Reverts Z3Prover/z3#9963
2026-06-25 19:57:30 -06:00
Nikolaj Bjorner
22c2635786
Derive with ranges (#9963)
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Margus Veanes <margus@microsoft.com>
Co-authored-by: Margus Veanes <veanes@users.noreply.github.com>
2026-06-25 19:47:25 -06:00
CEisenhofer
af0c0efae9 Branch on all minterms to speed up partial automata construction 2026-06-25 17:03:29 +02:00
CEisenhofer
2aa1d1ee01 Memorize previous conflicts 2026-06-25 15:40:53 +02:00
CEisenhofer
64fed10e86 Projection operator => view 2026-06-25 10:48:20 +02:00
Nikolaj Bjorner
6fd303c4b9 set the auf flag to false in all cases
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-24 20:38:15 -07:00
Lev Nachmanson
d1170d19bd
[snapshot-regression-fix] Bound ho_var term enumeration to fix MBQI timeout regression (iss-5753/small-3.smt2) (#9939)
## Summary

Fixes a Z3 snapshot-regression divergence tracked in Z3Prover/bench
discussion
https://github.com/Z3Prover/bench/discussions/2662.

- **Benchmark:** `iss-5753/small-3.smt2` (Z3Prover/bench corpus,
original issue z3#5753)
- **Regression:** recorded oracle `unsat` (captured 2026-06-05) →
current `master` produces `timeout` at `-T:20`
- **bench workflow run:**
https://github.com/Z3Prover/bench/actions/runs/28078176175

### Divergence

```diff
--- small-3.expected.out (expected)
+++ produced (current z3)
@@ -1 +1 @@
-unsat
+timeout
```

The answer `unsat` is still correct — z3 simply can no longer prove it
within the
budget. This is a **performance regression**, not a wrong/unsound
result.

## Root cause

The benchmark is a quantified Array/Real/Int problem solved via MBQI.
The model
finder's quantifier analyzer (`src/smt/smt_model_finder.cpp`) now
creates a
`ho_var` qinfo for **array-sorted quantified variables used as terms**
(the new
higher-order term-enumeration path introduced in #9908, "Term
enumeration",
commit `5699142f5`). Before that commit such an occurrence set
`m_info->m_is_auf = false` (a safe fallback that left no extra
instantiation
hints), which is the behaviour that was active when the `unsat` oracle
was
captured.

`ho_var::populate_inst_sets` builds instantiation candidates with:

```cpp
for (auto t : tn.enum_terms(srt)) {
    ...
    S->insert(t, generation);
}
```

`term_enumeration::enum_terms` is a **lazy, increasing-cost generator
with no
inherent bound** (see `ast/rewriter/term_enumeration.h`). For this
benchmark the
relevant array sort `(Array Int (Array Int Real))` has many array-valued
uninterpreted productions (`tptpummul`, `trans`, `inv`, ...), so
iterating the
generator to exhaustion inserts an explosively large number of terms
into the
instantiation set, blowing up MBQI instantiation and exhausting the 20s
budget.

Confirmed empirically: running the benchmark with `-v:3` shows
`ho_var::populate_inst_sets: 622 (Array Int (Array Int Real))`, i.e.
this exact
path fires for the divergent benchmark.

Notably, the original commit `5699142f5` declared `unsigned max_count =
20;` for
this very loop but **never applied it**, and that dead variable was
subsequently
removed — leaving the enumeration completely unbounded.

## Fix

Restore the intended bound so at most 20 of the cheapest enumerated
terms are
added to the instantiation set:

```cpp
unsigned max_count = 20;
for (auto t : tn.enum_terms(srt)) {
    if (max_count == 0)
        break;
    --max_count;
    ...
    S->insert(t, generation);
}
```

This is sound (instantiation only ever adds valid ground instances of
the
quantified formula) and is strictly more information than the pre-#9908
baseline
(which added no `ho_var` terms at all), so it does not regress problems
the
feature was meant to help. The change is confined to a single loop in
`src/smt/smt_model_finder.cpp`.

## Validation

Built the checkout in Release mode and re-ran the failing benchmark with
the
same options the snapshot harness uses:

```
$ build/z3 -T:20 inputs/issues/iss-5753/small-3.smt2
unsat        # was: timeout

real    0m0.120s
```

The combined output now matches the recorded `small-3.expected.out`
oracle
**byte-for-byte** (`unsat\n`). A smoke run over a sample of other corpus
benchmarks showed no crashes or new divergences, and a basic
`(check-sat)/(get-model)` sanity check still works.

---

This PR is opened as a **draft** for human review by the automated
snapshot-regression fixer.

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




> Generated by [Fix a Z3 snapshot-regression
divergence](https://github.com/Z3Prover/bench/actions/runs/28078343154)
· 2.8K AIC · ⌖ 150.7 AIC · ⊞ 39K ·
[◷](https://github.com/search?q=repo%3AZ3Prover%2Fz3+%22gh-aw-workflow-id%3A+snapshot-regression-fixer%22&type=pullrequests)

<!-- gh-aw-agentic-workflow: Fix a Z3 snapshot-regression divergence,
engine: copilot, version: 1.0.60, model: claude-opus-4.8, id:
28078343154, workflow_id: snapshot-regression-fixer, run:
https://github.com/Z3Prover/bench/actions/runs/28078343154 -->

<!-- gh-aw-workflow-id: snapshot-regression-fixer -->
<!-- gh-aw-workflow-call-id: Z3Prover/bench/snapshot-regression-fixer
-->

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 11:58:32 -06:00
Nikolaj Bjorner
cb3d058067 fix build warnings 2026-06-22 18:20:23 -07:00
Nikolaj Bjorner
5699142f5b
Term enumeration (#9908)
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: davedets <daviddetlefs@gmail.com>
Co-authored-by: Lev Nachmanson <5377127+levnach@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Margus Veanes <veanes@users.noreply.github.com>
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Co-authored-by: Shantanu Gontia <gontia.shantanu@gmail.com>
Co-authored-by: Peter Chen J. <34339487+peter941221@users.noreply.github.com>
Co-authored-by: Alcides Fonseca <me@alcidesfonseca.com>
Co-authored-by: Can Cebeci <can.cebeci99@gmail.com>
Co-authored-by: Can Cebeci <t-cancebeci@microsoft.com>
2026-06-20 18:14:44 -06:00
Nikolaj Bjorner
871b98169f fix rewriting of complemnt of ranges
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-20 11:08:00 -07:00
Nikolaj Bjorner
d9385e9713 extend cases for process_formulas_on_stack
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-18 12:45:45 -07:00
Nikolaj Bjorner
728ac39a59 flexible handling with quantifiers
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-18 12:43:27 -07:00
Nikolaj Bjorner
225ac56f5a extend cases for process_formulas_on_stack
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-18 12:39:45 -07:00
davedets
86de0cbd71
Eliminate unused private fields and local variables. (#9875)
This is another PR towards the goal of getting a clean build with clang,
using the compiler options used in building clang-tidy.

By default, without any new -W flags, clang warns about unused local
variables and private class fields. This PR deletes the handful of these
that clang found.

I'm assuming that the class "enode" in smt_context.cpp is the one in
smt_enode.h, so that
```
parent->get_expr()
```
calls a const method with no side effects.
2026-06-16 14:55:18 +01:00
Lev Nachmanson
f508854fe5
Lcube (#9858)
Implemented the largest cube heuristic from Bromberger and Weidenbach's
paper on cubes. Also fixes an overflow bug in mzp.
Use vswhere to find the visual studio version on windows in the build's ymls.
---------

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-14 16:25:21 -07:00
CEisenhofer
1feb610daa Probably quite instable, but included the splitting into the legacy solver 2026-06-12 17:05:38 +02:00
CEisenhofer
f126b60369 Giving up is still no conflict 2026-06-11 16:27:59 +02:00
CEisenhofer
b9d5f273ee Removed logging 2026-06-11 16:14:07 +02:00
CEisenhofer
fd8100475c Eliminate top-level nonsense cases from regex decomposition 2026-06-11 16:01:08 +02:00
CEisenhofer
be627007e1 Use lookahead for regex decomposition
Make snode const
2026-06-11 15:34:25 +02:00