3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

merged with unstable

This commit is contained in:
Ken McMillan 2013-10-18 17:26:41 -07:00
commit 3a0947b3ba
413 changed files with 31618 additions and 17204 deletions

View file

@ -268,6 +268,8 @@ public:
bool is_int_real(expr const * n) const { return is_int_real(get_sort(n)); }
MATCH_UNARY(is_uminus);
MATCH_UNARY(is_to_real);
MATCH_UNARY(is_to_int);
MATCH_BINARY(is_sub);
MATCH_BINARY(is_add);
MATCH_BINARY(is_mul);

View file

@ -300,7 +300,7 @@ std::ostream & operator<<(std::ostream & out, func_decl_info const & info) {
//
// -----------------------------------
char const * g_ast_kind_names[] = {"application", "variable", "quantifier", "sort", "function declaration" };
static char const * g_ast_kind_names[] = {"application", "variable", "quantifier", "sort", "function declaration" };
char const * get_ast_kind_name(ast_kind k) {
return g_ast_kind_names[k];
@ -2765,7 +2765,7 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro
app const * cls = to_app(f1);
unsigned num_args = cls->get_num_args();
#ifdef Z3DEBUG
vector<bool> found;
svector<bool> found;
#endif
for (unsigned i = 0; i < num_args; i++) {
expr * lit = cls->get_arg(i);

View file

@ -1194,7 +1194,6 @@ enum pattern_op_kind {
heurisitic quantifier instantiation.
*/
class pattern_decl_plugin : public decl_plugin {
sort * m_list;
public:
virtual decl_plugin * mk_fresh() { return alloc(pattern_decl_plugin); }

View file

@ -134,6 +134,16 @@ bool lt(ast * n1, ast * n2) {
}
}
bool is_sorted(unsigned num, expr * const * ns) {
for (unsigned i = 1; i < num; i++) {
ast * prev = ns[i-1];
ast * curr = ns[i];
if (lt(curr, prev))
return false;
}
return true;
}
bool lex_lt(unsigned num, ast * const * n1, ast * const * n2) {
for (unsigned i = 0; i < num; i ++) {
if (n1[i] == n2[i])

View file

@ -22,6 +22,7 @@ Revision History:
class ast;
bool lt(ast * n1, ast * n2);
bool is_sorted(unsigned num, expr * const * ns);
struct ast_to_lt {
bool operator()(ast * n1, ast * n2) const { return lt(n1, n2); }

View file

@ -260,6 +260,7 @@ class smt_printer {
else {
m_out << sym << "[";
}
for (unsigned i = 0; i < num_params; ++i) {
parameter const& p = params[i];
if (p.is_ast()) {
@ -642,9 +643,7 @@ class smt_printer {
m_out << m_var_names[m_num_var_names - idx - 1];
}
else {
if (!m_is_smt2) {
m_out << "?" << idx;
}
m_out << "?" << idx;
}
}

View file

@ -1,3 +1,21 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
ast_util.cpp
Abstract:
Helper functions
Author:
Leonardo de Moura (leonardo) 2007-06-08.
Revision History:
--*/
#include "ast_util.h"
app * mk_list_assoc_app(ast_manager & m, func_decl * f, unsigned num_args, expr * const * args) {
@ -138,3 +156,38 @@ expr * get_clause_literal(ast_manager & m, expr * cls, unsigned idx) {
SASSERT(m.is_or(cls));
return to_app(cls)->get_arg(idx);
}
expr * mk_and(ast_manager & m, unsigned num_args, expr * const * args) {
if (num_args == 0)
return m.mk_true();
else if (num_args == 1)
return args[0];
else
return m.mk_and(num_args, args);
}
expr * mk_or(ast_manager & m, unsigned num_args, expr * const * args) {
if (num_args == 0)
return m.mk_false();
else if (num_args == 1)
return args[0];
else
return m.mk_or(num_args, args);
}
expr * mk_not(ast_manager & m, expr * arg) {
expr * atom;
if (m.is_not(arg, atom))
return atom;
else
return m.mk_not(arg);
}
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++) {
for (unsigned j = i + 1; j < num_args; j++)
new_diseqs.push_back(m.mk_not(m.mk_eq(args[i], args[j])));
}
return mk_and(m, new_diseqs.size(), new_diseqs.c_ptr());
}

View file

@ -95,5 +95,36 @@ bool is_clause(ast_manager & m, expr * n);
unsigned get_clause_num_literals(ast_manager & m, expr * cls);
expr * get_clause_literal(ast_manager & m, expr * cls, unsigned idx);
// -----------------------------------
//
// Goodies for creating Boolean expressions
//
// -----------------------------------
/**
Return (and args[0] ... args[num_args-1]) if num_args >= 2
Return args[0] if num_args == 1
Return true if num_args == 0
*/
expr * mk_and(ast_manager & m, unsigned num_args, expr * const * args);
/**
Return (or args[0] ... args[num_args-1]) if num_args >= 2
Return args[0] if num_args == 1
Return false if num_args == 0
*/
expr * mk_or(ast_manager & m, unsigned num_args, expr * const * args);
/**
Return a if arg = (not a)
Retur (not arg) otherwise
*/
expr * mk_not(ast_manager & m, expr * 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);
#endif /* _AST_UTIL_H_ */

View file

@ -210,6 +210,10 @@ func_decl * bv_decl_plugin::mk_unary(ptr_vector<func_decl> & decls, decl_kind k,
func_decl * bv_decl_plugin::mk_int2bv(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain) {
if (bv_size == 0) {
m_manager->raise_exception("bit-vector size must be greater than zero");
}
force_ptr_array_size(m_int2bv, bv_size + 1);
if (arity != 1) {
@ -415,6 +419,9 @@ func_decl * bv_decl_plugin::mk_num_decl(unsigned num_parameters, parameter const
return 0;
}
unsigned bv_size = parameters[1].get_int();
if (bv_size == 0) {
m_manager->raise_exception("bit-vector size must be greater than zero");
}
// TODO: sign an error if the parameters[0] is out of range, that is, it is a value not in [0, 2^{bv_size})
// This cannot be enforced now, since some Z3 modules try to generate these invalid numerals.
// After SMT-COMP, I should find all offending modules.
@ -766,7 +773,7 @@ bool bv_recognizers::is_zero(expr const * n) const {
return decl->get_parameter(0).get_rational().is_zero();
}
bool bv_recognizers::is_extract(expr const* e, unsigned& low, unsigned& high, expr*& b) {
bool bv_recognizers::is_extract(expr const* e, unsigned& low, unsigned& high, expr*& b) const {
if (!is_extract(e)) return false;
low = get_extract_low(e);
high = get_extract_high(e);
@ -774,7 +781,7 @@ bool bv_recognizers::is_extract(expr const* e, unsigned& low, unsigned& high, ex
return true;
}
bool bv_recognizers::is_bv2int(expr const* e, expr*& r) {
bool bv_recognizers::is_bv2int(expr const* e, expr*& r) const {
if (!is_bv2int(e)) return false;
r = to_app(e)->get_arg(0);
return true;

View file

@ -288,10 +288,10 @@ public:
bool is_extract(expr const * e) const { return is_app_of(e, get_fid(), OP_EXTRACT); }
unsigned get_extract_high(func_decl const * f) const { return f->get_parameter(0).get_int(); }
unsigned get_extract_low(func_decl const * f) const { return f->get_parameter(1).get_int(); }
unsigned get_extract_high(expr const * n) { SASSERT(is_extract(n)); return get_extract_high(to_app(n)->get_decl()); }
unsigned get_extract_low(expr const * n) { SASSERT(is_extract(n)); return get_extract_low(to_app(n)->get_decl()); }
bool is_extract(expr const * e, unsigned & low, unsigned & high, expr * & b);
bool is_bv2int(expr const * e, expr * & r);
unsigned get_extract_high(expr const * n) const { SASSERT(is_extract(n)); return get_extract_high(to_app(n)->get_decl()); }
unsigned get_extract_low(expr const * n) const { SASSERT(is_extract(n)); return get_extract_low(to_app(n)->get_decl()); }
bool is_extract(expr const * e, unsigned & low, unsigned & high, expr * & b) const;
bool is_bv2int(expr const * e, expr * & r) const;
bool is_bv_add(expr const * e) const { return is_app_of(e, get_fid(), OP_BADD); }
bool is_bv_sub(expr const * e) const { return is_app_of(e, get_fid(), OP_BSUB); }
bool is_bv_mul(expr const * e) const { return is_app_of(e, get_fid(), OP_BMUL); }

View file

@ -84,7 +84,8 @@ class datatype_decl {
ptr_vector<constructor_decl> m_constructors;
public:
datatype_decl(const symbol & n, unsigned num_constructors, constructor_decl * const * constructors):
m_name(n), m_constructors(num_constructors, constructors) {}
m_name(n), m_constructors(num_constructors, constructors) {
}
~datatype_decl() {
std::for_each(m_constructors.begin(), m_constructors.end(), delete_proc<constructor_decl>());
}

View file

@ -326,6 +326,7 @@ namespace datalog {
}
unsigned index0;
sort* last_sort = 0;
SASSERT(num_params > 0);
for (unsigned i = 0; i < num_params; ++i) {
parameter const& p = params[i];
if (!p.is_int()) {
@ -636,9 +637,13 @@ namespace datalog {
app* dl_decl_util::mk_numeral(uint64 value, sort* s) {
if (is_finite_sort(s)) {
uint64 sz = 0;
if (try_get_size(s, sz) && sz <= value) {
m.raise_exception("value is out of bounds");
}
parameter params[2] = { parameter(rational(value, rational::ui64())), parameter(s) };
return m.mk_const(m.mk_func_decl(m_fid, OP_DL_CONSTANT, 2, params, 0, (sort*const*)0));
}
}
if (m_arith.is_int(s) || m_arith.is_real(s)) {
return m_arith.mk_numeral(rational(value, rational::ui64()), s);
}
@ -652,13 +657,15 @@ namespace datalog {
SASSERT(value == 1);
return m.mk_true();
}
m.raise_exception("unrecognized sort");
std::stringstream strm;
strm << "sort '" << mk_pp(s, m) << "' is not recognized as a sort that contains numeric values.\nUse Bool, BitVec, Int, Real, or a Finite domain sort";
m.raise_exception(strm.str().c_str());
return 0;
}
bool dl_decl_util::is_numeral(expr* e, uint64& v) const {
bool dl_decl_util::is_numeral(const expr* e, uint64& v) const {
if (is_numeral(e)) {
app* c = to_app(e);
const app* c = to_app(e);
SASSERT(c->get_decl()->get_num_parameters() == 2);
parameter const& p = c->get_decl()->get_parameter(0);
SASSERT(p.is_rational());

View file

@ -169,11 +169,11 @@ namespace datalog {
app* mk_le(expr* a, expr* b);
bool is_lt(expr* a) { return is_app_of(a, m_fid, OP_DL_LT); }
bool is_lt(const expr* a) const { return is_app_of(a, m_fid, OP_DL_LT); }
bool is_numeral(expr* c) const { return is_app_of(c, m_fid, OP_DL_CONSTANT); }
bool is_numeral(const expr* c) const { return is_app_of(c, m_fid, OP_DL_CONSTANT); }
bool is_numeral(expr* e, uint64& v) const;
bool is_numeral(const expr* e, uint64& v) const;
//
// Utilities for extracting constants

View file

@ -20,52 +20,50 @@ Notes:
#include "expr_abstract.h"
#include "map.h"
void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) {
ast_ref_vector pinned(m);
ptr_vector<expr> stack;
obj_map<expr, expr*> map;
void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) {
expr * curr = 0, *b = 0;
SASSERT(n->get_ref_count() > 0);
stack.push_back(n);
m_stack.push_back(n);
for (unsigned i = 0; i < num_bound; ++i) {
b = bound[i];
expr* v = m.mk_var(base + num_bound - i - 1, m.get_sort(b));
pinned.push_back(v);
map.insert(b, v);
m_pinned.push_back(v);
m_map.insert(b, v);
}
while(!stack.empty()) {
curr = stack.back();
if (map.contains(curr)) {
stack.pop_back();
while(!m_stack.empty()) {
curr = m_stack.back();
if (m_map.contains(curr)) {
m_stack.pop_back();
continue;
}
switch(curr->get_kind()) {
case AST_VAR: {
map.insert(curr, curr);
stack.pop_back();
m_map.insert(curr, curr);
m_stack.pop_back();
break;
}
case AST_APP: {
app* a = to_app(curr);
bool all_visited = true;
ptr_vector<expr> args;
m_args.reset();
for (unsigned i = 0; i < a->get_num_args(); ++i) {
if (!map.find(a->get_arg(i), b)) {
stack.push_back(a->get_arg(i));
if (!m_map.find(a->get_arg(i), b)) {
m_stack.push_back(a->get_arg(i));
all_visited = false;
}
else {
args.push_back(b);
m_args.push_back(b);
}
}
if (all_visited) {
b = m.mk_app(a->get_decl(), args.size(), args.c_ptr());
pinned.push_back(b);
map.insert(curr, b);
stack.pop_back();
b = m.mk_app(a->get_decl(), m_args.size(), m_args.c_ptr());
m_pinned.push_back(b);
m_map.insert(curr, b);
m_stack.pop_back();
}
break;
}
@ -81,17 +79,24 @@ void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* cons
}
expr_abstract(m, new_base, num_bound, bound, q->get_expr(), result1);
b = m.update_quantifier(q, patterns.size(), patterns.c_ptr(), result1.get());
pinned.push_back(b);
map.insert(curr, b);
stack.pop_back();
m_pinned.push_back(b);
m_map.insert(curr, b);
m_stack.pop_back();
break;
}
default:
UNREACHABLE();
}
}
if (!map.find(n, b)) {
UNREACHABLE();
}
VERIFY (m_map.find(n, b));
result = b;
m_pinned.reset();
m_map.reset();
m_stack.reset();
m_args.reset();
}
void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) {
expr_abstractor abs(m);
abs(base, num_bound, bound, n, result);
}

View file

@ -21,6 +21,17 @@ Notes:
#include"ast.h"
class expr_abstractor {
ast_manager& m;
expr_ref_vector m_pinned;
ptr_vector<expr> m_stack, m_args;
obj_map<expr, expr*> m_map;
public:
expr_abstractor(ast_manager& m): m(m), m_pinned(m) {}
void operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result);
};
void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result);
#endif

View file

@ -200,6 +200,7 @@ func_decl * float_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_par
}
else {
m_manager->raise_exception("sort of floating point constant was not specified");
UNREACHABLE();
}
SASSERT(is_sort_of(s, m_family_id, FLOAT_SORT));
@ -254,7 +255,11 @@ func_decl * float_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_param
case OP_FLOAT_IS_ZERO: name = "isZero"; break;
case OP_FLOAT_IS_NZERO: name = "isNZero"; break;
case OP_FLOAT_IS_PZERO: name = "isPZero"; break;
case OP_FLOAT_IS_SIGN_MINUS: name = "isSignMinus"; break;
case OP_FLOAT_IS_SIGN_MINUS: name = "isSignMinus"; break;
case OP_FLOAT_IS_NAN: name = "isNaN"; break;
case OP_FLOAT_IS_INF: name = "isInfinite"; break;
case OP_FLOAT_IS_NORMAL: name = "isNormal"; break;
case OP_FLOAT_IS_SUBNORMAL: name = "isSubnormal"; break;
default:
UNREACHABLE();
break;
@ -353,27 +358,22 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters,
sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1);
symbol name("asFloat");
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
}
else {
// .. Otherwise we only know how to convert rationals/reals.
if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int()))
m_manager->raise_exception("expecting two integer parameters to asFloat");
if (arity != 2 && arity != 3)
m_manager->raise_exception("invalid number of arguments to asFloat operator");
if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort)
if (arity == 3 && domain[2] != m_int_sort)
m_manager->raise_exception("sort mismatch");
if (!is_rm_sort(domain[0]) ||
!(domain[1] == m_real_sort || is_sort_of(domain[1], m_family_id, FLOAT_SORT)))
m_manager->raise_exception("sort mismatch");
if (arity == 2) {
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
symbol name("asFloat");
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
else {
if (domain[2] != m_int_sort)
m_manager->raise_exception("sort mismatch");
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
symbol name("asFloat");
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int());
symbol name("asFloat");
return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters));
}
}
@ -419,6 +419,10 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
case OP_FLOAT_IS_NZERO:
case OP_FLOAT_IS_PZERO:
case OP_FLOAT_IS_SIGN_MINUS:
case OP_FLOAT_IS_NAN:
case OP_FLOAT_IS_INF:
case OP_FLOAT_IS_NORMAL:
case OP_FLOAT_IS_SUBNORMAL:
return mk_unary_rel_decl(k, num_parameters, parameters, arity, domain, range);
case OP_FLOAT_ABS:
case OP_FLOAT_UMINUS:
@ -477,9 +481,13 @@ void float_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol co
op_names.push_back(builtin_name("<=", OP_FLOAT_LE));
op_names.push_back(builtin_name(">=", OP_FLOAT_GE));
op_names.push_back(builtin_name("isNaN", OP_FLOAT_IS_NAN));
op_names.push_back(builtin_name("isInfinite", OP_FLOAT_IS_INF));
op_names.push_back(builtin_name("isZero", OP_FLOAT_IS_ZERO));
op_names.push_back(builtin_name("isNZero", OP_FLOAT_IS_NZERO));
op_names.push_back(builtin_name("isPZero", OP_FLOAT_IS_PZERO));
op_names.push_back(builtin_name("isNormal", OP_FLOAT_IS_NORMAL));
op_names.push_back(builtin_name("isSubnormal", OP_FLOAT_IS_SUBNORMAL));
op_names.push_back(builtin_name("isSignMinus", OP_FLOAT_IS_SIGN_MINUS));
op_names.push_back(builtin_name("min", OP_FLOAT_MIN));
@ -496,6 +504,15 @@ void float_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbo
sort_names.push_back(builtin_name("RoundingMode", ROUNDING_MODE_SORT));
}
expr * float_decl_plugin::get_some_value(sort * s) {
SASSERT(s->is_sort_of(m_family_id, FLOAT_SORT));
mpf tmp;
m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp);
expr * res = this->mk_value(tmp);
m_fm.del(tmp);
return res;
}
bool float_decl_plugin::is_value(app * e) const {
if (e->get_family_id() != m_family_id)
return false;

View file

@ -61,9 +61,13 @@ enum float_op_kind {
OP_FLOAT_GT,
OP_FLOAT_LE,
OP_FLOAT_GE,
OP_FLOAT_IS_NAN,
OP_FLOAT_IS_INF,
OP_FLOAT_IS_ZERO,
OP_FLOAT_IS_NZERO,
OP_FLOAT_IS_NORMAL,
OP_FLOAT_IS_SUBNORMAL,
OP_FLOAT_IS_PZERO,
OP_FLOAT_IS_NZERO,
OP_FLOAT_IS_SIGN_MINUS,
OP_TO_FLOAT,
@ -140,6 +144,7 @@ public:
unsigned arity, sort * const * domain, sort * range);
virtual void get_op_names(svector<builtin_name> & op_names, symbol const & logic);
virtual void get_sort_names(svector<builtin_name> & sort_names, symbol const & logic);
virtual expr * get_some_value(sort * s);
virtual bool is_value(app* e) const;
virtual bool is_unique_value(app* e) const { return is_value(e); }
@ -222,7 +227,7 @@ public:
app * mk_rem(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_REM, arg1, arg2); }
app * mk_max(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MAX, arg1, arg2); }
app * mk_min(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MIN, arg1, arg2); }
app * mk_abs(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ABS, arg1, arg2); }
app * mk_abs(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_ABS, arg1); }
app * mk_sqrt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_SQRT, arg1, arg2); }
app * mk_round(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ROUND_TO_INTEGRAL, arg1, arg2); }
app * mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4) {
@ -236,7 +241,11 @@ public:
app * mk_le(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_LE, arg1, arg2); }
app * mk_ge(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_GE, arg1, arg2); }
app * mk_is_nan(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NAN, arg1); }
app * mk_is_inf(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_INF, arg1); }
app * mk_is_zero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_ZERO, arg1); }
app * mk_is_normal(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NORMAL, arg1); }
app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SUBNORMAL, arg1); }
app * mk_is_nzero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NZERO, arg1); }
app * mk_is_pzero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_PZERO, arg1); }
app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SIGN_MINUS, arg1); }

View file

@ -79,7 +79,6 @@ void func_decl_dependencies::collect_ng_func_decls(expr * n, func_decl_set * s)
*/
class func_decl_dependencies::top_sort {
enum color { OPEN, IN_PROGRESS, CLOSED };
ast_manager & m_manager;
dependency_graph & m_deps;
typedef obj_map<func_decl, color> color_map;
@ -177,7 +176,7 @@ class func_decl_dependencies::top_sort {
}
public:
top_sort(ast_manager & m, dependency_graph & deps):m_manager(m), m_deps(deps) {}
top_sort(dependency_graph & deps) : m_deps(deps) {}
bool operator()(func_decl * new_decl) {
@ -198,7 +197,7 @@ bool func_decl_dependencies::insert(func_decl * f, func_decl_set * s) {
m_deps.insert(f, s);
top_sort cycle_detector(m_manager, m_deps);
top_sort cycle_detector(m_deps);
if (cycle_detector(f)) {
m_deps.erase(f);
dealloc(s);

View file

@ -597,8 +597,9 @@ void hint_to_macro_head(ast_manager & m, app * head, unsigned num_decls, app_ref
is_hint_head(head, vars) must also return true
*/
bool macro_util::is_poly_hint(expr * n, app * head, expr * exception) {
TRACE("macro_util_hint", tout << "is_poly_hint n:\n" << mk_pp(n, m_manager) << "\nhead:\n" << mk_pp(head, m_manager) << "\nexception:\n"
<< mk_pp(exception, m_manager) << "\n";);
TRACE("macro_util_hint", tout << "is_poly_hint n:\n" << mk_pp(n, m_manager) << "\nhead:\n" << mk_pp(head, m_manager) << "\nexception:\n";
if (exception) tout << mk_pp(exception, m_manager); else tout << "<null>";
tout << "\n";);
ptr_buffer<var> vars;
if (!is_hint_head(head, vars)) {
TRACE("macro_util_hint", tout << "failed because head is not hint head\n";);
@ -792,7 +793,10 @@ void macro_util::collect_arith_macro_candidates(expr * lhs, expr * rhs, expr * a
mk_add(args.size(), args.c_ptr(), m_manager.get_sort(arg), rest);
expr_ref def(m_manager);
mk_sub(rhs, rest, def);
add_arith_macro_candidate(to_app(arg), num_decls, def, atom, is_ineq, _is_poly_hint, r);
// If is_poly_hint, rhs may contain variables that do not occur in to_app(arg).
// So, we should re-check.
if (!_is_poly_hint || is_poly_hint(def, to_app(arg), 0))
add_arith_macro_candidate(to_app(arg), num_decls, def, atom, is_ineq, _is_poly_hint, r);
}
else if (is_times_minus_one(arg, neg_arg) && is_app(neg_arg)) {
f = to_app(neg_arg)->get_decl();
@ -810,7 +814,10 @@ void macro_util::collect_arith_macro_candidates(expr * lhs, expr * rhs, expr * a
mk_add(args.size(), args.c_ptr(), m_manager.get_sort(arg), rest);
expr_ref def(m_manager);
mk_sub(rest, rhs, def);
add_arith_macro_candidate(to_app(neg_arg), num_decls, def, atom, is_ineq, _is_poly_hint, r);
// If is_poly_hint, rhs may contain variables that do not occur in to_app(neg_arg).
// So, we should re-check.
if (!_is_poly_hint || is_poly_hint(def, to_app(neg_arg), 0))
add_arith_macro_candidate(to_app(neg_arg), num_decls, def, atom, is_ineq, _is_poly_hint, r);
}
}
}

View file

@ -22,10 +22,9 @@ Revision History:
#include"uint_set.h"
#include"var_subst.h"
quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm, basic_simplifier_plugin & p, simplifier & s) :
quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s) :
m_manager(m),
m_macro_manager(mm),
m_bsimp(p),
m_simplifier(s),
m_new_vars(m),
m_new_eqs(m),

View file

@ -32,7 +32,6 @@ class quasi_macros {
ast_manager & m_manager;
macro_manager & m_macro_manager;
basic_simplifier_plugin & m_bsimp;
simplifier & m_simplifier;
occurrences_map m_occurrences;
ptr_vector<expr> m_todo;
@ -57,7 +56,7 @@ class quasi_macros {
void apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs);
public:
quasi_macros(ast_manager & m, macro_manager & mm, basic_simplifier_plugin & p, simplifier & s);
quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s);
~quasi_macros();
/**

View file

@ -119,13 +119,13 @@
:pattern (?select (?select (?asElems e) a) i))))
(assert (forall ((x Int) (f Int) (a0 Int))
(!
(or (<= (+ a0 (* -1 (?fClosedTime f))) 0)
(or (<= (+ a0 (* (- 1) (?fClosedTime f))) 0)
(not (= (?isAllocated x a0) 1))
(= (?isAllocated (?select f x) a0) 1))
:pattern (?isAllocated (?select f x) a0))))
(assert (forall ((a Int) (e Int) (i Int) (a0 Int))
(!
(or (<= (+ a0 (* -1 (?eClosedTime e))) 0)
(or (<= (+ a0 (* (- 1) (?eClosedTime e))) 0)
(not (= (?isAllocated a a0) 1))
(= (?isAllocated (?select (?select e a) i) a0) 1))
:pattern (?isAllocated (?select (?select e a) i) a0))))
@ -281,13 +281,13 @@
:pattern (IntsAllocated h (?StructGet_ s f)))))
(assert (forall ((x Int) (f Int) (a0 Int))
(!
(or (<= (+ a0 (* -1 (?fClosedTime f))) 0)
(or (<= (+ a0 (* (- 1) (?fClosedTime f))) 0)
(not (?isAllocated_ x a0))
(?isAllocated_ (?select f x) a0))
:pattern (?isAllocated_ (?select f x) a0))))
(assert (forall ((a Int) (e Int) (i Int) (a0 Int))
(!
(or (<= (+ a0 (* -1 (?eClosedTime e))) 0)
(or (<= (+ a0 (* (- 1) (?eClosedTime e))) 0)
(not (?isAllocated_ a a0))
(?isAllocated_ (?select (?select e a) i) a0))
:pattern (?isAllocated_ (?select (?select e a) i) a0))))

View file

@ -30,7 +30,7 @@ class recurse_expr : public Visitor {
vector<T, CallDestructors> m_results2;
bool is_cached(expr * n) const { T c; return m_cache.find(n, c); }
T get_cached(expr * n) const { T c; m_cache.find(n, c); return c; }
T get_cached(expr * n) const { return m_cache.find(n); }
void cache_result(expr * n, T c) { m_cache.insert(n, c); }
void visit(expr * n, bool & visited);

View file

@ -118,7 +118,7 @@ public:
void mk_eq(expr * arg1, expr * arg2, expr_ref & result) {
if (mk_eq_core(arg1, arg2, result) == BR_FAILED)
result = m_util.mk_le(arg1, arg2);
result = m_util.mk_eq(arg1, arg2);
}
void mk_le(expr * arg1, expr * arg2, expr_ref & result) {
if (mk_le_core(arg1, arg2, result) == BR_FAILED)

View file

@ -25,6 +25,7 @@ void array_rewriter::updt_params(params_ref const & _p) {
array_rewriter_params p(_p);
m_sort_store = p.sort_store();
m_expand_select_store = p.expand_select_store();
m_expand_store_eq = p.expand_store_eq();
}
void array_rewriter::get_param_descrs(param_descrs & r) {
@ -365,3 +366,40 @@ br_status array_rewriter::mk_set_subset(expr * arg1, expr * arg2, expr_ref & res
return BR_REWRITE3;
}
br_status array_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) {
if (!m_expand_store_eq) {
return BR_FAILED;
}
expr* lhs1 = lhs;
while (m_util.is_store(lhs1)) {
lhs1 = to_app(lhs1)->get_arg(0);
}
expr* rhs1 = rhs;
while (m_util.is_store(rhs1)) {
rhs1 = to_app(rhs1)->get_arg(0);
}
if (lhs1 != rhs1) {
return BR_FAILED;
}
ptr_buffer<expr> fmls, args;
expr* e;
expr_ref tmp1(m()), tmp2(m());
#define MK_EQ() \
while (m_util.is_store(e)) { \
args.push_back(lhs); \
args.append(to_app(e)->get_num_args()-2,to_app(e)->get_args()+1); \
mk_select(args.size(), args.c_ptr(), tmp1); \
args[0] = rhs; \
mk_select(args.size(), args.c_ptr(), tmp2); \
fmls.push_back(m().mk_eq(tmp1, tmp2)); \
e = to_app(e)->get_arg(0); \
args.reset(); \
} \
e = lhs;
MK_EQ();
e = rhs;
MK_EQ();
result = m().mk_and(fmls.size(), fmls.c_ptr());
return BR_REWRITE_FULL;
}

View file

@ -31,12 +31,14 @@ class array_rewriter {
array_util m_util;
bool m_sort_store;
bool m_expand_select_store;
bool m_expand_store_eq;
template<bool CHECK_DISEQ>
lbool compare_args(unsigned num_args, expr * const * args1, expr * const * args2);
public:
array_rewriter(ast_manager & m, params_ref const & p = params_ref()):
m_util(m) {
updt_params(p);
}
ast_manager & m() const { return m_util.get_manager(); }
family_id get_fid() const { return m_util.get_family_id(); }
@ -60,6 +62,7 @@ public:
br_status mk_set_complement(expr * arg, expr_ref & result);
br_status mk_set_difference(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_set_subset(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_eq_core(expr * lhs, expr * rhs, expr_ref & result);
};
#endif

View file

@ -2,4 +2,5 @@ def_module_params(module_name='rewriter',
class_name='array_rewriter_params',
export=True,
params=(("expand_select_store", BOOL, False, "replace a (select (store ...) ...) term by an if-then-else term"),
("expand_store_eq", BOOL, False, "reduce (store ...) = (store ...) with a common base into selects"),
("sort_store", BOOL, False, "sort nested stores when the indices are known to be different")))

View file

@ -0,0 +1,175 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
ast_counter.cpp
Abstract:
Routines for counting features of terms, such as free variables.
Author:
Nikolaj Bjorner (nbjorner) 2013-03-18.
Revision History:
--*/
#include "ast_counter.h"
#include "var_subst.h"
void counter::update(unsigned el, int delta) {
int & counter = get(el);
SASSERT(!m_stay_non_negative || counter>=0);
SASSERT(!m_stay_non_negative || static_cast<int>(counter)>=-delta);
counter += delta;
}
int & counter::get(unsigned el) {
return m_data.insert_if_not_there2(el, 0)->get_data().m_value;
}
counter & counter::count(unsigned sz, const unsigned * els, int delta) {
for(unsigned i=0; i<sz; i++) {
update(els[i], delta);
}
return *this;
}
unsigned counter::get_positive_count() const {
unsigned cnt = 0;
iterator eit = begin();
iterator eend = end();
for(; eit!=eend; ++eit) {
if( eit->m_value>0 ) {
cnt++;
}
}
return cnt;
}
void counter::collect_positive(uint_set & acc) const {
iterator eit = begin();
iterator eend = end();
for(; eit!=eend; ++eit) {
if(eit->m_value>0) { acc.insert(eit->m_key); }
}
}
bool counter::get_max_positive(unsigned & res) const {
bool found = false;
iterator eit = begin();
iterator eend = end();
for(; eit!=eend; ++eit) {
if( eit->m_value>0 && (!found || eit->m_key>res) ) {
found = true;
res = eit->m_key;
}
}
return found;
}
unsigned counter::get_max_positive() const {
unsigned max_pos;
VERIFY(get_max_positive(max_pos));
return max_pos;
}
int counter::get_max_counter_value() const {
int res = 0;
iterator eit = begin();
iterator eend = end();
for (; eit!=eend; ++eit) {
if( eit->m_value>res ) {
res = eit->m_value;
}
}
return res;
}
void var_counter::count_vars(ast_manager & m, const app * pred, int coef) {
unsigned n = pred->get_num_args();
for (unsigned i = 0; i < n; i++) {
m_sorts.reset();
m_todo.reset();
m_mark.reset();
::get_free_vars(m_mark, m_todo, pred->get_arg(i), m_sorts);
for (unsigned j = 0; j < m_sorts.size(); ++j) {
if (m_sorts[j]) {
update(j, coef);
}
}
}
}
unsigned var_counter::get_max_var(bool& has_var) {
has_var = false;
unsigned max_var = 0;
ptr_vector<quantifier> qs;
while (!m_todo.empty()) {
expr* e = m_todo.back();
m_todo.pop_back();
if (m_visited.is_marked(e)) {
continue;
}
m_visited.mark(e, true);
switch(e->get_kind()) {
case AST_QUANTIFIER: {
qs.push_back(to_quantifier(e));
break;
}
case AST_VAR: {
if (to_var(e)->get_idx() >= max_var) {
has_var = true;
max_var = to_var(e)->get_idx();
}
break;
}
case AST_APP: {
app* a = to_app(e);
for (unsigned i = 0; i < a->get_num_args(); ++i) {
m_todo.push_back(a->get_arg(i));
}
break;
}
default:
UNREACHABLE();
break;
}
}
m_visited.reset();
while (!qs.empty()) {
var_counter aux_counter;
quantifier* q = qs.back();
qs.pop_back();
aux_counter.m_todo.push_back(q->get_expr());
bool has_var1 = false;
unsigned max_v = aux_counter.get_max_var(has_var1);
if (max_v >= max_var + q->get_num_decls()) {
max_var = max_v - q->get_num_decls();
has_var = has_var || has_var1;
}
}
return max_var;
}
unsigned var_counter::get_max_var(expr* e) {
bool has_var = false;
m_todo.push_back(e);
return get_max_var(has_var);
}
unsigned var_counter::get_next_var(expr* e) {
bool has_var = false;
m_todo.push_back(e);
unsigned mv = get_max_var(has_var);
if (has_var) mv++;
return mv;
}

View file

@ -0,0 +1,109 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
ast_counter.h
Abstract:
Routines for counting features of terms, such as free variables.
Author:
Nikolaj Bjorner (nbjorner) 2013-03-18.
Krystof Hoder (t-khoder) 2010-10-10.
Revision History:
Hoisted from dl_util.h 2013-03-18.
--*/
#ifndef _AST_COUNTER_H_
#define _AST_COUNTER_H_
#include "ast.h"
#include "map.h"
#include "uint_set.h"
class counter {
protected:
typedef u_map<int> map_impl;
map_impl m_data;
const bool m_stay_non_negative;
public:
typedef map_impl::iterator iterator;
counter(bool stay_non_negative = true) : m_stay_non_negative(stay_non_negative) {}
void reset() { m_data.reset(); }
iterator begin() const { return m_data.begin(); }
iterator end() const { return m_data.end(); }
void update(unsigned el, int delta);
int & get(unsigned el);
/**
\brief Increase values of elements in \c els by \c delta.
The function returns a reference to \c *this to allow for expressions like
counter().count(sz, arr).get_positive_count()
*/
counter & count(unsigned sz, const unsigned * els, int delta = 1);
counter & count(const unsigned_vector & els, int delta = 1) {
return count(els.size(), els.c_ptr(), delta);
}
void collect_positive(uint_set & acc) const;
unsigned get_positive_count() const;
bool get_max_positive(unsigned & res) const;
unsigned get_max_positive() const;
/**
Since the default counter value of a counter is zero, the result is never negative.
*/
int get_max_counter_value() const;
};
class var_counter : public counter {
protected:
ptr_vector<sort> m_sorts;
expr_fast_mark1 m_visited;
ptr_vector<expr> m_todo;
ast_mark m_mark;
unsigned_vector m_scopes;
unsigned get_max_var(bool & has_var);
public:
var_counter(bool stay_non_negative = true): counter(stay_non_negative) {}
void count_vars(ast_manager & m, const app * t, int coef = 1);
unsigned get_max_var(expr* e);
unsigned get_next_var(expr* e);
};
class ast_counter {
typedef obj_map<ast, int> map_impl;
map_impl m_data;
bool m_stay_non_negative;
public:
typedef map_impl::iterator iterator;
ast_counter(bool stay_non_negative = true) : m_stay_non_negative(stay_non_negative) {}
iterator begin() const { return m_data.begin(); }
iterator end() const { return m_data.end(); }
int & get(ast * el) {
return m_data.insert_if_not_there2(el, 0)->get_data().m_value;
}
void update(ast * el, int delta){
get(el) += delta;
SASSERT(!m_stay_non_negative || get(el) >= 0);
}
void inc(ast * el) { update(el, 1); }
void dec(ast * el) { update(el, -1); }
};
#endif

View file

@ -64,6 +64,7 @@ void bv_rewriter::updt_local_params(params_ref const & _p) {
m_split_concat_eq = p.split_concat_eq();
m_udiv2mul = p.udiv2mul();
m_bvnot2arith = p.bvnot2arith();
m_bv_sort_ac = p.bv_sort_ac();
m_mkbv2num = _p.get_bool("mkbv2num", false);
}
@ -1315,7 +1316,7 @@ br_status bv_rewriter::mk_bv_or(unsigned num, expr * const * args, expr_ref & re
return BR_REWRITE2;
}
if (!flattened && !merged && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero()))) {
if (!flattened && !merged && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero())) && (!m_bv_sort_ac || is_sorted(num, args))) {
return BR_FAILED;
}
@ -1331,6 +1332,8 @@ br_status bv_rewriter::mk_bv_or(unsigned num, expr * const * args, expr_ref & re
result = new_args[0];
return BR_DONE;
default:
if (m_bv_sort_ac)
std::sort(new_args.begin(), new_args.end(), ast_to_lt());
result = m_util.mk_bv_or(new_args.size(), new_args.c_ptr());
return BR_DONE;
}
@ -1456,7 +1459,8 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r
return BR_REWRITE3;
}
if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (rational::power_of_two(sz) - numeral(1)))))
if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (rational::power_of_two(sz) - numeral(1)))) &&
(!m_bv_sort_ac || is_sorted(num, args)))
return BR_FAILED;
ptr_buffer<expr> new_args;
@ -1497,6 +1501,8 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r
}
__fallthrough;
default:
if (m_bv_sort_ac)
std::sort(new_args.begin(), new_args.end(), ast_to_lt());
result = m_util.mk_bv_xor(new_args.size(), new_args.c_ptr());
return BR_DONE;
}

View file

@ -68,6 +68,7 @@ class bv_rewriter : public poly_rewriter<bv_rewriter_core> {
bool m_split_concat_eq;
bool m_udiv2mul;
bool m_bvnot2arith;
bool m_bv_sort_ac;
bool is_zero_bit(expr * x, unsigned idx);

View file

@ -8,5 +8,6 @@ def_module_params(module_name='rewriter',
("elim_sign_ext", BOOL, True, "expand sign-ext operator using concat and extract"),
("hi_div0", BOOL, True, "use the 'hardware interpretation' for division by zero (for bit-vector terms)"),
("mul2concat", BOOL, False, "replace multiplication by a power of two into a concatenation"),
("bvnot2arith", BOOL, False, "replace (bvnot x) with (bvsub -1 x)")
("bvnot2arith", BOOL, False, "replace (bvnot x) with (bvsub -1 x)"),
("bv_sort_ac", BOOL, False, "sort the arguments of all AC operators")
))

View file

@ -0,0 +1,115 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
expr_safe_replace.cpp
Abstract:
Version of expr_replace/expr_substitution that is safe for quantifiers.
Author:
Nikolaj Bjorner (nbjorner) 2012-11-30
Revision History:
--*/
#include "expr_safe_replace.h"
#include "rewriter.h"
void expr_safe_replace::insert(expr* src, expr* dst) {
m_src.push_back(src);
m_dst.push_back(dst);
m_subst.insert(src, dst);
}
void expr_safe_replace::operator()(expr* e, expr_ref& res) {
obj_map<expr,expr*> cache;
ptr_vector<expr> todo, args;
expr_ref_vector refs(m);
todo.push_back(e);
expr* a, *b, *d;
todo.push_back(e);
while (!todo.empty()) {
a = todo.back();
if (cache.contains(a)) {
todo.pop_back();
}
else if (m_subst.find(a, b)) {
cache.insert(a, b);
todo.pop_back();
}
else if (is_var(a)) {
cache.insert(a, a);
todo.pop_back();
}
else if (is_app(a)) {
app* c = to_app(a);
unsigned n = c->get_num_args();
args.reset();
for (unsigned i = 0; i < n; ++i) {
if (cache.find(c->get_arg(i), d)) {
args.push_back(d);
}
else {
todo.push_back(c->get_arg(i));
}
}
if (args.size() == n) {
b = m.mk_app(c->get_decl(), args.size(), args.c_ptr());
refs.push_back(b);
cache.insert(a, b);
todo.pop_back();
}
}
else {
SASSERT(is_quantifier(a));
quantifier* q = to_quantifier(a);
expr_safe_replace replace(m);
var_shifter shift(m);
expr_ref new_body(m), src(m), dst(m), tmp(m);
expr_ref_vector pats(m), nopats(m);
unsigned num_decls = q->get_num_decls();
for (unsigned i = 0; i < m_src.size(); ++i) {
shift(m_src[i].get(), num_decls, src);
shift(m_dst[i].get(), num_decls, dst);
replace.insert(src, dst);
}
unsigned np = q->get_num_patterns();
for (unsigned i = 0; i < np; ++i) {
replace(q->get_pattern(i), tmp);
pats.push_back(tmp);
}
np = q->get_num_no_patterns();
for (unsigned i = 0; i < np; ++i) {
replace(q->get_no_pattern(i), tmp);
nopats.push_back(tmp);
}
replace(q->get_expr(), new_body);
b = m.update_quantifier(q, pats.size(), pats.c_ptr(), nopats.size(), nopats.c_ptr(), new_body);
refs.push_back(b);
cache.insert(a, b);
todo.pop_back();
}
}
res = cache.find(e);
}
void expr_safe_replace::reset() {
m_src.reset();
m_dst.reset();
m_subst.reset();
}
void expr_safe_replace::apply_substitution(expr* s, expr* def, expr_ref& t) {
reset();
insert(s, def);
(*this)(t, t);
reset();
}

View file

@ -0,0 +1,47 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
expr_safe_replace.h
Abstract:
Version of expr_replace/expr_substitution that is safe for quantifiers.
Author:
Nikolaj Bjorner (nbjorner) 2012-11-30
Revision History:
--*/
#ifndef __EXPR_SAFE_REPLACE_H__
#define __EXPR_SAFE_REPLACE_H__
#include "ast.h"
class expr_safe_replace {
ast_manager& m;
expr_ref_vector m_src;
expr_ref_vector m_dst;
obj_map<expr, expr*> m_subst;
public:
expr_safe_replace(ast_manager& m): m(m), m_src(m), m_dst(m) {}
void insert(expr* src, expr* dst);
void operator()(expr_ref& e) { (*this)(e.get(), e); }
void operator()(expr* src, expr_ref& e);
void apply_substitution(expr* s, expr* def, expr_ref& t);
void reset();
};
#endif /* __EXPR_SAFE_REPLACE_H__ */

View file

@ -58,6 +58,10 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
case OP_FLOAT_IS_ZERO: SASSERT(num_args == 1); st = mk_is_zero(args[0], result); break;
case OP_FLOAT_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break;
case OP_FLOAT_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break;
case OP_FLOAT_IS_NAN: SASSERT(num_args == 1); st = mk_is_nan(args[0], result); break;
case OP_FLOAT_IS_INF: SASSERT(num_args == 1); st = mk_is_inf(args[0], result); break;
case OP_FLOAT_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break;
case OP_FLOAT_IS_SUBNORMAL: SASSERT(num_args == 1); st = mk_is_subnormal(args[0], result); break;
case OP_FLOAT_IS_SIGN_MINUS: SASSERT(num_args == 1); st = mk_is_sign_minus(args[0], result); break;
case OP_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break;
}
@ -77,14 +81,27 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
return BR_FAILED;
rational q;
if (!m_util.au().is_numeral(args[1], q))
mpf q_mpf;
if (m_util.au().is_numeral(args[1], q)) {
TRACE("fp_rewriter", tout << "q: " << q << std::endl; );
mpf v;
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
result = m_util.mk_value(v);
m_util.fm().del(v);
// TRACE("fp_rewriter", tout << "result: " << result << std::endl; );
return BR_DONE;
}
else if (m_util.is_value(args[1], q_mpf)) {
TRACE("fp_rewriter", tout << "q: " << m_util.fm().to_string(q_mpf) << std::endl; );
mpf v;
m_util.fm().set(v, ebits, sbits, rm, q_mpf);
result = m_util.mk_value(v);
m_util.fm().del(v);
// TRACE("fp_rewriter", tout << "result: " << result << std::endl; );
return BR_DONE;
}
else
return BR_FAILED;
mpf v;
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
result = m_util.mk_value(v);
m_util.fm().del(v);
return BR_DONE;
}
else if (num_args == 3 &&
m_util.is_rm(m().get_sort(args[0])) &&
@ -104,11 +121,11 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
return BR_FAILED;
TRACE("fp_rewriter", tout << "q: " << q << ", e: " << e << "\n";);
mpf v;
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator());
result = m_util.mk_value(v);
m_util.fm().del(v);
m_util.fm().del(v);
// TRACE("fp_rewriter", tout << "result: " << result << std::endl; );
return BR_DONE;
}
else {
@ -217,8 +234,7 @@ br_status float_rewriter::mk_abs(expr * arg1, expr_ref & result) {
result = arg1;
return BR_DONE;
}
sort * s = m().get_sort(arg1);
result = m().mk_ite(m_util.mk_lt(arg1, m_util.mk_pzero(s)),
result = m().mk_ite(m_util.mk_is_sign_minus(arg1),
m_util.mk_uminus(arg1),
arg1);
return BR_REWRITE2;
@ -234,13 +250,13 @@ br_status float_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) {
return BR_DONE;
}
// expand as using ite's
result = m().mk_ite(mk_eq_nan(arg1),
result = m().mk_ite(m().mk_or(mk_eq_nan(arg1), m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2))),
arg2,
m().mk_ite(mk_eq_nan(arg2),
arg1,
m().mk_ite(m_util.mk_lt(arg1, arg2),
arg1,
arg2)));
arg1,
arg2)));
return BR_REWRITE_FULL;
}
@ -254,7 +270,7 @@ br_status float_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
return BR_DONE;
}
// expand as using ite's
result = m().mk_ite(mk_eq_nan(arg1),
result = m().mk_ite(m().mk_or(mk_eq_nan(arg1), m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2))),
arg2,
m().mk_ite(mk_eq_nan(arg2),
arg1,
@ -420,6 +436,46 @@ br_status float_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) {
return BR_FAILED;
}
br_status float_rewriter::mk_is_nan(expr * arg1, expr_ref & result) {
scoped_mpf v(m_util.fm());
if (m_util.is_value(arg1, v)) {
result = (m_util.fm().is_nan(v)) ? m().mk_true() : m().mk_false();
return BR_DONE;
}
return BR_FAILED;
}
br_status float_rewriter::mk_is_inf(expr * arg1, expr_ref & result) {
scoped_mpf v(m_util.fm());
if (m_util.is_value(arg1, v)) {
result = (m_util.fm().is_inf(v)) ? m().mk_true() : m().mk_false();
return BR_DONE;
}
return BR_FAILED;
}
br_status float_rewriter::mk_is_normal(expr * arg1, expr_ref & result) {
scoped_mpf v(m_util.fm());
if (m_util.is_value(arg1, v)) {
result = (m_util.fm().is_normal(v)) ? m().mk_true() : m().mk_false();
return BR_DONE;
}
return BR_FAILED;
}
br_status float_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) {
scoped_mpf v(m_util.fm());
if (m_util.is_value(arg1, v)) {
result = (m_util.fm().is_denormal(v)) ? m().mk_true() : m().mk_false();
return BR_DONE;
}
return BR_FAILED;
}
br_status float_rewriter::mk_is_sign_minus(expr * arg1, expr_ref & result) {
scoped_mpf v(m_util.fm());
if (m_util.is_value(arg1, v)) {

View file

@ -66,6 +66,10 @@ public:
br_status mk_is_zero(expr * arg1, expr_ref & result);
br_status mk_is_nzero(expr * arg1, expr_ref & result);
br_status mk_is_pzero(expr * arg1, expr_ref & result);
br_status mk_is_nan(expr * arg1, expr_ref & result);
br_status mk_is_inf(expr * arg1, expr_ref & result);
br_status mk_is_normal(expr * arg1, expr_ref & result);
br_status mk_is_subnormal(expr * arg1, expr_ref & result);
br_status mk_is_sign_minus(expr * arg1, expr_ref & result);
br_status mk_to_ieee_bv(expr * arg1, expr_ref & result);

View file

@ -62,6 +62,8 @@ struct mk_simplified_app::imp {
st = m_dt_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_f_rw.get_fid())
st = m_f_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_ar_rw.get_fid())
st = m_ar_rw.mk_eq_core(args[0], args[1], result);
if (st != BR_FAILED)
return st;

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,8 @@ Revision History:
#include "bool_rewriter.h"
#include "var_subst.h"
#include "ast_pp.h"
#include "ast_counter.h"
#include "expr_safe_replace.h"
//
// Bring quantifiers of common type into prenex form.
@ -42,7 +43,7 @@ public:
void operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result) {
quantifier_type qt = Q_none_pos;
pull_quantifiers(fml, qt, vars, result);
pull_quantifier(fml, qt, vars, result);
TRACE("qe_verbose",
tout << mk_pp(fml, m) << "\n";
tout << mk_pp(result, m) << "\n";);
@ -52,7 +53,7 @@ public:
void pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result) {
quantifier_type qt = Q_exists_pos;
pull_quantifiers(fml, qt, vars, result);
pull_quantifier(fml, qt, vars, result);
TRACE("qe_verbose",
tout << mk_pp(fml, m) << "\n";
tout << mk_pp(result, m) << "\n";);
@ -61,7 +62,7 @@ public:
void pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars) {
quantifier_type qt = is_forall?Q_forall_pos:Q_exists_pos;
expr_ref result(m);
pull_quantifiers(fml, qt, vars, result);
pull_quantifier(fml, qt, vars, result);
TRACE("qe_verbose",
tout << mk_pp(fml, m) << "\n";
tout << mk_pp(result, m) << "\n";);
@ -78,7 +79,57 @@ public:
expr * const * exprs = (expr* const*) (vars.c_ptr() + vars.size()- nd);
instantiate(m, q, exprs, result);
}
unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector<sort>* sorts, svector<symbol>* names) {
unsigned index = var_counter().get_next_var(fml);
while (is_quantifier(fml) && (is_forall == to_quantifier(fml)->is_forall())) {
quantifier* q = to_quantifier(fml);
index += q->get_num_decls();
if (names) {
names->append(q->get_num_decls(), q->get_decl_names());
}
if (sorts) {
sorts->append(q->get_num_decls(), q->get_decl_sorts());
}
fml = q->get_expr();
}
if (!has_quantifiers(fml)) {
return index;
}
app_ref_vector vars(m);
pull_quantifier(is_forall, fml, vars);
if (vars.empty()) {
return index;
}
// replace vars by de-bruijn indices
expr_safe_replace rep(m);
svector<symbol> bound_names;
ptr_vector<sort> bound_sorts;
for (unsigned i = 0; i < vars.size(); ++i) {
app* v = vars[i].get();
if (names) {
bound_names.push_back(v->get_decl()->get_name());
}
if (sorts) {
bound_sorts.push_back(m.get_sort(v));
}
rep.insert(v, m.mk_var(index++, m.get_sort(v)));
}
if (names && !bound_names.empty()) {
bound_names.reverse();
bound_names.append(*names);
names->reset();
names->append(bound_names);
}
if (sorts && !bound_sorts.empty()) {
bound_sorts.reverse();
bound_sorts.append(*sorts);
sorts->reset();
sorts->append(bound_sorts);
}
rep(fml);
return index;
}
private:
@ -143,7 +194,7 @@ private:
}
void pull_quantifiers(expr* fml, quantifier_type& qt, app_ref_vector& vars, expr_ref& result) {
void pull_quantifier(expr* fml, quantifier_type& qt, app_ref_vector& vars, expr_ref& result) {
if (!has_quantifiers(fml)) {
result = fml;
@ -159,7 +210,7 @@ private:
if (m.is_and(fml)) {
num_args = a->get_num_args();
for (unsigned i = 0; i < num_args; ++i) {
pull_quantifiers(a->get_arg(i), qt, vars, tmp);
pull_quantifier(a->get_arg(i), qt, vars, tmp);
args.push_back(tmp);
}
m_rewriter.mk_and(args.size(), args.c_ptr(), result);
@ -167,25 +218,25 @@ private:
else if (m.is_or(fml)) {
num_args = to_app(fml)->get_num_args();
for (unsigned i = 0; i < num_args; ++i) {
pull_quantifiers(to_app(fml)->get_arg(i), qt, vars, tmp);
pull_quantifier(to_app(fml)->get_arg(i), qt, vars, tmp);
args.push_back(tmp);
}
m_rewriter.mk_or(args.size(), args.c_ptr(), result);
}
else if (m.is_not(fml)) {
pull_quantifiers(to_app(fml)->get_arg(0), negate(qt), vars, tmp);
pull_quantifier(to_app(fml)->get_arg(0), negate(qt), vars, tmp);
negate(qt);
result = m.mk_not(tmp);
}
else if (m.is_implies(fml)) {
pull_quantifiers(to_app(fml)->get_arg(0), negate(qt), vars, tmp);
pull_quantifier(to_app(fml)->get_arg(0), negate(qt), vars, tmp);
negate(qt);
pull_quantifiers(to_app(fml)->get_arg(1), qt, vars, result);
pull_quantifier(to_app(fml)->get_arg(1), qt, vars, result);
result = m.mk_implies(tmp, result);
}
else if (m.is_ite(fml)) {
pull_quantifiers(to_app(fml)->get_arg(1), qt, vars, tmp);
pull_quantifiers(to_app(fml)->get_arg(2), qt, vars, result);
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 {
@ -203,7 +254,7 @@ private:
}
set_quantifier_type(qt, q->is_forall());
extract_quantifier(q, vars, tmp);
pull_quantifiers(tmp, qt, vars, result);
pull_quantifier(tmp, qt, vars, result);
break;
}
case AST_VAR:
@ -215,6 +266,7 @@ private:
break;
}
}
};
quantifier_hoister::quantifier_hoister(ast_manager& m) {
@ -237,3 +289,6 @@ void quantifier_hoister::pull_quantifier(bool is_forall, expr_ref& fml, app_ref_
m_impl->pull_quantifier(is_forall, fml, vars);
}
unsigned quantifier_hoister::pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector<sort>* sorts, svector<symbol>* names) {
return m_impl->pull_quantifier(is_forall, fml, sorts, names);
}

View file

@ -59,6 +59,15 @@ public:
The list of variables is empty if there are no top-level universal/existential quantifier.
*/
void pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars);
/**
\brief Pull top-most universal (is_forall true) or existential (is_forall=false) quantifier up.
Return an expression with de-Bruijn indices and the list of names that were used.
Return index of maximal variable.
*/
unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector<sort>* sorts, svector<symbol>* names);
};
#endif

View file

@ -169,7 +169,9 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
st = m_dt_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_f_rw.get_fid())
st = m_f_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_ar_rw.get_fid())
st = m_ar_rw.mk_eq_core(args[0], args[1], result);
if (st != BR_FAILED)
return st;
}

View file

@ -17,7 +17,6 @@ Notes:
--*/
#include"var_subst.h"
#include"used_vars.h"
#include"ast_ll_pp.h"
#include"ast_pp.h"
#include"ast_smt2_pp.h"
@ -40,7 +39,7 @@ void var_subst::operator()(expr * n, unsigned num_args, expr * const * args, exp
tout << mk_ismt2_pp(result, m_reducer.m()) << "\n";);
}
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
SASSERT(is_well_sorted(m, q));
if (is_ground(q->get_expr())) {
// ignore patterns if the body is a ground formula.
@ -51,17 +50,17 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
result = q;
return;
}
used_vars used;
used.process(q->get_expr());
m_used.reset();
m_used.process(q->get_expr());
unsigned num_patterns = q->get_num_patterns();
for (unsigned i = 0; i < num_patterns; i++)
used.process(q->get_pattern(i));
m_used.process(q->get_pattern(i));
unsigned num_no_patterns = q->get_num_no_patterns();
for (unsigned i = 0; i < num_no_patterns; i++)
used.process(q->get_no_pattern(i));
m_used.process(q->get_no_pattern(i));
unsigned num_decls = q->get_num_decls();
if (used.uses_all_vars(num_decls)) {
if (m_used.uses_all_vars(num_decls)) {
q->set_no_unused_vars();
result = q;
return;
@ -70,7 +69,7 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
ptr_buffer<sort> used_decl_sorts;
buffer<symbol> used_decl_names;
for (unsigned i = 0; i < num_decls; ++i) {
if (used.contains(num_decls - i - 1)) {
if (m_used.contains(num_decls - i - 1)) {
used_decl_sorts.push_back(q->get_decl_sort(i));
used_decl_names.push_back(q->get_decl_name(i));
}
@ -79,10 +78,10 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
unsigned num_removed = 0;
expr_ref_buffer var_mapping(m);
int next_idx = 0;
unsigned sz = used.get_max_found_var_idx_plus_1();
unsigned sz = m_used.get_max_found_var_idx_plus_1();
for (unsigned i = 0; i < num_decls; ++i) {
sort * s = used.contains(i);
sort * s = m_used.contains(i);
if (s) {
var_mapping.push_back(m.mk_var(next_idx, s));
next_idx++;
@ -95,7 +94,7 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
// (VAR 0) is in the first position of var_mapping.
for (unsigned i = num_decls; i < sz; i++) {
sort * s = used.contains(i);
sort * s = m_used.contains(i);
if (s)
var_mapping.push_back(m.mk_var(i - num_removed, s));
else
@ -110,9 +109,8 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
std::reverse(var_mapping.c_ptr(), var_mapping.c_ptr() + var_mapping.size());
expr_ref new_expr(m);
var_subst subst(m);
subst(q->get_expr(), var_mapping.size(), var_mapping.c_ptr(), new_expr);
m_subst(q->get_expr(), var_mapping.size(), var_mapping.c_ptr(), new_expr);
if (num_removed == num_decls) {
result = new_expr;
@ -124,11 +122,11 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
expr_ref_buffer new_no_patterns(m);
for (unsigned i = 0; i < num_patterns; i++) {
subst(q->get_pattern(i), var_mapping.size(), var_mapping.c_ptr(), tmp);
m_subst(q->get_pattern(i), var_mapping.size(), var_mapping.c_ptr(), tmp);
new_patterns.push_back(tmp);
}
for (unsigned i = 0; i < num_no_patterns; i++) {
subst(q->get_no_pattern(i), var_mapping.size(), var_mapping.c_ptr(), tmp);
m_subst(q->get_no_pattern(i), var_mapping.size(), var_mapping.c_ptr(), tmp);
new_no_patterns.push_back(tmp);
}
@ -145,7 +143,12 @@ void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
num_no_patterns,
new_no_patterns.c_ptr());
to_quantifier(result)->set_no_unused_vars();
SASSERT(is_well_sorted(m, result));
SASSERT(is_well_sorted(m, result));
}
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
unused_vars_eliminator el(m);
el(q, result);
}
void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref & result) {
@ -161,9 +164,7 @@ void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref
tout << "\n----->\n" << mk_ismt2_pp(result, m) << "\n";);
}
static void get_free_vars_offset(expr* e, unsigned offset, ptr_vector<sort>& sorts) {
ast_mark mark;
ptr_vector<expr> todo;
static void get_free_vars_offset(ast_mark& mark, ptr_vector<expr>& todo, unsigned offset, expr* e, ptr_vector<sort>& sorts) {
todo.push_back(e);
while (!todo.empty()) {
e = todo.back();
@ -175,7 +176,9 @@ static void get_free_vars_offset(expr* e, unsigned offset, ptr_vector<sort>& sor
switch(e->get_kind()) {
case AST_QUANTIFIER: {
quantifier* q = to_quantifier(e);
get_free_vars_offset(q->get_expr(), offset+q->get_num_decls(), sorts);
ast_mark mark1;
ptr_vector<expr> todo1;
get_free_vars_offset(mark1, todo1, offset+q->get_num_decls(), q->get_expr(), sorts);
break;
}
case AST_VAR: {
@ -207,5 +210,11 @@ static void get_free_vars_offset(expr* e, unsigned offset, ptr_vector<sort>& sor
void get_free_vars(expr* e, ptr_vector<sort>& sorts) {
get_free_vars_offset(e, 0, sorts);
ast_mark mark;
ptr_vector<expr> todo;
get_free_vars_offset(mark, todo, 0, e, sorts);
}
void get_free_vars(ast_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts) {
get_free_vars_offset(mark, todo, 0, e, sorts);
}

View file

@ -20,6 +20,7 @@ Notes:
#define _VAR_SUBST_H_
#include"rewriter.h"
#include"used_vars.h"
/**
\brief Alias for var_shifter class.
@ -53,6 +54,15 @@ public:
/**
\brief Eliminate the unused variables from \c q. Store the result in \c r.
*/
class unused_vars_eliminator {
ast_manager& m;
var_subst m_subst;
used_vars m_used;
public:
unused_vars_eliminator(ast_manager& m): m(m), m_subst(m) {}
void operator()(quantifier* q, expr_ref& r);
};
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & r);
/**
@ -73,6 +83,8 @@ void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref
*/
void get_free_vars(expr* e, ptr_vector<sort>& sorts);
void get_free_vars(ast_mark& mark, ptr_vector<expr>& todo, expr* e, ptr_vector<sort>& sorts);
#endif

55
src/ast/scoped_proof.h Normal file
View file

@ -0,0 +1,55 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
scoped_proof.h
Abstract:
Scoped proof environments. Toggles enabling proofs.
Author:
Nikolaj Bjorner (nbjorner) 2013-08-28
Revision History:
--*/
#ifndef _SCOPED_PROOF__H_
#define _SCOPED_PROOF_H_
#include "ast.h"
class scoped_proof_mode {
ast_manager& m;
proof_gen_mode m_mode;
public:
scoped_proof_mode(ast_manager& m, proof_gen_mode mode): m(m) {
m_mode = m.proof_mode();
m.toggle_proof_mode(mode);
}
~scoped_proof_mode() {
m.toggle_proof_mode(m_mode);
}
};
class scoped_proof : public scoped_proof_mode {
public:
scoped_proof(ast_manager& m): scoped_proof_mode(m, PGM_FINE) {}
};
class scoped_no_proof : public scoped_proof_mode {
public:
scoped_no_proof(ast_manager& m): scoped_proof_mode(m, PGM_DISABLED) {}
};
class scoped_restore_proof : public scoped_proof_mode {
public:
scoped_restore_proof(ast_manager& m): scoped_proof_mode(m, m.proof_mode()) {}
};
#endif

View file

@ -179,7 +179,7 @@ bool bv_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const
}
SASSERT(result.get());
TRACE("bv_simplifier",
TRACE("bv_simplifier",
tout << mk_pp(f, m_manager) << "\n";
for (unsigned i = 0; i < num_args; ++i) {
tout << mk_pp(args[i], m_manager) << " ";
@ -636,7 +636,31 @@ bool bv_simplifier_plugin::try_mk_extract(unsigned high, unsigned low, expr * ar
if (!all_found) {
return false;
}
result = m_manager.mk_app(m_fid, a->get_decl_kind(), new_args.size(), new_args.c_ptr());
// We should not use mk_app because it does not guarantee that the result would be in simplified form.
// result = m_manager.mk_app(m_fid, a->get_decl_kind(), new_args.size(), new_args.c_ptr());
if (is_app_of(a, m_fid, OP_BAND))
mk_bv_and(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BOR))
mk_bv_or(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BXOR))
mk_bv_xor(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BNOR))
mk_bv_nor(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BNAND))
mk_bv_nand(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BNOT)) {
SASSERT(new_args.size() == 1);
mk_bv_not(new_args[0], result);
}
else if (is_app_of(a, m_fid, OP_BADD))
mk_add(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BMUL))
mk_mul(new_args.size(), new_args.c_ptr(), result);
else if (is_app_of(a, m_fid, OP_BSUB))
mk_sub(new_args.size(), new_args.c_ptr(), result);
else {
UNREACHABLE();
}
return true;
}
else if (m_manager.is_ite(a)) {
@ -747,16 +771,16 @@ void bv_simplifier_plugin::mk_bv_eq(expr* a1, expr* a2, expr_ref& result) {
expr * arg1 = *it1;
expr * arg2 = *it2;
TRACE("expr_bv_util", tout << "low1: " << low1 << " low2: " << low2 << "\n";
ast_ll_pp(tout, m_manager, arg1);
ast_ll_pp(tout, m_manager, arg2););
tout << mk_pp(arg1, m_manager) << "\n";
tout << mk_pp(arg2, m_manager) << "\n";);
unsigned sz1 = get_bv_size(arg1);
unsigned sz2 = get_bv_size(arg2);
SASSERT(low1 < sz1 && low2 < sz2);
unsigned rsz1 = sz1 - low1;
unsigned rsz2 = sz2 - low2;
TRACE("expr_bv_util", tout << "rsz1: " << rsz1 << " rsz2: " << rsz2 << "\n";
ast_ll_pp(tout, m_manager, arg1); ast_ll_pp(tout, m_manager, arg2););
tout << mk_pp(arg1, m_manager) << "\n";
tout << mk_pp(arg2, m_manager) << "\n";);
if (rsz1 == rsz2) {
mk_extract(sz1 - 1, low1, arg1, lhs);
@ -826,9 +850,9 @@ void bv_simplifier_plugin::mk_eq_core(expr * arg1, expr * arg2, expr_ref & resul
}
m_bsimp.mk_and(tmps.size(), tmps.c_ptr(), result);
TRACE("mk_eq_bb",
ast_ll_pp(tout, m_manager, arg1);
ast_ll_pp(tout, m_manager, arg2);
ast_ll_pp(tout, m_manager, result););
tout << mk_pp(arg1, m_manager) << "\n";
tout << mk_pp(arg2, m_manager) << "\n";
tout << mk_pp(result, m_manager) << "\n";);
return;
}
#endif

View file

@ -18,6 +18,7 @@ Author:
#include"ast_pp.h"
#include"ast_util.h"
#include"ast_smt2_pp.h"
#include"ast_ll_pp.h"
poly_simplifier_plugin::poly_simplifier_plugin(symbol const & fname, ast_manager & m, decl_kind add, decl_kind mul, decl_kind uminus, decl_kind sub,
decl_kind num):
@ -173,7 +174,7 @@ void poly_simplifier_plugin::mk_monomial(unsigned num_args, expr * * args, expr_
result = args[0];
break;
default:
std::sort(args, args + num_args, monomial_element_lt_proc(*this));
std::stable_sort(args, args + num_args, monomial_element_lt_proc(*this));
result = mk_mul(num_args, args);
SASSERT(wf_monomial(result));
break;
@ -284,6 +285,7 @@ bool poly_simplifier_plugin::merge_monomials(bool inv, expr * n1, expr * n2, exp
else
result = m_manager.mk_app(m_fid, m_MUL, mk_numeral(k1), b);
}
TRACE("merge_monomials", tout << mk_pp(n1, m_manager) << "\n" << mk_pp(n2, m_manager) << "\n" << mk_pp(result, m_manager) << "\n";);
return true;
}
@ -465,7 +467,9 @@ void poly_simplifier_plugin::mk_sum_of_monomials(expr_ref_vector & monomials, ex
result = monomials.get(0);
break;
default: {
std::sort(monomials.c_ptr(), monomials.c_ptr() + monomials.size(), monomial_lt_proc(*this));
TRACE("mk_sum_sort", tout << "before\n"; for (unsigned i = 0; i < monomials.size(); i++) tout << mk_ll_pp(monomials.get(i), m_manager) << "\n";);
std::stable_sort(monomials.c_ptr(), monomials.c_ptr() + monomials.size(), monomial_lt_proc(*this));
TRACE("mk_sum_sort", tout << "after\n"; for (unsigned i = 0; i < monomials.size(); i++) tout << mk_ll_pp(monomials.get(i), m_manager) << "\n";);
if (is_simple_sum_of_monomials(monomials)) {
mk_sum_of_monomials_core(monomials.size(), monomials.c_ptr(), result);
return;

View file

@ -18,10 +18,6 @@ Revision History:
--*/
#include"matcher.h"
matcher::matcher(ast_manager & m):
m_manager(m) {
}
bool matcher::operator()(expr * e1, expr * e2, substitution & s) {
reset();
m_subst = &s;

View file

@ -30,7 +30,6 @@ class matcher {
typedef pair_hash<obj_ptr_hash<expr>, obj_ptr_hash<expr> > expr_pair_hash;
typedef hashtable<expr_pair, expr_pair_hash, default_eq<expr_pair> > cache;
ast_manager & m_manager;
substitution * m_subst;
// cache m_cache;
svector<expr_pair> m_todo;
@ -38,7 +37,7 @@ class matcher {
void reset();
public:
matcher(ast_manager & m);
matcher() {}
/**
\brief Return true if e2 is an instance of e1.

View file

@ -148,7 +148,7 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e
expr * arg = to_app(e)->get_arg(i);
expr * new_arg;
m_apply_cache.find(expr_offset(arg, off), new_arg);
VERIFY(m_apply_cache.find(expr_offset(arg, off), new_arg));
new_args.push_back(new_arg);
if (arg != new_arg)
has_new_args = true;