3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-06-28 03:18:49 +00:00
Commit graph

18515 commits

Author SHA1 Message Date
Nikolaj Bjorner
5d23edd473 adding choice
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-27 08:59:19 -07:00
CEisenhofer
c640bf2a2b Disequalities prevent a fast-check 2026-05-27 17:59:14 +02:00
CEisenhofer
dc7c94a3ac le != lt 2026-05-27 17:37:39 +02:00
CEisenhofer
b7f9019a6e Duplicate function signature 2026-05-27 17:29:06 +02:00
CEisenhofer
0fa1e75f3f Remove redundant function 2026-05-27 17:27:48 +02:00
CEisenhofer
e74b235d87 Solve disequalities lazily 2026-05-27 17:25:39 +02:00
ValentinPromies
f124cacf1e
fix edge case in algebraic number comparison (#9498)
So far, `algebraic_numbers compare_core ` handles an edge case
incorrectly:
- If the two compared numbers (`a`, `b`) are different,
- the intervals still overlap after refinements, and
- both a and b are a root of the second polynomial (`cell_b->m_p`), e.g.
they are the first and second root

then the method would return `sign_zero` (i.e. "equal"). This behavior
can be replicated with the provided test case (before the fix). This
requires `algebraic.factor=false`, though i first encountered it during
solver runs on QF_NRA instances with the default
`algebraic.factor=true`, which apparently means that the polynomials for
anums are still not always factored.

The fix is to compare the interval bounds of b to a and vice versa. Then
the Sturm-Tarski check is only run if `a` and `b` both lie in the
intersection of the intervals, because only then is it guaranteed to be
correct.
2026-05-27 05:01:47 -07:00
Copilot
316d249b3f
SMT2 front-end: accept HO_ALL and normalize curried expression-head applications (#9636)
The SMT2 front-end rejected valid higher-order inputs using `HO_ALL` and
failed on curried applications where the function position is itself an
expression (e.g., `((transfer top) 0)`).
This update adds `HO_ALL` support and makes curried parsing consistently
lower to implicit `select` chains.

- **Logic recognition**
  - Treat `HO_ALL` as an `ALL`-class logic in SMT logic classification.
- This unblocks `(set-logic HO_ALL)` in the standard SMT2 command path.

- **Curried application parsing**
- Extend application-frame handling to support parenthesized expression
heads, not only symbol heads.
- When the head is an expression, parse application arguments normally
and construct nested implicit selects:
    - `(f a b)` → `(select (select f a) b)`
- Preserve existing behavior for symbol-based applications, qualified
identifiers, and lambda-led forms.

- **Regression coverage**
- Add a focused parser/eval regression using the reported higher-order
case to lock in behavior.

```smt2
(set-logic HO_ALL)
(declare-fun transfer () (-> (-> Int Bool) (-> Int Bool)))
(assert (forall ((P (-> Int Bool))) (=> (P 0) ((transfer P) 0))))
(declare-fun top () (-> Int Bool))
(assert (forall ((x Int)) (top x)))
(assert (not ((transfer top) 0)))
(check-sat)
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-26 18:39:38 -07:00
Arie
73151f1960
nla_grobner: add mod_residue pattern to propagate_quotients (#9597)
Adds a new lemma pattern to nla_grobner::propagate_quotients that
derives a modular-residue constraint from polynomial divisibility,
filling a gap between quotient1-5 (model-value-driven case splits) and
the polynomials Grobner actually produces on Skolem-encoded mod
arithmetic.

Pattern
-------

For a polynomial p with all-integer free variables and a linear monomial
c_v * v (single integer var), the pattern computes M = gcd(|c_i/c_v|)
over the other monomials and K = c0/c_v for the constant term. When both
are integers, dividing p by c_v gives

    v + M*Q + K = 0   with Q an integer

so v ≡ -K (mod M). The pattern emits the sound disjunctive lemma

    (v < 0)  ∨  (v ≥ M)  ∨  (v = target)

where target = (-K) mod M ∈ [0, M-1]. This encodes "v ∈ target + M·Z" in
a form the LP / SAT layer can refute against current bounds.

Motivation
----------

QF_UFNIA verification benchmarks over fixed-prime modular arithmetic
(e.g. zk applications using the BabyBear prime 2013265921) regularly
produce basis polynomials of the form

    -p*v_div + p*(v_a * v_b) - v_mod = 0

where v_mod is the result of (mod (* v_a v_b) p). The polynomial sits in
the Grobner basis but none of quotient1-5 fires: they all require
specific model-value alignments (r_value == 0, |v_value| > |r_value|,
etc.) that don't hold when all variables in scope are similarly sized
integers in [0, p). The proof spins on interval-tightening lemmas
without ever extracting the modular conclusion.

The author of propagate_quotients flagged this gap with the comment
\"other division lemmas are possible\" preceding the fall-through \"no
lemmas found\" CTRACE. This patch supplies one.

Soundness
---------

The lemma is sound regardless of v's LP bounds — the bound-negation
disjuncts (v < 0) and (v ≥ M) make the disjunction unconditionally true
under the polynomial identity, with v = target as the canonical residue
in [0, M-1]. M is derived from the polynomial's coefficient gcd, not
from any LP-side bound.

Validated under smt.arith.validate=true on the mod-factor-propagation
reproducers (PR #9235 follow-up), zk verifier benchmarks, and a broader
QF_UFNIA sample — 50+ files total, zero validate_conflict() assertion
violations.

Performance
-----------

A model-value gate (skip emission when v's current value already
satisfies one of the disjuncts) prevents the pattern from
short-circuiting the propagate_quotients || propagate_gcd_test ||
propagate_eqs || propagate_factorization || propagate_linear_equations
chain with redundant emissions. Without the gate, a single (v, M,
target) triple can re-emit each Grobner round and starve the downstream
propagators — observed in regression testing as thousands of identical
emissions on a small benchmark, turning a sub-second closure into a
timeout.

On six small mod-factor-propagation reproducers, the patch closes four
cases that previously timed out at 30 s (~1 s typical under the
Grobner-ramped config: smt.arith.nl.gr_q=50,
smt.arith.nl.grobner_eqs_growth=50,
smt.arith.nl.grobner_exp_delay=false, smt.arith.nl.grobner_frequency=1).
The two remaining timeouts in that set are attributable to different
gaps (Boolean-disjunction propagation, and the multi-bounded-mod-result
polynomial shape that needs Grobner over Z/pZ), not to mod_residue
itself.

Diagnostics
-----------

TRACE under the existing 'grobner' tag emits one line per lemma
emission, recording v, M, c_v, c0, and target.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-26 18:12:38 -07:00
Can Cebeci
c3f5365a95
Update generation number of already-internalized enodes (#9628)
Below are the effects on Mariposa's unsat core:

| Query | Unsats before | Unknowns before | Timeouts before | Unsats
after | Unknowns after | Timeouts after | Delta Unsat | Delta Unknown |
Delta Timeout |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
d_fvbkv-Betree-BetreeInv.i.dfy.Impl__BetreeInv.__default.FlushPreservesLookups.smt2
| 94 | 5 | 1 | 99 | 0 | 1 | +5 | -5 | +0 |
|
d_fvbkv-ByteBlockCacheSystem-ByteSystem.i.dfy.Impl__ByteSystem.__default.ReqWrite2StepPreservesInv.smt2
| 41 | 0 | 59 | 44 | 0 | 56 | +3 | +0 | -3 |
|
d_fvbkv-ByteBlockCacheSystem-InterpretationDisk.i.dfy.Impl__InterpretationDisk.__default.RefinesProcessWrite.smt2
| 75 | 25 | 0 | 99 | 1 | 0 | +24 | -24 | +0 |
|
d_fvbkv-Impl-FlushPolicyImpl.i.dfy.Impl__FlushPolicyImpl.__default.runFlushPolicy.smt2
| 12 | 0 | 88 | 6 | 0 | 94 | -6 | +0 | +6 |
| d_fvbkv-Impl-IOImpl.i.dfy.Impl__IOImpl.__default.PageInNodeResp.smt2 |
84 | 0 | 16 | 81 | 0 | 19 | -3 | +0 | +3 |
|
d_fvbkv-Impl-JournalistModel.i.dfy.CheckWellformed__JournalistModel.__default.append.smt2
| 88 | 12 | 0 | 99 | 1 | 0 | +11 | -11 | +0 |
|
d_fvbkv-Impl-QueryImpl.i.dfy.Impl__QueryImpl.__default.queryIterate.smt2
| 48 | 0 | 52 | 43 | 0 | 57 | -5 | +0 | +5 |
|
d_fvbkv-lib-Base-BitsetLemmas.i.dfy.Impl__BitsetLemmas.__default.set__bit__to__0__self__uint64.smt2
| 100 | 0 | 0 | 100 | 0 | 0 | +0 | +0 | +0 |
|
d_fvbkv-lib-Base-BitsetLemmas.i.dfy.Impl__BitsetLemmas.__default.set__bit__to__1__self__uint64.smt2
| 100 | 0 | 0 | 100 | 0 | 0 | +0 | +0 | +0 |
|
d_fvbkv-lib-Buckets-KMBPKVOps.i.dfy.Impl__KMBPKVOps.__default.IndexFillDpkv.smt2
| 42 | 0 | 58 | 41 | 0 | 59 | -1 | +0 | +1 |
|
d_fvbkv-lib-Buckets-PackedKV.i.dfy.Impl__PackedKV.__default.BinarySearchQuery.smt2
| 78 | 5 | 17 | 92 | 1 | 7 | +14 | -4 | -10 |
|
d_fvbkv-lib-Buckets-PackedStringArray.i.dfy.Impl__PackedStringArray.__default.UniqueRepr.smt2
| 100 | 0 | 0 | 100 | 0 | 0 | +0 | +0 | +0 |
|
d_fvbkv-lib-Buckets-PackedStringArray.i.dfy.Impl__PackedStringArray.__default.WFpsaSubSeq.smt2
| 90 | 1 | 9 | 82 | 0 | 18 | -8 | -1 | +9 |
|
d_fvbkv-lib-DataStructures-BtreeModel.i.dfy.Impl__BtreeModel.__default.SplitIndexAllKeys.smt2
| 8 | 0 | 92 | 9 | 0 | 91 | +1 | +0 | -1 |
|
d_fvbkv-lib-DataStructures-LruImpl.i.dfy.Impl__LruImpl.LruImplQueue.Use.smt2
| 92 | 5 | 3 | 97 | 0 | 3 | +5 | -5 | +0 |
|
d_fvbkv-lib-DataStructures-MutableBtree.i.dfy.Impl__MutableBtree.__default.SubIndex.smt2
| 44 | 28 | 28 | 50 | 2 | 48 | +6 | -26 | +20 |
|
d_fvbkv-lib-DataStructures-MutableBtree.i.dfy.Impl__MutableBtree.__default.SubReprLowerBound.smt2
| 96 | 4 | 0 | 98 | 2 | 0 | +2 | -2 | +0 |
|
d_fvbkv-lib-Marshalling-GenericMarshalling.i.dfy.Impl__GenericMarshalling.__default.MarshallArray.smt2
| 46 | 54 | 0 | 76 | 24 | 0 | +30 | -30 | +0 |
|
d_fvbkv-lib-Marshalling-GenericMarshalling.i.dfy.Impl__GenericMarshalling.__default.MarshallUint32Array.smt2
| 81 | 19 | 0 | 96 | 3 | 1 | +15 | -16 | +1 |
|
d_fvbkv-lib-Marshalling-GenericMarshalling.i.dfy.Impl__GenericMarshalling.__default.MarshallUint64Array.smt2
| 85 | 15 | 0 | 95 | 5 | 0 | +10 | -10 | +0 |
|
d_fvbkv-lib-Marshalling-Math.i.dfy.Impl__Math.__default.lemma__2toX.smt2
| 74 | 26 | 0 | 100 | 0 | 0 | +26 | -26 | +0 |
|
d_fvbkv-lib-Marshalling-Math.i.dfy.Impl__Math.__default.lemma__div__denominator.smt2
| 93 | 0 | 7 | 99 | 0 | 1 | +6 | +0 | -6 |
|
d_fvbkv-lib-Math-mod_auto_proofs.i.dfy.Impl__Math____mod__auto__proofs__i.__default.lemma__mod__induction__forall2.smt2
| 67 | 0 | 33 | 67 | 0 | 33 | +0 | +0 | +0 |
|
d_fvbkv-lib-Math-mod_auto_proofs.i.dfy.Impl__Math____mod__auto__proofs__i.__default.lemma__mod__induction__forall.smt2
| 0 | 0 | 100 | 0 | 0 | 100 | +0 | +0 | +0 |
|
d_fvbkv-lib-Math-mul.i.dfy.Impl__Math____mul__i.__default.lemma__mul__nonnegative.smt2
| 0 | 0 | 100 | 0 | 0 | 100 | +0 | +0 | +0 |
|
d_komodo-verified-ptebits.i.dfyImpl___module.__default.lemma__l1ptesmatch.smt2
| 59 | 0 | 41 | 68 | 0 | 32 | +9 | +0 | -9 |
|
d_komodo-verified-secprop-conf_ni.i.dfyImpl___module.__default.lemma__initL2PTable__loweq__pdb.smt2
| 81 | 0 | 19 | 85 | 0 | 15 | +4 | +0 | -4 |
|
d_komodo-verified-sha-sha256-body-00-15.gen.dfyImpl___module.__default.va__refined__Body__00__15UnrolledRecursive.smt2
| 0 | 0 | 100 | 0 | 0 | 100 | +0 | +0 | +0 |
|
d_komodo-verified-sha-sha256-body-16-xx.gen.dfyImpl___module.__default.va__refined__Body__16__XXUnroller.smt2
| 8 | 0 | 92 | 9 | 0 | 91 | +1 | +0 | -1 |
|
d_komodo-verified-sha-sha256.i.dfyImpl___module.__default.lemma__SHA256FinalHelper1.smt2
| 95 | 0 | 5 | 95 | 1 | 4 | +0 | +1 | -1 |
|
d_komodo-verified-verify.gen.dfyImpl___module.__default.va__lemma__svc__returning__verify__inner_k.smt2
| 9 | 0 | 91 | 6 | 0 | 94 | -3 | +0 | +3 |
|
d_komodo-verified-verify.gen.dfyImpl___module.__default.va__lemma__svc__returning__verify__inner.smt2
| 69 | 0 | 31 | 61 | 0 | 39 | -8 | +0 | +8 |
|
d_komodo-verified-verify.gen.dfyImpl___module.__default.va__lemma__svc__returning__verify.smt2
| 85 | 0 | 15 | 78 | 0 | 22 | -7 | +0 | +7 |
|
d_lvbkv-Impl-BucketGeneratorModel.i.dfy.Impl__BucketGeneratorModel.__default.GenComposeIsCompose.smt2
| 53 | 0 | 47 | 53 | 0 | 47 | +0 | +0 | +0 |
|
d_lvbkv-Impl-JournalistImpl.i.dfy.Impl__JournalistImpl.Journalist.append.smt2
| 93 | 4 | 3 | 96 | 0 | 4 | +3 | -4 | +1 |
|
d_lvbkv-Impl-MarshallingImpl.i.dfy.Impl__MarshallingImpl.__default.strictlySortedPivotsToVal.smt2
| 5 | 0 | 95 | 0 | 0 | 100 | -5 | +0 | +5 |
|
d_lvbkv-lib-Base-total_order_impl.i.dfy.Impl__Total__Order__Impl.__default.ArrayLargestLtePlus1Linear.smt2
| 48 | 52 | 0 | 99 | 1 | 0 | +51 | -51 | +0 |
|
d_lvbkv-lib-Buckets-BucketsLib.i.dfy.Impl__BucketsLib.__default.WFProperSplitBucketInList.smt2
| 39 | 22 | 39 | 40 | 15 | 45 | +1 | -7 | +6 |
|
d_lvbkv-lib-Buckets-PackedKV.i.dfy.Impl__DynamicPkv.DynamicPkv.Append.smt2
| 80 | 0 | 20 | 80 | 0 | 20 | +0 | +0 | +0 |
|
d_lvbkv-lib-Buckets-PackedKV.i.dfy.Impl__PackedKV.__default.BinarySearchQuery.smt2
| 15 | 5 | 80 | 11 | 0 | 89 | -4 | -5 | +9 |
|
d_lvbkv-lib-Buckets-PackedStringArray.i.dfy.Impl__PackedStringArray.__default.psaCanAppendI.smt2
| 61 | 0 | 39 | 70 | 0 | 30 | +9 | +0 | -9 |
|
d_lvbkv-lib-Buckets-PackedStringArray.i.dfy.Impl__PackedStringArray.DynamicPsa.AppendSeq.smt2
| 2 | 0 | 98 | 4 | 0 | 96 | +2 | +0 | -2 |
|
d_lvbkv-lib-Checksums-BitLemmas.i.dfy.Impl__BitLemmas.__default.eq__from__unpack__LittleEndian__Uint32__eq.smt2
| 99 | 0 | 1 | 99 | 0 | 1 | +0 | +0 | +0 |
|
d_lvbkv-lib-DataStructures-LinearContentMutableMap.i.dfy.Impl__LinearContentMutableMap.__default.Realloc.smt2
| 1 | 0 | 99 | 0 | 0 | 100 | -1 | +0 | +1 |
|
d_lvbkv-lib-DataStructures-LinearDList.i.dfy.Impl__DList.DList.InsertAfter.smt2
| 0 | 0 | 100 | 0 | 0 | 100 | +0 | +0 | +0 |
|
d_lvbkv-lib-DataStructures-LinearDList.i.dfy.Impl__DList.DList.InsertBefore.smt2
| 0 | 2 | 98 | 0 | 1 | 99 | +0 | -1 | +1 |
|
d_lvbkv-lib-DataStructures-MutableBtree.i.dfy.Impl__LMutableBtree.__default.InsertIndex.smt2
| 98 | 0 | 2 | 83 | 0 | 17 | -15 | +0 | +15 |
|
d_lvbkv-lib-Lang-LinearSequence.i.dfy.Impl__LinearSequence__i.__default.AllocAndMoveLseq.smt2
| 97 | 3 | 0 | 100 | 0 | 0 | +3 | -3 | +0 |
|
d_lvbkv-lib-Marshalling-GenericMarshalling.i.dfy.Impl__GenericMarshalling.__default.MarshallArray.smt2
| 79 | 21 | 0 | 77 | 23 | 0 | -2 | +2 | +0 |
|
d_lvbkv-lib-Marshalling-GenericMarshalling.i.dfy.Impl__GenericMarshalling.__default.MarshallByteArrayInterior.smt2
| 100 | 0 | 0 | 100 | 0 | 0 | +0 | +0 | +0 |
|
d_lvbkv-lib-Marshalling-GenericMarshalling.i.dfy.Impl__GenericMarshalling.__default.MarshallByteArray.smt2
| 94 | 6 | 0 | 98 | 2 | 0 | +4 | -4 | +0 |
|
d_lvbkv-lib-Math-Nonlinear.i.dfy.Impl__NonlinearLemmas.__default.div__denom__ge__1.smt2
| 91 | 9 | 0 | 97 | 3 | 0 | +6 | -6 | +0 |
|
d_lvbkv-MapSpec-TSJMap_Refines_ThreeStateVersionedMap.i.dfy.Impl__TSJMap__Refines__ThreeStateVersionedMap.__default.RefinesReplay.smt2
| 69 | 0 | 31 | 66 | 0 | 34 | -3 | +0 | +3 |
|
d_lvbkv-PivotBetree-PivotBetreeSpecRefinement.i.dfy.Impl__PivotBetreeSpecRefinement.__default.SplitChildrenConsistent.smt2
| 31 | 0 | 69 | 28 | 0 | 72 | -3 | +0 | +3 |
|
d_lvbkv-PivotBetree-PivotBetreeSpecWFNodes.i.dfy.Impl__PivotBetreeSpecWFNodes.__default.ValidSplitWritesInvNodes.smt2
| 100 | 0 | 0 | 99 | 0 | 1 | -1 | +0 | +1 |
| fs_dice-queries-ASN1.Low.Base-3.smt2 | 1 | 32 | 0 | 1 | 32 | 0 | +0 |
+0 | +0 |
| fs_dice-queries-L0.X509.AliasKeyTBS.Issuer-7.smt2 | 33 | 0 | 0 | 33 |
0 | 0 | +0 | +0 | +0 |
| fs_dice-queries-L0.X509.AliasKeyTBS.Subject-7.smt2 | 33 | 0 | 0 | 33 |
0 | 0 | +0 | +0 | +0 |
| s_komodo-1504.4.smt2 | 0 | 0 | 100 | 0 | 0 | 100 | +0 | +0 | +0 |

---------

Co-authored-by: Can Cebeci <t-cancebeci@microsoft.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-26 15:08:11 -07:00
Copilot
91205d2f60
Allow JS/WASM init to accept Deno-friendly wasm load paths (#9621)
The JS bindings currently assume the wasm can be located via the default
Emscripten path resolution, which can force Deno users into
`--allow-read`. This change lets callers provide a custom wasm load path
through `init(...)`, so Deno can resolve the packaged wasm asset without
filesystem reads.

- **Public init API**
- Extend the JS entrypoints (`node` and `browser`) so `init(...)`
accepts optional Emscripten module overrides.
- Surface a typed `Z3ModuleOverrides` shape with explicit support for
`locateFile(path, prefix)`.

- **Low-level initialization**
- Thread module overrides through the generated low-level wrapper
instead of always calling the Emscripten module factory with no
arguments.
  - Keep the default behavior unchanged when no overrides are provided.

- **Docs**
  - Document the Deno usage pattern in the published JS README.
- Clarify the `locateFile` signature and show the intended Deno 2.1+
`import.meta.resolve(...)` flow.

- **Focused coverage**
- Add unit tests for `node` and `browser` init to verify module
overrides are forwarded correctly.

Example:

```ts
import { init } from 'npm:z3-solver';

const api = await init({
  locateFile: (file, _prefix): string =>
    import.meta.resolve(`npm:z3-solver/build/${file}`),
});
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-05-26 14:02:04 -07:00
CEisenhofer
4cd908345a Prevent expressions in partial dfa being freed to early 2026-05-26 13:07:38 +02:00
Nikolaj Bjorner
8c989f8840 update tptp front-end 2026-05-25 09:31:25 -07:00
Nikolaj Bjorner
24bb93c3e4 nit 2026-05-24 15:48:10 -07:00
Nikolaj Bjorner
bb73d5fc8e remove redundant code
theory_array_full.cpp performs a similar unfolding of lambda definitions.
2026-05-24 15:39:54 -07:00
Nikolaj Bjorner
24248b3300 code nits 2026-05-24 13:14:25 -07:00
Nikolaj Bjorner
459629c662 bugfixes to ho_matcher
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-23 18:06:04 -07:00
Nikolaj Bjorner
4a90d31050 Update tptp_frontend.cpp 2026-05-23 13:29:01 -07:00
Nikolaj Bjorner
ea0964d195 enable higher-order matching in mam/smt_quantifier 2026-05-22 17:06:37 -07:00
Nikolaj Bjorner
98d0e7f27c updates to ho-matcher for lambdas 2026-05-22 14:16:06 -07:00
Nikolaj Bjorner
e7eef2432d allow mam work with ground patterns 2026-05-22 14:14:23 -07:00
Nikolaj Bjorner
95b3ffeb25 replace struct by class
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-22 14:14:23 -07:00
Nikolaj Bjorner
19166bd0b5 prepare for lambda unfolding in ho-matcher and selectively enable ho matching
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-22 13:25:01 -07:00
Nikolaj Bjorner
f40e4759e4 fixes to tptp 2026-05-22 13:25:00 -07:00
CEisenhofer
c18aa647e1 Removed recursion from regex unwinding 2026-05-22 15:15:48 +02:00
CEisenhofer
5dcc5efcdd Remove recursive paths from model construction 2026-05-22 14:56:17 +02:00
CEisenhofer
cedb13d045 First check for conflict and then sat 2026-05-22 14:38:07 +02:00
CEisenhofer
7ede1b9c3d re.plus is a regex as well 2026-05-22 14:03:22 +02:00
Can Cebeci
286b107d7d
Fix oversized enum (#9590)
Co-authored-by: Can Cebeci <t-cancebeci@microsoft.com>
2026-05-21 15:24:35 -07:00
Copilot
ce9cf4ad7b
Fix ARM64 nightly build: dotnet NuGet packaging broken under Ninja/cmake (#9589)
The Windows ARM64 nightly build (`mk_win_dist_cmake.py --arm64-only`)
was failing because the cmake-built `Microsoft.Z3` NuGet package was
produced without any native Windows DLL, causing the downstream dotnet
example build to fail.

## Root causes

- **Wrong DLL path in `Microsoft.Z3.csproj.in`**: Path included
`/$(_DN_CMAKE_CONFIG)/` (e.g., `.../RelWithDebInfo/libz3.dll`), but
`CMakeLists.txt` sets `CMAKE_RUNTIME_OUTPUT_DIRECTORY =
PROJECT_BINARY_DIR` with no config subdir. With Ninja single-config, the
DLL lands at `build-dir/libz3.dll`. The `Exists()` guard silently
excluded the DLL from the package.
- **Wrong runtime identifier**: ARM64 DLL was being packed under
`runtimes\win-x64\native` instead of `runtimes\win-arm64\native`.
- **Legacy copy fires for `net8.0`**: `Microsoft.Z3.targets` excluded
`netstandard`/`netcoreapp` but not modern TFMs like `net8.0`, so
`CopyToOutputDirectory` fired and failed trying to copy the absent
`win-x64` DLL.

## Changes

- **`src/api/dotnet/CMakeLists.txt`**: Introduce `Z3_DOTNET_WIN_RID`
cmake variable (`win-x64` / `win-x86` / `win-arm64`) derived from
`TARGET_ARCHITECTURE`; used at `configure_file` time.
- **`src/api/dotnet/Microsoft.Z3.csproj.in`**: Remove
`/$(_DN_CMAKE_CONFIG)` from the Windows DLL path; replace hardcoded
`runtimes\win-x64\native` with `runtimes\${Z3_DOTNET_WIN_RID}\native`.
- **`src/api/dotnet/Microsoft.Z3.targets`**: Add
`!$(TargetFramework.Contains('.'))` to the legacy-copy condition, which
correctly excludes `net5.0`/`net6.0`/`net7.0`/`net8.0` (all use dotted
TFMs) while keeping `net45`/`net472` etc.
- **`src/api/dotnet/Microsoft.Z3.props`**: Add explicit `arm64`
condition mapping `$(Platform) == 'arm64'` to
`runtimes\win-arm64\native\libz3.dll` for legacy .NET Framework ARM64
consumers.

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-05-21 11:18:03 -07:00
Copilot
34ba2962ef
Fix unsound array equality rewrite for const-array store chains (#9572)
Z3 could return `sat` for an unsatisfiable QF_ABV formula equating two
store chains over distinct constant arrays. The rewrite path for array
equalities was missing a necessary base-value constraint in
finite-domain cases where stores cannot cover all indices.

- **Root cause**
- In `array_rewriter::mk_eq_core`, equality rewriting for nested stores
over const-array bases did not enforce equality of the underlying const
values when the index domain size exceeds the number of updated indices.

- **Rewriter fix**
  - Added a sound rewrite branch for:
    - `store* ((as const ...) v)` vs `store* ((as const ...) w)`
  - When `|domain| > (#stores_lhs + #stores_rhs)`, rewrite now includes:
    - select equalities for touched indices (existing behavior)
    - **and** base-value equality `v = w` (new requirement)
- This prevents spurious models where only updated indices are
constrained.

- **Regression coverage**
- Added a focused regression in `src/test/mod_factor.cpp` that asserts
`unsat` for a minimized constant-array/store-chain BV case with
`(distinct x y)` and one store per side.

```cpp
(assert (distinct x y))
(assert (= (store A0 i0 e0) (store A1 i1 e1)))
(check-sat) ; expected: unsat
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-05-21 11:15:42 -07:00
Nikolaj Bjorner
af33dfaa7d detect quantifiers in patterns
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-21 10:37:36 -07:00
Nikolaj Bjorner
af7a4de258 update ignore 2026-05-21 10:37:36 -07:00
Filipe Marques
c33a725bd8
Expose Seq.mk_re_diff in ocaml bindings (#9584)
Noticed it was missing
2026-05-21 10:29:08 -07:00
Filipe Marques
ce6abd65db
Expose other mk_seq_replace variants in OCaml bindings (#9586)
Also update the documentation for the base `mk_seq_replace` function to
match the new inline documentation style.
2026-05-21 10:28:48 -07:00
CEisenhofer
2ea1c74071 Make var-nielsen case non-recursive 2026-05-21 19:12:15 +02:00
CEisenhofer
dafa3cf5bd Added feature (?) to SAT core to prefer the Nielsen assumptions during splitting 2026-05-21 19:06:45 +02:00
Lev Nachmanson
1323530001
tptp: share 0-arity decls across sorts to fix bare constant equality (#9587)
Fix the TPTP frontend so that a bare name used in an equality refers to
a single shared `func_decl`, regardless of how the surrounding context
coerces its sort.

## Problem

With the following input the conjecture was not proved:

```tptp
fof(a1,axiom, ! [X] : (X = a)).
fof(c1,conjecture, b = a).
```

`parse_atomic_formula` created bare names as 0-arity **Bool
predicates**, and `coerce_eq` later retyped them by calling
`m.mk_func_decl(...)` directly, without registering the result in
`m_decls`. So the `a` used inside `! [X] : (X = a)` (coerced to sort
`U`) and the `a` used inside `b = a` (left as Bool) ended up as two
unrelated `func_decl`s sharing only the name. The axiom no longer
constrained the conjecture.

## Fix

In `src/cmd_context/tptp_frontend.cpp`:

1. Add `mk_zero_arity_decl(name, range)` / `coerce_zero_arity(app*,
range)` helpers that memoize the 0-arity `func_decl` per `(name, target
sort)` in `m_decls`, delegating to the existing `mk_decl_or_ho_const`
for `U` and Bool targets.
2. Rewrite `coerce_eq` to use the new helpers and add an explicit Bool /
non-Bool retyping branch so a bare-Bool side is recast to the other
side's sort.
3. In `parse_atomic_formula`, when a bare name is immediately followed
by `=` or `!=`, create it as a non-predicate (sort `U`). Terms in
equalities are no longer first introduced as Bool predicates.
4. Reorder the constructor init-list so `m_univ` is initialized before
the pinned ref vectors (matches declaration order; silences
`-Wreorder`).

Net effect: every reference to a given name at a given sort yields the
same `func_decl`, eliminating duplicate-symbol bugs in equalities over
bare TPTP constants.

## Test

Added `fof-bare-constant-equality` to `src/test/tptp.cpp`. Without the
C++ change the new case asserts; with it, `./build/release/test-z3 /seq
tptp` reports `PASS`.

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

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 08:55:10 -07:00
CEisenhofer
ca12eae670 WIP: Undid internal constraints 2026-05-21 17:17:49 +02:00
Lev Nachmanson
43791ebf2a
Iss9139 fix (#9577)
Preserve the de-linearization of the linear constraints but fixing the
den bug. @ValentinPromies, that is what you had in mind.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 06:33:14 -07:00
Copilot
8e3be3ad1f
Prevent Spacer segfault on ADT CHCs by hardening datatype model-value construction (#9571)
Spacer can crash on small HORN/ADT benchmarks when model construction
reaches datatype enodes without a fully populated constructor state. The
failure manifested as a null/invalid-path dereference inside datatype
model value generation.

- **Root cause area: datatype model extraction path**
- Hardened `theory_datatype::mk_value` to handle incomplete theory state
safely instead of assuming constructor metadata is always present.
  - Added guarded fallback to a factory-provided datatype value when:
    - `th_var` is missing,
    - union-find lookup is invalid,
    - var data/constructor is unavailable.

- **Behavioral change**
- Missing constructor state now degrades to a safe model value
(`expr_wrapper_proc`) instead of crashing during model generation.

- **Regression coverage**
- Added a focused API regression in `src/test/api_datalog.cpp` using a
Spacer + ADT HORN script (with reproducing seed) to ensure the code path
executes without parser/runtime failure.

```cpp
// theory_datatype::mk_value fallback shape
if (v == null_theory_var || invalid_var_data || d->m_constructor == nullptr) {
    app* val = to_app(m_factory->get_some_value(n->get_sort()));
    return alloc(expr_wrapper_proc, val);
}
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-05-20 16:04:41 -07:00
Nikolaj Bjorner
eeddc94647 fix tptp errors
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-20 15:19:27 -07:00
Nikolaj Bjorner
2ba86c1ac3 benchmark patching
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-20 13:32:23 -07:00
CEisenhofer
315a09aea8 [WIP] Try to replace "recursive reusage" of variables by seq.slice 2026-05-20 17:24:57 +02:00
CEisenhofer
dd00dd7362 First step towards not-reusing variables 2026-05-20 10:11:50 +02:00
Copilot
bc6c38e7d3
[code-simplifier] Simplify api_ast.cpp by removing unreachable branch and stray comment (#9570)
This change simplifies recently touched API code in
`src/api/api_ast.cpp` without altering semantics. It removes an
unreachable error path in `Z3_get_index_value` and deletes an empty
comment in `Z3_mk_rec_func_decl`.

- **`Z3_get_index_value`: remove dead branch**
- After validating `a` is non-null and of kind `AST_VAR`, the conversion
to `var*` is already guaranteed by existing AST casting invariants.
- The redundant null-check/error-return branch was removed, leaving a
direct index return.

- **`Z3_mk_rec_func_decl`: remove noise**
  - Deleted a stray empty `//` line.

```cpp
// before
var* va = to_var(_a);
if (va) {
    return va->get_idx();
}
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;

// after
var* va = to_var(_a);
return va->get_idx();
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-05-19 13:56:17 -07:00
CEisenhofer
9bb0f7e337 Fix some IDE warnings 2026-05-19 16:03:21 +02:00
CEisenhofer
0d1ee09e62 Keep most of the Nielsen graph and do a hot-restart when only external literals changed 2026-05-19 15:33:20 +02:00
Nikolaj Bjorner
d4babf7181 safe instruction cache 2026-05-18 17:52:31 -07:00
CEisenhofer
6321a7c479 Implemented fast path for still satisfied Nielsen nodes 2026-05-18 14:42:06 +02:00