mirror of
https://github.com/Z3Prover/z3
synced 2025-06-03 21:01:22 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
0194df611c
21 changed files with 204 additions and 101 deletions
|
@ -240,7 +240,7 @@ def param2javaw(p):
|
||||||
if k == OUT:
|
if k == OUT:
|
||||||
return "jobject"
|
return "jobject"
|
||||||
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
|
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
|
||||||
if param_type(p) == INT or param_type(p) == UINT:
|
if param_type(p) == INT or param_type(p) == UINT or param_type(p) == BOOL:
|
||||||
return "jintArray"
|
return "jintArray"
|
||||||
else:
|
else:
|
||||||
return "jlongArray"
|
return "jlongArray"
|
||||||
|
@ -258,7 +258,7 @@ def param2pystr(p):
|
||||||
def param2ml(p):
|
def param2ml(p):
|
||||||
k = param_kind(p)
|
k = param_kind(p)
|
||||||
if k == OUT:
|
if k == OUT:
|
||||||
if param_type(p) == INT or param_type(p) == UINT or param_type(p) == INT64 or param_type(p) == UINT64:
|
if param_type(p) == INT or param_type(p) == UINT or param_type(p) == BOOL or param_type(p) == INT64 or param_type(p) == UINT64:
|
||||||
return "int"
|
return "int"
|
||||||
elif param_type(p) == STRING:
|
elif param_type(p) == STRING:
|
||||||
return "string"
|
return "string"
|
||||||
|
@ -491,7 +491,7 @@ def java_method_name(name):
|
||||||
|
|
||||||
# Return the type of the java array elements
|
# Return the type of the java array elements
|
||||||
def java_array_element_type(p):
|
def java_array_element_type(p):
|
||||||
if param_type(p) == INT or param_type(p) == UINT:
|
if param_type(p) == INT or param_type(p) == UINT or param_type(p) == BOOL:
|
||||||
return 'jint'
|
return 'jint'
|
||||||
else:
|
else:
|
||||||
return 'jlong'
|
return 'jlong'
|
||||||
|
@ -653,7 +653,7 @@ def mk_java(java_dir, package_name):
|
||||||
if k == OUT or k == INOUT:
|
if k == OUT or k == INOUT:
|
||||||
java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i))
|
java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i))
|
||||||
elif k == IN_ARRAY or k == INOUT_ARRAY:
|
elif k == IN_ARRAY or k == INOUT_ARRAY:
|
||||||
if param_type(param) == INT or param_type(param) == UINT:
|
if param_type(param) == INT or param_type(param) == UINT or param_type(param) == BOOL:
|
||||||
java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i))
|
java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i))
|
||||||
else:
|
else:
|
||||||
java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i))
|
java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i))
|
||||||
|
@ -663,7 +663,7 @@ def mk_java(java_dir, package_name):
|
||||||
type2str(param_type(param)),
|
type2str(param_type(param)),
|
||||||
param_array_capacity_pos(param),
|
param_array_capacity_pos(param),
|
||||||
type2str(param_type(param))))
|
type2str(param_type(param))))
|
||||||
if param_type(param) == INT or param_type(param) == UINT:
|
if param_type(param) == INT or param_type(param) == UINT or param_type(param) == BOOL:
|
||||||
java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i))
|
java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i))
|
||||||
else:
|
else:
|
||||||
java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i))
|
java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i))
|
||||||
|
@ -702,19 +702,19 @@ def mk_java(java_dir, package_name):
|
||||||
for param in params:
|
for param in params:
|
||||||
k = param_kind(param)
|
k = param_kind(param)
|
||||||
if k == OUT_ARRAY:
|
if k == OUT_ARRAY:
|
||||||
if param_type(param) == INT or param_type(param) == UINT:
|
if param_type(param) == INT or param_type(param) == UINT or param_type(param) == BOOL:
|
||||||
java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i))
|
java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i))
|
||||||
else:
|
else:
|
||||||
java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i))
|
java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i))
|
||||||
java_wrapper.write(' free(_a%s);\n' % i)
|
java_wrapper.write(' free(_a%s);\n' % i)
|
||||||
elif k == IN_ARRAY or k == OUT_ARRAY:
|
elif k == IN_ARRAY or k == OUT_ARRAY:
|
||||||
if param_type(param) == INT or param_type(param) == UINT:
|
if param_type(param) == INT or param_type(param) == UINT or param_type(param) == BOOL:
|
||||||
java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i))
|
java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i))
|
||||||
else:
|
else:
|
||||||
java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i))
|
java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i))
|
||||||
|
|
||||||
elif k == OUT or k == INOUT:
|
elif k == OUT or k == INOUT:
|
||||||
if param_type(param) == INT or param_type(param) == UINT:
|
if param_type(param) == INT or param_type(param) == UINT or param_type(param) == BOOL:
|
||||||
java_wrapper.write(' {\n')
|
java_wrapper.write(' {\n')
|
||||||
java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i)
|
java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i)
|
||||||
java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n')
|
java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n')
|
||||||
|
@ -957,7 +957,7 @@ def def_API(name, result, params):
|
||||||
log_c.write(" }\n")
|
log_c.write(" }\n")
|
||||||
log_c.write(" Au(a%s);\n" % sz)
|
log_c.write(" Au(a%s);\n" % sz)
|
||||||
exe_c.write("in.get_uint_array(%s)" % i)
|
exe_c.write("in.get_uint_array(%s)" % i)
|
||||||
elif ty == INT:
|
elif ty == INT or ty == BOOL:
|
||||||
log_c.write("U(a%s[i]);" % i)
|
log_c.write("U(a%s[i]);" % i)
|
||||||
log_c.write(" }\n")
|
log_c.write(" }\n")
|
||||||
log_c.write(" Au(a%s);\n" % sz)
|
log_c.write(" Au(a%s);\n" % sz)
|
||||||
|
|
|
@ -387,4 +387,17 @@ extern "C" {
|
||||||
Z3_CATCH_RETURN(Z3_FALSE);
|
Z3_CATCH_RETURN(Z3_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Z3_ast Z3_API Z3_mk_bv_numeral(Z3_context c, unsigned sz, Z3_bool const* bits) {
|
||||||
|
Z3_TRY;
|
||||||
|
LOG_Z3_mk_bv_numeral(c, sz, bits);
|
||||||
|
RESET_ERROR_CODE();
|
||||||
|
rational r(0);
|
||||||
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
if (bits[i]) r += rational::power_of_two(i);
|
||||||
|
}
|
||||||
|
ast * a = mk_c(c)->mk_numeral_core(r, mk_c(c)->bvutil().mk_sort(sz));
|
||||||
|
RETURN_Z3(of_ast(a));
|
||||||
|
Z3_CATCH_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -301,6 +301,7 @@ namespace z3 {
|
||||||
expr bv_val(__int64 n, unsigned sz);
|
expr bv_val(__int64 n, unsigned sz);
|
||||||
expr bv_val(__uint64 n, unsigned sz);
|
expr bv_val(__uint64 n, unsigned sz);
|
||||||
expr bv_val(char const * n, unsigned sz);
|
expr bv_val(char const * n, unsigned sz);
|
||||||
|
expr bv_val(unsigned n, bool const* bits);
|
||||||
|
|
||||||
expr string_val(char const* s);
|
expr string_val(char const* s);
|
||||||
expr string_val(std::string const& s);
|
expr string_val(std::string const& s);
|
||||||
|
@ -964,6 +965,13 @@ namespace z3 {
|
||||||
friend expr operator|(expr const & a, expr const & b);
|
friend expr operator|(expr const & a, expr const & b);
|
||||||
friend expr operator|(expr const & a, int b);
|
friend expr operator|(expr const & a, int b);
|
||||||
friend expr operator|(int a, expr const & b);
|
friend expr operator|(int a, expr const & b);
|
||||||
|
friend expr nand(expr const& a, expr const& b);
|
||||||
|
friend expr nor(expr const& a, expr const& b);
|
||||||
|
friend expr xnor(expr const& a, expr const& b);
|
||||||
|
|
||||||
|
expr rotate_left(unsigned i) { Z3_ast r = Z3_mk_rotate_left(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); }
|
||||||
|
expr rotate_right(unsigned i) { Z3_ast r = Z3_mk_rotate_right(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); }
|
||||||
|
expr repeat(unsigned i) { Z3_ast r = Z3_mk_repeat(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); }
|
||||||
|
|
||||||
friend expr operator~(expr const & a);
|
friend expr operator~(expr const & a);
|
||||||
expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); ctx().check_error(); return expr(ctx(), r); }
|
expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); ctx().check_error(); return expr(ctx(), r); }
|
||||||
|
@ -1332,6 +1340,10 @@ namespace z3 {
|
||||||
inline expr operator|(expr const & a, int b) { return a | a.ctx().num_val(b, a.get_sort()); }
|
inline expr operator|(expr const & a, int b) { return a | a.ctx().num_val(b, a.get_sort()); }
|
||||||
inline expr operator|(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) | b; }
|
inline expr operator|(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) | b; }
|
||||||
|
|
||||||
|
inline expr nand(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_bvnand(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||||
|
inline expr nor(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_bvnor(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||||
|
inline expr xnor(expr const& a, expr const& b) { check_context(a, b); Z3_ast r = Z3_mk_bvxnor(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||||
|
|
||||||
inline expr operator~(expr const & a) { Z3_ast r = Z3_mk_bvnot(a.ctx(), a); return expr(a.ctx(), r); }
|
inline expr operator~(expr const & a) { Z3_ast r = Z3_mk_bvnot(a.ctx(), a); return expr(a.ctx(), r); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -1406,11 +1418,18 @@ namespace z3 {
|
||||||
inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), b); }
|
inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), b); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief signed reminder operator for bitvectors
|
\brief signed remainder operator for bitvectors
|
||||||
*/
|
*/
|
||||||
inline expr srem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsrem(a.ctx(), a, b)); }
|
inline expr srem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsrem(a.ctx(), a, b)); }
|
||||||
inline expr srem(expr const & a, int b) { return srem(a, a.ctx().num_val(b, a.get_sort())); }
|
inline expr srem(expr const & a, int b) { return srem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||||
inline expr srem(int a, expr const & b) { return srem(b.ctx().num_val(a, b.get_sort()), b); }
|
inline expr srem(int a, expr const & b) { return srem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief signed modulus operator for bitvectors
|
||||||
|
*/
|
||||||
|
inline expr smod(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsmod(a.ctx(), a, b)); }
|
||||||
|
inline expr smod(expr const & a, int b) { return smod(a, a.ctx().num_val(b, a.get_sort())); }
|
||||||
|
inline expr smod(int a, expr const & b) { return smod(b.ctx().num_val(a, b.get_sort()), b); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief unsigned reminder operator for bitvectors
|
\brief unsigned reminder operator for bitvectors
|
||||||
|
@ -2455,6 +2474,11 @@ namespace z3 {
|
||||||
inline expr context::bv_val(__int64 n, unsigned sz) { Z3_ast r = Z3_mk_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
|
inline expr context::bv_val(__int64 n, unsigned sz) { Z3_ast r = Z3_mk_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
|
||||||
inline expr context::bv_val(__uint64 n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
|
inline expr context::bv_val(__uint64 n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
|
||||||
inline expr context::bv_val(char const * n, unsigned sz) { Z3_ast r = Z3_mk_numeral(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
|
inline expr context::bv_val(char const * n, unsigned sz) { Z3_ast r = Z3_mk_numeral(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
|
||||||
|
inline expr context::bv_val(unsigned n, bool const* bits) {
|
||||||
|
array<Z3_bool> _bits(n);
|
||||||
|
for (unsigned i = 0; i < n; ++i) _bits[i] = bits[i] ? 1 : 0;
|
||||||
|
Z3_ast r = Z3_mk_bv_numeral(m_ctx, n, _bits.ptr()); check_error(); return expr(*this, r);
|
||||||
|
}
|
||||||
|
|
||||||
inline expr context::string_val(char const* s) { Z3_ast r = Z3_mk_string(m_ctx, s); check_error(); return expr(*this, r); }
|
inline expr context::string_val(char const* s) { Z3_ast r = Z3_mk_string(m_ctx, s); check_error(); return expr(*this, r); }
|
||||||
inline expr context::string_val(std::string const& s) { Z3_ast r = Z3_mk_string(m_ctx, s.c_str()); check_error(); return expr(*this, r); }
|
inline expr context::string_val(std::string const& s) { Z3_ast r = Z3_mk_string(m_ctx, s.c_str()); check_error(); return expr(*this, r); }
|
||||||
|
|
|
@ -3127,6 +3127,20 @@ namespace Microsoft.Z3
|
||||||
|
|
||||||
return (BitVecNum)MkNumeral(v, MkBitVecSort(size));
|
return (BitVecNum)MkNumeral(v, MkBitVecSort(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a bit-vector numeral.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bits">An array of bits representing the bit-vector. Least signficant bit is at position 0.</param>
|
||||||
|
public BitVecNum MkBV(bool[] bits)
|
||||||
|
{
|
||||||
|
Contract.Ensures(Contract.Result<BitVecNum>() != null);
|
||||||
|
int[] _bits = new int[bits.Length];
|
||||||
|
for (int i = 0; i < bits.Length; ++i) _bits[i] = bits[i] ? 1 : 0;
|
||||||
|
return (BitVecNum)Expr.Create(this, Native.Z3_mk_bv_numeral(nCtx, (uint)bits.Length, _bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion // Numerals
|
#endregion // Numerals
|
||||||
|
|
|
@ -3248,6 +3248,14 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
Z3_ast Z3_API Z3_mk_unsigned_int64(Z3_context c, __uint64 v, Z3_sort ty);
|
Z3_ast Z3_API Z3_mk_unsigned_int64(Z3_context c, __uint64 v, Z3_sort ty);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief create a bit-vector numeral from a vector of Booleans.
|
||||||
|
|
||||||
|
\sa Z3_mk_numeral
|
||||||
|
def_API('Z3_mk_bv_numeral', AST, (_in(CONTEXT), _in(UINT), _in_array(1, BOOL)))
|
||||||
|
*/
|
||||||
|
Z3_ast Z3_API Z3_mk_bv_numeral(Z3_context c, unsigned sz, Z3_bool const* bits);
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/** @name Sequences and regular expressions */
|
/** @name Sequences and regular expressions */
|
||||||
|
|
|
@ -1684,22 +1684,9 @@ ast * ast_manager::register_node_core(ast * n) {
|
||||||
CASSERT("nondet_bug", contains || slow_not_contains(n));
|
CASSERT("nondet_bug", contains || slow_not_contains(n));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
static unsigned counter = 0;
|
|
||||||
counter++;
|
|
||||||
if (counter % 100000 == 0)
|
|
||||||
verbose_stream() << "[ast-table] counter: " << counter << " collisions: " << m_ast_table.collisions() << " capacity: " << m_ast_table.capacity() << " size: " << m_ast_table.size() << "\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ast * r = m_ast_table.insert_if_not_there(n);
|
ast * r = m_ast_table.insert_if_not_there(n);
|
||||||
SASSERT(r->m_hash == h);
|
SASSERT(r->m_hash == h);
|
||||||
if (r != n) {
|
if (r != n) {
|
||||||
#if 0
|
|
||||||
static unsigned reused = 0;
|
|
||||||
reused++;
|
|
||||||
if (reused % 100000 == 0)
|
|
||||||
verbose_stream() << "[ast-table] reused: " << reused << "\n";
|
|
||||||
#endif
|
|
||||||
SASSERT(contains);
|
SASSERT(contains);
|
||||||
SASSERT(m_ast_table.contains(n));
|
SASSERT(m_ast_table.contains(n));
|
||||||
if (is_func_decl(r) && to_func_decl(r)->get_range() != to_func_decl(n)->get_range()) {
|
if (is_func_decl(r) && to_func_decl(r)->get_range() != to_func_decl(n)->get_range()) {
|
||||||
|
|
|
@ -687,7 +687,7 @@ br_status poly_rewriter<Config>::mk_sub(unsigned num_args, expr * const * args,
|
||||||
}
|
}
|
||||||
set_curr_sort(m().get_sort(args[0]));
|
set_curr_sort(m().get_sort(args[0]));
|
||||||
expr_ref minus_one(mk_numeral(numeral(-1)), m());
|
expr_ref minus_one(mk_numeral(numeral(-1)), m());
|
||||||
ptr_buffer<expr> new_args;
|
expr_ref_buffer new_args(m());
|
||||||
new_args.push_back(args[0]);
|
new_args.push_back(args[0]);
|
||||||
for (unsigned i = 1; i < num_args; i++) {
|
for (unsigned i = 1; i < num_args; i++) {
|
||||||
if (is_zero(args[i])) continue;
|
if (is_zero(args[i])) continue;
|
||||||
|
|
|
@ -277,16 +277,21 @@ namespace datalog {
|
||||||
return get_max_var(has_var);
|
return get_max_var(has_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_rule(horn_subsume_model_converter* mc, rule& r) {
|
void del_rule(horn_subsume_model_converter* mc, rule& r, bool unreachable) {
|
||||||
if (mc) {
|
if (mc) {
|
||||||
ast_manager& m = mc->get_manager();
|
ast_manager& m = mc->get_manager();
|
||||||
expr_ref_vector body(m);
|
expr_ref_vector body(m);
|
||||||
for (unsigned i = 0; i < r.get_tail_size(); ++i) {
|
if (unreachable) {
|
||||||
if (r.is_neg_tail(i)) {
|
body.push_back(m.mk_false());
|
||||||
body.push_back(m.mk_not(r.get_tail(i)));
|
}
|
||||||
}
|
else {
|
||||||
else {
|
for (unsigned i = 0; i < r.get_tail_size(); ++i) {
|
||||||
body.push_back(r.get_tail(i));
|
if (r.is_neg_tail(i)) {
|
||||||
|
body.push_back(m.mk_not(r.get_tail(i)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
body.push_back(r.get_tail(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("dl_dr",
|
TRACE("dl_dr",
|
||||||
|
|
|
@ -354,7 +354,7 @@ namespace datalog {
|
||||||
unsigned get_max_rule_var(const rule& r);
|
unsigned get_max_rule_var(const rule& r);
|
||||||
};
|
};
|
||||||
|
|
||||||
void del_rule(horn_subsume_model_converter* mc, rule& r);
|
void del_rule(horn_subsume_model_converter* mc, rule& r, bool unreachable);
|
||||||
|
|
||||||
void resolve_rule(rule_manager& rm,
|
void resolve_rule(rule_manager& rm,
|
||||||
replace_proof_converter* pc, rule const& r1, rule const& r2, unsigned idx,
|
replace_proof_converter* pc, rule const& r1, rule const& r2, unsigned idx,
|
||||||
|
|
|
@ -607,6 +607,9 @@ namespace datalog {
|
||||||
rule_set * res = alloc(rule_set, m_context);
|
rule_set * res = alloc(rule_set, m_context);
|
||||||
if (transform_rules(source, *res)) {
|
if (transform_rules(source, *res)) {
|
||||||
res->inherit_predicates(source);
|
res->inherit_predicates(source);
|
||||||
|
TRACE("dl",
|
||||||
|
source.display(tout);
|
||||||
|
res->display(tout););
|
||||||
} else {
|
} else {
|
||||||
dealloc(res);
|
dealloc(res);
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
|
@ -426,7 +426,7 @@ namespace datalog {
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_inlined_rules.get_num_rules(); ++i) {
|
for (unsigned i = 0; i < m_inlined_rules.get_num_rules(); ++i) {
|
||||||
rule* r = m_inlined_rules.get_rule(i);
|
rule* r = m_inlined_rules.get_rule(i);
|
||||||
datalog::del_rule(m_mc, *r);
|
datalog::del_rule(m_mc, *r, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modified) {
|
if (modified) {
|
||||||
datalog::del_rule(m_mc, *r0);
|
datalog::del_rule(m_mc, *r0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return modified;
|
return modified;
|
||||||
|
@ -488,9 +488,9 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (something_done && m_mc) {
|
if (something_done && m_mc) {
|
||||||
for (rule_set::iterator rit = orig.begin(); rit!=rend; ++rit) {
|
for (rule* r : orig) {
|
||||||
if (inlining_allowed(orig, (*rit)->get_decl())) {
|
if (inlining_allowed(orig, r->get_decl())) {
|
||||||
datalog::del_rule(m_mc, **rit);
|
datalog::del_rule(m_mc, *r, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -580,7 +580,7 @@ namespace datalog {
|
||||||
// nothing unifies with the tail atom, therefore the rule is unsatisfiable
|
// nothing unifies with the tail atom, therefore the rule is unsatisfiable
|
||||||
// (we can say this because relation pred doesn't have any ground facts either)
|
// (we can say this because relation pred doesn't have any ground facts either)
|
||||||
res = 0;
|
res = 0;
|
||||||
datalog::del_rule(m_mc, *r);
|
datalog::del_rule(m_mc, *r, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!is_oriented_rewriter(inlining_candidate, strat)) {
|
if (!is_oriented_rewriter(inlining_candidate, strat)) {
|
||||||
|
@ -590,7 +590,7 @@ namespace datalog {
|
||||||
goto process_next_tail;
|
goto process_next_tail;
|
||||||
}
|
}
|
||||||
if (!try_to_inline_rule(*r, *inlining_candidate, ti, res)) {
|
if (!try_to_inline_rule(*r, *inlining_candidate, ti, res)) {
|
||||||
datalog::del_rule(m_mc, *r);
|
datalog::del_rule(m_mc, *r, false);
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -823,7 +823,7 @@ namespace datalog {
|
||||||
if (num_tail_unifiers == 1) {
|
if (num_tail_unifiers == 1) {
|
||||||
TRACE("dl", tout << "setting invalid: " << j << "\n";);
|
TRACE("dl", tout << "setting invalid: " << j << "\n";);
|
||||||
valid.set(j, false);
|
valid.set(j, false);
|
||||||
datalog::del_rule(m_mc, *r2);
|
datalog::del_rule(m_mc, *r2, true);
|
||||||
del_rule(r2, j);
|
del_rule(r2, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -426,8 +426,8 @@ namespace datalog {
|
||||||
bool change = true;
|
bool change = true;
|
||||||
while (change) {
|
while (change) {
|
||||||
change = false;
|
change = false;
|
||||||
for (unsigned i = 0; i < src.get_num_rules(); ++i) {
|
for (rule* r : src) {
|
||||||
change = prune_rule(*src.get_rule(i)) || change;
|
change = prune_rule(*r) || change;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,18 +457,19 @@ namespace datalog {
|
||||||
|
|
||||||
void mk_slice::solve_vars(rule& r, uint_set& used_vars, uint_set& parameter_vars) {
|
void mk_slice::solve_vars(rule& r, uint_set& used_vars, uint_set& parameter_vars) {
|
||||||
expr_ref_vector conjs = get_tail_conjs(r);
|
expr_ref_vector conjs = get_tail_conjs(r);
|
||||||
for (unsigned j = 0; j < conjs.size(); ++j) {
|
for (expr * e : conjs) {
|
||||||
expr* e = conjs[j].get();
|
|
||||||
expr_ref r(m);
|
expr_ref r(m);
|
||||||
unsigned v;
|
unsigned v;
|
||||||
if (is_eq(e, v, r) && is_output(v) && m_var_is_sliceable[v]) {
|
if (is_eq(e, v, r) && is_output(v) && m_var_is_sliceable[v]) {
|
||||||
TRACE("dl", tout << "is_eq: " << mk_pp(e, m) << " " << (m_solved_vars[v].get()?"solved":"new") << "\n";);
|
TRACE("dl", tout << "is_eq: " << mk_pp(e, m) << " " << (m_solved_vars[v].get()?"solved":"new") << "\n";);
|
||||||
add_var(v);
|
add_var(v);
|
||||||
if (!m_solved_vars[v].get()) {
|
if (!m_solved_vars[v].get()) {
|
||||||
|
TRACE("dl", tout << v << " is solved\n";);
|
||||||
add_free_vars(parameter_vars, r);
|
add_free_vars(parameter_vars, r);
|
||||||
m_solved_vars[v] = r;
|
m_solved_vars[v] = r;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
TRACE("dl", tout << v << " is used\n";);
|
||||||
// variables can only be solved once.
|
// variables can only be solved once.
|
||||||
add_free_vars(used_vars, e);
|
add_free_vars(used_vars, e);
|
||||||
add_free_vars(used_vars, m_solved_vars[v].get());
|
add_free_vars(used_vars, m_solved_vars[v].get());
|
||||||
|
@ -508,10 +509,9 @@ namespace datalog {
|
||||||
//
|
//
|
||||||
uint_set used_vars, parameter_vars;
|
uint_set used_vars, parameter_vars;
|
||||||
solve_vars(r, used_vars, parameter_vars);
|
solve_vars(r, used_vars, parameter_vars);
|
||||||
uint_set::iterator it = used_vars.begin(), end = used_vars.end();
|
for (unsigned uv : used_vars) {
|
||||||
for (; it != end; ++it) {
|
if (uv < m_var_is_sliceable.size()) {
|
||||||
if (*it < m_var_is_sliceable.size()) {
|
m_var_is_sliceable[uv] = false;
|
||||||
m_var_is_sliceable[*it] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -533,6 +533,9 @@ namespace datalog {
|
||||||
if (m_solved_vars[i].get()) {
|
if (m_solved_vars[i].get()) {
|
||||||
m_var_is_sliceable[i] = false;
|
m_var_is_sliceable[i] = false;
|
||||||
}
|
}
|
||||||
|
if (parameter_vars.contains(i)) {
|
||||||
|
m_var_is_sliceable[i] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (is_output) {
|
else if (is_output) {
|
||||||
if (parameter_vars.contains(i)) {
|
if (parameter_vars.contains(i)) {
|
||||||
|
@ -687,11 +690,9 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mk_slice::display(std::ostream& out) {
|
void mk_slice::display(std::ostream& out) {
|
||||||
obj_map<func_decl, bit_vector>::iterator it = m_sliceable.begin();
|
for (auto const& kv : m_sliceable) {
|
||||||
obj_map<func_decl, bit_vector>::iterator end = m_sliceable.end();
|
out << kv.m_key->get_name() << " ";
|
||||||
for (; it != end; ++it) {
|
bit_vector const& bv = kv.m_value;
|
||||||
out << it->m_key->get_name() << " ";
|
|
||||||
bit_vector const& bv = it->m_value;
|
|
||||||
for (unsigned i = 0; i < bv.size(); ++i) {
|
for (unsigned i = 0; i < bv.size(); ++i) {
|
||||||
out << (bv.get(i)?"1":"0");
|
out << (bv.get(i)?"1":"0");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,10 @@ Revision History:
|
||||||
#include "ast/rewriter/rewriter.h"
|
#include "ast/rewriter/rewriter.h"
|
||||||
#include "ast/rewriter/rewriter_def.h"
|
#include "ast/rewriter/rewriter_def.h"
|
||||||
#include "muz/transforms/dl_mk_subsumption_checker.h"
|
#include "muz/transforms/dl_mk_subsumption_checker.h"
|
||||||
|
|
||||||
#include "muz/base/fixedpoint_params.hpp"
|
#include "muz/base/fixedpoint_params.hpp"
|
||||||
|
#include "tactic/extension_model_converter.h"
|
||||||
|
|
||||||
|
|
||||||
namespace datalog {
|
namespace datalog {
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,26 +39,28 @@ namespace datalog {
|
||||||
|
|
||||||
|
|
||||||
bool mk_subsumption_checker::is_total_rule(const rule * r) {
|
bool mk_subsumption_checker::is_total_rule(const rule * r) {
|
||||||
if(r->get_tail_size()!=0) { return false; }
|
if (r->get_tail_size() != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned pt_len = r->get_positive_tail_size();
|
unsigned pt_len = r->get_positive_tail_size();
|
||||||
if(pt_len!=r->get_uninterpreted_tail_size()) {
|
if(pt_len != r->get_uninterpreted_tail_size()) {
|
||||||
//we dont' expect rules with negative tails to be total
|
// we dont' expect rules with negative tails to be total
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned i=0; i<pt_len; i++) {
|
for (unsigned i = 0; i < pt_len; i++) {
|
||||||
func_decl * tail_pred = r->get_tail(i)->get_decl();
|
func_decl * tail_pred = r->get_tail(i)->get_decl();
|
||||||
if(!m_total_relations.contains(tail_pred)) {
|
if (!m_total_relations.contains(tail_pred)) {
|
||||||
//this rule has a non-total predicate in the tail
|
// this rule has a non-total predicate in the tail
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned t_len = r->get_positive_tail_size();
|
unsigned t_len = r->get_positive_tail_size();
|
||||||
for(unsigned i=pt_len; i<t_len; i++) {
|
for(unsigned i = pt_len; i < t_len; i++) {
|
||||||
SASSERT(!r->is_neg_tail(i)); //we assume interpreted tail not to be negated
|
SASSERT(!r->is_neg_tail(i)); //we assume interpreted tail not to be negated
|
||||||
if(!m.is_true(r->get_tail(i))) {
|
if (!m.is_true(r->get_tail(i))) {
|
||||||
//this rule has an interpreted tail which is not constant true
|
//this rule has an interpreted tail which is not constant true
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -183,20 +187,15 @@ namespace datalog {
|
||||||
rule_ref_vector orig_rules(m_context.get_rule_manager());
|
rule_ref_vector orig_rules(m_context.get_rule_manager());
|
||||||
orig_rules.append(orig.get_num_rules(), orig.begin());
|
orig_rules.append(orig.get_num_rules(), orig.begin());
|
||||||
|
|
||||||
rule * * rbegin = orig_rules.c_ptr();
|
|
||||||
rule * * rend = rbegin + orig_rules.size();
|
|
||||||
|
|
||||||
//before traversing we sort rules so that the shortest are in the beginning.
|
//before traversing we sort rules so that the shortest are in the beginning.
|
||||||
//this will help make subsumption checks more efficient
|
//this will help make subsumption checks more efficient
|
||||||
std::sort(rbegin, rend, rule_size_comparator);
|
std::sort(orig_rules.c_ptr(), orig_rules.c_ptr() + orig_rules.size(), rule_size_comparator);
|
||||||
|
|
||||||
for(rule_set::iterator rit = rbegin; rit!=rend; ++rit) {
|
for (rule * r : orig_rules) {
|
||||||
|
|
||||||
rule * r = *rit;
|
|
||||||
func_decl * head_pred = r->get_decl();
|
func_decl * head_pred = r->get_decl();
|
||||||
|
|
||||||
if(m_total_relations.contains(head_pred)) {
|
if (m_total_relations.contains(head_pred)) {
|
||||||
if(!orig.is_output_predicate(head_pred) ||
|
if (!orig.is_output_predicate(head_pred) ||
|
||||||
total_relations_with_included_rules.contains(head_pred)) {
|
total_relations_with_included_rules.contains(head_pred)) {
|
||||||
//We just skip definitions of total non-output relations as
|
//We just skip definitions of total non-output relations as
|
||||||
//we'll eliminate them from the problem.
|
//we'll eliminate them from the problem.
|
||||||
|
@ -205,8 +204,7 @@ namespace datalog {
|
||||||
modified = true;
|
modified = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rule * defining_rule;
|
rule * defining_rule = m_total_relation_defining_rules.find(head_pred);
|
||||||
VERIFY(m_total_relation_defining_rules.find(head_pred, defining_rule));
|
|
||||||
if (defining_rule) {
|
if (defining_rule) {
|
||||||
rule_ref totality_rule(m_context.get_rule_manager());
|
rule_ref totality_rule(m_context.get_rule_manager());
|
||||||
VERIFY(transform_rule(defining_rule, subs_index, totality_rule));
|
VERIFY(transform_rule(defining_rule, subs_index, totality_rule));
|
||||||
|
@ -224,24 +222,31 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
rule_ref new_rule(m_context.get_rule_manager());
|
rule_ref new_rule(m_context.get_rule_manager());
|
||||||
if(!transform_rule(r, subs_index, new_rule)) {
|
if (!transform_rule(r, subs_index, new_rule)) {
|
||||||
modified = true;
|
modified = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(m_new_total_relation_discovery_during_transformation && is_total_rule(new_rule)) {
|
if (m_new_total_relation_discovery_during_transformation && is_total_rule(new_rule)) {
|
||||||
on_discovered_total_relation(head_pred, new_rule.get());
|
on_discovered_total_relation(head_pred, new_rule.get());
|
||||||
}
|
}
|
||||||
if(subs_index.is_subsumed(new_rule)) {
|
if (subs_index.is_subsumed(new_rule)) {
|
||||||
modified = true;
|
modified = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(new_rule.get()!=r) {
|
if (new_rule.get()!=r) {
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
tgt.add_rule(new_rule);
|
tgt.add_rule(new_rule);
|
||||||
subs_index.add(new_rule);
|
subs_index.add(new_rule);
|
||||||
}
|
}
|
||||||
tgt.inherit_predicates(orig);
|
tgt.inherit_predicates(orig);
|
||||||
|
if (!m_total_relations.empty() && m_context.get_model_converter()) {
|
||||||
|
extension_model_converter* mc0 = alloc(extension_model_converter, m);
|
||||||
|
for (func_decl* p : m_total_relations) {
|
||||||
|
mc0->insert(p, m.mk_true());
|
||||||
|
}
|
||||||
|
m_context.add_model_converter(mc0);
|
||||||
|
}
|
||||||
TRACE("dl",
|
TRACE("dl",
|
||||||
tout << "original set size: "<<orig.get_num_rules()<<"\n"
|
tout << "original set size: "<<orig.get_num_rules()<<"\n"
|
||||||
<< "reduced set size: "<<tgt.get_num_rules()<<"\n"; );
|
<< "reduced set size: "<<tgt.get_num_rules()<<"\n"; );
|
||||||
|
|
|
@ -20,7 +20,6 @@ Revision History:
|
||||||
#include "qe/qe_lite.h"
|
#include "qe/qe_lite.h"
|
||||||
#include "ast/expr_abstract.h"
|
#include "ast/expr_abstract.h"
|
||||||
#include "ast/used_vars.h"
|
#include "ast/used_vars.h"
|
||||||
#include "ast/occurs.h"
|
|
||||||
#include "ast/rewriter/rewriter_def.h"
|
#include "ast/rewriter/rewriter_def.h"
|
||||||
#include "ast/ast_pp.h"
|
#include "ast/ast_pp.h"
|
||||||
#include "ast/ast_ll_pp.h"
|
#include "ast/ast_ll_pp.h"
|
||||||
|
@ -39,6 +38,30 @@ Revision History:
|
||||||
#include "qe/qe_vartest.h"
|
#include "qe/qe_vartest.h"
|
||||||
|
|
||||||
namespace eq {
|
namespace eq {
|
||||||
|
|
||||||
|
bool occurs_var(unsigned idx, expr* e) {
|
||||||
|
ptr_buffer<expr> todo;
|
||||||
|
todo.push_back(e);
|
||||||
|
ast_mark mark;
|
||||||
|
while (!todo.empty()) {
|
||||||
|
expr* e = todo.back();
|
||||||
|
todo.pop_back();
|
||||||
|
if (mark.is_marked(e)) continue;
|
||||||
|
mark.mark(e, true);
|
||||||
|
if (is_var(e)) {
|
||||||
|
if (to_var(e)->get_idx() == idx) return true;
|
||||||
|
}
|
||||||
|
else if (is_app(e)) {
|
||||||
|
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
|
||||||
|
}
|
||||||
|
else if (is_quantifier(e)) {
|
||||||
|
quantifier* q = to_quantifier(e);
|
||||||
|
if (occurs_var(idx + q->get_num_decls(), q->get_expr())) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
class der {
|
class der {
|
||||||
ast_manager & m;
|
ast_manager & m;
|
||||||
arith_util a;
|
arith_util a;
|
||||||
|
@ -65,7 +88,7 @@ namespace eq {
|
||||||
for (unsigned i = 0; i < definitions.size(); i++) {
|
for (unsigned i = 0; i < definitions.size(); i++) {
|
||||||
var * v = vars[i];
|
var * v = vars[i];
|
||||||
expr * t = definitions[i];
|
expr * t = definitions[i];
|
||||||
if (t == 0 || has_quantifiers(t) || occurs(v, t))
|
if (t == 0 || has_quantifiers(t) || occurs_var(v->get_idx(), t))
|
||||||
definitions[i] = 0;
|
definitions[i] = 0;
|
||||||
else
|
else
|
||||||
found = true; // found at least one candidate
|
found = true; // found at least one candidate
|
||||||
|
@ -679,9 +702,9 @@ namespace eq {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_unconstrained(var* x, expr* t, unsigned i, expr_ref_vector const& conjs) {
|
bool is_unconstrained(var* x, expr* t, unsigned i, expr_ref_vector const& conjs) {
|
||||||
bool occ = occurs(x, t);
|
bool occ = occurs_var(x->get_idx(), t);
|
||||||
for (unsigned j = 0; !occ && j < conjs.size(); ++j) {
|
for (unsigned j = 0; !occ && j < conjs.size(); ++j) {
|
||||||
occ = (i != j) && occurs(x, conjs[j]);
|
occ = (i != j) && occurs_var(x->get_idx(), conjs[j]);
|
||||||
}
|
}
|
||||||
return !occ;
|
return !occ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4373,7 +4373,7 @@ namespace smt {
|
||||||
void context::add_rec_funs_to_model() {
|
void context::add_rec_funs_to_model() {
|
||||||
ast_manager& m = m_manager;
|
ast_manager& m = m_manager;
|
||||||
SASSERT(m_model);
|
SASSERT(m_model);
|
||||||
for (unsigned i = 0; i < m_asserted_formulas.get_num_formulas(); ++i) {
|
for (unsigned i = 0; !get_cancel_flag() && i < m_asserted_formulas.get_num_formulas(); ++i) {
|
||||||
expr* e = m_asserted_formulas.get_formula(i);
|
expr* e = m_asserted_formulas.get_formula(i);
|
||||||
if (is_quantifier(e)) {
|
if (is_quantifier(e)) {
|
||||||
TRACE("context", tout << mk_pp(e, m) << "\n";);
|
TRACE("context", tout << mk_pp(e, m) << "\n";);
|
||||||
|
|
|
@ -209,7 +209,12 @@ namespace smt {
|
||||||
~scoped_mk_model() {
|
~scoped_mk_model() {
|
||||||
if (m_ctx.m_proto_model.get() != 0) {
|
if (m_ctx.m_proto_model.get() != 0) {
|
||||||
m_ctx.m_model = m_ctx.m_proto_model->mk_model();
|
m_ctx.m_model = m_ctx.m_proto_model->mk_model();
|
||||||
m_ctx.add_rec_funs_to_model();
|
try {
|
||||||
|
m_ctx.add_rec_funs_to_model();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
m_ctx.m_proto_model = 0; // proto_model is not needed anymore.
|
m_ctx.m_proto_model = 0; // proto_model is not needed anymore.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace smt {
|
||||||
sLevel(0),
|
sLevel(0),
|
||||||
finalCheckProgressIndicator(false),
|
finalCheckProgressIndicator(false),
|
||||||
m_trail(m),
|
m_trail(m),
|
||||||
|
m_factory(nullptr),
|
||||||
|
m_unused_id(0),
|
||||||
m_delayed_axiom_setup_terms(m),
|
m_delayed_axiom_setup_terms(m),
|
||||||
tmpStringVarCount(0),
|
tmpStringVarCount(0),
|
||||||
tmpXorVarCount(0),
|
tmpXorVarCount(0),
|
||||||
|
@ -61,8 +63,8 @@ namespace smt {
|
||||||
cacheHitCount(0),
|
cacheHitCount(0),
|
||||||
cacheMissCount(0),
|
cacheMissCount(0),
|
||||||
m_fresh_id(0),
|
m_fresh_id(0),
|
||||||
m_find(*this),
|
m_trail_stack(*this),
|
||||||
m_trail_stack(*this)
|
m_find(*this)
|
||||||
{
|
{
|
||||||
initialize_charset();
|
initialize_charset();
|
||||||
}
|
}
|
||||||
|
@ -279,7 +281,7 @@ namespace smt {
|
||||||
} else {
|
} else {
|
||||||
theory_var v = theory::mk_var(n);
|
theory_var v = theory::mk_var(n);
|
||||||
m_find.mk_var();
|
m_find.mk_var();
|
||||||
TRACE("str", tout << "new theory var v#" << v << std::endl;);
|
TRACE("str", tout << "new theory var v#" << v << " find " << m_find.find(v) << std::endl;);
|
||||||
get_context().attach_th_var(n, this, v);
|
get_context().attach_th_var(n, this, v);
|
||||||
get_context().mark_as_relevant(n);
|
get_context().mark_as_relevant(n);
|
||||||
return v;
|
return v;
|
||||||
|
@ -1903,8 +1905,8 @@ namespace smt {
|
||||||
|
|
||||||
// support for user_smt_theory-style EQC handling
|
// support for user_smt_theory-style EQC handling
|
||||||
|
|
||||||
app * theory_str::get_ast(theory_var i) {
|
app * theory_str::get_ast(theory_var v) {
|
||||||
return get_enode(i)->get_owner();
|
return get_enode(v)->get_owner();
|
||||||
}
|
}
|
||||||
|
|
||||||
theory_var theory_str::get_var(expr * n) const {
|
theory_var theory_str::get_var(expr * n) const {
|
||||||
|
@ -4648,14 +4650,20 @@ namespace smt {
|
||||||
// We only check m_find for a string constant.
|
// We only check m_find for a string constant.
|
||||||
|
|
||||||
expr * theory_str::z3str2_get_eqc_value(expr * n , bool & hasEqcValue) {
|
expr * theory_str::z3str2_get_eqc_value(expr * n , bool & hasEqcValue) {
|
||||||
expr * curr = n;
|
theory_var curr = get_var(n);
|
||||||
do {
|
if (curr != null_theory_var) {
|
||||||
if (u.str.is_string(curr)) {
|
curr = m_find.find(curr);
|
||||||
hasEqcValue = true;
|
theory_var first = curr;
|
||||||
return curr;
|
do {
|
||||||
}
|
expr* a = get_ast(curr);
|
||||||
curr = get_eqc_next(curr);
|
if (u.str.is_string(a)) {
|
||||||
} while (curr != n);
|
hasEqcValue = true;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
curr = m_find.next(curr);
|
||||||
|
}
|
||||||
|
while (curr != first && curr != null_theory_var);
|
||||||
|
}
|
||||||
hasEqcValue = false;
|
hasEqcValue = false;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -10584,7 +10592,9 @@ namespace smt {
|
||||||
return alloc(expr_wrapper_proc, val);
|
return alloc(expr_wrapper_proc, val);
|
||||||
} else {
|
} else {
|
||||||
TRACE("str", tout << "WARNING: failed to find a concrete value, falling back" << std::endl;);
|
TRACE("str", tout << "WARNING: failed to find a concrete value, falling back" << std::endl;);
|
||||||
return alloc(expr_wrapper_proc, to_app(mk_string("**UNUSED**")));
|
std::ostringstream unused;
|
||||||
|
unused << "**UNUSED**" << (m_unused_id++);
|
||||||
|
return alloc(expr_wrapper_proc, to_app(mk_string(unused.str().c_str())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,10 @@ protected:
|
||||||
|
|
||||||
str_value_factory * m_factory;
|
str_value_factory * m_factory;
|
||||||
|
|
||||||
|
// Unique identifier appended to unused variables to ensure that model construction
|
||||||
|
// does not introduce equalities when they weren't enforced.
|
||||||
|
unsigned m_unused_id;
|
||||||
|
|
||||||
// terms we couldn't go through set_up_axioms() with because they weren't internalized
|
// terms we couldn't go through set_up_axioms() with because they weren't internalized
|
||||||
expr_ref_vector m_delayed_axiom_setup_terms;
|
expr_ref_vector m_delayed_axiom_setup_terms;
|
||||||
|
|
||||||
|
@ -358,8 +362,8 @@ protected:
|
||||||
// cache mapping each string S to Length(S)
|
// cache mapping each string S to Length(S)
|
||||||
obj_map<expr, app*> length_ast_map;
|
obj_map<expr, app*> length_ast_map;
|
||||||
|
|
||||||
th_union_find m_find;
|
|
||||||
th_trail_stack m_trail_stack;
|
th_trail_stack m_trail_stack;
|
||||||
|
th_union_find m_find;
|
||||||
theory_var get_var(expr * n) const;
|
theory_var get_var(expr * n) const;
|
||||||
expr * get_eqc_next(expr * n);
|
expr * get_eqc_next(expr * n);
|
||||||
app * get_ast(theory_var i);
|
app * get_ast(theory_var i);
|
||||||
|
|
|
@ -95,13 +95,13 @@ class diff_neq_tactic : public tactic {
|
||||||
if (is_uninterp_const(lhs) && u.is_numeral(rhs, k) && m_max_neg_k <= k && k <= m_max_k) {
|
if (is_uninterp_const(lhs) && u.is_numeral(rhs, k) && m_max_neg_k <= k && k <= m_max_k) {
|
||||||
var x = mk_var(lhs);
|
var x = mk_var(lhs);
|
||||||
int _k = static_cast<int>(k.get_int64());
|
int _k = static_cast<int>(k.get_int64());
|
||||||
m_upper[x] = _k;
|
m_upper[x] = std::min(m_upper[x], _k);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (is_uninterp_const(rhs) && u.is_numeral(lhs, k) && m_max_neg_k <= k && k <= m_max_k) {
|
else if (is_uninterp_const(rhs) && u.is_numeral(lhs, k) && m_max_neg_k <= k && k <= m_max_k) {
|
||||||
var x = mk_var(rhs);
|
var x = mk_var(rhs);
|
||||||
int _k = static_cast<int>(k.get_int64());
|
int _k = static_cast<int>(k.get_int64());
|
||||||
m_lower[x] = _k;
|
m_lower[x] = std::max(m_lower[x], _k);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw_not_supported();
|
throw_not_supported();
|
||||||
|
|
|
@ -1157,7 +1157,7 @@ public:
|
||||||
|
|
||||||
bool explanation_is_correct(const vector<std::pair<mpq, unsigned>>& explanation) const {
|
bool explanation_is_correct(const vector<std::pair<mpq, unsigned>>& explanation) const {
|
||||||
#ifdef Z3DEBUG
|
#ifdef Z3DEBUG
|
||||||
lconstraint_kind kind;
|
lconstraint_kind kind = EQ; // initialize it just to avoid a warning
|
||||||
SASSERT(the_relations_are_of_same_type(explanation, kind));
|
SASSERT(the_relations_are_of_same_type(explanation, kind));
|
||||||
SASSERT(the_left_sides_sum_to_zero(explanation));
|
SASSERT(the_left_sides_sum_to_zero(explanation));
|
||||||
mpq rs = sum_of_right_sides_of_explanation(explanation);
|
mpq rs = sum_of_right_sides_of_explanation(explanation);
|
||||||
|
|
|
@ -102,6 +102,7 @@ public:
|
||||||
|
|
||||||
unsigned find(unsigned v) const {
|
unsigned find(unsigned v) const {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
SASSERT(v < m_find.size());
|
||||||
unsigned new_v = m_find[v];
|
unsigned new_v = m_find[v];
|
||||||
if (new_v == v)
|
if (new_v == v)
|
||||||
return v;
|
return v;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue