3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-24 03:57:51 +00:00

Merge branch 'unstable' of https://git01.codeplex.com/z3 into unstable

This commit is contained in:
Christoph M. Wintersteiger 2013-05-01 14:11:21 +01:00
commit 7053b7636b
90 changed files with 4876 additions and 907 deletions

View file

@ -93,7 +93,9 @@ 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();
::get_free_vars(pred->get_arg(i), m_sorts);
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);
@ -108,24 +110,27 @@ unsigned var_counter::get_max_var(bool& has_var) {
unsigned max_var = 0;
while (!m_todo.empty()) {
expr* e = m_todo.back();
unsigned scope = m_scopes.back();
m_todo.pop_back();
m_scopes.pop_back();
if (m_visited.is_marked(e)) {
continue;
}
m_visited.mark(e, true);
switch(e->get_kind()) {
case AST_QUANTIFIER: {
var_counter aux_counter;
quantifier* q = to_quantifier(e);
m_todo.push_back(q->get_expr());
m_scopes.push_back(scope + q->get_num_decls());
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 = true;
}
break;
}
case AST_VAR: {
if (to_var(e)->get_idx() >= scope + max_var) {
if (to_var(e)->get_idx() >= max_var) {
has_var = true;
max_var = to_var(e)->get_idx() - scope;
max_var = to_var(e)->get_idx();
}
break;
}
@ -133,7 +138,6 @@ unsigned var_counter::get_max_var(bool& has_var) {
app* a = to_app(e);
for (unsigned i = 0; i < a->get_num_args(); ++i) {
m_todo.push_back(a->get_arg(i));
m_scopes.push_back(scope);
}
break;
}
@ -150,14 +154,12 @@ unsigned var_counter::get_max_var(bool& has_var) {
unsigned var_counter::get_max_var(expr* e) {
bool has_var = false;
m_todo.push_back(e);
m_scopes.push_back(0);
return get_max_var(has_var);
}
unsigned var_counter::get_next_var(expr* e) {
bool has_var = false;
m_todo.push_back(e);
m_scopes.push_back(0);
unsigned mv = get_max_var(has_var);
if (has_var) mv++;
return mv;

View file

@ -38,6 +38,7 @@ public:
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);
@ -71,6 +72,7 @@ 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:

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