3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-21 06:25:50 +00:00
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Nikolaj Bjorner 2026-07-12 13:35:57 -07:00 committed by GitHub
parent ba7b12c18c
commit eaceded5f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 269 additions and 11 deletions

View file

@ -18,6 +18,7 @@ z3_add_component(bv_tactics
bv1_blaster_tactic.h
bv_bound_chk_tactic.h
bv_bounds_tactic.h
bv_divrem_bounds_tactic.h
bv_size_reduction_tactic.h
bv_slice_tactic.h
bvarray2uf_tactic.h

View file

@ -0,0 +1,63 @@
/*++
Copyright (c) 2026 Microsoft Corporation
Module Name:
bv_divrem_bounds_tactic.h
Abstract:
Tactic wrapper around the bv::divrem_bounds simplifier. It adds range
lemmas for bit-vector division and remainder terms with a non-constant
divisor. See ast/simplifiers/bv_divrem_bounds.h for details.
Author:
Nikolaj Bjorner (nbjorner)
Tactic Documentation
## Tactic bv-divrem-bounds
### Short Description
Add range lemmas for bit-vector division/remainder terms with a symbolic divisor.
### Long Description
For a divisor `b` that is not a numeral, the remainder magnitude is bounded by
the divisor magnitude and the unsigned quotient is bounded by the dividend.
These facts are hidden once a division circuit is bit-blasted, so the tactic
emits them as implied lemmas up front, letting a downstream SAT solver reason
about magnitudes without unfolding the circuit.
### Example
```z3
(declare-const a (_ BitVec 8))
(declare-const b (_ BitVec 8))
(declare-const c (_ BitVec 8))
(assert (= (bvsrem a (bvadd b c)) #x05))
(apply bv-divrem-bounds)
```
--*/
#pragma once
#include "util/params.h"
#include "tactic/tactic.h"
#include "tactic/dependent_expr_state_tactic.h"
#include "ast/simplifiers/bv_divrem_bounds.h"
class ast_manager;
class tactic;
inline tactic* mk_bv_divrem_bounds_tactic(ast_manager& m, params_ref const& p = params_ref()) {
return alloc(dependent_expr_state_tactic, m, p,
[](auto& m, auto& p, auto& s) -> dependent_expr_simplifier* { return alloc(bv::divrem_bounds, m, s); });
}
/*
ADD_TACTIC("bv-divrem-bounds", "add range lemmas for bit-vector division/remainder terms with a symbolic divisor.", "mk_bv_divrem_bounds_tactic(m, p)")
ADD_SIMPLIFIER("bv-divrem-bounds", "add range lemmas for bit-vector division/remainder terms with a symbolic divisor.", "alloc(bv::divrem_bounds, m, s)")
*/

View file

@ -23,6 +23,7 @@ Notes:
#include "tactic/core/elim_uncnstr_tactic.h"
#include "tactic/bv/max_bv_sharing_tactic.h"
#include "tactic/bv/bv_size_reduction_tactic.h"
#include "tactic/bv/bv_divrem_bounds_tactic.h"
#include "tactic/core/ctx_simplify_tactic.h"
#include "tactic/smtlogics/qfbv_tactic.h"
#include "tactic/smtlogics/smt_tactic.h"
@ -42,6 +43,7 @@ static tactic * mk_qfaufbv_preamble(ast_manager & m, params_ref const & p) {
mk_propagate_values_tactic(m),
mk_solve_eqs_tactic(m),
mk_elim_uncnstr_tactic(m),
mk_bv_divrem_bounds_tactic(m),
// sound to use? if_no_proofs(if_no_unsat_cores(mk_reduce_args_tactic(m))),
if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
using_params(mk_simplify_tactic(m), simp2_p),

View file

@ -25,6 +25,7 @@ Notes:
#include "tactic/bv/bv1_blaster_tactic.h"
#include "tactic/bv/max_bv_sharing_tactic.h"
#include "tactic/bv/bv_size_reduction_tactic.h"
#include "tactic/bv/bv_divrem_bounds_tactic.h"
#include "tactic/aig/aig_tactic.h"
#include "sat/tactic/sat_tactic.h"
#include "sat/sat_solver/inc_sat_solver.h"
@ -63,6 +64,7 @@ static tactic * mk_qfbv_preamble(ast_manager& m, params_ref const& p) {
using_params(mk_propagate_values_tactic(m), flat_and_or_p),
using_params(mk_solve_eqs_tactic(m), solve_eq_p),
mk_elim_uncnstr_tactic(m),
mk_bv_divrem_bounds_tactic(m),
if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))),
using_params(mk_simplify_tactic(m), simp2_p),