mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 17:45:32 +00:00
Merge branch 'unstable' of https://git01.codeplex.com/z3 into unstable
This commit is contained in:
commit
99e94e3263
131 changed files with 1027 additions and 6914 deletions
|
@ -23,7 +23,6 @@ Revision History:
|
|||
#include"cmd_context.h"
|
||||
#include"smt2parser.h"
|
||||
#include"smtparser.h"
|
||||
#include"z3_solver.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -248,40 +247,6 @@ extern "C" {
|
|||
return mk_c(c)->m_smtlib_error_buffer.c_str();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_ast parse_z3_stream(Z3_context c, std::istream& is) {
|
||||
z3_solver parser(c, is, verbose_stream(), mk_c(c)->fparams(), false);
|
||||
if (!parser.parse()) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return of_ast(mk_c(c)->m().mk_true());
|
||||
}
|
||||
expr_ref_vector assumptions(mk_c(c)->m());
|
||||
parser.get_assumptions(assumptions);
|
||||
return of_ast(mk_c(c)->mk_and(assumptions.size(), assumptions.c_ptr()));
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_parse_z3_string(Z3_context c, Z3_string str) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_z3_string(c, str);
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
Z3_ast r = parse_z3_stream(c, is);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_parse_z3_file(Z3_context c, Z3_string file_name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_z3_file(c, file_name);
|
||||
std::ifstream is(file_name);
|
||||
if (!is) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_ast r = parse_z3_stream(c, is);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// Support for SMTLIB2
|
||||
|
|
|
@ -4977,23 +4977,6 @@ BEGIN_MLAPI_EXCLUDE
|
|||
Z3_string Z3_API Z3_get_smtlib_error(__in Z3_context c);
|
||||
END_MLAPI_EXCLUDE
|
||||
|
||||
/**
|
||||
\brief \mlh parse_z3_string c str \endmlh
|
||||
Parse the given string using the Z3 native parser.
|
||||
|
||||
Return the conjunction of asserts made in the input.
|
||||
|
||||
def_API('Z3_parse_z3_string', AST, (_in(CONTEXT), _in(STRING)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_parse_z3_string(__in Z3_context c, __in Z3_string str);
|
||||
|
||||
/**
|
||||
\brief Similar to #Z3_parse_z3_string, but reads the benchmark from a file.
|
||||
|
||||
def_API('Z3_parse_z3_file', AST, (_in(CONTEXT), _in(STRING)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_parse_z3_file(__in Z3_context c, __in Z3_string file_name);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#ifdef CorML4
|
||||
|
|
File diff suppressed because it is too large
Load diff
1007
src/api/z3_solver.h
1007
src/api/z3_solver.h
File diff suppressed because it is too large
Load diff
|
@ -1410,6 +1410,51 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XOR is a mask
|
||||
// All arguments but one is a numeral.
|
||||
//
|
||||
// Apply a transformation of the form:
|
||||
//
|
||||
// (bvxor a 0011) --> (concat ((_ extract 3 2) a) ((_ extract 1 0) (bvnot a)))
|
||||
//
|
||||
if (!v1.is_zero() && num_coeffs == num - 1) {
|
||||
// find argument that is not a numeral
|
||||
expr * t = 0;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
t = args[i];
|
||||
if (!is_numeral(t))
|
||||
break;
|
||||
}
|
||||
SASSERT(t != 0);
|
||||
numeral two(2);
|
||||
expr_ref_buffer exs(m());
|
||||
expr_ref not_t(m());
|
||||
not_t = m_util.mk_bv_not(t);
|
||||
unsigned low = 0;
|
||||
unsigned i = 0;
|
||||
while (i < sz) {
|
||||
while (i < sz && mod(v1, two).is_one()) {
|
||||
i++;
|
||||
div(v1, two, v1);
|
||||
}
|
||||
if (i != low) {
|
||||
exs.push_back(m_mk_extract(i-1, low, not_t));
|
||||
low = i;
|
||||
}
|
||||
while (i < sz && mod(v1, two).is_zero()) {
|
||||
i++;
|
||||
div(v1, two, v1);
|
||||
}
|
||||
if (i != low) {
|
||||
exs.push_back(m_mk_extract(i-1, low, t));
|
||||
low = i;
|
||||
}
|
||||
}
|
||||
std::reverse(exs.c_ptr(), exs.c_ptr() + exs.size());
|
||||
result = m_util.mk_concat(exs.size(), exs.c_ptr());
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
|
||||
if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (m_util.power_of_two(sz) - numeral(1)))))
|
||||
return BR_FAILED;
|
||||
|
|
1343
src/bindings/c++/z3++.h
Normal file
1343
src/bindings/c++/z3++.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2853,30 +2853,6 @@ namespace Microsoft.Z3
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region Native Parser
|
||||
/// <summary>
|
||||
/// Parse the given string using the Z3 native parser.
|
||||
/// </summary>
|
||||
/// <returns>A conjunction of asserts made in <paramref name="str"/>.</returns>
|
||||
public Expr ParseZ3String(string str)
|
||||
{
|
||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||
|
||||
return Expr.Create(this, Native.Z3_parse_z3_string(nCtx, str));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the given file using the Z3 native parser.
|
||||
/// </summary>
|
||||
/// <returns>A conjunction of asserts made in the file.</returns>
|
||||
public Expr ParseZ3File(string fileName)
|
||||
{
|
||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||
|
||||
return Expr.Create(this, Native.Z3_parse_z3_file(nCtx, fileName));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Goals
|
||||
/// <summary>
|
||||
/// Creates a new Goal.
|
|
@ -1,8 +0,0 @@
|
|||
from z3 import *
|
||||
|
||||
x = Real('x')
|
||||
y = Real('y')
|
||||
s = Solver()
|
||||
s.add(x + y > 5, x > 1, y > 1)
|
||||
print s.check()
|
||||
print s.model()
|
|
@ -24,7 +24,7 @@ Small example:
|
|||
>>> s.check()
|
||||
sat
|
||||
>>> s.model()
|
||||
[x = 1, y = 2]
|
||||
[y = 2, x = 1]
|
||||
|
||||
Z3 exceptions:
|
||||
|
||||
|
@ -1698,9 +1698,9 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
|
|||
>>> q
|
||||
Exists([x, y], f(x, y) >= x)
|
||||
>>> Tactic('nnf')(q)
|
||||
[[f(x!foo!2, y!foo!1) >= x!foo!2]]
|
||||
[[f(x!foo!1, y!foo!0) >= x!foo!1]]
|
||||
>>> Tactic('nnf')(q).as_expr()
|
||||
f(x!foo!4, y!foo!3) >= x!foo!4
|
||||
f(x!foo!3, y!foo!2) >= x!foo!3
|
||||
"""
|
||||
return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
|
||||
|
||||
|
@ -6908,7 +6908,7 @@ def solve(*args, **keywords):
|
|||
|
||||
>>> a, b = Ints('a b')
|
||||
>>> solve(a + b == 3, Or(a == 0, a == 1), a != 0)
|
||||
[a = 1, b = 2]
|
||||
[b = 2, a = 1]
|
||||
"""
|
||||
s = Solver()
|
||||
s.set(**keywords)
|
||||
|
|
|
@ -45,6 +45,7 @@ Revision History:
|
|||
#include "cooperate.h"
|
||||
#include "tactical.h"
|
||||
#include "model_v2_pp.h"
|
||||
#include "obj_hashtable.h"
|
||||
|
||||
|
||||
namespace qe {
|
||||
|
@ -723,6 +724,85 @@ namespace qe {
|
|||
}
|
||||
};
|
||||
|
||||
// ----------------------------
|
||||
// def_vector
|
||||
|
||||
void def_vector::normalize() {
|
||||
// apply nested definitions into place.
|
||||
ast_manager& m = m_vars.get_manager();
|
||||
expr_substitution sub(m);
|
||||
scoped_ptr<expr_replacer> rep = mk_expr_simp_replacer(m);
|
||||
if (size() <= 1) {
|
||||
return;
|
||||
}
|
||||
for (unsigned i = size(); i > 0; ) {
|
||||
--i;
|
||||
expr_ref e(m);
|
||||
e = def(i);
|
||||
rep->set_substitution(&sub);
|
||||
(*rep)(e);
|
||||
sub.insert(m.mk_const(var(i)), e);
|
||||
def_ref(i) = e;
|
||||
}
|
||||
}
|
||||
|
||||
void def_vector::project(unsigned num_vars, app* const* vars) {
|
||||
obj_hashtable<func_decl> fns;
|
||||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
fns.insert(vars[i]->get_decl());
|
||||
}
|
||||
for (unsigned i = 0; i < size(); ++i) {
|
||||
if (fns.contains(m_vars[i].get())) {
|
||||
//
|
||||
// retain only first occurrence of eliminated variable.
|
||||
// later occurrences are just recycling the name.
|
||||
//
|
||||
fns.remove(m_vars[i].get());
|
||||
}
|
||||
else {
|
||||
for (unsigned j = i+1; j < size(); ++j) {
|
||||
m_vars.set(j-1, m_vars.get(j));
|
||||
m_defs.set(j-1, m_defs.get(j));
|
||||
}
|
||||
m_vars.pop_back();
|
||||
m_defs.pop_back();
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// guarded_defs
|
||||
|
||||
std::ostream& guarded_defs::display(std::ostream& out) const {
|
||||
ast_manager& m = m_guards.get_manager();
|
||||
for (unsigned i = 0; i < size(); ++i) {
|
||||
for (unsigned j = 0; j < defs(i).size(); ++j) {
|
||||
out << defs(i).var(j)->get_name() << " := " << mk_pp(defs(i).def(j), m) << "\n";
|
||||
}
|
||||
out << "if " << mk_pp(guard(i), m) << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool guarded_defs::inv() {
|
||||
return m_defs.size() == m_guards.size();
|
||||
}
|
||||
|
||||
void guarded_defs::add(expr* guard, def_vector const& defs) {
|
||||
SASSERT(inv());
|
||||
m_defs.push_back(defs);
|
||||
m_guards.push_back(guard);
|
||||
m_defs.back().normalize();
|
||||
SASSERT(inv());
|
||||
}
|
||||
|
||||
void guarded_defs::project(unsigned num_vars, app* const* vars) {
|
||||
for (unsigned i = 0; i < size(); ++i) {
|
||||
m_defs[i].project(num_vars, vars);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Obtain atoms in NNF formula.
|
||||
|
||||
|
@ -810,7 +890,7 @@ namespace qe {
|
|||
|
||||
virtual lbool eliminate_exists(
|
||||
unsigned num_vars, app* const* vars,
|
||||
expr_ref& fml, app_ref_vector& free_vars, bool get_first, def_vector* defs) = 0;
|
||||
expr_ref& fml, app_ref_vector& free_vars, bool get_first, guarded_defs* defs) = 0;
|
||||
|
||||
virtual void set_assumption(expr* fml) = 0;
|
||||
|
||||
|
@ -918,40 +998,25 @@ namespace qe {
|
|||
}
|
||||
}
|
||||
|
||||
bool get_leaf_rec(expr_ref& fml, def_vector& defs) {
|
||||
void get_leaves_rec(def_vector& defs, guarded_defs& gdefs) {
|
||||
expr* f = this->fml();
|
||||
unsigned sz = defs.size();
|
||||
defs.append(def());
|
||||
if (m_children.empty() && f && !m.is_false(f) &&
|
||||
m_vars.empty() && !has_var()) {
|
||||
fml = f;
|
||||
return true;
|
||||
gdefs.add(f, defs);
|
||||
}
|
||||
unsigned sz = defs.size();
|
||||
for (unsigned i = 0; i < m_children.size(); ++i) {
|
||||
search_tree* st = m_children[i];
|
||||
defs.append(st->def());
|
||||
if (st->get_leaf_rec(fml, defs)) {
|
||||
return true;
|
||||
else {
|
||||
for (unsigned i = 0; i < m_children.size(); ++i) {
|
||||
m_children[i]->get_leaves_rec(defs, gdefs);
|
||||
}
|
||||
defs.shrink(sz);
|
||||
}
|
||||
return false;
|
||||
defs.shrink(sz);
|
||||
}
|
||||
|
||||
void get_leaf(expr_ref& fml, def_vector& defs) {
|
||||
get_leaf_rec(fml, defs);
|
||||
|
||||
// apply nested definitions into place.
|
||||
expr_substitution sub(m);
|
||||
scoped_ptr<expr_replacer> rep = mk_expr_simp_replacer(m);
|
||||
for (unsigned i = defs.size(); i > 0; ) {
|
||||
--i;
|
||||
expr_ref e(m);
|
||||
e = defs.def(i);
|
||||
rep->set_substitution(&sub);
|
||||
(*rep)(e);
|
||||
sub.insert(m.mk_const(defs.var(i)), e);
|
||||
defs.def_ref(i) = e;
|
||||
}
|
||||
void get_leaves(guarded_defs& gdefs) {
|
||||
def_vector defs(m);
|
||||
get_leaves_rec(defs, gdefs);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
|
@ -1248,7 +1313,7 @@ namespace qe {
|
|||
|
||||
app_ref_vector m_new_vars; // variables added by solvers
|
||||
bool m_get_first; // get first satisfying branch.
|
||||
def_vector* m_defs;
|
||||
guarded_defs* m_defs;
|
||||
nnf_normalizer m_nnf; // nnf conversion
|
||||
|
||||
|
||||
|
@ -1311,7 +1376,7 @@ namespace qe {
|
|||
|
||||
void check(unsigned num_vars, app* const* vars,
|
||||
expr* assumption, expr_ref& fml, bool get_first,
|
||||
app_ref_vector& free_vars, def_vector* defs) {
|
||||
app_ref_vector& free_vars, guarded_defs* defs) {
|
||||
|
||||
reset();
|
||||
m_solver.push();
|
||||
|
@ -1366,9 +1431,11 @@ namespace qe {
|
|||
expr_ref_vector result(m);
|
||||
m_root.get_leaves(result);
|
||||
m_bool_rewriter.mk_or(result.size(), result.c_ptr(), fml);
|
||||
}
|
||||
else if (defs) {
|
||||
m_root.get_leaf(fml, *defs);
|
||||
}
|
||||
|
||||
if (defs) {
|
||||
m_root.get_leaves(*defs);
|
||||
defs->project(num_vars, vars);
|
||||
}
|
||||
|
||||
TRACE("qe",
|
||||
|
@ -1401,7 +1468,7 @@ namespace qe {
|
|||
private:
|
||||
|
||||
void final_check(model_evaluator& model_eval) {
|
||||
TRACE("qe", tout << (m_fml?"fml":"null") << "\n";);
|
||||
TRACE("qe", tout << "\n";);
|
||||
while (can_propagate_assignment(model_eval)) {
|
||||
propagate_assignment(model_eval);
|
||||
}
|
||||
|
@ -1480,7 +1547,7 @@ namespace qe {
|
|||
m_qe.eliminate_exists(1, &var, fml, m_free_vars, false, 0);
|
||||
}
|
||||
|
||||
lbool eliminate_exists(unsigned num_vars, app* const* vars, expr_ref& fml, bool get_first, def_vector* defs) {
|
||||
lbool eliminate_exists(unsigned num_vars, app* const* vars, expr_ref& fml, bool get_first, guarded_defs* defs) {
|
||||
return m_qe.eliminate_exists(num_vars, vars, fml, m_free_vars, get_first, defs);
|
||||
}
|
||||
|
||||
|
@ -1700,7 +1767,7 @@ namespace qe {
|
|||
|
||||
void propagate_assignment(model_evaluator& model_eval) {
|
||||
if (m_fml) {
|
||||
update_current(model_eval, true);
|
||||
update_status st = update_current(model_eval, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1982,7 +2049,7 @@ namespace qe {
|
|||
|
||||
virtual lbool eliminate_exists(
|
||||
unsigned num_vars, app* const* vars, expr_ref& fml,
|
||||
app_ref_vector& free_vars, bool get_first, def_vector* defs) {
|
||||
app_ref_vector& free_vars, bool get_first, guarded_defs* defs) {
|
||||
if (get_first) {
|
||||
return eliminate_block(num_vars, vars, fml, free_vars, get_first, defs);
|
||||
}
|
||||
|
@ -2008,7 +2075,7 @@ namespace qe {
|
|||
|
||||
lbool eliminate_block(
|
||||
unsigned num_vars, app* const* vars, expr_ref& fml,
|
||||
app_ref_vector& free_vars, bool get_first, def_vector* defs) {
|
||||
app_ref_vector& free_vars, bool get_first, guarded_defs* defs) {
|
||||
|
||||
checkpoint();
|
||||
|
||||
|
@ -2094,54 +2161,6 @@ namespace qe {
|
|||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Instantiation based quantifier elimination procedure.
|
||||
// try a few loops of checking satisfiability.
|
||||
// substitute in model values for bound variables.
|
||||
//
|
||||
class quant_elim_inst : public quant_elim {
|
||||
ast_manager&
|
||||
public:
|
||||
quant_elim_inst(ast_manager& m): m(m) {}
|
||||
|
||||
virtual lbool eliminate_exists(
|
||||
unsigned num_vars, app* const* vars,
|
||||
expr_ref& fml, app_ref_vector& free_vars, bool get_first, def_vector* defs) {
|
||||
|
||||
}
|
||||
|
||||
virtual void set_assumption(expr* fml) {}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
m_solver.collect_statistics(st);
|
||||
}
|
||||
|
||||
virtual void eliminate(bool is_forall, unsigned num_vars, app* const* vars, expr_ref& fml) {
|
||||
if (is_forall) {
|
||||
fml = m.mk_not(fml);
|
||||
r = eliminate_exists(num_vars, vars, fml, free_vars, false, defs);
|
||||
fml = m.mk_not(fml);
|
||||
}
|
||||
else {
|
||||
r = eliminate_exists(num_vars, vars, fml, free_vars, false, defs);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
m_solver.set_cancel(f);
|
||||
}
|
||||
|
||||
virtual void updt_params(params_ref const& p) {
|
||||
m_solver.updt_params(p);
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------
|
||||
// expr_quant_elim
|
||||
|
||||
|
@ -2310,40 +2329,28 @@ namespace qe {
|
|||
lbool expr_quant_elim::first_elim(unsigned num_vars, app* const* vars, expr_ref& fml, def_vector& defs) {
|
||||
app_ref_vector fvs(m);
|
||||
init_qe();
|
||||
return m_qe->eliminate_exists(num_vars, vars, fml, fvs, true, &defs);
|
||||
}
|
||||
|
||||
bool expr_quant_elim::solve_for_var(app* var, expr* _fml, expr_ref_vector& terms, expr_ref_vector& fmls) {
|
||||
expr_ref assms(m.mk_true(), m);
|
||||
func_decl* v = var->get_decl();
|
||||
init_qe();
|
||||
while (true) {
|
||||
def_vector defs(m);
|
||||
app_ref_vector fvs(m);
|
||||
m_qe->set_assumption(assms);
|
||||
expr_ref fml(_fml, m);
|
||||
lbool is_sat = m_qe->eliminate_exists(1, &var, fml, fvs, true, &defs);
|
||||
switch (is_sat) {
|
||||
case l_false: return true;
|
||||
case l_undef: return false;
|
||||
default: break;
|
||||
}
|
||||
bool found = false;
|
||||
for (unsigned i = 0; !found && i < defs.size(); ++i) {
|
||||
if (defs.var(i) == v) {
|
||||
terms.push_back(defs.def(i));
|
||||
fmls.push_back(fml);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
assms = m.mk_and(assms, m.mk_not(fml));
|
||||
guarded_defs gdefs(m);
|
||||
lbool res = m_qe->eliminate_exists(num_vars, vars, fml, fvs, true, &gdefs);
|
||||
if (gdefs.size() > 0) {
|
||||
defs.reset();
|
||||
defs.append(gdefs.defs(0));
|
||||
fml = gdefs.guard(0);
|
||||
}
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool expr_quant_elim::solve_for_var(app* var, expr* fml, guarded_defs& defs) {
|
||||
return solve_for_vars(1,&var, fml, defs);
|
||||
}
|
||||
|
||||
bool expr_quant_elim::solve_for_vars(unsigned num_vars, app* const* vars, expr* _fml, guarded_defs& defs) {
|
||||
app_ref_vector fvs(m);
|
||||
expr_ref fml(_fml, m);
|
||||
TRACE("qe", tout << mk_pp(fml, m) << "\n";);
|
||||
init_qe();
|
||||
lbool is_sat = m_qe->eliminate_exists(num_vars, vars, fml, fvs, false, &defs);
|
||||
return is_sat != l_undef;
|
||||
}
|
||||
|
||||
void expr_quant_elim::set_cancel(bool f) {
|
||||
if (m_qe) {
|
||||
|
|
|
@ -226,8 +226,10 @@ namespace qe {
|
|||
class def_vector {
|
||||
func_decl_ref_vector m_vars;
|
||||
expr_ref_vector m_defs;
|
||||
def_vector& operator=(def_vector const& other);
|
||||
public:
|
||||
def_vector(ast_manager& m): m_vars(m), m_defs(m) {}
|
||||
def_vector(def_vector const& other): m_vars(other.m_vars), m_defs(other.m_defs) {}
|
||||
void push_back(func_decl* v, expr* e) {
|
||||
m_vars.push_back(v);
|
||||
m_defs.push_back(e);
|
||||
|
@ -240,6 +242,33 @@ namespace qe {
|
|||
func_decl* var(unsigned i) const { return m_vars[i]; }
|
||||
expr* def(unsigned i) const { return m_defs[i]; }
|
||||
expr_ref_vector::element_ref def_ref(unsigned i) { return m_defs[i]; }
|
||||
void normalize();
|
||||
void project(unsigned num_vars, app* const* vars);
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Guarded definitions.
|
||||
|
||||
A realizer to a an existential quantified formula is a disjunction
|
||||
together with a substitution from the existentially quantified variables
|
||||
to terms such that:
|
||||
1. The original formula (exists (vars) fml) is equivalent to the disjunction of guards.
|
||||
2. Each guard is equivalent to fml where 'vars' are replaced by the substitution associated
|
||||
with the guard.
|
||||
*/
|
||||
|
||||
class guarded_defs {
|
||||
expr_ref_vector m_guards;
|
||||
vector<def_vector> m_defs;
|
||||
bool inv();
|
||||
public:
|
||||
guarded_defs(ast_manager& m): m_guards(m) { SASSERT(inv()); }
|
||||
void add(expr* guard, def_vector const& defs);
|
||||
unsigned size() const { return m_guards.size(); }
|
||||
def_vector const& defs(unsigned i) const { return m_defs[i]; }
|
||||
expr* guard(unsigned i) const { return m_guards[i]; }
|
||||
std::ostream& display(std::ostream& out) const;
|
||||
void project(unsigned num_vars, app* const* vars);
|
||||
};
|
||||
|
||||
class quant_elim;
|
||||
|
@ -277,10 +306,12 @@ namespace qe {
|
|||
\brief solve for (exists (var) fml).
|
||||
Return false if operation failed.
|
||||
Return true and list of pairs (t_i, fml_i) in <terms, fmls>
|
||||
such that fml[t_1] \/ ... \/ fml[t_n] == (exists (var) fml)
|
||||
and fml_i == fml[t_1]
|
||||
such that fml_1 \/ ... \/ fml_n == (exists (var) fml)
|
||||
and fml_i => fml[t_i]
|
||||
*/
|
||||
bool solve_for_var(app* var, expr* fml, expr_ref_vector& terms, expr_ref_vector& fmls);
|
||||
bool solve_for_var(app* var, expr* fml, guarded_defs& defs);
|
||||
|
||||
bool solve_for_vars(unsigned num_vars, app* const* vars, expr* fml, guarded_defs& defs);
|
||||
|
||||
|
||||
void set_cancel(bool f);
|
||||
|
|
|
@ -367,16 +367,6 @@ namespace qe {
|
|||
simplify(result);
|
||||
}
|
||||
|
||||
expr_ref mk_idiv(expr* a, numeral const & k) {
|
||||
if (k.is_one()) {
|
||||
return expr_ref(a, m);
|
||||
}
|
||||
expr_ref result(m);
|
||||
result = m_arith.mk_idiv(a, m_arith.mk_numeral(k, true));
|
||||
simplify(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
expr* mk_numeral(numeral const& k, bool is_int = true) { return m_arith.mk_numeral(k, is_int); }
|
||||
|
||||
expr* mk_numeral(int k, bool is_int) { return mk_numeral(numeral(k),is_int); }
|
||||
|
@ -1699,6 +1689,40 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
/**
|
||||
\brief Compute least upper/greatest lower bounds for x.
|
||||
|
||||
Assume:
|
||||
(not (= k 0))
|
||||
(<= 0 (mod m k))
|
||||
(< (mod m k) (abs k))
|
||||
(= m (+ (* k (div m k)) (mod m k)))
|
||||
i.e.
|
||||
k * (e div k) + (e mod k) = e
|
||||
|
||||
|
||||
When k is positive, least upper bound
|
||||
for x such that: k*x <= e is e div k
|
||||
|
||||
When k is negative, greatest lower bound
|
||||
for x such that k*x <= e is e div k
|
||||
|
||||
k * (e div k) + (e mod k) = e
|
||||
*/
|
||||
expr_ref mk_idiv(expr* e, numeral k) {
|
||||
SASSERT(!k.is_zero());
|
||||
arith_util& a = m_util.m_arith;
|
||||
if (k.is_one()) {
|
||||
return expr_ref(e, m);
|
||||
}
|
||||
if (k.is_minus_one()) {
|
||||
return expr_ref(a.mk_uminus(e), m);
|
||||
}
|
||||
SASSERT(a.is_int(e));
|
||||
return expr_ref(a.mk_idiv(e, a.mk_numeral(k, true)), m);
|
||||
}
|
||||
|
||||
|
||||
void get_def(contains_app& contains_x, unsigned v, expr* fml, expr_ref& def) {
|
||||
app* x = contains_x.x();
|
||||
x_subst x_t(m_util);
|
||||
|
@ -1730,35 +1754,30 @@ public:
|
|||
// a*x + term <= 0
|
||||
expr_ref term(bounds.exprs(is_strict, !is_lower)[i], m);
|
||||
rational a = bounds.coeffs(is_strict, !is_lower)[i];
|
||||
|
||||
if (x_t.get_term()) {
|
||||
// a*(c*x' + s) + term <= 0
|
||||
// term <- a*s + term
|
||||
// a <- a*c
|
||||
term = m_util.mk_add(m_util.mk_mul(a,x_t.get_term()), term);
|
||||
a = a * x_t.get_coeff();
|
||||
// x := coeff * x' + s
|
||||
// solve instead for
|
||||
// a*coeff*x' + term + a*s <= 0
|
||||
TRACE("qe", tout << x_t.get_coeff() << "* " << mk_pp(x,m) << " + "
|
||||
<< mk_pp(x_t.get_term(), m) << "\n";);
|
||||
SASSERT(x_t.get_coeff().is_pos());
|
||||
term = m_util.mk_add(term, m_util.mk_mul(a, x_t.get_term()));
|
||||
a = a * x_t.get_coeff();
|
||||
}
|
||||
|
||||
TRACE("qe", tout << a << "* " << mk_pp(x,m) << " + " << mk_pp(term, m) << " <= 0\n";);
|
||||
SASSERT(a.is_int());
|
||||
if (is_lower) {
|
||||
// a*x + t <= 0
|
||||
// <=
|
||||
// x <= -t div a
|
||||
SASSERT(a.is_pos());
|
||||
term = m_util.mk_idiv(m_util.mk_uminus(term), a);
|
||||
}
|
||||
else {
|
||||
// -a*x + t <= 0
|
||||
// <=>
|
||||
// t <= a*x
|
||||
// <=
|
||||
// ((div t a) + 1) <= x
|
||||
term = m_util.mk_idiv(term, abs(a));
|
||||
if (!(abs(a).is_one())) {
|
||||
term = m_util.mk_add(term, m_util.mk_one(x));
|
||||
}
|
||||
}
|
||||
terms.push_back(term);
|
||||
SASSERT(is_lower == a.is_pos());
|
||||
TRACE("qe", tout << is_lower << " " << a << " " << mk_pp(term, m) << "\n";);
|
||||
|
||||
// a*x + t <= 0
|
||||
// <=
|
||||
// x <= -t div a + 1
|
||||
|
||||
term = m_util.mk_uminus(term);
|
||||
term = mk_idiv(term, a);
|
||||
terms.push_back(term);
|
||||
TRACE("qe", tout << "a: " << a << " term: " << mk_pp(term, m) << "\n";);
|
||||
}
|
||||
is_strict = true;
|
||||
sz = bounds.size(is_strict, !is_lower);
|
||||
|
@ -1788,14 +1807,11 @@ public:
|
|||
}
|
||||
|
||||
if (x_t.get_term()) {
|
||||
//
|
||||
// x = x_t.get_coeff()*x' + x_t.get_term()
|
||||
// =>
|
||||
// x' = (x - x_t.get_term()) div x_t.get_coeff()
|
||||
//
|
||||
def = m_util.mk_idiv(m_util.mk_sub(def, x_t.get_term()), x_t.get_coeff());
|
||||
// x := coeff * x + s
|
||||
TRACE("qe", tout << x_t.get_coeff() << "* " << mk_pp(x,m) << " + "
|
||||
<< mk_pp(x_t.get_term(), m) << "\n";);
|
||||
def = m_util.mk_add(m_util.mk_mul(x_t.get_coeff(), def), x_t.get_term());
|
||||
}
|
||||
|
||||
m_util.simplify(def);
|
||||
return;
|
||||
}
|
||||
|
@ -1822,25 +1838,39 @@ public:
|
|||
// assert v => (x <= t_i)
|
||||
//
|
||||
SASSERT(v < bounds.size(is_strict, is_lower));
|
||||
expr_ref t(bounds.exprs(is_strict, is_lower)[v], m);
|
||||
def = bounds.exprs(is_strict, is_lower)[v];
|
||||
rational a = bounds.coeffs(is_strict, is_lower)[v];
|
||||
|
||||
t = x_t.mk_term(a, t);
|
||||
a = x_t.mk_coeff(a);
|
||||
|
||||
def = t;
|
||||
if (a.is_pos()) {
|
||||
def = m_util.mk_uminus(def);
|
||||
}
|
||||
if (x_t.get_term()) {
|
||||
def = m_util.mk_idiv(m_util.mk_sub(def, x_t.get_term()), x_t.get_coeff());
|
||||
// x := coeff * x' + s
|
||||
// solve instead for
|
||||
// a*coeff*x' + term + a*s <= 0
|
||||
TRACE("qe", tout << x_t.get_coeff() << "* " << mk_pp(x,m) << " + "
|
||||
<< mk_pp(x_t.get_term(), m) << "\n";);
|
||||
SASSERT(x_t.get_coeff().is_pos());
|
||||
def = m_util.mk_add(def, m_util.mk_mul(a, x_t.get_term()));
|
||||
a = a * x_t.get_coeff();
|
||||
}
|
||||
if (!a.is_one()) {
|
||||
def = m_util.mk_idiv(def, a);
|
||||
|
||||
SASSERT(a.is_int());
|
||||
SASSERT(is_lower != a.is_pos());
|
||||
|
||||
// a*x + t <= 0
|
||||
// <=
|
||||
// x <= -t div a
|
||||
|
||||
def = m_util.mk_uminus(def);
|
||||
def = mk_idiv(def, a);
|
||||
|
||||
if (x_t.get_term()) {
|
||||
// x := coeff * x + s
|
||||
def = m_util.mk_add(m_util.mk_mul(x_t.get_coeff(), def), x_t.get_term());
|
||||
}
|
||||
|
||||
m_util.simplify(def);
|
||||
|
||||
TRACE("qe", tout << "TBD: " << a << " " << mk_pp(t, m) << "\n";);
|
||||
|
||||
TRACE("qe", tout << "TBD: " << a << " " << mk_pp(def, m) << "\n";);
|
||||
}
|
||||
|
||||
expr_ref mk_not(expr* e) {
|
||||
|
|
|
@ -467,10 +467,10 @@ namespace qe {
|
|||
SASSERT(m_datatype_util.is_datatype(s));
|
||||
TRACE("quant_elim", tout << mk_pp(x.x(), m) << " " << vl << "\n";);
|
||||
if (m_datatype_util.is_recursive(s)) {
|
||||
subst_rec(x, vl, fml);
|
||||
subst_rec(x, vl, fml, def);
|
||||
}
|
||||
else {
|
||||
subst_nonrec(x, vl, fml);
|
||||
subst_nonrec(x, vl, fml, def);
|
||||
}
|
||||
if (def) {
|
||||
*def = 0; // TBD
|
||||
|
@ -501,14 +501,21 @@ namespace qe {
|
|||
|
||||
private:
|
||||
|
||||
void add_def(expr* term, expr_ref* def) {
|
||||
if (def) {
|
||||
*def = term;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// replace x by C(y1,..,yn) where y1,..,yn are fresh variables.
|
||||
//
|
||||
void subst_constructor(contains_app& x, func_decl* c, expr_ref& fml) {
|
||||
void subst_constructor(contains_app& x, func_decl* c, expr_ref& fml, expr_ref* def) {
|
||||
subst_clos* sub = 0;
|
||||
|
||||
if (m_subst_cache.find(x.x(), c, sub)) {
|
||||
m_replace->apply_substitution(x.x(), sub->first, 0, fml);
|
||||
add_def(sub->first, def);
|
||||
for (unsigned i = 0; i < sub->second.size(); ++i) {
|
||||
m_ctx.add_var(sub->second[i]);
|
||||
}
|
||||
|
@ -529,6 +536,7 @@ namespace qe {
|
|||
m_trail.push_back(c);
|
||||
m_trail.push_back(t);
|
||||
|
||||
add_def(t, def);
|
||||
m_replace->apply_substitution(x.x(), t, 0, fml);
|
||||
sub->first = t;
|
||||
m_subst_cache.insert(x.x(), c, sub);
|
||||
|
@ -643,7 +651,7 @@ namespace qe {
|
|||
}
|
||||
}
|
||||
|
||||
void subst_rec(contains_app& contains_x, rational const& vl, expr_ref& fml) {
|
||||
void subst_rec(contains_app& contains_x, rational const& vl, expr_ref& fml, expr_ref* def) {
|
||||
app* x = contains_x.x();
|
||||
sort* s = x->get_decl()->get_range();
|
||||
SASSERT(m_datatype_util.is_datatype(s));
|
||||
|
@ -661,6 +669,7 @@ namespace qe {
|
|||
app_ref fresh_x(m.mk_fresh_const("x", s), m);
|
||||
m_ctx.add_var(fresh_x);
|
||||
m_replace->apply_substitution(x, fresh_x, 0, fml);
|
||||
add_def(fresh_x, def);
|
||||
TRACE("quant_elim", tout << "Add recognizer " << mk_pp(is_c, m) << "\n";);
|
||||
return;
|
||||
}
|
||||
|
@ -668,7 +677,7 @@ namespace qe {
|
|||
|
||||
if (has_selector(contains_x, fml, c)) {
|
||||
TRACE("quant_elim", tout << "Eliminate selector " << mk_ll_pp(c, m) << "\n";);
|
||||
subst_constructor(contains_x, c, fml);
|
||||
subst_constructor(contains_x, c, fml, def);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -697,6 +706,7 @@ namespace qe {
|
|||
if (idx < eqs.num_eqs()) {
|
||||
expr* t = eqs.eq(idx);
|
||||
expr* c = eqs.eq_cond(idx);
|
||||
add_def(t, def);
|
||||
m_replace->apply_substitution(x, t, fml);
|
||||
if (!m.is_true(c)) {
|
||||
fml = m.mk_and(c, fml);
|
||||
|
@ -710,6 +720,10 @@ namespace qe {
|
|||
for (unsigned i = 0; i < eqs.num_neqs(); ++i) {
|
||||
m_replace->apply_substitution(eqs.neq_atom(i), m.mk_true(), fml);
|
||||
}
|
||||
if (def) {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
// you need to create a diagonal term
|
||||
}
|
||||
}
|
||||
TRACE("quant_elim", tout << "reduced " << mk_pp(fml.get(), m) << "\n";);
|
||||
}
|
||||
|
@ -753,7 +767,7 @@ namespace qe {
|
|||
m_ctx.add_constraint(true, is_c);
|
||||
}
|
||||
|
||||
virtual void subst_nonrec(contains_app& x, rational const& vl, expr_ref& fml) {
|
||||
virtual void subst_nonrec(contains_app& x, rational const& vl, expr_ref& fml, expr_ref* def) {
|
||||
sort* s = x.x()->get_decl()->get_range();
|
||||
SASSERT(m_datatype_util.is_datatype(s));
|
||||
SASSERT(!m_datatype_util.is_recursive(s));
|
||||
|
@ -767,7 +781,7 @@ namespace qe {
|
|||
SASSERT(vl.get_unsigned() < sz);
|
||||
c = (*m_datatype_util.get_datatype_constructors(s))[vl.get_unsigned()];
|
||||
}
|
||||
subst_constructor(x, c, fml);
|
||||
subst_constructor(x, c, fml, def);
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,11 +19,10 @@ Revision History:
|
|||
#ifndef _SMT_PARSER_H_
|
||||
#define _SMT_PARSER_H_
|
||||
|
||||
#include "ast.h"
|
||||
#include "vector.h"
|
||||
#include "smtlib.h"
|
||||
#include "z3.h"
|
||||
#include <iostream>
|
||||
#include<iostream>
|
||||
#include"ast.h"
|
||||
#include"vector.h"
|
||||
#include"smtlib.h"
|
||||
|
||||
namespace smtlib {
|
||||
class parser {
|
||||
|
@ -42,8 +41,6 @@ namespace smtlib {
|
|||
virtual bool parse_file(char const * path) = 0;
|
||||
virtual bool parse_string(char const * string) = 0;
|
||||
|
||||
virtual bool parse_commands(Z3_context ctx, std::istream& is, std::ostream& os) = 0;
|
||||
|
||||
virtual benchmark * get_benchmark() = 0;
|
||||
};
|
||||
};
|
|
@ -27,7 +27,7 @@ class tactic;
|
|||
tactic * mk_propagate_values_tactic(ast_manager & m, params_ref const & p = params_ref());
|
||||
|
||||
/*
|
||||
ADD_TACTIC_CMD("propagate-values", "propagate constants.", "mk_propagate_values_tactic(m, p)")
|
||||
ADD_TACTIC("propagate-values", "propagate constants.", "mk_propagate_values_tactic(m, p)")
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tst_ast_pp.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Test AST Pretty printing module
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2006-10-5
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "ast.h"
|
||||
#include "ast_pp.h"
|
||||
#include "ast_dag_pp.h"
|
||||
#include "smtparser.h"
|
||||
#include <iostream>
|
||||
|
||||
void tst_ast_pp()
|
||||
{
|
||||
ast_manager m;
|
||||
smtlib::parser* parser = smtlib::parser::create(m);
|
||||
|
||||
parser->initialize_smtlib();
|
||||
|
||||
|
||||
if (!parser->parse_string(
|
||||
"(benchmark test :extrasorts (A B) :extrafuns ((f A A) (g A A A) (x A) (p A bool)) \n"
|
||||
":formula (p (f x))\n"
|
||||
":extrafuns ((x1 Int) (y1 Int))\n"
|
||||
":formula (<= 1 (+ x1 y1))\n"
|
||||
":formula (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (p (g x x))))))\n"
|
||||
":formula (p x)\n"
|
||||
")")) {
|
||||
SASSERT(false);
|
||||
dealloc(parser);
|
||||
return;
|
||||
}
|
||||
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
|
||||
for (unsigned j = 0; j < b->get_num_assumptions(); ++j) {
|
||||
expr* e = b->get_assumptions()[j];
|
||||
std::cout << mk_pp(e, m) << "\n";
|
||||
ast_dag_pp(std::cout, m, e);
|
||||
}
|
||||
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
|
||||
expr* e = b->begin_formulas()[j];
|
||||
std::cout << mk_pp(e, m) << "\n";
|
||||
ast_dag_pp(std::cout, m, e);
|
||||
}
|
||||
dealloc(parser);
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2008 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tst_ast_smt_pp.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Test AST Pretty printing module
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2008-09-04
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include "ast.h"
|
||||
#include "ast_smt_pp.h"
|
||||
#include "smtparser.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
void tst_ast_smt_pp()
|
||||
{
|
||||
ast_manager m;
|
||||
smtlib::parser* parser = smtlib::parser::create(m);
|
||||
|
||||
parser->initialize_smtlib();
|
||||
|
||||
|
||||
if (!parser->parse_string(
|
||||
"(benchmark test :extrasorts (A B) :extrafuns ((f A A) (g A A A) (x A) (p A bool)) \n"
|
||||
":extrafuns ((arg0 BitVec[8]) (arg1 BitVec[8]) (arg2 BitVec[8]))\n"
|
||||
":formula (p (f x))\n"
|
||||
":extrafuns ((x1 Int) (y1 Int))\n"
|
||||
":formula (<= 1 (+ x1 y1))\n"
|
||||
":formula (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (p (g x x))))))\n"
|
||||
":formula (p x)\n"
|
||||
":formula (bvsge (bvadd arg0 arg2) (extract[7:0] bv3[32]))\n"
|
||||
":formula (forall (x Int) (y Int) (z Int) (and (<= 1 x) (<= x y))) \n"
|
||||
":formula (forall (x Int) (y Int) (z Int) (and (<= 2 (ite (<= z 1) x (* 2 x))) (<= x y)))\n"
|
||||
":formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (<= z 1)) x (* 2 x))) (<= x y)))\n"
|
||||
":formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (or (> x y) (<= z 1))) x (* 2 x))) (<= x y)))\n"
|
||||
":extrafuns ((a1 Array))\n"
|
||||
":formula (= x1 (select (store a1 y1 y1) x1))\n"
|
||||
":extrafuns ((a2 Array[32:8]))\n"
|
||||
":formula (= arg0 (select a2 bv0[32]))\n"
|
||||
":datatypes ((list (cons (car Int) (cdr list)) nil))\n"
|
||||
":extrafuns ((a list) (b list) (c list))\n"
|
||||
":formula (is_nil nil)\n"
|
||||
":datatypes ((list1 (cons1 (car1 Int) (cdr1 list2)) nil1) (list2 (cons1 (car2 list) (cdr2 list1)) nil2) )\n"
|
||||
":formula (is_nil2 nil2)\n"
|
||||
")")) {
|
||||
SASSERT(false);
|
||||
dealloc(parser);
|
||||
return;
|
||||
}
|
||||
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
|
||||
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
|
||||
expr* e = b->begin_formulas()[j];
|
||||
ast_smt_pp pp(m);
|
||||
pp.display(std::cout, e);
|
||||
}
|
||||
|
||||
|
||||
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
|
||||
expr* e = b->begin_formulas()[j];
|
||||
|
||||
// print and parse formula again.
|
||||
std::ostringstream buffer;
|
||||
ast_smt_pp pp(m);
|
||||
pp.display(buffer, e);
|
||||
ast_manager m2;
|
||||
smtlib::parser* parser2 = smtlib::parser::create(m2);
|
||||
parser2->initialize_smtlib();
|
||||
if (!parser2->parse_string(buffer.str().c_str())) {
|
||||
SASSERT(false);
|
||||
dealloc(parser2);
|
||||
return;
|
||||
}
|
||||
dealloc(parser2);
|
||||
}
|
||||
|
||||
|
||||
dealloc(parser);
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dl_rule_set.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2010-05-18.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"dl_context.h"
|
||||
#include"dl_rule_set.h"
|
||||
#include"dl_mk_filter_rules.h"
|
||||
#include"dl_mk_simple_joins.h"
|
||||
#include"smtparser.h"
|
||||
#include"ast_pp.h"
|
||||
#include<iostream>
|
||||
#include<sstream>
|
||||
|
||||
void tst_dl_rule_set() {
|
||||
enable_trace("mk_filter_rules");
|
||||
front_end_params params;
|
||||
ast_manager m;
|
||||
smtlib::parser * parser = smtlib::parser::create(m);
|
||||
parser->initialize_smtlib();
|
||||
datalog::context ctx(m, params);
|
||||
datalog::rule_set rs(ctx);
|
||||
datalog::rule_manager& rm = ctx.get_rule_manager();
|
||||
datalog::rule_ref_vector rv(rm);
|
||||
|
||||
|
||||
if (!parser->parse_string(
|
||||
"(benchmark test\n"
|
||||
":extrapreds ((T Int Int) (Q Int Int) (R Int Int Int) (S Int Int Int) (DynActual Int Int Int) (GlobalSym Int Int) (HeapPointsTo Int Int Int) (Calls Int Int)) \n"
|
||||
":extrapreds ((Actual Int Int Int) (PointsTo Int Int) (PointsTo0 Int Int) (FuncDecl0 Int Int) (Assign Int Int) (Load Int Int Int))\n"
|
||||
":formula (forall (x Int) (=> (Q x 1) (T x x)))\n"
|
||||
":formula (forall (v Int) (h Int) (=> (PointsTo0 v h) (PointsTo v h)))\n"
|
||||
":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n"
|
||||
":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n"
|
||||
":formula (forall (v1 Int) (v2 Int) (h Int) (=> (and (PointsTo v2 h) (Assign v1 v2)) (PointsTo v1 h)))\n"
|
||||
":formula (forall (x Int) (y Int) (z Int) (=> (and (Q x y) (T y z)) (T x y)))\n"
|
||||
":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 0 h1) (PointsTo v h1)) (DynActual i1 2 v)))\n"
|
||||
":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 1 h1) (PointsTo v h1)) (DynActual i1 3 v)))\n"
|
||||
":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 2 h1) (PointsTo v h1)) (DynActual i1 4 v)))\n"
|
||||
":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 f) (PointsTo v1 h1) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n"
|
||||
":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 0) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n"
|
||||
":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (not (Load v2 v1 0)) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n"
|
||||
")")) {
|
||||
SASSERT(false);
|
||||
dealloc(parser);
|
||||
return;
|
||||
}
|
||||
|
||||
smtlib::benchmark * b = parser->get_benchmark();
|
||||
|
||||
|
||||
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
|
||||
expr * e = b->begin_formulas()[j];
|
||||
ptr_vector<expr> todo;
|
||||
todo.push_back(e);
|
||||
while (!todo.empty()) {
|
||||
e = todo.back();
|
||||
todo.pop_back();
|
||||
if (is_quantifier(e)) {
|
||||
e = to_quantifier(e)->get_expr();
|
||||
todo.push_back(e);
|
||||
}
|
||||
else if (is_app(e)) {
|
||||
app* a = to_app(e);
|
||||
if (is_uninterp(e) && !ctx.is_predicate(a->get_decl())) {
|
||||
std::cout << "registering " << a->get_decl()->get_name() << "\n";
|
||||
|
||||
ctx.register_predicate(a->get_decl());
|
||||
}
|
||||
else {
|
||||
todo.append(a->get_num_args(), a->get_args());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
|
||||
expr * e = b->begin_formulas()[j];
|
||||
if (is_quantifier(e)) {
|
||||
try {
|
||||
rm.mk_rule(e, rv);
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << "ERROR: it is not a valid Datalog rule:\n" << mk_pp(e, m) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
rs.add_rules(rv.size(), rv.c_ptr());
|
||||
rs.display(std::cout);
|
||||
|
||||
datalog::mk_filter_rules p(ctx);
|
||||
model_converter_ref mc;
|
||||
proof_converter_ref pc;
|
||||
datalog::rule_set * new_rs = p(rs, mc, pc);
|
||||
std::cout << "\nAfter mk_filter:\n";
|
||||
new_rs->display(std::cout);
|
||||
datalog::mk_simple_joins p2(ctx);
|
||||
datalog::rule_set * new_rs2 = p2(*new_rs, mc, pc);
|
||||
std::cout << "\nAfter mk_simple_joins:\n";
|
||||
new_rs2->display(std::cout);
|
||||
dealloc(new_rs);
|
||||
dealloc(new_rs2);
|
||||
dealloc(parser);
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
#include "expr_delta.h"
|
||||
#include "smtparser.h"
|
||||
#include "ast_pp.h"
|
||||
#include "ast_smt_pp.h"
|
||||
|
||||
static void iterate_delta(ast_manager& m, expr_delta& delta) {
|
||||
unsigned n = 0;
|
||||
expr_ref_vector result(m);
|
||||
std::cout << "Delta\n";
|
||||
while (true) {
|
||||
result.reset();
|
||||
if (!delta.delta_dfs(n, result)) {
|
||||
return;
|
||||
}
|
||||
std::cout << n << ": ";
|
||||
for (unsigned i = 0; i < result.size(); ++i) {
|
||||
std::cout << mk_pp(result[i].get(), m) << " ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_expr_delta1() {
|
||||
ast_manager m;
|
||||
smtlib::parser* parser = smtlib::parser::create(m);
|
||||
parser->initialize_smtlib();
|
||||
|
||||
parser->parse_string(
|
||||
"(benchmark samples :logic QF_LIA \n"
|
||||
" :extrafuns ((a Int) (b Int) (c Int)) \n"
|
||||
" :assumption (> a 0) \n"
|
||||
" :assumption (> b 0) \n"
|
||||
" :formula (forall (x Int) (y Int) (z Int) (and (<= 1 x) (<= x y))) \n"
|
||||
" :formula (forall (x Int) (y Int) (z Int) (and (<= 2 (ite (<= z 1) x (* 2 x))) (<= x y)))\n"
|
||||
" :formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (<= z 1)) x (* 2 x))) (<= x y)))\n"
|
||||
" :formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (or (> x y) (<= z 1))) x (* 2 x))) (<= x y)))\n"
|
||||
")"
|
||||
);
|
||||
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
|
||||
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
|
||||
expr_delta delta(m);
|
||||
|
||||
for (unsigned i = 0; i < b->get_num_assumptions(); ++i) {
|
||||
delta.assert_cnstr(b->get_assumptions()[i]);
|
||||
}
|
||||
delta.assert_cnstr(b->begin_formulas()[j]);
|
||||
iterate_delta(m, delta);
|
||||
}
|
||||
|
||||
dealloc(parser);
|
||||
}
|
||||
|
||||
static void get_expr_delta(unsigned position, char const* in, char const* out) {
|
||||
ast_manager m;
|
||||
smtlib::parser* parser = smtlib::parser::create(m);
|
||||
parser->initialize_smtlib();
|
||||
|
||||
if (!parser->parse_file(in)) {
|
||||
std::cout << "error parsing file\n";
|
||||
dealloc(parser);
|
||||
return;
|
||||
}
|
||||
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
|
||||
SASSERT(b->get_num_formulas() == 1);
|
||||
expr_delta delta(m);
|
||||
|
||||
for (unsigned i = 0; i < b->get_num_assumptions(); ++i) {
|
||||
delta.assert_cnstr(b->get_assumptions()[i]);
|
||||
}
|
||||
delta.assert_cnstr(b->begin_formulas()[0]);
|
||||
|
||||
|
||||
expr_ref_vector result(m);
|
||||
if (!delta.delta_dfs(position, result)) {
|
||||
std::cout << "done\n";
|
||||
}
|
||||
else {
|
||||
ast_smt_pp pp(m);
|
||||
std::ofstream outf(out);
|
||||
if (outf.bad() || outf.fail()) {
|
||||
std::cout << "Could not open output\n";
|
||||
}
|
||||
else {
|
||||
switch(b->get_status()) {
|
||||
case smtlib::benchmark::UNKNOWN:
|
||||
pp.set_status("unknown");
|
||||
break;
|
||||
case smtlib::benchmark::SAT:
|
||||
pp.set_status("sat");
|
||||
break;
|
||||
case smtlib::benchmark::UNSAT:
|
||||
pp.set_status("unsat");
|
||||
break;
|
||||
}
|
||||
pp.set_logic(b->get_logic().str().c_str());
|
||||
for (unsigned i = 0; i + 1 < result.size(); ++i) {
|
||||
pp.add_assumption(result[i].get());
|
||||
}
|
||||
pp.display(outf, result[result.size()-1].get());
|
||||
|
||||
std::cout << "ok\n";
|
||||
}
|
||||
}
|
||||
|
||||
dealloc(parser);
|
||||
}
|
||||
|
||||
void tst_expr_delta(char** argv, int argc, int& i) {
|
||||
if (i + 3 >= argc) {
|
||||
std::cout << "Usage: <position:number> <input:file-name> <output:file-name>\n";
|
||||
return;
|
||||
}
|
||||
++i;
|
||||
unsigned position = atol(argv[i]);
|
||||
++i;
|
||||
char const* in_file = argv[i];
|
||||
++i;
|
||||
char const* out_file = argv[i];
|
||||
|
||||
get_expr_delta(position, in_file, out_file);
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
#include "expr_pattern_match.h"
|
||||
#include "smtparser.h"
|
||||
#include "ast_pp.h"
|
||||
#include "arith_decl_plugin.h"
|
||||
#include "bv_decl_plugin.h"
|
||||
#include "array_decl_plugin.h"
|
||||
#include "reg_decl_plugins.h"
|
||||
|
||||
void tst_expr_pattern_match() {
|
||||
ast_manager manager;
|
||||
reg_decl_plugins(manager);
|
||||
|
||||
expr_pattern_match apm(manager);
|
||||
|
||||
apm.display(std::cout);
|
||||
|
||||
const char* test_string = "(benchmark patterns :status unknown :logic ALL \n"
|
||||
":extrasorts (S) \n"
|
||||
":extrafuns ((R S S bool)) \n"
|
||||
":formula (forall (x S) (y S) (z S) \n"
|
||||
" (or (not (R x y)) (not (R y z)) (R x z)) \n"
|
||||
" ; :pats { (R x y) (R y z) } \n"
|
||||
" :weight { 2 } \n"
|
||||
" )\n"
|
||||
")";
|
||||
smtlib::parser* parser = smtlib::parser::create(manager);
|
||||
parser->initialize_smtlib();
|
||||
std::cout << "parsing test string\n";
|
||||
if (!parser->parse_string(test_string)) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
std::cout << "test string parsed\n";
|
||||
smtlib::benchmark* bench = parser->get_benchmark();
|
||||
|
||||
for (unsigned i = 0; i < bench->get_num_formulas(); ++i) {
|
||||
expr* fml = bench->begin_formulas()[i];
|
||||
SASSERT(fml->get_kind() == AST_QUANTIFIER);
|
||||
quantifier* qf = to_quantifier(fml);
|
||||
app_ref_vector patterns(manager);
|
||||
unsigned weight = 0;
|
||||
if (apm.match_quantifier(qf, patterns, weight)) {
|
||||
std::cout << "Found pattern match\n";
|
||||
for (unsigned i = 0; i < patterns.size(); ++i) {
|
||||
ast_pp(std::cout, patterns[i].get(), manager) << "\n";
|
||||
}
|
||||
std::cout << "weight: " << weight << "\n";
|
||||
}
|
||||
}
|
||||
dealloc(parser);
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
grobner.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-12-05.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"smtparser.h"
|
||||
#include"ast_pp.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"simplifier.h"
|
||||
#include"basic_simplifier_plugin.h"
|
||||
#include"arith_simplifier_plugin.h"
|
||||
#include"front_end_params.h"
|
||||
#include"grobner.h"
|
||||
#include"reg_decl_plugins.h"
|
||||
|
||||
void display_eqs(grobner & gb, v_dependency_manager & dep_m) {
|
||||
std::cerr << "RESULT:\n";
|
||||
ptr_vector<grobner::equation> eqs;
|
||||
gb.get_equations(eqs);
|
||||
ptr_vector<grobner::equation>::iterator it = eqs.begin();
|
||||
ptr_vector<grobner::equation>::iterator end = eqs.end();
|
||||
for (; it != end; ++it) {
|
||||
grobner::equation * eq = *it;
|
||||
ptr_vector<void> exs;
|
||||
v_dependency * d = eq->get_dependency();
|
||||
dep_m.linearize(d, exs);
|
||||
std::cerr << "{";
|
||||
ptr_vector<void>::iterator it2 = exs.begin();
|
||||
ptr_vector<void>::iterator end2 = exs.end();
|
||||
for (bool first = true; it2 != end2; ++it2) {
|
||||
if (first) first = false; else std::cerr << " ";
|
||||
std::cerr << *it2;
|
||||
}
|
||||
std::cerr << "}, lc: " << eq->is_linear_combination() << ", ";
|
||||
gb.display_equation(std::cerr, *eq);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_grobner(char ** argv, int argc, int & i) {
|
||||
front_end_params params;
|
||||
if (i + 1 < argc) {
|
||||
char const* file_path = argv[i+1];
|
||||
|
||||
ast_manager m;
|
||||
smtlib::parser* parser = smtlib::parser::create(m);
|
||||
reg_decl_plugins(m);
|
||||
parser->initialize_smtlib();
|
||||
|
||||
if (!parser->parse_file(file_path)) {
|
||||
std::cout << "Could not parse file : " << file_path << std::endl;
|
||||
dealloc(parser);
|
||||
return;
|
||||
}
|
||||
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
simplifier simp(m);
|
||||
basic_simplifier_plugin * bp = alloc(basic_simplifier_plugin, m);
|
||||
simp.register_plugin(bp);
|
||||
simp.register_plugin(alloc(arith_simplifier_plugin, m, *bp, params));
|
||||
arith_util util(m);
|
||||
v_dependency_manager dep_m;
|
||||
grobner gb(m, dep_m);
|
||||
|
||||
ptr_vector<expr>::const_iterator it = b->begin_axioms();
|
||||
ptr_vector<expr>::const_iterator end = b->end_axioms();
|
||||
for (unsigned idx = 1; it != end; ++it, ++idx) {
|
||||
expr * ax = *it;
|
||||
expr_ref s_ax(m);
|
||||
proof_ref pr(m);
|
||||
simp(ax, s_ax, pr);
|
||||
std::cerr << mk_pp(s_ax, m) << "\n";
|
||||
if (m.is_eq(s_ax))
|
||||
gb.assert_eq(s_ax, dep_m.mk_leaf(reinterpret_cast<void*>(idx)));
|
||||
}
|
||||
gb.display(std::cerr);
|
||||
gb.compute_basis(1024);
|
||||
display_eqs(gb, dep_m);
|
||||
dealloc(parser);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ Revision History:
|
|||
--*/
|
||||
#include"imdd.h"
|
||||
|
||||
#ifndef _AMD64_
|
||||
|
||||
static void tst0() {
|
||||
std::cout << "--------------------------------\n";
|
||||
imdd_manager m;
|
||||
|
@ -607,3 +609,9 @@ void tst_imdd() {
|
|||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void tst_imdd() {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -123,7 +123,6 @@ int main(int argc, char ** argv) {
|
|||
memory::initialize(0);
|
||||
bool do_display_usage = false;
|
||||
parse_cmd_line_args(argc, argv, do_display_usage);
|
||||
TST_ARGV(grobner);
|
||||
TST(random);
|
||||
TST(vector);
|
||||
TST(symbol_table);
|
||||
|
@ -131,23 +130,17 @@ int main(int argc, char ** argv) {
|
|||
TST(symbol);
|
||||
TST(heap);
|
||||
TST(hashtable);
|
||||
TST_ARGV(smtparser);
|
||||
TST(rational);
|
||||
TST(inf_rational);
|
||||
TST(ast);
|
||||
TST(optional);
|
||||
TST(bit_vector);
|
||||
TST(ast_pp);
|
||||
TST(ast_smt_pp);
|
||||
TST_ARGV(expr_delta);
|
||||
TST(string_buffer);
|
||||
TST(map);
|
||||
TST(diff_logic);
|
||||
TST(uint_set);
|
||||
TST_ARGV(expr_rand);
|
||||
TST(expr_context_simplifier);
|
||||
TST(ini_file);
|
||||
TST(expr_pattern_match);
|
||||
TST(list);
|
||||
TST(small_object_allocator);
|
||||
TST(timeout);
|
||||
|
@ -157,9 +150,6 @@ int main(int argc, char ** argv) {
|
|||
TST(bit_blaster);
|
||||
TST(var_subst);
|
||||
TST(simple_parser);
|
||||
TST(symmetry);
|
||||
TST_ARGV(symmetry_parse);
|
||||
TST_ARGV(symmetry_prove);
|
||||
TST(api);
|
||||
TST(old_interval);
|
||||
TST(interval_skip_list);
|
||||
|
@ -167,10 +157,8 @@ int main(int argc, char ** argv) {
|
|||
TST(memory);
|
||||
TST(get_implied_equalities);
|
||||
TST(arith_simplifier_plugin);
|
||||
TST(quant_elim);
|
||||
TST(matcher);
|
||||
TST(datalog_parser);
|
||||
TST(dl_rule_set);
|
||||
TST_ARGV(datalog_parser_file);
|
||||
TST(object_allocator);
|
||||
TST(mpz);
|
||||
|
@ -208,7 +196,6 @@ int main(int argc, char ** argv) {
|
|||
TST(prime_generator);
|
||||
TST(permutation);
|
||||
TST(nlsat);
|
||||
TST(qe_defs);
|
||||
TST(ext_numeral);
|
||||
TST(interval);
|
||||
TST(quant_solve);
|
||||
|
|
|
@ -20,8 +20,6 @@ Revision History:
|
|||
#include"util.h"
|
||||
#include"vector.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * p, unsigned * target) {
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
target[i] = src[p[i]];
|
||||
|
@ -29,6 +27,7 @@ void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const *
|
|||
}
|
||||
|
||||
static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) {
|
||||
#if 0
|
||||
unsigned_vector data;
|
||||
unsigned_vector p;
|
||||
unsigned_vector new_data;
|
||||
|
@ -51,6 +50,7 @@ static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) {
|
|||
for (unsigned i = 0; i < 0; i++)
|
||||
SASSERT(data[i] == new_data[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_permutation() {
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
#include "arith_decl_plugin.h"
|
||||
#include "qe.h"
|
||||
#include "ast_pp.h"
|
||||
#include "smtparser.h"
|
||||
#include "reg_decl_plugins.h"
|
||||
|
||||
|
||||
static void test_defs(ast_manager& m, expr* _fml) {
|
||||
arith_util a(m);
|
||||
app_ref x(m);
|
||||
qe::def_vector defs(m);
|
||||
expr_ref fml(_fml, m);
|
||||
x = m.mk_const(symbol("x"), a.mk_int());
|
||||
app* vars[1] = { x.get() };
|
||||
front_end_params fparams;
|
||||
qe::expr_quant_elim qelim(m, fparams);
|
||||
lbool result = qelim.first_elim(1, vars, fml, defs);
|
||||
std::cout << mk_pp(_fml, m) << "\n--->\n";
|
||||
std::cout << mk_pp(fml, m) << "\n";
|
||||
for (unsigned i = 0; i < defs.size(); ++i) {
|
||||
std::cout << defs.var(i)->get_name() << " "
|
||||
<< mk_pp(defs.def(i), m) << "\n";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
static void test_defs_all(ast_manager& m, expr* _fml) {
|
||||
arith_util a(m);
|
||||
app_ref x(m);
|
||||
expr_ref fml(_fml, m), fml0(_fml, m);
|
||||
x = m.mk_const(symbol("x"), a.mk_int());
|
||||
app* vars[1] = { x.get() };
|
||||
front_end_params fparams;
|
||||
qe::expr_quant_elim qelim(m, fparams);
|
||||
lbool result = l_true;
|
||||
while (result == l_true) {
|
||||
fml = fml0;
|
||||
qe::def_vector defs(m);
|
||||
result = qelim.first_elim(1, vars, fml, defs);
|
||||
std::cout << result << "\n";
|
||||
std::cout << mk_pp(fml, m) << "\n";
|
||||
for (unsigned i = 0; i < defs.size(); ++i) {
|
||||
std::cout << defs.var(i)->get_name() << " "
|
||||
<< mk_pp(defs.def(i), m) << "\n";
|
||||
}
|
||||
fml0 = m.mk_and(fml0, m.mk_not(fml));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_defs(char const* str) {
|
||||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
scoped_ptr<smtlib::parser> parser = smtlib::parser::create(m);
|
||||
parser->initialize_smtlib();
|
||||
std::ostringstream buffer;
|
||||
buffer << "(benchmark presburger :status unknown :logic AUFLIA "
|
||||
<< ":extrafuns ((x Int) (y Int) (z Int))\n"
|
||||
<< ":formula " << str << ")";
|
||||
parser->parse_string(buffer.str().c_str());
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
smtlib::theory::expr_iterator it = b->begin_formulas();
|
||||
smtlib::theory::expr_iterator end = b->end_formulas();
|
||||
for (; it != end; ++it) {
|
||||
test_defs(m, *it);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qe_defs() {
|
||||
enable_trace("qe");
|
||||
test_defs("(and (<= (* 2 x) y) (>= (* 3 x) z) (<= (* 4 x) (* 2 z)) (= (mod x 2) 0))");
|
||||
|
||||
return;
|
||||
test_defs("(and (<= (* 2 x) y) (>= (* 3 x) z) (= (mod x 2) 0))");
|
||||
test_defs("(and (<= (* 2 x) y) (= (mod x 2) 0))");
|
||||
test_defs("(= (* 2 x) y)");
|
||||
test_defs("(or (< x 0) (> x 1))");
|
||||
test_defs("(or (< x y) (> x y))");
|
||||
test_defs("(= x y)");
|
||||
test_defs("(<= x y)");
|
||||
test_defs("(>= x y)");
|
||||
test_defs("(and (<= (+ x y) 0) (<= (+ x z) 0))");
|
||||
test_defs("(and (<= (+ x y) 0) (<= (+ (* 2 x) z) 0))");
|
||||
test_defs("(and (<= (+ (* 3 x) y) 0) (<= (+ (* 2 x) z) 0))");
|
||||
test_defs("(and (>= x y) (>= x z))");
|
||||
test_defs("(< x y)");
|
||||
test_defs("(> x y)");
|
||||
}
|
|
@ -8,39 +8,85 @@
|
|||
#include "expr_replacer.h"
|
||||
#include "smt_solver.h"
|
||||
#include "reg_decl_plugins.h"
|
||||
#include "expr_abstract.h"
|
||||
#include "model_smt2_pp.h"
|
||||
#include "smt2parser.h"
|
||||
#include "var_subst.h"
|
||||
|
||||
static void validate_quant_solution(ast_manager& m, app* x, expr* fml, expr* t, expr* new_fml) {
|
||||
static void validate_quant_solution(ast_manager& m, expr* fml, expr* guard, qe::def_vector const& defs) {
|
||||
// verify:
|
||||
// new_fml <=> fml[t/x]
|
||||
// new_fml => fml[t/x]
|
||||
scoped_ptr<expr_replacer> rep = mk_expr_simp_replacer(m);
|
||||
app_ref_vector xs(m);
|
||||
expr_substitution sub(m);
|
||||
sub.insert(x, t);
|
||||
for (unsigned i = 0; i < defs.size(); ++i) {
|
||||
xs.push_back(m.mk_const(defs.var(i)));
|
||||
sub.insert(xs.back(), defs.def(i));
|
||||
}
|
||||
rep->set_substitution(&sub);
|
||||
expr_ref fml1(fml, m);
|
||||
(*rep)(fml1);
|
||||
expr_ref tmp(m);
|
||||
tmp = m.mk_not(m.mk_iff(new_fml, fml1));
|
||||
tmp = m.mk_not(m.mk_implies(guard, fml1));
|
||||
front_end_params fp;
|
||||
smt::solver solver(m, fp);
|
||||
solver.assert_expr(tmp);
|
||||
lbool res = solver.check();
|
||||
std::cout << res << "\n";
|
||||
//SASSERT(res == l_false);
|
||||
if (res != l_false) {
|
||||
std::cout << "Validation failed: " << res << "\n";
|
||||
std::cout << mk_pp(tmp, m) << "\n";
|
||||
model_ref model;
|
||||
solver.get_model(model);
|
||||
model_smt2_pp(std::cout, m, *model, 0);
|
||||
fatal_error(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void validate_quant_solutions(app* x, expr* fml, expr_ref_vector& guards) {
|
||||
return;
|
||||
// quant_elim option got removed...
|
||||
// verify:
|
||||
// fml <=> guard_1 \/ guard_2 \/ ...
|
||||
ast_manager& m = guards.get_manager();
|
||||
expr_ref tmp(m), fml2(m);
|
||||
tmp = m.mk_or(guards.size(), guards.c_ptr());
|
||||
expr* _x = x;
|
||||
std::cout << mk_pp(fml, m) << "\n";
|
||||
expr_abstract(m, 0, 1, &_x, fml, fml2);
|
||||
std::cout << mk_pp(fml2, m) << "\n";
|
||||
symbol name(x->get_decl()->get_name());
|
||||
sort* s = m.get_sort(x);
|
||||
fml2 = m.mk_exists(1, &s, &name, fml2);
|
||||
std::cout << mk_pp(fml2, m) << "\n";
|
||||
tmp = m.mk_not(m.mk_iff(fml2, tmp));
|
||||
std::cout << mk_pp(tmp, m) << "\n";
|
||||
front_end_params fp;
|
||||
smt::solver solver(m, fp);
|
||||
solver.assert_expr(tmp);
|
||||
lbool res = solver.check();
|
||||
std::cout << "checked\n";
|
||||
SASSERT(res == l_false);
|
||||
if (res != l_false) {
|
||||
std::cout << res << "\n";
|
||||
fatal_error(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_quant_solver(ast_manager& m, app* x, expr* fml) {
|
||||
|
||||
|
||||
static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, expr* fml) {
|
||||
front_end_params params;
|
||||
params.m_quant_elim = true;
|
||||
qe::expr_quant_elim qe(m, params);
|
||||
expr_ref_vector terms(m);
|
||||
expr_ref_vector fmls(m);
|
||||
bool success = qe.solve_for_var(x, fml, terms, fmls);
|
||||
qe::guarded_defs defs(m);
|
||||
bool success = qe.solve_for_vars(sz, xs, fml, defs);
|
||||
std::cout << "------------------------\n";
|
||||
std::cout << mk_pp(fml, m) << "\n";
|
||||
if (success) {
|
||||
for (unsigned i = 0; i < terms.size(); ++i) {
|
||||
std::cout << mk_pp(x, m) << " = " << mk_pp(terms[i].get(), m) << "\n" << mk_pp(fmls[i].get(), m) << "\n";
|
||||
validate_quant_solution(m, x, fml, terms[i].get(), fmls[i].get());
|
||||
if (success) {
|
||||
defs.display(std::cout);
|
||||
for (unsigned i = 0; i < defs.size(); ++i) {
|
||||
validate_quant_solution(m, fml, defs.guard(i), defs.defs(i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -48,99 +94,136 @@ static void test_quant_solver(ast_manager& m, app* x, expr* fml) {
|
|||
}
|
||||
}
|
||||
|
||||
static void test_quant_solver_rec(ast_manager& m, unsigned num_vars, app* const* xs, expr* fml) {
|
||||
if (num_vars == 0) {
|
||||
return;
|
||||
}
|
||||
front_end_params params;
|
||||
params.m_quant_elim = true;
|
||||
qe::expr_quant_elim qe(m, params);
|
||||
expr_ref_vector fmls(m), ors(m), terms(m);
|
||||
app* x = xs[0];
|
||||
bool success = qe.solve_for_var(x, fml, terms, fmls);
|
||||
std::cout << "------------------------\n";
|
||||
std::cout << mk_pp(fml, m) << "\n";
|
||||
if (success) {
|
||||
for (unsigned i = 0; i < terms.size(); ++i) {
|
||||
std::cout << mk_pp(x, m) << " = " << mk_pp(terms[i].get(), m) << "\n" << mk_pp(fmls[i].get(), m) << "\n";
|
||||
validate_quant_solution(m, x, fml, terms[i].get(), fmls[i].get());
|
||||
ors.reset();
|
||||
if (m.is_or(fmls[i].get())) {
|
||||
ors.append(to_app(fmls[i].get())->get_num_args(), to_app(fmls[i].get())->get_args());
|
||||
}
|
||||
else {
|
||||
ors.push_back(fmls[i].get());
|
||||
}
|
||||
for (unsigned j = 0; j < ors.size(); ++j) {
|
||||
test_quant_solver_rec(m, num_vars-1, xs+1, ors[j].get());
|
||||
}
|
||||
static expr_ref parse_fml(ast_manager& m, char const* str) {
|
||||
expr_ref result(m);
|
||||
front_end_params fp;
|
||||
cmd_context ctx(fp, false, &m);
|
||||
ctx.set_ignore_check(true);
|
||||
std::ostringstream buffer;
|
||||
buffer << "(declare-const x Int)\n"
|
||||
<< "(declare-const y Int)\n"
|
||||
<< "(declare-const z Int)\n"
|
||||
<< "(declare-const a Int)\n"
|
||||
<< "(declare-const b Int)\n"
|
||||
<< "(declare-datatypes () ((IList (nil) (cons (car Int) (cdr IList)))))\n"
|
||||
<< "(declare-const l1 IList)\n"
|
||||
<< "(declare-const l2 IList)\n"
|
||||
<< "(declare-datatypes () ((Cell (null) (cell (car Cell) (cdr Cell)))))\n"
|
||||
<< "(declare-const c1 Cell)\n"
|
||||
<< "(declare-const c2 Cell)\n"
|
||||
<< "(declare-const c3 Cell)\n"
|
||||
<< "(declare-datatypes () ((Tuple (tuple (first Int) (second Bool) (third Real)))))\n"
|
||||
<< "(declare-const t1 Tuple)\n"
|
||||
<< "(declare-const t2 Tuple)\n"
|
||||
<< "(declare-const t3 Tuple)\n"
|
||||
<< "(assert " << str << ")\n";
|
||||
std::istringstream is(buffer.str());
|
||||
VERIFY(parse_smt2_commands(ctx, is));
|
||||
SASSERT(ctx.begin_assertions() != ctx.end_assertions());
|
||||
result = *ctx.begin_assertions();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void parse_fml(char const* str, app_ref_vector& vars, expr_ref& fml) {
|
||||
ast_manager& m = fml.get_manager();
|
||||
fml = parse_fml(m, str);
|
||||
if (is_exists(fml)) {
|
||||
quantifier* q = to_quantifier(fml);
|
||||
for (unsigned i = 0; i < q->get_num_decls(); ++i) {
|
||||
vars.push_back(m.mk_const(q->get_decl_name(i), q->get_decl_sort(i)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "failed\n";
|
||||
fml = q->get_expr();
|
||||
var_subst vs(m, true);
|
||||
vs(fml, vars.size(), (expr*const*)vars.c_ptr(), fml);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_quant_solver(ast_manager& m, app* x, char const* str) {
|
||||
expr_ref fml = parse_fml(m, str);
|
||||
test_quant_solver(m, 1, &x, fml);
|
||||
}
|
||||
|
||||
static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, char const* str) {
|
||||
expr_ref fml = parse_fml(m, str);
|
||||
test_quant_solver(m, sz, xs, fml);
|
||||
}
|
||||
|
||||
static void test_quant_solver(ast_manager& m, char const* str) {
|
||||
expr_ref fml(m);
|
||||
app_ref_vector vars(m);
|
||||
parse_fml(str, vars, fml);
|
||||
test_quant_solver(m, vars.size(), vars.c_ptr(), fml);
|
||||
}
|
||||
|
||||
|
||||
static void test_quant_solve1() {
|
||||
ast_manager m;
|
||||
arith_util ar(m);
|
||||
|
||||
reg_decl_plugins(m);
|
||||
sort* i = ar.mk_int();
|
||||
app_ref x(m.mk_const(symbol("x"),i), m);
|
||||
app_ref y(m.mk_const(symbol("y"),i), m);
|
||||
app_ref a(m.mk_const(symbol("a"),i), m);
|
||||
app_ref b(m.mk_const(symbol("b"),i), m);
|
||||
expr_ref n2(ar.mk_numeral(rational(2), true), m);
|
||||
expr_ref n3(ar.mk_numeral(rational(3), true), m);
|
||||
expr_ref n4(ar.mk_numeral(rational(4), true), m);
|
||||
expr_ref n10(ar.mk_numeral(rational(10), true), m);
|
||||
expr_ref n20(ar.mk_numeral(rational(20), true), m);
|
||||
expr_ref x2(ar.mk_mul(n2, x), m);
|
||||
expr_ref x3(ar.mk_mul(n3, x), m);
|
||||
expr_ref fml1(m), fml2(m), fml3(m), fml4(m);
|
||||
expr_ref fml(m), t1(m), t2(m);
|
||||
|
||||
fml1 = m.mk_eq(x, a);
|
||||
fml2 = ar.mk_lt(x, a);
|
||||
fml3 = ar.mk_gt(x, a);
|
||||
fml4 = m.mk_and(ar.mk_lt(x, a), ar.mk_lt(x, b));
|
||||
expr_ref fml5(m.mk_and(ar.mk_gt(x, a), ar.mk_lt(x, b)), m);
|
||||
expr_ref fml6(ar.mk_le(x, a), m);
|
||||
expr_ref fml7(ar.mk_ge(x, a), m);
|
||||
expr_ref fml8(ar.mk_lt(ar.mk_mul(n2, x), a), m);
|
||||
expr_ref fml9(m.mk_eq(ar.mk_mul(n2, x), a), m);
|
||||
|
||||
test_quant_solver(m, x.get(), fml1.get());
|
||||
test_quant_solver(m, x.get(), fml2.get());
|
||||
test_quant_solver(m, x.get(), fml3.get());
|
||||
test_quant_solver(m, x.get(), fml4.get());
|
||||
test_quant_solver(m, x.get(), fml5.get());
|
||||
test_quant_solver(m, x.get(), fml6.get());
|
||||
test_quant_solver(m, x.get(), fml7.get());
|
||||
test_quant_solver(m, x.get(), fml8.get());
|
||||
test_quant_solver(m, x.get(), fml9.get());
|
||||
|
||||
fml = ar.mk_lt(x2, a); test_quant_solver(m, x.get(), fml.get());
|
||||
fml = ar.mk_gt(x2, a); test_quant_solver(m, x.get(), fml.get());
|
||||
fml = ar.mk_le(x2, a); test_quant_solver(m, x.get(), fml.get());
|
||||
fml = ar.mk_ge(x2, a); test_quant_solver(m, x.get(), fml.get());
|
||||
app_ref xr(m.mk_const(symbol("x"),i), m);
|
||||
app_ref yr(m.mk_const(symbol("y"),i), m);
|
||||
app* x = xr.get();
|
||||
app* y = yr.get();
|
||||
app* xy[2] = { x, y };
|
||||
|
||||
|
||||
fml = m.mk_and(ar.mk_lt(a, ar.mk_mul(n3,x)), ar.mk_lt(ar.mk_mul(n3,x), b));
|
||||
test_quant_solver(m, x.get(), fml.get());
|
||||
test_quant_solver(m, x, "(and (<= x y) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(and (<= (* 2 x) y) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(and (>= x y) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(and (>= (* 2 x) y) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(and (<= (* 2 x) y) (>= x z) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(and (<= (* 2 x) y) (>= (* 3 x) z) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(>= (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(<= (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(< (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(= (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(< (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(> (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(and (<= a x) (<= (* 2 x) b))");
|
||||
test_quant_solver(m, x, "(and (<= a x) (<= x b))");
|
||||
test_quant_solver(m, x, "(and (<= (* 2 a) x) (<= x b))");
|
||||
test_quant_solver(m, x, "(and (<= (* 2 a) x) (<= (* 2 x) b))");
|
||||
test_quant_solver(m, x, "(and (<= a x) (<= (* 3 x) b))");
|
||||
test_quant_solver(m, x, "(and (<= (* 3 a) x) (<= x b))");
|
||||
test_quant_solver(m, x, "(and (<= (* 3 a) x) (<= (* 3 x) b))");
|
||||
test_quant_solver(m, x, "(and (< a (* 3 x)) (< (* 3 x) b))");
|
||||
test_quant_solver(m, x, "(< (* 3 x) a)");
|
||||
test_quant_solver(m, x, "(= (* 3 x) a)");
|
||||
test_quant_solver(m, x, "(< (* 3 x) a)");
|
||||
test_quant_solver(m, x, "(> (* 3 x) a)");
|
||||
test_quant_solver(m, x, "(<= (* 3 x) a)");
|
||||
test_quant_solver(m, x, "(>= (* 3 x) a)");
|
||||
test_quant_solver(m, x, "(<= (* 2 x) a)");
|
||||
test_quant_solver(m, x, "(or (= (* 2 x) y) (= (+ (* 2 x) 1) y))");
|
||||
test_quant_solver(m, x, "(= x a)");
|
||||
test_quant_solver(m, x, "(< x a)");
|
||||
test_quant_solver(m, x, "(> x a)");
|
||||
test_quant_solver(m, x, "(and (> x a) (< x b))");
|
||||
test_quant_solver(m, x, "(and (> x a) (< x b))");
|
||||
test_quant_solver(m, x, "(<= x a)");
|
||||
test_quant_solver(m, x, "(>= x a)");
|
||||
test_quant_solver(m, x, "(and (<= (* 2 x) y) (= (mod x 2) 0))");
|
||||
test_quant_solver(m, x, "(= (* 2 x) y)");
|
||||
test_quant_solver(m, x, "(or (< x 0) (> x 1))");
|
||||
test_quant_solver(m, x, "(or (< x y) (> x y))");
|
||||
test_quant_solver(m, x, "(= x y)");
|
||||
test_quant_solver(m, x, "(<= x y)");
|
||||
test_quant_solver(m, x, "(>= x y)");
|
||||
test_quant_solver(m, x, "(and (<= (+ x y) 0) (<= (+ x z) 0))");
|
||||
test_quant_solver(m, x, "(and (<= (+ x y) 0) (<= (+ (* 2 x) z) 0))");
|
||||
test_quant_solver(m, x, "(and (<= (+ (* 3 x) y) 0) (<= (+ (* 2 x) z) 0))");
|
||||
test_quant_solver(m, x, "(and (>= x y) (>= x z))");
|
||||
test_quant_solver(m, x, "(< x y)");
|
||||
test_quant_solver(m, x, "(> x y)");
|
||||
test_quant_solver(m, 2, xy, "(and (<= (- (* 2 y) b) (+ (* 3 x) a)) (<= (- (* 2 x) a) (+ (* 4 y) b)))");
|
||||
|
||||
t1 = ar.mk_sub(ar.mk_mul(n2,y),b);
|
||||
t2 = ar.mk_add(ar.mk_mul(n3,x),a);
|
||||
fml1 = ar.mk_le(t1, t2);
|
||||
t1 = ar.mk_sub(ar.mk_mul(n2,x),a);
|
||||
t2 = ar.mk_add(ar.mk_mul(n4,y),b);
|
||||
fml2 = ar.mk_le(t1,t2);
|
||||
fml = m.mk_and(fml1, fml2);
|
||||
app* xy[2] = { x.get(), y.get() };
|
||||
test_quant_solver_rec(m, 2, xy, fml.get());
|
||||
test_quant_solver(m, "(exists ((c Cell)) (= c null))");
|
||||
test_quant_solver(m, "(exists ((c Cell)) (= c (cell null c1)))");
|
||||
//TBD:
|
||||
//test_quant_solver(m, "(exists ((c Cell)) (= (cell c c) c1))");
|
||||
//test_quant_solver(m, "(exists ((c Cell)) (not (= c null)))");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
#ifdef _WINDOWS
|
||||
#include <iostream>
|
||||
#include <strstream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "smtparser.h"
|
||||
#include "for_each_file.h"
|
||||
#include "array_decl_plugin.h"
|
||||
#include "bv_decl_plugin.h"
|
||||
#include "reg_decl_plugins.h"
|
||||
|
||||
class for_each_file_smt : public for_each_file_proc {
|
||||
public:
|
||||
for_each_file_smt() {}
|
||||
|
||||
bool operator()(char const * file_path) {
|
||||
bool result = true;
|
||||
std::cout << "Parsing: " << file_path << std::endl;
|
||||
|
||||
ast_manager ast_manager;
|
||||
smtlib::parser* parser = smtlib::parser::create(ast_manager);
|
||||
reg_decl_plugins(ast_manager);
|
||||
|
||||
parser->initialize_smtlib();
|
||||
|
||||
if (!parser->parse_file(file_path)) {
|
||||
std::cout << "Could not parse file : " << file_path << std::endl;
|
||||
result = false;
|
||||
}
|
||||
dealloc(parser);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static bool test_directory(char const * base) {
|
||||
for_each_file_smt foreach;
|
||||
return for_each_file(foreach, base, "*.smt");
|
||||
}
|
||||
|
||||
void tst_smtparser(char** argv, int argc, int & i) {
|
||||
bool result = true;
|
||||
if (i + 1 < argc) {
|
||||
result = test_directory(argv[i+1]);
|
||||
i += 1;
|
||||
}
|
||||
SASSERT(result);
|
||||
}
|
||||
#else
|
||||
void tst_smtparser(char** argv, int argc, int & i) {
|
||||
}
|
||||
#endif
|
|
@ -17,7 +17,6 @@ Revision History:
|
|||
|
||||
--*/
|
||||
#include"var_subst.h"
|
||||
#include"smtparser.h"
|
||||
#include"ast_pp.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
|
@ -104,22 +103,4 @@ void tst_var_subst() {
|
|||
ast_manager m;
|
||||
reg_decl_plugins(m);
|
||||
tst_subst(m);
|
||||
|
||||
scoped_ptr<smtlib::parser> parser = smtlib::parser::create(m);
|
||||
parser->initialize_smtlib();
|
||||
|
||||
parser->parse_string(
|
||||
"(benchmark samples :logic AUFLIA\n"
|
||||
" :extrafuns ((f Int Int) (g Int Int Int) (a Int) (b Int))\n"
|
||||
" :formula (forall (x Int) (or (= (f x) x) (forall (y Int) (z Int) (= (g x y) (f z)))))\n"
|
||||
" :formula (forall (x Int) (w Int) (or (= (f x) x) (forall (y Int) (z Int) (or (= (g x y) (g w z)) (forall (x1 Int) (= (f x1) (g x y)))))))\n"
|
||||
")"
|
||||
);
|
||||
|
||||
smtlib::benchmark* b = parser->get_benchmark();
|
||||
|
||||
smtlib::theory::expr_iterator it = b->begin_formulas();
|
||||
smtlib::theory::expr_iterator end = b->end_formulas();
|
||||
for (; it != end; ++it)
|
||||
tst_instantiate(m, *it);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ protected:
|
|||
\brief Return true if the given key \c k is in the entry \c e. That is,
|
||||
k \in [e.begin_key(), e.end_key()].
|
||||
*/
|
||||
bool contains(entry const & e, key const & k) const { return leq(e.begin_key(), k) && leq(k, e.end_key()); }
|
||||
bool contains(entry const & e, key const & k) const { return this->leq(e.begin_key(), k) && this->leq(k, e.end_key()); }
|
||||
|
||||
/**
|
||||
\brief Return true if the given key \c k is in the entry \c e. That is,
|
||||
|
@ -193,7 +193,7 @@ protected:
|
|||
for (;;) {
|
||||
int mid = low + ((high - low) / 2);
|
||||
entry const & mid_entry = bt->get(mid);
|
||||
if (gt(k, mid_entry.end_key())) {
|
||||
if (this->gt(k, mid_entry.end_key())) {
|
||||
low = mid + 1;
|
||||
if (low > high) {
|
||||
idx = static_cast<unsigned>(mid) + 1;
|
||||
|
@ -277,7 +277,7 @@ protected:
|
|||
|
||||
// the search_key must be in the current bucket, or in the first entry of the next bucket (if the next bucket is not 0).
|
||||
SASSERT(curr->empty() || lt(first_key(curr), k));
|
||||
SASSERT(next == 0 || geq(first_key(next), k));
|
||||
SASSERT(next == 0 || this->geq(first_key(next), k));
|
||||
DEBUG_CODE({
|
||||
if (UpdatePredVect && next != 0)
|
||||
for (unsigned i = 0; i < next->level(); i++)
|
||||
|
@ -318,7 +318,7 @@ protected:
|
|||
\brief Return true if the two entries (that satisfy lt(e1, e2)) can be merged.
|
||||
*/
|
||||
bool can_be_merged(entry const & e1, entry const & e2) const {
|
||||
return val_eq(e1.val(), e2.val()) && eq(succ(e1.end_key()), e2.begin_key());
|
||||
return this->val_eq(e1.val(), e2.val()) && this->eq(this->succ(e1.end_key()), e2.begin_key());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,16 +327,16 @@ protected:
|
|||
\remark pred_vect contains the predecessors of the successor of bt.
|
||||
*/
|
||||
void merge_first_of_succ_if_possible(manager & m, bucket * bt, bucket * pred_vect[]) {
|
||||
SASSERT(check_pred_vect(bt->get_next(0), pred_vect));
|
||||
SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect));
|
||||
bucket * next_bucket = bt->get_next(0);
|
||||
if (next_bucket != 0) {
|
||||
entry & curr_entry = bt->last_entry();
|
||||
entry & next_entry = next_bucket->get(0);
|
||||
if (can_be_merged(curr_entry, next_entry)) {
|
||||
curr_entry.set_end_key(next_entry.end_key());
|
||||
del_entry(m, next_bucket, 0); // del_entry invokes dec_ref_eh
|
||||
this->del_entry(m, next_bucket, 0); // del_entry invokes dec_ref_eh
|
||||
if (next_bucket->empty())
|
||||
del_bucket(m, next_bucket, pred_vect);
|
||||
this->del_bucket(m, next_bucket, pred_vect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ protected:
|
|||
entry & next_entry = bt->get(idx+1);
|
||||
if (can_be_merged(curr_entry, next_entry)) {
|
||||
curr_entry.set_end_key(next_entry.end_key());
|
||||
del_entry(m, bt, idx+1); // del_entry invokes dec_ref_eh
|
||||
this->del_entry(m, bt, idx+1); // del_entry invokes dec_ref_eh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ protected:
|
|||
entry & prev_entry = bt->get(idx-1);
|
||||
if (can_be_merged(prev_entry, curr_entry)) {
|
||||
prev_entry.set_end_key(curr_entry.end_key());
|
||||
del_entry(m, bt, idx); // del_entry invokes dec_ref_eh
|
||||
this->del_entry(m, bt, idx); // del_entry invokes dec_ref_eh
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,7 +439,7 @@ protected:
|
|||
int mid = low + ((high - low) / 2);
|
||||
SASSERT(mid < static_cast<int>(bt->size()));
|
||||
entry & mid_entry = bt->get(mid);
|
||||
if (gt(k, mid_entry.end_key())) {
|
||||
if (this->gt(k, mid_entry.end_key())) {
|
||||
low = mid + 1;
|
||||
if (low > high) {
|
||||
// mid entry must be deleted since k > mid_entry.end_key().
|
||||
|
@ -461,7 +461,7 @@ protected:
|
|||
SASSERT(contains(mid_entry, k));
|
||||
if (lt(k, mid_entry.end_key())) {
|
||||
TRACE("del_entries_upto_bug", tout << "exit 3) mid: " << mid << "\n"; this->display(tout, mid_entry); tout << "\n";);
|
||||
mid_entry.set_begin_key(succ(k));
|
||||
mid_entry.set_begin_key(this->succ(k));
|
||||
SASSERT(mid < static_cast<int>(bt->size())); // Reason: loop invariant
|
||||
return del_entries<RECYCLE_ENTRY>(m, bt, s_idx, mid);
|
||||
}
|
||||
|
@ -479,21 +479,21 @@ protected:
|
|||
\brief Keep deleting keys <= k in bt and its successors.
|
||||
*/
|
||||
void del_entries_upto_loop(manager & m, bucket * bt, key const & k, bucket * pred_vect []) {
|
||||
SASSERT(check_pred_vect(bt, pred_vect));
|
||||
SASSERT(this->check_pred_vect(bt, pred_vect));
|
||||
while (bt != 0) {
|
||||
key const & bt_last_key = last_key(bt);
|
||||
if (lt(k, bt_last_key)) {
|
||||
del_last_entries_upto<false>(m, bt, 0, k);
|
||||
return;
|
||||
}
|
||||
else if (eq(k, bt_last_key)) {
|
||||
del_bucket(m, bt, pred_vect);
|
||||
else if (this->eq(k, bt_last_key)) {
|
||||
this->del_bucket(m, bt, pred_vect);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
SASSERT(gt(k, bt_last_key));
|
||||
SASSERT(this->gt(k, bt_last_key));
|
||||
bucket * next = bt->get_next(0);
|
||||
del_bucket(m, bt, pred_vect);
|
||||
this->del_bucket(m, bt, pred_vect);
|
||||
bt = next;
|
||||
// continue deleting...
|
||||
}
|
||||
|
@ -516,7 +516,7 @@ protected:
|
|||
*/
|
||||
template<bool INSERT>
|
||||
bool del_entries_upto(manager & m, bucket * bt, key const & k, bucket * pred_vect[], bucket * next_pred_vect[]) {
|
||||
SASSERT(check_pred_vect(bt, pred_vect)); // pred_vect contains the predecessors of bt.
|
||||
SASSERT(this->check_pred_vect(bt, pred_vect)); // pred_vect contains the predecessors of bt.
|
||||
if (lt(k, first_key(bt))) {
|
||||
// nothing to be done...
|
||||
return false; // didn't manage to recycle entry.
|
||||
|
@ -524,7 +524,7 @@ protected:
|
|||
|
||||
key const & bt_last_key = last_key(bt);
|
||||
TRACE("del_entries_upto_bug", tout << "bt_last_key: " << bt_last_key << "\n";);
|
||||
if (lt(k, bt_last_key)) {
|
||||
if (this->lt(k, bt_last_key)) {
|
||||
return del_last_entries_upto<INSERT>(m, bt, 0, k);
|
||||
}
|
||||
else {
|
||||
|
@ -533,10 +533,10 @@ protected:
|
|||
this->dec_ref(m, bt);
|
||||
// REMARK: the slot 0 will be reused, but the element there is gone.
|
||||
bt->set_size(1);
|
||||
if (gt(k, bt_last_key)) {
|
||||
if (this->gt(k, bt_last_key)) {
|
||||
bucket * next = bt->get_next(0);
|
||||
if (next != 0) {
|
||||
update_predecessor_vector(pred_vect, bt, next_pred_vect);
|
||||
this->update_predecessor_vector(pred_vect, bt, next_pred_vect);
|
||||
del_entries_upto_loop(m, next, k, next_pred_vect);
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ protected:
|
|||
}
|
||||
else {
|
||||
bucket * next = bt->get_next(0);
|
||||
del_bucket(m, bt, pred_vect); // it will invoke dec_ref_eh for all values in bt.
|
||||
this->del_bucket(m, bt, pred_vect); // it will invoke dec_ref_eh for all values in bt.
|
||||
// pred_vect does not need to be updated since it contains the predecessors of
|
||||
// bt, since bt was deleted they are now the predecessors of its successor.
|
||||
if (next != 0) {
|
||||
|
@ -566,7 +566,7 @@ protected:
|
|||
*/
|
||||
template<bool INSERT>
|
||||
bool del_entries_upto(manager & m, bucket * bt, unsigned s_idx, key const & k, bucket * pred_vect[]) {
|
||||
SASSERT(check_pred_vect(bt->get_next(0), pred_vect)); // pred_vect contains the predecessors of the successor of bt.
|
||||
SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect)); // pred_vect contains the predecessors of the successor of bt.
|
||||
SASSERT(s_idx > 0);
|
||||
TRACE("del_entries_upto_bug",
|
||||
tout << "INSERT: " << INSERT << "\n";
|
||||
|
@ -592,7 +592,7 @@ protected:
|
|||
return del_last_entries_upto<INSERT>(m, bt, s_idx, k);
|
||||
}
|
||||
else {
|
||||
if (gt(k, bt_last_key)) {
|
||||
if (this->gt(k, bt_last_key)) {
|
||||
del_entries_upto_loop(m, bt->get_next(0), k, pred_vect);
|
||||
}
|
||||
if (Traits::ref_count) {
|
||||
|
@ -619,10 +619,10 @@ protected:
|
|||
*/
|
||||
void insert_begin(manager & m, bucket * bt, key const & b, key const & e, value const & v, bucket * pred_vect[]) {
|
||||
TRACE("interval_skip_list_bug", tout << "insert_begin: [" << b << ", " << e << "] -> " << v << "\n"; this->display(tout, bt););
|
||||
SASSERT(check_pred_vect(bt, pred_vect));
|
||||
SASSERT(this->check_pred_vect(bt, pred_vect));
|
||||
SASSERT(!bt->empty());
|
||||
SASSERT(bt->size() <= bt->capacity());
|
||||
SASSERT(leq(b, first_key(bt)));
|
||||
SASSERT(this->leq(b, first_key(bt)));
|
||||
bucket * next_pred_vect[Traits::max_level];
|
||||
next_pred_vect[0] = 0;
|
||||
|
||||
|
@ -639,14 +639,14 @@ protected:
|
|||
merge_next_if_possible(m, bt, 0, next_pred_vect);
|
||||
}
|
||||
else {
|
||||
update_predecessor_vector(pred_vect, bt);
|
||||
this->update_predecessor_vector(pred_vect, bt);
|
||||
merge_next_if_possible(m, bt, 0, pred_vect);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// check if can merge with first entry in the bucket.
|
||||
entry & fe = bt->first_entry();
|
||||
if (val_eq(fe.val(), v) && eq(fe.begin_key(), succ(e))) {
|
||||
if (this->val_eq(fe.val(), v) && this->eq(fe.begin_key(), this->succ(e))) {
|
||||
// can merge
|
||||
fe.set_begin_key(b);
|
||||
// A new reference to v was not created. So, we must invoke dec_ref_eh since we increased the counter above.
|
||||
|
@ -657,15 +657,15 @@ protected:
|
|||
if (bt->size() == bt->capacity()) {
|
||||
if (bt->capacity() < Traits::max_capacity) {
|
||||
SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0);
|
||||
expand_first_bucket(m);
|
||||
this->expand_first_bucket(m);
|
||||
bt = this->first_bucket();
|
||||
}
|
||||
else {
|
||||
// there is no space
|
||||
splice(m, bt, pred_vect);
|
||||
this->splice(m, bt, pred_vect);
|
||||
}
|
||||
}
|
||||
open_space(bt, 0);
|
||||
this->open_space(bt, 0);
|
||||
set_entry(bt, 0, b, e, v); // Reference to v was stored, and inc_ref_eh was invoked above.
|
||||
SASSERT(!can_be_merged(bt->get(0), bt->get(1)));
|
||||
}
|
||||
|
@ -675,7 +675,7 @@ protected:
|
|||
*/
|
||||
void insert_at(manager & m, bucket * bt, unsigned idx, key const & b, key const & e, value const & v, bucket * pred_vect[]) {
|
||||
SASSERT(idx > 0);
|
||||
SASSERT(check_pred_vect(bt->get_next(0), pred_vect));
|
||||
SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect));
|
||||
|
||||
this->inc_ref(m, v);
|
||||
TRACE("insert_at_bug", tout << "before del_entries_upto:\n"; this->display_physical(tout););
|
||||
|
@ -697,17 +697,17 @@ protected:
|
|||
// there is no space
|
||||
if (bt->capacity() < Traits::max_capacity) {
|
||||
SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0);
|
||||
expand_first_bucket(m);
|
||||
this->expand_first_bucket(m);
|
||||
bt = this->first_bucket();
|
||||
// there is no need to update pred_vect, since the list contains only one bucket.
|
||||
}
|
||||
else {
|
||||
splice(m, bt, pred_vect);
|
||||
this->splice(m, bt, pred_vect);
|
||||
bucket * new_next = bt->get_next(0);
|
||||
SASSERT(bt->size() == bt->capacity()/2);
|
||||
if (idx == bt->capacity()/2) {
|
||||
entry & bt_last_entry = bt->last_entry();
|
||||
if (val_eq(bt_last_entry.val(), v) && eq(bt_last_entry.end_key(), pred(b))) {
|
||||
if (this->val_eq(bt_last_entry.val(), v) && this->eq(bt_last_entry.end_key(), this->pred(b))) {
|
||||
// merged with the last key of bt
|
||||
bt_last_entry.set_end_key(e);
|
||||
// A new reference to v was not created. So, we must invoke dec_ref_eh since we increased the counter above.
|
||||
|
@ -715,7 +715,7 @@ protected:
|
|||
return;
|
||||
}
|
||||
entry & new_next_first_entry = new_next->first_entry();
|
||||
if (val_eq(new_next_first_entry.val(), v) && eq(new_next_first_entry.begin_key(), succ(e))) {
|
||||
if (this->val_eq(new_next_first_entry.val(), v) && this->eq(new_next_first_entry.begin_key(), this->succ(e))) {
|
||||
// merged with the first key of new_next
|
||||
new_next_first_entry.set_begin_key(b);
|
||||
// A new reference to v was not created. So, we must invoke dec_ref_eh since we increased the counter above.
|
||||
|
@ -731,12 +731,12 @@ protected:
|
|||
idx -= bt->capacity()/2;
|
||||
SASSERT(idx > 0);
|
||||
bt = new_next;
|
||||
update_predecessor_vector(pred_vect, bt);
|
||||
this->update_predecessor_vector(pred_vect, bt);
|
||||
}
|
||||
}
|
||||
}
|
||||
SASSERT(idx > 0);
|
||||
open_space(bt, idx);
|
||||
this->open_space(bt, idx);
|
||||
set_entry(bt, idx, b, e, v); // Reference to v was stored, and inc_ref_eh was invoked above.
|
||||
merge_next_if_possible(m, bt, idx, pred_vect);
|
||||
merge_prev_if_possible(m, bt, idx);
|
||||
|
@ -750,7 +750,7 @@ protected:
|
|||
*/
|
||||
void insert_inside(manager & m, bucket * bt, key const & b, key const & e, value const & v, bucket * pred_vect[]) {
|
||||
TRACE("interval_skip_list_bug", tout << "insert_inside: [" << b << ", " << e << "] -> " << v << "\n";);
|
||||
SASSERT(check_pred_vect(bt->get_next(0), pred_vect));
|
||||
SASSERT(this->check_pred_vect(bt->get_next(0), pred_vect));
|
||||
SASSERT(!bt->empty());
|
||||
SASSERT(bt->size() <= bt->capacity());
|
||||
// perform binary search to find position to insert [b, e]->v
|
||||
|
@ -759,7 +759,7 @@ protected:
|
|||
for (;;) {
|
||||
int mid = low + ((high - low) / 2);
|
||||
entry & mid_entry = bt->get(mid);
|
||||
if (gt(b, mid_entry.end_key())) {
|
||||
if (this->gt(b, mid_entry.end_key())) {
|
||||
low = mid + 1;
|
||||
if (low > high) {
|
||||
// insert after mid_entry since b > mid_entry.end_key().
|
||||
|
@ -779,8 +779,8 @@ protected:
|
|||
else {
|
||||
SASSERT(contains(mid_entry, b));
|
||||
TRACE("insert_inside_bug", tout << "insert_inside:\n"; this->display(tout, bt););
|
||||
if (val_eq(mid_entry.val(), v)) {
|
||||
if (gt(e, mid_entry.end_key())) {
|
||||
if (this->val_eq(mid_entry.val(), v)) {
|
||||
if (this->gt(e, mid_entry.end_key())) {
|
||||
// No need to create space.
|
||||
// We did not create a new reference to v.
|
||||
mid_entry.set_end_key(e);
|
||||
|
@ -790,8 +790,8 @@ protected:
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (gt(b, mid_entry.begin_key())) {
|
||||
if (lt(e, mid_entry.end_key())) {
|
||||
if (this->gt(b, mid_entry.begin_key())) {
|
||||
if (this->lt(e, mid_entry.end_key())) {
|
||||
// New interval is the middle of existing interval
|
||||
|
||||
// We must INVOKE add_ref_eh for mid_entry.val() and v.
|
||||
|
@ -802,11 +802,11 @@ protected:
|
|||
if (bt->size() >= bt->capacity() - 1) {
|
||||
if (bt->capacity() < Traits::max_capacity) {
|
||||
SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0);
|
||||
expand_first_bucket(m);
|
||||
this->expand_first_bucket(m);
|
||||
bt = this->first_bucket();
|
||||
}
|
||||
else {
|
||||
splice(m, bt, pred_vect);
|
||||
this->splice(m, bt, pred_vect);
|
||||
int new_sz = bt->size();
|
||||
bucket * new_next = bt->get_next(0);
|
||||
if (mid >= new_sz) {
|
||||
|
@ -816,24 +816,24 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
open_2spaces(bt, mid);
|
||||
this->open_2spaces(bt, mid);
|
||||
entry & mid1_entry = bt->get(mid);
|
||||
entry & new_entry = bt->get(mid+1);
|
||||
entry & mid2_entry = bt->get(mid+2);
|
||||
mid2_entry = mid1_entry;
|
||||
mid1_entry.set_end_key(pred(b));
|
||||
mid1_entry.set_end_key(this->pred(b));
|
||||
new_entry.set_begin_key(b);
|
||||
new_entry.set_end_key(e);
|
||||
new_entry.set_val(v);
|
||||
mid2_entry.set_begin_key(succ(e));
|
||||
mid2_entry.set_begin_key(this->succ(e));
|
||||
}
|
||||
else {
|
||||
mid_entry.set_end_key(pred(b));
|
||||
mid_entry.set_end_key(this->pred(b));
|
||||
insert_at(m, bt, mid+1, b, e, v, pred_vect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SASSERT(eq(b, mid_entry.begin_key()));
|
||||
SASSERT(this->eq(b, mid_entry.begin_key()));
|
||||
SASSERT(mid > 0); // Reason: insert_begin would have been called instead.
|
||||
insert_at(m, bt, mid, b, e, v, pred_vect);
|
||||
}
|
||||
|
@ -864,7 +864,7 @@ protected:
|
|||
for (;;) {
|
||||
int mid = low + ((high - low) / 2);
|
||||
entry & mid_entry = bt->get(mid);
|
||||
if (gt(b, mid_entry.end_key())) {
|
||||
if (this->gt(b, mid_entry.end_key())) {
|
||||
low = mid + 1;
|
||||
if (low > high) {
|
||||
// insert after mid_entry since b > mid_entry.end_key().
|
||||
|
@ -872,7 +872,7 @@ protected:
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (lt(b, mid_entry.begin_key())) {
|
||||
else if (this->lt(b, mid_entry.begin_key())) {
|
||||
high = mid - 1;
|
||||
if (low > high) {
|
||||
// insert before mid_entry since b < mid_entry.begin_key().
|
||||
|
@ -883,8 +883,8 @@ protected:
|
|||
}
|
||||
else {
|
||||
SASSERT(contains(mid_entry, b));
|
||||
if (gt(b, mid_entry.begin_key())) {
|
||||
if (lt(e, mid_entry.end_key())) {
|
||||
if (this->gt(b, mid_entry.begin_key())) {
|
||||
if (this->lt(e, mid_entry.end_key())) {
|
||||
// The removed interval is inside of an existing interval.
|
||||
|
||||
// mid_entry will be split in two. So, we must invoke add_ref_eh for mid_entry.val()
|
||||
|
@ -894,12 +894,12 @@ protected:
|
|||
if (bt->size() == bt->capacity()) {
|
||||
if (bt->capacity() < Traits::max_capacity) {
|
||||
SASSERT(this->first_bucket() == bt && this->first_bucket()->get_next(0) == 0);
|
||||
expand_first_bucket(m);
|
||||
this->expand_first_bucket(m);
|
||||
bt = this->first_bucket();
|
||||
SASSERT(bt->size() < bt->capacity());
|
||||
}
|
||||
else {
|
||||
splice(m, bt, pred_vect);
|
||||
this->splice(m, bt, pred_vect);
|
||||
if (mid >= static_cast<int>(bt->size())) {
|
||||
// mid_entry moved to new (successor) bucket
|
||||
mid -= bt->size();
|
||||
|
@ -907,19 +907,19 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
open_space(bt, mid);
|
||||
this->open_space(bt, mid);
|
||||
entry & mid1_entry = bt->get(mid);
|
||||
entry & mid2_entry = bt->get(mid+1);
|
||||
mid1_entry.set_end_key(pred(b));
|
||||
mid2_entry.set_begin_key(succ(e));
|
||||
mid1_entry.set_end_key(this->pred(b));
|
||||
mid2_entry.set_begin_key(this->succ(e));
|
||||
}
|
||||
else {
|
||||
mid_entry.set_end_key(pred(b));
|
||||
mid_entry.set_end_key(this->pred(b));
|
||||
del_entries_upto<false>(m, bt, mid+1, e, pred_vect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SASSERT(eq(b, mid_entry.begin_key()));
|
||||
SASSERT(this->eq(b, mid_entry.begin_key()));
|
||||
SASSERT(mid > 0); // Reason: remove_begin would have been called instead.
|
||||
del_entries_upto<false>(m, bt, mid, e, pred_vect);
|
||||
}
|
||||
|
@ -1022,7 +1022,7 @@ private:
|
|||
SASSERT(pred_vect[i]->get_next(i) == next);
|
||||
});
|
||||
SASSERT(curr == this->m_header || lt(first_key(curr), k));
|
||||
SASSERT(next == 0 || leq(k, first_key(next)));
|
||||
SASSERT(next == 0 || this->leq(k, first_key(next)));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -1031,7 +1031,7 @@ public:
|
|||
\brief Insert the entries [i -> v] for every i \in [b, e].
|
||||
*/
|
||||
void insert(manager & m, key const & b, key const & e, value const & v) {
|
||||
SASSERT(leq(b, e));
|
||||
SASSERT(this->leq(b, e));
|
||||
if (this->empty()) {
|
||||
insert_first_entry(m, b, e, v);
|
||||
return;
|
||||
|
@ -1052,20 +1052,20 @@ public:
|
|||
SASSERT(this->first_bucket() == next);
|
||||
insert_begin(m, next, b, e, v, pred_vect);
|
||||
}
|
||||
else if (next == 0 || gt(first_key(next), b)) {
|
||||
else if (next == 0 || this->gt(first_key(next), b)) {
|
||||
insert_inside(m, curr, b, e, v, pred_vect);
|
||||
}
|
||||
else {
|
||||
SASSERT(!curr->empty());
|
||||
SASSERT(!next->empty());
|
||||
SASSERT(next != 0);
|
||||
SASSERT(eq(first_key(next), b));
|
||||
SASSERT(this->eq(first_key(next), b));
|
||||
// Bucket curr is the predecessor of next.
|
||||
SASSERT(curr->get_next(0) == next);
|
||||
|
||||
// check if we can merge with last entry of curr
|
||||
entry & curr_last_entry = curr->last_entry();
|
||||
if (val_eq(curr_last_entry.val(), v) && eq(curr_last_entry.end_key(), pred(b))) {
|
||||
if (this->val_eq(curr_last_entry.val(), v) && this->eq(curr_last_entry.end_key(), this->pred(b))) {
|
||||
// No new reference to v was create, we don't need to invok inc_ref_eh
|
||||
curr_last_entry.set_end_key(e);
|
||||
del_entries_upto<false>(m, next, e, pred_vect, 0);
|
||||
|
@ -1190,7 +1190,7 @@ public:
|
|||
\brief For each i \in [b, e] remove any entry [i->v] if it is in the list.
|
||||
*/
|
||||
void remove(manager & m, key const & b, key const & e) {
|
||||
SASSERT(leq(b, e));
|
||||
SASSERT(this->leq(b, e));
|
||||
if (this->empty())
|
||||
return;
|
||||
bucket * pred_vect[Traits::max_level];
|
||||
|
@ -1202,12 +1202,12 @@ public:
|
|||
SASSERT(next != 0);
|
||||
remove_begin(m, next, b, e, pred_vect);
|
||||
}
|
||||
else if (next == 0 || gt(first_key(next), b)) {
|
||||
else if (next == 0 || this->gt(first_key(next), b)) {
|
||||
remove_inside(m, curr, b, e, pred_vect);
|
||||
}
|
||||
else {
|
||||
SASSERT(next != 0);
|
||||
SASSERT(eq(first_key(next), b));
|
||||
SASSERT(this->eq(first_key(next), b));
|
||||
remove_begin(m, next, b, e, pred_vect);
|
||||
}
|
||||
}
|
||||
|
@ -1273,9 +1273,9 @@ public:
|
|||
--i;
|
||||
for (;;) {
|
||||
next = curr->get_next(i);
|
||||
if (next != 0 && leq(first_key(next), k)) {
|
||||
TRACE("interval_skip_list", tout << "next_bucket(" << k << "), i: " << i << " skipping #" << get_bucket_idx(curr);
|
||||
tout << ", moving to: #" << get_bucket_idx(next) << "\n"; this->display(tout, next););
|
||||
if (next != 0 && this->leq(first_key(next), k)) {
|
||||
TRACE("interval_skip_list", tout << "next_bucket(" << k << "), i: " << i << " skipping #" << this->get_bucket_idx(curr);
|
||||
tout << ", moving to: #" << this->get_bucket_idx(next) << "\n"; this->display(tout, next););
|
||||
curr = next;
|
||||
if (curr->level() > max) {
|
||||
max = curr->level();
|
||||
|
@ -1427,11 +1427,11 @@ public:
|
|||
for (; it1 != end1 && it2 != end2; it1++, it2++) {
|
||||
entry const & e1 = *it1;
|
||||
entry const & e2 = *it2;
|
||||
if (!eq(e1.begin_key(), e2.begin_key()))
|
||||
if (!this->eq(e1.begin_key(), e2.begin_key()))
|
||||
return false;
|
||||
if (!eq(e1.end_key(), e2.end_key()))
|
||||
if (!this->eq(e1.end_key(), e2.end_key()))
|
||||
return false;
|
||||
if (!val_eq(e1.val(), e2.val()))
|
||||
if (!this->val_eq(e1.val(), e2.val()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1459,8 +1459,8 @@ public:
|
|||
entry & curr = const_cast<entry&>(*it);
|
||||
value const & old_val = curr.val();
|
||||
value new_val = f(old_val);
|
||||
inc_ref(m, new_val);
|
||||
dec_ref(m, old_val);
|
||||
this->inc_ref(m, new_val);
|
||||
this->dec_ref(m, old_val);
|
||||
curr.set_val(new_val);
|
||||
}
|
||||
SASSERT(check_invariant());
|
||||
|
@ -1599,7 +1599,7 @@ private:
|
|||
*/
|
||||
void move_js(join_state & js, key const & k) const {
|
||||
SASSERT(!js.done());
|
||||
if (leq(k, js.tail())) {
|
||||
if (this->leq(k, js.tail())) {
|
||||
// We can't skip the current entry, because k in inside it.
|
||||
// So, we just update the head.
|
||||
js.m_head = k;
|
||||
|
@ -1666,7 +1666,7 @@ public:
|
|||
#ifdef Z3DEBUG
|
||||
private:
|
||||
bool check_invariant(entry const & e) const {
|
||||
SASSERT(leq(e.begin_key(), e.end_key()));
|
||||
SASSERT(this->leq(e.begin_key(), e.end_key()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1705,7 +1705,7 @@ public:
|
|||
bucket const * next = curr->get_next(i);
|
||||
if (next != 0) {
|
||||
SASSERT(next->level() >= i);
|
||||
SASSERT(i == 0 || is_reachable_at_i(curr, next, i-1));
|
||||
SASSERT(i == 0 || this->is_reachable_at_i(curr, next, i-1));
|
||||
SASSERT(!next->empty());
|
||||
entry const & last_of_curr = curr->last_entry();
|
||||
entry const & first_of_next = next->first_entry();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue