3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

Merge remote-tracking branch 'upstream/master' into refactoring

This commit is contained in:
Murphy Berzish 2018-03-19 01:43:18 -04:00
commit d569485170
22 changed files with 192 additions and 190 deletions

View file

@ -19,7 +19,7 @@ Revision History:
#include "smt/smt_context.h"
#include "ast/ast_ll_pp.h"
#include "ast/ast_pp.h"
#include "ast/ast_smt_pp.h"
#include "ast/ast_pp_util.h"
#include "util/stats.h"
namespace smt {
@ -43,11 +43,10 @@ namespace smt {
return out << "RESOURCE_LIMIT";
case THEORY:
if (!m_incomplete_theories.empty()) {
ptr_vector<theory>::const_iterator it = m_incomplete_theories.begin();
ptr_vector<theory>::const_iterator end = m_incomplete_theories.end();
for (bool first = true; it != end; ++it) {
bool first = true;
for (theory* th : m_incomplete_theories) {
if (first) first = false; else out << " ";
out << (*it)->get_name();
out << th->get_name();
}
}
else {
@ -173,12 +172,10 @@ namespace smt {
void context::display_binary_clauses(std::ostream & out) const {
bool first = true;
vector<watch_list>::const_iterator it = m_watches.begin();
vector<watch_list>::const_iterator end = m_watches.end();
for (unsigned l_idx = 0; it != end; ++it, ++l_idx) {
literal l1 = to_literal(l_idx);
unsigned l_idx = 0;
for (watch_list const& wl : m_watches) {
literal l1 = to_literal(l_idx++);
literal neg_l1 = ~l1;
watch_list const & wl = *it;
literal const * it2 = wl.begin_literals();
literal const * end2 = wl.end_literals();
for (; it2 != end2; ++it2) {
@ -291,10 +288,7 @@ namespace smt {
}
void context::display_theories(std::ostream & out) const {
ptr_vector<theory>::const_iterator it = m_theory_set.begin();
ptr_vector<theory>::const_iterator end = m_theory_set.end();
for (; it != end; ++it) {
theory * th = *it;
for (theory* th : m_theory_set) {
th->display(out);
}
}
@ -393,10 +387,8 @@ namespace smt {
#endif
m_qmanager->collect_statistics(st);
m_asserted_formulas.collect_statistics(st);
ptr_vector<theory>::const_iterator it = m_theory_set.begin();
ptr_vector<theory>::const_iterator end = m_theory_set.end();
for (; it != end; ++it) {
(*it)->collect_statistics(st);
for (theory* th : m_theory_set) {
th->collect_statistics(st);
}
}
@ -413,19 +405,23 @@ namespace smt {
}
void context::display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents, literal consequent, symbol const& logic) const {
ast_smt_pp pp(m_manager);
pp.set_benchmark_name("lemma");
pp.set_status("unsat");
pp.set_logic(logic);
ast_pp_util visitor(m_manager);
expr_ref_vector fmls(m_manager);
visitor.collect(fmls);
expr_ref n(m_manager);
for (unsigned i = 0; i < num_antecedents; i++) {
literal l = antecedents[i];
expr_ref n(m_manager);
literal2expr(l, n);
pp.add_assumption(n);
fmls.push_back(n);
}
expr_ref n(m_manager);
literal2expr(~consequent, n);
pp.display_smt2(out, n);
if (consequent != false_literal) {
literal2expr(~consequent, n);
fmls.push_back(n);
}
if (logic != symbol::null) out << "(set-logic " << logic << ")\n";
visitor.collect(fmls);
visitor.display_decls(out);
visitor.display_asserts(out, fmls, true);
}
static unsigned g_lemma_id = 0;
@ -448,25 +444,29 @@ namespace smt {
void context::display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents,
unsigned num_eq_antecedents, enode_pair const * eq_antecedents,
literal consequent, symbol const& logic) const {
ast_smt_pp pp(m_manager);
pp.set_benchmark_name("lemma");
pp.set_status("unsat");
pp.set_logic(logic);
ast_pp_util visitor(m_manager);
expr_ref_vector fmls(m_manager);
visitor.collect(fmls);
expr_ref n(m_manager);
for (unsigned i = 0; i < num_antecedents; i++) {
literal l = antecedents[i];
expr_ref n(m_manager);
literal2expr(l, n);
pp.add_assumption(n);
fmls.push_back(n);
}
for (unsigned i = 0; i < num_eq_antecedents; i++) {
enode_pair const & p = eq_antecedents[i];
expr_ref eq(m_manager);
eq = m_manager.mk_eq(p.first->get_owner(), p.second->get_owner());
pp.add_assumption(eq);
n = m_manager.mk_eq(p.first->get_owner(), p.second->get_owner());
fmls.push_back(n);
}
expr_ref n(m_manager);
literal2expr(~consequent, n);
pp.display_smt2(out, n);
if (consequent != false_literal) {
literal2expr(~consequent, n);
fmls.push_back(n);
}
if (logic != symbol::null) out << "(set-logic " << logic << ")\n";
visitor.collect(fmls);
visitor.display_decls(out);
visitor.display_asserts(out, fmls, true);
}
void context::display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
@ -490,10 +490,7 @@ namespace smt {
*/
void context::display_normalized_enodes(std::ostream & out) const {
out << "normalized enodes:\n";
ptr_vector<enode>::const_iterator it = m_enodes.begin();
ptr_vector<enode>::const_iterator end = m_enodes.end();
for (; it != end; ++it) {
enode * n = *it;
for (enode * n : m_enodes) {
out << "#";
out.width(5);
out << std::left << n->get_owner_id() << " #";
@ -524,28 +521,23 @@ namespace smt {
}
void context::display_enodes_lbls(std::ostream & out) const {
ptr_vector<enode>::const_iterator it = m_enodes.begin();
ptr_vector<enode>::const_iterator end = m_enodes.end();
for (; it != end; ++it) {
enode * n = *it;
for (enode* n : m_enodes) {
n->display_lbls(out);
}
}
void context::display_decl2enodes(std::ostream & out) const {
out << "decl2enodes:\n";
vector<enode_vector>::const_iterator it1 = m_decl2enodes.begin();
vector<enode_vector>::const_iterator end1 = m_decl2enodes.end();
for (unsigned id = 0; it1 != end1; ++it1, ++id) {
enode_vector const & v = *it1;
unsigned id = 0;
for (enode_vector const& v : m_decl2enodes) {
if (!v.empty()) {
out << "id " << id << " ->";
enode_vector::const_iterator it2 = v.begin();
enode_vector::const_iterator end2 = v.end();
for (; it2 != end2; ++it2)
out << " #" << (*it2)->get_owner_id();
for (enode* n : v) {
out << " #" << n->get_owner_id();
}
out << "\n";
}
++id;
}
}
@ -588,20 +580,20 @@ namespace smt {
case b_justification::BIN_CLAUSE: {
literal l2 = j.get_literal();
out << "bin-clause ";
display_literal(out, l2);
display_literal_verbose(out, l2);
break;
}
case b_justification::CLAUSE: {
clause * cls = j.get_clause();
out << "clause ";
if (cls) display_literals(out, cls->get_num_literals(), cls->begin_literals());
if (cls) display_literals_verbose(out, cls->get_num_literals(), cls->begin_literals());
break;
}
case b_justification::JUSTIFICATION: {
out << "justification " << j.get_justification()->get_from_theory() << ": ";
literal_vector lits;
const_cast<conflict_resolution&>(*m_conflict_resolution).justification2literals(j.get_justification(), lits);
display_literals(out, lits);
display_literals_verbose(out, lits);
break;
}
default:

View file

@ -222,7 +222,7 @@ namespace smt {
final_check_status final_check_eh(bool full) {
if (full) {
IF_VERBOSE(100, verbose_stream() << "(smt.final-check \"quantifiers\")\n";);
IF_VERBOSE(100, if (!m_quantifiers.empty()) verbose_stream() << "(smt.final-check \"quantifiers\")\n";);
final_check_status result = m_qi_queue.final_check_eh() ? FC_DONE : FC_CONTINUE;
final_check_status presult = m_plugin->final_check_eh(full);
if (presult != FC_DONE)

View file

@ -2404,8 +2404,7 @@ bool theory_seq::add_stoi_val_axiom(expr* e) {
lits.push_back(~is_digit(ith_char));
nums.push_back(digit2int(ith_char));
}
for (unsigned i = sz-1, c = 1; i > 0; c *= 10) {
--i;
for (unsigned i = sz, c = 1; i-- > 0; c *= 10) {
coeff = m_autil.mk_int(c);
nums[i] = m_autil.mk_mul(coeff, nums[i].get());
}
@ -2414,9 +2413,10 @@ bool theory_seq::add_stoi_val_axiom(expr* e) {
lits.push_back(mk_eq(e, num, false));
++m_stats.m_add_axiom;
m_new_propagation = true;
for (unsigned i = 0; i < lits.size(); ++i) {
ctx.mark_as_relevant(lits[i]);
for (literal lit : lits) {
ctx.mark_as_relevant(lit);
}
TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";);
ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
m_stoi_axioms.insert(val);
m_trail_stack.push(insert_map<theory_seq, rational_set, rational>(m_stoi_axioms, val));

View file

@ -288,9 +288,9 @@ namespace smt {
}
}
static void cut_vars_map_copy(std::map<expr*, int> & dest, std::map<expr*, int> & src) {
for (auto entry : src) {
dest[entry.first] = 1;
static void cut_vars_map_copy(obj_map<expr, int> & dest, obj_map<expr, int> & src) {
for (auto const& kv : src) {
dest.insert(kv.m_key, 1);
}
}
@ -305,8 +305,8 @@ namespace smt {
return false;
}
for (auto entry : cut_var_map[n1].top()->vars) {
if (cut_var_map[n2].top()->vars.find(entry.first) != cut_var_map[n2].top()->vars.end()) {
for (auto const& kv : cut_var_map[n1].top()->vars) {
if (cut_var_map[n2].top()->vars.contains(kv.m_key)) {
return true;
}
}
@ -321,7 +321,7 @@ namespace smt {
T_cut * varInfo = alloc(T_cut);
m_cut_allocs.push_back(varInfo);
varInfo->level = slevel;
varInfo->vars[node] = 1;
varInfo->vars.insert(node, 1);
cut_var_map.insert(baseNode, std::stack<T_cut*>());
cut_var_map[baseNode].push(varInfo);
TRACE("str", tout << "add var info for baseNode=" << mk_pp(baseNode, get_manager()) << ", node=" << mk_pp(node, get_manager()) << " [" << slevel << "]" << std::endl;);
@ -330,7 +330,7 @@ namespace smt {
T_cut * varInfo = alloc(T_cut);
m_cut_allocs.push_back(varInfo);
varInfo->level = slevel;
varInfo->vars[node] = 1;
varInfo->vars.insert(node, 1);
cut_var_map[baseNode].push(varInfo);
TRACE("str", tout << "add var info for baseNode=" << mk_pp(baseNode, get_manager()) << ", node=" << mk_pp(node, get_manager()) << " [" << slevel << "]" << std::endl;);
} else {
@ -339,11 +339,11 @@ namespace smt {
m_cut_allocs.push_back(varInfo);
varInfo->level = slevel;
cut_vars_map_copy(varInfo->vars, cut_var_map[baseNode].top()->vars);
varInfo->vars[node] = 1;
varInfo->vars.insert(node, 1);
cut_var_map[baseNode].push(varInfo);
TRACE("str", tout << "add var info for baseNode=" << mk_pp(baseNode, get_manager()) << ", node=" << mk_pp(node, get_manager()) << " [" << slevel << "]" << std::endl;);
} else if (cut_var_map[baseNode].top()->level == slevel) {
cut_var_map[baseNode].top()->vars[node] = 1;
cut_var_map[baseNode].top()->vars.insert(node, 1);
TRACE("str", tout << "add var info for baseNode=" << mk_pp(baseNode, get_manager()) << ", node=" << mk_pp(node, get_manager()) << " [" << slevel << "]" << std::endl;);
} else {
get_manager().raise_exception("entered illegal state during add_cut_info_one_node()");
@ -441,7 +441,7 @@ namespace smt {
void theory_str::track_variable_scope(expr * var) {
if (internal_variable_scope_levels.find(sLevel) == internal_variable_scope_levels.end()) {
internal_variable_scope_levels[sLevel] = std::set<expr*>();
internal_variable_scope_levels[sLevel] = obj_hashtable<expr>();
}
internal_variable_scope_levels[sLevel].insert(var);
}
@ -2566,8 +2566,8 @@ namespace smt {
if (cut_var_map.contains(node)) {
if (!cut_var_map[node].empty()) {
xout << "[" << cut_var_map[node].top()->level << "] ";
for (auto entry : cut_var_map[node].top()->vars) {
xout << mk_pp(entry.first, m) << ", ";
for (auto const& kv : cut_var_map[node].top()->vars) {
xout << mk_pp(kv.m_key, m) << ", ";
}
xout << std::endl;
}
@ -5530,7 +5530,8 @@ namespace smt {
return node;
}
void theory_str::get_grounded_concats(expr* node, std::map<expr*, expr*> & varAliasMap,
void theory_str::get_grounded_concats(unsigned depth,
expr* node, std::map<expr*, expr*> & varAliasMap,
std::map<expr*, expr*> & concatAliasMap, std::map<expr*, expr*> & varConstMap,
std::map<expr*, expr*> & concatConstMap, std::map<expr*, std::map<expr*, int> > & varEqConcatMap,
std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap) {
@ -5545,6 +5546,9 @@ namespace smt {
if (groundedMap.find(node) != groundedMap.end()) {
return;
}
IF_VERBOSE(100, verbose_stream() << "concats " << depth << "\n";
if (depth > 100) verbose_stream() << mk_pp(node, get_manager()) << "\n";
);
// haven't computed grounded concats for "node" (de-aliased)
// ---------------------------------------------------------
@ -5572,12 +5576,10 @@ namespace smt {
// merge arg0 and arg1
expr * arg0 = to_app(node)->get_arg(0);
expr * arg1 = to_app(node)->get_arg(1);
SASSERT(arg0 != node);
SASSERT(arg1 != node);
expr * arg0DeAlias = dealias_node(arg0, varAliasMap, concatAliasMap);
expr * arg1DeAlias = dealias_node(arg1, varAliasMap, concatAliasMap);
get_grounded_concats(arg0DeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(arg1DeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(depth + 1, arg0DeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(depth + 1, arg1DeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
std::map<std::vector<expr*>, std::set<expr*> >::iterator arg0_grdItor = groundedMap[arg0DeAlias].begin();
std::map<std::vector<expr*>, std::set<expr*> >::iterator arg1_grdItor;
@ -5627,7 +5629,7 @@ namespace smt {
else if (varEqConcatMap.find(node) != varEqConcatMap.end()) {
expr * eqConcat = varEqConcatMap[node].begin()->first;
expr * deAliasedEqConcat = dealias_node(eqConcat, varAliasMap, concatAliasMap);
get_grounded_concats(deAliasedEqConcat, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(depth + 1, deAliasedEqConcat, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
std::map<std::vector<expr*>, std::set<expr*> >::iterator grdItor = groundedMap[deAliasedEqConcat].begin();
for (; grdItor != groundedMap[deAliasedEqConcat].end(); grdItor++) {
@ -5836,8 +5838,8 @@ namespace smt {
expr* strDeAlias = dealias_node(str, varAliasMap, concatAliasMap);
expr* subStrDeAlias = dealias_node(subStr, varAliasMap, concatAliasMap);
get_grounded_concats(strDeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(subStrDeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(0, strDeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
get_grounded_concats(0, subStrDeAlias, varAliasMap, concatAliasMap, varConstMap, concatConstMap, varEqConcatMap, groundedMap);
// debugging
print_grounded_concat(strDeAlias, groundedMap);
@ -6448,7 +6450,7 @@ namespace smt {
// TODO figure out regex NFA stuff
if (!regex_nfa_cache.contains(regexTerm)) {
TRACE("str", tout << "regex_nfa_cache: cache miss" << std::endl;);
regex_nfa_cache[regexTerm] = nfa(u, regexTerm);
regex_nfa_cache.insert(regexTerm, nfa(u, regexTerm));
} else {
TRACE("str", tout << "regex_nfa_cache: cache hit" << std::endl;);
}
@ -9265,7 +9267,7 @@ namespace smt {
h++;
coverAll = get_next_val_encode(options[options.size() - 1], base);
}
val_range_map[val_indicator] = options[options.size() - 1];
val_range_map.insert(val_indicator, options[options.size() - 1]);
TRACE("str",
tout << "value tester encoding " << "{" << std::endl;
@ -9359,7 +9361,7 @@ namespace smt {
TRACE("str", tout << "no previous value testers, or none of them were in scope" << std::endl;);
int tries = 0;
expr * val_indicator = mk_internal_valTest_var(freeVar, len, tries);
valueTester_fvar_map[val_indicator] = freeVar;
valueTester_fvar_map.insert(val_indicator, freeVar);
fvar_valueTester_map[freeVar][len].push_back(std::make_pair(sLevel, val_indicator));
print_value_tester_list(fvar_valueTester_map[freeVar][len]);
return gen_val_options(freeVar, len_indicator, val_indicator, len_valueStr, tries);
@ -9409,7 +9411,7 @@ namespace smt {
refresh_theory_var(valTester);
} else {
valTester = mk_internal_valTest_var(freeVar, len, i + 1);
valueTester_fvar_map[valTester] = freeVar;
valueTester_fvar_map.insert(valTester, freeVar);
fvar_valueTester_map[freeVar][len].push_back(std::make_pair(sLevel, valTester));
print_value_tester_list(fvar_valueTester_map[freeVar][len]);
}
@ -9606,8 +9608,9 @@ namespace smt {
// put together
toAssert = mgr.mk_and(ctx.mk_eq_atom(op0, and1), toAssert);
unroll_var_map[unrFunc] = toAssert;
} else {
unroll_var_map.insert(unrFunc, toAssert);
}
else {
toAssert = unroll_var_map[unrFunc];
}
}

View file

@ -77,25 +77,8 @@ public:
void register_value(expr * n) override { /* Ignore */ }
};
// rather than modify obj_pair_map I inherit from it and add my own helper methods
class theory_str_contain_pair_bool_map_t : public obj_pair_map<expr, expr, expr*> {
public:
expr * operator[](std::pair<expr*, expr*> key) const {
expr * value;
bool found = this->find(key.first, key.second, value);
if (found) {
return value;
} else {
TRACE("t_str", tout << "WARNING: lookup miss in contain_pair_bool_map!" << std::endl;);
return nullptr;
}
}
bool contains(std::pair<expr*, expr*> key) const {
expr * unused;
return this->find(key.first, key.second, unused);
}
};
// NSB: added operator[] and contains to obj_pair_hashtable
class theory_str_contain_pair_bool_map_t : public obj_pair_map<expr, expr, expr*> {};
template<typename Ctx>
class binary_search_trail : public trail<Ctx> {
@ -169,7 +152,7 @@ class theory_str : public theory {
struct T_cut
{
int level;
std::map<expr*, int> vars;
obj_map<expr, int> vars;
T_cut() {
level = -100;
@ -292,8 +275,8 @@ protected:
int tmpXorVarCount;
int tmpLenTestVarCount;
int tmpValTestVarCount;
std::map<std::pair<expr*, expr*>, std::map<int, expr*> > varForBreakConcat;
// obj_pair_map<expr, expr, std::map<int, expr*> > varForBreakConcat;
std::map<std::pair<expr*,expr*>, std::map<int, expr*> > varForBreakConcat;
bool avoidLoopCut;
bool loopDetected;
obj_map<expr, std::stack<T_cut*> > cut_var_map;
@ -303,7 +286,7 @@ protected:
obj_hashtable<expr> variable_set;
obj_hashtable<expr> internal_variable_set;
obj_hashtable<expr> regex_variable_set;
std::map<int, std::set<expr*> > internal_variable_scope_levels;
std::map<int, obj_hashtable<expr> > internal_variable_scope_levels;
obj_hashtable<expr> internal_lenTest_vars;
obj_hashtable<expr> internal_valTest_vars;
@ -315,7 +298,9 @@ protected:
obj_map<expr, ptr_vector<expr> > fvar_lenTester_map;
obj_map<expr, expr*> lenTester_fvar_map;
obj_map<expr, std::map<int, svector<std::pair<int, expr*> > > > fvar_valueTester_map;
obj_map<expr, expr*> valueTester_fvar_map;
obj_map<expr, int_vector> val_range_map;
@ -331,9 +316,9 @@ protected:
theory_str_contain_pair_bool_map_t contain_pair_bool_map;
obj_map<expr, std::set<std::pair<expr*, expr*> > > contain_pair_idx_map;
// TBD: do a curried map for determinism.
std::map<std::pair<expr*, zstring>, expr*> regex_in_bool_map;
obj_map<expr, std::set<zstring> > regex_in_var_reg_str_map;
obj_map<expr, nfa> regex_nfa_cache; // Regex term --> NFA
svector<char> char_set;
@ -494,10 +479,11 @@ protected:
std::map<expr*, expr*> & concatAliasMap, std::map<expr*, expr *> & varConstMap,
std::map<expr*, expr*> & concatConstMap, std::map<expr*, std::map<expr*, int> > & varEqConcatMap);
expr * dealias_node(expr * node, std::map<expr*, expr*> & varAliasMap, std::map<expr*, expr*> & concatAliasMap);
void get_grounded_concats(expr* node, std::map<expr*, expr*> & varAliasMap,
std::map<expr*, expr*> & concatAliasMap, std::map<expr*, expr*> & varConstMap,
std::map<expr*, expr*> & concatConstMap, std::map<expr*, std::map<expr*, int> > & varEqConcatMap,
std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap);
void get_grounded_concats(unsigned depth,
expr* node, std::map<expr*, expr*> & varAliasMap,
std::map<expr*, expr*> & concatAliasMap, std::map<expr*, expr*> & varConstMap,
std::map<expr*, expr*> & concatConstMap, std::map<expr*, std::map<expr*, int> > & varEqConcatMap,
std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap);
void print_grounded_concat(expr * node, std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap);
void check_subsequence(expr* str, expr* strDeAlias, expr* subStr, expr* subStrDeAlias, expr* boolVar,
std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap);