3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-06-19 15:16:29 +00:00
Commit graph

915 commits

Author SHA1 Message Date
CEisenhofer
043c6c0ad1 Merge branch 'master' into c3 2026-06-03 17:33:26 +02:00
Hari Govind V K
922f49e187
Fix MBP QEL soundness bug in datatype accessor elimination (#9571) (#9692)
Two fixes for mbp_dt_tg::apply() when encountering an accessor whose
argument has a different constructor in the model:

1. Don't call rm_accessor (which would assert a contradictory
recognizer, making the formula false). This prevents the original bug
where QEL returned 'false' for satisfiable formulas.

2. Branch on the model-assigned constructor for the accessor's argument.

The correct output should include the literal introduced in (2).
However, this fix does not produce it. Spacer is sound with this
over-approximation, as long as the counter example does not depend on
value of mismatched accessors (e.g. (tl nil)).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-03 07:23:21 -07:00
Nikolaj Bjorner
77f8b33794 re-enable unit tests 2026-06-02 10:39:41 -07:00
Nikolaj Bjorner
eaf7562a1d disable test in tptp, move to native lambdas 2026-06-02 10:38:51 -07:00
Nikolaj Bjorner
3e0a350411
Comment out ho_curried_application and ho_choice_expression tests
Comment out two test functions for debugging purposes.
2026-06-02 08:47:43 -07:00
Nikolaj Bjorner
358378a6f0 remove tptp from all
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-06-01 19:36:18 -07:00
Nikolaj Bjorner
94b981024e set up udoc relation to use datalog engine 2026-06-01 19:06:25 -07:00
Nikolaj Bjorner
c4366e57f8
Update udoc_relation.cpp 2026-06-01 17:22:06 -07:00
Nikolaj Bjorner
705569df24 add include directive 2026-06-01 11:39:18 -07:00
CEisenhofer
5b41c6eb9f Better tracking for debugging 2026-06-01 19:50:34 +02:00
Nikolaj Bjorner
ebdf031c8f ensure engine is datalog for dl_table and dl_util tests 2026-05-31 15:32:23 -07:00
Nikolaj Bjorner
24e5a6ae3f ensure base class has propagation
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-30 22:21:15 -07:00
Copilot
51da9db615
Add SMT-LIB choice support via array OP_CHOICE and instantiate choice axioms in array solvers (#9649)
This change wires SMT-LIB Hilbert choice parsing to a concrete
array-theory operator and ensures both array backends enforce the
expected semantic axiom. Previously, `(choice ((x T)) phi)` parsed as
NYI and had no solver-side instantiation path.

- **Parser: lower `choice_k` into array `OP_CHOICE`**
- `pop_quant_frame(choice_k)` now builds `(choice p)` instead of
throwing.
- Added parser include/use of array utilities to construct the term
directly from the generated lambda predicate.

- **Array decl plugin: add `OP_CHOICE` typing + surface syntax**
  - Added declaration support for `choice` with signature:
- `(Array T Bool) -> T` (encoded as `('a -> Bool) -> 'a` in HO view).
- Added recognizer/util helpers (`is_choice`, `mk_choice`) and exposed
`"choice"` in op names.

- **SMT array theory (`theory_array_full`): instantiate choice axiom**
  - Added instantiation for each encountered `choice(p)`:
    - `forall x . p(x) => p(choice(p))`
  - Integrated into internalization/relevancy paths and statistics.

- **SAT/SMT array backend (`sat/smt/array_*`): instantiate choice
axiom**
- Added new axiom record kind for choice, internalization hook,
assertion routine, and diagnostics/stat tracking.
  - Uses the same quantified implication schema as above.

- **Regression coverage**
- Extended SMT2 parser regression with an HO `choice` example to ensure
parser/eval pipeline accepts and processes choice terms.

Example of the now-supported input:

```smt2
(set-logic HO_ALL)
(declare-sort U 0)
(declare-fun P () (-> U Bool))
(assert (exists ((x U)) (P x)))
(assert (= witness (choice ((x U)) (P x))))
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-27 10:05:06 -07: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
Nikolaj Bjorner
8c989f8840 update tptp front-end 2026-05-25 09:31:25 -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
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
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
CEisenhofer
315a09aea8 [WIP] Try to replace "recursive reusage" of variables by seq.slice 2026-05-20 17:24:57 +02:00
Nikolaj Bjorner
2a36b9a68e split into context and sub-solver, move length force predicates to context-solver
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-17 19:01:03 -07:00
Nikolaj Bjorner
9d4feed0ae remove expr_ref from dependencies, only use literals that are true.
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-17 13:28:12 -07:00
Nikolaj Bjorner
b75acc5c14 replace seq::le by generic expr_ref
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-16 23:10:44 -07:00
Copilot
bd9326134c
Fix sat.smt=true model reconstruction for QF_UFBV with Bool-valued UF predicates (#9519)
`sat.smt=true` could return `sat` with an invalid model for QF_UFBV
formulas combining Bool-valued UFs and BV range constraints. The failure
came from broken model-trail reconstruction in `elim_unconstrained`,
where `ADD` entries were effectively turned into identity substitutions.

- **Root-cause fix: restore model-trail substitution composition**
- In `elim_unconstrained::update_model_trail`,
`generic_model_converter::ADD` entries now use `entry.m_def` (rewritten
through accumulated substitutions) instead of creating self-referential
const-to-const mappings.
- This re-enables correct back-substitution for eliminated unconstrained
terms during witness reconstruction.

- **Regression coverage: QF_UFBV + `sat.smt=true` + model validation**
  - Added a focused unit test in `src/test/simplifier.cpp` for:
    - Bool-valued UF predicate over BV vars
    - split BV range constraints (`bvuge` / `bvult`)
    - `:sat.smt true` and `:model_validate true`
- The test asserts the solver returns `sat` without emitting an
invalid-model error.

```cpp
// before (effectively no-op back-mapping)
new_def = m.mk_const(entry.m_f);
sub->insert(new_def, new_def, nullptr, nullptr);

// after (compose and apply recorded definition)
new_def = entry.m_def;
(*rp)(new_def);
sub->insert(m.mk_const(entry.m_f), new_def, nullptr, nullptr);
```

---------

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-14 04:19:37 -04:00
Copilot
ce07160d64
TPTP frontend: enforce implicit universal quantification for free variables and add regression coverage (#9527)
Discussion #9524 reported systematic TPTP result polarity errors
(notably `Unsatisfiable/Theorem` cases returned as `Satisfiable`) and
timeout-path instability in the frontend. The dominant issue was
semantic: free variables in FOF/CNF formulas were parsed as constants
instead of implicitly universally quantified variables.

- **Parser semantics: free variables now follow TPTP rules**
- In `/home/runner/work/z3/z3/src/cmd_context/tptp_frontend.cpp`, free
variables encountered while parsing an annotated formula are now
collected in formula scope and wrapped with a top-level `forall`.
- This applies to both term and atomic-formula paths, so variable
occurrences are treated consistently.
- Explicitly bound quantifier variables continue to take precedence over
implicit ones.

- **Scoped implementation cleanup**
- Added scoped state for implicit-variable collection to avoid leaking
parser state across formulas.
- Kept variable binding order stable so quantifier construction is
deterministic.

- **Timeout-path robustness**
- Updated frontend exception catches to `const&` in the TPTP stream
entrypoint to make timeout/error handling behavior consistent with
thrown exception forms.

- **Regression tests**
- Extended `/home/runner/work/z3/z3/src/test/tptp.cpp` with focused
cases for:
    - FOF free-variable implicit universal quantification.
    - CNF free-variable implicit universal quantification.

```tptp
cnf(c1,axiom, p(X)).
cnf(c2,axiom, ~ p(a)).
```

This now maps to `forall X. p(X)` plus `~p(a)`, yielding `% SZS status
Unsatisfiable` as expected.

---------

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-13 13:19:14 -04:00
Copilot
2f7ff62173
Fix soundness bug in fpa2bv mk_to_real: wrong exponent power for negative exponents (#9513)
`fpa2bv_converter::mk_to_real` computed `2^(1/|exp|)` instead of
`1/(2^|exp|)` for floats with negative exponents, causing the NRA solver
to reach contradictory conclusions and return spurious `unsat` for
satisfiable QF_FPLRA formulas.

## Root Cause

After the loop that evaluates `exp2 = |unbiased_exp|` as an integer, the
code took `1/exp2` (reciprocal of the integer) before calling
`mk_power`, yielding `2^(1/3)` instead of `2^(-3) = 1/8` for a float
with exponent -3:

```cpp
// Buggy
one_div_exp2 = mk_div(one, exp2);                       // 1/|exp|, not 1/2^|exp|
exp2 = mk_ite(exp_is_neg, one_div_exp2, exp2);
two_exp2 = mk_power(two, exp2);                         // 2^(1/3) ≠ 1/8 for exp=-3
```

## Fix

Compute the power of 2 first, then invert it:

```cpp
// Fixed
two_exp2 = mk_power(two, exp2);                         // 2^|exp|
one_div_two_exp2 = mk_div(one, two_exp2);               // 1/(2^|exp|)
two_exp2 = mk_ite(exp_is_neg, one_div_two_exp2, two_exp2);  // correct 2^exp
```

## Impact

- **QF_FPLRA**: `to_fp(RTZ, r)` with a symbolic real `r` constrained to
an interval containing a float's exact rational value now correctly
returns `sat`.
- **fp.to_real**: Fixes incorrect real-valued encoding for all floats
with negative exponents, including denormals (which adjust the exponent
by subtracting leading-zero count).

A regression test covering the reported case is added to
`src/test/fpa.cpp`.

---------

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-13 06:11:36 -04:00
Copilot
36fffb3a2f
TPTP frontend: fix TFF numeric atom typing, decimal literals, and $uminus (#9518)
This PR targets the main TFF frontend parsing failures: bare numeric
atoms were being treated as uninterpreted terms (`U`) in formula
position, decimal literals were not parsed, and `$uminus` was not
recognized as an arithmetic builtin. These issues caused widespread
parse/type failures in arithmetic-heavy TPTP inputs.

- **Numeric atom parsing in formulas (TFF)**
- Added a shared numeric-literal parser path for term/formula contexts.
- In atomic formulas, numeric LHS now parses as arithmetic numerals
before `=`/`!=` handling, avoiding `U` vs `Int/Real` mismatches.

- **Decimal literal support**
- Extended numeral parsing to accept `d.d` forms and construct `Real`
numerals.
- Keeps existing integer (`d`) and rational (`d/d`) behavior on the same
code path.

- **`$uminus` builtin support**
  - Added explicit handling for `$uminus(<arg>)` in term parsing.
- Enforces arity 1 and arithmetic-argument checks; maps directly to
arithmetic unary minus.

- **Focused regression coverage**
  - Added/updated TPTP unit cases for:
    - bare integer inequality: `31 != 12`
    - decimal arithmetic literal usage
    - `$uminus` in arithmetic predicates

Example of now-supported inputs:

```tptp
tff(c1,conjecture, 31 != 12).
tff(c2,conjecture, ~ $less(-3.25,-8.69)).
tff(c3,conjecture, $less($uminus(2),0)).
```

---------

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-13 06:03:53 -04:00
Copilot
1a2d3e0ebb
Integrate TPTP with internal APIs via cmd_context, add embedded-string TPTP regression tests, and fix TFF arithmetic/timeout regressions (#9483)
* Add shell-integrated self-contained TPTP frontend and CLI wiring

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/ba80bc5a-d80f-4d9f-8ed4-a962f697697c

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

* Fix TPTP frontend build integration and validate with tests

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/ba80bc5a-d80f-4d9f-8ed4-a962f697697c

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

* Address review feedback and clean up TPTP/frontend readability

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/ba80bc5a-d80f-4d9f-8ed4-a962f697697c

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

* Refine TPTP parser semantics and keying based on review feedback

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/ba80bc5a-d80f-4d9f-8ed4-a962f697697c

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

* Polish TPTP frontend keys/path checks and deduplicate skip logic

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/ba80bc5a-d80f-4d9f-8ed4-a962f697697c

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

* Add src/api include path to shell CMake target

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/e07bbe13-16bc-4cc6-92e8-1708981b04ad

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

* Use internal AST/cmd_context APIs in TPTP shell frontend

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/2a6b01d0-c799-4e44-aa73-ef228cb4402e

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

* Harden TPTP cmd_context integration and suppress check-sat echo

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/2a6b01d0-c799-4e44-aa73-ef228cb4402e

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

* Make TPTP check-sat stream redirection exception-safe

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/2a6b01d0-c799-4e44-aa73-ef228cb4402e

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

* Address review nits in TPTP internal API frontend

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/2a6b01d0-c799-4e44-aa73-ef228cb4402e

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

* Refine TPTP frontend ownership and stream restoration semantics

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/2a6b01d0-c799-4e44-aa73-ef228cb4402e

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

* Add TPTP regression files and test-z3 tptp test

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/dc1d46fc-4b6c-4f64-91a0-9fb57c73c166

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

* Adjust Agatha TPTP expectation and tidy test helper constant

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/dc1d46fc-4b6c-4f64-91a0-9fb57c73c166

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

* Harden tptp test command handling and readability

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/dc1d46fc-4b6c-4f64-91a0-9fb57c73c166

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

* Validate tptp test filenames against empty and traversal patterns

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/dc1d46fc-4b6c-4f64-91a0-9fb57c73c166

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

* Tighten tptp filename checks and rename output buffer constant

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/dc1d46fc-4b6c-4f64-91a0-9fb57c73c166

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

* Use read_tptp API directly in tptp unit test

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/f07170c1-549a-464c-89f8-fee973f9790f

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

* Clarify required tptp frontend extern flags in test

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/f07170c1-549a-464c-89f8-fee973f9790f

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

* Move tptp frontend to cmd_context and add string API

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/1be7cf7e-2747-43ba-9a33-2e71dad2d14d

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

* Polish tptp stream parser naming and simplify test asserts

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/1be7cf7e-2747-43ba-9a33-2e71dad2d14d

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

* Fix mk_make include resolution for moved tptp frontend

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/7cbce0d2-0ed9-4941-91d4-49977c0a97a1

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

* Update CMakeLists.txt

* Fix TPTP parsing, arithmetic builtin mapping, and timeout handling

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/f2be81f6-e506-47ea-a38a-46d1970add8c

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

* Polish TPTP parser diagnostics and type parsing details

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/f2be81f6-e506-47ea-a38a-46d1970add8c

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

* Refine digit-check helper naming in TPTP frontend

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/f2be81f6-e506-47ea-a38a-46d1970add8c

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

* Add rational zero-denominator regression test for TPTP

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/f2be81f6-e506-47ea-a38a-46d1970add8c

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

* Fix missing g_display_* symbol definitions for non-shell link targets

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/0283d958-26a8-4b1c-86be-b75a5bc26d8c

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>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-05-12 19:29:58 -04:00
Copilot
42582c6835
euf_seq_plugin: fix identity elimination after merge, activate loop merging, integrate sgraph improvements (#9414)
* Initial plan

* Initial plan

* Fix identity elimination after merge and activate loop merging in euf_seq_plugin

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/053b94e4-645a-4cde-ae5d-cf6d61222f92

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

* Apply three ZIPT code review improvements to euf_seq_plugin

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/da8647c4-ddff-47ce-9364-2eee3810c38d

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

* Address code review: improve loop-merge defensive code and test variable names

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/053b94e4-645a-4cde-ae5d-cf6d61222f92

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

* Refactor: extract saturating_add helper, simplify hash-check condition

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/da8647c4-ddff-47ce-9364-2eee3810c38d

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 11:12:00 -07:00
Nikolaj Bjorner
f461369ab8 fix tests
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-26 08:23:26 -07:00
Nikolaj Bjorner
ace4105a90 fix test build
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-23 08:06:15 -07:00
Copilot
99f64b80fa
Prevent unsound solve-eqs elimination across recursive-function definitions (#9358)
* Initial plan

* Prevent unsound solve-eqs elimination across recursive-function definitions

Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/9a2fc92f-15e8-4806-988b-28bce96e8007

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

* Update solve_eqs.cpp

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-23 16:17:21 +02:00
Nikolaj Bjorner
5f7e14315d fix tests
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-22 10:54:06 -07:00
Arie
665d4f36ff
Fixes for lar_term== operator (#9284)
* Fix broken term_comparer in m_normalized_terms_to_columns lookup

The `m_normalized_terms_to_columns` map in `lar_solver` uses a
`term_comparer` that delegates to `lar_term::operator==`, which
intentionally returns `false` (with comment "take care not to create
identical terms"). This makes `fetch_normalized_term_column` unable to
find any term, rendering the Horner module's `interval_from_term`
bounds-recovery path dead code.

History: `lar_term::operator==` returning `false` has been present since
the original "merge LRA" commit (911b24784, 2018). The
`m_normalized_terms_to_columns` lookup was added later (dfe0e856,
c95f66e0, Aug 2019) as "toward fetching existing terms intervals from
lar_solver". The initial code had `lp_assert(find == end)` on
registration (always true with broken ==) and `lp_assert(find != end)`
on deregister (always false). The very next commit (207c1c50, one day
later) removed both asserts, replacing them with soft checks. The
`term_comparer` struct delegating to `operator==` was introduced during
a later PIMPL refactor (b375faa77).

Fix: Replace the `term_comparer` implementation with a structural
comparison that checks size and then verifies each coefficient-variable
pair via `coeffs().find_core()`. This is localized to the
`m_normalized_terms_to_columns` map and does not change
`lar_term::operator==`, preserving its intentional semantics elsewhere.

Validated: on a QF_UFNIA benchmark, `interval_from_term` lookups go
from 0/573 successful to 34/573 successful. Unit test added for the
`fetch_normalized_term_column` round-trip.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Disable operator== for lar_term

The operator== for lar_term was never intended to be used.
This changes physically disables it to identify what happens to depend
on the operator.

* Work around missing lar_term==

Previous commit disabled lar_term==. This is the only use of the
operator that seems meaningful. Changed it to compare by references
instead.

Compiles, but not sure this is the best solution.

* replace with e

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

* Delete unused ineq::operator==

The operator is unused, so there is no need to figure what is
the best fix for it.

* Remove lp tests that use ineq::operator==

---------

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-12 14:31:18 -07: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
Nikolaj Bjorner
23ae00a57e update count to 2
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-09 16:39:51 -07:00
Nikolaj Bjorner
bb48e3a405 disable spurious test
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-09 02:20:45 -07:00
CEisenhofer
26d36ba6ee Missing justification added
Added check for correctness of conflict core
2026-04-08 10:15:27 +02: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
CEisenhofer
1282e4de11 Prevent unsoudness because of missing length propagation 2026-04-02 14:34:46 +02:00
Nikolaj Bjorner
6e8c201234 fix test
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-04-01 16:00:01 -07:00
CEisenhofer
813a06fa38 Use subsolvers bounds rather than computing them inside nseq 2026-03-25 20:21:49 +01:00
Copilot
46c76d89e0
Make dep_mgr private in seq_nielsen; expose conflict sources vector (#9129)
* make dep_mgr private in seq_nielsen, expose conflict_sources vector

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/998d8021-4808-4feb-afc5-b2447c6a64e5

* move deps_to_lits to seq namespace in seq_nielsen

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/8d736478-8f9b-4451-8d1f-539ce72525c7

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-03-25 08:05:00 -07:00
CEisenhofer
c91b485fcf Int Bounds where not updated properly 2026-03-25 12:47:52 +01:00
Copilot
e3e235aa7f
Refactor: replace int_constraint with constraint struct, promote cur_path to member, expose path leaf side constraints (#9124)
* chore: update plan with cur_path and side constraints requirements

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/1523cf0a-b7a4-41a6-b792-7cd41b4dcd3b

* Refactor: rename int_constraint to constraint, remove int_constraint_kind enum

- Rename int_constraint struct to constraint with fields fml/dep
- Remove int_constraint_kind enum; pre-build formula expressions instead
- nielsen_edge: add_side_int/side_int() -> add_side_constraint/side_constraints()
- nielsen_node: add_int_constraint/int_constraints() -> add_constraint/constraints()
- nielsen_graph: mk_int_constraint(lhs,rhs,kind,dep) -> mk_constraint(fml,dep)
- Remove int_constraint_to_expr (no longer needed)
- search_dfs/simplify_and_init/check_int_feasibility/check_lp_le: drop cur_path param
- Add m_cur_path member to nielsen_graph; m_cur_path.reset() in solve()
- Add get_path_leaf_side_constraints() implementation
- Update seq_parikh.h/cpp and seq_nielsen_pp.cpp to use new constraint API

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

* refactor: constraint struct, promote cur_path, expose path leaf side constraints

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/1523cf0a-b7a4-41a6-b792-7cd41b4dcd3b

* fix: remove spurious includes from seq_nielsen.cpp

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/aa283d79-cd42-4b87-aaf0-4273a8327b76

* fix: update test files to use renamed constraint API and fix inverted root guard

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/b09bbc56-9617-4277-8e0c-27fa7e588037

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-03-24 22:18:30 -07:00
Nikolaj Bjorner
6a6f9b1892 Merge remote-tracking branch 'origin/master' into c3
# Conflicts:
#	.github/workflows/qf-s-benchmark.lock.yml
#	.github/workflows/qf-s-benchmark.md
#	.github/workflows/zipt-code-reviewer.lock.yml
#	.github/workflows/zipt-code-reviewer.md
#	.gitignore
#	src/ast/rewriter/seq_rewriter.cpp
#	src/test/main.cpp
2026-03-24 17:44:48 -07:00
Nikolaj Bjorner
5803c6f202 fix bug in non-emptiness witness extraction
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2026-03-24 13:27:28 -07:00
Lev Nachmanson
44e84dc5d0 refactor try_bivar_hensel_lift and outline the algorithm
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
2026-03-24 06:25:29 -10:00
Lev Nachmanson
3e5e9026d8 Implement multivariate polynomial factorization via Hensel lifting
Replace the stub factor_n_sqf_pp (TODO: invoke Dejan's procedure) with a
working implementation using bivariate Hensel lifting:

- Evaluate away extra variables to reduce to bivariate
- Factor the univariate specialization
- Lift univariate factors to bivariate via linear Hensel lifting in Zp[x]
- Verify lifted factors multiply to original over Z[x,y]
- For >2 variables, check bivariate factors divide the original polynomial

Tests: (x0+x1)(x0+2x1)(x0+3x1) now correctly factors into 3 linear factors.
All 89 unit tests pass in both release and debug builds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 06:25:29 -10:00