mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 10:25:18 +00:00
merge useful utilities from qsat
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
f951372f03
commit
f175f864ec
|
@ -604,8 +604,16 @@ namespace z3 {
|
|||
|
||||
/**
|
||||
\brief Return true if this expression is a numeral.
|
||||
Specialized functions also return representations for the numerals as
|
||||
small integers, 64 bit integers or rational or decimal strings.
|
||||
*/
|
||||
bool is_numeral() const { return kind() == Z3_NUMERAL_AST; }
|
||||
bool is_numeral_i64(__int64& i) const { bool r = Z3_get_numeral_int64(ctx(), m_ast, &i); return r;}
|
||||
bool is_numeral_u64(__uint64& i) const { bool r = Z3_get_numeral_uint64(ctx(), m_ast, &i); return r;}
|
||||
bool is_numeral_i(int& i) const { bool r = Z3_get_numeral_int(ctx(), m_ast, &i); return r;}
|
||||
bool is_numeral_u(unsigned& i) const { bool r = Z3_get_numeral_uint(ctx(), m_ast, &i); return r;}
|
||||
bool is_numeral(std::string& s) const { if (!is_numeral()) return false; s = Z3_get_numeral_string(ctx(), m_ast); return true; }
|
||||
bool is_numeral(std::string& s, unsigned precision) const { if (!is_numeral()) return false; s = Z3_get_numeral_decimal_string(ctx(), m_ast, precision); return true; }
|
||||
/**
|
||||
\brief Return true if this expression is an application.
|
||||
*/
|
||||
|
|
|
@ -3940,7 +3940,7 @@ class ArraySortRef(SortRef):
|
|||
>>> A.range()
|
||||
Bool
|
||||
"""
|
||||
return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
|
||||
return _to_sort_ref(Z3_get_array_sort_range(self.ctx_ref(), self.ast), self.ctx)
|
||||
|
||||
class ArrayRef(ExprRef):
|
||||
"""Array expressions. """
|
||||
|
@ -4162,6 +4162,16 @@ def Select(a, i):
|
|||
_z3_assert(is_array(a), "First argument must be a Z3 array expression")
|
||||
return a[i]
|
||||
|
||||
def Default(a):
|
||||
""" Return a default value for array expression.
|
||||
>>> b = K(IntSort(), 1)
|
||||
>>> prove(Default(b) == 1)
|
||||
proved
|
||||
"""
|
||||
if __debug__:
|
||||
_z3_assert(is_array(a), "First argument must be a Z3 array expression")
|
||||
return a.mk_default()
|
||||
|
||||
def Map(f, *args):
|
||||
"""Return a Z3 map array expression.
|
||||
|
||||
|
|
|
@ -664,3 +664,45 @@ algebraic_numbers::anum const & arith_util::to_irrational_algebraic_numeral(expr
|
|||
SASSERT(is_irrational_algebraic_numeral(n));
|
||||
return plugin().aw().to_anum(to_app(n)->get_decl());
|
||||
}
|
||||
|
||||
expr_ref arith_util::mk_mul_simplify(expr_ref_vector const& args) {
|
||||
return mk_mul_simplify(args.size(), args.c_ptr());
|
||||
|
||||
}
|
||||
expr_ref arith_util::mk_mul_simplify(unsigned sz, expr* const* args) {
|
||||
expr_ref result(m_manager);
|
||||
|
||||
switch (sz) {
|
||||
case 0:
|
||||
result = mk_numeral(rational(1), true);
|
||||
break;
|
||||
case 1:
|
||||
result = args[0];
|
||||
break;
|
||||
default:
|
||||
result = mk_mul(sz, args);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
expr_ref arith_util::mk_add_simplify(expr_ref_vector const& args) {
|
||||
return mk_add_simplify(args.size(), args.c_ptr());
|
||||
|
||||
}
|
||||
expr_ref arith_util::mk_add_simplify(unsigned sz, expr* const* args) {
|
||||
expr_ref result(m_manager);
|
||||
|
||||
switch (sz) {
|
||||
case 0:
|
||||
result = mk_numeral(rational(0), true);
|
||||
break;
|
||||
case 1:
|
||||
result = args[0];
|
||||
break;
|
||||
default:
|
||||
result = mk_add(sz, args);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -149,7 +149,6 @@ protected:
|
|||
func_decl * m_mod_0_decl;
|
||||
func_decl * m_u_asin_decl;
|
||||
func_decl * m_u_acos_decl;
|
||||
|
||||
ptr_vector<app> m_small_ints;
|
||||
ptr_vector<app> m_small_reals;
|
||||
|
||||
|
@ -416,6 +415,11 @@ public:
|
|||
return m_manager.mk_eq(lhs, rhs);
|
||||
}
|
||||
|
||||
expr_ref mk_mul_simplify(expr_ref_vector const& args);
|
||||
expr_ref mk_mul_simplify(unsigned sz, expr* const* args);
|
||||
|
||||
expr_ref mk_add_simplify(expr_ref_vector const& args);
|
||||
expr_ref mk_add_simplify(unsigned sz, expr* const* args);
|
||||
};
|
||||
|
||||
#endif /* ARITH_DECL_PLUGIN_H_ */
|
||||
|
|
|
@ -1200,6 +1200,14 @@ std::ostream& operator<<(std::ostream& out, app_ref const& e) {
|
|||
return out << mk_ismt2_pp(e.get(), e.get_manager());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, func_decl_ref const& e) {
|
||||
return out << mk_ismt2_pp(e.get(), e.get_manager());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, sort_ref const& e) {
|
||||
return out << mk_ismt2_pp(e.get(), e.get_manager());
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, expr_ref_vector const& e) {
|
||||
for (unsigned i = 0; i < e.size(); ++i) {
|
||||
out << mk_ismt2_pp(e[i], e.get_manager());
|
||||
|
@ -1216,6 +1224,18 @@ std::ostream& operator<<(std::ostream& out, app_ref_vector const& e) {
|
|||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, func_decl_ref_vector const& e) {
|
||||
for (unsigned i = 0; i < e.size(); ++i)
|
||||
out << mk_ismt2_pp(e[i], e.get_manager()) << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, sort_ref_vector const& e) {
|
||||
for (unsigned i = 0; i < e.size(); ++i)
|
||||
out << mk_ismt2_pp(e[i], e.get_manager()) << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
#ifdef Z3DEBUG
|
||||
void pp(expr const * n, ast_manager & m) {
|
||||
std::cout << mk_ismt2_pp(const_cast<expr*>(n), m) << std::endl;
|
||||
|
|
|
@ -117,8 +117,13 @@ std::ostream& operator<<(std::ostream& out, mk_ismt2_pp const & p);
|
|||
|
||||
std::ostream& operator<<(std::ostream& out, expr_ref const& e);
|
||||
std::ostream& operator<<(std::ostream& out, app_ref const& e);
|
||||
std::ostream& operator<<(std::ostream& out, func_decl_ref const& e);
|
||||
std::ostream& operator<<(std::ostream& out, sort_ref const& e);
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, expr_ref_vector const& e);
|
||||
std::ostream& operator<<(std::ostream& out, app_ref_vector const& e);
|
||||
std::ostream& operator<<(std::ostream& out, func_decl_ref_vector const& e);
|
||||
std::ostream& operator<<(std::ostream& out, sort_ref_vector const& e);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -170,7 +170,6 @@ app* mk_and(ast_manager & m, unsigned num_args, app * const * args) {
|
|||
return to_app(mk_and(m, num_args, (expr* const*) args));
|
||||
}
|
||||
|
||||
|
||||
expr * mk_or(ast_manager & m, unsigned num_args, expr * const * args) {
|
||||
if (num_args == 0)
|
||||
return m.mk_false();
|
||||
|
@ -188,10 +187,43 @@ expr * mk_not(ast_manager & m, expr * arg) {
|
|||
expr * atom;
|
||||
if (m.is_not(arg, atom))
|
||||
return atom;
|
||||
else if (m.is_true(arg))
|
||||
return m.mk_false();
|
||||
else if (m.is_false(arg))
|
||||
return m.mk_true();
|
||||
else
|
||||
return m.mk_not(arg);
|
||||
}
|
||||
|
||||
expr_ref push_not(const expr_ref& e) {
|
||||
ast_manager& m = e.get_manager();
|
||||
if (!is_app(e)) {
|
||||
return expr_ref(m.mk_not(e), m);
|
||||
}
|
||||
app* a = to_app(e);
|
||||
if (m.is_and(a)) {
|
||||
if (a->get_num_args() == 0) {
|
||||
return expr_ref(m.mk_false(), m);
|
||||
}
|
||||
expr_ref_vector args(m);
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
args.push_back(push_not(expr_ref(a->get_arg(i), m)));
|
||||
}
|
||||
return mk_or(args);
|
||||
}
|
||||
if (m.is_or(a)) {
|
||||
if (a->get_num_args() == 0) {
|
||||
return expr_ref(m.mk_true(), m);
|
||||
}
|
||||
expr_ref_vector args(m);
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
args.push_back(push_not(expr_ref(a->get_arg(i), m)));
|
||||
}
|
||||
return mk_and(args);
|
||||
}
|
||||
return expr_ref(mk_not(m, e), m);
|
||||
}
|
||||
|
||||
expr * expand_distinct(ast_manager & m, unsigned num_args, expr * const * args) {
|
||||
expr_ref_buffer new_diseqs(m);
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
|
@ -201,6 +233,24 @@ expr * expand_distinct(ast_manager & m, unsigned num_args, expr * const * args)
|
|||
return mk_and(m, new_diseqs.size(), new_diseqs.c_ptr());
|
||||
}
|
||||
|
||||
expr* mk_distinct(ast_manager& m, unsigned num_args, expr * const * args) {
|
||||
switch (num_args) {
|
||||
case 0:
|
||||
case 1:
|
||||
return m.mk_true();
|
||||
case 2:
|
||||
return m.mk_not(m.mk_eq(args[0], args[1]));
|
||||
default:
|
||||
return m.mk_distinct(num_args, args);
|
||||
}
|
||||
}
|
||||
|
||||
expr_ref mk_distinct(expr_ref_vector const& args) {
|
||||
ast_manager& m = args.get_manager();
|
||||
return expr_ref(mk_distinct(m, args.size(), args.c_ptr()), m);
|
||||
}
|
||||
|
||||
|
||||
void flatten_and(expr_ref_vector& result) {
|
||||
ast_manager& m = result.get_manager();
|
||||
expr* e1, *e2, *e3;
|
||||
|
|
|
@ -121,18 +121,29 @@ app * mk_or(ast_manager & m, unsigned num_args, app * const * args);
|
|||
inline app_ref mk_or(app_ref_vector const& args) { return app_ref(mk_or(args.get_manager(), args.size(), args.c_ptr()), args.get_manager()); }
|
||||
inline expr_ref mk_or(expr_ref_vector const& args) { return expr_ref(mk_or(args.get_manager(), args.size(), args.c_ptr()), args.get_manager()); }
|
||||
|
||||
|
||||
/**
|
||||
Return a if arg = (not a)
|
||||
Retur (not arg) otherwise
|
||||
*/
|
||||
expr * mk_not(ast_manager & m, expr * arg);
|
||||
|
||||
/**
|
||||
Negate and push over conjunction or disjunction.
|
||||
*/
|
||||
expr_ref push_not(const expr_ref& arg);
|
||||
|
||||
/**
|
||||
Return the expression (and (not (= args[0] args[1])) (not (= args[0] args[2])) ... (not (= args[num_args-2] args[num_args-1])))
|
||||
*/
|
||||
expr * expand_distinct(ast_manager & m, unsigned num_args, expr * const * args);
|
||||
|
||||
/**
|
||||
Create simplified distinct term. Binary distinct becomes a single disequality.
|
||||
*/
|
||||
expr * mk_distinct(ast_manager& m, unsigned num_args, expr * const * args);
|
||||
|
||||
expr_ref mk_distinct(expr_ref_vector const& args);
|
||||
|
||||
/**
|
||||
\brief Collect top-level conjunctions and disjunctions.
|
||||
*/
|
||||
|
|
|
@ -865,6 +865,12 @@ sort * bv_util::mk_sort(unsigned bv_size) {
|
|||
return m_manager.mk_sort(get_fid(), BV_SORT, 1, p);
|
||||
}
|
||||
|
||||
unsigned bv_util::get_int2bv_size(parameter const& p) {
|
||||
int sz;
|
||||
VERIFY(m_plugin->get_int2bv_size(1, &p, sz));
|
||||
return static_cast<unsigned>(sz);
|
||||
}
|
||||
|
||||
app * bv_util::mk_bv2int(expr* e) {
|
||||
sort* s = m_manager.mk_sort(m_manager.mk_family_id("arith"), INT_SORT);
|
||||
parameter p(s);
|
||||
|
|
|
@ -234,7 +234,6 @@ protected:
|
|||
|
||||
func_decl * mk_mkbv(unsigned arity, sort * const * domain);
|
||||
|
||||
bool get_int2bv_size(unsigned num_parameters, parameter const * parameters, int & result);
|
||||
|
||||
func_decl * mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity);
|
||||
|
||||
|
@ -267,6 +266,8 @@ public:
|
|||
|
||||
virtual expr * get_some_value(sort * s);
|
||||
|
||||
bool get_int2bv_size(unsigned num_parameters, parameter const * parameters, int & result);
|
||||
|
||||
virtual bool is_considered_uninterpreted(func_decl * f) {
|
||||
if (f->get_family_id() != get_family_id())
|
||||
return false;
|
||||
|
@ -390,6 +391,8 @@ public:
|
|||
return static_cast<unsigned>(s->get_parameter(0).get_int());
|
||||
}
|
||||
unsigned get_bv_size(expr const * n) const { return get_bv_size(m_manager.get_sort(n)); }
|
||||
unsigned get_int2bv_size(parameter const& p);
|
||||
|
||||
|
||||
app * mk_ule(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_ULEQ, arg1, arg2); }
|
||||
app * mk_sle(expr * arg1, expr * arg2) { return m_manager.mk_app(get_fid(), OP_SLEQ, arg1, arg2); }
|
||||
|
@ -427,6 +430,7 @@ public:
|
|||
app * mk_bvumul_no_ovfl(expr* m, expr* n) { return m_manager.mk_app(get_fid(), OP_BUMUL_NO_OVFL, n, m); }
|
||||
|
||||
app * mk_bv(unsigned n, expr* const* es) { return m_manager.mk_app(get_fid(), OP_MKBV, n, es); }
|
||||
|
||||
};
|
||||
|
||||
#endif /* BV_DECL_PLUGIN_H_ */
|
||||
|
|
|
@ -1000,3 +1000,25 @@ void datatype_util::display_datatype(sort *s0, std::ostream& strm) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
bool datatype_util::is_func_decl(datatype_op_kind k, unsigned num_params, parameter const* params, func_decl* f) {
|
||||
bool eq =
|
||||
f->get_decl_kind() == k &&
|
||||
f->get_family_id() == m_family_id &&
|
||||
f->get_num_parameters() == num_params;
|
||||
for (unsigned i = 0; eq && i < num_params; ++i) {
|
||||
eq = params[i] == f->get_parameter(i);
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
|
||||
bool datatype_util::is_constructor_of(unsigned num_params, parameter const* params, func_decl* f) {
|
||||
return
|
||||
num_params == 2 &&
|
||||
m_family_id == f->get_family_id() &&
|
||||
OP_DT_CONSTRUCTOR == f->get_decl_kind() &&
|
||||
2 == f->get_num_parameters() &&
|
||||
params[0] == f->get_parameter(0) &&
|
||||
params[1] == f->get_parameter(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,8 @@ public:
|
|||
func_decl * get_recognizer_constructor(func_decl * recognizer);
|
||||
family_id get_family_id() const { return m_family_id; }
|
||||
bool are_siblings(sort * s1, sort * s2);
|
||||
bool is_func_decl(datatype_op_kind k, unsigned num_params, parameter const* params, func_decl* f);
|
||||
bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f);
|
||||
void reset();
|
||||
void display_datatype(sort *s, std::ostream& strm);
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@ Notes:
|
|||
|
||||
void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) {
|
||||
|
||||
if (num_bound == 0) {
|
||||
result = n;
|
||||
return;
|
||||
}
|
||||
expr * curr = 0, *b = 0;
|
||||
SASSERT(n->get_ref_count() > 0);
|
||||
|
||||
|
@ -106,3 +110,27 @@ void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* cons
|
|||
expr_abstractor abs(m);
|
||||
abs(base, num_bound, bound, n, result);
|
||||
}
|
||||
|
||||
expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
|
||||
expr_ref result(m);
|
||||
expr_abstract(m, 0, num_bound, (expr* const*)bound, n, result);
|
||||
if (num_bound > 0) {
|
||||
ptr_vector<sort> sorts;
|
||||
svector<symbol> names;
|
||||
for (unsigned i = 0; i < num_bound; ++i) {
|
||||
sorts.push_back(m.get_sort(bound[i]));
|
||||
names.push_back(bound[i]->get_decl()->get_name());
|
||||
}
|
||||
result = m.mk_quantifier(is_forall, num_bound, sorts.c_ptr(), names.c_ptr(), result);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
expr_ref mk_forall(ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
|
||||
return mk_quantifier(true, m, num_bound, bound, n);
|
||||
}
|
||||
|
||||
expr_ref mk_exists(ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
|
||||
return mk_quantifier(false, m, num_bound, bound, n);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
};
|
||||
|
||||
void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result);
|
||||
expr_ref mk_forall(ast_manager& m, unsigned num_bound, app* const* bound, expr* n);
|
||||
expr_ref mk_exists(ast_manager& m, unsigned num_bound, app* const* bound, expr* n);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,6 +30,14 @@ void expr_safe_replace::insert(expr* src, expr* dst) {
|
|||
m_subst.insert(src, dst);
|
||||
}
|
||||
|
||||
void expr_safe_replace::operator()(expr_ref_vector& es) {
|
||||
expr_ref val(m);
|
||||
for (unsigned i = 0; i < es.size(); ++i) {
|
||||
(*this)(es[i].get(), val);
|
||||
es[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void expr_safe_replace::operator()(expr* e, expr_ref& res) {
|
||||
m_todo.push_back(e);
|
||||
expr* a, *b;
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
|
||||
void operator()(expr* src, expr_ref& e);
|
||||
|
||||
void operator()(expr_ref_vector& es);
|
||||
|
||||
void apply_substitution(expr* s, expr* def, expr_ref& t);
|
||||
|
||||
void reset();
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
unsigned nd = q->get_num_decls();
|
||||
for (unsigned i = 0; i < nd; ++i) {
|
||||
sort* s = q->get_decl_sort(i);
|
||||
app* a = m.mk_fresh_const("x", s);
|
||||
app* a = m.mk_fresh_const(q->get_decl_name(i).str().c_str(), s);
|
||||
vars.push_back(a);
|
||||
}
|
||||
expr * const * exprs = (expr* const*) (vars.c_ptr() + vars.size()- nd);
|
||||
|
@ -154,9 +154,7 @@ private:
|
|||
}
|
||||
|
||||
quantifier_type& negate(quantifier_type& qt) {
|
||||
TRACE("qe", display(qt, tout); tout << "\n";);
|
||||
qt = static_cast<quantifier_type>(qt ^0x1);
|
||||
TRACE("qe", display(qt, tout); tout << "\n";);
|
||||
return qt;
|
||||
}
|
||||
|
||||
|
@ -205,6 +203,7 @@ private:
|
|||
case AST_APP: {
|
||||
expr_ref_vector args(m);
|
||||
expr_ref tmp(m);
|
||||
expr* t1, *t2, *t3;
|
||||
unsigned num_args = 0;
|
||||
app* a = to_app(fml);
|
||||
if (m.is_and(fml)) {
|
||||
|
@ -228,16 +227,35 @@ private:
|
|||
negate(qt);
|
||||
result = m.mk_not(tmp);
|
||||
}
|
||||
else if (m.is_implies(fml)) {
|
||||
pull_quantifier(to_app(fml)->get_arg(0), negate(qt), vars, tmp);
|
||||
else if (m.is_implies(fml, t1, t2)) {
|
||||
pull_quantifier(t1, negate(qt), vars, tmp);
|
||||
negate(qt);
|
||||
pull_quantifier(to_app(fml)->get_arg(1), qt, vars, result);
|
||||
pull_quantifier(t2, qt, vars, result);
|
||||
result = m.mk_implies(tmp, result);
|
||||
}
|
||||
else if (m.is_ite(fml)) {
|
||||
pull_quantifier(to_app(fml)->get_arg(1), qt, vars, tmp);
|
||||
pull_quantifier(to_app(fml)->get_arg(2), qt, vars, result);
|
||||
result = m.mk_ite(to_app(fml)->get_arg(0), tmp, result);
|
||||
else if (m.is_ite(fml, t1, t2, t3)) {
|
||||
expr_ref tt1(m), tt2(m), tt3(m), ntt1(m), nt1(m);
|
||||
pull_quantifier(t2, qt, vars, tt2);
|
||||
pull_quantifier(t3, qt, vars, tt3);
|
||||
if (has_quantifiers(t1)) {
|
||||
pull_quantifier(t1, qt, vars, tt1);
|
||||
nt1 = m.mk_not(t1);
|
||||
pull_quantifier(nt1, qt, vars, ntt1);
|
||||
result = m.mk_and(m.mk_or(ntt1, tt2), m.mk_or(tt1, tt3));
|
||||
}
|
||||
else {
|
||||
result = m.mk_ite(t1, tt2, tt3);
|
||||
}
|
||||
}
|
||||
else if ((m.is_eq(fml, t1, t2) && m.is_bool(t1)) || m.is_iff(fml, t1, t2)) {
|
||||
expr_ref tt1(m), tt2(m), ntt1(m), ntt2(m), nt1(m), nt2(m);
|
||||
pull_quantifier(t1, qt, vars, tt1);
|
||||
pull_quantifier(t2, qt, vars, tt2);
|
||||
nt1 = m.mk_not(t1);
|
||||
nt2 = m.mk_not(t2);
|
||||
pull_quantifier(nt1, qt, vars, ntt1);
|
||||
pull_quantifier(nt2, qt, vars, ntt2);
|
||||
result = m.mk_and(m.mk_or(ntt1, tt2), m.mk_or(ntt2, tt1));
|
||||
}
|
||||
else {
|
||||
// the formula contains a quantifier, but it is "inaccessible"
|
||||
|
|
|
@ -303,8 +303,8 @@ public:
|
|||
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
|
||||
assert_exprs_from(ctx, *g);
|
||||
|
||||
unsigned timeout = p.get_uint("timeout", UINT_MAX);
|
||||
unsigned rlimit = p.get_uint("rlimit", 0);
|
||||
unsigned timeout = p.get_uint("timeout", ctx.params().m_timeout);
|
||||
unsigned rlimit = p.get_uint("rlimit", ctx.params().m_rlimit);
|
||||
|
||||
goal_ref_buffer result_goals;
|
||||
model_converter_ref mc;
|
||||
|
|
|
@ -539,7 +539,6 @@ namespace algebraic_numbers {
|
|||
}
|
||||
|
||||
bool factor(scoped_upoly const & up, factors & r) {
|
||||
// std::cout << "factor: "; upm().display(std::cout, up); std::cout << std::endl;
|
||||
if (m_factor) {
|
||||
return upm().factor(up, r, m_factor_params);
|
||||
}
|
||||
|
@ -547,7 +546,7 @@ namespace algebraic_numbers {
|
|||
scoped_upoly & up_sqf = m_isolate_tmp3;
|
||||
up_sqf.reset();
|
||||
upm().square_free(up.size(), up.c_ptr(), up_sqf);
|
||||
TRACE("anum_bug", upm().display(tout, up_sqf.size(), up_sqf.c_ptr()); tout << "\n";);
|
||||
TRACE("algebraic", upm().display(tout, up_sqf.size(), up_sqf.c_ptr()); tout << "\n";);
|
||||
r.push_back(up_sqf, 1);
|
||||
return false;
|
||||
}
|
||||
|
@ -566,6 +565,7 @@ namespace algebraic_numbers {
|
|||
}
|
||||
|
||||
void isolate_roots(scoped_upoly const & up, numeral_vector & roots) {
|
||||
TRACE("algebraic", upm().display(tout, up); tout << "\n";);
|
||||
if (up.empty())
|
||||
return; // ignore the zero polynomial
|
||||
factors & fs = m_isolate_factors;
|
||||
|
@ -586,6 +586,7 @@ namespace algebraic_numbers {
|
|||
upolynomial::numeral_vector const & f = fs[i];
|
||||
// polynomial f contains the non zero roots
|
||||
unsigned d = upm().degree(f);
|
||||
TRACE("algebraic", tout << "factor " << i << " degree: " << d << "\n";);
|
||||
if (d == 0)
|
||||
continue; // found all roots of f
|
||||
scoped_mpq r(qm());
|
||||
|
@ -601,8 +602,9 @@ namespace algebraic_numbers {
|
|||
}
|
||||
SASSERT(m_isolate_roots.empty() && m_isolate_lowers.empty() && m_isolate_uppers.empty());
|
||||
upm().sqf_isolate_roots(f.size(), f.c_ptr(), bqm(), m_isolate_roots, m_isolate_lowers, m_isolate_uppers);
|
||||
// collect rational/basic roots
|
||||
// collect rational/basic roots
|
||||
unsigned sz = m_isolate_roots.size();
|
||||
TRACE("algebraic", tout << "isolated roots: " << sz << "\n";);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
to_mpq(qm(), m_isolate_roots[i], r);
|
||||
roots.push_back(numeral(mk_basic_cell(r)));
|
||||
|
|
|
@ -29,7 +29,6 @@ Revision History:
|
|||
#include"ast_counter.h"
|
||||
#include"statistics.h"
|
||||
#include"lbool.h"
|
||||
#include"qe_util.h"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ Revision History:
|
|||
#include "pdr_closure.h"
|
||||
#include "pdr_context.h"
|
||||
#include "expr_safe_replace.h"
|
||||
#include "ast_util.h"
|
||||
|
||||
namespace pdr {
|
||||
|
||||
|
@ -147,7 +148,7 @@ namespace pdr {
|
|||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
||||
fmls[i] = close_fml(fmls[i].get());
|
||||
}
|
||||
return qe::mk_and(fmls);
|
||||
return expr_ref(mk_and(fmls), m);
|
||||
}
|
||||
|
||||
expr_ref closure::relax(unsigned i, expr* fml) {
|
||||
|
@ -169,7 +170,7 @@ namespace pdr {
|
|||
for (unsigned i = 0; i < As.size(); ++i) {
|
||||
fmls.push_back(relax(i, As[i]));
|
||||
}
|
||||
B = qe::mk_and(fmls);
|
||||
B = mk_and(fmls);
|
||||
return B;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ Notes:
|
|||
#include "smt_value_sort.h"
|
||||
#include "proof_utils.h"
|
||||
#include "dl_boogie_proof.h"
|
||||
#include "qe_util.h"
|
||||
#include "scoped_proof.h"
|
||||
#include "blast_term_ite_tactic.h"
|
||||
#include "model_implicant.h"
|
||||
|
|
|
@ -201,7 +201,7 @@ namespace pdr {
|
|||
lits.push_back(extract_consequence(lo, hi));
|
||||
lo = hi;
|
||||
}
|
||||
res = qe::mk_or(lits);
|
||||
res = mk_or(lits);
|
||||
IF_VERBOSE(2, { if (lits.size() > 1) { verbose_stream() << "combined lemma: " << mk_pp(res, m) << "\n"; } });
|
||||
#endif
|
||||
}
|
||||
|
@ -415,6 +415,7 @@ namespace pdr {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class collect_pure_proc {
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace pdr {
|
|||
void core_farkas_generalizer::operator()(model_node& n, expr_ref_vector& core, bool& uses_level) {
|
||||
ast_manager& m = n.pt().get_manager();
|
||||
if (core.empty()) return;
|
||||
expr_ref A(m), B(qe::mk_and(core)), C(m);
|
||||
expr_ref A(m), B(mk_and(core)), C(m);
|
||||
expr_ref_vector Bs(m);
|
||||
flatten_or(B, Bs);
|
||||
A = n.pt().get_propagation_formula(m_ctx.get_pred_transformers(), n.level());
|
||||
|
@ -129,13 +129,13 @@ namespace pdr {
|
|||
if (m_farkas_learner.get_lemma_guesses(A, B, lemmas)) {
|
||||
TRACE("pdr",
|
||||
tout << "Old core:\n" << mk_pp(B, m) << "\n";
|
||||
tout << "New core:\n" << mk_pp(qe::mk_and(lemmas), m) << "\n";);
|
||||
Bs[i] = qe::mk_and(lemmas);
|
||||
tout << "New core:\n" << mk_and(lemmas) << "\n";);
|
||||
Bs[i] = mk_and(lemmas);
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
if (change) {
|
||||
C = qe::mk_or(Bs);
|
||||
C = mk_or(Bs);
|
||||
TRACE("pdr", tout << "prop:\n" << mk_pp(A,m) << "\ngen:" << mk_pp(B, m) << "\nto: " << mk_pp(C, m) << "\n";);
|
||||
core.reset();
|
||||
flatten_and(C, core);
|
||||
|
@ -186,7 +186,7 @@ namespace pdr {
|
|||
}
|
||||
closure cl(n.pt(), m_is_closure);
|
||||
|
||||
expr_ref fml1 = qe::mk_and(core);
|
||||
expr_ref fml1 = mk_and(core);
|
||||
expr_ref fml2 = n.pt().get_formulas(n.level(), false);
|
||||
fml1_2.push_back(fml1);
|
||||
fml1_2.push_back(0);
|
||||
|
@ -205,7 +205,7 @@ namespace pdr {
|
|||
if (l_false == n.pt().is_reachable(nd, &conv2, uses_level1)) {
|
||||
new_cores.push_back(std::make_pair(conv2, uses_level1));
|
||||
change = true;
|
||||
expr_ref state1 = qe::mk_and(conv2);
|
||||
expr_ref state1 = mk_and(conv2);
|
||||
TRACE("pdr",
|
||||
tout << mk_pp(state, m) << "\n";
|
||||
tout << "Generalized to:\n" << mk_pp(state1, m) << "\n";);
|
||||
|
@ -593,7 +593,7 @@ namespace pdr {
|
|||
for (unsigned i = ut_size; i < t_size; i++) {
|
||||
conj.push_back(rule.get_tail(i));
|
||||
}
|
||||
result = qe::mk_and(conj);
|
||||
result = mk_and(conj);
|
||||
if (!sub.empty()) {
|
||||
expr_ref tmp = result;
|
||||
var_subst(m, false)(tmp, sub.size(), sub.c_ptr(), result);
|
||||
|
@ -685,7 +685,7 @@ namespace pdr {
|
|||
for (unsigned i = 0; i < rules.size(); ++i) {
|
||||
fmls.push_back(m.mk_not(mk_transition_rule(reps, level, *rules[i])));
|
||||
}
|
||||
fml = qe::mk_and(fmls);
|
||||
fml = mk_and(fmls);
|
||||
TRACE("pdr", tout << mk_pp(fml, m) << "\n";);
|
||||
return fml;
|
||||
}
|
||||
|
@ -741,7 +741,7 @@ namespace pdr {
|
|||
}
|
||||
}
|
||||
|
||||
expr_ref result = qe::mk_and(conjs);
|
||||
expr_ref result = mk_and(conjs);
|
||||
TRACE("pdr", tout << mk_pp(result, m) << "\n";);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
|
||||
#include "check_relation.h"
|
||||
#include "dl_relation_manager.h"
|
||||
#include "qe_util.h"
|
||||
#include "ast_util.h"
|
||||
#include "smt_kernel.h"
|
||||
#include <typeinfo>
|
||||
|
|
|
@ -23,7 +23,6 @@ Notes:
|
|||
--*/
|
||||
#include "udoc_relation.h"
|
||||
#include "dl_relation_manager.h"
|
||||
#include "qe_util.h"
|
||||
#include "ast_util.h"
|
||||
#include "smt_kernel.h"
|
||||
|
||||
|
|
|
@ -39,6 +39,17 @@ namespace nlsat {
|
|||
m_values.swap(other.m_values);
|
||||
m_assigned.swap(other.m_assigned);
|
||||
}
|
||||
void copy(assignment const& other) {
|
||||
m_assigned.reset();
|
||||
m_assigned.append(other.m_assigned);
|
||||
m_values.reserve(m_assigned.size(), anum());
|
||||
for (unsigned i = 0; i < m_assigned.size(); ++i) {
|
||||
if (is_assigned(i)) {
|
||||
am().set(m_values[i], other.value(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_core(var x, anum & v) {
|
||||
m_values.reserve(x+1, anum());
|
||||
m_assigned.reserve(x+1, false);
|
||||
|
@ -52,11 +63,26 @@ namespace nlsat {
|
|||
am().set(m_values[x], v);
|
||||
}
|
||||
void reset(var x) { if (x < m_assigned.size()) m_assigned[x] = false; }
|
||||
void reset() { m_assigned.reset(); }
|
||||
bool is_assigned(var x) const { return m_assigned.get(x, false); }
|
||||
anum const & value(var x) const { return m_values[x]; }
|
||||
virtual anum_manager & m() const { return am(); }
|
||||
virtual bool contains(var x) const { return is_assigned(x); }
|
||||
virtual anum const & operator()(var x) const { SASSERT(is_assigned(x)); return value(x); }
|
||||
void swap(var x, var y) {
|
||||
SASSERT(x < m_values.size() && y < m_values.size());
|
||||
std::swap(m_assigned[x], m_assigned[y]);
|
||||
std::swap(m_values[x], m_values[y]);
|
||||
}
|
||||
void display(std::ostream& out) const {
|
||||
for (unsigned i = 0; i < m_assigned.size(); ++i) {
|
||||
if (m_assigned[i]) {
|
||||
out << "x" << i << " := ";
|
||||
m_values.m().display(out, m_values[i]);
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -111,6 +111,20 @@ namespace nlsat {
|
|||
struct eq_proc { bool operator()(ineq_atom const * a1, ineq_atom const * a2) const; };
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, atom::kind k) {
|
||||
switch (k) {
|
||||
case atom::kind::EQ: return out << "=";
|
||||
case atom::kind::LT: return out << "<";
|
||||
case atom::kind::ROOT_EQ: return out << "= root";
|
||||
case atom::kind::ROOT_LT: return out << "< root";
|
||||
case atom::kind::ROOT_LE: return out << "<= root";
|
||||
case atom::kind::ROOT_GT: return out << "> root";
|
||||
case atom::kind::ROOT_GE: return out << ">= root";
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
class root_atom : public atom {
|
||||
friend class solver;
|
||||
var m_x;
|
||||
|
|
|
@ -60,7 +60,7 @@ class nla2bv_tactic : public tactic {
|
|||
expr_ref_vector m_trail;
|
||||
unsigned m_num_bits;
|
||||
unsigned m_default_bv_size;
|
||||
ref<filter_model_converter> m_fmc;
|
||||
filter_model_converter_ref m_fmc;
|
||||
|
||||
public:
|
||||
imp(ast_manager & m, params_ref const& p):
|
||||
|
|
|
@ -60,7 +60,7 @@ struct bv_size_reduction_tactic::imp {
|
|||
obj_map<app, numeral> m_unsigned_lowers;
|
||||
obj_map<app, numeral> m_unsigned_uppers;
|
||||
ref<bv_size_reduction_mc> m_mc;
|
||||
ref<filter_model_converter> m_fmc;
|
||||
filter_model_converter_ref m_fmc;
|
||||
scoped_ptr<expr_replacer> m_replacer;
|
||||
bool m_produce_models;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
bool contains(T1 * t1, T2 * t2) const { return m_set.contains(obj_pair(t1, t2)); }
|
||||
bool contains(obj_pair const & p) const { return m_set.contains(p); }
|
||||
void reset() { m_set.reset(); }
|
||||
bool empty() const { return m_set.empty(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,7 @@ void small_object_allocator::reset() {
|
|||
#define MASK ((1 << PTR_ALIGNMENT) - 1)
|
||||
|
||||
void small_object_allocator::deallocate(size_t size, void * p) {
|
||||
if (size == 0) return;
|
||||
#if defined(Z3DEBUG) && !defined(_WINDOWS)
|
||||
// Valgrind friendly
|
||||
memory::deallocate(p);
|
||||
|
@ -91,6 +92,7 @@ void small_object_allocator::deallocate(size_t size, void * p) {
|
|||
}
|
||||
|
||||
void * small_object_allocator::allocate(size_t size) {
|
||||
if (size == 0) return 0;
|
||||
#if defined(Z3DEBUG) && !defined(_WINDOWS)
|
||||
// Valgrind friendly
|
||||
return memory::allocate(size);
|
||||
|
|
Loading…
Reference in a new issue