mirror of
https://github.com/Z3Prover/z3
synced 2025-06-19 12:23:38 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
4d4497674f
30 changed files with 266 additions and 191 deletions
|
@ -189,3 +189,6 @@ python -c 'import z3; print(z3.get_version_string())'
|
||||||
|
|
||||||
See [``examples/python``](examples/python) for examples.
|
See [``examples/python``](examples/python) for examples.
|
||||||
|
|
||||||
|
### ``Web Assembly``
|
||||||
|
|
||||||
|
[WebAssembly](https://github.com/cpitclaudel/z3.wasm) bindings are provided by Clément Pit-Claudel.
|
||||||
|
|
|
@ -1657,7 +1657,7 @@ else:
|
||||||
if hasattr(builtins, "Z3_LIB_DIRS"):
|
if hasattr(builtins, "Z3_LIB_DIRS"):
|
||||||
_all_dirs = builtins.Z3_LIB_DIRS
|
_all_dirs = builtins.Z3_LIB_DIRS
|
||||||
|
|
||||||
for v in ('Z3_LIBRARY_PATH', 'PATH'):
|
for v in ('Z3_LIBRARY_PATH', 'PATH', 'PYTHONPATH'):
|
||||||
if v in os.environ:
|
if v in os.environ:
|
||||||
lp = os.environ[v];
|
lp = os.environ[v];
|
||||||
lds = lp.split(';') if sys.platform in ('win32') else lp.split(':')
|
lds = lp.split(';') if sys.platform in ('win32') else lp.split(':')
|
||||||
|
|
|
@ -78,7 +78,6 @@ namespace api {
|
||||||
m_bv_util(m()),
|
m_bv_util(m()),
|
||||||
m_datalog_util(m()),
|
m_datalog_util(m()),
|
||||||
m_fpa_util(m()),
|
m_fpa_util(m()),
|
||||||
m_dtutil(m()),
|
|
||||||
m_sutil(m()),
|
m_sutil(m()),
|
||||||
m_last_result(m()),
|
m_last_result(m()),
|
||||||
m_ast_trail(m()),
|
m_ast_trail(m()),
|
||||||
|
|
|
@ -61,7 +61,6 @@ namespace api {
|
||||||
bv_util m_bv_util;
|
bv_util m_bv_util;
|
||||||
datalog::dl_decl_util m_datalog_util;
|
datalog::dl_decl_util m_datalog_util;
|
||||||
fpa_util m_fpa_util;
|
fpa_util m_fpa_util;
|
||||||
datatype_util m_dtutil;
|
|
||||||
seq_util m_sutil;
|
seq_util m_sutil;
|
||||||
|
|
||||||
// Support for old solver API
|
// Support for old solver API
|
||||||
|
@ -122,12 +121,12 @@ namespace api {
|
||||||
bool produce_unsat_cores() const { return m_params.m_unsat_core; }
|
bool produce_unsat_cores() const { return m_params.m_unsat_core; }
|
||||||
bool use_auto_config() const { return m_params.m_auto_config; }
|
bool use_auto_config() const { return m_params.m_auto_config; }
|
||||||
unsigned get_timeout() const { return m_params.m_timeout; }
|
unsigned get_timeout() const { return m_params.m_timeout; }
|
||||||
unsigned get_rlimit() const { return m_params.m_rlimit; }
|
unsigned get_rlimit() const { return m_params.rlimit(); }
|
||||||
arith_util & autil() { return m_arith_util; }
|
arith_util & autil() { return m_arith_util; }
|
||||||
bv_util & bvutil() { return m_bv_util; }
|
bv_util & bvutil() { return m_bv_util; }
|
||||||
datalog::dl_decl_util & datalog_util() { return m_datalog_util; }
|
datalog::dl_decl_util & datalog_util() { return m_datalog_util; }
|
||||||
fpa_util & fpautil() { return m_fpa_util; }
|
fpa_util & fpautil() { return m_fpa_util; }
|
||||||
datatype_util& dtutil() { return m_dtutil; }
|
datatype_util& dtutil() { return m_dt_plugin->u(); }
|
||||||
seq_util& sutil() { return m_sutil; }
|
seq_util& sutil() { return m_sutil; }
|
||||||
family_id get_basic_fid() const { return m_basic_fid; }
|
family_id get_basic_fid() const { return m_basic_fid; }
|
||||||
family_id get_array_fid() const { return m_array_fid; }
|
family_id get_array_fid() const { return m_array_fid; }
|
||||||
|
|
|
@ -2254,7 +2254,12 @@ var * ast_manager::mk_var(unsigned idx, sort * s) {
|
||||||
unsigned sz = var::get_obj_size();
|
unsigned sz = var::get_obj_size();
|
||||||
void * mem = allocate_node(sz);
|
void * mem = allocate_node(sz);
|
||||||
var * new_node = new (mem) var(idx, s);
|
var * new_node = new (mem) var(idx, s);
|
||||||
return register_node(new_node);
|
var * r = register_node(new_node);
|
||||||
|
|
||||||
|
if (m_trace_stream && r == new_node) {
|
||||||
|
*m_trace_stream << "[mk-var] #" << r->get_id() << "\n";
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
app * ast_manager::mk_label(bool pos, unsigned num_names, symbol const * names, expr * n) {
|
app * ast_manager::mk_label(bool pos, unsigned num_names, symbol const * names, expr * n) {
|
||||||
|
|
|
@ -390,6 +390,7 @@ namespace datatype {
|
||||||
TRACE("datatype", tout << "declaring " << datatypes[i]->name() << "\n";);
|
TRACE("datatype", tout << "declaring " << datatypes[i]->name() << "\n";);
|
||||||
if (m_defs.find(datatypes[i]->name(), d)) {
|
if (m_defs.find(datatypes[i]->name(), d)) {
|
||||||
TRACE("datatype", tout << "delete previous version for " << datatypes[i]->name() << "\n";);
|
TRACE("datatype", tout << "delete previous version for " << datatypes[i]->name() << "\n";);
|
||||||
|
u().reset();
|
||||||
dealloc(d);
|
dealloc(d);
|
||||||
}
|
}
|
||||||
m_defs.insert(datatypes[i]->name(), datatypes[i]);
|
m_defs.insert(datatypes[i]->name(), datatypes[i]);
|
||||||
|
|
|
@ -239,7 +239,6 @@ namespace datatype {
|
||||||
map<symbol, def*, symbol_hash_proc, symbol_eq_proc> m_defs;
|
map<symbol, def*, symbol_hash_proc, symbol_eq_proc> m_defs;
|
||||||
svector<symbol> m_def_block;
|
svector<symbol> m_def_block;
|
||||||
unsigned m_class_id;
|
unsigned m_class_id;
|
||||||
util & u() const;
|
|
||||||
|
|
||||||
void inherit(decl_plugin* other_p, ast_translation& tr) override;
|
void inherit(decl_plugin* other_p, ast_translation& tr) override;
|
||||||
|
|
||||||
|
@ -279,6 +278,8 @@ namespace datatype {
|
||||||
def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); }
|
def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); }
|
||||||
def& get_def(symbol const& s) { return *(m_defs[s]); }
|
def& get_def(symbol const& s) { return *(m_defs[s]); }
|
||||||
bool is_declared(sort* s) const { return m_defs.contains(datatype_name(s)); }
|
bool is_declared(sort* s) const { return m_defs.contains(datatype_name(s)); }
|
||||||
|
util & u() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
|
bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
|
||||||
|
|
||||||
|
|
|
@ -3252,7 +3252,9 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args
|
||||||
expr_ref ul(m), in_range(m);
|
expr_ref ul(m), in_range(m);
|
||||||
if (!is_signed) {
|
if (!is_signed) {
|
||||||
ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_bv_neg(m_bv_util.mk_numeral(1, bv_sz)));
|
ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_bv_neg(m_bv_util.mk_numeral(1, bv_sz)));
|
||||||
in_range = m.mk_and(m.mk_not(x_is_neg), m.mk_not(ovfl),
|
in_range = m.mk_and(m.mk_or(m.mk_not(x_is_neg),
|
||||||
|
m.mk_eq(pre_rounded, m_bv_util.mk_numeral(0, bv_sz+3))),
|
||||||
|
m.mk_not(ovfl),
|
||||||
m_bv_util.mk_ule(pre_rounded, ul));
|
m_bv_util.mk_ule(pre_rounded, ul));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -387,7 +387,7 @@ expr_pattern_match::initialize(char const * spec_string) {
|
||||||
m_instrs.push_back(instr(BACKTRACK));
|
m_instrs.push_back(instr(BACKTRACK));
|
||||||
|
|
||||||
std::istringstream is(spec_string);
|
std::istringstream is(spec_string);
|
||||||
cmd_context ctx(true, &m_manager);
|
cmd_context ctx(true, &m_manager);
|
||||||
bool ps = ctx.print_success_enabled();
|
bool ps = ctx.print_success_enabled();
|
||||||
ctx.set_print_success(false);
|
ctx.set_print_success(false);
|
||||||
VERIFY(parse_smt2_commands(ctx, is));
|
VERIFY(parse_smt2_commands(ctx, is));
|
||||||
|
|
|
@ -367,6 +367,9 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
|
||||||
SASSERT(num_args == 2);
|
SASSERT(num_args == 2);
|
||||||
return mk_re_concat(args[0], args[1], result);
|
return mk_re_concat(args[0], args[1], result);
|
||||||
case OP_RE_UNION:
|
case OP_RE_UNION:
|
||||||
|
if (num_args == 1) {
|
||||||
|
result = args[0]; return BR_DONE;
|
||||||
|
}
|
||||||
SASSERT(num_args == 2);
|
SASSERT(num_args == 2);
|
||||||
return mk_re_union(args[0], args[1], result);
|
return mk_re_union(args[0], args[1], result);
|
||||||
case OP_RE_RANGE:
|
case OP_RE_RANGE:
|
||||||
|
@ -853,7 +856,7 @@ br_status seq_rewriter::mk_seq_replace(expr* a, expr* b, expr* c, expr_ref& resu
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
}
|
}
|
||||||
if (m_util.str.is_string(b, s2) && s2.length() == 0) {
|
if (m_util.str.is_string(b, s2) && s2.length() == 0) {
|
||||||
result = m_util.str.mk_concat(a, c);
|
result = m_util.str.mk_concat(c, a);
|
||||||
return BR_REWRITE1;
|
return BR_REWRITE1;
|
||||||
}
|
}
|
||||||
if (m_util.str.is_string(a, s1) && s1.length() == 0) {
|
if (m_util.str.is_string(a, s1) && s1.length() == 0) {
|
||||||
|
|
|
@ -177,7 +177,7 @@ zstring zstring::replace(zstring const& src, zstring const& dst) const {
|
||||||
return zstring(*this);
|
return zstring(*this);
|
||||||
}
|
}
|
||||||
if (src.length() == 0) {
|
if (src.length() == 0) {
|
||||||
return zstring(*this);
|
return dst + zstring(*this);
|
||||||
}
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (unsigned i = 0; i < length(); ++i) {
|
for (unsigned i = 0; i < length(); ++i) {
|
||||||
|
@ -256,6 +256,7 @@ bool zstring::contains(zstring const& other) const {
|
||||||
|
|
||||||
int zstring::indexof(zstring const& other, int offset) const {
|
int zstring::indexof(zstring const& other, int offset) const {
|
||||||
SASSERT(offset >= 0);
|
SASSERT(offset >= 0);
|
||||||
|
if (static_cast<unsigned>(offset) <= length() && other.length() == 0) return offset;
|
||||||
if (static_cast<unsigned>(offset) == length()) return -1;
|
if (static_cast<unsigned>(offset) == length()) return -1;
|
||||||
if (other.length() + offset > length()) return -1;
|
if (other.length() + offset > length()) return -1;
|
||||||
unsigned last = length() - other.length();
|
unsigned last = length() - other.length();
|
||||||
|
|
|
@ -503,7 +503,7 @@ public:
|
||||||
ctx.set_random_seed(to_unsigned(val));
|
ctx.set_random_seed(to_unsigned(val));
|
||||||
}
|
}
|
||||||
else if (m_option == m_reproducible_resource_limit) {
|
else if (m_option == m_reproducible_resource_limit) {
|
||||||
ctx.params().m_rlimit = to_unsigned(val);
|
ctx.params().set_rlimit(to_unsigned(val));
|
||||||
}
|
}
|
||||||
else if (m_option == m_verbosity) {
|
else if (m_option == m_verbosity) {
|
||||||
set_verbosity_level(to_unsigned(val));
|
set_verbosity_level(to_unsigned(val));
|
||||||
|
|
|
@ -718,8 +718,8 @@ void cmd_context::init_manager_core(bool new_manager) {
|
||||||
}
|
}
|
||||||
m_dt_eh = alloc(dt_eh, *this);
|
m_dt_eh = alloc(dt_eh, *this);
|
||||||
m_pmanager->set_new_datatype_eh(m_dt_eh.get());
|
m_pmanager->set_new_datatype_eh(m_dt_eh.get());
|
||||||
if (!has_logic()) {
|
if (!has_logic() && new_manager) {
|
||||||
TRACE("cmd_context", tout << "init manager\n";);
|
TRACE("cmd_context", tout << "init manager " << m_logic << "\n";);
|
||||||
// add list type only if the logic is not specified.
|
// add list type only if the logic is not specified.
|
||||||
// it prevents clashes with builtin types.
|
// it prevents clashes with builtin types.
|
||||||
insert(pm().mk_plist_decl());
|
insert(pm().mk_plist_decl());
|
||||||
|
@ -757,6 +757,7 @@ void cmd_context::init_external_manager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmd_context::set_logic(symbol const & s) {
|
bool cmd_context::set_logic(symbol const & s) {
|
||||||
|
TRACE("cmd_context", tout << s << "\n";);
|
||||||
if (has_logic())
|
if (has_logic())
|
||||||
throw cmd_exception("the logic has already been set");
|
throw cmd_exception("the logic has already been set");
|
||||||
if (has_manager() && m_main_ctx)
|
if (has_manager() && m_main_ctx)
|
||||||
|
@ -1240,7 +1241,7 @@ void cmd_context::insert_aux_pdecl(pdecl * p) {
|
||||||
m_aux_pdecls.push_back(p);
|
m_aux_pdecls.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_context::reset(bool finalize) {
|
void cmd_context::reset(bool finalize) {
|
||||||
m_processing_pareto = false;
|
m_processing_pareto = false;
|
||||||
m_logic = symbol::null;
|
m_logic = symbol::null;
|
||||||
m_check_sat_result = nullptr;
|
m_check_sat_result = nullptr;
|
||||||
|
@ -1327,7 +1328,8 @@ void cmd_context::push() {
|
||||||
s.m_macros_stack_lim = m_macros_stack.size();
|
s.m_macros_stack_lim = m_macros_stack.size();
|
||||||
s.m_aux_pdecls_lim = m_aux_pdecls.size();
|
s.m_aux_pdecls_lim = m_aux_pdecls.size();
|
||||||
s.m_assertions_lim = m_assertions.size();
|
s.m_assertions_lim = m_assertions.size();
|
||||||
if (m_solver)
|
m().limit().push(m_params.rlimit());
|
||||||
|
if (m_solver)
|
||||||
m_solver->push();
|
m_solver->push();
|
||||||
if (m_opt)
|
if (m_opt)
|
||||||
m_opt->push();
|
m_opt->push();
|
||||||
|
@ -1350,9 +1352,10 @@ void cmd_context::restore_func_decls(unsigned old_sz) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_context::restore_psort_inst(unsigned old_sz) {
|
void cmd_context::restore_psort_inst(unsigned old_sz) {
|
||||||
for (unsigned i = old_sz; i < m_psort_inst_stack.size(); ++i) {
|
for (unsigned i = m_psort_inst_stack.size(); i-- > old_sz; ) {
|
||||||
pdecl * s = m_psort_inst_stack[i];
|
pdecl * s = m_psort_inst_stack[i];
|
||||||
s->reset_cache(*m_pmanager);
|
s->reset_cache(pm());
|
||||||
|
pm().dec_ref(s);
|
||||||
}
|
}
|
||||||
m_psort_inst_stack.resize(old_sz);
|
m_psort_inst_stack.resize(old_sz);
|
||||||
}
|
}
|
||||||
|
@ -1441,6 +1444,9 @@ void cmd_context::pop(unsigned n) {
|
||||||
restore_assertions(s.m_assertions_lim);
|
restore_assertions(s.m_assertions_lim);
|
||||||
restore_psort_inst(s.m_psort_inst_stack_lim);
|
restore_psort_inst(s.m_psort_inst_stack_lim);
|
||||||
m_scopes.shrink(new_lvl);
|
m_scopes.shrink(new_lvl);
|
||||||
|
while (n--) {
|
||||||
|
m().limit().pop();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1451,7 +1457,7 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
|
||||||
TRACE("before_check_sat", dump_assertions(tout););
|
TRACE("before_check_sat", dump_assertions(tout););
|
||||||
init_manager();
|
init_manager();
|
||||||
unsigned timeout = m_params.m_timeout;
|
unsigned timeout = m_params.m_timeout;
|
||||||
unsigned rlimit = m_params.m_rlimit;
|
unsigned rlimit = m_params.rlimit();
|
||||||
scoped_watch sw(*this);
|
scoped_watch sw(*this);
|
||||||
lbool r;
|
lbool r;
|
||||||
bool was_opt = false;
|
bool was_opt = false;
|
||||||
|
@ -1528,7 +1534,7 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
|
||||||
|
|
||||||
void cmd_context::get_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars, expr_ref_vector & conseq) {
|
void cmd_context::get_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars, expr_ref_vector & conseq) {
|
||||||
unsigned timeout = m_params.m_timeout;
|
unsigned timeout = m_params.m_timeout;
|
||||||
unsigned rlimit = m_params.m_rlimit;
|
unsigned rlimit = m_params.rlimit();
|
||||||
lbool r;
|
lbool r;
|
||||||
m_check_sat_result = m_solver.get(); // solver itself stores the result.
|
m_check_sat_result = m_solver.get(); // solver itself stores the result.
|
||||||
m_solver->set_progress_callback(this);
|
m_solver->set_progress_callback(this);
|
||||||
|
@ -2024,8 +2030,8 @@ void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_owner.m_scopes.size() > 0) {
|
if (m_owner.m_scopes.size() > 0) {
|
||||||
|
m_owner.pm().inc_ref(pd);
|
||||||
m_owner.m_psort_inst_stack.push_back(pd);
|
m_owner.m_psort_inst_stack.push_back(pd);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ class context_params {
|
||||||
void set_bool(bool & opt, char const * param, char const * value);
|
void set_bool(bool & opt, char const * param, char const * value);
|
||||||
void set_uint(unsigned & opt, char const * param, char const * value);
|
void set_uint(unsigned & opt, char const * param, char const * value);
|
||||||
|
|
||||||
|
unsigned m_rlimit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool m_auto_config;
|
bool m_auto_config;
|
||||||
bool m_proof;
|
bool m_proof;
|
||||||
|
@ -42,10 +44,11 @@ public:
|
||||||
bool m_unsat_core;
|
bool m_unsat_core;
|
||||||
bool m_smtlib2_compliant; // it must be here because it enable/disable the use of coercions in the ast_manager.
|
bool m_smtlib2_compliant; // it must be here because it enable/disable the use of coercions in the ast_manager.
|
||||||
unsigned m_timeout;
|
unsigned m_timeout;
|
||||||
unsigned m_rlimit;
|
|
||||||
|
|
||||||
|
unsigned rlimit() const { return m_rlimit; }
|
||||||
context_params();
|
context_params();
|
||||||
void set(char const * param, char const * value);
|
void set(char const * param, char const * value);
|
||||||
|
void set_rlimit(unsigned lim) { m_rlimit = lim; }
|
||||||
void updt_params();
|
void updt_params();
|
||||||
void updt_params(params_ref const & p);
|
void updt_params(params_ref const & p);
|
||||||
static void collect_param_descrs(param_descrs & d);
|
static void collect_param_descrs(param_descrs & d);
|
||||||
|
|
|
@ -205,7 +205,7 @@ public:
|
||||||
tref->set_logic(ctx.get_logic());
|
tref->set_logic(ctx.get_logic());
|
||||||
ast_manager & m = ctx.m();
|
ast_manager & m = ctx.m();
|
||||||
unsigned timeout = p.get_uint("timeout", ctx.params().m_timeout);
|
unsigned timeout = p.get_uint("timeout", ctx.params().m_timeout);
|
||||||
unsigned rlimit = p.get_uint("rlimit", ctx.params().m_rlimit);
|
unsigned rlimit = p.get_uint("rlimit", ctx.params().rlimit());
|
||||||
labels_vec labels;
|
labels_vec labels;
|
||||||
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
|
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
|
||||||
assert_exprs_from(ctx, *g);
|
assert_exprs_from(ctx, *g);
|
||||||
|
@ -321,7 +321,7 @@ public:
|
||||||
assert_exprs_from(ctx, *g);
|
assert_exprs_from(ctx, *g);
|
||||||
|
|
||||||
unsigned timeout = p.get_uint("timeout", ctx.params().m_timeout);
|
unsigned timeout = p.get_uint("timeout", ctx.params().m_timeout);
|
||||||
unsigned rlimit = p.get_uint("rlimit", ctx.params().m_rlimit);
|
unsigned rlimit = p.get_uint("rlimit", ctx.params().rlimit());
|
||||||
|
|
||||||
goal_ref_buffer result_goals;
|
goal_ref_buffer result_goals;
|
||||||
model_converter_ref mc;
|
model_converter_ref mc;
|
||||||
|
|
|
@ -31,6 +31,10 @@ Revision History:
|
||||||
#include "muz/base/dl_rule.h"
|
#include "muz/base/dl_rule.h"
|
||||||
#include "muz/base/dl_util.h"
|
#include "muz/base/dl_util.h"
|
||||||
#include "util/stopwatch.h"
|
#include "util/stopwatch.h"
|
||||||
|
#ifndef __STDC_FORMAT_MACROS
|
||||||
|
#define __STDC_FORMAT_MACROS
|
||||||
|
#endif
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
namespace datalog {
|
namespace datalog {
|
||||||
|
|
||||||
|
@ -623,9 +627,9 @@ namespace datalog {
|
||||||
|
|
||||||
bool string_to_uint64(const char * s, uint64_t & res) {
|
bool string_to_uint64(const char * s, uint64_t & res) {
|
||||||
#if _WINDOWS
|
#if _WINDOWS
|
||||||
int converted = sscanf_s(s, "%I64u", &res);
|
int converted = sscanf_s(s, "%" SCNu64, &res);
|
||||||
#else
|
#else
|
||||||
int converted = sscanf(s, "%I64u", &res);
|
int converted = sscanf(s, "%" SCNu64, &res);
|
||||||
#endif
|
#endif
|
||||||
if(converted==0) {
|
if(converted==0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -265,6 +265,9 @@ namespace opt {
|
||||||
normalize();
|
normalize();
|
||||||
internalize();
|
internalize();
|
||||||
update_solver();
|
update_solver();
|
||||||
|
if (contains_quantifiers()) {
|
||||||
|
warning_msg("optimization with quantified constraints is not supported");
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
if (is_qsat_opt()) {
|
if (is_qsat_opt()) {
|
||||||
return run_qsat_opt();
|
return run_qsat_opt();
|
||||||
|
@ -368,7 +371,6 @@ namespace opt {
|
||||||
if (result == l_true && committed) m_optsmt.commit_assignment(index);
|
if (result == l_true && committed) m_optsmt.commit_assignment(index);
|
||||||
if (result == l_true && m_optsmt.is_unbounded(index, is_max) && contains_quantifiers()) {
|
if (result == l_true && m_optsmt.is_unbounded(index, is_max) && contains_quantifiers()) {
|
||||||
throw default_exception("unbounded objectives on quantified constraints is not supported");
|
throw default_exception("unbounded objectives on quantified constraints is not supported");
|
||||||
result = l_undef;
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,13 +283,13 @@ namespace opt {
|
||||||
struct is_propositional_fn;
|
struct is_propositional_fn;
|
||||||
bool is_propositional(expr* e);
|
bool is_propositional(expr* e);
|
||||||
|
|
||||||
void init_solver();
|
void init_solver();
|
||||||
void update_solver();
|
void update_solver();
|
||||||
void setup_arith_solver();
|
void setup_arith_solver();
|
||||||
void add_maxsmt(symbol const& id, unsigned index);
|
void add_maxsmt(symbol const& id, unsigned index);
|
||||||
void set_simplify(tactic *simplify);
|
void set_simplify(tactic *simplify);
|
||||||
void set_pareto(pareto_base* p);
|
void set_pareto(pareto_base* p);
|
||||||
void clear_state();
|
void clear_state();
|
||||||
|
|
||||||
bool is_numeral(expr* e, rational& n) const;
|
bool is_numeral(expr* e, rational& n) const;
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,9 @@ namespace opt {
|
||||||
if (m.canceled()) {
|
if (m.canceled()) {
|
||||||
is_sat = l_undef;
|
is_sat = l_undef;
|
||||||
}
|
}
|
||||||
|
if (is_sat == l_undef) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (is_sat == l_false) {
|
if (is_sat == l_false) {
|
||||||
TRACE("opt", tout << "Unsat\n";);
|
TRACE("opt", tout << "Unsat\n";);
|
||||||
break;
|
break;
|
||||||
|
@ -97,9 +100,6 @@ namespace opt {
|
||||||
//DEBUG_CODE(verify_cores(cores););
|
//DEBUG_CODE(verify_cores(cores););
|
||||||
s().assert_expr(fml);
|
s().assert_expr(fml);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
//DEBUG_CODE(verify_cores(cores););
|
|
||||||
}
|
|
||||||
update_cores(wth(), cores);
|
update_cores(wth(), cores);
|
||||||
wth().init_min_cost(m_upper - m_lower);
|
wth().init_min_cost(m_upper - m_lower);
|
||||||
trace_bounds("wmax");
|
trace_bounds("wmax");
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct pattern_validation_functor {
|
||||||
|
|
||||||
bool is_forbidden(func_decl const * decl) {
|
bool is_forbidden(func_decl const * decl) {
|
||||||
family_id fid = decl->get_family_id();
|
family_id fid = decl->get_family_id();
|
||||||
if (fid == m_bfid && decl->get_decl_kind() != OP_TRUE && decl->get_decl_kind() != OP_FALSE)
|
if (fid == m_bfid && decl->get_decl_kind() != OP_EQ && decl->get_decl_kind() != OP_TRUE && decl->get_decl_kind() != OP_FALSE)
|
||||||
return true;
|
return true;
|
||||||
if (fid == m_lfid)
|
if (fid == m_lfid)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -461,7 +461,7 @@ namespace smt {
|
||||||
TRACE("datatype", tout << "occurs_check_explain " << mk_bounded_pp(app->get_owner(), get_manager()) << " <-> " << mk_bounded_pp(root->get_owner(), get_manager()) << "\n";);
|
TRACE("datatype", tout << "occurs_check_explain " << mk_bounded_pp(app->get_owner(), get_manager()) << " <-> " << mk_bounded_pp(root->get_owner(), get_manager()) << "\n";);
|
||||||
enode* app_parent = nullptr;
|
enode* app_parent = nullptr;
|
||||||
|
|
||||||
// first: explain that root=v, given that app=cstor(…,v,…)
|
// first: explain that root=v, given that app=cstor(...,v,...)
|
||||||
for (enode * arg : enode::args(oc_get_cstor(app))) {
|
for (enode * arg : enode::args(oc_get_cstor(app))) {
|
||||||
// found an argument which is equal to root
|
// found an argument which is equal to root
|
||||||
if (arg->get_root() == root->get_root()) {
|
if (arg->get_root() == root->get_root()) {
|
||||||
|
|
|
@ -134,8 +134,7 @@ void theory_seq::solution_map::pop_scope(unsigned num_scopes) {
|
||||||
if (num_scopes == 0) return;
|
if (num_scopes == 0) return;
|
||||||
m_cache.reset();
|
m_cache.reset();
|
||||||
unsigned start = m_limit[m_limit.size() - num_scopes];
|
unsigned start = m_limit[m_limit.size() - num_scopes];
|
||||||
for (unsigned i = m_updates.size(); i > start; ) {
|
for (unsigned i = m_updates.size(); i-- > start; ) {
|
||||||
--i;
|
|
||||||
if (m_updates[i] == INS) {
|
if (m_updates[i] == INS) {
|
||||||
m_map.remove(m_lhs[i].get());
|
m_map.remove(m_lhs[i].get());
|
||||||
}
|
}
|
||||||
|
@ -436,8 +435,8 @@ bool theory_seq::is_unit_eq(expr_ref_vector const& ls, expr_ref_vector const& rs
|
||||||
if (ls.empty() || !is_var(ls[0])) {
|
if (ls.empty() || !is_var(ls[0])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < rs.size(); ++i) {
|
for (expr* r : rs) {
|
||||||
if (!m_util.str.is_unit(rs[i])) {
|
if (!m_util.str.is_unit(r)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,8 +481,7 @@ void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector
|
||||||
|
|
||||||
bool theory_seq::branch_variable_mb() {
|
bool theory_seq::branch_variable_mb() {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
for (unsigned i = 0; i < m_eqs.size(); ++i) {
|
for (eq const& e : m_eqs) {
|
||||||
eq const& e = m_eqs[i];
|
|
||||||
vector<rational> len1, len2;
|
vector<rational> len1, len2;
|
||||||
if (!is_complex(e)) {
|
if (!is_complex(e)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1473,7 +1471,7 @@ bool theory_seq::add_solution(expr* l, expr* r, dependency* deps) {
|
||||||
if (l == r) {
|
if (l == r) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TRACE("seq", tout << mk_pp(l, m) << " ==> " << mk_pp(r, m) << "\n";);
|
TRACE("seq", tout << mk_pp(l, m) << " ==> " << mk_pp(r, m) << "\n"; display_deps(tout, deps););
|
||||||
m_new_solution = true;
|
m_new_solution = true;
|
||||||
m_rep.update(l, r, deps);
|
m_rep.update(l, r, deps);
|
||||||
enode* n1 = ensure_enode(l);
|
enode* n1 = ensure_enode(l);
|
||||||
|
@ -1513,7 +1511,9 @@ bool theory_seq::solve_eq(expr_ref_vector const& l, expr_ref_vector const& r, de
|
||||||
change = canonize(r, rs, dep2) || change;
|
change = canonize(r, rs, dep2) || change;
|
||||||
deps = m_dm.mk_join(dep2, deps);
|
deps = m_dm.mk_join(dep2, deps);
|
||||||
TRACE("seq", tout << l << " = " << r << " ==> ";
|
TRACE("seq", tout << l << " = " << r << " ==> ";
|
||||||
tout << ls << " = " << rs << "\n";);
|
tout << ls << " = " << rs << "\n";
|
||||||
|
display_deps(tout, deps);
|
||||||
|
);
|
||||||
if (!ctx.inconsistent() && simplify_eq(ls, rs, deps)) {
|
if (!ctx.inconsistent() && simplify_eq(ls, rs, deps)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2224,63 +2224,7 @@ void theory_seq::internalize_eq_eh(app * atom, bool_var v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool theory_seq::internalize_atom(app* a, bool) {
|
bool theory_seq::internalize_atom(app* a, bool) {
|
||||||
#if 1
|
|
||||||
return internalize_term(a);
|
return internalize_term(a);
|
||||||
#else
|
|
||||||
if (is_skolem(m_eq, a)) {
|
|
||||||
return internalize_term(a);
|
|
||||||
}
|
|
||||||
context & ctx = get_context();
|
|
||||||
bool_var bv = ctx.mk_bool_var(a);
|
|
||||||
ctx.set_var_theory(bv, get_id());
|
|
||||||
ctx.mark_as_relevant(bv);
|
|
||||||
|
|
||||||
expr* e1, *e2;
|
|
||||||
if (m_util.str.is_in_re(a, e1, e2)) {
|
|
||||||
return internalize_term(to_app(e1)) && internalize_re(e2);
|
|
||||||
}
|
|
||||||
if (m_util.str.is_contains(a, e1, e2) ||
|
|
||||||
m_util.str.is_prefix(a, e1, e2) ||
|
|
||||||
m_util.str.is_suffix(a, e1, e2)) {
|
|
||||||
return internalize_term(to_app(e1)) && internalize_term(to_app(e2));
|
|
||||||
}
|
|
||||||
if (is_accept(a) || is_reject(a) || is_step(a) || is_skolem(symbol("seq.is_digit"), a)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
UNREACHABLE();
|
|
||||||
return internalize_term(a);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool theory_seq::internalize_re(expr* e) {
|
|
||||||
expr* e1, *e2;
|
|
||||||
unsigned lc, uc;
|
|
||||||
if (m_util.re.is_to_re(e, e1)) {
|
|
||||||
return internalize_term(to_app(e1));
|
|
||||||
}
|
|
||||||
if (m_util.re.is_star(e, e1) ||
|
|
||||||
m_util.re.is_plus(e, e1) ||
|
|
||||||
m_util.re.is_opt(e, e1) ||
|
|
||||||
m_util.re.is_loop(e, e1, lc) ||
|
|
||||||
m_util.re.is_loop(e, e1, lc, uc) ||
|
|
||||||
m_util.re.is_complement(e, e1)) {
|
|
||||||
return internalize_re(e1);
|
|
||||||
}
|
|
||||||
if (m_util.re.is_union(e, e1, e2) ||
|
|
||||||
m_util.re.is_intersection(e, e1, e2) ||
|
|
||||||
m_util.re.is_concat(e, e1, e2)) {
|
|
||||||
return internalize_re(e1) && internalize_re(e2);
|
|
||||||
}
|
|
||||||
if (m_util.re.is_full_seq(e) ||
|
|
||||||
m_util.re.is_full_char(e) ||
|
|
||||||
m_util.re.is_empty(e)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (m_util.re.is_range(e, e1, e2)) {
|
|
||||||
return internalize_term(to_app(e1)) && internalize_term(to_app(e2));
|
|
||||||
}
|
|
||||||
UNREACHABLE();
|
|
||||||
return internalize_term(to_app(e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool theory_seq::internalize_term(app* term) {
|
bool theory_seq::internalize_term(app* term) {
|
||||||
|
@ -2344,8 +2288,8 @@ void theory_seq::add_int_string(expr* e) {
|
||||||
|
|
||||||
bool theory_seq::check_int_string() {
|
bool theory_seq::check_int_string() {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
for (unsigned i = 0; i < m_int_string.size(); ++i) {
|
for (expr * e : m_int_string) {
|
||||||
expr* e = m_int_string[i].get(), *n;
|
expr* n = nullptr;
|
||||||
if (m_util.str.is_itos(e) && add_itos_val_axiom(e)) {
|
if (m_util.str.is_itos(e) && add_itos_val_axiom(e)) {
|
||||||
change = true;
|
change = true;
|
||||||
}
|
}
|
||||||
|
@ -2358,9 +2302,21 @@ bool theory_seq::check_int_string() {
|
||||||
|
|
||||||
void theory_seq::add_stoi_axiom(expr* e) {
|
void theory_seq::add_stoi_axiom(expr* e) {
|
||||||
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
||||||
SASSERT(m_util.str.is_stoi(e));
|
expr* s = nullptr;
|
||||||
literal l = mk_simplified_literal(m_autil.mk_ge(e, arith_util(m).mk_int(-1)));
|
VERIFY (m_util.str.is_stoi(e, s));
|
||||||
|
|
||||||
|
// stoi(s) >= -1
|
||||||
|
literal l = mk_simplified_literal(m_autil.mk_ge(e, m_autil.mk_int(-1)));
|
||||||
add_axiom(l);
|
add_axiom(l);
|
||||||
|
|
||||||
|
// stoi(s) >= 0 <=> s in (0-9)+
|
||||||
|
expr_ref num_re(m);
|
||||||
|
num_re = m_util.re.mk_range(m_util.str.mk_string(symbol("0")), m_util.str.mk_string(symbol("9")));
|
||||||
|
num_re = m_util.re.mk_plus(num_re);
|
||||||
|
app_ref in_re(m_util.re.mk_in_re(s, num_re), m);
|
||||||
|
literal ge0 = mk_simplified_literal(m_autil.mk_ge(e, m_autil.mk_int(0)));
|
||||||
|
add_axiom(~ge0, mk_literal(in_re));
|
||||||
|
add_axiom(ge0, ~mk_literal(in_re));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool theory_seq::add_stoi_val_axiom(expr* e) {
|
bool theory_seq::add_stoi_val_axiom(expr* e) {
|
||||||
|
@ -2404,8 +2360,9 @@ bool theory_seq::add_stoi_val_axiom(expr* e) {
|
||||||
lits.push_back(~is_digit(ith_char));
|
lits.push_back(~is_digit(ith_char));
|
||||||
nums.push_back(digit2int(ith_char));
|
nums.push_back(digit2int(ith_char));
|
||||||
}
|
}
|
||||||
for (unsigned i = sz, c = 1; i-- > 0; c *= 10) {
|
rational c(1);
|
||||||
coeff = m_autil.mk_int(c);
|
for (unsigned i = sz; i-- > 0; c *= rational(10)) {
|
||||||
|
coeff = m_autil.mk_numeral(c, true);
|
||||||
nums[i] = m_autil.mk_mul(coeff, nums[i].get());
|
nums[i] = m_autil.mk_mul(coeff, nums[i].get());
|
||||||
}
|
}
|
||||||
num = m_autil.mk_add(nums.size(), nums.c_ptr());
|
num = m_autil.mk_add(nums.size(), nums.c_ptr());
|
||||||
|
@ -2674,7 +2631,12 @@ void theory_seq::init_model(expr_ref_vector const& es) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void theory_seq::finalize_model(model_generator& mg) {
|
||||||
|
m_rep.pop_scope(1);
|
||||||
|
}
|
||||||
|
|
||||||
void theory_seq::init_model(model_generator & mg) {
|
void theory_seq::init_model(model_generator & mg) {
|
||||||
|
m_rep.push_scope();
|
||||||
m_factory = alloc(seq_factory, get_manager(), get_family_id(), mg.get_model());
|
m_factory = alloc(seq_factory, get_manager(), get_family_id(), mg.get_model());
|
||||||
mg.register_factory(m_factory);
|
mg.register_factory(m_factory);
|
||||||
for (ne const& n : m_nqs) {
|
for (ne const& n : m_nqs) {
|
||||||
|
@ -3428,8 +3390,8 @@ void theory_seq::add_itos_length_axiom(expr* len) {
|
||||||
|
|
||||||
void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
||||||
TRACE("seq", tout << mk_pp(n, m) << " <- " << (is_true?"true":"false") << "\n";);
|
TRACE("seq", tout << mk_pp(n, m) << " <- " << (is_true?"true":"false") << "\n";);
|
||||||
expr* e1 = nullptr, *e2 = nullptr;
|
expr* s = nullptr, *re = nullptr;
|
||||||
VERIFY(m_util.str.is_in_re(n, e1, e2));
|
VERIFY(m_util.str.is_in_re(n, s, re));
|
||||||
|
|
||||||
expr_ref tmp(n, m);
|
expr_ref tmp(n, m);
|
||||||
m_rewrite(tmp);
|
m_rewrite(tmp);
|
||||||
|
@ -3450,21 +3412,21 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref e3(e2, m);
|
expr_ref e3(re, m);
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
literal lit = ctx.get_literal(n);
|
literal lit = ctx.get_literal(n);
|
||||||
if (!is_true) {
|
if (!is_true) {
|
||||||
e3 = m_util.re.mk_complement(e2);
|
e3 = m_util.re.mk_complement(re);
|
||||||
lit.neg();
|
lit.neg();
|
||||||
}
|
}
|
||||||
eautomaton* a = get_automaton(e3);
|
eautomaton* a = get_automaton(e3);
|
||||||
if (!a) return;
|
if (!a) return;
|
||||||
|
|
||||||
|
|
||||||
expr_ref len(m_util.str.mk_length(e1), m);
|
expr_ref len(m_util.str.mk_length(s), m);
|
||||||
for (unsigned i = 0; i < a->num_states(); ++i) {
|
for (unsigned i = 0; i < a->num_states(); ++i) {
|
||||||
literal acc = mk_accept(e1, len, e3, i);
|
literal acc = mk_accept(s, len, e3, i);
|
||||||
literal rej = mk_reject(e1, len, e3, i);
|
literal rej = mk_reject(s, len, e3, i);
|
||||||
add_axiom(a->is_final_state(i)?acc:~acc);
|
add_axiom(a->is_final_state(i)?acc:~acc);
|
||||||
add_axiom(a->is_final_state(i)?~rej:rej);
|
add_axiom(a->is_final_state(i)?~rej:rej);
|
||||||
}
|
}
|
||||||
|
@ -3475,8 +3437,8 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
||||||
literal_vector lits;
|
literal_vector lits;
|
||||||
lits.push_back(~lit);
|
lits.push_back(~lit);
|
||||||
|
|
||||||
for (unsigned i = 0; i < states.size(); ++i) {
|
for (unsigned st : states) {
|
||||||
lits.push_back(mk_accept(e1, zero, e3, states[i]));
|
lits.push_back(mk_accept(s, zero, e3, st));
|
||||||
}
|
}
|
||||||
if (lits.size() == 2) {
|
if (lits.size() == 2) {
|
||||||
propagate_lit(nullptr, 1, &lit, lits[1]);
|
propagate_lit(nullptr, 1, &lit, lits[1]);
|
||||||
|
@ -3527,8 +3489,8 @@ static bool get_arith_value(context& ctx, theory_id afid, expr* e, expr_ref& v)
|
||||||
bool theory_seq::get_num_value(expr* e, rational& val) const {
|
bool theory_seq::get_num_value(expr* e, rational& val) const {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
expr_ref _val(m);
|
expr_ref _val(m);
|
||||||
if (!ctx.e_internalized(e))
|
if (!ctx.e_internalized(e))
|
||||||
return false;
|
return false;
|
||||||
enode* next = ctx.get_enode(e), *n = next;
|
enode* next = ctx.get_enode(e), *n = next;
|
||||||
do {
|
do {
|
||||||
if (get_arith_value(ctx, m_autil.get_family_id(), next->get_owner(), _val) && m_autil.is_numeral(_val, val) && val.is_int()) {
|
if (get_arith_value(ctx, m_autil.get_family_id(), next->get_owner(), _val) && m_autil.is_numeral(_val, val) && val.is_int()) {
|
||||||
|
@ -3925,8 +3887,8 @@ theory_seq::dependency* theory_seq::mk_join(dependency* deps, literal lit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
theory_seq::dependency* theory_seq::mk_join(dependency* deps, literal_vector const& lits) {
|
theory_seq::dependency* theory_seq::mk_join(dependency* deps, literal_vector const& lits) {
|
||||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
for (literal l : lits) {
|
||||||
deps = mk_join(deps, lits[i]);
|
deps = mk_join(deps, l);
|
||||||
}
|
}
|
||||||
return deps;
|
return deps;
|
||||||
}
|
}
|
||||||
|
@ -4131,53 +4093,15 @@ void theory_seq::new_diseq_eh(theory_var v1, theory_var v2) {
|
||||||
TRACE("seq", tout << "new disequality " << get_context().get_scope_level() << ": " << eq << "\n";);
|
TRACE("seq", tout << "new disequality " << get_context().get_scope_level() << ": " << eq << "\n";);
|
||||||
m_rewrite(eq);
|
m_rewrite(eq);
|
||||||
if (!m.is_false(eq)) {
|
if (!m.is_false(eq)) {
|
||||||
|
|
||||||
literal lit = mk_eq(e1, e2, false);
|
literal lit = mk_eq(e1, e2, false);
|
||||||
|
|
||||||
|
|
||||||
if (m_util.str.is_empty(e2)) {
|
if (m_util.str.is_empty(e2)) {
|
||||||
std::swap(e1, e2);
|
std::swap(e1, e2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false && m_util.str.is_empty(e1)) {
|
dependency* dep = m_dm.mk_leaf(assumption(~lit));
|
||||||
expr_ref head(m), tail(m), conc(m);
|
m_nqs.push_back(ne(e1, e2, dep));
|
||||||
mk_decompose(e2, head, tail);
|
solve_nqs(m_nqs.size() - 1);
|
||||||
conc = mk_concat(head, tail);
|
|
||||||
propagate_eq(~lit, e2, conc, true);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
// (e1 = "" & e2 = xdz) or (e2 = "" & e1 = xcy) or (e1 = xcy & e2 = xdz & c != d) or (e1 = x & e2 = xdz) or (e2 = x & e1 = xcy)
|
|
||||||
// e1 = "" or e1 = xcy or e1 = x
|
|
||||||
// e2 = "" or e2 = xdz or e2 = x
|
|
||||||
// e1 = xcy or e2 = xdz
|
|
||||||
// c != d
|
|
||||||
|
|
||||||
sort* char_sort = 0;
|
|
||||||
expr_ref emp(m);
|
|
||||||
VERIFY(m_util.is_seq(m.get_sort(e1), char_sort));
|
|
||||||
emp = m_util.str.mk_empty(m.get_sort(e1));
|
|
||||||
|
|
||||||
expr_ref x = mk_skolem(symbol("seq.ne.x"), e1, e2);
|
|
||||||
expr_ref y = mk_skolem(symbol("seq.ne.y"), e1, e2);
|
|
||||||
expr_ref z = mk_skolem(symbol("seq.ne.z"), e1, e2);
|
|
||||||
expr_ref c = mk_skolem(symbol("seq.ne.c"), e1, e2, 0, char_sort);
|
|
||||||
expr_ref d = mk_skolem(symbol("seq.ne.d"), e1, e2, 0, char_sort);
|
|
||||||
literal e1_is_emp = mk_seq_eq(e1, emp);
|
|
||||||
literal e2_is_emp = mk_seq_eq(e2, emp);
|
|
||||||
literal e1_is_xcy = mk_seq_eq(e1, mk_concat(x, m_util.str.mk_unit(c), y));
|
|
||||||
literal e2_is_xdz = mk_seq_eq(e2, mk_concat(x, m_util.str.mk_unit(d), z));
|
|
||||||
add_axiom(lit, e1_is_emp, e1_is_xcy, mk_seq_eq(e1, x));
|
|
||||||
add_axiom(lit, e2_is_emp, e2_is_xdz, mk_seq_eq(e2, x));
|
|
||||||
add_axiom(lit, e1_is_xcy, e2_is_xdz);
|
|
||||||
add_axiom(lit, ~mk_eq(c, d, false));
|
|
||||||
#else
|
|
||||||
else {
|
|
||||||
dependency* dep = m_dm.mk_leaf(assumption(~lit));
|
|
||||||
m_nqs.push_back(ne(e1, e2, dep));
|
|
||||||
solve_nqs(m_nqs.size() - 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4508,8 +4432,7 @@ bool theory_seq::add_reject2reject(expr* rej, bool& change) {
|
||||||
ensure_nth(~len_le_idx, s, idx);
|
ensure_nth(~len_le_idx, s, idx);
|
||||||
literal_vector eqs;
|
literal_vector eqs;
|
||||||
bool has_undef = false;
|
bool has_undef = false;
|
||||||
for (unsigned i = 0; i < mvs.size(); ++i) {
|
for (eautomaton::move const& mv : mvs) {
|
||||||
eautomaton::move const& mv = mvs[i];
|
|
||||||
literal eq = mk_literal(mv.t()->accept(nth));
|
literal eq = mk_literal(mv.t()->accept(nth));
|
||||||
switch (ctx.get_assignment(eq)) {
|
switch (ctx.get_assignment(eq)) {
|
||||||
case l_false:
|
case l_false:
|
||||||
|
|
|
@ -64,14 +64,14 @@ namespace smt {
|
||||||
// + a cache for normalization.
|
// + a cache for normalization.
|
||||||
class solution_map {
|
class solution_map {
|
||||||
enum map_update { INS, DEL };
|
enum map_update { INS, DEL };
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
dependency_manager& m_dm;
|
dependency_manager& m_dm;
|
||||||
eqdep_map_t m_map;
|
eqdep_map_t m_map;
|
||||||
eval_cache m_cache;
|
eval_cache m_cache;
|
||||||
expr_ref_vector m_lhs, m_rhs;
|
expr_ref_vector m_lhs, m_rhs;
|
||||||
ptr_vector<dependency> m_deps;
|
ptr_vector<dependency> m_deps;
|
||||||
svector<map_update> m_updates;
|
svector<map_update> m_updates;
|
||||||
unsigned_vector m_limit;
|
unsigned_vector m_limit;
|
||||||
|
|
||||||
void add_trail(map_update op, expr* l, expr* r, dependency* d);
|
void add_trail(map_update op, expr* l, expr* r, dependency* d);
|
||||||
public:
|
public:
|
||||||
|
@ -362,6 +362,7 @@ namespace smt {
|
||||||
void collect_statistics(::statistics & st) const override;
|
void collect_statistics(::statistics & st) const override;
|
||||||
model_value_proc * mk_value(enode * n, model_generator & mg) override;
|
model_value_proc * mk_value(enode * n, model_generator & mg) override;
|
||||||
void init_model(model_generator & mg) override;
|
void init_model(model_generator & mg) override;
|
||||||
|
void finalize_model(model_generator & mg) override;
|
||||||
void init_search_eh() override;
|
void init_search_eh() override;
|
||||||
|
|
||||||
void init_model(expr_ref_vector const& es);
|
void init_model(expr_ref_vector const& es);
|
||||||
|
@ -389,7 +390,6 @@ namespace smt {
|
||||||
vector<rational> const& ll, vector<rational> const& rl);
|
vector<rational> const& ll, vector<rational> const& rl);
|
||||||
bool set_empty(expr* x);
|
bool set_empty(expr* x);
|
||||||
bool is_complex(eq const& e);
|
bool is_complex(eq const& e);
|
||||||
bool internalize_re(expr* e);
|
|
||||||
|
|
||||||
bool check_extensionality();
|
bool check_extensionality();
|
||||||
bool check_contains();
|
bool check_contains();
|
||||||
|
|
|
@ -8096,7 +8096,7 @@ namespace smt {
|
||||||
rational nn1Len, nn2Len;
|
rational nn1Len, nn2Len;
|
||||||
bool nn1Len_exists = get_len_value(lhs, nn1Len);
|
bool nn1Len_exists = get_len_value(lhs, nn1Len);
|
||||||
bool nn2Len_exists = get_len_value(rhs, nn2Len);
|
bool nn2Len_exists = get_len_value(rhs, nn2Len);
|
||||||
expr * emptyStr = mk_string("");
|
expr_ref emptyStr(mk_string(""), m);
|
||||||
|
|
||||||
if (nn1Len_exists && nn1Len.is_zero()) {
|
if (nn1Len_exists && nn1Len.is_zero()) {
|
||||||
if (!in_same_eqc(lhs, emptyStr) && rhs != emptyStr) {
|
if (!in_same_eqc(lhs, emptyStr) && rhs != emptyStr) {
|
||||||
|
|
|
@ -22,14 +22,14 @@ Revision History:
|
||||||
|
|
||||||
|
|
||||||
bool smt_logics::supported_logic(symbol const & s) {
|
bool smt_logics::supported_logic(symbol const & s) {
|
||||||
return logic_has_uf(s) || logic_is_all(s) || logic_has_fd(s) ||
|
return logic_has_uf(s) || logic_is_all(s) || logic_has_fd(s) ||
|
||||||
logic_has_arith(s) || logic_has_bv(s) ||
|
logic_has_arith(s) || logic_has_bv(s) ||
|
||||||
logic_has_array(s) || logic_has_seq(s) || logic_has_str(s) ||
|
logic_has_array(s) || logic_has_seq(s) || logic_has_str(s) ||
|
||||||
logic_has_horn(s) || logic_has_fpa(s);
|
logic_has_horn(s) || logic_has_fpa(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_reals_only(symbol const& s) {
|
bool smt_logics::logic_has_reals_only(symbol const& s) {
|
||||||
return
|
return
|
||||||
s == "QF_RDL" ||
|
s == "QF_RDL" ||
|
||||||
s == "QF_LRA" ||
|
s == "QF_LRA" ||
|
||||||
s == "UFLRA" ||
|
s == "UFLRA" ||
|
||||||
|
@ -84,8 +84,9 @@ bool smt_logics::logic_has_arith(symbol const & s) {
|
||||||
s == "QF_BVFP" ||
|
s == "QF_BVFP" ||
|
||||||
s == "QF_S" ||
|
s == "QF_S" ||
|
||||||
s == "ALL" ||
|
s == "ALL" ||
|
||||||
s == "QF_FD" ||
|
s == "QF_FD" ||
|
||||||
s == "HORN";
|
s == "HORN" ||
|
||||||
|
s == "QF_FPLRA";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_bv(symbol const & s) {
|
bool smt_logics::logic_has_bv(symbol const & s) {
|
||||||
|
@ -137,7 +138,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 == "ALL";
|
return s == "QF_FP" || s == "QF_FPBV" || s == "QF_BVFP" || s == "QF_FPLRA" || s == "ALL";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_logics::logic_has_uf(symbol const & s) {
|
bool smt_logics::logic_has_uf(symbol const & s) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ z3_add_component(fpa_tactics
|
||||||
fpa2bv_model_converter.cpp
|
fpa2bv_model_converter.cpp
|
||||||
fpa2bv_tactic.cpp
|
fpa2bv_tactic.cpp
|
||||||
qffp_tactic.cpp
|
qffp_tactic.cpp
|
||||||
|
qffplra_tactic.cpp
|
||||||
COMPONENT_DEPENDENCIES
|
COMPONENT_DEPENDENCIES
|
||||||
arith_tactics
|
arith_tactics
|
||||||
bv_tactics
|
bv_tactics
|
||||||
|
@ -14,4 +15,5 @@ z3_add_component(fpa_tactics
|
||||||
TACTIC_HEADERS
|
TACTIC_HEADERS
|
||||||
fpa2bv_tactic.h
|
fpa2bv_tactic.h
|
||||||
qffp_tactic.h
|
qffp_tactic.h
|
||||||
|
qffplra_tactic.h
|
||||||
)
|
)
|
||||||
|
|
72
src/tactic/fpa/qffplra_tactic.cpp
Normal file
72
src/tactic/fpa/qffplra_tactic.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2012 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
qffpalra_tactic.cpp
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Tactic for QF_FPLRA benchmarks.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Christoph (cwinter) 2018-04-24
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#include "tactic/tactical.h"
|
||||||
|
#include "tactic/fpa/qffp_tactic.h"
|
||||||
|
#include "tactic/fpa/qffplra_tactic.h"
|
||||||
|
|
||||||
|
tactic * mk_qffplra_tactic(ast_manager & m, params_ref const & p) {
|
||||||
|
tactic * st = mk_qffp_tactic(m, p);
|
||||||
|
st->updt_params(p);
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct is_non_qffplra_predicate {
|
||||||
|
struct found {};
|
||||||
|
ast_manager & m;
|
||||||
|
bv_util bu;
|
||||||
|
fpa_util fu;
|
||||||
|
arith_util au;
|
||||||
|
|
||||||
|
is_non_qffplra_predicate(ast_manager & _m) : m(_m), bu(m), fu(m), au(m) {}
|
||||||
|
|
||||||
|
void operator()(var *) { throw found(); }
|
||||||
|
|
||||||
|
void operator()(quantifier *) { throw found(); }
|
||||||
|
|
||||||
|
void operator()(app * n) {
|
||||||
|
sort * s = get_sort(n);
|
||||||
|
if (!m.is_bool(s) && !fu.is_float(s) && !fu.is_rm(s) && !bu.is_bv_sort(s) && !au.is_real(s))
|
||||||
|
throw found();
|
||||||
|
family_id fid = n->get_family_id();
|
||||||
|
if (fid == m.get_basic_family_id() ||
|
||||||
|
fid == fu.get_family_id() ||
|
||||||
|
fid == bu.get_family_id() ||
|
||||||
|
fid == au.get_family_id())
|
||||||
|
return;
|
||||||
|
if (is_uninterp_const(n))
|
||||||
|
return;
|
||||||
|
if (au.is_real(s))
|
||||||
|
return;
|
||||||
|
|
||||||
|
throw found();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class is_qffplra_probe : public probe {
|
||||||
|
public:
|
||||||
|
result operator()(goal const & g) override {
|
||||||
|
return !test<is_non_qffplra_predicate>(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
~is_qffplra_probe() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
probe * mk_is_qffplra_probe() {
|
||||||
|
return alloc(is_qffplra_probe);
|
||||||
|
}
|
38
src/tactic/fpa/qffplra_tactic.h
Normal file
38
src/tactic/fpa/qffplra_tactic.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2012 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
qffplra_tactic.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Tactic for QF_FPLRA benchmarks.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Christoph (cwinter) 2018-04-24
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#ifndef QFFPLRA_TACTIC_H_
|
||||||
|
#define QFFPLRA_TACTIC_H_
|
||||||
|
|
||||||
|
#include "util/params.h"
|
||||||
|
class ast_manager;
|
||||||
|
class tactic;
|
||||||
|
|
||||||
|
tactic * mk_qffplra_tactic(ast_manager & m, params_ref const & p = params_ref());
|
||||||
|
/*
|
||||||
|
ADD_TACTIC("qffplra", "(try to) solve goal using the tactic for QF_FPLRA.", "mk_qffplra_tactic(m, p)")
|
||||||
|
*/
|
||||||
|
|
||||||
|
probe * mk_is_qffplra_probe();
|
||||||
|
/*
|
||||||
|
ADD_PROBE("is-qffplra", "true if the goal is in QF_FPLRA.", "mk_is_qffplra_probe()")
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
|
@ -28,24 +28,26 @@ Notes:
|
||||||
#include "tactic/arith/probe_arith.h"
|
#include "tactic/arith/probe_arith.h"
|
||||||
#include "tactic/smtlogics/quant_tactics.h"
|
#include "tactic/smtlogics/quant_tactics.h"
|
||||||
#include "tactic/fpa/qffp_tactic.h"
|
#include "tactic/fpa/qffp_tactic.h"
|
||||||
|
#include "tactic/fpa/qffplra_tactic.h"
|
||||||
#include "tactic/smtlogics/qfaufbv_tactic.h"
|
#include "tactic/smtlogics/qfaufbv_tactic.h"
|
||||||
#include "tactic/smtlogics/qfauflia_tactic.h"
|
#include "tactic/smtlogics/qfauflia_tactic.h"
|
||||||
#include "tactic/smtlogics/qfufnra_tactic.h"
|
#include "tactic/smtlogics/qfufnra_tactic.h"
|
||||||
|
|
||||||
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_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),
|
||||||
cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m),
|
cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m),
|
||||||
cond(mk_is_qflra_probe(), mk_qflra_tactic(m),
|
cond(mk_is_qflra_probe(), mk_qflra_tactic(m),
|
||||||
cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m),
|
cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m),
|
||||||
cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m),
|
cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m),
|
||||||
cond(mk_is_lira_probe(), mk_lira_tactic(m, p),
|
cond(mk_is_lira_probe(), mk_lira_tactic(m, p),
|
||||||
cond(mk_is_nra_probe(), mk_nra_tactic(m),
|
cond(mk_is_nra_probe(), mk_nra_tactic(m),
|
||||||
cond(mk_is_qffp_probe(), mk_qffp_tactic(m, p),
|
cond(mk_is_qffp_probe(), mk_qffp_tactic(m, p),
|
||||||
|
cond(mk_is_qffplra_probe(), mk_qffplra_tactic(m, p),
|
||||||
//cond(mk_is_qfufnra_probe(), mk_qfufnra_tactic(m, p),
|
//cond(mk_is_qfufnra_probe(), mk_qfufnra_tactic(m, p),
|
||||||
mk_smt_tactic()))))))))))),
|
mk_smt_tactic())))))))))))),
|
||||||
p);
|
p);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,14 +208,22 @@ struct scoped_timer::imp {
|
||||||
pthread_cond_signal(&m_condition_var);
|
pthread_cond_signal(&m_condition_var);
|
||||||
pthread_mutex_unlock(&m_mutex);
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
|
||||||
if (pthread_join(m_thread_id, nullptr) != 0)
|
if (pthread_join(m_thread_id, nullptr) != 0) {
|
||||||
throw default_exception("failed to join thread");
|
warning_msg("failed to join thread");
|
||||||
if (pthread_mutex_destroy(&m_mutex) != 0)
|
return;
|
||||||
throw default_exception("failed to destroy pthread mutex");
|
}
|
||||||
if (pthread_cond_destroy(&m_condition_var) != 0)
|
if (pthread_mutex_destroy(&m_mutex) != 0) {
|
||||||
throw default_exception("failed to destroy pthread condition variable");
|
warning_msg("failed to destroy pthread mutex");
|
||||||
if (pthread_attr_destroy(&m_attributes) != 0)
|
return;
|
||||||
throw default_exception("failed to destroy pthread attributes object");
|
}
|
||||||
|
if (pthread_cond_destroy(&m_condition_var) != 0) {
|
||||||
|
warning_msg("failed to destroy pthread condition variable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pthread_attr_destroy(&m_attributes) != 0) {
|
||||||
|
warning_msg("failed to destroy pthread attributes object");
|
||||||
|
return;
|
||||||
|
}
|
||||||
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NETBSD_)
|
#elif defined(_LINUX_) || defined(_FREEBSD_) || defined(_NETBSD_)
|
||||||
// Linux & FreeBSD & NetBSD
|
// Linux & FreeBSD & NetBSD
|
||||||
bool init = false;
|
bool init = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue