3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

debugging information for dependence analysis

This commit is contained in:
Murphy Berzish 2016-06-08 19:32:25 -04:00
parent 04fe8f66df
commit bd2b014008
2 changed files with 227 additions and 4 deletions

View file

@ -27,6 +27,10 @@ namespace smt {
theory_str::theory_str(ast_manager & m):
theory(m.mk_family_id("str")),
/* Options */
opt_AggressiveLengthTesting(true),
opt_AggressiveValueTesting(true),
/* Internal setup */
search_started(false),
m_autil(m),
m_strutil(m),
@ -344,6 +348,14 @@ void theory_str::check_and_init_cut_var(expr * node) {
}
}
literal theory_str::mk_literal(expr* _e) {
ast_manager & m = get_manager();
expr_ref e(_e, m);
context& ctx = get_context();
ensure_enode(e);
return ctx.get_literal(e);
}
app * theory_str::mk_int(int n) {
return m_autil.mk_numeral(rational(n), true);
}
@ -3513,6 +3525,160 @@ inline expr * theory_str::getMostRightNodeInConcat(expr * node) {
}
}
void theory_str::trace_ctx_dep(std::ofstream & tout,
std::map<expr*, expr*> & aliasIndexMap,
std::map<expr*, expr*> & var_eq_constStr_map,
std::map<expr*, std::map<expr*, int> > & var_eq_concat_map,
std::map<expr*, expr*> & concat_eq_constStr_map,
std::map<expr*, std::map<expr*, int> > & concat_eq_concat_map) {
#ifdef _TRACE
ast_manager & mgr = get_manager();
{
tout << "(0) alias: variables" << std::endl;
std::map<expr*, std::map<expr*, int> > aliasSumMap;
std::map<expr*, expr*>::iterator itor0 = aliasIndexMap.begin();
for (; itor0 != aliasIndexMap.end(); itor0++) {
aliasSumMap[itor0->second][itor0->first] = 1;
}
std::map<expr*, std::map<expr*, int> >::iterator keyItor = aliasSumMap.begin();
for (; keyItor != aliasSumMap.end(); keyItor++) {
tout << " * ";
tout << mk_pp(keyItor->first, mgr);
tout << " : ";
std::map<expr*, int>::iterator innerItor = keyItor->second.begin();
for (; innerItor != keyItor->second.end(); innerItor++) {
tout << mk_pp(innerItor->first, mgr);
tout << ", ";
}
tout << std::endl;
}
tout << std::endl;
}
{
tout << "(1) var = constStr:" << std::endl;
std::map<expr*, expr*>::iterator itor1 = var_eq_constStr_map.begin();
for (; itor1 != var_eq_constStr_map.end(); itor1++) {
tout << " * ";
tout << mk_pp(itor1->first, mgr);
tout << " = ";
tout << mk_pp(itor1->second, mgr);
if (!in_same_eqc(itor1->first, itor1->second)) {
tout << " (not true in ctx)";
}
tout << std::endl;
}
tout << std::endl;
}
{
tout << "(2) var = concat:" << std::endl;
std::map<expr*, std::map<expr*, int> >::iterator itor2 = var_eq_concat_map.begin();
for (; itor2 != var_eq_concat_map.end(); itor2++) {
tout << " * ";
tout << mk_pp(itor2->first, mgr);
tout << " = { ";
std::map<expr*, int>::iterator i_itor = itor2->second.begin();
for (; i_itor != itor2->second.end(); i_itor++) {
tout << mk_pp(i_itor->first, mgr);
tout << ", ";
}
tout << std::endl;
}
tout << std::endl;
}
/*// TODO
{
__debugPrint(logFile, "(3) var = unrollFunc:\n");
std::map<Z3_ast, std::map<Z3_ast, int> >::iterator itor2 = var_eq_unroll_map.begin();
for (; itor2 != var_eq_unroll_map.end(); itor2++) {
__debugPrint(logFile, " * ");
printZ3Node(t, itor2->first);
__debugPrint(logFile, " = { ");
std::map<Z3_ast, int>::iterator i_itor = itor2->second.begin();
for (; i_itor != itor2->second.end(); i_itor++) {
printZ3Node(t, i_itor->first);
__debugPrint(logFile, ", ");
}
__debugPrint(logFile, " }\n");
}
__debugPrint(logFile, "\n");
}
*/
{
tout << "(4) concat = constStr:" << std::endl;
std::map<expr*, expr*>::iterator itor3 = concat_eq_constStr_map.begin();
for (; itor3 != concat_eq_constStr_map.end(); itor3++) {
tout << " * ";
tout << mk_pp(itor3->first, mgr);
tout << " = ";
tout << mk_pp(itor3->second, mgr);
tout << std::endl;
}
tout << std::endl;
}
{
tout << "(5) eq concats:" << std::endl;
std::map<expr*, std::map<expr*, int> >::iterator itor4 = concat_eq_concat_map.begin();
for (; itor4 != concat_eq_concat_map.end(); itor4++) {
if (itor4->second.size() > 1) {
std::map<expr*, int>::iterator i_itor = itor4->second.begin();
tout << " * ";
for (; i_itor != itor4->second.end(); i_itor++) {
tout << mk_pp(i_itor->first, mgr);
tout << " , ";
}
tout << std::endl;
}
}
tout << std::endl;
}
/*// TODO
{
__debugPrint(logFile, "(6) eq unrolls:\n");
std::map<Z3_ast, std::set<Z3_ast> >::iterator itor5 = unrollGroupMap.begin();
for (; itor5 != unrollGroupMap.end(); itor5++) {
__debugPrint(logFile, " * ");
std::set<Z3_ast>::iterator i_itor = itor5->second.begin();
for (; i_itor != itor5->second.end(); i_itor++) {
printZ3Node(t, *i_itor);
__debugPrint(logFile, ", ");
}
__debugPrint(logFile, "\n");
}
__debugPrint(logFile, "\n");
}
{
__debugPrint(logFile, "(7) unroll = concats:\n");
std::map<Z3_ast, std::set<Z3_ast> >::iterator itor5 = unrollGroupMap.begin();
for (; itor5 != unrollGroupMap.end(); itor5++) {
__debugPrint(logFile, " * ");
Z3_ast unroll = itor5->first;
printZ3Node(t, unroll);
__debugPrint(logFile, "\n");
Z3_ast curr = unroll;
do {
if (isConcatFunc(t, curr)) {
__debugPrint(logFile, " >>> ");
printZ3Node(t, curr);
__debugPrint(logFile, "\n");
}
curr = Z3_theory_get_eqc_next(t, curr);
}while (curr != unroll);
__debugPrint(logFile, "\n");
}
__debugPrint(logFile, "\n");
}
*/
#else
return;
#endif // _TRACE
}
/*
* Dependence analysis from current context assignment
* - "freeVarMap" contains a set of variables that doesn't constrained by Concats.
@ -3747,7 +3913,9 @@ int theory_str::ctx_dep_analysis(std::map<expr*, int> & strVarMap, std::map<expr
}
}
// TODO this would be a great place to print some debugging information
// print some debugging info
TRACE("t_str_detail", trace_ctx_dep(tout, aliasIndexMap, var_eq_constStr_map,
var_eq_concat_map, concat_eq_constStr_map, concat_eq_concat_map););
// TODO compute Contains
/*
@ -4409,6 +4577,7 @@ bool theory_str::get_next_val_encode(int_vector & base, int_vector & next) {
expr * theory_str::gen_val_options(expr * freeVar, expr * len_indicator, expr * val_indicator,
std::string lenStr, int tries) {
ast_manager & m = get_manager();
context & ctx = get_context();
int distance = 32;
@ -4434,8 +4603,11 @@ expr * theory_str::gen_val_options(expr * freeVar, expr * len_indicator, expr *
<< "len_indicator = " << mk_ismt2_pp(len_indicator, m) << std::endl
<< "val_indicator = " << mk_ismt2_pp(val_indicator, m) << std::endl
<< "lenstr = " << lenStr << std::endl
<< "tries = " << tries << std::endl
;);
<< "tries = " << tries << std::endl;
if (opt_AggressiveValueTesting) {
tout << "note: aggressive value testing is enabled" << std::endl;
}
);
if (tries == 0) {
base = int_vector(len + 1, 0);
@ -4474,12 +4646,23 @@ expr * theory_str::gen_val_options(expr * freeVar, expr * len_indicator, expr *
for (long long i = l; i < h; i++) {
orList.push_back(m.mk_eq(val_indicator, m_strutil.mk_string(longlong_to_string(i).c_str()) ));
if (opt_AggressiveValueTesting) {
literal l = mk_eq(val_indicator, m_strutil.mk_string(longlong_to_string(i).c_str()), false);
ctx.mark_as_relevant(l);
ctx.force_phase(l);
}
std::string aStr = gen_val_string(len, options[i - l]);
expr * strAst = m_strutil.mk_string(aStr);
andList.push_back(m.mk_eq(orList[orList.size() - 1], m.mk_eq(freeVar, strAst)));
}
if (!coverAll) {
orList.push_back(m.mk_eq(val_indicator, m_strutil.mk_string("more")));
if (opt_AggressiveValueTesting) {
literal l = mk_eq(val_indicator, m_strutil.mk_string("more"), false);
ctx.mark_as_relevant(l);
ctx.force_phase(~l);
}
}
expr ** or_items = alloc_svect(expr*, orList.size());
@ -4593,6 +4776,7 @@ expr * theory_str::gen_free_var_options(expr * freeVar, expr * len_indicator,
expr * theory_str::gen_len_test_options(expr * freeVar, expr * indicator, int tries) {
ast_manager & m = get_manager();
context & ctx = get_context();
TRACE("t_str_detail", tout << "entry" << std::endl;);
@ -4606,7 +4790,12 @@ expr * theory_str::gen_len_test_options(expr * freeVar, expr * indicator, int tr
int l = (tries - 1) * distance;
int h = tries * distance;
TRACE("t_str_detail", tout << "building andList and orList" << std::endl;);
TRACE("t_str_detail",
tout << "building andList and orList" << std::endl;
if (opt_AggressiveLengthTesting) {
tout << "note: aggressive length testing is active" << std::endl;
}
);
for (int i = l; i < h; ++i) {
std::string i_str = int_to_string(i);
@ -4616,12 +4805,24 @@ expr * theory_str::gen_len_test_options(expr * freeVar, expr * indicator, int tr
TRACE("t_str_detail", tout << "or_expr = " << mk_ismt2_pp(or_expr, m) << std::endl;);
orList.push_back(or_expr);
if (opt_AggressiveLengthTesting) {
literal l = mk_eq(indicator, str_indicator, false);
ctx.mark_as_relevant(l);
ctx.force_phase(l);
}
expr * and_expr = m.mk_eq(orList[orList.size() - 1], m.mk_eq(freeVarLen, mk_int(i)));
TRACE("t_str_detail", tout << "and_expr = " << mk_ismt2_pp(and_expr, m) << std::endl;);
andList.push_back(and_expr);
}
orList.push_back(m.mk_eq(indicator, m_strutil.mk_string("more")));
if (opt_AggressiveLengthTesting) {
literal l = mk_eq(indicator, m_strutil.mk_string("more"), false);
ctx.mark_as_relevant(l);
ctx.force_phase(~l);
}
andList.push_back(m.mk_eq(orList[orList.size() - 1], m_autil.mk_ge(freeVarLen, mk_int(h))));
// TODO refactor this to use expr_ref_vector/svector/buffer instead

View file

@ -62,6 +62,20 @@ namespace smt {
}
};
protected:
// Some options that control how the solver operates.
/*
* If AggressiveLengthTesting is true, we manipulate the phase of length tester equalities
* to prioritize trying concrete length options over choosing the "more" option.
*/
bool opt_AggressiveLengthTesting;
/*
* Similarly, if AggressiveValueTesting is true, we manipulate the phase of value tester equalities
* to prioritize trying concrete value options over choosing the "more" option.
*/
bool opt_AggressiveValueTesting;
bool search_started;
arith_util m_autil;
str_util m_strutil;
@ -116,6 +130,7 @@ namespace smt {
expr * mk_concat(expr * n1, expr * n2);
expr * mk_concat_const_str(expr * n1, expr * n2);
literal mk_literal(expr* _e);
app * mk_int(int n);
app * mk_int(rational & q);
@ -183,6 +198,13 @@ namespace smt {
int ctx_dep_analysis(std::map<expr*, int> & strVarMap, std::map<expr*, int> & freeVarMap,
std::map<expr*, std::set<expr*> > & unrollGroupMap);
void trace_ctx_dep(std::ofstream & tout,
std::map<expr*, expr*> & aliasIndexMap,
std::map<expr*, expr*> & var_eq_constStr_map,
std::map<expr*, std::map<expr*, int> > & var_eq_concat_map,
std::map<expr*, expr*> & concat_eq_constStr_map,
std::map<expr*, std::map<expr*, int> > & concat_eq_concat_map);
void classify_ast_by_type(expr * node, std::map<expr*, int> & varMap,
std::map<expr*, int> & concatMap, std::map<expr*, int> & unrollMap);
void classify_ast_by_type_in_positive_context(std::map<expr*, int> & varMap,