mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
Merge branch 'unstable' of https://git01.codeplex.com/z3 into fpa-api
This commit is contained in:
commit
634a93d699
32 changed files with 602 additions and 94 deletions
|
@ -23,6 +23,7 @@ void preprocessor_params::updt_local_params(params_ref const & _p) {
|
|||
smt_params_helper p(_p);
|
||||
m_macro_finder = p.macro_finder();
|
||||
m_pull_nested_quantifiers = p.pull_nested_quantifiers();
|
||||
m_refine_inj_axiom = p.refine_inj_axioms();
|
||||
}
|
||||
|
||||
void preprocessor_params::updt_params(params_ref const & p) {
|
||||
|
|
|
@ -14,6 +14,7 @@ def_module_params(module_name='smt',
|
|||
('delay_units', BOOL, False, 'if true then z3 will not restart when a unit clause is learned'),
|
||||
('delay_units_threshold', UINT, 32, 'maximum number of learned unit clauses before restarting, ingored if delay_units is false'),
|
||||
('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'),
|
||||
('refine_inj_axioms', BOOL, True, 'refine injectivity axioms'),
|
||||
('soft_timeout', UINT, 0, 'soft timeout (0 means no timeout)'),
|
||||
('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'),
|
||||
('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'),
|
||||
|
|
|
@ -20,6 +20,7 @@ Revision History:
|
|||
#include"proto_model.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"expr_functors.h"
|
||||
|
||||
datatype_factory::datatype_factory(ast_manager & m, proto_model & md):
|
||||
struct_factory(m, m.mk_family_id("datatype"), md),
|
||||
|
@ -47,8 +48,10 @@ expr * datatype_factory::get_some_value(sort * s) {
|
|||
*/
|
||||
expr * datatype_factory::get_last_fresh_value(sort * s) {
|
||||
expr * val = 0;
|
||||
if (m_last_fresh_value.find(s, val))
|
||||
if (m_last_fresh_value.find(s, val)) {
|
||||
TRACE("datatype_factory", tout << "cached fresh value: " << mk_pp(val, m_manager) << "\n";);
|
||||
return val;
|
||||
}
|
||||
value_set * set = get_value_set(s);
|
||||
if (set->empty())
|
||||
val = get_some_value(s);
|
||||
|
@ -59,6 +62,17 @@ expr * datatype_factory::get_last_fresh_value(sort * s) {
|
|||
return val;
|
||||
}
|
||||
|
||||
bool datatype_factory::is_subterm_of_last_value(app* e) {
|
||||
expr* last;
|
||||
if (!m_last_fresh_value.find(m_manager.get_sort(e), last)) {
|
||||
return false;
|
||||
}
|
||||
contains_app contains(m_manager, e);
|
||||
bool result = contains(last);
|
||||
TRACE("datatype_factory", tout << mk_pp(e, m_manager) << " in " << mk_pp(last, m_manager) << " " << result << "\n";);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Create an almost fresh value. If s is recursive, then the result is not 0.
|
||||
It also updates m_last_fresh_value
|
||||
|
@ -105,11 +119,18 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) {
|
|||
}
|
||||
}
|
||||
if (recursive || found_fresh_arg) {
|
||||
expr * new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
|
||||
app * new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
|
||||
SASSERT(!found_fresh_arg || !set->contains(new_value));
|
||||
register_value(new_value);
|
||||
if (m_util.is_recursive(s))
|
||||
m_last_fresh_value.insert(s, new_value);
|
||||
if (m_util.is_recursive(s)) {
|
||||
if (is_subterm_of_last_value(new_value)) {
|
||||
new_value = static_cast<app*>(m_last_fresh_value.find(s));
|
||||
}
|
||||
else {
|
||||
m_last_fresh_value.insert(s, new_value);
|
||||
}
|
||||
}
|
||||
TRACE("datatype_factory", tout << "almost fresh: " << mk_pp(new_value, m_manager) << "\n";);
|
||||
return new_value;
|
||||
}
|
||||
}
|
||||
|
@ -181,12 +202,20 @@ expr * datatype_factory::get_fresh_value(sort * s) {
|
|||
expr_ref_vector args(m_manager);
|
||||
bool found_sibling = false;
|
||||
unsigned num = constructor->get_arity();
|
||||
TRACE("datatype_factory", tout << "checking constructor: " << constructor->get_name() << "\n";);
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
sort * s_arg = constructor->get_domain(i);
|
||||
TRACE("datatype_factory", tout << mk_pp(s, m_manager) << " "
|
||||
<< mk_pp(s_arg, m_manager) << " are_siblings "
|
||||
<< m_util.are_siblings(s, s_arg) << " is_datatype "
|
||||
<< m_util.is_datatype(s_arg) << " found_sibling "
|
||||
<< found_sibling << "\n";);
|
||||
if (!found_sibling && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg)) {
|
||||
found_sibling = true;
|
||||
expr * maybe_new_arg = get_almost_fresh_value(s_arg);
|
||||
if (!maybe_new_arg) {
|
||||
TRACE("datatype_factory",
|
||||
tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";);
|
||||
maybe_new_arg = m_model.get_some_value(s_arg);
|
||||
found_sibling = false;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ class datatype_factory : public struct_factory {
|
|||
expr * get_last_fresh_value(sort * s);
|
||||
expr * get_almost_fresh_value(sort * s);
|
||||
|
||||
bool is_subterm_of_last_value(app* e);
|
||||
|
||||
public:
|
||||
datatype_factory(ast_manager & m, proto_model & md);
|
||||
virtual ~datatype_factory() {}
|
||||
|
|
|
@ -247,6 +247,7 @@ bool proto_model::eval(expr * e, expr_ref & result, bool model_completion) {
|
|||
new_t = mk_some_interp_for(f);
|
||||
}
|
||||
else {
|
||||
TRACE("model_eval", tout << f->get_name() << " is uninterpreted\n";);
|
||||
is_ok = false;
|
||||
}
|
||||
}
|
||||
|
@ -294,6 +295,7 @@ bool proto_model::eval(expr * e, expr_ref & result, bool model_completion) {
|
|||
// f is an uninterpreted function, there is no need to use m_simplifier.mk_app
|
||||
new_t = m_manager.mk_app(f, num_args, args.c_ptr());
|
||||
trail.push_back(new_t);
|
||||
TRACE("model_eval", tout << f->get_name() << " is uninterpreted\n";);
|
||||
is_ok = false;
|
||||
}
|
||||
}
|
||||
|
@ -326,6 +328,7 @@ bool proto_model::eval(expr * e, expr_ref & result, bool model_completion) {
|
|||
todo.pop_back();
|
||||
break;
|
||||
case AST_QUANTIFIER:
|
||||
TRACE("model_eval", tout << "found quantifier\n" << mk_pp(a, m_manager) << "\n";);
|
||||
is_ok = false; // evaluator does not handle quantifiers.
|
||||
SASSERT(a != 0);
|
||||
eval_cache.insert(a, a);
|
||||
|
|
|
@ -396,7 +396,7 @@ namespace smt {
|
|||
|
||||
// Support for evaluating expressions in the current model.
|
||||
proto_model * m_model;
|
||||
obj_map<expr, expr *> m_eval_cache;
|
||||
obj_map<expr, expr *> m_eval_cache[2];
|
||||
expr_ref_vector m_eval_cache_range;
|
||||
|
||||
ptr_vector<node> m_root_nodes;
|
||||
|
@ -409,7 +409,8 @@ namespace smt {
|
|||
}
|
||||
|
||||
void reset_eval_cache() {
|
||||
m_eval_cache.reset();
|
||||
m_eval_cache[0].reset();
|
||||
m_eval_cache[1].reset();
|
||||
m_eval_cache_range.reset();
|
||||
}
|
||||
|
||||
|
@ -468,6 +469,7 @@ namespace smt {
|
|||
|
||||
~auf_solver() {
|
||||
flush_nodes();
|
||||
reset_eval_cache();
|
||||
}
|
||||
|
||||
void set_context(context * ctx) {
|
||||
|
@ -547,7 +549,7 @@ namespace smt {
|
|||
for (obj_map<expr, unsigned>::iterator it = elems.begin(); it != elems.end(); it++) {
|
||||
expr * n = it->m_key;
|
||||
expr * n_val = eval(n, true);
|
||||
if (!m_manager.is_value(n_val))
|
||||
if (!n_val || !m_manager.is_value(n_val))
|
||||
to_delete.push_back(n);
|
||||
}
|
||||
for (ptr_vector<expr>::iterator it = to_delete.begin(); it != to_delete.end(); it++) {
|
||||
|
@ -569,16 +571,19 @@ namespace smt {
|
|||
|
||||
virtual expr * eval(expr * n, bool model_completion) {
|
||||
expr * r = 0;
|
||||
if (m_eval_cache.find(n, r)) {
|
||||
if (m_eval_cache[model_completion].find(n, r)) {
|
||||
return r;
|
||||
}
|
||||
expr_ref tmp(m_manager);
|
||||
if (!m_model->eval(n, tmp, model_completion))
|
||||
if (!m_model->eval(n, tmp, model_completion)) {
|
||||
r = 0;
|
||||
else
|
||||
TRACE("model_finder", tout << "eval\n" << mk_pp(n, m_manager) << "\n-----> null\n";);
|
||||
}
|
||||
else {
|
||||
r = tmp;
|
||||
TRACE("model_finder", tout << "eval\n" << mk_pp(n, m_manager) << "\n----->\n" << mk_pp(r, m_manager) << "\n";);
|
||||
m_eval_cache.insert(n, r);
|
||||
TRACE("model_finder", tout << "eval\n" << mk_pp(n, m_manager) << "\n----->\n" << mk_pp(r, m_manager) << "\n";);
|
||||
}
|
||||
m_eval_cache[model_completion].insert(n, r);
|
||||
m_eval_cache_range.push_back(r);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ namespace smt {
|
|||
if (th && th->build_models()) {
|
||||
if (r->get_th_var(th->get_id()) != null_theory_var) {
|
||||
proc = th->mk_value(r, *this);
|
||||
SASSERT(proc);
|
||||
}
|
||||
else {
|
||||
TRACE("model_bug", tout << "creating fresh value for #" << r->get_owner_id() << "\n";);
|
||||
|
@ -110,6 +111,7 @@ namespace smt {
|
|||
}
|
||||
else {
|
||||
proc = mk_model_value(r);
|
||||
SASSERT(proc);
|
||||
}
|
||||
}
|
||||
SASSERT(proc);
|
||||
|
|
|
@ -193,7 +193,7 @@ namespace smt {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!r.get_base_var() == x && x > y) {
|
||||
if (r.get_base_var() != x && x > y) {
|
||||
std::swap(x, y);
|
||||
k.neg();
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ namespace smt {
|
|||
m.register_factory(alloc(dl_factory, m_util, m.get_model()));
|
||||
}
|
||||
|
||||
virtual smt::model_value_proc * mk_value(smt::enode * n) {
|
||||
virtual smt::model_value_proc * mk_value(smt::enode * n, smt::model_generator&) {
|
||||
return alloc(dl_value_proc, *this, n);
|
||||
}
|
||||
|
||||
|
@ -201,9 +201,8 @@ namespace smt {
|
|||
if(!m_reps.find(s, r) || !m_vals.find(s,v)) {
|
||||
SASSERT(!m_reps.contains(s));
|
||||
sort* bv = b().mk_sort(64);
|
||||
// TBD: filter these from model.
|
||||
r = m().mk_fresh_func_decl("rep",1, &s,bv);
|
||||
v = m().mk_fresh_func_decl("val",1, &bv,s);
|
||||
r = m().mk_func_decl(m_util.get_family_id(), datalog::OP_DL_REP, 0, 0, 1, &s, bv);
|
||||
v = m().mk_func_decl(m_util.get_family_id(), datalog::OP_DL_ABS, 0, 0, 1, &bv, s);
|
||||
m_reps.insert(s, r);
|
||||
m_vals.insert(s, v);
|
||||
add_trail(r);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue