3
0
Fork 0
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:
Nikolaj Bjorner 2016-03-19 12:01:44 -07:00
parent f951372f03
commit f175f864ec
32 changed files with 323 additions and 38 deletions

View file

@ -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.
*/

View file

@ -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.

View file

@ -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;
}

View file

@ -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_ */

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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.
*/

View file

@ -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);

View file

@ -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_ */

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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();

View file

@ -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"

View file

@ -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;

View file

@ -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)));

View file

@ -29,7 +29,6 @@ Revision History:
#include"ast_counter.h"
#include"statistics.h"
#include"lbool.h"
#include"qe_util.h"
namespace datalog {

View file

@ -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;
}

View file

@ -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"

View file

@ -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 {

View file

@ -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;
}

View file

@ -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>

View file

@ -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"

View file

@ -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";
}
}
}
};
/**

View file

@ -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;

View file

@ -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):

View file

@ -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;

View file

@ -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

View file

@ -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);