mirror of
https://github.com/Z3Prover/z3
synced 2025-08-21 02:30:23 +00:00
Merge branch 'master' into unit_prop_on_monomials
This commit is contained in:
commit
db84d21e3b
24 changed files with 128 additions and 60 deletions
|
@ -157,6 +157,9 @@ namespace api {
|
|||
flush_objects();
|
||||
for (auto& kv : m_allocated_objects) {
|
||||
api::object* val = kv.m_value;
|
||||
#ifdef SINGLE_THREAD
|
||||
# define m_concurrent_dec_ref false
|
||||
#endif
|
||||
DEBUG_CODE(if (!m_concurrent_dec_ref) warning_msg("Uncollected memory: %d: %s", kv.m_key, typeid(*val).name()););
|
||||
dealloc(val);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ Notes:
|
|||
* Add or overwrite value in model.
|
||||
*/
|
||||
void model_converter::display_add(std::ostream& out, smt2_pp_environment& env, ast_manager& m, func_decl* f, expr* e) {
|
||||
VERIFY(e);
|
||||
if (!e)
|
||||
return;
|
||||
VERIFY(f->get_range() == e->get_sort());
|
||||
ast_smt2_pp_rev(out, f, e, env, params_ref(), 0, "model-add") << "\n";
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ Revision History:
|
|||
--*/
|
||||
#include "ast/normal_forms/elim_term_ite.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
|
||||
br_status elim_term_ite_cfg::reduce_app(func_decl* f, unsigned n, expr * const* args, expr_ref& result, proof_ref& result_pr) {
|
||||
if (!m.is_term_ite(f)) {
|
||||
|
@ -38,3 +39,4 @@ br_status elim_term_ite_cfg::reduce_app(func_decl* f, unsigned n, expr * const*
|
|||
return BR_DONE;
|
||||
}
|
||||
|
||||
template class rewriter_tpl<elim_term_ite_cfg>;
|
||||
|
|
|
@ -624,9 +624,11 @@ bool pattern_inference_cfg::reduce_quantifier(
|
|||
proof_ref & result_pr) {
|
||||
|
||||
TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";);
|
||||
if (!is_forall(q)) {
|
||||
if (!m_params.m_pi_enabled)
|
||||
return false;
|
||||
|
||||
if (!is_forall(q))
|
||||
return false;
|
||||
}
|
||||
|
||||
int weight = q->get_weight();
|
||||
|
||||
|
@ -653,9 +655,8 @@ bool pattern_inference_cfg::reduce_quantifier(
|
|||
}
|
||||
}
|
||||
|
||||
if (q->get_num_patterns() > 0) {
|
||||
if (q->get_num_patterns() > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_params.m_pi_nopat_weight >= 0)
|
||||
weight = m_params.m_pi_nopat_weight;
|
||||
|
|
|
@ -17,6 +17,8 @@ Notes:
|
|||
|
||||
--*/
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
#include "ast/rewriter/push_app_ite.h"
|
||||
#include "ast/rewriter/elim_bounds.h"
|
||||
#include "ast/ast_ll_pp.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
|
@ -417,3 +419,6 @@ void inv_var_shifter::process_var(var * v) {
|
|||
}
|
||||
|
||||
template class rewriter_tpl<beta_reducer_cfg>;
|
||||
template class rewriter_tpl<ng_push_app_ite_cfg>;
|
||||
template class rewriter_tpl<push_app_ite_cfg>;
|
||||
template class rewriter_tpl<elim_bounds_cfg>;
|
||||
|
|
|
@ -1716,6 +1716,10 @@ br_status seq_rewriter::mk_seq_last_index(expr* a, expr* b, expr_ref& result) {
|
|||
result = m_autil.mk_numeral(rational(idx), true);
|
||||
return BR_DONE;
|
||||
}
|
||||
if (a == b) {
|
||||
result = m_autil.mk_int(0);
|
||||
return BR_DONE;
|
||||
}
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
||||
|
|
|
@ -243,8 +243,8 @@ namespace euf {
|
|||
|
||||
void solve_context_eqs::collect_nested_equalities(dependent_expr const& df, expr_mark& visited, dep_eq_vector& eqs) {
|
||||
|
||||
svector<std::tuple<bool,unsigned,expr*>> todo;
|
||||
todo.push_back({ false, 0, df.fml()});
|
||||
svector<std::tuple<bool,unsigned,expr*, unsigned>> todo;
|
||||
todo.push_back({ false, 0, df.fml(), 0});
|
||||
|
||||
// even depth is conjunctive context, odd is disjunctive
|
||||
// when alternating between conjunctive and disjunctive context, increment depth.
|
||||
|
@ -255,37 +255,85 @@ namespace euf {
|
|||
return (0 == depth % 2) ? depth : depth + 1;
|
||||
};
|
||||
|
||||
while (!todo.empty()) {
|
||||
auto [s, depth, f] = todo.back();
|
||||
todo.pop_back();
|
||||
for (unsigned i = 0; i < todo.size(); ++i) {
|
||||
auto [s, depth, f, p] = todo[i];
|
||||
if (visited.is_marked(f))
|
||||
continue;
|
||||
visited.mark(f, true);
|
||||
if (s && m.is_and(f)) {
|
||||
for (auto* arg : *to_app(f))
|
||||
todo.push_back({ s, inc_or(depth), arg });
|
||||
todo.push_back({ s, inc_or(depth), arg, i });
|
||||
}
|
||||
else if (!s && m.is_or(f)) {
|
||||
for (auto* arg : *to_app(f))
|
||||
todo.push_back({ s, inc_or(depth), arg });
|
||||
todo.push_back({ s, inc_or(depth), arg, i });
|
||||
}
|
||||
if (!s && m.is_and(f)) {
|
||||
for (auto* arg : *to_app(f))
|
||||
todo.push_back({ s, inc_and(depth), arg });
|
||||
todo.push_back({ s, inc_and(depth), arg, i });
|
||||
}
|
||||
else if (s && m.is_or(f)) {
|
||||
for (auto* arg : *to_app(f))
|
||||
todo.push_back({ s, inc_and(depth), arg });
|
||||
todo.push_back({ s, inc_and(depth), arg, i });
|
||||
}
|
||||
else if (m.is_not(f, f))
|
||||
todo.push_back({ !s, depth, f });
|
||||
todo.push_back({ !s, depth, f, i });
|
||||
else if (!s && 1 <= depth) {
|
||||
unsigned sz = eqs.size();
|
||||
for (extract_eq* ex : m_solve_eqs.m_extract_plugins) {
|
||||
ex->set_allow_booleans(false);
|
||||
ex->get_eqs(dependent_expr(m, f, nullptr, df.dep()), eqs);
|
||||
ex->set_allow_booleans(true);
|
||||
}
|
||||
// prune eqs for solutions that are not safe in df.fml()
|
||||
for (; sz < eqs.size(); ++sz) {
|
||||
if (!is_safe_var(eqs[sz].var, i, df.fml(), todo)) {
|
||||
eqs[sz] = eqs.back();
|
||||
--sz;
|
||||
eqs.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool solve_context_eqs::is_safe_var(expr* x, unsigned i, expr* f, svector<std::tuple<bool,unsigned,expr*,unsigned>> const& todo) {
|
||||
m_contains_v.reset();
|
||||
m_todo.push_back(f);
|
||||
mark_occurs(m_todo, x, m_contains_v);
|
||||
SASSERT(m_todo.empty());
|
||||
|
||||
auto is_parent = [&](unsigned p, unsigned i) {
|
||||
while (p != i && i != 0) {
|
||||
auto [_s,_depth, _f, _p] = todo[i];
|
||||
i = _p;
|
||||
}
|
||||
return p == i;
|
||||
};
|
||||
|
||||
// retrieve oldest parent of i within the same alternation of and
|
||||
unsigned pi = i;
|
||||
auto [_s, _depth, _f, _p] = todo[i];
|
||||
while (pi != 0) {
|
||||
auto [s, depth, f, p] = todo[pi];
|
||||
if (depth != _depth)
|
||||
break;
|
||||
pi = p;
|
||||
}
|
||||
|
||||
// determine if j and j have common conjunctive parent
|
||||
// for every j in todo.
|
||||
for (unsigned j = 0; j < todo.size(); ++j) {
|
||||
auto [s, depth, f, p] = todo[j];
|
||||
if (i == j || !m_contains_v.is_marked(f))
|
||||
continue;
|
||||
if (is_parent(j, i)) // j is a parent if i
|
||||
continue;
|
||||
if (is_parent(pi, j)) // pi is a parent of j
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,9 @@ namespace euf {
|
|||
bool contains_conjunctively(expr* f, bool sign, expr* e, signed_expressions& conjuncts);
|
||||
bool is_conjunction(bool sign, expr* f) const;
|
||||
|
||||
void collect_nested_equalities(dependent_expr const& f, expr_mark& visited, dep_eq_vector& eqs);
|
||||
void collect_nested_equalities(dependent_expr const& f, expr_mark& visited, dep_eq_vector& eqs);
|
||||
|
||||
bool is_safe_var(expr* x, unsigned i, expr* f, svector<std::tuple<bool,unsigned,expr*,unsigned>> const& todo);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -7,16 +7,14 @@
|
|||
--*/
|
||||
#pragma once
|
||||
namespace nla {
|
||||
class core;
|
||||
class monotone : common {
|
||||
public:
|
||||
monotone(core *core);
|
||||
void monotonicity_lemma();
|
||||
private:
|
||||
void monotonicity_lemma(monic const& m);
|
||||
void monotonicity_lemma_gt(const monic& m);
|
||||
void monotonicity_lemma_lt(const monic& m);
|
||||
// std_vector<rational> get_sorted_key(const monic& rm) const;
|
||||
vector<std::pair<rational, lpvar>> get_sorted_key_with_rvars(const monic& a) const;
|
||||
};
|
||||
class core;
|
||||
class monotone : common {
|
||||
public:
|
||||
monotone(core *core);
|
||||
void monotonicity_lemma();
|
||||
private:
|
||||
void monotonicity_lemma(monic const& m);
|
||||
void monotonicity_lemma_gt(const monic& m);
|
||||
void monotonicity_lemma_lt(const monic& m);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ Revision History:
|
|||
|
||||
void pattern_inference_params::updt_params(params_ref const & _p) {
|
||||
pattern_inference_params_helper p(_p);
|
||||
m_pi_enabled = p.enabled();
|
||||
m_pi_max_multi_patterns = p.max_multi_patterns();
|
||||
m_pi_block_loop_patterns = p.block_loop_patterns();
|
||||
m_pi_decompose_patterns = p.decompose_patterns();
|
||||
|
@ -35,6 +36,7 @@ void pattern_inference_params::updt_params(params_ref const & _p) {
|
|||
#define DISPLAY_PARAM(X) out << #X"=" << X << '\n';
|
||||
|
||||
void pattern_inference_params::display(std::ostream & out) const {
|
||||
DISPLAY_PARAM(m_pi_enabled);
|
||||
DISPLAY_PARAM(m_pi_max_multi_patterns);
|
||||
DISPLAY_PARAM(m_pi_block_loop_patterns);
|
||||
DISPLAY_PARAM(m_pi_decompose_patterns);
|
||||
|
|
|
@ -27,7 +27,8 @@ enum arith_pattern_inference_kind {
|
|||
};
|
||||
|
||||
struct pattern_inference_params {
|
||||
unsigned m_pi_max_multi_patterns;
|
||||
bool m_pi_enabled = true;
|
||||
unsigned m_pi_max_multi_patterns = 1;
|
||||
bool m_pi_block_loop_patterns;
|
||||
bool m_pi_decompose_patterns;
|
||||
arith_pattern_inference_kind m_pi_arith;
|
||||
|
@ -35,13 +36,11 @@ struct pattern_inference_params {
|
|||
unsigned m_pi_arith_weight;
|
||||
unsigned m_pi_non_nested_arith_weight;
|
||||
bool m_pi_pull_quantifiers;
|
||||
int m_pi_nopat_weight;
|
||||
bool m_pi_avoid_skolems;
|
||||
int m_pi_nopat_weight = -1;
|
||||
bool m_pi_avoid_skolems = true;
|
||||
bool m_pi_warnings;
|
||||
|
||||
pattern_inference_params(params_ref const & p = params_ref()):
|
||||
m_pi_nopat_weight(-1),
|
||||
m_pi_avoid_skolems(true) {
|
||||
pattern_inference_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ def_module_params(class_name='pattern_inference_params_helper',
|
|||
('decompose_patterns', BOOL, True, 'allow decomposition of patterns into multipatterns'),
|
||||
('arith', UINT, 1, '0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms'),
|
||||
('use_database', BOOL, False, 'use pattern database'),
|
||||
('enabled', BOOL, True, 'enable a heuristic to infer patterns, when they are not provided'),
|
||||
('arith_weight', UINT, 5, 'default weight for quantifiers where the only available pattern has nested arithmetic terms'),
|
||||
('non_nested_arith_weight', UINT, 10, 'default weight for quantifiers where the only available pattern has non nested arithmetic terms'),
|
||||
('pull_quantifiers', BOOL, True, 'pull nested quantifiers, if no pattern was found'),
|
||||
|
|
|
@ -963,6 +963,7 @@ namespace smt2 {
|
|||
unsigned line = m_scanner.get_line();
|
||||
unsigned pos = m_scanner.get_pos();
|
||||
symbol dt_name = curr_id();
|
||||
check_identifier("unexpected token used as datatype name");
|
||||
next();
|
||||
|
||||
m_dt_name2idx.reset();
|
||||
|
|
|
@ -110,12 +110,13 @@ class simplifier_solver : public solver {
|
|||
expr_ref_vector orig_assumptions(assumptions);
|
||||
m_core_replace.reset();
|
||||
if (qhead < m_fmls.size() || !assumptions.empty()) {
|
||||
TRACE("solver", tout << "qhead " << qhead << "\n");
|
||||
m_preprocess_state.replay(qhead, assumptions);
|
||||
m_preprocess_state.freeze(assumptions);
|
||||
m_preprocess.reduce();
|
||||
if (!m.inc())
|
||||
return;
|
||||
TRACE("solver", tout << "qhead " << qhead << "\n";
|
||||
m_preprocess_state.display(tout));
|
||||
m_preprocess_state.advance_qhead();
|
||||
for (unsigned i = 0; i < assumptions.size(); ++i)
|
||||
m_core_replace.insert(assumptions.get(i), orig_assumptions.get(i));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue