mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 00:55:31 +00:00
try zero_ext
This commit is contained in:
parent
0b17a14c83
commit
6dfc9dd936
6 changed files with 43 additions and 2 deletions
|
@ -17,7 +17,6 @@ Author:
|
|||
#include "math/polysat/interval.h"
|
||||
#include "math/polysat/assignment.h"
|
||||
#include "math/polysat/univariate/univariate_solver.h"
|
||||
#include "util/tbv.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace polysat {
|
||||
|
|
|
@ -596,6 +596,9 @@ namespace polysat {
|
|||
rational q = mod2k(machine_div2k(p.val(), lo), hi - lo + 1);
|
||||
return p.manager().mk_val(q);
|
||||
}
|
||||
if (lo == hi) {
|
||||
// could turn it into a single-bit constraint... unclear if that is useful
|
||||
}
|
||||
if (!lo) {
|
||||
// TODO: we could push the extract down into variables of the term instead of introducing a name.
|
||||
}
|
||||
|
@ -637,6 +640,22 @@ namespace polysat {
|
|||
return s.var(v);
|
||||
}
|
||||
|
||||
pdd constraint_manager::zero_ext(pdd const& p, unsigned bit_width) {
|
||||
SASSERT(bit_width > p.power_of_2());
|
||||
pdd const q = s.var(s.m_names.mk_name(p));
|
||||
constraint_dedup::zext_args args = {q.var(), bit_width};
|
||||
auto it = m_dedup.m_zext_expr.find_iterator(args);
|
||||
if (it != m_dedup.m_zext_expr.end())
|
||||
return s.var(it->m_value);
|
||||
pdd const v = s.var(s.add_var(bit_width));
|
||||
m_dedup.m_zext_expr.insert(args, v.var());
|
||||
// v[|p|-1:0] = p
|
||||
s.add_eq(q, extract(v, p.power_of_2() - 1, 0));
|
||||
// v < 2^|p|
|
||||
s.add_ule(q, p.manager().max_value());
|
||||
return v;
|
||||
}
|
||||
|
||||
/** unsigned quotient/remainder */
|
||||
std::pair<pdd, pdd> constraint_manager::div_rem_op_constraint(pdd const& a, pdd const& b) {
|
||||
auto& m = a.manager();
|
||||
|
|
|
@ -41,6 +41,16 @@ namespace polysat {
|
|||
using quot_rem_expr_map = map<quot_rem_args, std::pair<pvar, pvar>, quot_rem_args_hash, quot_rem_args_eq>;
|
||||
quot_rem_expr_map m_quot_rem_expr;
|
||||
vector<std::tuple<pdd, pdd, pvar, pvar>> m_div_rem_list;
|
||||
|
||||
using zext_args = std::pair<pvar, unsigned>;
|
||||
using zext_args_eq = default_eq<zext_args>;
|
||||
struct zext_args_hash {
|
||||
unsigned operator()(zext_args const& args) const {
|
||||
return combine_hash(args.first, args.second);
|
||||
}
|
||||
};
|
||||
using zext_expr_map = map<zext_args, pvar, zext_args_hash, zext_args_eq>;
|
||||
zext_expr_map m_zext_expr;
|
||||
};
|
||||
|
||||
// Manage constraint lifetime, deduplication, and connection to boolean variables/literals.
|
||||
|
@ -161,6 +171,8 @@ namespace polysat {
|
|||
pdd concat(pdd const& p, pdd const& q);
|
||||
pdd concat(unsigned num_args, pdd const* args);
|
||||
|
||||
pdd zero_ext(pdd const& p, unsigned bit_width);
|
||||
|
||||
constraint* const* begin() const { return m_constraints.data(); }
|
||||
constraint* const* end() const { return m_constraints.data() + m_constraints.size(); }
|
||||
|
||||
|
|
|
@ -418,6 +418,9 @@ namespace polysat {
|
|||
/** Create expression for concatenation of args */
|
||||
pdd concat(unsigned num_args, pdd const* args) { return m_constraints.concat(num_args, args); }
|
||||
|
||||
/** Create expression for zero-extension of p */
|
||||
pdd zero_ext(pdd const& p, unsigned bit_width) { return m_constraints.zero_ext(p, bit_width); }
|
||||
|
||||
/**
|
||||
* Create terms for unsigned quot-rem
|
||||
*
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace bv {
|
|||
case OP_EXTRACT: polysat_extract(a); break;
|
||||
case OP_CONCAT: polysat_concat(a); break;
|
||||
|
||||
case OP_ZERO_EXT:
|
||||
case OP_ZERO_EXT: polysat_zero_ext(a); break;
|
||||
case OP_SIGN_EXT:
|
||||
|
||||
// polysat::solver should also support at least:
|
||||
|
@ -197,6 +197,13 @@ namespace bv {
|
|||
polysat_set(e, p);
|
||||
}
|
||||
|
||||
void solver::polysat_zero_ext(app* e) {
|
||||
pdd const arg = expr2pdd(e->get_arg(0));
|
||||
unsigned const sz = e->get_parameter(0).get_int();
|
||||
pdd const p = m_polysat.zero_ext(p, sz);
|
||||
polysat_set(e, p);
|
||||
}
|
||||
|
||||
void solver::polysat_binary(app* e, std::function<polysat::pdd(polysat::pdd, polysat::pdd)> const& fn) {
|
||||
SASSERT(e->get_num_args() >= 1);
|
||||
auto p = expr2pdd(e->get_arg(0));
|
||||
|
|
|
@ -327,6 +327,7 @@ namespace bv {
|
|||
void polysat_binary(app* e, std::function<polysat::pdd(polysat::pdd, polysat::pdd)> const& fn);
|
||||
void polysat_extract(app* e);
|
||||
void polysat_concat(app* e);
|
||||
void polysat_zero_ext(app* e);
|
||||
polysat::pdd expr2pdd(expr* e);
|
||||
void polysat_set(euf::theory_var v, polysat::pdd const& p);
|
||||
polysat::pdd var2pdd(euf::theory_var v);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue