mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
Merge branch 'master' of https://github.com/z3prover/z3
This commit is contained in:
commit
15d5be66b6
|
@ -1166,6 +1166,14 @@ static void parse_example() {
|
||||||
// expr b = c.parse_string("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))");
|
// expr b = c.parse_string("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_string() {
|
||||||
|
std::cout << "parse string\n";
|
||||||
|
z3::context c;
|
||||||
|
z3::solver s(c);
|
||||||
|
s.from_string("(declare-const x Int)(assert (> x 10))");
|
||||||
|
std::cout << s.check() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
void mk_model_example() {
|
void mk_model_example() {
|
||||||
context c;
|
context c;
|
||||||
|
|
||||||
|
@ -1252,6 +1260,7 @@ int main() {
|
||||||
sudoku_example(); std::cout << "\n";
|
sudoku_example(); std::cout << "\n";
|
||||||
consequence_example(); std::cout << "\n";
|
consequence_example(); std::cout << "\n";
|
||||||
parse_example(); std::cout << "\n";
|
parse_example(); std::cout << "\n";
|
||||||
|
parse_string(); std::cout << "\n";
|
||||||
mk_model_example(); std::cout << "\n";
|
mk_model_example(); std::cout << "\n";
|
||||||
recfun_example(); std::cout << "\n";
|
recfun_example(); std::cout << "\n";
|
||||||
std::cout << "done\n";
|
std::cout << "done\n";
|
||||||
|
|
|
@ -338,26 +338,33 @@ def Z3_set_error_handler(ctx, hndlr, _elems=Elementaries(_lib.Z3_set_error_handl
|
||||||
""")
|
""")
|
||||||
|
|
||||||
for sig in _API2PY:
|
for sig in _API2PY:
|
||||||
name = sig[0]
|
mk_py_wrapper_single(sig)
|
||||||
result = sig[1]
|
if sig[1] == STRING:
|
||||||
params = sig[2]
|
mk_py_wrapper_single(sig, decode_string=False)
|
||||||
num = len(params)
|
|
||||||
core_py.write("def %s(" % name)
|
def mk_py_wrapper_single(sig, decode_string=True):
|
||||||
display_args(num)
|
name = sig[0]
|
||||||
comma = ", " if num != 0 else ""
|
result = sig[1]
|
||||||
core_py.write("%s_elems=Elementaries(_lib.%s)):\n" % (comma, name))
|
params = sig[2]
|
||||||
lval = "r = " if result != VOID else ""
|
num = len(params)
|
||||||
core_py.write(" %s_elems.f(" % lval)
|
def_name = name
|
||||||
display_args_to_z3(params)
|
if not decode_string:
|
||||||
core_py.write(")\n")
|
def_name += '_bytes'
|
||||||
if len(params) > 0 and param_type(params[0]) == CONTEXT and not name in Unwrapped:
|
core_py.write("def %s(" % def_name)
|
||||||
core_py.write(" _elems.Check(a0)\n")
|
display_args(num)
|
||||||
if result == STRING:
|
comma = ", " if num != 0 else ""
|
||||||
core_py.write(" return _to_pystr(r)\n")
|
core_py.write("%s_elems=Elementaries(_lib.%s)):\n" % (comma, name))
|
||||||
elif result != VOID:
|
lval = "r = " if result != VOID else ""
|
||||||
core_py.write(" return r\n")
|
core_py.write(" %s_elems.f(" % lval)
|
||||||
core_py.write("\n")
|
display_args_to_z3(params)
|
||||||
core_py
|
core_py.write(")\n")
|
||||||
|
if len(params) > 0 and param_type(params[0]) == CONTEXT and not name in Unwrapped:
|
||||||
|
core_py.write(" _elems.Check(a0)\n")
|
||||||
|
if result == STRING and decode_string:
|
||||||
|
core_py.write(" return _to_pystr(r)\n")
|
||||||
|
elif result != VOID:
|
||||||
|
core_py.write(" return r\n")
|
||||||
|
core_py.write("\n")
|
||||||
|
|
||||||
|
|
||||||
## .NET API native interface
|
## .NET API native interface
|
||||||
|
@ -1704,6 +1711,7 @@ def write_exe_c_preamble(exe_c):
|
||||||
def write_core_py_post(core_py):
|
def write_core_py_post(core_py):
|
||||||
core_py.write("""
|
core_py.write("""
|
||||||
# Clean up
|
# Clean up
|
||||||
|
del _lib
|
||||||
del _default_dirs
|
del _default_dirs
|
||||||
del _all_dirs
|
del _all_dirs
|
||||||
del _ext
|
del _ext
|
||||||
|
|
|
@ -122,7 +122,7 @@ bool lackr::ackr(app * const t1, app * const t2) {
|
||||||
TRACE("ackermannize", tout << "ackr constr abs:" << mk_ismt2_pp(cga, m_m, 2) << "\n";);
|
TRACE("ackermannize", tout << "ackr constr abs:" << mk_ismt2_pp(cga, m_m, 2) << "\n";);
|
||||||
if (m_m.is_true(cga)) return false;
|
if (m_m.is_true(cga)) return false;
|
||||||
m_st.m_ackrs_sz++;
|
m_st.m_ackrs_sz++;
|
||||||
m_ackrs.push_back(cga);
|
m_ackrs.push_back(std::move(cga));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,7 @@ struct lackr_model_constructor::imp {
|
||||||
// handle functions
|
// handle functions
|
||||||
if (m_ackr_helper.should_ackermannize(a)) { // handle uninterpreted
|
if (m_ackr_helper.should_ackermannize(a)) { // handle uninterpreted
|
||||||
app_ref key(m_m.mk_app(a->get_decl(), values.c_ptr()), m_m);
|
app_ref key(m_m.mk_app(a->get_decl(), values.c_ptr()), m_m);
|
||||||
if (!make_value_uninterpreted_function(a, values, key.get(), result)) {
|
if (!make_value_uninterpreted_function(a, key.get(), result)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,6 @@ struct lackr_model_constructor::imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool make_value_uninterpreted_function(app* a,
|
bool make_value_uninterpreted_function(app* a,
|
||||||
expr_ref_vector& values,
|
|
||||||
app* key,
|
app* key,
|
||||||
expr_ref& result) {
|
expr_ref& result) {
|
||||||
// get ackermann constant
|
// get ackermann constant
|
||||||
|
@ -370,15 +369,12 @@ lackr_model_constructor::lackr_model_constructor(ast_manager& m, ackr_info_ref i
|
||||||
{}
|
{}
|
||||||
|
|
||||||
lackr_model_constructor::~lackr_model_constructor() {
|
lackr_model_constructor::~lackr_model_constructor() {
|
||||||
if (m_imp) dealloc(m_imp);
|
dealloc(m_imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lackr_model_constructor::check(model_ref& abstr_model) {
|
bool lackr_model_constructor::check(model_ref& abstr_model) {
|
||||||
m_conflicts.reset();
|
m_conflicts.reset();
|
||||||
if (m_imp) {
|
dealloc(m_imp);
|
||||||
dealloc(m_imp);
|
|
||||||
m_imp = nullptr;
|
|
||||||
}
|
|
||||||
m_imp = alloc(lackr_model_constructor::imp, m_m, m_info, abstr_model, m_conflicts);
|
m_imp = alloc(lackr_model_constructor::imp, m_m, m_info, abstr_model, m_conflicts);
|
||||||
const bool rv = m_imp->check();
|
const bool rv = m_imp->check();
|
||||||
m_state = rv ? CHECKED : CONFLICT;
|
m_state = rv ? CHECKED : CONFLICT;
|
||||||
|
|
|
@ -24,6 +24,7 @@ Revision History:
|
||||||
#include "util/vector.h"
|
#include "util/vector.h"
|
||||||
#include "util/smt2_util.h"
|
#include "util/smt2_util.h"
|
||||||
#include "ast/ast_smt_pp.h"
|
#include "ast/ast_smt_pp.h"
|
||||||
|
#include "ast/ast_smt2_pp.h"
|
||||||
#include "ast/arith_decl_plugin.h"
|
#include "ast/arith_decl_plugin.h"
|
||||||
#include "ast/bv_decl_plugin.h"
|
#include "ast/bv_decl_plugin.h"
|
||||||
#include "ast/array_decl_plugin.h"
|
#include "ast/array_decl_plugin.h"
|
||||||
|
@ -223,7 +224,7 @@ class smt_printer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_manager.is_ite(d)) {
|
else if (m_manager.is_ite(d)) {
|
||||||
m_out << "ite";
|
m_out << "ite";
|
||||||
}
|
}
|
||||||
else if (m_manager.is_implies(d)) {
|
else if (m_manager.is_implies(d)) {
|
||||||
m_out << "=>";
|
m_out << "=>";
|
||||||
|
@ -266,7 +267,7 @@ class smt_printer {
|
||||||
else {
|
else {
|
||||||
m_out << "(_ " << sym << " ";
|
m_out << "(_ " << sym << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_params; ++i) {
|
for (unsigned i = 0; i < num_params; ++i) {
|
||||||
parameter const& p = params[i];
|
parameter const& p = params[i];
|
||||||
if (p.is_ast()) {
|
if (p.is_ast()) {
|
||||||
|
@ -320,7 +321,7 @@ class smt_printer {
|
||||||
if (num_sorts > 0) {
|
if (num_sorts > 0) {
|
||||||
m_out << "(";
|
m_out << "(";
|
||||||
}
|
}
|
||||||
m_out << m_renaming.get_symbol(s->get_name(), false);
|
m_out << m_renaming.get_symbol(s->get_name(), false);
|
||||||
if (num_sorts > 0) {
|
if (num_sorts > 0) {
|
||||||
for (unsigned i = 0; i < num_sorts; ++i) {
|
for (unsigned i = 0; i < num_sorts; ++i) {
|
||||||
m_out << " ";
|
m_out << " ";
|
||||||
|
@ -388,10 +389,7 @@ class smt_printer {
|
||||||
m_out << "(_ bv" << val << " " << bv_size << ")";
|
m_out << "(_ bv" << val << " " << bv_size << ")";
|
||||||
}
|
}
|
||||||
else if (m_futil.is_numeral(n, float_val)) {
|
else if (m_futil.is_numeral(n, float_val)) {
|
||||||
m_out << "((_ to_fp " <<
|
m_out << mk_ismt2_pp(n, m_manager);
|
||||||
float_val.get().get_ebits() << " " <<
|
|
||||||
float_val.get().get_sbits() << ") RTZ " <<
|
|
||||||
m_futil.fm().to_string(float_val).c_str() << ")";
|
|
||||||
}
|
}
|
||||||
else if (m_bvutil.is_bit2bool(n)) {
|
else if (m_bvutil.is_bit2bool(n)) {
|
||||||
unsigned bit = n->get_decl()->get_parameter(0).get_int();
|
unsigned bit = n->get_decl()->get_parameter(0).get_int();
|
||||||
|
@ -402,7 +400,7 @@ class smt_printer {
|
||||||
else if (m_manager.is_label(n, pos, names) && !names.empty()) {
|
else if (m_manager.is_label(n, pos, names) && !names.empty()) {
|
||||||
m_out << "(! ";
|
m_out << "(! ";
|
||||||
pp_marked_expr(n->get_arg(0));
|
pp_marked_expr(n->get_arg(0));
|
||||||
m_out << (pos?":lblpos":":lblneg") << " " << m_renaming.get_symbol(names[0], false) << ")";
|
m_out << (pos?":lblpos":":lblneg") << " " << m_renaming.get_symbol(names[0], false) << ")";
|
||||||
}
|
}
|
||||||
else if (m_manager.is_label_lit(n, names) && !names.empty()) {
|
else if (m_manager.is_label_lit(n, names) && !names.empty()) {
|
||||||
m_out << "(! true :lblpos " << m_renaming.get_symbol(names[0], false) << ")";
|
m_out << "(! true :lblpos " << m_renaming.get_symbol(names[0], false) << ")";
|
||||||
|
@ -435,7 +433,7 @@ class smt_printer {
|
||||||
pp_arg(curr, n);
|
pp_arg(curr, n);
|
||||||
m_out << ")";
|
m_out << ")";
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (m_manager.is_distinct(decl)) {
|
else if (m_manager.is_distinct(decl)) {
|
||||||
ptr_vector<expr> args(num_args, n->get_args());
|
ptr_vector<expr> args(num_args, n->get_args());
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
|
@ -613,7 +611,7 @@ class smt_printer {
|
||||||
pp_id(n);
|
pp_id(n);
|
||||||
m_out << " ";
|
m_out << " ";
|
||||||
pp_expr(n);
|
pp_expr(n);
|
||||||
m_out << ")";
|
m_out << ")";
|
||||||
m_out << ")";
|
m_out << ")";
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
|
@ -781,7 +779,7 @@ public:
|
||||||
datatype_util util(m_manager);
|
datatype_util util(m_manager);
|
||||||
SASSERT(util.is_datatype(s));
|
SASSERT(util.is_datatype(s));
|
||||||
|
|
||||||
sort_ref_vector ps(m_manager);
|
sort_ref_vector ps(m_manager);
|
||||||
ptr_vector<datatype::def> defs;
|
ptr_vector<datatype::def> defs;
|
||||||
util.get_defs(s, defs);
|
util.get_defs(s, defs);
|
||||||
|
|
||||||
|
@ -790,7 +788,7 @@ public:
|
||||||
if (mark.is_marked(sr)) return; // already processed
|
if (mark.is_marked(sr)) return; // already processed
|
||||||
mark.mark(sr, true);
|
mark.mark(sr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out << "(declare-datatypes (";
|
m_out << "(declare-datatypes (";
|
||||||
bool first_def = true;
|
bool first_def = true;
|
||||||
for (datatype::def* d : defs) {
|
for (datatype::def* d : defs) {
|
||||||
|
@ -800,7 +798,7 @@ public:
|
||||||
m_out << ") (";
|
m_out << ") (";
|
||||||
bool first_sort = true;
|
bool first_sort = true;
|
||||||
for (datatype::def* d : defs) {
|
for (datatype::def* d : defs) {
|
||||||
if (!first_sort) m_out << "\n "; else first_sort = false;
|
if (!first_sort) m_out << "\n "; else first_sort = false;
|
||||||
if (!d->params().empty()) {
|
if (!d->params().empty()) {
|
||||||
m_out << "(par (";
|
m_out << "(par (";
|
||||||
bool first_param = true;
|
bool first_param = true;
|
||||||
|
@ -814,7 +812,7 @@ public:
|
||||||
bool first_constr = true;
|
bool first_constr = true;
|
||||||
for (datatype::constructor* f : *d) {
|
for (datatype::constructor* f : *d) {
|
||||||
if (!first_constr) m_out << " "; else first_constr = false;
|
if (!first_constr) m_out << " "; else first_constr = false;
|
||||||
m_out << "(";
|
m_out << "(";
|
||||||
m_out << m_renaming.get_symbol(f->name(), false);
|
m_out << m_renaming.get_symbol(f->name(), false);
|
||||||
for (datatype::accessor* a : *f) {
|
for (datatype::accessor* a : *f) {
|
||||||
m_out << " (" << m_renaming.get_symbol(a->name(), false) << " ";
|
m_out << " (" << m_renaming.get_symbol(a->name(), false) << " ";
|
||||||
|
@ -828,7 +826,7 @@ public:
|
||||||
}
|
}
|
||||||
m_out << ")";
|
m_out << ")";
|
||||||
}
|
}
|
||||||
m_out << "))";
|
m_out << "))";
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,7 +862,7 @@ public:
|
||||||
}
|
}
|
||||||
m_out << ") ";
|
m_out << ") ";
|
||||||
visit_sort(d->get_range());
|
visit_sort(d->get_range());
|
||||||
m_out << ")";
|
m_out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_pred(func_decl* d) {
|
void visit_pred(func_decl* d) {
|
||||||
|
|
|
@ -548,11 +548,15 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
|
||||||
case OP_ROTATE_LEFT:
|
case OP_ROTATE_LEFT:
|
||||||
if (arity != 1)
|
if (arity != 1)
|
||||||
m_manager->raise_exception("rotate left expects one argument");
|
m_manager->raise_exception("rotate left expects one argument");
|
||||||
|
if (num_parameters != 1 || !parameters[0].is_int())
|
||||||
|
m_manager->raise_exception("rotate left expects one integer parameter");
|
||||||
return m_manager->mk_func_decl(m_rotate_left_sym, arity, domain, domain[0],
|
return m_manager->mk_func_decl(m_rotate_left_sym, arity, domain, domain[0],
|
||||||
func_decl_info(m_family_id, k, num_parameters, parameters));
|
func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||||
case OP_ROTATE_RIGHT:
|
case OP_ROTATE_RIGHT:
|
||||||
if (arity != 1)
|
if (arity != 1)
|
||||||
m_manager->raise_exception("rotate right expects one argument");
|
m_manager->raise_exception("rotate right expects one argument");
|
||||||
|
if (num_parameters != 1 || !parameters[0].is_int())
|
||||||
|
m_manager->raise_exception("rotate right expects one integer parameter");
|
||||||
return m_manager->mk_func_decl(m_rotate_right_sym, arity, domain, domain[0],
|
return m_manager->mk_func_decl(m_rotate_right_sym, arity, domain, domain[0],
|
||||||
func_decl_info(m_family_id, k, num_parameters, parameters));
|
func_decl_info(m_family_id, k, num_parameters, parameters));
|
||||||
case OP_REPEAT:
|
case OP_REPEAT:
|
||||||
|
|
|
@ -375,7 +375,13 @@ br_status array_rewriter::mk_set_intersect(unsigned num_args, expr * const * arg
|
||||||
|
|
||||||
|
|
||||||
br_status array_rewriter::mk_set_complement(expr * arg, expr_ref & result) {
|
br_status array_rewriter::mk_set_complement(expr * arg, expr_ref & result) {
|
||||||
return mk_map_core(m().mk_not_decl(), 1, &arg, result);
|
func_decl* fnot = m().mk_not_decl();
|
||||||
|
br_status st = mk_map_core(fnot, 1, &arg, result);
|
||||||
|
if (BR_FAILED == st) {
|
||||||
|
result = m_util.mk_map(fnot, 1, &arg);
|
||||||
|
st = BR_DONE;
|
||||||
|
}
|
||||||
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
br_status array_rewriter::mk_set_difference(expr * arg1, expr * arg2, expr_ref & result) {
|
br_status array_rewriter::mk_set_difference(expr * arg1, expr * arg2, expr_ref & result) {
|
||||||
|
|
|
@ -374,13 +374,11 @@ void der::apply_substitution(quantifier * q, expr_ref & r) {
|
||||||
expr_ref_buffer new_patterns(m_manager);
|
expr_ref_buffer new_patterns(m_manager);
|
||||||
expr_ref_buffer new_no_patterns(m_manager);
|
expr_ref_buffer new_no_patterns(m_manager);
|
||||||
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
|
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
|
||||||
expr_ref new_pat = m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
|
new_patterns.push_back(m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr()));
|
||||||
new_patterns.push_back(new_pat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
|
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
|
||||||
expr_ref new_nopat = m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
|
new_no_patterns.push_back(m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr()));
|
||||||
new_no_patterns.push_back(new_nopat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = m_manager.update_quantifier(q, new_patterns.size(), new_patterns.c_ptr(),
|
r = m_manager.update_quantifier(q, new_patterns.size(), new_patterns.c_ptr(),
|
||||||
|
|
|
@ -126,8 +126,7 @@ void distribute_forall::reduce1_quantifier(quantifier * q) {
|
||||||
br.mk_not(arg, not_arg);
|
br.mk_not(arg, not_arg);
|
||||||
quantifier_ref tmp_q(m_manager);
|
quantifier_ref tmp_q(m_manager);
|
||||||
tmp_q = m_manager.update_quantifier(q, not_arg);
|
tmp_q = m_manager.update_quantifier(q, not_arg);
|
||||||
expr_ref new_q = elim_unused_vars(m_manager, tmp_q, params_ref());
|
new_args.push_back(elim_unused_vars(m_manager, tmp_q, params_ref()));
|
||||||
new_args.push_back(new_q);
|
|
||||||
}
|
}
|
||||||
expr_ref result(m_manager);
|
expr_ref result(m_manager);
|
||||||
// m_bsimp.mk_and actually constructs a (not (or ...)) formula,
|
// m_bsimp.mk_and actually constructs a (not (or ...)) formula,
|
||||||
|
|
|
@ -69,7 +69,6 @@ br_status hoist_rewriter::mk_or(unsigned num_args, expr * const * es, expr_ref &
|
||||||
turn = !turn;
|
turn = !turn;
|
||||||
(*preds)[turn].reset();
|
(*preds)[turn].reset();
|
||||||
reset(m_uf0);
|
reset(m_uf0);
|
||||||
unsigned v1 = 0, v2 = 0;
|
|
||||||
VERIFY(is_and(es[j], args[turn]));
|
VERIFY(is_and(es[j], args[turn]));
|
||||||
|
|
||||||
for (expr* e : *args[turn]) {
|
for (expr* e : *args[turn]) {
|
||||||
|
@ -196,6 +195,7 @@ bool hoist_rewriter::is_and(expr * e, expr_ref_vector* args) {
|
||||||
void hoist_rewriter::reset(basic_union_find& uf) {
|
void hoist_rewriter::reset(basic_union_find& uf) {
|
||||||
uf.reset();
|
uf.reset();
|
||||||
for (expr* e : m_var2expr) {
|
for (expr* e : m_var2expr) {
|
||||||
|
(void)e;
|
||||||
uf.mk_var();
|
uf.mk_var();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,17 +135,14 @@ expr_ref unused_vars_eliminator::operator()(quantifier* q) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref tmp(m);
|
|
||||||
expr_ref_buffer new_patterns(m);
|
expr_ref_buffer new_patterns(m);
|
||||||
expr_ref_buffer new_no_patterns(m);
|
expr_ref_buffer new_no_patterns(m);
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_patterns; i++) {
|
for (unsigned i = 0; i < num_patterns; i++) {
|
||||||
tmp = m_subst(q->get_pattern(i), var_mapping.size(), var_mapping.c_ptr());
|
new_patterns.push_back(m_subst(q->get_pattern(i), var_mapping.size(), var_mapping.c_ptr()));
|
||||||
new_patterns.push_back(tmp);
|
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < num_no_patterns; i++) {
|
for (unsigned i = 0; i < num_no_patterns; i++) {
|
||||||
tmp = m_subst(q->get_no_pattern(i), var_mapping.size(), var_mapping.c_ptr());
|
new_no_patterns.push_back(m_subst(q->get_no_pattern(i), var_mapping.size(), var_mapping.c_ptr()));
|
||||||
new_no_patterns.push_back(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = m.mk_quantifier(q->get_kind(),
|
result = m.mk_quantifier(q->get_kind(),
|
||||||
|
|
|
@ -112,7 +112,7 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e
|
||||||
TRACE("subst_bug", tout << "visited: " << visited << ", n1: " << mk_pp(n1.get_expr(), m_manager) << " : " << n1.get_offset() << "\n";);
|
TRACE("subst_bug", tout << "visited: " << visited << ", n1: " << mk_pp(n1.get_expr(), m_manager) << " : " << n1.get_offset() << "\n";);
|
||||||
if (visited) {
|
if (visited) {
|
||||||
m_todo.pop_back();
|
m_todo.pop_back();
|
||||||
expr * new_expr;
|
expr * new_expr = nullptr;
|
||||||
m_apply_cache.find(n1, new_expr);
|
m_apply_cache.find(n1, new_expr);
|
||||||
m_apply_cache.insert(n, new_expr);
|
m_apply_cache.insert(n, new_expr);
|
||||||
TRACE("subst_bug", tout << "1. insert n: " << mk_pp(n.get_expr(), m_manager) << " : " << n.get_offset()
|
TRACE("subst_bug", tout << "1. insert n: " << mk_pp(n.get_expr(), m_manager) << " : " << n.get_offset()
|
||||||
|
|
|
@ -217,13 +217,18 @@ struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
}
|
}
|
||||||
if (get_macro(g, def, q, def_pr)) {
|
if (get_macro(g, def, q, def_pr)) {
|
||||||
sort_ref_vector vars(m);
|
sort_ref_vector sorts(m);
|
||||||
|
expr_ref_vector vars(m);
|
||||||
svector<symbol> var_names;
|
svector<symbol> var_names;
|
||||||
for (unsigned i = 0; i < g->get_arity(); ++i) {
|
unsigned sz = g->get_arity();
|
||||||
var_names.push_back(symbol(i));
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
vars.push_back(g->get_domain(i));
|
var_names.push_back(symbol(sz - i - 1));
|
||||||
|
vars.push_back(m.mk_var(sz - i - 1, g->get_domain(i)));
|
||||||
|
sorts.push_back(g->get_domain(i));
|
||||||
}
|
}
|
||||||
result = m.mk_lambda(vars.size(), vars.c_ptr(), var_names.c_ptr(), def);
|
var_subst subst(m, false);
|
||||||
|
result = subst(def, sorts.size(), vars.c_ptr());
|
||||||
|
result = m.mk_lambda(sorts.size(), sorts.c_ptr(), var_names.c_ptr(), result);
|
||||||
model_evaluator ev(m_model, m_params);
|
model_evaluator ev(m_model, m_params);
|
||||||
result = ev(result);
|
result = ev(result);
|
||||||
m_pinned.push_back(result);
|
m_pinned.push_back(result);
|
||||||
|
|
|
@ -41,7 +41,6 @@ namespace datalog {
|
||||||
|
|
||||||
execution_context::~execution_context() {
|
execution_context::~execution_context() {
|
||||||
reset();
|
reset();
|
||||||
dealloc(m_stopwatch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void execution_context::reset() {
|
void execution_context::reset() {
|
||||||
|
@ -104,15 +103,15 @@ namespace datalog {
|
||||||
m_timelimit_ms = time_in_ms;
|
m_timelimit_ms = time_in_ms;
|
||||||
if (!m_stopwatch) {
|
if (!m_stopwatch) {
|
||||||
m_stopwatch = alloc(stopwatch);
|
m_stopwatch = alloc(stopwatch);
|
||||||
|
} else {
|
||||||
|
m_stopwatch->stop();
|
||||||
|
m_stopwatch->reset();
|
||||||
}
|
}
|
||||||
m_stopwatch->stop();
|
|
||||||
m_stopwatch->reset();
|
|
||||||
m_stopwatch->start();
|
m_stopwatch->start();
|
||||||
}
|
}
|
||||||
void execution_context::reset_timelimit() {
|
void execution_context::reset_timelimit() {
|
||||||
if (m_stopwatch) {
|
dealloc(m_stopwatch);
|
||||||
m_stopwatch->stop();
|
m_stopwatch = nullptr;
|
||||||
}
|
|
||||||
m_timelimit_ms = 0;
|
m_timelimit_ms = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,11 +74,6 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_value(soft& soft, lbool v) {
|
|
||||||
soft.set_value(v);
|
|
||||||
assert_value(soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_assignment(model_ref & mdl) {
|
void update_assignment(model_ref & mdl) {
|
||||||
bool first_undef = true, second_undef = false;
|
bool first_undef = true, second_undef = false;
|
||||||
for (auto & soft : m_soft) {
|
for (auto & soft : m_soft) {
|
||||||
|
@ -95,7 +90,9 @@ namespace opt {
|
||||||
soft.set_value(v);
|
soft.set_value(v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_value(soft, v); // also update constraints
|
SASSERT(v == l_true);
|
||||||
|
soft.set_value(v);
|
||||||
|
assert_value(soft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,121 +127,9 @@ namespace opt {
|
||||||
if (mdl) update_assignment(mdl);
|
if (mdl) update_assignment(mdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool maxlex1() {
|
//
|
||||||
for (auto & soft : m_soft) {
|
// include soft constraints that are known to be assignable to true after failed literal.
|
||||||
if (soft.value == l_true) {
|
//
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SASSERT(soft.value == l_undef);
|
|
||||||
expr* a = soft.s;
|
|
||||||
lbool is_sat = s().check_sat(1, &a);
|
|
||||||
switch (is_sat) {
|
|
||||||
case l_false:
|
|
||||||
set_value(soft, l_false);
|
|
||||||
update_bounds();
|
|
||||||
break;
|
|
||||||
case l_true:
|
|
||||||
update_assignment();
|
|
||||||
SASSERT(soft.value == l_true);
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
return l_undef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try two literals per round.
|
|
||||||
// doesn't seem to make a difference based on sample test.
|
|
||||||
lbool maxlex2() {
|
|
||||||
unsigned sz = m_soft.size();
|
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
|
||||||
auto& soft = m_soft[i];
|
|
||||||
if (soft.value != l_undef) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SASSERT(soft.value == l_undef);
|
|
||||||
if (i + 1 == sz) {
|
|
||||||
expr* a = soft.s;
|
|
||||||
lbool is_sat = s().check_sat(1, &a);
|
|
||||||
switch (is_sat) {
|
|
||||||
case l_false:
|
|
||||||
set_value(soft, l_false);
|
|
||||||
update_bounds();
|
|
||||||
break;
|
|
||||||
case l_true:
|
|
||||||
update_assignment();
|
|
||||||
SASSERT(soft.value == l_true);
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
return l_undef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto& soft2 = m_soft[i+1];
|
|
||||||
expr_ref_vector core(m);
|
|
||||||
expr* a = soft.s;
|
|
||||||
expr* b = soft2.s;
|
|
||||||
expr* asms[2] = { a, b };
|
|
||||||
lbool is_sat = s().check_sat(2, asms);
|
|
||||||
switch (is_sat) {
|
|
||||||
case l_true:
|
|
||||||
update_assignment();
|
|
||||||
SASSERT(soft.value == l_true);
|
|
||||||
SASSERT(soft2.value == l_true);
|
|
||||||
break;
|
|
||||||
case l_false:
|
|
||||||
s().get_unsat_core(core);
|
|
||||||
if (core.contains(b)) {
|
|
||||||
expr_ref not_b(mk_not(m, b), m);
|
|
||||||
asms[1] = not_b;
|
|
||||||
switch (s().check_sat(2, asms)) {
|
|
||||||
case l_true:
|
|
||||||
// a, b is unsat, a, not b is sat.
|
|
||||||
set_value(soft2, l_false);
|
|
||||||
update_assignment();
|
|
||||||
SASSERT(soft.value == l_true);
|
|
||||||
SASSERT(soft2.value == l_false);
|
|
||||||
break;
|
|
||||||
case l_false:
|
|
||||||
// a, b is unsat, a, not b is unsat -> a is unsat
|
|
||||||
// b is unsat, a, not b is unsat -> not a, not b
|
|
||||||
set_value(soft, l_false);
|
|
||||||
// core1 = { b }
|
|
||||||
// core2 = { a, not b }
|
|
||||||
if (!core.contains(a)) {
|
|
||||||
set_value(soft2, l_false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// core1 = { a, b}
|
|
||||||
// core2 = { not_b }
|
|
||||||
core.reset();
|
|
||||||
s().get_unsat_core(core);
|
|
||||||
if (!core.contains(a)) {
|
|
||||||
set_value(soft2, l_true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update_bounds();
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
return l_undef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_value(soft, l_false);
|
|
||||||
update_bounds();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
return l_undef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// every time probing whether to include soft_i,
|
|
||||||
// include suffix that is known to be assignable to T
|
|
||||||
lbool maxlexN() {
|
lbool maxlexN() {
|
||||||
unsigned sz = m_soft.size();
|
unsigned sz = m_soft.size();
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
@ -254,12 +139,6 @@ namespace opt {
|
||||||
}
|
}
|
||||||
expr_ref_vector asms(m);
|
expr_ref_vector asms(m);
|
||||||
asms.push_back(soft.s);
|
asms.push_back(soft.s);
|
||||||
for (unsigned j = i + 1; j < sz; ++j) {
|
|
||||||
auto& soft2 = m_soft[j];
|
|
||||||
if (soft2.value == l_true) {
|
|
||||||
asms.push_back(soft2.s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lbool is_sat = s().check_sat(asms);
|
lbool is_sat = s().check_sat(asms);
|
||||||
switch (is_sat) {
|
switch (is_sat) {
|
||||||
case l_true:
|
case l_true:
|
||||||
|
@ -267,7 +146,8 @@ namespace opt {
|
||||||
SASSERT(soft.value == l_true);
|
SASSERT(soft.value == l_true);
|
||||||
break;
|
break;
|
||||||
case l_false:
|
case l_false:
|
||||||
set_value(soft, l_false);
|
soft.set_value(l_false);
|
||||||
|
assert_value(soft);
|
||||||
for (unsigned j = i + 1; j < sz; ++j) {
|
for (unsigned j = i + 1; j < sz; ++j) {
|
||||||
auto& soft2 = m_soft[j];
|
auto& soft2 = m_soft[j];
|
||||||
if (soft2.value != l_true) {
|
if (soft2.value != l_true) {
|
||||||
|
|
|
@ -38,7 +38,6 @@ namespace sat {
|
||||||
memcpy(m_lits, lits, sizeof(literal) * sz);
|
memcpy(m_lits, lits, sizeof(literal) * sz);
|
||||||
mark_strengthened();
|
mark_strengthened();
|
||||||
SASSERT(check_approx());
|
SASSERT(check_approx());
|
||||||
SASSERT(sz > 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var_approx_set clause::approx(unsigned num, literal const * lits) {
|
var_approx_set clause::approx(unsigned num, literal const * lits) {
|
||||||
|
@ -83,6 +82,7 @@ namespace sat {
|
||||||
i++;
|
i++;
|
||||||
for (; i < m_size; i++)
|
for (; i < m_size; i++)
|
||||||
m_lits[i-1] = m_lits[i];
|
m_lits[i-1] = m_lits[i];
|
||||||
|
m_lits[m_size-1] = l;
|
||||||
m_size--;
|
m_size--;
|
||||||
mark_strengthened();
|
mark_strengthened();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,10 +49,13 @@ namespace sat {
|
||||||
dealloc(m_bout);
|
dealloc(m_bout);
|
||||||
for (unsigned i = 0; i < m_proof.size(); ++i) {
|
for (unsigned i = 0; i < m_proof.size(); ++i) {
|
||||||
clause* c = m_proof[i];
|
clause* c = m_proof[i];
|
||||||
if (c && (c->size() == 2 || m_status[i] == status::deleted || m_status[i] == status::external)) {
|
if (c) {
|
||||||
s.dealloc_clause(c);
|
m_alloc.del_clause(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_proof.reset();
|
||||||
|
m_out = nullptr;
|
||||||
|
m_bout = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drat::updt_config() {
|
void drat::updt_config() {
|
||||||
|
@ -75,12 +78,12 @@ namespace sat {
|
||||||
if (st == status::asserted || st == status::external) {
|
if (st == status::asserted || st == status::external) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[10000];
|
char buffer[10000];
|
||||||
char digits[20]; // enough for storing unsigned
|
char digits[20]; // enough for storing unsigned
|
||||||
char* lastd = digits + sizeof(digits);
|
char* lastd = digits + sizeof(digits);
|
||||||
|
|
||||||
int len = 0;
|
unsigned len = 0;
|
||||||
if (st == status::deleted) {
|
if (st == status::deleted) {
|
||||||
buffer[0] = 'd';
|
buffer[0] = 'd';
|
||||||
buffer[1] = ' ';
|
buffer[1] = ' ';
|
||||||
|
@ -120,22 +123,27 @@ namespace sat {
|
||||||
case status::deleted: ch = 'd'; break;
|
case status::deleted: ch = 'd'; break;
|
||||||
default: UNREACHABLE(); break;
|
default: UNREACHABLE(); break;
|
||||||
}
|
}
|
||||||
(*m_bout) << ch;
|
char buffer[10000];
|
||||||
|
int len = 0;
|
||||||
|
buffer[len++] = ch;
|
||||||
|
|
||||||
for (unsigned i = 0; i < n; ++i) {
|
for (unsigned i = 0; i < n; ++i) {
|
||||||
literal lit = c[i];
|
literal lit = c[i];
|
||||||
unsigned v = 2 * lit.var() + (lit.sign() ? 1 : 0);
|
unsigned v = 2 * lit.var() + (lit.sign() ? 1 : 0);
|
||||||
do {
|
do {
|
||||||
ch = static_cast<unsigned char>(v & ((1 << 7) - 1));
|
ch = static_cast<unsigned char>(v & 255);
|
||||||
v >>= 7;
|
v >>= 7;
|
||||||
if (v) ch |= (1 << 7);
|
if (v) ch |= 128;
|
||||||
//std::cout << std::hex << ((unsigned char)ch) << std::dec << " ";
|
buffer[len++] = ch;
|
||||||
(*m_bout) << ch;
|
if (len == sizeof(buffer)) {
|
||||||
|
m_bout->write(buffer, len);
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (v);
|
while (v);
|
||||||
}
|
}
|
||||||
ch = 0;
|
buffer[len++] = 0;
|
||||||
(*m_bout) << ch;
|
m_bout->write(buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool drat::is_cleaned(clause& c) const {
|
bool drat::is_cleaned(clause& c) const {
|
||||||
|
@ -161,6 +169,9 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void drat::append(literal l, status st) {
|
void drat::append(literal l, status st) {
|
||||||
|
TRACE("sat_drat", tout << st << " " << l << "\n";);
|
||||||
|
|
||||||
|
declare(l);
|
||||||
IF_VERBOSE(20, trace(verbose_stream(), 1, &l, st););
|
IF_VERBOSE(20, trace(verbose_stream(), 1, &l, st););
|
||||||
if (st == status::learned) {
|
if (st == status::learned) {
|
||||||
verify(1, &l);
|
verify(1, &l);
|
||||||
|
@ -168,11 +179,19 @@ namespace sat {
|
||||||
if (st == status::deleted) {
|
if (st == status::deleted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assign_propagate(l);
|
if (m_check_unsat) {
|
||||||
|
assign_propagate(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_units.push_back(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drat::append(literal l1, literal l2, status st) {
|
void drat::append(literal l1, literal l2, status st) {
|
||||||
|
TRACE("sat_drat", tout << st << " " << l1 << " " << l2 << "\n";);
|
||||||
|
declare(l1);
|
||||||
|
declare(l2);
|
||||||
literal lits[2] = { l1, l2 };
|
literal lits[2] = { l1, l2 };
|
||||||
|
|
||||||
IF_VERBOSE(20, trace(verbose_stream(), 2, lits, st););
|
IF_VERBOSE(20, trace(verbose_stream(), 2, lits, st););
|
||||||
if (st == status::deleted) {
|
if (st == status::deleted) {
|
||||||
// noop
|
// noop
|
||||||
|
@ -182,9 +201,10 @@ namespace sat {
|
||||||
if (st == status::learned) {
|
if (st == status::learned) {
|
||||||
verify(2, lits);
|
verify(2, lits);
|
||||||
}
|
}
|
||||||
clause* c = s.alloc_clause(2, lits, st == status::learned);
|
clause* c = m_alloc.mk_clause(2, lits, st == status::learned);
|
||||||
m_proof.push_back(c);
|
m_proof.push_back(c);
|
||||||
m_status.push_back(st);
|
m_status.push_back(st);
|
||||||
|
if (!m_check_unsat) return;
|
||||||
unsigned idx = m_watched_clauses.size();
|
unsigned idx = m_watched_clauses.size();
|
||||||
m_watched_clauses.push_back(watched_clause(c, l1, l2));
|
m_watched_clauses.push_back(watched_clause(c, l1, l2));
|
||||||
m_watches[(~l1).index()].push_back(idx);
|
m_watches[(~l1).index()].push_back(idx);
|
||||||
|
@ -202,14 +222,37 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// debugging code
|
||||||
|
bool drat::is_clause(clause& c, literal l1, literal l2, literal l3, drat::status st1, drat::status st2) {
|
||||||
|
//if (st1 != st2) return false;
|
||||||
|
if (c.size() != 3) return false;
|
||||||
|
if (l1 == c[0]) {
|
||||||
|
if (l2 == c[1] && l3 == c[2]) return true;
|
||||||
|
if (l2 == c[2] && l3 == c[1]) return true;
|
||||||
|
}
|
||||||
|
if (l2 == c[0]) {
|
||||||
|
if (l1 == c[1] && l3 == c[2]) return true;
|
||||||
|
if (l1 == c[2] && l3 == c[1]) return true;
|
||||||
|
}
|
||||||
|
if (l3 == c[0]) {
|
||||||
|
if (l1 == c[1] && l2 == c[2]) return true;
|
||||||
|
if (l1 == c[2] && l2 == c[1]) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void drat::append(clause& c, status st) {
|
void drat::append(clause& c, status st) {
|
||||||
|
TRACE("sat_drat", tout << st << " " << c << "\n";);
|
||||||
|
for (literal lit : c) declare(lit);
|
||||||
unsigned n = c.size();
|
unsigned n = c.size();
|
||||||
IF_VERBOSE(20, trace(verbose_stream(), n, c.begin(), st););
|
IF_VERBOSE(20, trace(verbose_stream(), n, c.begin(), st););
|
||||||
|
|
||||||
if (st == status::learned) {
|
if (st == status::learned) {
|
||||||
verify(c);
|
verify(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_status.push_back(st);
|
m_status.push_back(st);
|
||||||
m_proof.push_back(&c);
|
m_proof.push_back(&c);
|
||||||
if (st == status::deleted) {
|
if (st == status::deleted) {
|
||||||
|
@ -262,6 +305,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void drat::declare(literal l) {
|
void drat::declare(literal l) {
|
||||||
|
if (!m_check) return;
|
||||||
unsigned n = static_cast<unsigned>(l.var());
|
unsigned n = static_cast<unsigned>(l.var());
|
||||||
while (m_assignment.size() <= n) {
|
while (m_assignment.size() <= n) {
|
||||||
m_assignment.push_back(l_undef);
|
m_assignment.push_back(l_undef);
|
||||||
|
@ -357,7 +401,7 @@ namespace sat {
|
||||||
void drat::validate_propagation() const {
|
void drat::validate_propagation() const {
|
||||||
for (unsigned i = 0; i < m_proof.size(); ++i) {
|
for (unsigned i = 0; i < m_proof.size(); ++i) {
|
||||||
status st = m_status[i];
|
status st = m_status[i];
|
||||||
if (m_proof[i] && st != status::deleted) {
|
if (m_proof[i] && m_proof[i]->size() > 1 && st != status::deleted) {
|
||||||
clause& c = *m_proof[i];
|
clause& c = *m_proof[i];
|
||||||
unsigned num_undef = 0, num_true = 0;
|
unsigned num_undef = 0, num_true = 0;
|
||||||
for (unsigned j = 0; j < c.size(); ++j) {
|
for (unsigned j = 0; j < c.size(); ++j) {
|
||||||
|
@ -367,7 +411,7 @@ namespace sat {
|
||||||
case l_undef: num_undef++; break;
|
case l_undef: num_undef++; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CTRACE("sat", num_true == 0 && num_undef == 1, display(tout););
|
CTRACE("sat_drat", num_true == 0 && num_undef == 1, display(tout););
|
||||||
SASSERT(num_true != 0 || num_undef != 1);
|
SASSERT(num_true != 0 || num_undef != 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,7 +424,7 @@ namespace sat {
|
||||||
SASSERT(lits.size() == n);
|
SASSERT(lits.size() == n);
|
||||||
for (unsigned i = 0; i < m_proof.size(); ++i) {
|
for (unsigned i = 0; i < m_proof.size(); ++i) {
|
||||||
status st = m_status[i];
|
status st = m_status[i];
|
||||||
if (m_proof[i] && (st == status::asserted || st == status::external)) {
|
if (m_proof[i] && m_proof[i]->size() > 1 && (st == status::asserted || st == status::external)) {
|
||||||
clause& c = *m_proof[i];
|
clause& c = *m_proof[i];
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
for (; j < c.size() && c[j] != ~l; ++j) {}
|
for (; j < c.size() && c[j] != ~l; ++j) {}
|
||||||
|
@ -411,7 +455,7 @@ namespace sat {
|
||||||
exit(0);
|
exit(0);
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
//display(std::cout);
|
//display(std::cout);
|
||||||
TRACE("sat",
|
TRACE("sat_drat",
|
||||||
tout << literal_vector(n, c) << "\n";
|
tout << literal_vector(n, c) << "\n";
|
||||||
display(tout);
|
display(tout);
|
||||||
s.display(tout););
|
s.display(tout););
|
||||||
|
@ -419,16 +463,41 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool drat::contains(literal c, justification const& j) {
|
||||||
|
if (!m_check_sat) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (j.get_kind()) {
|
||||||
|
case justification::NONE:
|
||||||
|
return m_units.contains(c);
|
||||||
|
case justification::BINARY:
|
||||||
|
return contains(c, j.get_literal());
|
||||||
|
case justification::TERNARY:
|
||||||
|
return contains(c, j.get_literal1(), j.get_literal2());
|
||||||
|
case justification::CLAUSE:
|
||||||
|
return contains(s.get_clause(j));
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool drat::contains(unsigned n, literal const* lits) {
|
bool drat::contains(unsigned n, literal const* lits) {
|
||||||
if (!m_check) return true;
|
if (!m_check) return true;
|
||||||
|
unsigned num_add = 0;
|
||||||
|
unsigned num_del = 0;
|
||||||
for (unsigned i = m_proof.size(); i-- > 0; ) {
|
for (unsigned i = m_proof.size(); i-- > 0; ) {
|
||||||
clause& c = *m_proof[i];
|
clause& c = *m_proof[i];
|
||||||
status st = m_status[i];
|
status st = m_status[i];
|
||||||
if (match(n, lits, c)) {
|
if (match(n, lits, c)) {
|
||||||
return st != status::deleted;
|
if (st == status::deleted) {
|
||||||
|
num_del++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_add++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return num_add > num_del;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool drat::match(unsigned n, literal const* lits, clause const& c) const {
|
bool drat::match(unsigned n, literal const* lits, clause const& c) const {
|
||||||
|
@ -442,7 +511,9 @@ namespace sat {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) return false;
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -500,7 +571,7 @@ namespace sat {
|
||||||
void drat::assign(literal l) {
|
void drat::assign(literal l) {
|
||||||
lbool new_value = l.sign() ? l_false : l_true;
|
lbool new_value = l.sign() ? l_false : l_true;
|
||||||
lbool old_value = value(l);
|
lbool old_value = value(l);
|
||||||
// TRACE("sat", tout << "assign " << l << " := " << new_value << " from " << old_value << "\n";);
|
// TRACE("sat_drat", tout << "assign " << l << " := " << new_value << " from " << old_value << "\n";);
|
||||||
switch (old_value) {
|
switch (old_value) {
|
||||||
case l_false:
|
case l_false:
|
||||||
m_inconsistent = true;
|
m_inconsistent = true;
|
||||||
|
@ -532,7 +603,7 @@ namespace sat {
|
||||||
watched_clause& wc = m_watched_clauses[idx];
|
watched_clause& wc = m_watched_clauses[idx];
|
||||||
clause& c = *wc.m_clause;
|
clause& c = *wc.m_clause;
|
||||||
|
|
||||||
//TRACE("sat", tout << "Propagate " << l << " " << c << " watch: " << wc.m_l1 << " " << wc.m_l2 << "\n";);
|
//TRACE("sat_drat", tout << "Propagate " << l << " " << c << " watch: " << wc.m_l1 << " " << wc.m_l2 << "\n";);
|
||||||
if (wc.m_l1 == ~l) {
|
if (wc.m_l1 == ~l) {
|
||||||
std::swap(wc.m_l1, wc.m_l2);
|
std::swap(wc.m_l1, wc.m_l2);
|
||||||
}
|
}
|
||||||
|
@ -578,23 +649,18 @@ namespace sat {
|
||||||
|
|
||||||
void drat::add() {
|
void drat::add() {
|
||||||
if (m_out) (*m_out) << "0\n";
|
if (m_out) (*m_out) << "0\n";
|
||||||
if (m_bout) bdump(0, nullptr, learned);
|
if (m_bout) bdump(0, nullptr, status::learned);
|
||||||
if (m_check_unsat) {
|
if (m_check_unsat) {
|
||||||
SASSERT(m_inconsistent);
|
SASSERT(m_inconsistent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drat::add(literal l, bool learned) {
|
void drat::add(literal l, bool learned) {
|
||||||
TRACE("sat", tout << "add: " << l << " " << (learned?"l":"t") << "\n";);
|
|
||||||
declare(l);
|
|
||||||
status st = get_status(learned);
|
status st = get_status(learned);
|
||||||
if (m_out) dump(1, &l, st);
|
if (m_out) dump(1, &l, st);
|
||||||
if (m_bout) bdump(1, &l, st);
|
if (m_bout) bdump(1, &l, st);
|
||||||
if (m_check) append(l, st);
|
if (m_check) append(l, st);
|
||||||
}
|
}
|
||||||
void drat::add(literal l1, literal l2, bool learned) {
|
void drat::add(literal l1, literal l2, bool learned) {
|
||||||
TRACE("sat", tout << "add: " << l1 << " " << l2 << " " << (learned?"l":"t") << "\n";);
|
|
||||||
declare(l1);
|
|
||||||
declare(l2);
|
|
||||||
literal ls[2] = {l1, l2};
|
literal ls[2] = {l1, l2};
|
||||||
status st = get_status(learned);
|
status st = get_status(learned);
|
||||||
if (m_out) dump(2, ls, st);
|
if (m_out) dump(2, ls, st);
|
||||||
|
@ -602,12 +668,13 @@ namespace sat {
|
||||||
if (m_check) append(l1, l2, st);
|
if (m_check) append(l1, l2, st);
|
||||||
}
|
}
|
||||||
void drat::add(clause& c, bool learned) {
|
void drat::add(clause& c, bool learned) {
|
||||||
TRACE("sat", tout << "add: " << c << "\n";);
|
|
||||||
for (unsigned i = 0; i < c.size(); ++i) declare(c[i]);
|
|
||||||
status st = get_status(learned);
|
status st = get_status(learned);
|
||||||
if (m_out) dump(c.size(), c.begin(), st);
|
if (m_out) dump(c.size(), c.begin(), st);
|
||||||
if (m_bout) bdump(c.size(), c.begin(), st);
|
if (m_bout) bdump(c.size(), c.begin(), st);
|
||||||
if (m_check_unsat) append(c, get_status(learned));
|
if (m_check) {
|
||||||
|
clause* cl = m_alloc.mk_clause(c.size(), c.begin(), learned);
|
||||||
|
append(*cl, get_status(learned));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void drat::add(literal_vector const& lits, svector<premise> const& premises) {
|
void drat::add(literal_vector const& lits, svector<premise> const& premises) {
|
||||||
if (m_check) {
|
if (m_check) {
|
||||||
|
@ -615,7 +682,7 @@ namespace sat {
|
||||||
case 0: add(); break;
|
case 0: add(); break;
|
||||||
case 1: append(lits[0], status::external); break;
|
case 1: append(lits[0], status::external); break;
|
||||||
default: {
|
default: {
|
||||||
clause* c = s.alloc_clause(lits.size(), lits.c_ptr(), true);
|
clause* c = m_alloc.mk_clause(lits.size(), lits.c_ptr(), true);
|
||||||
append(*c, status::external);
|
append(*c, status::external);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -623,16 +690,16 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drat::add(literal_vector const& c) {
|
void drat::add(literal_vector const& c) {
|
||||||
for (unsigned i = 0; i < c.size(); ++i) declare(c[i]);
|
|
||||||
if (m_out) dump(c.size(), c.begin(), status::learned);
|
if (m_out) dump(c.size(), c.begin(), status::learned);
|
||||||
if (m_bout) bdump(c.size(), c.begin(), status::learned);
|
if (m_bout) bdump(c.size(), c.begin(), status::learned);
|
||||||
if (m_check) {
|
if (m_check) {
|
||||||
|
for (literal lit : c) declare(lit);
|
||||||
switch (c.size()) {
|
switch (c.size()) {
|
||||||
case 0: add(); break;
|
case 0: add(); break;
|
||||||
case 1: append(c[0], status::learned); break;
|
case 1: append(c[0], status::learned); break;
|
||||||
default: {
|
default: {
|
||||||
verify(c.size(), c.begin());
|
verify(c.size(), c.begin());
|
||||||
clause* cl = s.alloc_clause(c.size(), c.c_ptr(), true);
|
clause* cl = m_alloc.mk_clause(c.size(), c.c_ptr(), true);
|
||||||
append(*cl, status::external);
|
append(*cl, status::external);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -645,8 +712,10 @@ namespace sat {
|
||||||
if (m_bout) bdump(1, &l, status::deleted);
|
if (m_bout) bdump(1, &l, status::deleted);
|
||||||
if (m_check_unsat) append(l, status::deleted);
|
if (m_check_unsat) append(l, status::deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drat::del(literal l1, literal l2) {
|
void drat::del(literal l1, literal l2) {
|
||||||
literal ls[2] = {l1, l2};
|
literal ls[2] = {l1, l2};
|
||||||
|
SASSERT(!(l1 == literal(13923, false) && l2 == literal(14020, true)));
|
||||||
if (m_out) dump(2, ls, status::deleted);
|
if (m_out) dump(2, ls, status::deleted);
|
||||||
if (m_bout) bdump(2, ls, status::deleted);
|
if (m_bout) bdump(2, ls, status::deleted);
|
||||||
if (m_check) append(l1, l2, status::deleted);
|
if (m_check) append(l1, l2, status::deleted);
|
||||||
|
@ -665,11 +734,11 @@ namespace sat {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE("sat", tout << "del: " << c << "\n";);
|
//SASSERT(!(c.size() == 2 && c[0] == literal(13923, false) && c[1] == literal(14020, true)));
|
||||||
if (m_out) dump(c.size(), c.begin(), status::deleted);
|
if (m_out) dump(c.size(), c.begin(), status::deleted);
|
||||||
if (m_bout) bdump(c.size(), c.begin(), status::deleted);
|
if (m_bout) bdump(c.size(), c.begin(), status::deleted);
|
||||||
if (m_check) {
|
if (m_check) {
|
||||||
clause* c1 = s.alloc_clause(c.size(), c.begin(), c.is_learned());
|
clause* c1 = m_alloc.mk_clause(c.size(), c.begin(), c.is_learned());
|
||||||
append(*c1, status::deleted);
|
append(*c1, status::deleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace sat {
|
||||||
svector<watched_clause> m_watched_clauses;
|
svector<watched_clause> m_watched_clauses;
|
||||||
typedef svector<unsigned> watch;
|
typedef svector<unsigned> watch;
|
||||||
solver& s;
|
solver& s;
|
||||||
|
clause_allocator m_alloc;
|
||||||
std::ostream* m_out;
|
std::ostream* m_out;
|
||||||
std::ostream* m_bout;
|
std::ostream* m_bout;
|
||||||
ptr_vector<clause> m_proof;
|
ptr_vector<clause> m_proof;
|
||||||
|
@ -61,6 +62,8 @@ namespace sat {
|
||||||
void append(literal l1, literal l2, status st);
|
void append(literal l1, literal l2, status st);
|
||||||
void append(clause& c, status st);
|
void append(clause& c, status st);
|
||||||
|
|
||||||
|
bool is_clause(clause& c, literal l1, literal l2, literal l3, status st1, status st2);
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream & out, status st);
|
friend std::ostream& operator<<(std::ostream & out, status st);
|
||||||
status get_status(bool learned) const;
|
status get_status(bool learned) const;
|
||||||
|
|
||||||
|
@ -104,6 +107,7 @@ namespace sat {
|
||||||
bool contains(unsigned n, literal const* c);
|
bool contains(unsigned n, literal const* c);
|
||||||
bool contains(literal l1, literal l2) { literal lits[2] = {l1, l2}; return contains(2, lits); }
|
bool contains(literal l1, literal l2) { literal lits[2] = {l1, l2}; return contains(2, lits); }
|
||||||
bool contains(literal l1, literal l2, literal l3) { literal lits[3] = {l1, l2, l3}; return contains(3, lits); }
|
bool contains(literal l1, literal l2, literal l3) { literal lits[3] = {l1, l2, l3}; return contains(3, lits); }
|
||||||
|
bool contains(literal c, justification const& j);
|
||||||
|
|
||||||
void check_model(model const& m);
|
void check_model(model const& m);
|
||||||
};
|
};
|
||||||
|
|
|
@ -207,7 +207,7 @@ namespace sat {
|
||||||
c.update_approx();
|
c.update_approx();
|
||||||
}
|
}
|
||||||
if (m_solver.m_config.m_drat) {
|
if (m_solver.m_config.m_drat) {
|
||||||
m_solver.m_drat.add(c, true);
|
m_solver.m_drat.add(c, true);
|
||||||
drat_delete_clause();
|
drat_delete_clause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,6 @@ namespace sat {
|
||||||
reinit();
|
reinit();
|
||||||
DEBUG_CODE(verify_slack(););
|
DEBUG_CODE(verify_slack(););
|
||||||
timer timer;
|
timer timer;
|
||||||
timer.start();
|
|
||||||
unsigned step = 0, total_flips = 0, tries = 0;
|
unsigned step = 0, total_flips = 0, tries = 0;
|
||||||
|
|
||||||
for (tries = 1; !m_unsat_stack.empty() && m_limit.inc(); ++tries) {
|
for (tries = 1; !m_unsat_stack.empty() && m_limit.inc(); ++tries) {
|
||||||
|
|
|
@ -52,6 +52,9 @@ namespace sat {
|
||||||
unsigned tr_sz = s.m_trail.size();
|
unsigned tr_sz = s.m_trail.size();
|
||||||
for (unsigned i = old_tr_sz; i < tr_sz; i++) {
|
for (unsigned i = old_tr_sz; i < tr_sz; i++) {
|
||||||
entry.m_lits.push_back(s.m_trail[i]);
|
entry.m_lits.push_back(s.m_trail[i]);
|
||||||
|
if (s.m_config.m_drat) {
|
||||||
|
s.m_drat.add(~l, s.m_trail[i], true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,9 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void simplifier::remove_clause(clause & c) {
|
inline void simplifier::remove_clause(clause & c, bool is_unique) {
|
||||||
if (!c.was_removed()) {
|
if (!c.was_removed()) {
|
||||||
if (s.m_config.m_drat) {
|
if (s.m_config.m_drat && is_unique) {
|
||||||
s.m_drat.del(c);
|
s.m_drat.del(c);
|
||||||
}
|
}
|
||||||
for (literal l : c) {
|
for (literal l : c) {
|
||||||
|
@ -477,7 +477,7 @@ namespace sat {
|
||||||
s.set_learned(c1, false);
|
s.set_learned(c1, false);
|
||||||
}
|
}
|
||||||
TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";);
|
TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";);
|
||||||
remove_clause(c2);
|
remove_clause(c2, false);
|
||||||
m_num_subsumed++;
|
m_num_subsumed++;
|
||||||
}
|
}
|
||||||
else if (!c2.was_removed()) {
|
else if (!c2.was_removed()) {
|
||||||
|
@ -577,7 +577,7 @@ namespace sat {
|
||||||
if (c1.is_learned() && !c2.is_learned())
|
if (c1.is_learned() && !c2.is_learned())
|
||||||
s.set_learned(c1, false);
|
s.set_learned(c1, false);
|
||||||
TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";);
|
TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";);
|
||||||
remove_clause(c2);
|
remove_clause(c2, false);
|
||||||
m_num_subsumed++;
|
m_num_subsumed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -662,7 +662,7 @@ namespace sat {
|
||||||
for (auto it = cs.mk_iterator(); !it.at_end(); ) {
|
for (auto it = cs.mk_iterator(); !it.at_end(); ) {
|
||||||
clause & c = it.curr();
|
clause & c = it.curr();
|
||||||
it.next();
|
it.next();
|
||||||
remove_clause(c);
|
remove_clause(c, true);
|
||||||
}
|
}
|
||||||
cs.reset();
|
cs.reset();
|
||||||
}
|
}
|
||||||
|
@ -674,10 +674,12 @@ namespace sat {
|
||||||
m_num_elim_lits++;
|
m_num_elim_lits++;
|
||||||
insert_elim_todo(l.var());
|
insert_elim_todo(l.var());
|
||||||
if (s.m_config.m_drat && c.contains(l)) {
|
if (s.m_config.m_drat && c.contains(l)) {
|
||||||
m_dummy.set(c.size(), c.begin(), c.is_learned());
|
unsigned sz = c.size();
|
||||||
c.elim(l);
|
c.elim(l);
|
||||||
s.m_drat.add(c, true);
|
s.m_drat.add(c, true);
|
||||||
s.m_drat.del(*m_dummy.get());
|
c.restore(sz);
|
||||||
|
s.m_drat.del(c);
|
||||||
|
c.shrink(sz-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.elim(l);
|
c.elim(l);
|
||||||
|
@ -690,7 +692,7 @@ namespace sat {
|
||||||
if (cleanup_clause(c)) {
|
if (cleanup_clause(c)) {
|
||||||
// clause was satisfied
|
// clause was satisfied
|
||||||
TRACE("elim_lit", tout << "clause was satisfied\n";);
|
TRACE("elim_lit", tout << "clause was satisfied\n";);
|
||||||
remove_clause(c);
|
remove_clause(c, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned sz = c.size();
|
unsigned sz = c.size();
|
||||||
|
@ -710,7 +712,7 @@ namespace sat {
|
||||||
c.restore(sz0);
|
c.restore(sz0);
|
||||||
s.mk_bin_clause(c[0], c[1], c.is_learned());
|
s.mk_bin_clause(c[0], c[1], c.is_learned());
|
||||||
m_sub_bin_todo.push_back(bin_clause(c[0], c[1], c.is_learned()));
|
m_sub_bin_todo.push_back(bin_clause(c[0], c[1], c.is_learned()));
|
||||||
remove_clause(c);
|
remove_clause(c, sz0 != sz);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (s.m_config.m_drat && sz0 != sz) {
|
if (s.m_config.m_drat && sz0 != sz) {
|
||||||
|
@ -888,7 +890,7 @@ namespace sat {
|
||||||
if (s.m_trail.size() > m_last_sub_trail_sz) {
|
if (s.m_trail.size() > m_last_sub_trail_sz) {
|
||||||
unsigned sz0 = c.size();
|
unsigned sz0 = c.size();
|
||||||
if (cleanup_clause(c)) {
|
if (cleanup_clause(c)) {
|
||||||
remove_clause(c);
|
remove_clause(c, true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
unsigned sz = c.size();
|
unsigned sz = c.size();
|
||||||
|
@ -906,7 +908,7 @@ namespace sat {
|
||||||
s.mk_bin_clause(c[0], c[1], c.is_learned());
|
s.mk_bin_clause(c[0], c[1], c.is_learned());
|
||||||
m_sub_bin_todo.push_back(bin_clause(c[0], c[1], c.is_learned()));
|
m_sub_bin_todo.push_back(bin_clause(c[0], c[1], c.is_learned()));
|
||||||
c.restore(sz0);
|
c.restore(sz0);
|
||||||
remove_clause(c);
|
remove_clause(c, sz != sz0);
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
if (s.m_config.m_drat && sz != sz0) {
|
if (s.m_config.m_drat && sz != sz0) {
|
||||||
|
@ -1222,7 +1224,6 @@ namespace sat {
|
||||||
RI literals.
|
RI literals.
|
||||||
*/
|
*/
|
||||||
void minimize_covered_clause(unsigned idx) {
|
void minimize_covered_clause(unsigned idx) {
|
||||||
literal _blocked = m_covered_clause[idx];
|
|
||||||
for (literal l : m_tautology) VERIFY(s.is_marked(l));
|
for (literal l : m_tautology) VERIFY(s.is_marked(l));
|
||||||
for (literal l : m_covered_clause) s.unmark_visited(l);
|
for (literal l : m_covered_clause) s.unmark_visited(l);
|
||||||
for (literal l : m_tautology) s.mark_visited(l);
|
for (literal l : m_tautology) s.mark_visited(l);
|
||||||
|
|
|
@ -133,7 +133,7 @@ namespace sat {
|
||||||
|
|
||||||
void register_clauses(clause_vector & cs);
|
void register_clauses(clause_vector & cs);
|
||||||
|
|
||||||
void remove_clause(clause & c);
|
void remove_clause(clause & c, bool is_unique);
|
||||||
void set_learned(clause & c);
|
void set_learned(clause & c);
|
||||||
void set_learned(literal l1, literal l2);
|
void set_learned(literal l1, literal l2);
|
||||||
|
|
||||||
|
|
|
@ -27,25 +27,29 @@ Revision History:
|
||||||
#include "util/trace.h"
|
#include "util/trace.h"
|
||||||
#include "util/max_cliques.h"
|
#include "util/max_cliques.h"
|
||||||
#include "util/gparams.h"
|
#include "util/gparams.h"
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# include <xmmintrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// define to update glue during propagation
|
// define to update glue during propagation
|
||||||
#define UPDATE_GLUE
|
#define UPDATE_GLUE
|
||||||
|
|
||||||
namespace sat {
|
namespace sat {
|
||||||
|
|
||||||
|
|
||||||
solver::solver(params_ref const & p, reslimit& l):
|
solver::solver(params_ref const & p, reslimit& l):
|
||||||
solver_core(l),
|
solver_core(l),
|
||||||
m_checkpoint_enabled(true),
|
m_checkpoint_enabled(true),
|
||||||
m_config(p),
|
m_config(p),
|
||||||
m_par(nullptr),
|
m_par(nullptr),
|
||||||
m_cls_allocator_idx(false),
|
m_cls_allocator_idx(false),
|
||||||
|
m_drat(*this),
|
||||||
m_cleaner(*this),
|
m_cleaner(*this),
|
||||||
m_simplifier(*this, p),
|
m_simplifier(*this, p),
|
||||||
m_scc(*this, p),
|
m_scc(*this, p),
|
||||||
m_asymm_branch(*this, p),
|
m_asymm_branch(*this, p),
|
||||||
m_probing(*this, p),
|
m_probing(*this, p),
|
||||||
m_mus(*this),
|
m_mus(*this),
|
||||||
m_drat(*this),
|
|
||||||
m_inconsistent(false),
|
m_inconsistent(false),
|
||||||
m_searching(false),
|
m_searching(false),
|
||||||
m_num_frozen(0),
|
m_num_frozen(0),
|
||||||
|
@ -413,8 +417,6 @@ namespace sat {
|
||||||
clause * r = alloc_clause(3, lits, learned);
|
clause * r = alloc_clause(3, lits, learned);
|
||||||
bool reinit = attach_ter_clause(*r);
|
bool reinit = attach_ter_clause(*r);
|
||||||
if (reinit && !learned) push_reinit_stack(*r);
|
if (reinit && !learned) push_reinit_stack(*r);
|
||||||
if (m_config.m_drat) m_drat.add(*r, learned);
|
|
||||||
|
|
||||||
if (learned)
|
if (learned)
|
||||||
m_learned.push_back(r);
|
m_learned.push_back(r);
|
||||||
else
|
else
|
||||||
|
@ -424,6 +426,9 @@ namespace sat {
|
||||||
|
|
||||||
bool solver::attach_ter_clause(clause & c) {
|
bool solver::attach_ter_clause(clause & c) {
|
||||||
bool reinit = false;
|
bool reinit = false;
|
||||||
|
if (m_config.m_drat) m_drat.add(c, c.is_learned());
|
||||||
|
TRACE("sat", tout << c << "\n";);
|
||||||
|
SASSERT(!c.was_removed());
|
||||||
m_watches[(~c[0]).index()].push_back(watched(c[1], c[2]));
|
m_watches[(~c[0]).index()].push_back(watched(c[1], c[2]));
|
||||||
m_watches[(~c[1]).index()].push_back(watched(c[0], c[2]));
|
m_watches[(~c[1]).index()].push_back(watched(c[0], c[2]));
|
||||||
m_watches[(~c[2]).index()].push_back(watched(c[0], c[1]));
|
m_watches[(~c[2]).index()].push_back(watched(c[0], c[1]));
|
||||||
|
@ -459,8 +464,9 @@ namespace sat {
|
||||||
else {
|
else {
|
||||||
m_clauses.push_back(r);
|
m_clauses.push_back(r);
|
||||||
}
|
}
|
||||||
if (m_config.m_drat)
|
if (m_config.m_drat) {
|
||||||
m_drat.add(*r, learned);
|
m_drat.add(*r, learned);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1157,6 +1163,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
catch (const abort_solver &) {
|
catch (const abort_solver &) {
|
||||||
m_reason_unknown = "sat.giveup";
|
m_reason_unknown = "sat.giveup";
|
||||||
|
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort giveup\")\n";);
|
||||||
return l_undef;
|
return l_undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1779,39 +1786,31 @@ namespace sat {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IF_VERBOSE(10, verbose_stream() << "\"checking model\"\n";);
|
|
||||||
if (!check_clauses(m_model)) {
|
|
||||||
throw solver_exception("check model failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_config.m_drat) m_drat.check_model(m_model);
|
|
||||||
|
|
||||||
// m_mc.set_solver(nullptr);
|
|
||||||
m_mc(m_model);
|
|
||||||
|
|
||||||
if (!check_clauses(m_model)) {
|
|
||||||
IF_VERBOSE(0, verbose_stream() << "failure checking clauses on transformed model\n";);
|
|
||||||
IF_VERBOSE(10, m_mc.display(verbose_stream()));
|
|
||||||
//IF_VERBOSE(0, display_units(verbose_stream()));
|
|
||||||
//IF_VERBOSE(0, display(verbose_stream()));
|
|
||||||
IF_VERBOSE(0, for (bool_var v = 0; v < num; v++) verbose_stream() << v << ": " << m_model[v] << "\n";);
|
|
||||||
|
|
||||||
throw solver_exception("check model failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("sat", for (bool_var v = 0; v < num; v++) tout << v << ": " << m_model[v] << "\n";);
|
|
||||||
|
|
||||||
if (m_clone) {
|
if (m_clone) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "\"checking model (on original set of clauses)\"\n";);
|
IF_VERBOSE(10, verbose_stream() << "\"checking model\"\n";);
|
||||||
if (!m_clone->check_model(m_model)) {
|
if (!check_clauses(m_model)) {
|
||||||
//IF_VERBOSE(0, display(verbose_stream()));
|
throw solver_exception("check model failed");
|
||||||
//IF_VERBOSE(0, display_watches(verbose_stream()));
|
|
||||||
IF_VERBOSE(0, m_mc.display(verbose_stream()));
|
|
||||||
IF_VERBOSE(0, display_units(verbose_stream()));
|
|
||||||
//IF_VERBOSE(0, m_clone->display(verbose_stream() << "clone\n"));
|
|
||||||
throw solver_exception("check model failed (for cloned solver)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_config.m_drat) {
|
||||||
|
m_drat.check_model(m_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mc(m_model);
|
||||||
|
|
||||||
|
if (m_clone && !check_clauses(m_model)) {
|
||||||
|
IF_VERBOSE(1, verbose_stream() << "failure checking clauses on transformed model\n";);
|
||||||
|
IF_VERBOSE(10, m_mc.display(verbose_stream()));
|
||||||
|
IF_VERBOSE(10, display_model(verbose_stream()));
|
||||||
|
throw solver_exception("check model failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_clone && !m_clone->check_model(m_model)) {
|
||||||
|
IF_VERBOSE(1, m_mc.display(verbose_stream()));
|
||||||
|
IF_VERBOSE(1, display_units(verbose_stream()));
|
||||||
|
throw solver_exception("check model failed (for cloned solver)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::check_clauses(model const& m) const {
|
bool solver::check_clauses(model const& m) const {
|
||||||
|
@ -1819,7 +1818,7 @@ namespace sat {
|
||||||
for (clause const* cp : m_clauses) {
|
for (clause const* cp : m_clauses) {
|
||||||
clause const & c = *cp;
|
clause const & c = *cp;
|
||||||
if (!c.satisfied_by(m)) {
|
if (!c.satisfied_by(m)) {
|
||||||
IF_VERBOSE(0, verbose_stream() << "failed clause " << c.id() << ": " << c << "\n";);
|
IF_VERBOSE(1, verbose_stream() << "failed clause " << c.id() << ": " << c << "\n";);
|
||||||
TRACE("sat", tout << "failed: " << c << "\n";
|
TRACE("sat", tout << "failed: " << c << "\n";
|
||||||
tout << "assumptions: " << m_assumptions << "\n";
|
tout << "assumptions: " << m_assumptions << "\n";
|
||||||
tout << "trail: " << m_trail << "\n";
|
tout << "trail: " << m_trail << "\n";
|
||||||
|
@ -1827,7 +1826,7 @@ namespace sat {
|
||||||
m_mc.display(tout);
|
m_mc.display(tout);
|
||||||
);
|
);
|
||||||
for (literal l : c) {
|
for (literal l : c) {
|
||||||
if (was_eliminated(l.var())) IF_VERBOSE(0, verbose_stream() << "eliminated: " << l << "\n";);
|
if (was_eliminated(l.var())) IF_VERBOSE(1, verbose_stream() << "eliminated: " << l << "\n";);
|
||||||
}
|
}
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -1843,8 +1842,8 @@ namespace sat {
|
||||||
if (l.index() > l2.index())
|
if (l.index() > l2.index())
|
||||||
continue;
|
continue;
|
||||||
if (value_at(l2, m) != l_true) {
|
if (value_at(l2, m) != l_true) {
|
||||||
IF_VERBOSE(0, verbose_stream() << "failed binary: " << l << " := " << value_at(l, m) << " " << l2 << " := " << value_at(l2, m) << "\n");
|
IF_VERBOSE(1, verbose_stream() << "failed binary: " << l << " := " << value_at(l, m) << " " << l2 << " := " << value_at(l2, m) << "\n");
|
||||||
IF_VERBOSE(0, verbose_stream() << "elim l1: " << was_eliminated(l.var()) << " elim l2: " << was_eliminated(l2) << "\n");
|
IF_VERBOSE(1, verbose_stream() << "elim l1: " << was_eliminated(l.var()) << " elim l2: " << was_eliminated(l2) << "\n");
|
||||||
TRACE("sat", m_mc.display(tout << "failed binary: " << l << " " << l2 << "\n"););
|
TRACE("sat", m_mc.display(tout << "failed binary: " << l << " " << l2 << "\n"););
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
@ -1855,7 +1854,7 @@ namespace sat {
|
||||||
for (literal l : m_assumptions) {
|
for (literal l : m_assumptions) {
|
||||||
if (value_at(l, m) != l_true) {
|
if (value_at(l, m) != l_true) {
|
||||||
VERIFY(is_external(l.var()));
|
VERIFY(is_external(l.var()));
|
||||||
IF_VERBOSE(0, verbose_stream() << "assumption: " << l << " does not model check " << value_at(l, m) << "\n";);
|
IF_VERBOSE(1, verbose_stream() << "assumption: " << l << " does not model check " << value_at(l, m) << "\n";);
|
||||||
TRACE("sat",
|
TRACE("sat",
|
||||||
tout << l << " does not model check\n";
|
tout << l << " does not model check\n";
|
||||||
tout << "trail: " << m_trail << "\n";
|
tout << "trail: " << m_trail << "\n";
|
||||||
|
@ -1876,8 +1875,8 @@ namespace sat {
|
||||||
if (ok && !m_mc.check_model(m)) {
|
if (ok && !m_mc.check_model(m)) {
|
||||||
ok = false;
|
ok = false;
|
||||||
TRACE("sat", tout << "model: " << m << "\n"; m_mc.display(tout););
|
TRACE("sat", tout << "model: " << m << "\n"; m_mc.display(tout););
|
||||||
|
IF_VERBOSE(0, verbose_stream() << "model check failed\n");
|
||||||
}
|
}
|
||||||
IF_VERBOSE(1, verbose_stream() << "model check " << (ok?"OK":"failed") << "\n";);
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2170,6 +2169,36 @@ namespace sat {
|
||||||
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat-gc :strategy " << st_name << " :deleted " << (sz - new_sz) << ")\n";);
|
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat-gc :strategy " << st_name << " :deleted " << (sz - new_sz) << ")\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool solver::can_delete3(literal l1, literal l2, literal l3) const {
|
||||||
|
if (value(l1) == l_true &&
|
||||||
|
value(l2) == l_false &&
|
||||||
|
value(l3) == l_false) {
|
||||||
|
justification const& j = m_justification[l1.var()];
|
||||||
|
if (j.is_ternary_clause()) {
|
||||||
|
watched w1(l2, l3);
|
||||||
|
watched w2(j.get_literal1(), j.get_literal2());
|
||||||
|
return w1 != w2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool solver::can_delete(clause const & c) const {
|
||||||
|
if (c.on_reinit_stack())
|
||||||
|
return false;
|
||||||
|
if (c.size() == 3) {
|
||||||
|
return
|
||||||
|
can_delete3(c[0],c[1],c[2]) &&
|
||||||
|
can_delete3(c[1],c[0],c[2]) &&
|
||||||
|
can_delete3(c[2],c[0],c[1]);
|
||||||
|
}
|
||||||
|
literal l0 = c[0];
|
||||||
|
if (value(l0) != l_true)
|
||||||
|
return true;
|
||||||
|
justification const & jst = m_justification[l0.var()];
|
||||||
|
return !jst.is_clause() || cls_allocator().get_clause(jst.get_clause_offset()) != &c;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Use gc based on dynamic psm. Clauses are initially frozen.
|
\brief Use gc based on dynamic psm. Clauses are initially frozen.
|
||||||
*/
|
*/
|
||||||
|
@ -2388,6 +2417,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_lemma.reset();
|
m_lemma.reset();
|
||||||
|
|
||||||
unsigned idx = skip_literals_above_conflict_level();
|
unsigned idx = skip_literals_above_conflict_level();
|
||||||
|
@ -2408,6 +2438,7 @@ namespace sat {
|
||||||
do {
|
do {
|
||||||
TRACE("sat_conflict_detail", tout << "processing consequent: " << consequent << "\n";
|
TRACE("sat_conflict_detail", tout << "processing consequent: " << consequent << "\n";
|
||||||
tout << "num_marks: " << num_marks << ", js: " << js << "\n";);
|
tout << "num_marks: " << num_marks << ", js: " << js << "\n";);
|
||||||
|
|
||||||
switch (js.get_kind()) {
|
switch (js.get_kind()) {
|
||||||
case justification::NONE:
|
case justification::NONE:
|
||||||
break;
|
break;
|
||||||
|
@ -2462,6 +2493,8 @@ namespace sat {
|
||||||
idx--;
|
idx--;
|
||||||
num_marks--;
|
num_marks--;
|
||||||
reset_mark(c_var);
|
reset_mark(c_var);
|
||||||
|
|
||||||
|
TRACE("sat", display_justification(tout << consequent << " ", js) << "\n";);
|
||||||
}
|
}
|
||||||
while (num_marks > 0);
|
while (num_marks > 0);
|
||||||
|
|
||||||
|
@ -2474,12 +2507,13 @@ namespace sat {
|
||||||
TRACE("sat_lemma", tout << "new lemma size: " << m_lemma.size() << "\n" << m_lemma << "\n";);
|
TRACE("sat_lemma", tout << "new lemma size: " << m_lemma.size() << "\n" << m_lemma << "\n";);
|
||||||
|
|
||||||
unsigned new_scope_lvl = 0;
|
unsigned new_scope_lvl = 0;
|
||||||
|
bool sub_min = false, res_min = false;
|
||||||
if (!m_lemma.empty()) {
|
if (!m_lemma.empty()) {
|
||||||
if (m_config.m_minimize_lemmas) {
|
if (m_config.m_minimize_lemmas) {
|
||||||
minimize_lemma();
|
res_min = minimize_lemma();
|
||||||
reset_lemma_var_marks();
|
reset_lemma_var_marks();
|
||||||
if (m_config.m_dyn_sub_res)
|
if (m_config.m_dyn_sub_res)
|
||||||
dyn_sub_res();
|
sub_min = dyn_sub_res();
|
||||||
TRACE("sat_lemma", tout << "new lemma (after minimization) size: " << m_lemma.size() << "\n" << m_lemma << "\n";);
|
TRACE("sat_lemma", tout << "new lemma (after minimization) size: " << m_lemma.size() << "\n" << m_lemma << "\n";);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2499,12 +2533,12 @@ namespace sat {
|
||||||
m_slow_glue_avg.update(glue);
|
m_slow_glue_avg.update(glue);
|
||||||
pop_reinit(m_scope_lvl - new_scope_lvl);
|
pop_reinit(m_scope_lvl - new_scope_lvl);
|
||||||
TRACE("sat_conflict_detail", tout << glue << " " << new_scope_lvl << "\n";);
|
TRACE("sat_conflict_detail", tout << glue << " " << new_scope_lvl << "\n";);
|
||||||
// unsound: m_asymm_branch.minimize(m_scc, m_lemma);
|
|
||||||
clause * lemma = mk_clause_core(m_lemma.size(), m_lemma.c_ptr(), true);
|
clause * lemma = mk_clause_core(m_lemma.size(), m_lemma.c_ptr(), true);
|
||||||
if (lemma) {
|
if (lemma) {
|
||||||
lemma->set_glue(glue);
|
lemma->set_glue(glue);
|
||||||
if (m_par) m_par->share_clause(*this, *lemma);
|
if (m_par) m_par->share_clause(*this, *lemma);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("sat_conflict_detail", tout << new_scope_lvl << "\n";);
|
TRACE("sat_conflict_detail", tout << new_scope_lvl << "\n";);
|
||||||
decay_activity();
|
decay_activity();
|
||||||
updt_phase_counters();
|
updt_phase_counters();
|
||||||
|
@ -2851,7 +2885,7 @@ namespace sat {
|
||||||
if (m_lvl_set.may_contain(var_lvl)) {
|
if (m_lvl_set.may_contain(var_lvl)) {
|
||||||
mark(var);
|
mark(var);
|
||||||
m_unmark.push_back(var);
|
m_unmark.push_back(var);
|
||||||
m_lemma_min_stack.push_back(var);
|
m_lemma_min_stack.push_back(antecedent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2869,11 +2903,12 @@ namespace sat {
|
||||||
*/
|
*/
|
||||||
bool solver::implied_by_marked(literal lit) {
|
bool solver::implied_by_marked(literal lit) {
|
||||||
m_lemma_min_stack.reset(); // avoid recursive function
|
m_lemma_min_stack.reset(); // avoid recursive function
|
||||||
m_lemma_min_stack.push_back(lit.var());
|
m_lemma_min_stack.push_back(lit);
|
||||||
unsigned old_size = m_unmark.size();
|
unsigned old_size = m_unmark.size();
|
||||||
|
|
||||||
while (!m_lemma_min_stack.empty()) {
|
while (!m_lemma_min_stack.empty()) {
|
||||||
bool_var var = m_lemma_min_stack.back();
|
lit = m_lemma_min_stack.back();
|
||||||
|
bool_var var = lit.var();
|
||||||
m_lemma_min_stack.pop_back();
|
m_lemma_min_stack.pop_back();
|
||||||
justification const& js = m_justification[var];
|
justification const& js = m_justification[var];
|
||||||
switch(js.get_kind()) {
|
switch(js.get_kind()) {
|
||||||
|
@ -2935,6 +2970,8 @@ namespace sat {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
TRACE("sat_conflict",
|
||||||
|
display_justification(tout << var << " ",js) << "\n";);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2965,7 +3002,7 @@ namespace sat {
|
||||||
literals that are implied by other literals in m_lemma and/or literals
|
literals that are implied by other literals in m_lemma and/or literals
|
||||||
assigned at level 0.
|
assigned at level 0.
|
||||||
*/
|
*/
|
||||||
void solver::minimize_lemma() {
|
bool solver::minimize_lemma() {
|
||||||
SASSERT(!m_lemma.empty());
|
SASSERT(!m_lemma.empty());
|
||||||
SASSERT(m_unmark.empty());
|
SASSERT(m_unmark.empty());
|
||||||
updt_lemma_lvl_set();
|
updt_lemma_lvl_set();
|
||||||
|
@ -2989,6 +3026,7 @@ namespace sat {
|
||||||
reset_unmark(0);
|
reset_unmark(0);
|
||||||
m_lemma.shrink(j);
|
m_lemma.shrink(j);
|
||||||
m_stats.m_minimized_lits += sz - j;
|
m_stats.m_minimized_lits += sz - j;
|
||||||
|
return j < sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3062,7 +3100,7 @@ namespace sat {
|
||||||
\brief Apply dynamic subsumption resolution to new lemma.
|
\brief Apply dynamic subsumption resolution to new lemma.
|
||||||
Only binary and ternary clauses are used.
|
Only binary and ternary clauses are used.
|
||||||
*/
|
*/
|
||||||
void solver::dyn_sub_res() {
|
bool solver::dyn_sub_res() {
|
||||||
unsigned sz = m_lemma.size();
|
unsigned sz = m_lemma.size();
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
mark_lit(m_lemma[i]);
|
mark_lit(m_lemma[i]);
|
||||||
|
@ -3175,6 +3213,7 @@ namespace sat {
|
||||||
|
|
||||||
SASSERT(j >= 1);
|
SASSERT(j >= 1);
|
||||||
m_lemma.shrink(j);
|
m_lemma.shrink(j);
|
||||||
|
return j < sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3543,6 +3582,14 @@ namespace sat {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& solver::display_model(std::ostream& out) const {
|
||||||
|
unsigned num = num_vars();
|
||||||
|
for (bool_var v = 0; v < num; v++) {
|
||||||
|
out << v << ": " << m_model[v] << "\n";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void solver::display_binary(std::ostream & out) const {
|
void solver::display_binary(std::ostream & out) const {
|
||||||
unsigned sz = m_watches.size();
|
unsigned sz = m_watches.size();
|
||||||
for (unsigned l_idx = 0; l_idx < sz; l_idx++) {
|
for (unsigned l_idx = 0; l_idx < sz; l_idx++) {
|
||||||
|
|
|
@ -85,9 +85,10 @@ namespace sat {
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
scoped_ptr<extension> m_ext;
|
scoped_ptr<extension> m_ext;
|
||||||
parallel* m_par;
|
parallel* m_par;
|
||||||
random_gen m_rand;
|
drat m_drat; // DRAT for generating proofs
|
||||||
clause_allocator m_cls_allocator[2];
|
clause_allocator m_cls_allocator[2];
|
||||||
bool m_cls_allocator_idx;
|
bool m_cls_allocator_idx;
|
||||||
|
random_gen m_rand;
|
||||||
cleaner m_cleaner;
|
cleaner m_cleaner;
|
||||||
model m_model;
|
model m_model;
|
||||||
model_converter m_mc;
|
model_converter m_mc;
|
||||||
|
@ -97,7 +98,6 @@ namespace sat {
|
||||||
asymm_branch m_asymm_branch;
|
asymm_branch m_asymm_branch;
|
||||||
probing m_probing;
|
probing m_probing;
|
||||||
mus m_mus; // MUS for minimal core extraction
|
mus m_mus; // MUS for minimal core extraction
|
||||||
drat m_drat; // DRAT for generating proofs
|
|
||||||
bool m_inconsistent;
|
bool m_inconsistent;
|
||||||
bool m_searching;
|
bool m_searching;
|
||||||
// A conflict is usually a single justification. That is, a justification
|
// A conflict is usually a single justification. That is, a justification
|
||||||
|
@ -328,6 +328,7 @@ namespace sat {
|
||||||
if (!m_rlimit.inc()) {
|
if (!m_rlimit.inc()) {
|
||||||
m_mc.reset();
|
m_mc.reset();
|
||||||
m_model_is_current = false;
|
m_model_is_current = false;
|
||||||
|
TRACE("sat", tout << "canceled\n";);
|
||||||
throw solver_exception(Z3_CANCELED_MSG);
|
throw solver_exception(Z3_CANCELED_MSG);
|
||||||
}
|
}
|
||||||
++m_num_checkpoints;
|
++m_num_checkpoints;
|
||||||
|
@ -384,7 +385,7 @@ namespace sat {
|
||||||
model_converter const & get_model_converter() const { return m_mc; }
|
model_converter const & get_model_converter() const { return m_mc; }
|
||||||
void flush(model_converter& mc) override { mc.flush(m_mc); }
|
void flush(model_converter& mc) override { mc.flush(m_mc); }
|
||||||
void set_model(model const& mdl);
|
void set_model(model const& mdl);
|
||||||
char const* get_reason_unknown() const { return m_reason_unknown.c_str(); }
|
char const* get_reason_unknown() const override { return m_reason_unknown.c_str(); }
|
||||||
bool check_clauses(model const& m) const;
|
bool check_clauses(model const& m) const;
|
||||||
bool is_assumption(bool_var v) const;
|
bool is_assumption(bool_var v) const;
|
||||||
void set_activity(bool_var v, unsigned act);
|
void set_activity(bool_var v, unsigned act);
|
||||||
|
@ -460,17 +461,8 @@ namespace sat {
|
||||||
void gc_dyn_psm();
|
void gc_dyn_psm();
|
||||||
bool activate_frozen_clause(clause & c);
|
bool activate_frozen_clause(clause & c);
|
||||||
unsigned psm(clause const & c) const;
|
unsigned psm(clause const & c) const;
|
||||||
bool can_delete(clause const & c) const {
|
bool can_delete(clause const & c) const;
|
||||||
if (c.on_reinit_stack())
|
bool can_delete3(literal l1, literal l2, literal l3) const;
|
||||||
return false;
|
|
||||||
if (c.size() == 3)
|
|
||||||
return true; // not needed to justify anything.
|
|
||||||
literal l0 = c[0];
|
|
||||||
if (value(l0) != l_true)
|
|
||||||
return true;
|
|
||||||
justification const & jst = m_justification[l0.var()];
|
|
||||||
return !jst.is_clause() || cls_allocator().get_clause(jst.get_clause_offset()) != &c;
|
|
||||||
}
|
|
||||||
|
|
||||||
clause& get_clause(watch_list::iterator it) const {
|
clause& get_clause(watch_list::iterator it) const {
|
||||||
SASSERT(it->get_kind() == watched::CLAUSE);
|
SASSERT(it->get_kind() == watched::CLAUSE);
|
||||||
|
@ -521,14 +513,14 @@ namespace sat {
|
||||||
typedef approx_set_tpl<unsigned, u2u, unsigned> level_approx_set;
|
typedef approx_set_tpl<unsigned, u2u, unsigned> level_approx_set;
|
||||||
bool_var_vector m_unmark;
|
bool_var_vector m_unmark;
|
||||||
level_approx_set m_lvl_set;
|
level_approx_set m_lvl_set;
|
||||||
bool_var_vector m_lemma_min_stack;
|
literal_vector m_lemma_min_stack;
|
||||||
bool process_antecedent_for_minimization(literal antecedent);
|
bool process_antecedent_for_minimization(literal antecedent);
|
||||||
bool implied_by_marked(literal lit);
|
bool implied_by_marked(literal lit);
|
||||||
void reset_unmark(unsigned old_size);
|
void reset_unmark(unsigned old_size);
|
||||||
void updt_lemma_lvl_set();
|
void updt_lemma_lvl_set();
|
||||||
void minimize_lemma();
|
|
||||||
void reset_lemma_var_marks();
|
void reset_lemma_var_marks();
|
||||||
void dyn_sub_res();
|
bool minimize_lemma();
|
||||||
|
bool dyn_sub_res();
|
||||||
|
|
||||||
// -----------------------
|
// -----------------------
|
||||||
//
|
//
|
||||||
|
@ -668,6 +660,7 @@ namespace sat {
|
||||||
void display_watches(std::ostream & out) const;
|
void display_watches(std::ostream & out) const;
|
||||||
void display_watches(std::ostream & out, literal lit) const;
|
void display_watches(std::ostream & out, literal lit) const;
|
||||||
void display_dimacs(std::ostream & out) const override;
|
void display_dimacs(std::ostream & out) const override;
|
||||||
|
std::ostream& display_model(std::ostream& out) const;
|
||||||
void display_wcnf(std::ostream & out, unsigned sz, literal const* lits, unsigned const* weights) const;
|
void display_wcnf(std::ostream & out, unsigned sz, literal const* lits, unsigned const* weights) const;
|
||||||
void display_assignment(std::ostream & out) const;
|
void display_assignment(std::ostream & out) const;
|
||||||
std::ostream& display_justification(std::ostream & out, justification const& j) const;
|
std::ostream& display_justification(std::ostream & out, justification const& j) const;
|
||||||
|
|
|
@ -50,6 +50,8 @@ namespace sat {
|
||||||
// check satisfiability
|
// check satisfiability
|
||||||
virtual lbool check(unsigned num_lits = 0, literal const* lits = nullptr) = 0;
|
virtual lbool check(unsigned num_lits = 0, literal const* lits = nullptr) = 0;
|
||||||
|
|
||||||
|
virtual char const* get_reason_unknown() const { return "reason unavailable"; }
|
||||||
|
|
||||||
// add clauses
|
// add clauses
|
||||||
virtual void add_clause(unsigned n, literal* lits, bool is_redundant) = 0;
|
virtual void add_clause(unsigned n, literal* lits, bool is_redundant) = 0;
|
||||||
void add_clause(literal l1, literal l2, bool is_redundant) {
|
void add_clause(literal l1, literal l2, bool is_redundant) {
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace sat {
|
||||||
while (s.rlimit().inc() && st == l_undef) {
|
while (s.rlimit().inc() && st == l_undef) {
|
||||||
if (inconsistent() && !m_decisions.empty()) do_pop();
|
if (inconsistent() && !m_decisions.empty()) do_pop();
|
||||||
else if (inconsistent()) st = l_false;
|
else if (inconsistent()) st = l_false;
|
||||||
|
else if (should_restart()) restart();
|
||||||
else if (should_backjump()) st = do_backjump();
|
else if (should_backjump()) st = do_backjump();
|
||||||
else st = decide();
|
else st = decide();
|
||||||
}
|
}
|
||||||
|
@ -276,9 +277,6 @@ namespace sat {
|
||||||
init_runs();
|
init_runs();
|
||||||
init_phase();
|
init_phase();
|
||||||
}
|
}
|
||||||
if (false && should_restart()) {
|
|
||||||
restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unit_walk::should_restart() {
|
bool unit_walk::should_restart() {
|
||||||
|
@ -287,9 +285,7 @@ namespace sat {
|
||||||
++m_luby_index;
|
++m_luby_index;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_walk::restart() {
|
void unit_walk::restart() {
|
||||||
|
@ -328,9 +324,9 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_walk::propagate() {
|
void unit_walk::propagate() {
|
||||||
while (m_qhead < m_trail.size() && !inconsistent())
|
while (m_qhead < m_trail.size() && !inconsistent()) {
|
||||||
propagate(choose_literal());
|
propagate(m_trail[m_qhead++]);
|
||||||
// IF_VERBOSE(1, verbose_stream() << m_trail.size() << " " << inconsistent() << "\n";);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& unit_walk::display(std::ostream& out) const {
|
std::ostream& unit_walk::display(std::ostream& out) const {
|
||||||
|
@ -495,10 +491,6 @@ namespace sat {
|
||||||
<< ")\n";);
|
<< ")\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
literal unit_walk::choose_literal() {
|
|
||||||
return m_trail[m_qhead++];
|
|
||||||
}
|
|
||||||
|
|
||||||
void unit_walk::set_conflict(literal l1, literal l2) {
|
void unit_walk::set_conflict(literal l1, literal l2) {
|
||||||
set_conflict();
|
set_conflict();
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,6 @@ namespace sat {
|
||||||
void flip_phase(literal l);
|
void flip_phase(literal l);
|
||||||
void propagate();
|
void propagate();
|
||||||
void propagate(literal lit);
|
void propagate(literal lit);
|
||||||
literal choose_literal();
|
|
||||||
void set_conflict(literal l1, literal l2);
|
void set_conflict(literal l1, literal l2);
|
||||||
void set_conflict(literal l1, literal l2, literal l3);
|
void set_conflict(literal l1, literal l2, literal l3);
|
||||||
void set_conflict(clause const& c);
|
void set_conflict(clause const& c);
|
||||||
|
|
|
@ -86,7 +86,15 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wlist.set_end(it2);
|
wlist.set_end(it2);
|
||||||
//VERIFY(found);
|
#if 0
|
||||||
|
VERIFY(found);
|
||||||
|
for (watched const& w2 : wlist) {
|
||||||
|
if (w2 == w) {
|
||||||
|
std::cout << l1 << " " << l2 << "\n";
|
||||||
|
}
|
||||||
|
//VERIFY(w2 != w);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void conflict_cleanup(watch_list::iterator it, watch_list::iterator it2, watch_list& wlist) {
|
void conflict_cleanup(watch_list::iterator it, watch_list::iterator it2, watch_list& wlist) {
|
||||||
|
|
|
@ -65,6 +65,7 @@ class sat_tactic : public tactic {
|
||||||
TRACE("sat_dimacs", m_solver->display_dimacs(tout););
|
TRACE("sat_dimacs", m_solver->display_dimacs(tout););
|
||||||
dep2assumptions(dep2asm, assumptions);
|
dep2assumptions(dep2asm, assumptions);
|
||||||
lbool r = m_solver->check(assumptions.size(), assumptions.c_ptr());
|
lbool r = m_solver->check(assumptions.size(), assumptions.c_ptr());
|
||||||
|
TRACE("sat", tout << "result of checking: " << r << " " << m_solver->get_reason_unknown() << "\n";);
|
||||||
if (r == l_false) {
|
if (r == l_false) {
|
||||||
expr_dependency * lcore = nullptr;
|
expr_dependency * lcore = nullptr;
|
||||||
if (produce_core) {
|
if (produce_core) {
|
||||||
|
@ -198,6 +199,11 @@ public:
|
||||||
proc.m_solver->collect_statistics(m_stats);
|
proc.m_solver->collect_statistics(m_stats);
|
||||||
throw tactic_exception(ex.msg());
|
throw tactic_exception(ex.msg());
|
||||||
}
|
}
|
||||||
|
catch (z3_exception& ex) {
|
||||||
|
(void)ex;
|
||||||
|
TRACE("sat", tout << ex.msg() << "\n";);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
TRACE("sat_stats", m_stats.display_smt2(tout););
|
TRACE("sat_stats", m_stats.display_smt2(tout););
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ void display_usage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_cmd_line_args(int argc, char ** argv) {
|
void parse_cmd_line_args(int argc, char ** argv) {
|
||||||
|
long timeout = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
char * eq_pos = nullptr;
|
char * eq_pos = nullptr;
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
|
@ -216,8 +217,7 @@ void parse_cmd_line_args(int argc, char ** argv) {
|
||||||
else if (strcmp(opt_name, "T") == 0) {
|
else if (strcmp(opt_name, "T") == 0) {
|
||||||
if (!opt_arg)
|
if (!opt_arg)
|
||||||
error("option argument (-T:timeout) is missing.");
|
error("option argument (-T:timeout) is missing.");
|
||||||
long tm = strtol(opt_arg, nullptr, 10);
|
timeout = strtol(opt_arg, nullptr, 10);
|
||||||
set_timeout(tm * 1000);
|
|
||||||
}
|
}
|
||||||
else if (strcmp(opt_name, "t") == 0) {
|
else if (strcmp(opt_name, "t") == 0) {
|
||||||
if (!opt_arg)
|
if (!opt_arg)
|
||||||
|
@ -292,6 +292,9 @@ void parse_cmd_line_args(int argc, char ** argv) {
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
set_timeout(timeout * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3496,7 +3496,6 @@ namespace smt {
|
||||||
m_case_split_queue ->init_search_eh();
|
m_case_split_queue ->init_search_eh();
|
||||||
m_next_progress_sample = 0;
|
m_next_progress_sample = 0;
|
||||||
TRACE("literal_occ", display_literal_num_occs(tout););
|
TRACE("literal_occ", display_literal_num_occs(tout););
|
||||||
m_timer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::end_search() {
|
void context::end_search() {
|
||||||
|
|
|
@ -156,6 +156,14 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_activity(expr* lit, double act) {
|
void set_activity(expr* lit, double act) {
|
||||||
|
SASSERT(m().is_bool(lit));
|
||||||
|
m().is_not(lit, lit);
|
||||||
|
if (!m_kernel.b_internalized(lit)) {
|
||||||
|
m_kernel.internalize(lit, false);
|
||||||
|
}
|
||||||
|
if (!m_kernel.b_internalized(lit)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto v = m_kernel.get_bool_var(lit);
|
auto v = m_kernel.get_bool_var(lit);
|
||||||
double old_act = m_kernel.get_activity(v);
|
double old_act = m_kernel.get_activity(v);
|
||||||
m_kernel.set_activity(v, act);
|
m_kernel.set_activity(v, act);
|
||||||
|
|
|
@ -499,7 +499,10 @@ namespace smt {
|
||||||
|
|
||||||
std::ostream& theory_jobscheduler::display(std::ostream & out, job_resource const& jr) const {
|
std::ostream& theory_jobscheduler::display(std::ostream & out, job_resource const& jr) const {
|
||||||
return out << "r:" << jr.m_resource_id << " cap:" << jr.m_capacity << " load:" << jr.m_loadpct << " end:" << jr.m_finite_capacity_end;
|
return out << "r:" << jr.m_resource_id << " cap:" << jr.m_capacity << " load:" << jr.m_loadpct << " end:" << jr.m_finite_capacity_end;
|
||||||
for (auto const& s : jr.m_properties) out << " " << s; out << "\n";
|
for (auto const& s : jr.m_properties) {
|
||||||
|
out << " " << s;
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& theory_jobscheduler::display(std::ostream & out, job_info const& j) const {
|
std::ostream& theory_jobscheduler::display(std::ostream & out, job_info const& j) const {
|
||||||
|
@ -511,7 +514,10 @@ namespace smt {
|
||||||
|
|
||||||
std::ostream& theory_jobscheduler::display(std::ostream & out, res_available const& r) const {
|
std::ostream& theory_jobscheduler::display(std::ostream & out, res_available const& r) const {
|
||||||
return out << "[" << r.m_start << ":" << r.m_end << "] @ " << r.m_loadpct << "%";
|
return out << "[" << r.m_start << ":" << r.m_end << "] @ " << r.m_loadpct << "%";
|
||||||
for (auto const& s : r.m_properties) out << " " << s; out << "\n";
|
for (auto const& s : r.m_properties) {
|
||||||
|
out << " " << s;
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& theory_jobscheduler::display(std::ostream & out, res_info const& r) const {
|
std::ostream& theory_jobscheduler::display(std::ostream & out, res_info const& r) const {
|
||||||
|
|
|
@ -80,6 +80,7 @@ bool smt_logics::logic_has_arith(symbol const & s) {
|
||||||
s == "LRA" ||
|
s == "LRA" ||
|
||||||
s == "UFIDL" ||
|
s == "UFIDL" ||
|
||||||
s == "QF_FP" ||
|
s == "QF_FP" ||
|
||||||
|
s == "FP" ||
|
||||||
s == "QF_FPBV" ||
|
s == "QF_FPBV" ||
|
||||||
s == "QF_BVFP" ||
|
s == "QF_BVFP" ||
|
||||||
s == "QF_S" ||
|
s == "QF_S" ||
|
||||||
|
@ -101,6 +102,7 @@ bool smt_logics::logic_has_bv(symbol const & s) {
|
||||||
s == "QF_AUFBV" ||
|
s == "QF_AUFBV" ||
|
||||||
s == "QF_BVRE" ||
|
s == "QF_BVRE" ||
|
||||||
s == "QF_FPBV" ||
|
s == "QF_FPBV" ||
|
||||||
|
s == "FP" ||
|
||||||
s == "QF_BVFP" ||
|
s == "QF_BVFP" ||
|
||||||
logic_is_allcsp(s) ||
|
logic_is_allcsp(s) ||
|
||||||
s == "QF_FD" ||
|
s == "QF_FD" ||
|
||||||
|
@ -138,7 +140,7 @@ bool smt_logics::logic_has_str(symbol const & s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_fpa(symbol const & s) {
|
bool smt_logics::logic_has_fpa(symbol const & s) {
|
||||||
return s == "QF_FP" || s == "QF_FPBV" || s == "QF_BVFP" || s == "QF_FPLRA" || logic_is_allcsp(s);
|
return s == "FP" || s == "QF_FP" || s == "QF_FPBV" || s == "QF_BVFP" || s == "QF_FPLRA" || logic_is_allcsp(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_uf(symbol const & s) {
|
bool smt_logics::logic_has_uf(symbol const & s) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
||||||
#include "tactic/tactical.h"
|
#include "tactic/tactical.h"
|
||||||
#include "ast/arith_decl_plugin.h"
|
#include "ast/arith_decl_plugin.h"
|
||||||
#include "ast/bv_decl_plugin.h"
|
#include "ast/bv_decl_plugin.h"
|
||||||
|
#include "ast/pb_decl_plugin.h"
|
||||||
#include "ast/for_each_expr.h"
|
#include "ast/for_each_expr.h"
|
||||||
#include "ast/rewriter/expr_replacer.h"
|
#include "ast/rewriter/expr_replacer.h"
|
||||||
#include "util/optional.h"
|
#include "util/optional.h"
|
||||||
|
@ -85,13 +86,18 @@ class nla2bv_tactic : public tactic {
|
||||||
TRACE("nla2bv", g.display(tout);
|
TRACE("nla2bv", g.display(tout);
|
||||||
tout << "Muls: " << count_mul(g) << "\n";
|
tout << "Muls: " << count_mul(g) << "\n";
|
||||||
);
|
);
|
||||||
|
tactic_report report("nla->bv", g);
|
||||||
m_fmc = alloc(generic_model_converter, m_manager, "nla2bv");
|
m_fmc = alloc(generic_model_converter, m_manager, "nla2bv");
|
||||||
m_bounds(g);
|
m_bounds(g);
|
||||||
collect_power2(g);
|
collect_power2(g);
|
||||||
if(!collect_vars(g)) {
|
switch (collect_vars(g)) {
|
||||||
|
case has_num:
|
||||||
|
break;
|
||||||
|
case not_supported:
|
||||||
throw tactic_exception("goal is not in the fragment supported by nla2bv");
|
throw tactic_exception("goal is not in the fragment supported by nla2bv");
|
||||||
|
case is_bool:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
tactic_report report("nla->bv", g);
|
|
||||||
substitute_vars(g);
|
substitute_vars(g);
|
||||||
TRACE("nla2bv", g.display(tout << "substitute vars\n"););
|
TRACE("nla2bv", g.display(tout << "substitute vars\n"););
|
||||||
reduce_bv2int(g);
|
reduce_bv2int(g);
|
||||||
|
@ -308,41 +314,47 @@ class nla2bv_tactic : public tactic {
|
||||||
|
|
||||||
class get_uninterp_proc {
|
class get_uninterp_proc {
|
||||||
imp& m_imp;
|
imp& m_imp;
|
||||||
|
arith_util& a;
|
||||||
|
ast_manager& m;
|
||||||
|
pb_util pb;
|
||||||
ptr_vector<app> m_vars;
|
ptr_vector<app> m_vars;
|
||||||
|
bool m_no_arith;
|
||||||
bool m_in_supported_fragment;
|
bool m_in_supported_fragment;
|
||||||
public:
|
public:
|
||||||
get_uninterp_proc(imp& s): m_imp(s), m_in_supported_fragment(true) {}
|
get_uninterp_proc(imp& s): m_imp(s), a(s.m_arith), m(a.get_manager()), pb(m), m_no_arith(true), m_in_supported_fragment(true) {}
|
||||||
ptr_vector<app> const& vars() { return m_vars; }
|
ptr_vector<app> const& vars() { return m_vars; }
|
||||||
|
bool no_arith() const { return m_no_arith; }
|
||||||
void operator()(var * n) {
|
void operator()(var * n) {
|
||||||
m_in_supported_fragment = false;
|
m_in_supported_fragment = false;
|
||||||
}
|
}
|
||||||
void operator()(app* n) {
|
void operator()(app* n) {
|
||||||
arith_util& a = m_imp.m_arith;
|
if (a.is_int(n) && is_uninterp_const(n)) {
|
||||||
ast_manager& m = a.get_manager();
|
|
||||||
if (a.is_int(n) &&
|
|
||||||
is_uninterp_const(n)) {
|
|
||||||
m_vars.push_back(n);
|
m_vars.push_back(n);
|
||||||
}
|
}
|
||||||
else if (a.is_real(n) &&
|
else if (a.is_real(n) && is_uninterp_const(n)) {
|
||||||
is_uninterp_const(n)) {
|
|
||||||
m_vars.push_back(n);
|
m_vars.push_back(n);
|
||||||
}
|
}
|
||||||
else if (m.is_bool(n) && is_uninterp_const(n)) {
|
else if (m.is_bool(n) && is_uninterp_const(n)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (!(a.is_mul(n) ||
|
else if (m.is_bool(n) && n->get_decl()->get_family_id() == pb.get_family_id()) {
|
||||||
a.is_add(n) ||
|
|
||||||
a.is_sub(n) ||
|
}
|
||||||
a.is_le(n) ||
|
else if (a.is_mul(n) ||
|
||||||
a.is_lt(n) ||
|
a.is_add(n) ||
|
||||||
a.is_ge(n) ||
|
a.is_sub(n) ||
|
||||||
a.is_gt(n) ||
|
a.is_le(n) ||
|
||||||
a.is_numeral(n) ||
|
a.is_lt(n) ||
|
||||||
a.is_uminus(n) ||
|
a.is_ge(n) ||
|
||||||
m_imp.m_bv2real.is_pos_le(n) ||
|
a.is_gt(n) ||
|
||||||
m_imp.m_bv2real.is_pos_lt(n) ||
|
a.is_numeral(n) ||
|
||||||
n->get_family_id() == a.get_manager().get_basic_family_id())) {
|
a.is_uminus(n) ||
|
||||||
TRACE("nla2bv", tout << "Not supported: " << mk_ismt2_pp(n, a.get_manager()) << "\n";);
|
m_imp.m_bv2real.is_pos_le(n) ||
|
||||||
|
m_imp.m_bv2real.is_pos_lt(n)) {
|
||||||
|
m_no_arith = false;
|
||||||
|
}
|
||||||
|
else if (n->get_family_id() != m.get_basic_family_id()) {
|
||||||
|
TRACE("nla2bv", tout << "Not supported: " << mk_ismt2_pp(n, m) << "\n";);
|
||||||
m_in_supported_fragment = false;
|
m_in_supported_fragment = false;
|
||||||
}
|
}
|
||||||
m_imp.update_num_bits(n);
|
m_imp.update_num_bits(n);
|
||||||
|
@ -353,13 +365,17 @@ class nla2bv_tactic : public tactic {
|
||||||
bool is_supported() const { return m_in_supported_fragment; }
|
bool is_supported() const { return m_in_supported_fragment; }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool collect_vars(goal const & g) {
|
enum collect_t { has_num, not_supported, is_bool };
|
||||||
|
|
||||||
|
collect_t collect_vars(goal const & g) {
|
||||||
get_uninterp_proc fe_var(*this);
|
get_uninterp_proc fe_var(*this);
|
||||||
for_each_expr_at(fe_var, g);
|
for_each_expr_at(fe_var, g);
|
||||||
for (unsigned i = 0; i < fe_var.vars().size(); ++i) {
|
for (unsigned i = 0; i < fe_var.vars().size(); ++i) {
|
||||||
add_var(fe_var.vars()[i]);
|
add_var(fe_var.vars()[i]);
|
||||||
}
|
}
|
||||||
return fe_var.is_supported() && !fe_var.vars().empty();
|
if (!fe_var.is_supported()) return not_supported;
|
||||||
|
if (fe_var.vars().empty() && fe_var.no_arith()) return is_bool;
|
||||||
|
return has_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
class count_mul_proc {
|
class count_mul_proc {
|
||||||
|
|
|
@ -37,7 +37,6 @@ class elim_small_bv_tactic : public tactic {
|
||||||
bv_util m_util;
|
bv_util m_util;
|
||||||
th_rewriter m_simp;
|
th_rewriter m_simp;
|
||||||
ref<generic_model_converter> m_mc;
|
ref<generic_model_converter> m_mc;
|
||||||
goal * m_goal;
|
|
||||||
unsigned m_max_bits;
|
unsigned m_max_bits;
|
||||||
unsigned long long m_max_steps;
|
unsigned long long m_max_steps;
|
||||||
unsigned long long m_max_memory; // in bytes
|
unsigned long long m_max_memory; // in bytes
|
||||||
|
@ -53,7 +52,6 @@ class elim_small_bv_tactic : public tactic {
|
||||||
m_bindings(_m),
|
m_bindings(_m),
|
||||||
m_num_eliminated(0) {
|
m_num_eliminated(0) {
|
||||||
updt_params(p);
|
updt_params(p);
|
||||||
m_goal = nullptr;
|
|
||||||
m_max_steps = UINT_MAX;
|
m_max_steps = UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +74,7 @@ class elim_small_bv_tactic : public tactic {
|
||||||
TRACE("elim_small_bv", tout << "replace idx " << idx << " with " << mk_ismt2_pp(replacement, m) <<
|
TRACE("elim_small_bv", tout << "replace idx " << idx << " with " << mk_ismt2_pp(replacement, m) <<
|
||||||
" in " << mk_ismt2_pp(e, m) << std::endl;);
|
" in " << mk_ismt2_pp(e, m) << std::endl;);
|
||||||
expr_ref res(m);
|
expr_ref res(m);
|
||||||
expr_ref_vector substitution(m);
|
ptr_vector<expr> substitution;
|
||||||
|
|
||||||
substitution.resize(num_decls, nullptr);
|
substitution.resize(num_decls, nullptr);
|
||||||
substitution[num_decls - idx - 1] = replacement;
|
substitution[num_decls - idx - 1] = replacement;
|
||||||
|
@ -94,7 +92,7 @@ class elim_small_bv_tactic : public tactic {
|
||||||
|
|
||||||
TRACE("elim_small_bv", tout << "substitution: " << std::endl;
|
TRACE("elim_small_bv", tout << "substitution: " << std::endl;
|
||||||
for (unsigned k = 0; k < substitution.size(); k++) {
|
for (unsigned k = 0; k < substitution.size(); k++) {
|
||||||
expr * se = substitution[k].get();
|
expr * se = substitution[k];
|
||||||
tout << k << " = ";
|
tout << k << " = ";
|
||||||
if (se == 0) tout << "0";
|
if (se == 0) tout << "0";
|
||||||
else tout << mk_ismt2_pp(se, m);
|
else tout << mk_ismt2_pp(se, m);
|
||||||
|
@ -152,9 +150,7 @@ class elim_small_bv_tactic : public tactic {
|
||||||
expr_ref_vector new_bodies(m);
|
expr_ref_vector new_bodies(m);
|
||||||
for (unsigned j = 0; j < bv_sz && !max_steps_exceeded(num_steps); j ++) {
|
for (unsigned j = 0; j < bv_sz && !max_steps_exceeded(num_steps); j ++) {
|
||||||
expr_ref n(m_util.mk_numeral(j, bv_sz), m);
|
expr_ref n(m_util.mk_numeral(j, bv_sz), m);
|
||||||
expr_ref nb(m);
|
new_bodies.push_back(replace_var(uv, num_decls, max_var_idx_p1, i, s, body, n));
|
||||||
nb = replace_var(uv, num_decls, max_var_idx_p1, i, s, body, n);
|
|
||||||
new_bodies.push_back(nb);
|
|
||||||
num_steps++;
|
num_steps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +246,6 @@ public:
|
||||||
fail_if_unsat_core_generation("elim-small-bv", g);
|
fail_if_unsat_core_generation("elim-small-bv", g);
|
||||||
m_rw.cfg().m_produce_models = g->models_enabled();
|
m_rw.cfg().m_produce_models = g->models_enabled();
|
||||||
|
|
||||||
m_rw.m_cfg.m_goal = g.get();
|
|
||||||
expr_ref new_curr(m);
|
expr_ref new_curr(m);
|
||||||
proof_ref new_pr(m);
|
proof_ref new_pr(m);
|
||||||
unsigned size = g->size();
|
unsigned size = g->size();
|
||||||
|
|
|
@ -49,8 +49,7 @@ class distribute_forall_tactic : public tactic {
|
||||||
expr * not_arg = m.mk_not(arg);
|
expr * not_arg = m.mk_not(arg);
|
||||||
quantifier_ref tmp_q(m);
|
quantifier_ref tmp_q(m);
|
||||||
tmp_q = m.update_quantifier(old_q, not_arg);
|
tmp_q = m.update_quantifier(old_q, not_arg);
|
||||||
expr_ref new_q = elim_unused_vars(m, tmp_q, params_ref());
|
new_args.push_back(elim_unused_vars(m, tmp_q, params_ref()));
|
||||||
new_args.push_back(new_q);
|
|
||||||
}
|
}
|
||||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||||
return true;
|
return true;
|
||||||
|
@ -68,8 +67,7 @@ class distribute_forall_tactic : public tactic {
|
||||||
expr * arg = to_app(new_body)->get_arg(i);
|
expr * arg = to_app(new_body)->get_arg(i);
|
||||||
quantifier_ref tmp_q(m);
|
quantifier_ref tmp_q(m);
|
||||||
tmp_q = m.update_quantifier(old_q, arg);
|
tmp_q = m.update_quantifier(old_q, arg);
|
||||||
expr_ref new_q = elim_unused_vars(m, tmp_q, params_ref());
|
new_args.push_back(elim_unused_vars(m, tmp_q, params_ref()));
|
||||||
new_args.push_back(new_q);
|
|
||||||
}
|
}
|
||||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -35,7 +35,7 @@ Notes:
|
||||||
|
|
||||||
tactic * mk_default_tactic(ast_manager & m, params_ref const & p) {
|
tactic * mk_default_tactic(ast_manager & m, params_ref const & p) {
|
||||||
tactic * st = using_params(and_then(mk_simplify_tactic(m),
|
tactic * st = using_params(and_then(mk_simplify_tactic(m),
|
||||||
cond(mk_is_propositional_probe(), if_no_proofs(mk_fd_tactic(m, p)),
|
cond(mk_and(mk_is_propositional_probe(), mk_not(mk_produce_proofs_probe())), mk_fd_tactic(m, p),
|
||||||
cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m),
|
cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m),
|
||||||
cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m),
|
cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m),
|
||||||
cond(mk_is_qflia_probe(), mk_qflia_tactic(m),
|
cond(mk_is_qflia_probe(), mk_qflia_tactic(m),
|
||||||
|
|
|
@ -27,6 +27,7 @@ Notes:
|
||||||
#include "sat/tactic/sat_tactic.h"
|
#include "sat/tactic/sat_tactic.h"
|
||||||
#include "tactic/arith/nla2bv_tactic.h"
|
#include "tactic/arith/nla2bv_tactic.h"
|
||||||
#include "tactic/arith/lia2card_tactic.h"
|
#include "tactic/arith/lia2card_tactic.h"
|
||||||
|
#include "tactic/arith/card2bv_tactic.h"
|
||||||
#include "tactic/core/ctx_simplify_tactic.h"
|
#include "tactic/core/ctx_simplify_tactic.h"
|
||||||
#include "tactic/core/cofactor_term_ite_tactic.h"
|
#include "tactic/core/cofactor_term_ite_tactic.h"
|
||||||
#include "nlsat/tactic/qfnra_nlsat_tactic.h"
|
#include "nlsat/tactic/qfnra_nlsat_tactic.h"
|
||||||
|
@ -73,7 +74,8 @@ static tactic * mk_qfnia_premable(ast_manager & m, params_ref const & p_ref) {
|
||||||
using_params(mk_ctx_simplify_tactic(m), ctx_simp_p),
|
using_params(mk_ctx_simplify_tactic(m), ctx_simp_p),
|
||||||
using_params(mk_simplify_tactic(m), pull_ite_p),
|
using_params(mk_simplify_tactic(m), pull_ite_p),
|
||||||
mk_elim_uncnstr_tactic(m),
|
mk_elim_uncnstr_tactic(m),
|
||||||
mk_lia2card_tactic(m),
|
mk_lia2card_tactic(m),
|
||||||
|
mk_card2bv_tactic(m, p_ref),
|
||||||
skip_if_failed(using_params(mk_cofactor_term_ite_tactic(m), elim_p)));
|
skip_if_failed(using_params(mk_cofactor_term_ite_tactic(m), elim_p)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +107,9 @@ static tactic * mk_qfnia_nlsat_solver(ast_manager & m, params_ref const & p) {
|
||||||
static tactic * mk_qfnia_smt_solver(ast_manager& m, params_ref const& p) {
|
static tactic * mk_qfnia_smt_solver(ast_manager& m, params_ref const& p) {
|
||||||
params_ref simp_p = p;
|
params_ref simp_p = p;
|
||||||
simp_p.set_bool("som", true); // expand into sums of monomials
|
simp_p.set_bool("som", true); // expand into sums of monomials
|
||||||
return and_then(using_params(mk_simplify_tactic(m), simp_p), mk_smt_tactic(m));
|
return and_then(
|
||||||
|
using_params(mk_simplify_tactic(m), simp_p),
|
||||||
|
mk_smt_tactic(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
tactic * mk_qfnia_tactic(ast_manager & m, params_ref const & p) {
|
tactic * mk_qfnia_tactic(ast_manager & m, params_ref const & p) {
|
||||||
|
@ -113,6 +117,7 @@ tactic * mk_qfnia_tactic(ast_manager & m, params_ref const & p) {
|
||||||
return and_then(
|
return and_then(
|
||||||
mk_report_verbose_tactic("(qfnia-tactic)", 10),
|
mk_report_verbose_tactic("(qfnia-tactic)", 10),
|
||||||
mk_qfnia_premable(m, p),
|
mk_qfnia_premable(m, p),
|
||||||
|
|
||||||
or_else(mk_qfnia_sat_solver(m, p),
|
or_else(mk_qfnia_sat_solver(m, p),
|
||||||
try_for(mk_qfnia_smt_solver(m, p), 2000),
|
try_for(mk_qfnia_smt_solver(m, p), 2000),
|
||||||
mk_qfnia_nlsat_solver(m, p),
|
mk_qfnia_nlsat_solver(m, p),
|
||||||
|
|
|
@ -56,7 +56,6 @@ z3_add_component(util
|
||||||
symbol.cpp
|
symbol.cpp
|
||||||
timeit.cpp
|
timeit.cpp
|
||||||
timeout.cpp
|
timeout.cpp
|
||||||
timer.cpp
|
|
||||||
trace.cpp
|
trace.cpp
|
||||||
util.cpp
|
util.cpp
|
||||||
warning.cpp
|
warning.cpp
|
||||||
|
|
|
@ -151,7 +151,7 @@ public:
|
||||||
if (m_data == nullptr) {
|
if (m_data == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return static_cast<unsigned>(reinterpret_cast<size_t *>(m_data)[SIZE_IDX]);
|
return static_cast<unsigned>(reinterpret_cast<size_t *>(m_data)[ARRAY_SIZE_IDX]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const { return m_data == nullptr; }
|
bool empty() const { return m_data == nullptr; }
|
||||||
|
|
|
@ -1,268 +1,30 @@
|
||||||
/*++
|
/*++
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
Copyright (c) 2019 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
buffer.h
|
buffer.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
<abstract>
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2006-10-16.
|
Daniel Schemmel 2019-2-23
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#ifndef BUFFER_H_
|
#ifndef BUFFER_H_
|
||||||
#define BUFFER_H_
|
#define BUFFER_H_
|
||||||
|
|
||||||
#include<string.h>
|
#include "old_buffer.h"
|
||||||
#include "util/memory_manager.h"
|
|
||||||
|
|
||||||
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
|
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
|
||||||
class buffer {
|
using buffer = old_buffer<T, CallDestructors, INITIAL_SIZE>;
|
||||||
protected:
|
|
||||||
T * m_buffer;
|
|
||||||
unsigned m_pos;
|
|
||||||
unsigned m_capacity;
|
|
||||||
char m_initial_buffer[INITIAL_SIZE * sizeof(T)];
|
|
||||||
|
|
||||||
void free_memory() {
|
|
||||||
if (m_buffer != reinterpret_cast<T*>(m_initial_buffer)) {
|
|
||||||
dealloc_svect(m_buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void expand() {
|
// note that the append added in the old_ptr_buffer is actually not an addition over its base class old_buffer,
|
||||||
unsigned new_capacity = m_capacity << 1;
|
// which already has an append function with the same signature and implementation
|
||||||
T * new_buffer = reinterpret_cast<T*>(memory::allocate(sizeof(T) * new_capacity));
|
template<typename T, unsigned INITIAL_SIZE=16>
|
||||||
memcpy(new_buffer, m_buffer, m_pos * sizeof(T));
|
using ptr_buffer = old_ptr_buffer<T, INITIAL_SIZE>;
|
||||||
free_memory();
|
|
||||||
m_buffer = new_buffer;
|
|
||||||
m_capacity = new_capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy_elements() {
|
|
||||||
iterator it = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (; it != e; ++it) {
|
|
||||||
it->~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy() {
|
|
||||||
if (CallDestructors) {
|
|
||||||
destroy_elements();
|
|
||||||
}
|
|
||||||
free_memory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T data;
|
|
||||||
typedef T * iterator;
|
|
||||||
typedef const T * const_iterator;
|
|
||||||
|
|
||||||
buffer():
|
|
||||||
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
|
||||||
m_pos(0),
|
|
||||||
m_capacity(INITIAL_SIZE) {
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer(const buffer & source):
|
|
||||||
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
|
||||||
m_pos(0),
|
|
||||||
m_capacity(INITIAL_SIZE) {
|
|
||||||
unsigned sz = source.size();
|
|
||||||
for(unsigned i = 0; i < sz; i++) {
|
|
||||||
push_back(source.m_buffer[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer(unsigned sz, const T & elem):
|
|
||||||
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
|
||||||
m_pos(0),
|
|
||||||
m_capacity(INITIAL_SIZE) {
|
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
|
||||||
push_back(elem);
|
|
||||||
}
|
|
||||||
SASSERT(size() == sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
~buffer() {
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
if (CallDestructors) {
|
|
||||||
destroy_elements();
|
|
||||||
}
|
|
||||||
m_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void finalize() {
|
|
||||||
destroy();
|
|
||||||
m_buffer = reinterpret_cast<T *>(m_initial_buffer);
|
|
||||||
m_pos = 0;
|
|
||||||
m_capacity = INITIAL_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned size() const {
|
|
||||||
return m_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return m_pos == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return m_buffer + size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_end(iterator it) {
|
|
||||||
m_pos = static_cast<unsigned>(it - m_buffer);
|
|
||||||
if (CallDestructors) {
|
|
||||||
iterator e = end();
|
|
||||||
for (; it != e; ++it) {
|
|
||||||
it->~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const {
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const {
|
|
||||||
return m_buffer + size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(const T & elem) {
|
|
||||||
if (m_pos >= m_capacity)
|
|
||||||
expand();
|
|
||||||
new (m_buffer + m_pos) T(elem);
|
|
||||||
m_pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(T && elem) {
|
|
||||||
if (m_pos >= m_capacity)
|
|
||||||
expand();
|
|
||||||
new (m_buffer + m_pos) T(std::move(elem));
|
|
||||||
m_pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back() {
|
|
||||||
if (CallDestructors) {
|
|
||||||
back().~T();
|
|
||||||
}
|
|
||||||
m_pos--;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T & back() const {
|
|
||||||
SASSERT(!empty());
|
|
||||||
SASSERT(m_pos > 0);
|
|
||||||
return m_buffer[m_pos - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
T & back() {
|
|
||||||
SASSERT(!empty());
|
|
||||||
SASSERT(m_pos > 0);
|
|
||||||
return m_buffer[m_pos - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
T * c_ptr() const {
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(unsigned n, T const * elems) {
|
|
||||||
for (unsigned i = 0; i < n; i++) {
|
|
||||||
push_back(elems[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(const buffer& source) {
|
|
||||||
append(source.size(), source.c_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
T & operator[](unsigned idx) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_buffer[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
const T & operator[](unsigned idx) const {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_buffer[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
T & get(unsigned idx) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_buffer[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
const T & get(unsigned idx) const {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_buffer[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(unsigned idx, T const & val) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
m_buffer[idx] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(unsigned nsz, const T & elem=T()) {
|
|
||||||
unsigned sz = size();
|
|
||||||
if (nsz > sz) {
|
|
||||||
for (unsigned i = sz; i < nsz; i++) {
|
|
||||||
push_back(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (nsz < sz) {
|
|
||||||
for (unsigned i = nsz; i < sz; i++) {
|
|
||||||
pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SASSERT(size() == nsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shrink(unsigned nsz) {
|
|
||||||
unsigned sz = size();
|
|
||||||
SASSERT(nsz <= sz);
|
|
||||||
for (unsigned i = nsz; i < sz; i++)
|
|
||||||
pop_back();
|
|
||||||
SASSERT(size() == nsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer & operator=(buffer const & other) {
|
|
||||||
if (this == &other)
|
|
||||||
return *this;
|
|
||||||
reset();
|
|
||||||
append(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, unsigned INITIAL_SIZE=16>
|
template<typename T, unsigned INITIAL_SIZE=16>
|
||||||
class ptr_buffer : public buffer<T *, false, INITIAL_SIZE> {
|
using sbuffer = old_sbuffer<T, INITIAL_SIZE>;
|
||||||
public:
|
|
||||||
void append(unsigned n, T * const * elems) {
|
|
||||||
for (unsigned i = 0; i < n; i++) {
|
|
||||||
this->push_back(elems[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, unsigned INITIAL_SIZE=16>
|
|
||||||
class sbuffer : public buffer<T, false, INITIAL_SIZE> {
|
|
||||||
public:
|
|
||||||
sbuffer(): buffer<T, false, INITIAL_SIZE>() {}
|
|
||||||
sbuffer(unsigned sz, const T& elem) : buffer<T, false, INITIAL_SIZE>(sz,elem) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* BUFFER_H_ */
|
#endif /* BUFFER_H_ */
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,6 @@ template lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::dense_matrix(uns
|
||||||
template lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >& lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::operator=(lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> > const&);
|
template lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >& lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::operator=(lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> > const&);
|
||||||
template lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> > lp::operator*<lp::mpq, lp::numeric_pair<lp::mpq> >(lp::matrix<lp::mpq, lp::numeric_pair<lp::mpq> >&, lp::matrix<lp::mpq, lp::numeric_pair<lp::mpq> >&);
|
template lp::dense_matrix<lp::mpq, lp::numeric_pair<lp::mpq> > lp::operator*<lp::mpq, lp::numeric_pair<lp::mpq> >(lp::matrix<lp::mpq, lp::numeric_pair<lp::mpq> >&, lp::matrix<lp::mpq, lp::numeric_pair<lp::mpq> >&);
|
||||||
template void lp::dense_matrix<lp::mpq, lp::numeric_pair< lp::mpq> >::apply_from_right( vector< lp::mpq> &);
|
template void lp::dense_matrix<lp::mpq, lp::numeric_pair< lp::mpq> >::apply_from_right( vector< lp::mpq> &);
|
||||||
template void lp::dense_matrix<double,double>::apply_from_right(class vector<double> &);
|
template void lp::dense_matrix<double,double>::apply_from_right(vector<double> &);
|
||||||
template void lp::dense_matrix<lp::mpq, lp::mpq>::apply_from_left(vector<lp::mpq>&);
|
template void lp::dense_matrix<lp::mpq, lp::mpq>::apply_from_left(vector<lp::mpq>&);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -94,10 +94,8 @@ public:
|
||||||
|
|
||||||
obj_ref & operator=(obj_ref && n) {
|
obj_ref & operator=(obj_ref && n) {
|
||||||
SASSERT(&m_manager == &n.m_manager);
|
SASSERT(&m_manager == &n.m_manager);
|
||||||
if (this != &n) {
|
std::swap(m_obj, n.m_obj);
|
||||||
std::swap(m_obj, n.m_obj);
|
n.reset();
|
||||||
n.reset();
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
270
src/util/old_buffer.h
Normal file
270
src/util/old_buffer.h
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2006 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
old_buffer.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
<abstract>
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Leonardo de Moura (leonardo) 2006-10-16.
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
2019-2-23 Renamed to old_buffer from buffer to provide new implementation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#ifndef OLD_BUFFER_H_
|
||||||
|
#define OLD_BUFFER_H_
|
||||||
|
|
||||||
|
#include<string.h>
|
||||||
|
#include "util/memory_manager.h"
|
||||||
|
|
||||||
|
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
|
||||||
|
class old_buffer {
|
||||||
|
protected:
|
||||||
|
T * m_buffer;
|
||||||
|
unsigned m_pos;
|
||||||
|
unsigned m_capacity;
|
||||||
|
char m_initial_buffer[INITIAL_SIZE * sizeof(T)];
|
||||||
|
|
||||||
|
void free_memory() {
|
||||||
|
if (m_buffer != reinterpret_cast<T*>(m_initial_buffer)) {
|
||||||
|
dealloc_svect(m_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void expand() {
|
||||||
|
unsigned new_capacity = m_capacity << 1;
|
||||||
|
T * new_buffer = reinterpret_cast<T*>(memory::allocate(sizeof(T) * new_capacity));
|
||||||
|
memcpy(new_buffer, m_buffer, m_pos * sizeof(T));
|
||||||
|
free_memory();
|
||||||
|
m_buffer = new_buffer;
|
||||||
|
m_capacity = new_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_elements() {
|
||||||
|
iterator it = begin();
|
||||||
|
iterator e = end();
|
||||||
|
for (; it != e; ++it) {
|
||||||
|
it->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() {
|
||||||
|
if (CallDestructors) {
|
||||||
|
destroy_elements();
|
||||||
|
}
|
||||||
|
free_memory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T data;
|
||||||
|
typedef T * iterator;
|
||||||
|
typedef const T * const_iterator;
|
||||||
|
|
||||||
|
old_buffer():
|
||||||
|
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
||||||
|
m_pos(0),
|
||||||
|
m_capacity(INITIAL_SIZE) {
|
||||||
|
}
|
||||||
|
|
||||||
|
old_buffer(const old_buffer & source):
|
||||||
|
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
||||||
|
m_pos(0),
|
||||||
|
m_capacity(INITIAL_SIZE) {
|
||||||
|
unsigned sz = source.size();
|
||||||
|
for(unsigned i = 0; i < sz; i++) {
|
||||||
|
push_back(source.m_buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
old_buffer(unsigned sz, const T & elem):
|
||||||
|
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
||||||
|
m_pos(0),
|
||||||
|
m_capacity(INITIAL_SIZE) {
|
||||||
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
|
push_back(elem);
|
||||||
|
}
|
||||||
|
SASSERT(size() == sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
~old_buffer() {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
if (CallDestructors) {
|
||||||
|
destroy_elements();
|
||||||
|
}
|
||||||
|
m_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void finalize() {
|
||||||
|
destroy();
|
||||||
|
m_buffer = reinterpret_cast<T *>(m_initial_buffer);
|
||||||
|
m_pos = 0;
|
||||||
|
m_capacity = INITIAL_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size() const {
|
||||||
|
return m_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
return m_pos == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin() {
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() {
|
||||||
|
return m_buffer + size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_end(iterator it) {
|
||||||
|
m_pos = static_cast<unsigned>(it - m_buffer);
|
||||||
|
if (CallDestructors) {
|
||||||
|
iterator e = end();
|
||||||
|
for (; it != e; ++it) {
|
||||||
|
it->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const {
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const {
|
||||||
|
return m_buffer + size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const T & elem) {
|
||||||
|
if (m_pos >= m_capacity)
|
||||||
|
expand();
|
||||||
|
new (m_buffer + m_pos) T(elem);
|
||||||
|
m_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(T && elem) {
|
||||||
|
if (m_pos >= m_capacity)
|
||||||
|
expand();
|
||||||
|
new (m_buffer + m_pos) T(std::move(elem));
|
||||||
|
m_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back() {
|
||||||
|
if (CallDestructors) {
|
||||||
|
back().~T();
|
||||||
|
}
|
||||||
|
m_pos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T & back() const {
|
||||||
|
SASSERT(!empty());
|
||||||
|
SASSERT(m_pos > 0);
|
||||||
|
return m_buffer[m_pos - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
T & back() {
|
||||||
|
SASSERT(!empty());
|
||||||
|
SASSERT(m_pos > 0);
|
||||||
|
return m_buffer[m_pos - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
T * c_ptr() const {
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(unsigned n, T const * elems) {
|
||||||
|
for (unsigned i = 0; i < n; i++) {
|
||||||
|
push_back(elems[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(const old_buffer& source) {
|
||||||
|
append(source.size(), source.c_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator[](unsigned idx) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_buffer[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T & operator[](unsigned idx) const {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_buffer[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
T & get(unsigned idx) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_buffer[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T & get(unsigned idx) const {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_buffer[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(unsigned idx, T const & val) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
m_buffer[idx] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(unsigned nsz, const T & elem=T()) {
|
||||||
|
unsigned sz = size();
|
||||||
|
if (nsz > sz) {
|
||||||
|
for (unsigned i = sz; i < nsz; i++) {
|
||||||
|
push_back(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nsz < sz) {
|
||||||
|
for (unsigned i = nsz; i < sz; i++) {
|
||||||
|
pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SASSERT(size() == nsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shrink(unsigned nsz) {
|
||||||
|
unsigned sz = size();
|
||||||
|
SASSERT(nsz <= sz);
|
||||||
|
for (unsigned i = nsz; i < sz; i++)
|
||||||
|
pop_back();
|
||||||
|
SASSERT(size() == nsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
old_buffer & operator=(old_buffer const & other) {
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
reset();
|
||||||
|
append(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, unsigned INITIAL_SIZE=16>
|
||||||
|
class old_ptr_buffer : public old_buffer<T *, false, INITIAL_SIZE> {
|
||||||
|
public:
|
||||||
|
void append(unsigned n, T * const * elems) {
|
||||||
|
for (unsigned i = 0; i < n; i++) {
|
||||||
|
this->push_back(elems[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, unsigned INITIAL_SIZE=16>
|
||||||
|
class old_sbuffer : public old_buffer<T, false, INITIAL_SIZE> {
|
||||||
|
public:
|
||||||
|
old_sbuffer(): old_buffer<T, false, INITIAL_SIZE>() {}
|
||||||
|
old_sbuffer(unsigned sz, const T& elem) : old_buffer<T, false, INITIAL_SIZE>(sz,elem) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* OLD_BUFFER_H_ */
|
||||||
|
|
611
src/util/old_vector.h
Normal file
611
src/util/old_vector.h
Normal file
|
@ -0,0 +1,611 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2006 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
old_vector.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
Dynamic array implementation.
|
||||||
|
Remarks:
|
||||||
|
|
||||||
|
- Empty arrays consume only sizeof(T *) bytes.
|
||||||
|
|
||||||
|
- There is the option of disabling the destructor invocation for elements stored in the vector.
|
||||||
|
This is useful for vectors of int.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Leonardo de Moura (leonardo) 2006-09-11.
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
2019-2-23 Renamed from vector to old_vector to provide new implementation
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#ifndef OLD_VECTOR_H_
|
||||||
|
#define OLD_VECTOR_H_
|
||||||
|
|
||||||
|
#include "util/debug.h"
|
||||||
|
#include<algorithm>
|
||||||
|
#include<type_traits>
|
||||||
|
#include<memory.h>
|
||||||
|
#include<functional>
|
||||||
|
#include "util/memory_manager.h"
|
||||||
|
#include "util/hash.h"
|
||||||
|
#include "util/z3_exception.h"
|
||||||
|
|
||||||
|
// disable warning for constant 'if' expressions.
|
||||||
|
// these are used heavily in templates.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable:4127)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T, bool CallDestructors=true, typename SZ = unsigned>
|
||||||
|
class old_vector {
|
||||||
|
#define SIZE_IDX -1
|
||||||
|
#define CAPACITY_IDX -2
|
||||||
|
T * m_data;
|
||||||
|
|
||||||
|
void destroy_elements() {
|
||||||
|
iterator it = begin();
|
||||||
|
iterator e = end();
|
||||||
|
for (; it != e; ++it) {
|
||||||
|
it->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_memory() {
|
||||||
|
memory::deallocate(reinterpret_cast<char*>(reinterpret_cast<SZ*>(m_data) - 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void expand_vector() {
|
||||||
|
if (m_data == nullptr) {
|
||||||
|
SZ capacity = 2;
|
||||||
|
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
||||||
|
*mem = capacity;
|
||||||
|
mem++;
|
||||||
|
*mem = 0;
|
||||||
|
mem++;
|
||||||
|
m_data = reinterpret_cast<T *>(mem);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SASSERT(capacity() > 0);
|
||||||
|
SZ old_capacity = reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
||||||
|
SZ old_capacity_T = sizeof(T) * old_capacity + sizeof(SZ) * 2;
|
||||||
|
SZ new_capacity = (3 * old_capacity + 1) >> 1;
|
||||||
|
SZ new_capacity_T = sizeof(T) * new_capacity + sizeof(SZ) * 2;
|
||||||
|
if (new_capacity <= old_capacity || new_capacity_T <= old_capacity_T) {
|
||||||
|
throw default_exception("Overflow encountered when expanding old_vector");
|
||||||
|
}
|
||||||
|
SZ *mem, *old_mem = reinterpret_cast<SZ*>(m_data) - 2;
|
||||||
|
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
|
||||||
|
if (__has_trivial_copy(T)) {
|
||||||
|
#else
|
||||||
|
if (std::is_trivially_copyable<T>::value) {
|
||||||
|
#endif
|
||||||
|
mem = (SZ*)memory::reallocate(old_mem, new_capacity_T);
|
||||||
|
m_data = reinterpret_cast<T *>(mem + 2);
|
||||||
|
} else {
|
||||||
|
mem = (SZ*)memory::allocate(new_capacity_T);
|
||||||
|
auto old_data = m_data;
|
||||||
|
auto old_size = size();
|
||||||
|
mem[1] = old_size;
|
||||||
|
m_data = reinterpret_cast<T *>(mem + 2);
|
||||||
|
for (unsigned i = 0; i < old_size; ++i) {
|
||||||
|
new (&m_data[i]) T(std::move(old_data[i]));
|
||||||
|
old_data[i].~T();
|
||||||
|
}
|
||||||
|
memory::deallocate(old_mem);
|
||||||
|
}
|
||||||
|
*mem = new_capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_core(old_vector const & source) {
|
||||||
|
SZ size = source.size();
|
||||||
|
SZ capacity = source.capacity();
|
||||||
|
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
||||||
|
*mem = capacity;
|
||||||
|
mem++;
|
||||||
|
*mem = size;
|
||||||
|
mem++;
|
||||||
|
m_data = reinterpret_cast<T *>(mem);
|
||||||
|
const_iterator it = source.begin();
|
||||||
|
iterator it2 = begin();
|
||||||
|
SASSERT(it2 == m_data);
|
||||||
|
const_iterator e = source.end();
|
||||||
|
for (; it != e; ++it, ++it2) {
|
||||||
|
new (it2) T(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() {
|
||||||
|
if (m_data) {
|
||||||
|
if (CallDestructors) {
|
||||||
|
destroy_elements();
|
||||||
|
}
|
||||||
|
free_memory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T data;
|
||||||
|
typedef T * iterator;
|
||||||
|
typedef const T * const_iterator;
|
||||||
|
|
||||||
|
old_vector():
|
||||||
|
m_data(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector(SZ s) {
|
||||||
|
if (s == 0) {
|
||||||
|
m_data = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * s + sizeof(SZ) * 2));
|
||||||
|
*mem = s;
|
||||||
|
mem++;
|
||||||
|
*mem = s;
|
||||||
|
mem++;
|
||||||
|
m_data = reinterpret_cast<T *>(mem);
|
||||||
|
// initialize elements
|
||||||
|
iterator it = begin();
|
||||||
|
iterator e = end();
|
||||||
|
for (; it != e; ++it) {
|
||||||
|
new (it) T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector(SZ s, T const & elem):
|
||||||
|
m_data(nullptr) {
|
||||||
|
resize(s, elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector(old_vector const & source):
|
||||||
|
m_data(nullptr) {
|
||||||
|
if (source.m_data) {
|
||||||
|
copy_core(source);
|
||||||
|
}
|
||||||
|
SASSERT(size() == source.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector(old_vector&& other) : m_data(nullptr) {
|
||||||
|
std::swap(m_data, other.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector(SZ s, T const * data):
|
||||||
|
m_data(nullptr) {
|
||||||
|
for (SZ i = 0; i < s; i++) {
|
||||||
|
push_back(data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~old_vector() {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void finalize() {
|
||||||
|
destroy();
|
||||||
|
m_data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(old_vector const & other) const {
|
||||||
|
if (this == &other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (size() != other.size())
|
||||||
|
return false;
|
||||||
|
for (unsigned i = 0; i < size(); i++) {
|
||||||
|
if ((*this)[i] != other[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(old_vector const & other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
old_vector & operator=(old_vector const & source) {
|
||||||
|
if (this == &source) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
destroy();
|
||||||
|
if (source.m_data) {
|
||||||
|
copy_core(source);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_data = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector & operator=(old_vector && source) {
|
||||||
|
if (this == &source) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
destroy();
|
||||||
|
m_data = nullptr;
|
||||||
|
std::swap(m_data, source.m_data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsp(std::function<bool(T)>& predicate) const {
|
||||||
|
for (auto const& t : *this)
|
||||||
|
if (predicate(t))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retain elements that satisfy predicate. aka 'where'.
|
||||||
|
*/
|
||||||
|
old_vector filter_pure(std::function<bool(T)>& predicate) const {
|
||||||
|
old_vector result;
|
||||||
|
for (auto& t : *this)
|
||||||
|
if (predicate(t))
|
||||||
|
result.push_back(t);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector& filter_update(std::function<bool(T)>& predicate) {
|
||||||
|
unsigned j = 0;
|
||||||
|
for (auto& t : *this)
|
||||||
|
if (predicate(t))
|
||||||
|
set(j++, t);
|
||||||
|
shrink(j);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update elements using f, aka 'select'
|
||||||
|
*/
|
||||||
|
template <typename S>
|
||||||
|
old_vector<S> map_pure(std::function<S(T)>& f) const {
|
||||||
|
old_vector<S> result;
|
||||||
|
for (auto& t : *this)
|
||||||
|
result.push_back(f(t));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_vector& map_update(std::function<T(T)>& f) {
|
||||||
|
unsigned j = 0;
|
||||||
|
for (auto& t : *this)
|
||||||
|
set(j++, f(t));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
if (m_data) {
|
||||||
|
if (CallDestructors) {
|
||||||
|
destroy_elements();
|
||||||
|
}
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() { reset(); }
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
return m_data == nullptr || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SZ size() const {
|
||||||
|
if (m_data == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<SZ *>(m_data)[SIZE_IDX];
|
||||||
|
}
|
||||||
|
|
||||||
|
SZ capacity() const {
|
||||||
|
if (m_data == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin() {
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() {
|
||||||
|
return m_data + size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const {
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const {
|
||||||
|
return m_data + size();
|
||||||
|
}
|
||||||
|
|
||||||
|
class reverse_iterator {
|
||||||
|
T* v;
|
||||||
|
public:
|
||||||
|
reverse_iterator(T* v):v(v) {}
|
||||||
|
|
||||||
|
T operator*() { return *v; }
|
||||||
|
reverse_iterator operator++(int) {
|
||||||
|
reverse_iterator tmp = *this;
|
||||||
|
--v;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
reverse_iterator& operator++() {
|
||||||
|
--v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(reverse_iterator const& other) const {
|
||||||
|
return other.v == v;
|
||||||
|
}
|
||||||
|
bool operator!=(reverse_iterator const& other) const {
|
||||||
|
return other.v != v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
|
||||||
|
reverse_iterator rend() { return reverse_iterator(begin() - 1); }
|
||||||
|
|
||||||
|
void set_end(iterator it) {
|
||||||
|
if (m_data) {
|
||||||
|
SZ new_sz = static_cast<SZ>(it - m_data);
|
||||||
|
if (CallDestructors) {
|
||||||
|
iterator e = end();
|
||||||
|
for(; it != e; ++it) {
|
||||||
|
it->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = new_sz;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SASSERT(it == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator[](SZ idx) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
T const & operator[](SZ idx) const {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
T & get(SZ idx) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
T const & get(SZ idx) const {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
return m_data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(SZ idx, T const & val) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
m_data[idx] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(SZ idx, T && val) {
|
||||||
|
SASSERT(idx < size());
|
||||||
|
m_data[idx] = std::move(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
T & back() {
|
||||||
|
SASSERT(!empty());
|
||||||
|
return operator[](size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
T const & back() const {
|
||||||
|
SASSERT(!empty());
|
||||||
|
return operator[](size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back() {
|
||||||
|
SASSERT(!empty());
|
||||||
|
if (CallDestructors) {
|
||||||
|
back().~T();
|
||||||
|
}
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(T const & elem) {
|
||||||
|
if (m_data == nullptr || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX]) {
|
||||||
|
expand_vector();
|
||||||
|
}
|
||||||
|
new (m_data + reinterpret_cast<SZ *>(m_data)[SIZE_IDX]) T(elem);
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(T && elem) {
|
||||||
|
if (m_data == nullptr || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX]) {
|
||||||
|
expand_vector();
|
||||||
|
}
|
||||||
|
new (m_data + reinterpret_cast<SZ *>(m_data)[SIZE_IDX]) T(std::move(elem));
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(T const & elem) {
|
||||||
|
push_back(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(iterator pos) {
|
||||||
|
SASSERT(pos >= begin() && pos < end());
|
||||||
|
iterator prev = pos;
|
||||||
|
++pos;
|
||||||
|
iterator e = end();
|
||||||
|
for(; pos != e; ++pos, ++prev) {
|
||||||
|
*prev = *pos;
|
||||||
|
}
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(T const & elem) {
|
||||||
|
iterator it = std::find(begin(), end(), elem);
|
||||||
|
if (it != end()) {
|
||||||
|
erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void shrink(SZ s) {
|
||||||
|
if (m_data) {
|
||||||
|
SASSERT(s <= reinterpret_cast<SZ *>(m_data)[SIZE_IDX]);
|
||||||
|
if (CallDestructors) {
|
||||||
|
iterator it = m_data + s;
|
||||||
|
iterator e = end();
|
||||||
|
for(; it != e; ++it) {
|
||||||
|
it->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SASSERT(s == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Args>
|
||||||
|
void resize(SZ s, Args args...) {
|
||||||
|
SZ sz = size();
|
||||||
|
if (s <= sz) { shrink(s); return; }
|
||||||
|
while (s > capacity()) {
|
||||||
|
expand_vector();
|
||||||
|
}
|
||||||
|
SASSERT(m_data != 0);
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = s;
|
||||||
|
iterator it = m_data + sz;
|
||||||
|
iterator end = m_data + s;
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
new (it) T(std::forward<Args>(args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(SZ s) {
|
||||||
|
SZ sz = size();
|
||||||
|
if (s <= sz) { shrink(s); return; }
|
||||||
|
while (s > capacity()) {
|
||||||
|
expand_vector();
|
||||||
|
}
|
||||||
|
SASSERT(m_data != 0);
|
||||||
|
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = s;
|
||||||
|
iterator it = m_data + sz;
|
||||||
|
iterator end = m_data + s;
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
new (it) T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(old_vector<T, CallDestructors> const & other) {
|
||||||
|
for(SZ i = 0; i < other.size(); ++i) {
|
||||||
|
push_back(other[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(SZ sz, T const * data) {
|
||||||
|
for(SZ i = 0; i < sz; ++i) {
|
||||||
|
push_back(data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T * c_ptr() const {
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(old_vector & other) {
|
||||||
|
std::swap(m_data, other.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reverse() {
|
||||||
|
SZ sz = size();
|
||||||
|
for (SZ i = 0; i < sz/2; ++i) {
|
||||||
|
std::swap(m_data[i], m_data[sz-i-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill(T const & elem) {
|
||||||
|
iterator i = begin();
|
||||||
|
iterator e = end();
|
||||||
|
for (; i != e; ++i) {
|
||||||
|
*i = elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill(unsigned sz, T const & elem) {
|
||||||
|
resize(sz);
|
||||||
|
fill(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(T const & elem) const {
|
||||||
|
const_iterator it = begin();
|
||||||
|
const_iterator e = end();
|
||||||
|
for (; it != e; ++it) {
|
||||||
|
if (*it == elem) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set pos idx with elem. If idx >= size, then expand using default.
|
||||||
|
void setx(SZ idx, T const & elem, T const & d) {
|
||||||
|
if (idx >= size()) {
|
||||||
|
resize(idx+1, d);
|
||||||
|
}
|
||||||
|
m_data[idx] = elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return element at position idx, if idx >= size, then return default
|
||||||
|
T const & get(SZ idx, T const & d) const {
|
||||||
|
if (idx >= size()) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
return m_data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(SZ s, T const & d) {
|
||||||
|
if (s > size())
|
||||||
|
resize(s, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(SZ s) {
|
||||||
|
if (s > size())
|
||||||
|
resize(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class old_ptr_vector : public old_vector<T *, false> {
|
||||||
|
public:
|
||||||
|
old_ptr_vector():old_vector<T *, false>() {}
|
||||||
|
old_ptr_vector(unsigned s):old_vector<T *, false>(s) {}
|
||||||
|
old_ptr_vector(unsigned s, T * elem):old_vector<T *, false>(s, elem) {}
|
||||||
|
old_ptr_vector(old_ptr_vector const & source):old_vector<T *, false>(source) {}
|
||||||
|
old_ptr_vector(old_ptr_vector && other) : old_vector<T*, false>(std::move(other)) {}
|
||||||
|
old_ptr_vector(unsigned s, T * const * data):old_vector<T *, false>(s, const_cast<T**>(data)) {}
|
||||||
|
old_ptr_vector & operator=(old_ptr_vector const & source) {
|
||||||
|
old_vector<T *, false>::operator=(source);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename SZ = unsigned>
|
||||||
|
class old_svector : public old_vector<T, false, SZ> {
|
||||||
|
public:
|
||||||
|
old_svector():old_vector<T, false, SZ>() {}
|
||||||
|
old_svector(SZ s):old_vector<T, false, SZ>(s) {}
|
||||||
|
old_svector(SZ s, T const & elem):old_vector<T, false, SZ>(s, elem) {}
|
||||||
|
old_svector(old_svector const & source):old_vector<T, false, SZ>(source) {}
|
||||||
|
old_svector(old_svector && other) : old_vector<T, false, SZ>(std::move(other)) {}
|
||||||
|
old_svector(SZ s, T const * data):old_vector<T, false, SZ>(s, data) {}
|
||||||
|
old_svector & operator=(old_svector const & source) {
|
||||||
|
old_vector<T, false, SZ>::operator=(source);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* OLD_VECTOR_H_ */
|
|
@ -58,6 +58,12 @@ public:
|
||||||
inc_ref(n);
|
inc_ref(n);
|
||||||
m_buffer.push_back(n);
|
m_buffer.push_back(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
void push_back(obj_ref<T,M> && n) {
|
||||||
|
m_buffer.push_back(n.get());
|
||||||
|
n.steal();
|
||||||
|
}
|
||||||
|
|
||||||
void pop_back() {
|
void pop_back() {
|
||||||
SASSERT(!m_buffer.empty());
|
SASSERT(!m_buffer.empty());
|
||||||
|
|
|
@ -99,8 +99,8 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename W, typename M>
|
template <typename M>
|
||||||
ref_vector_core& push_back(obj_ref<W,M> && n) {
|
ref_vector_core& push_back(obj_ref<T,M> && n) {
|
||||||
m_nodes.push_back(n.get());
|
m_nodes.push_back(n.get());
|
||||||
n.steal();
|
n.steal();
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -26,39 +26,33 @@ Revision History:
|
||||||
|
|
||||||
|
|
||||||
struct scoped_timer::imp {
|
struct scoped_timer::imp {
|
||||||
event_handler * m_eh;
|
private:
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
std::timed_mutex m_mutex;
|
std::timed_mutex m_mutex;
|
||||||
unsigned m_ms;
|
|
||||||
|
|
||||||
static void* thread_func(imp * st) {
|
static void thread_func(unsigned ms, event_handler * eh, std::timed_mutex * mutex) {
|
||||||
auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(st->m_ms);
|
auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(ms);
|
||||||
|
|
||||||
while (!st->m_mutex.try_lock_until(end)) {
|
while (!mutex->try_lock_until(end)) {
|
||||||
if (std::chrono::steady_clock::now() > end) {
|
if (std::chrono::steady_clock::now() >= end) {
|
||||||
st->m_eh->operator()(TIMEOUT_EH_CALLER);
|
eh->operator()(TIMEOUT_EH_CALLER);
|
||||||
return nullptr;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
st->m_mutex.unlock();
|
mutex->unlock();
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imp(unsigned ms, event_handler * eh):
|
public:
|
||||||
m_eh(eh), m_ms(ms) {
|
imp(unsigned ms, event_handler * eh) {
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
m_thread = std::thread(thread_func, this);
|
m_thread = std::thread(thread_func, ms, eh, &m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
~imp() {
|
~imp() {
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
while (!m_thread.joinable()) {
|
|
||||||
std::this_thread::yield();
|
|
||||||
}
|
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
||||||
|
@ -69,6 +63,5 @@ scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_timer::~scoped_timer() {
|
scoped_timer::~scoped_timer() {
|
||||||
if (m_imp)
|
dealloc(m_imp);
|
||||||
dealloc(m_imp);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,171 +20,60 @@ Revision History:
|
||||||
#ifndef STOPWATCH_H_
|
#ifndef STOPWATCH_H_
|
||||||
#define STOPWATCH_H_
|
#define STOPWATCH_H_
|
||||||
|
|
||||||
#if defined(_WINDOWS) || defined(_CYGWIN) || defined(_MINGW)
|
#include "util/debug.h"
|
||||||
|
#include <chrono>
|
||||||
// Does this redefinition work?
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
class stopwatch
|
class stopwatch
|
||||||
{
|
{
|
||||||
private:
|
typedef decltype(std::chrono::steady_clock::now()) clock_t;
|
||||||
LARGE_INTEGER m_elapsed;
|
typedef decltype(std::chrono::steady_clock::now() - std::chrono::steady_clock::now()) duration_t;
|
||||||
LARGE_INTEGER m_last_start_time;
|
|
||||||
LARGE_INTEGER m_last_stop_time;
|
clock_t m_start;
|
||||||
LARGE_INTEGER m_frequency;
|
duration_t m_elapsed;
|
||||||
|
#if Z3DEBUG
|
||||||
|
bool m_running = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME: just use auto with VS 2015+
|
||||||
|
static clock_t get() {
|
||||||
|
return std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
stopwatch() {
|
stopwatch() {
|
||||||
QueryPerformanceFrequency(&m_frequency);
|
reset();
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~stopwatch() {};
|
void add(const stopwatch &s) {
|
||||||
|
m_elapsed += s.m_elapsed;
|
||||||
void add (const stopwatch &s) {/* TODO */}
|
|
||||||
|
|
||||||
void reset() { m_elapsed.QuadPart = 0; }
|
|
||||||
|
|
||||||
void start() {
|
|
||||||
QueryPerformanceCounter(&m_last_start_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop() {
|
|
||||||
QueryPerformanceCounter(&m_last_stop_time);
|
|
||||||
m_elapsed.QuadPart += m_last_stop_time.QuadPart - m_last_start_time.QuadPart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_seconds() const {
|
void reset() {
|
||||||
return static_cast<double>(m_elapsed.QuadPart / static_cast<double>(m_frequency.QuadPart)) ;
|
m_elapsed = duration_t::zero();
|
||||||
|
DEBUG_CODE(m_running = false;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
SASSERT(!m_running);
|
||||||
|
DEBUG_CODE(m_running = true;);
|
||||||
|
m_start = get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
SASSERT(m_running);
|
||||||
|
DEBUG_CODE(m_running = false;);
|
||||||
|
m_elapsed += get() - m_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_seconds() const {
|
||||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(m_elapsed).count() / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_current_seconds() const {
|
double get_current_seconds() const {
|
||||||
LARGE_INTEGER t;
|
return std::chrono::duration_cast<std::chrono::milliseconds>(get() - m_start).count() / 1000.0;
|
||||||
QueryPerformanceCounter(&t);
|
|
||||||
return static_cast<double>( (t.QuadPart - m_last_start_time.QuadPart) / static_cast<double>(m_frequency.QuadPart));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef max
|
|
||||||
#undef min
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__APPLE__) && defined (__MACH__) // macOS
|
|
||||||
|
|
||||||
#include<mach/mach.h>
|
|
||||||
#include<mach/clock.h>
|
|
||||||
|
|
||||||
class stopwatch {
|
|
||||||
unsigned long long m_time; // elapsed time in ns
|
|
||||||
bool m_running;
|
|
||||||
clock_serv_t m_host_clock;
|
|
||||||
mach_timespec_t m_start;
|
|
||||||
|
|
||||||
public:
|
|
||||||
stopwatch():m_time(0), m_running(false) {
|
|
||||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &m_host_clock);
|
|
||||||
}
|
|
||||||
|
|
||||||
~stopwatch() {}
|
|
||||||
|
|
||||||
void add (const stopwatch &s) {m_time += s.m_time;}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
m_time = 0ull;
|
|
||||||
}
|
|
||||||
|
|
||||||
void start() {
|
|
||||||
if (!m_running) {
|
|
||||||
clock_get_time(m_host_clock, &m_start);
|
|
||||||
m_running = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop() {
|
|
||||||
if (m_running) {
|
|
||||||
mach_timespec_t _stop;
|
|
||||||
clock_get_time(m_host_clock, &_stop);
|
|
||||||
m_time += (_stop.tv_sec - m_start.tv_sec) * 1000000000ull;
|
|
||||||
m_time += (_stop.tv_nsec - m_start.tv_nsec);
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_seconds() const {
|
|
||||||
if (m_running) {
|
|
||||||
const_cast<stopwatch*>(this)->stop();
|
|
||||||
/* update m_time */
|
|
||||||
const_cast<stopwatch*>(this)->start();
|
|
||||||
}
|
|
||||||
return static_cast<double>(m_time)/static_cast<double>(1000000000ull);
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_current_seconds() const {
|
|
||||||
return get_seconds();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#else // Linux
|
|
||||||
|
|
||||||
#include<ctime>
|
|
||||||
|
|
||||||
#ifndef CLOCK_PROCESS_CPUTIME_ID
|
|
||||||
/* BSD */
|
|
||||||
# define CLOCK_PROCESS_CPUTIME_ID CLOCK_MONOTONIC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class stopwatch {
|
|
||||||
unsigned long long m_time; // elapsed time in ns
|
|
||||||
bool m_running;
|
|
||||||
struct timespec m_start;
|
|
||||||
|
|
||||||
public:
|
|
||||||
stopwatch():m_time(0), m_running(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~stopwatch() {}
|
|
||||||
|
|
||||||
void add (const stopwatch &s) {m_time += s.m_time;}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
m_time = 0ull;
|
|
||||||
}
|
|
||||||
|
|
||||||
void start() {
|
|
||||||
if (!m_running) {
|
|
||||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &m_start);
|
|
||||||
m_running = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop() {
|
|
||||||
if (m_running) {
|
|
||||||
struct timespec _stop;
|
|
||||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &_stop);
|
|
||||||
m_time += (_stop.tv_sec - m_start.tv_sec) * 1000000000ull;
|
|
||||||
if (m_time != 0 || _stop.tv_nsec >= m_start.tv_nsec)
|
|
||||||
m_time += (_stop.tv_nsec - m_start.tv_nsec);
|
|
||||||
m_running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_seconds() const {
|
|
||||||
if (m_running) {
|
|
||||||
const_cast<stopwatch*>(this)->stop();
|
|
||||||
/* update m_time */
|
|
||||||
const_cast<stopwatch*>(this)->start();
|
|
||||||
}
|
|
||||||
return static_cast<double>(m_time)/static_cast<double>(1000000000ull);
|
|
||||||
}
|
|
||||||
|
|
||||||
double get_current_seconds() const {
|
|
||||||
return get_seconds();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct scoped_watch {
|
struct scoped_watch {
|
||||||
stopwatch &m_sw;
|
stopwatch &m_sw;
|
||||||
|
|
|
@ -19,7 +19,6 @@ Revision History:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#include<iostream>
|
#include<iostream>
|
||||||
#include "util/z3_omp.h"
|
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
#include "util/timeout.h"
|
#include "util/timeout.h"
|
||||||
#include "util/error_codes.h"
|
#include "util/error_codes.h"
|
||||||
|
@ -34,26 +33,21 @@ namespace {
|
||||||
class g_timeout_eh : public event_handler {
|
class g_timeout_eh : public event_handler {
|
||||||
public:
|
public:
|
||||||
void operator()(event_handler_caller_t caller_id) override {
|
void operator()(event_handler_caller_t caller_id) override {
|
||||||
#pragma omp critical (g_timeout_cs)
|
std::cout << "timeout\n";
|
||||||
{
|
m_caller_id = caller_id;
|
||||||
std::cout << "timeout\n";
|
if (g_on_timeout)
|
||||||
m_caller_id = caller_id;
|
g_on_timeout();
|
||||||
if (g_on_timeout)
|
throw z3_error(ERR_TIMEOUT);
|
||||||
g_on_timeout();
|
|
||||||
if (g_timeout)
|
|
||||||
delete g_timeout;
|
|
||||||
g_timeout = nullptr;
|
|
||||||
throw z3_error(ERR_TIMEOUT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_timeout(long ms) {
|
static g_timeout_eh eh;
|
||||||
if (g_timeout)
|
|
||||||
delete g_timeout;
|
|
||||||
|
|
||||||
g_timeout = new scoped_timer(ms, new g_timeout_eh());
|
void set_timeout(long ms) {
|
||||||
|
SASSERT(!g_timeout);
|
||||||
|
// this is leaked, but since it's only used in the shell, it's ok
|
||||||
|
g_timeout = new scoped_timer(ms, &eh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_on_timeout_proc(void (*proc)()) {
|
void register_on_timeout_proc(void (*proc)()) {
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
timer.cpp
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
<abstract>
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2009-01-06.
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#include "util/util.h"
|
|
||||||
#include "util/memory_manager.h"
|
|
||||||
#include "util/stopwatch.h"
|
|
||||||
#include "util/timer.h"
|
|
||||||
|
|
||||||
timer::timer(){
|
|
||||||
m_watch = alloc(stopwatch);
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
timer::~timer() {
|
|
||||||
dealloc(m_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void timer::start() {
|
|
||||||
m_watch->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
double timer::get_seconds() {
|
|
||||||
return m_watch->get_current_seconds();
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,21 +19,29 @@ Revision History:
|
||||||
#ifndef TIMER_H_
|
#ifndef TIMER_H_
|
||||||
#define TIMER_H_
|
#define TIMER_H_
|
||||||
|
|
||||||
class stopwatch;
|
#include "util/stopwatch.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Wrapper for the stopwatch class. It hides windows.h dependency.
|
\brief Wrapper for the stopwatch class.
|
||||||
*/
|
*/
|
||||||
class timer {
|
class timer {
|
||||||
stopwatch * m_watch;
|
stopwatch m_watch;
|
||||||
public:
|
public:
|
||||||
timer();
|
timer() {
|
||||||
~timer();
|
m_watch.start();
|
||||||
void start();
|
}
|
||||||
double get_seconds();
|
|
||||||
bool timeout(unsigned secs) { return secs > 0 && secs != UINT_MAX && get_seconds() > secs; }
|
double get_seconds() const {
|
||||||
bool ms_timeout(unsigned ms) { return ms > 0 && ms != UINT_MAX && get_seconds() * 1000 > ms; }
|
return m_watch.get_current_seconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool timeout(unsigned secs) const {
|
||||||
|
return secs != 0 && secs != UINT_MAX && get_seconds() > secs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ms_timeout(unsigned ms) const {
|
||||||
|
return ms != 0 && ms != UINT_MAX && get_seconds() * 1000 > ms;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TIMER_H_ */
|
#endif /* TIMER_H_ */
|
||||||
|
|
||||||
|
|
|
@ -1,616 +1,36 @@
|
||||||
/*++
|
/*++
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
Copyright (c) 2019 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
vector.h
|
vector.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
Dynamic array implementation.
|
|
||||||
Remarks:
|
|
||||||
|
|
||||||
- Empty arrays consume only sizeof(T *) bytes.
|
|
||||||
|
|
||||||
- There is the option of disabling the destructor invocation for elements stored in the vector.
|
|
||||||
This is useful for vectors of int.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2006-09-11.
|
Daniel Schemmel 2019-2-23
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#ifndef VECTOR_H_
|
#ifndef VECTOR_H_
|
||||||
#define VECTOR_H_
|
#define VECTOR_H_
|
||||||
|
|
||||||
#include "util/debug.h"
|
#include "old_vector.h"
|
||||||
#include<algorithm>
|
#include "hash.h"
|
||||||
#include<type_traits>
|
|
||||||
#include<memory.h>
|
|
||||||
#include<functional>
|
|
||||||
#include "util/memory_manager.h"
|
|
||||||
#include "util/hash.h"
|
|
||||||
#include "util/z3_exception.h"
|
|
||||||
|
|
||||||
// disable warning for constant 'if' expressions.
|
|
||||||
// these are used heavily in templates.
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T, bool CallDestructors=true, typename SZ = unsigned>
|
template<typename T, bool CallDestructors=true, typename SZ = unsigned>
|
||||||
class vector {
|
using vector = old_vector<T, CallDestructors, SZ>;
|
||||||
#define SIZE_IDX -1
|
|
||||||
#define CAPACITY_IDX -2
|
|
||||||
T * m_data;
|
|
||||||
|
|
||||||
void destroy_elements() {
|
|
||||||
iterator it = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (; it != e; ++it) {
|
|
||||||
it->~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_memory() {
|
|
||||||
memory::deallocate(reinterpret_cast<char*>(reinterpret_cast<SZ*>(m_data) - 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void expand_vector() {
|
|
||||||
if (m_data == nullptr) {
|
|
||||||
SZ capacity = 2;
|
|
||||||
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
|
||||||
*mem = capacity;
|
|
||||||
mem++;
|
|
||||||
*mem = 0;
|
|
||||||
mem++;
|
|
||||||
m_data = reinterpret_cast<T *>(mem);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SASSERT(capacity() > 0);
|
|
||||||
SZ old_capacity = reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
|
||||||
SZ old_capacity_T = sizeof(T) * old_capacity + sizeof(SZ) * 2;
|
|
||||||
SZ new_capacity = (3 * old_capacity + 1) >> 1;
|
|
||||||
SZ new_capacity_T = sizeof(T) * new_capacity + sizeof(SZ) * 2;
|
|
||||||
if (new_capacity <= old_capacity || new_capacity_T <= old_capacity_T) {
|
|
||||||
throw default_exception("Overflow encountered when expanding vector");
|
|
||||||
}
|
|
||||||
SZ *mem, *old_mem = reinterpret_cast<SZ*>(m_data) - 2;
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
|
|
||||||
if (__has_trivial_copy(T)) {
|
|
||||||
#else
|
|
||||||
if (std::is_trivially_copyable<T>::value) {
|
|
||||||
#endif
|
|
||||||
mem = (SZ*)memory::reallocate(old_mem, new_capacity_T);
|
|
||||||
m_data = reinterpret_cast<T *>(mem + 2);
|
|
||||||
} else {
|
|
||||||
mem = (SZ*)memory::allocate(new_capacity_T);
|
|
||||||
auto old_data = m_data;
|
|
||||||
auto old_size = size();
|
|
||||||
mem[1] = old_size;
|
|
||||||
m_data = reinterpret_cast<T *>(mem + 2);
|
|
||||||
for (unsigned i = 0; i < old_size; ++i) {
|
|
||||||
new (&m_data[i]) T(std::move(old_data[i]));
|
|
||||||
old_data[i].~T();
|
|
||||||
}
|
|
||||||
memory::deallocate(old_mem);
|
|
||||||
}
|
|
||||||
*mem = new_capacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_core(vector const & source) {
|
|
||||||
SZ size = source.size();
|
|
||||||
SZ capacity = source.capacity();
|
|
||||||
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
|
||||||
*mem = capacity;
|
|
||||||
mem++;
|
|
||||||
*mem = size;
|
|
||||||
mem++;
|
|
||||||
m_data = reinterpret_cast<T *>(mem);
|
|
||||||
const_iterator it = source.begin();
|
|
||||||
iterator it2 = begin();
|
|
||||||
SASSERT(it2 == m_data);
|
|
||||||
const_iterator e = source.end();
|
|
||||||
for (; it != e; ++it, ++it2) {
|
|
||||||
new (it2) T(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy() {
|
|
||||||
if (m_data) {
|
|
||||||
if (CallDestructors) {
|
|
||||||
destroy_elements();
|
|
||||||
}
|
|
||||||
free_memory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T data;
|
|
||||||
typedef T * iterator;
|
|
||||||
typedef const T * const_iterator;
|
|
||||||
|
|
||||||
vector():
|
|
||||||
m_data(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(SZ s) {
|
|
||||||
if (s == 0) {
|
|
||||||
m_data = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * s + sizeof(SZ) * 2));
|
|
||||||
*mem = s;
|
|
||||||
mem++;
|
|
||||||
*mem = s;
|
|
||||||
mem++;
|
|
||||||
m_data = reinterpret_cast<T *>(mem);
|
|
||||||
// initialize elements
|
|
||||||
iterator it = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (; it != e; ++it) {
|
|
||||||
new (it) T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(SZ s, T const & elem):
|
|
||||||
m_data(nullptr) {
|
|
||||||
resize(s, elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(vector const & source):
|
|
||||||
m_data(nullptr) {
|
|
||||||
if (source.m_data) {
|
|
||||||
copy_core(source);
|
|
||||||
}
|
|
||||||
SASSERT(size() == source.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(vector&& other) : m_data(nullptr) {
|
|
||||||
std::swap(m_data, other.m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector(SZ s, T const * data):
|
|
||||||
m_data(nullptr) {
|
|
||||||
for (SZ i = 0; i < s; i++) {
|
|
||||||
push_back(data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
~vector() {
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void finalize() {
|
|
||||||
destroy();
|
|
||||||
m_data = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(vector const & other) const {
|
|
||||||
if (this == &other) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (size() != other.size())
|
|
||||||
return false;
|
|
||||||
for (unsigned i = 0; i < size(); i++) {
|
|
||||||
if ((*this)[i] != other[i])
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(vector const & other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector & operator=(vector const & source) {
|
|
||||||
if (this == &source) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
destroy();
|
|
||||||
if (source.m_data) {
|
|
||||||
copy_core(source);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_data = nullptr;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector & operator=(vector && source) {
|
|
||||||
if (this == &source) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
destroy();
|
|
||||||
m_data = nullptr;
|
|
||||||
std::swap(m_data, source.m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool containsp(std::function<bool(T)>& predicate) const {
|
|
||||||
for (auto const& t : *this)
|
|
||||||
if (predicate(t))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* retain elements that satisfy predicate. aka 'where'.
|
|
||||||
*/
|
|
||||||
vector filter_pure(std::function<bool(T)>& predicate) const {
|
|
||||||
vector result;
|
|
||||||
for (auto& t : *this)
|
|
||||||
if (predicate(t))
|
|
||||||
result.push_back(t);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector& filter_update(std::function<bool(T)>& predicate) {
|
|
||||||
unsigned j = 0;
|
|
||||||
for (auto& t : *this)
|
|
||||||
if (predicate(t))
|
|
||||||
set(j++, t);
|
|
||||||
shrink(j);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* update elements using f, aka 'select'
|
|
||||||
*/
|
|
||||||
template <typename S>
|
|
||||||
vector<S> map_pure(std::function<S(T)>& f) const {
|
|
||||||
vector<S> result;
|
|
||||||
for (auto& t : *this)
|
|
||||||
result.push_back(f(t));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector& map_update(std::function<T(T)>& f) {
|
|
||||||
unsigned j = 0;
|
|
||||||
for (auto& t : *this)
|
|
||||||
set(j++, f(t));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
if (m_data) {
|
|
||||||
if (CallDestructors) {
|
|
||||||
destroy_elements();
|
|
||||||
}
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() { reset(); }
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return m_data == nullptr || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SZ size() const {
|
|
||||||
if (m_data == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<SZ *>(m_data)[SIZE_IDX];
|
|
||||||
}
|
|
||||||
|
|
||||||
SZ capacity() const {
|
|
||||||
if (m_data == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return m_data + size();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const {
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const {
|
|
||||||
return m_data + size();
|
|
||||||
}
|
|
||||||
|
|
||||||
class reverse_iterator {
|
|
||||||
T* v;
|
|
||||||
public:
|
|
||||||
reverse_iterator(T* v):v(v) {}
|
|
||||||
|
|
||||||
T operator*() { return *v; }
|
|
||||||
reverse_iterator operator++(int) {
|
|
||||||
reverse_iterator tmp = *this;
|
|
||||||
--v;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
reverse_iterator& operator++() {
|
|
||||||
--v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(reverse_iterator const& other) const {
|
|
||||||
return other.v == v;
|
|
||||||
}
|
|
||||||
bool operator!=(reverse_iterator const& other) const {
|
|
||||||
return other.v != v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
|
|
||||||
reverse_iterator rend() { return reverse_iterator(begin() - 1); }
|
|
||||||
|
|
||||||
void set_end(iterator it) {
|
|
||||||
if (m_data) {
|
|
||||||
SZ new_sz = static_cast<SZ>(it - m_data);
|
|
||||||
if (CallDestructors) {
|
|
||||||
iterator e = end();
|
|
||||||
for(; it != e; ++it) {
|
|
||||||
it->~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = new_sz;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SASSERT(it == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T & operator[](SZ idx) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_data[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
T const & operator[](SZ idx) const {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_data[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
T & get(SZ idx) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_data[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
T const & get(SZ idx) const {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
return m_data[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(SZ idx, T const & val) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
m_data[idx] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(SZ idx, T && val) {
|
|
||||||
SASSERT(idx < size());
|
|
||||||
m_data[idx] = std::move(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
T & back() {
|
|
||||||
SASSERT(!empty());
|
|
||||||
return operator[](size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
T const & back() const {
|
|
||||||
SASSERT(!empty());
|
|
||||||
return operator[](size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back() {
|
|
||||||
SASSERT(!empty());
|
|
||||||
if (CallDestructors) {
|
|
||||||
back().~T();
|
|
||||||
}
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(T const & elem) {
|
|
||||||
if (m_data == nullptr || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX]) {
|
|
||||||
expand_vector();
|
|
||||||
}
|
|
||||||
new (m_data + reinterpret_cast<SZ *>(m_data)[SIZE_IDX]) T(elem);
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(T && elem) {
|
|
||||||
if (m_data == nullptr || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX]) {
|
|
||||||
expand_vector();
|
|
||||||
}
|
|
||||||
new (m_data + reinterpret_cast<SZ *>(m_data)[SIZE_IDX]) T(std::move(elem));
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert(T const & elem) {
|
|
||||||
push_back(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase(iterator pos) {
|
|
||||||
SASSERT(pos >= begin() && pos < end());
|
|
||||||
iterator prev = pos;
|
|
||||||
++pos;
|
|
||||||
iterator e = end();
|
|
||||||
for(; pos != e; ++pos, ++prev) {
|
|
||||||
*prev = *pos;
|
|
||||||
}
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase(T const & elem) {
|
|
||||||
iterator it = std::find(begin(), end(), elem);
|
|
||||||
if (it != end()) {
|
|
||||||
erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shrink(SZ s) {
|
|
||||||
if (m_data) {
|
|
||||||
SASSERT(s <= reinterpret_cast<SZ *>(m_data)[SIZE_IDX]);
|
|
||||||
if (CallDestructors) {
|
|
||||||
iterator it = m_data + s;
|
|
||||||
iterator e = end();
|
|
||||||
for(; it != e; ++it) {
|
|
||||||
it->~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = s;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SASSERT(s == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Args>
|
|
||||||
void resize(SZ s, Args args...) {
|
|
||||||
SZ sz = size();
|
|
||||||
if (s <= sz) { shrink(s); return; }
|
|
||||||
while (s > capacity()) {
|
|
||||||
expand_vector();
|
|
||||||
}
|
|
||||||
SASSERT(m_data != 0);
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = s;
|
|
||||||
iterator it = m_data + sz;
|
|
||||||
iterator end = m_data + s;
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
new (it) T(std::forward<Args>(args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(SZ s) {
|
|
||||||
SZ sz = size();
|
|
||||||
if (s <= sz) { shrink(s); return; }
|
|
||||||
while (s > capacity()) {
|
|
||||||
expand_vector();
|
|
||||||
}
|
|
||||||
SASSERT(m_data != 0);
|
|
||||||
reinterpret_cast<SZ *>(m_data)[SIZE_IDX] = s;
|
|
||||||
iterator it = m_data + sz;
|
|
||||||
iterator end = m_data + s;
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
new (it) T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(vector<T, CallDestructors> const & other) {
|
|
||||||
for(SZ i = 0; i < other.size(); ++i) {
|
|
||||||
push_back(other[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(SZ sz, T const * data) {
|
|
||||||
for(SZ i = 0; i < sz; ++i) {
|
|
||||||
push_back(data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T * c_ptr() const {
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(vector & other) {
|
|
||||||
std::swap(m_data, other.m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reverse() {
|
|
||||||
SZ sz = size();
|
|
||||||
for (SZ i = 0; i < sz/2; ++i) {
|
|
||||||
std::swap(m_data[i], m_data[sz-i-1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fill(T const & elem) {
|
|
||||||
iterator i = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (; i != e; ++i) {
|
|
||||||
*i = elem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fill(unsigned sz, T const & elem) {
|
|
||||||
resize(sz);
|
|
||||||
fill(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool contains(T const & elem) const {
|
|
||||||
const_iterator it = begin();
|
|
||||||
const_iterator e = end();
|
|
||||||
for (; it != e; ++it) {
|
|
||||||
if (*it == elem) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set pos idx with elem. If idx >= size, then expand using default.
|
|
||||||
void setx(SZ idx, T const & elem, T const & d) {
|
|
||||||
if (idx >= size()) {
|
|
||||||
resize(idx+1, d);
|
|
||||||
}
|
|
||||||
m_data[idx] = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return element at position idx, if idx >= size, then return default
|
|
||||||
T const & get(SZ idx, T const & d) const {
|
|
||||||
if (idx >= size()) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
return m_data[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve(SZ s, T const & d) {
|
|
||||||
if (s > size())
|
|
||||||
resize(s, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve(SZ s) {
|
|
||||||
if (s > size())
|
|
||||||
resize(s);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class ptr_vector : public vector<T *, false> {
|
|
||||||
public:
|
|
||||||
ptr_vector():vector<T *, false>() {}
|
|
||||||
ptr_vector(unsigned s):vector<T *, false>(s) {}
|
|
||||||
ptr_vector(unsigned s, T * elem):vector<T *, false>(s, elem) {}
|
|
||||||
ptr_vector(ptr_vector const & source):vector<T *, false>(source) {}
|
|
||||||
ptr_vector(ptr_vector && other) : vector<T*, false>(std::move(other)) {}
|
|
||||||
ptr_vector(unsigned s, T * const * data):vector<T *, false>(s, const_cast<T**>(data)) {}
|
|
||||||
ptr_vector & operator=(ptr_vector const & source) {
|
|
||||||
vector<T *, false>::operator=(source);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename SZ = unsigned>
|
template<typename T, typename SZ = unsigned>
|
||||||
class svector : public vector<T, false, SZ> {
|
using svector = old_svector<T, SZ>;
|
||||||
public:
|
|
||||||
svector():vector<T, false, SZ>() {}
|
|
||||||
svector(SZ s):vector<T, false, SZ>(s) {}
|
|
||||||
svector(SZ s, T const & elem):vector<T, false, SZ>(s, elem) {}
|
|
||||||
svector(svector const & source):vector<T, false, SZ>(source) {}
|
|
||||||
svector(svector && other) : vector<T, false, SZ>(std::move(other)) {}
|
|
||||||
svector(SZ s, T const * data):vector<T, false, SZ>(s, data) {}
|
|
||||||
svector & operator=(svector const & source) {
|
|
||||||
vector<T, false, SZ>::operator=(source);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef svector<int> int_vector;
|
template<typename T>
|
||||||
typedef svector<unsigned> unsigned_vector;
|
using ptr_vector = old_ptr_vector<T>;
|
||||||
typedef svector<char> char_vector;
|
|
||||||
typedef svector<signed char> signed_char_vector;
|
using int_vector = old_svector<int>;
|
||||||
typedef svector<double> double_vector;
|
using unsigned_vector = old_svector<unsigned>;
|
||||||
|
using char_vector = old_svector<char>;
|
||||||
|
using signed_char_vector = old_svector<signed char>;
|
||||||
|
using double_vector = old_svector<double>;
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, unsigned_vector const& v) {
|
inline std::ostream& operator<<(std::ostream& out, unsigned_vector const& v) {
|
||||||
for (unsigned u : v) out << u << " ";
|
for (unsigned u : v) out << u << " ";
|
||||||
|
|
Loading…
Reference in a new issue