mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
updates
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
8744c62fca
commit
60bb02b709
11 changed files with 120 additions and 35 deletions
|
@ -351,6 +351,7 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) {
|
|||
case OP_MUL: return is_real ? m_r_mul_decl : m_i_mul_decl;
|
||||
case OP_DIV: return m_r_div_decl;
|
||||
case OP_IDIV: return m_i_div_decl;
|
||||
case OP_IDIVIDES: UNREACHABLE();
|
||||
case OP_REM: return m_i_rem_decl;
|
||||
case OP_MOD: return m_i_mod_decl;
|
||||
case OP_TO_REAL: return m_to_real_decl;
|
||||
|
@ -482,6 +483,14 @@ func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
|
|||
m_manager->raise_exception("no arguments supplied to arithmetical operator");
|
||||
return nullptr;
|
||||
}
|
||||
if (k == OP_IDIVIDES) {
|
||||
if (arity != 1 || domain[0] != m_int_decl || num_parameters != 1 || !parameters[0].is_int()) {
|
||||
m_manager->raise_exception("invalid divides application. Expects integer parameter and one argument of sort integer");
|
||||
}
|
||||
return m_manager->mk_func_decl(symbol("divides"), 1, &m_int_decl, m_manager->mk_bool_sort(),
|
||||
func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||
}
|
||||
|
||||
if (m_manager->int_real_coercions() && use_coercion(k)) {
|
||||
return mk_func_decl(fix_kind(k, arity), has_real_arg(arity, domain, m_real_decl));
|
||||
}
|
||||
|
@ -499,6 +508,13 @@ func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
|
|||
m_manager->raise_exception("no arguments supplied to arithmetical operator");
|
||||
return nullptr;
|
||||
}
|
||||
if (k == OP_IDIVIDES) {
|
||||
if (num_args != 1 || m_manager->get_sort(args[0]) != m_int_decl || num_parameters != 1 || !parameters[0].is_int()) {
|
||||
m_manager->raise_exception("invalid divides application. Expects integer parameter and one argument of sort integer");
|
||||
}
|
||||
return m_manager->mk_func_decl(symbol("divides"), 1, &m_int_decl, m_manager->mk_bool_sort(),
|
||||
func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||
}
|
||||
if (m_manager->int_real_coercions() && use_coercion(k)) {
|
||||
return mk_func_decl(fix_kind(k, num_args), has_real_arg(m_manager, num_args, args, m_real_decl));
|
||||
}
|
||||
|
@ -533,6 +549,7 @@ void arith_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol con
|
|||
op_names.push_back(builtin_name("*",OP_MUL));
|
||||
op_names.push_back(builtin_name("/",OP_DIV));
|
||||
op_names.push_back(builtin_name("div",OP_IDIV));
|
||||
op_names.push_back(builtin_name("divides",OP_IDIVIDES));
|
||||
op_names.push_back(builtin_name("rem",OP_REM));
|
||||
op_names.push_back(builtin_name("mod",OP_MOD));
|
||||
op_names.push_back(builtin_name("to_real",OP_TO_REAL));
|
||||
|
|
|
@ -46,6 +46,7 @@ enum arith_op_kind {
|
|||
OP_MUL,
|
||||
OP_DIV,
|
||||
OP_IDIV,
|
||||
OP_IDIVIDES,
|
||||
OP_REM,
|
||||
OP_MOD,
|
||||
OP_TO_REAL,
|
||||
|
|
|
@ -66,6 +66,7 @@ br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
|
|||
SASSERT(num_args == 2); st = mk_div_core(args[0], args[1], result); break;
|
||||
case OP_IDIV: if (num_args == 1) { result = args[0]; st = BR_DONE; break; }
|
||||
SASSERT(num_args == 2); st = mk_idiv_core(args[0], args[1], result); break;
|
||||
case OP_IDIVIDES: SASSERT(num_args == 1); st = mk_idivides(f->get_parameter(0).get_int(), args[0], result); break;
|
||||
case OP_MOD: SASSERT(num_args == 2); st = mk_mod_core(args[0], args[1], result); break;
|
||||
case OP_REM: SASSERT(num_args == 2); st = mk_rem_core(args[0], args[1], result); break;
|
||||
case OP_UMINUS: SASSERT(num_args == 1); st = mk_uminus(args[0], result); break;
|
||||
|
@ -792,6 +793,11 @@ br_status arith_rewriter::mk_div_core(expr * arg1, expr * arg2, expr_ref & resul
|
|||
return BR_FAILED;
|
||||
}
|
||||
|
||||
br_status arith_rewriter::mk_idivides(unsigned k, expr * arg, expr_ref & result) {
|
||||
result = m().mk_eq(m_util.mk_mod(arg, m_util.mk_int(k)), m_util.mk_int(0));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & result) {
|
||||
set_curr_sort(m().get_sort(arg1));
|
||||
numeral v1, v2;
|
||||
|
|
|
@ -143,6 +143,7 @@ public:
|
|||
|
||||
br_status mk_div_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_idiv_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_idivides(unsigned k, expr * arg, expr_ref & result);
|
||||
br_status mk_mod_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_rem_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_power_core(expr* arg1, expr* arg2, expr_ref & result);
|
||||
|
|
|
@ -1866,6 +1866,53 @@ bool seq_rewriter::reduce_eq(expr* l, expr* r, expr_ref_vector& lhs, expr_ref_ve
|
|||
}
|
||||
}
|
||||
|
||||
bool seq_rewriter::reduce_contains(expr* a, expr* b, expr_ref_vector& disj) {
|
||||
m_lhs.reset();
|
||||
m_util.str.get_concat(a, m_lhs);
|
||||
TRACE("seq", tout << expr_ref(a, m()) << " " << expr_ref(b, m()) << "\n";);
|
||||
zstring s;
|
||||
for (unsigned i = 0; i < m_lhs.size(); ++i) {
|
||||
expr* e = m_lhs.get(i);
|
||||
if (m_util.str.is_empty(e)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_util.str.is_string(e, s)) {
|
||||
unsigned sz = s.length();
|
||||
expr_ref_vector es(m());
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
es.push_back(m_util.str.mk_char(s, j));
|
||||
}
|
||||
es.append(m_lhs.size() - i, m_lhs.c_ptr() + i);
|
||||
for (unsigned j = 0; j < sz; ++j) {
|
||||
disj.push_back(m_util.str.mk_prefix(b, m_util.str.mk_concat(es.size() - j, es.c_ptr() + j)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (m_util.str.is_unit(e)) {
|
||||
disj.push_back(m_util.str.mk_prefix(b, m_util.str.mk_concat(m_lhs.size() - i, m_lhs.c_ptr() + i)));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_util.str.is_string(b, s)) {
|
||||
expr* all = m_util.re.mk_full_seq(m_util.re.mk_re(m().get_sort(b)));
|
||||
std::cout << sort_ref(m().get_sort(all), m()) << "\n";
|
||||
disj.push_back(m_util.re.mk_in_re(m_util.str.mk_concat(m_lhs.size() - i, m_lhs.c_ptr() + i),
|
||||
m_util.re.mk_concat(all, m_util.str.mk_concat(m_util.re.mk_to_re(b), all))));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
return false;
|
||||
}
|
||||
disj.push_back(m_util.str.mk_contains(m_util.str.mk_concat(m_lhs.size() - i, m_lhs.c_ptr() + i), b));
|
||||
return true;
|
||||
}
|
||||
disj.push_back(m().mk_eq(b, m_util.str.mk_empty(m().get_sort(b))));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
expr* seq_rewriter::concat_non_empty(unsigned n, expr* const* as) {
|
||||
SASSERT(n > 0);
|
||||
ptr_vector<expr> bs;
|
||||
|
|
|
@ -168,6 +168,8 @@ public:
|
|||
|
||||
bool reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs, bool& change);
|
||||
|
||||
bool reduce_contains(expr* a, expr* b, expr_ref_vector& disj);
|
||||
|
||||
void add_seqs(expr_ref_vector const& ls, expr_ref_vector const& rs, expr_ref_vector& lhs, expr_ref_vector& rhs);
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue