3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-09 20:50:50 +00:00

Merge branch 'master' into polysat

This commit is contained in:
Jakob Rath 2022-09-23 17:14:26 +02:00
commit 1df749ad33
368 changed files with 12363 additions and 6152 deletions

View file

@ -37,8 +37,7 @@ namespace smt {
m_context(ctx) {
}
virtual ~mam() {
}
virtual ~mam() = default;
virtual void add_pattern(quantifier * q, app * mp) = 0;

View file

@ -19,6 +19,7 @@ Revision History:
#include "smt/params/smt_params.h"
#include "smt/params/smt_params_helper.hpp"
#include "util/gparams.h"
#include "params/solver_params.hpp"
void smt_params::updt_local_params(params_ref const & _p) {
smt_params_helper p(_p);
@ -59,6 +60,10 @@ void smt_params::updt_local_params(params_ref const & _p) {
m_dump_benchmarks = false;
m_dump_min_time = 0.5;
m_dump_recheck = false;
solver_params sp(_p);
m_axioms2files = sp.axioms2files();
m_lemmas2console = sp.lemmas2console();
m_instantiations2console = sp.instantiations2console();
}
void smt_params::updt_params(params_ref const & p) {
@ -150,7 +155,8 @@ void smt_params::display(std::ostream & out) const {
DISPLAY_PARAM(m_old_clause_relevancy);
DISPLAY_PARAM(m_inv_clause_decay);
DISPLAY_PARAM(m_smtlib_dump_lemmas);
DISPLAY_PARAM(m_axioms2files);
DISPLAY_PARAM(m_lemmas2console);
DISPLAY_PARAM(m_logic);
DISPLAY_PARAM(m_string_solver);

View file

@ -82,144 +82,146 @@ struct smt_params : public preprocessor_params,
public theory_seq_params,
public theory_pb_params,
public theory_datatype_params {
bool m_display_proof;
bool m_display_dot_proof;
bool m_display_unsat_core;
bool m_check_proof;
bool m_eq_propagation;
bool m_binary_clause_opt;
unsigned m_relevancy_lvl;
bool m_relevancy_lemma;
unsigned m_random_seed;
double m_random_var_freq;
double m_inv_decay;
unsigned m_clause_decay;
initial_activity m_random_initial_activity;
phase_selection m_phase_selection;
unsigned m_phase_caching_on;
unsigned m_phase_caching_off;
bool m_minimize_lemmas;
unsigned m_max_conflicts;
bool m_display_proof = false;
bool m_display_dot_proof = false;
bool m_display_unsat_core = false;
bool m_check_proof = false;
bool m_eq_propagation = true;
bool m_binary_clause_opt = true;
unsigned m_relevancy_lvl = 2;
bool m_relevancy_lemma = false;
unsigned m_random_seed = 0;
double m_random_var_freq = 0.01;
double m_inv_decay = 1.052;
unsigned m_clause_decay = 1;
initial_activity m_random_initial_activity = initial_activity::IA_RANDOM_WHEN_SEARCHING;
phase_selection m_phase_selection = phase_selection::PS_CACHING_CONSERVATIVE;
unsigned m_phase_caching_on = 700;
unsigned m_phase_caching_off = 100;
bool m_minimize_lemmas = true;
unsigned m_max_conflicts = UINT_MAX;
unsigned m_restart_max;
unsigned m_cube_depth;
unsigned m_threads;
unsigned m_threads_max_conflicts;
unsigned m_threads_cube_frequency;
bool m_simplify_clauses;
unsigned m_tick;
bool m_display_features;
bool m_new_core2th_eq;
bool m_ematching;
bool m_induction;
bool m_clause_proof;
unsigned m_cube_depth = 1;
unsigned m_threads = 1;
unsigned m_threads_max_conflicts = UINT_MAX;
unsigned m_threads_cube_frequency = 2;
bool m_simplify_clauses = true;
unsigned m_tick = 1000;
bool m_display_features = false;
bool m_new_core2th_eq = true;
bool m_ematching = true;
bool m_induction = false;
bool m_clause_proof = false;
// -----------------------------------
//
// Case split strategy
//
// -----------------------------------
case_split_strategy m_case_split_strategy;
unsigned m_rel_case_split_order;
bool m_lookahead_diseq;
bool m_theory_case_split;
bool m_theory_aware_branching;
case_split_strategy m_case_split_strategy = case_split_strategy::CS_ACTIVITY_DELAY_NEW;
unsigned m_rel_case_split_order = 0;
bool m_lookahead_diseq = false;
bool m_theory_case_split = false;
bool m_theory_aware_branching = false;
// -----------------------------------
//
// Delay units...
//
// -----------------------------------
bool m_delay_units;
unsigned m_delay_units_threshold;
bool m_delay_units = false;
unsigned m_delay_units_threshold = 32;
// -----------------------------------
//
// Conflict resolution
//
// -----------------------------------
bool m_theory_resolve;
bool m_theory_resolve = false;
// -----------------------------------
//
// Restart
//
// -----------------------------------
restart_strategy m_restart_strategy;
unsigned m_restart_initial;
double m_restart_factor;
bool m_restart_adaptive;
double m_agility_factor;
double m_restart_agility_threshold;
restart_strategy m_restart_strategy = restart_strategy::RS_IN_OUT_GEOMETRIC;
unsigned m_restart_initial = 100;
double m_restart_factor = 1.1;
bool m_restart_adaptive = true;
double m_agility_factor = 0.9999;
double m_restart_agility_threshold = 0.18;
// -----------------------------------
//
// Lemma garbage collection
//
// -----------------------------------
lemma_gc_strategy m_lemma_gc_strategy;
bool m_lemma_gc_half;
unsigned m_recent_lemmas_size;
unsigned m_lemma_gc_initial;
double m_lemma_gc_factor;
unsigned m_new_old_ratio; //!< the ratio of new and old clauses.
unsigned m_new_clause_activity;
unsigned m_old_clause_activity;
unsigned m_new_clause_relevancy; //!< Max. number of unassigned literals to be considered relevant.
unsigned m_old_clause_relevancy; //!< Max. number of unassigned literals to be considered relevant.
double m_inv_clause_decay; //!< clause activity decay
lemma_gc_strategy m_lemma_gc_strategy = lemma_gc_strategy::LGC_FIXED;
bool m_lemma_gc_half = false;
unsigned m_recent_lemmas_size = 100;
unsigned m_lemma_gc_initial = 5000;
double m_lemma_gc_factor = 1.1;
unsigned m_new_old_ratio = 16; //!< the ratio of new and old clauses.
unsigned m_new_clause_activity = 10;
unsigned m_old_clause_activity = 500;
unsigned m_new_clause_relevancy = 45; //!< Max. number of unassigned literals to be considered relevant.
unsigned m_old_clause_relevancy = 6; //!< Max. number of unassigned literals to be considered relevant.
double m_inv_clause_decay = 1; //!< clause activity decay
// -----------------------------------
//
// SMT-LIB (debug) pretty printer
//
// -----------------------------------
bool m_smtlib_dump_lemmas;
symbol m_logic;
bool m_axioms2files = false;
bool m_lemmas2console = false;
bool m_instantiations2console = false;
symbol m_logic = symbol::null;
// -----------------------------------
//
// Statistics for Profiling
//
// -----------------------------------
bool m_profile_res_sub;
bool m_display_bool_var2expr;
bool m_display_ll_bool_var2expr;
bool m_profile_res_sub = false;
bool m_display_bool_var2expr = false;
bool m_display_ll_bool_var2expr = false;
// -----------------------------------
//
// Model generation
//
// -----------------------------------
bool m_model;
bool m_model_on_timeout;
bool m_model_on_final_check;
bool m_model = true;
bool m_model_on_timeout = false;
bool m_model_on_final_check = false;
// -----------------------------------
//
// Progress sampling
//
// -----------------------------------
unsigned m_progress_sampling_freq;
unsigned m_progress_sampling_freq = 0;
// -----------------------------------
//
// Debugging goodies
//
// -----------------------------------
bool m_core_validate;
bool m_core_validate = false;
// -----------------------------------
//
// From front_end_params
//
// -----------------------------------
bool m_preprocess; // temporary hack for disabling all preprocessing..
bool m_user_theory_preprocess_axioms;
bool m_user_theory_persist_axioms;
bool m_at_labels_cex; // only use labels which contains the @ symbol when building multiple counterexamples.
bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples.
bool m_dump_goal_as_smt;
bool m_auto_config;
bool m_preprocess = true; // temporary hack for disabling all preprocessing..
bool m_user_theory_preprocess_axioms = false;
bool m_user_theory_persist_axioms = false;
bool m_at_labels_cex = false; // only use labels which contains the @ symbol when building multiple counterexamples.
bool m_check_at_labels = false; // check that @ labels are inserted to generate unique counter-examples.
bool m_dump_goal_as_smt = false;
bool m_auto_config = true;
// -----------------------------------
//
@ -238,77 +240,6 @@ struct smt_params : public preprocessor_params,
symbol m_string_solver;
smt_params(params_ref const & p = params_ref()):
m_display_proof(false),
m_display_dot_proof(false),
m_display_unsat_core(false),
m_check_proof(false),
m_eq_propagation(true),
m_binary_clause_opt(true),
m_relevancy_lvl(2),
m_relevancy_lemma(false),
m_random_seed(0),
m_random_var_freq(0.01),
m_inv_decay(1.052),
m_clause_decay(1),
m_random_initial_activity(initial_activity::IA_RANDOM_WHEN_SEARCHING),
m_phase_selection(phase_selection::PS_CACHING_CONSERVATIVE),
m_phase_caching_on(700),
m_phase_caching_off(100),
m_minimize_lemmas(true),
m_max_conflicts(UINT_MAX),
m_cube_depth(1),
m_threads(1),
m_threads_max_conflicts(UINT_MAX),
m_threads_cube_frequency(2),
m_simplify_clauses(true),
m_tick(1000),
m_display_features(false),
m_new_core2th_eq(true),
m_ematching(true),
m_induction(false),
m_clause_proof(false),
m_case_split_strategy(case_split_strategy::CS_ACTIVITY_DELAY_NEW),
m_rel_case_split_order(0),
m_lookahead_diseq(false),
m_theory_case_split(false),
m_theory_aware_branching(false),
m_delay_units(false),
m_delay_units_threshold(32),
m_theory_resolve(false),
m_restart_strategy(restart_strategy::RS_IN_OUT_GEOMETRIC),
m_restart_initial(100),
m_restart_factor(1.1),
m_restart_adaptive(true),
m_agility_factor(0.9999),
m_restart_agility_threshold(0.18),
m_lemma_gc_strategy(lemma_gc_strategy::LGC_FIXED),
m_lemma_gc_half(false),
m_recent_lemmas_size(100),
m_lemma_gc_initial(5000),
m_lemma_gc_factor(1.1),
m_new_old_ratio(16),
m_new_clause_activity(10),
m_old_clause_activity(500),
m_new_clause_relevancy(45),
m_old_clause_relevancy(6),
m_inv_clause_decay(1),
m_smtlib_dump_lemmas(false),
m_logic(symbol::null),
m_profile_res_sub(false),
m_display_bool_var2expr(false),
m_display_ll_bool_var2expr(false),
m_model(true),
m_model_on_timeout(false),
m_model_on_final_check(false),
m_progress_sampling_freq(0),
m_core_validate(false),
m_preprocess(true), // temporary hack for disabling all preprocessing..
m_user_theory_preprocess_axioms(false),
m_user_theory_persist_axioms(false),
m_at_labels_cex(false),
m_check_at_labels(false),
m_dump_goal_as_smt(false),
m_auto_config(true),
m_string_solver(symbol("auto")){
updt_local_params(p);
}

View file

@ -48,9 +48,10 @@ def_module_params(module_name='smt',
('bv.reflect', BOOL, True, 'create enode for every bit-vector term'),
('bv.enable_int2bv', BOOL, True, 'enable support for int2bv and bv2int operators'),
('bv.watch_diseq', BOOL, False, 'use watch lists instead of eager axioms for bit-vectors'),
('bv.delay', BOOL, True, 'delay internalize expensive bit-vector operations'),
('bv.delay', BOOL, False, 'delay internalize expensive bit-vector operations'),
('bv.polysat', BOOL, False, 'use polysat bit-vector solver'),
('bv.eq_axioms', BOOL, True, 'enable redundant equality axioms for bit-vectors'),
('bv.size_reduce', BOOL, False, 'turn assertions that set the upper bits of a bit-vector to constants into a substitution that replaces the bit-vector with constant bits. Useful for minimizing circuits as many input bits to circuits are constant'),
('arith.random_initial_value', BOOL, False, 'use random initial values in the simplex-based procedure for linear arithmetic'),
('arith.solver', UINT, 6, 'arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination 4 - utvpi, 5 - infinitary lra, 6 - lra solver'),
('arith.nl', BOOL, True, '(incomplete) nonlinear arithmetic support based on Groebner basis and interval propagation, relevant only if smt.arith.solver=2'),
@ -106,6 +107,8 @@ def_module_params(module_name='smt',
('core.validate', BOOL, False, '[internal] validate unsat core produced by SMT context. This option is intended for debugging'),
('seq.split_w_len', BOOL, True, 'enable splitting guided by length constraints'),
('seq.validate', BOOL, False, 'enable self-validation of theory axioms created by seq theory'),
('seq.max_unfolding', UINT, 1000000000, 'maximal unfolding depth for checking string equations and regular expressions'),
('seq.min_unfolding', UINT, 1, 'initial bound for strings whose lengths are bounded by iterative deepening. Set this to a higher value if there are only models with larger string lengths'),
('str.strong_arrangements', BOOL, True, 'assert equivalences instead of implications when generating string arrangement axioms'),
('str.aggressive_length_testing', BOOL, False, 'prioritize testing concrete length values over generating more options'),
('str.aggressive_value_testing', BOOL, False, 'prioritize testing concrete string constant values over generating more options'),

View file

@ -34,7 +34,6 @@ void theory_arith_params::updt_params(params_ref const & _p) {
m_arith_int_eq_branching = p.arith_int_eq_branch();
m_arith_ignore_int = p.arith_ignore_int();
m_arith_bound_prop = static_cast<bound_prop_mode>(p.arith_propagation_mode());
m_arith_dump_lemmas = p.arith_dump_lemmas();
m_arith_eager_eq_axioms = p.arith_eager_eq_axioms();
m_arith_auto_config_simplex = p.arith_auto_config_simplex();
@ -67,7 +66,6 @@ void theory_arith_params::display(std::ostream & out) const {
DISPLAY_PARAM(m_arith_adaptive);
DISPLAY_PARAM(m_arith_adaptive_assertion_threshold);
DISPLAY_PARAM(m_arith_adaptive_propagation_threshold);
DISPLAY_PARAM(m_arith_dump_lemmas);
DISPLAY_PARAM(m_arith_eager_eq_axioms);
DISPLAY_PARAM(m_arith_branch_cut_ratio);
DISPLAY_PARAM(m_arith_int_eq_branching);

View file

@ -72,7 +72,6 @@ struct theory_arith_params {
bool m_arith_adaptive = false;
double m_arith_adaptive_assertion_threshold = 0.2;
double m_arith_adaptive_propagation_threshold = 0.4;
bool m_arith_dump_lemmas = false;
bool m_arith_eager_eq_axioms = true;
unsigned m_arith_branch_cut_ratio = 2;
bool m_arith_int_eq_branching = false;

View file

@ -29,6 +29,7 @@ void theory_bv_params::updt_params(params_ref const & _p) {
m_bv_delay = p.bv_delay();
m_bv_polysat = p.bv_polysat();
m_bv_eq_axioms = p.bv_eq_axioms();
m_bv_size_reduce = p.bv_size_reduce();
}
#define DISPLAY_PARAM(X) out << #X"=" << X << std::endl;
@ -44,4 +45,5 @@ void theory_bv_params::display(std::ostream & out) const {
DISPLAY_PARAM(m_bv_enable_int2bv2int);
DISPLAY_PARAM(m_bv_delay);
DISPLAY_PARAM(m_bv_polysat);
DISPLAY_PARAM(m_bv_size_reduce);
}

View file

@ -37,6 +37,7 @@ struct theory_bv_params {
bool m_bv_watch_diseq = false;
bool m_bv_delay = true;
bool m_bv_polysat = false;
bool m_bv_size_reduce = false;
theory_bv_params(params_ref const & p = params_ref()) {
updt_params(p);
}

View file

@ -21,4 +21,6 @@ void theory_seq_params::updt_params(params_ref const & _p) {
smt_params_helper p(_p);
m_split_w_len = p.seq_split_w_len();
m_seq_validate = p.seq_validate();
m_seq_max_unfolding = p.seq_max_unfolding();
m_seq_min_unfolding = p.seq_min_unfolding();
}

View file

@ -24,6 +24,8 @@ struct theory_seq_params {
*/
bool m_split_w_len = false;
bool m_seq_validate = false;
unsigned m_seq_max_unfolding = UINT_MAX/4;
unsigned m_seq_min_unfolding = 1;
theory_seq_params(params_ref const & p = params_ref()) {
updt_params(p);

View file

@ -23,6 +23,7 @@ Revision History:
#include "ast/rewriter/var_subst.h"
#include "smt/smt_context.h"
#include "smt/qi_queue.h"
#include <iostream>
namespace smt {
@ -228,15 +229,12 @@ namespace smt {
TRACE("qi_queue", tout << "new instance:\n" << mk_pp(instance, m) << "\n";);
TRACE("qi_queue_instance", tout << "new instance:\n" << mk_pp(instance, m) << "\n";);
expr_ref s_instance(m);
proof_ref pr(m);
m_context.get_rewriter()(instance, s_instance, pr);
TRACE("qi_queue_bug", tout << "new instance after simplification:\n" << s_instance << "\n";);
if (m.is_true(s_instance)) {
TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m););
STRACE("instance", tout << "Instance reduced to true\n";);
stat -> inc_num_instances_simplify_true();
if (m.has_trace_stream()) {
@ -250,9 +248,11 @@ namespace smt {
std::cout << "instantiate\n";
enode_vector _bindings(num_bindings, bindings);
for (auto * b : _bindings)
std::cout << enode_pp(b, m_context) << " ";
std::cout << mk_pp(b->get_expr(), m) << " ";
std::cout << "\n";
std::cout << mk_pp(q, m) << "\n";
std::cout << "instance\n";
std::cout << instance << "\n";
#endif
TRACE("qi_queue", tout << "simplified instance:\n" << s_instance << "\n";);

View file

@ -86,7 +86,7 @@ void seq_axioms::add_clause(expr_ref_vector const& clause) {
justification* js =
ctx().mk_justification(
ext_theory_eq_propagation_justification(
th.get_id(), ctx().get_region(), 0, nullptr, 0, nullptr, n1, n2));
th.get_id(), ctx(), 0, nullptr, 0, nullptr, n1, n2));
ctx().assign_eq(n1, n2, eq_justification(js));
return;
}

View file

@ -45,7 +45,7 @@ namespace smt {
virtual void pop_scope(unsigned num_scopes) = 0;
virtual void next_case_split(bool_var & next, lbool & phase) = 0;
virtual void display(std::ostream & out) = 0;
virtual ~case_split_queue() {}
virtual ~case_split_queue() = default;
// theory-aware branching hint
virtual void add_theory_aware_branching_info(bool_var v, double priority, lbool phase) {}

View file

@ -33,7 +33,7 @@ namespace smt {
*/
class clause_del_eh {
public:
virtual ~clause_del_eh() {}
virtual ~clause_del_eh() = default;
virtual void operator()(ast_manager & m, clause * cls) = 0;
};

View file

@ -80,7 +80,8 @@ namespace smt {
m_unsat_core(m),
m_mk_bool_var_trail(*this),
m_mk_enode_trail(*this),
m_mk_lambda_trail(*this) {
m_mk_lambda_trail(*this),
m_lemma_visitor(m) {
SASSERT(m_scope_lvl == 0);
SASSERT(m_base_lvl == 0);
@ -2560,7 +2561,7 @@ namespace smt {
justification * js = cls.get_justification();
justification * new_js = nullptr;
if (js->in_region())
new_js = mk_justification(unit_resolution_justification(m_region,
new_js = mk_justification(unit_resolution_justification(*this,
js,
simp_lits.size(),
simp_lits.data()));
@ -2618,7 +2619,7 @@ namespace smt {
if (!cls_js || cls_js->in_region()) {
// If cls_js is 0 or is allocated in a region, then
// we can allocate the new justification in a region too.
js = mk_justification(unit_resolution_justification(m_region,
js = mk_justification(unit_resolution_justification(*this,
cls_js,
simp_lits.size(),
simp_lits.data()));
@ -3197,13 +3198,22 @@ namespace smt {
void context::internalize_assertions() {
if (get_cancel_flag()) return;
if (m_internalizing_assertions) return;
flet<bool> _internalizing(m_internalizing_assertions, true);
TRACE("internalize_assertions", tout << "internalize_assertions()...\n";);
timeit tt(get_verbosity_level() >= 100, "smt.preprocessing");
reduce_assertions();
if (get_cancel_flag()) return;
if (!m_asserted_formulas.inconsistent()) {
unsigned sz = m_asserted_formulas.get_num_formulas();
unsigned qhead = m_asserted_formulas.get_qhead();
unsigned qhead = 0;
do {
reduce_assertions();
if (get_cancel_flag())
return;
if (m_asserted_formulas.inconsistent()) {
if (!inconsistent())
asserted_inconsistent();
break;
}
qhead = m_asserted_formulas.get_qhead();
unsigned sz = m_asserted_formulas.get_num_formulas();
while (qhead < sz) {
if (get_cancel_flag()) {
m_asserted_formulas.commit(qhead);
@ -3213,13 +3223,12 @@ namespace smt {
proof * pr = m_asserted_formulas.get_formula_proof(qhead);
SASSERT(!pr || f == m.get_fact(pr));
internalize_assertion(f, pr, 0);
qhead++;
++qhead;
}
m_asserted_formulas.commit();
}
if (m_asserted_formulas.inconsistent() && !inconsistent()) {
asserted_inconsistent();
}
while (qhead < m_asserted_formulas.get_num_formulas());
TRACE("internalize_assertions", tout << "after internalize_assertions()...\n";
tout << "inconsistent: " << inconsistent() << "\n";);
TRACE("after_internalize_assertions", display(tout););

View file

@ -107,11 +107,12 @@ namespace smt {
ptr_vector<justification> m_justifications;
unsigned m_final_check_idx; // circular counter used for implementing fairness
unsigned m_final_check_idx = 0; // circular counter used for implementing fairness
bool m_is_auxiliary { false }; // used to prevent unwanted information from being logged.
class parallel* m_par { nullptr };
unsigned m_par_index { 0 };
bool m_is_auxiliary = false; // used to prevent unwanted information from being logged.
class parallel* m_par = nullptr;
unsigned m_par_index = 0;
bool m_internalizing_assertions = false;
// -----------------------------------
//
@ -777,8 +778,6 @@ namespace smt {
bool has_lambda();
bool is_beta_redex(enode* p, enode* n) const;
void internalize_lambda(quantifier * q);
void internalize_formula_core(app * n, bool gate_ctx);
@ -892,6 +891,10 @@ namespace smt {
void remove_lit_occs(clause const& cls, unsigned num_bool_vars);
void add_lit_occs(clause const& cls);
ast_pp_util m_lemma_visitor;
void dump_lemma(unsigned n, literal const* lits);
void dump_axiom(unsigned n, literal const* lits);
public:
void ensure_internalized(expr* e);
@ -1031,6 +1034,8 @@ namespace smt {
bool is_shared(enode * n) const;
bool is_beta_redex(enode* p, enode* n) const;
void assign_eq(enode * lhs, enode * rhs, eq_justification const & js) {
push_eq(lhs, rhs, js);
}

View file

@ -766,11 +766,11 @@ namespace smt {
for (; p2 + 2 < str.size(); ++p2) l2 << " ";
l1 << ")\n";
l2 << ")\n";
IF_VERBOSE(1, verbose_stream() << l1.str() << l2.str());
IF_VERBOSE(2, verbose_stream() << l1.str() << l2.str());
m_last_positions.reset();
m_last_positions.append(offsets);
}
IF_VERBOSE(1, verbose_stream() << str);
IF_VERBOSE(2, verbose_stream() << str);
}
};

View file

@ -65,7 +65,7 @@ namespace smt {
public:
for_each_relevant_expr(context & ctx);
virtual ~for_each_relevant_expr() {}
virtual ~for_each_relevant_expr() = default;
/**
\brief Visit the relevant sub-expressions of n.
That is, only subexpressions m of n, such that m_context.is_relevant(m).

View file

@ -24,6 +24,8 @@ Revision History:
#include "smt/smt_model_finder.h"
#include "ast/for_each_expr.h"
#include <iostream>
namespace smt {
/**
@ -613,11 +615,15 @@ namespace smt {
bool context::has_lambda() {
for (auto const & [n, q] : m_lambdas) {
if (n->get_class_size() != 1)
if (n->get_class_size() != 1) {
TRACE("context", tout << "class size " << n->get_class_size() << " " << enode_pp(n, *this) << "\n");
return true;
}
for (enode* p : enode::parents(n))
if (!is_beta_redex(p, n))
if (!is_beta_redex(p, n)) {
TRACE("context", tout << "not a beta redex " << enode_pp(p, *this) << "\n");
return true;
}
}
return false;
}
@ -1372,8 +1378,10 @@ namespace smt {
TRACE("mk_clause", display_literals_verbose(tout << "creating clause: " << literal_vector(num_lits, lits) << "\n", num_lits, lits) << "\n";);
m_clause_proof.add(num_lits, lits, k, j);
switch (k) {
case CLS_AUX:
case CLS_TH_AXIOM: {
case CLS_TH_AXIOM:
dump_axiom(num_lits, lits);
Z3_fallthrough;
case CLS_AUX: {
literal_buffer simp_lits;
if (!simplify_aux_clause_literals(num_lits, lits, simp_lits)) {
if (j && !j->in_region()) {
@ -1384,11 +1392,12 @@ namespace smt {
}
DEBUG_CODE(for (literal lit : simp_lits) SASSERT(get_assignment(lit) == l_true););
if (!simp_lits.empty()) {
j = mk_justification(unit_resolution_justification(m_region, j, simp_lits.size(), simp_lits.data()));
j = mk_justification(unit_resolution_justification(*this, j, simp_lits.size(), simp_lits.data()));
}
break;
}
case CLS_TH_LEMMA:
case CLS_TH_LEMMA:
dump_lemma(num_lits, lits);
if (!simplify_aux_lemma_literals(num_lits, lits)) {
if (j && !j->in_region()) {
j->del_eh(m);
@ -1398,7 +1407,10 @@ namespace smt {
}
// simplify_aux_lemma_literals does not delete literals assigned to false, so
// it is not necessary to create a unit_resolution_justification
break;
break;
case CLS_LEARNED:
dump_lemma(num_lits, lits);
break;
default:
break;
}
@ -1503,6 +1515,30 @@ namespace smt {
}}
}
void context::dump_axiom(unsigned n, literal const* lits) {
if (m_fparams.m_axioms2files) {
literal_buffer tmp;
neg_literals(n, lits, tmp);
SASSERT(tmp.size() == n);
display_lemma_as_smt_problem(tmp.size(), tmp.data(), false_literal, m_fparams.m_logic);
}
}
void context::dump_lemma(unsigned n, literal const* lits) {
if (m_fparams.m_lemmas2console) {
expr_ref fml(m);
expr_ref_vector fmls(m);
for (unsigned i = 0; i < n; ++i)
fmls.push_back(literal2expr(lits[i]));
fml = mk_or(fmls);
m_lemma_visitor.collect(fml);
m_lemma_visitor.display_skolem_decls(std::cout);
m_lemma_visitor.display_assert(std::cout, fml.get(), true);
}
}
void context::mk_clause(literal l1, literal l2, justification * j) {
literal ls[2] = { l1, l2 };
mk_clause(2, ls, j);
@ -1518,13 +1554,7 @@ namespace smt {
TRACE("mk_th_axiom", display_literals_verbose(tout, num_lits, lits) << "\n";);
if (m.proofs_enabled()) {
js = mk_justification(theory_axiom_justification(tid, m_region, num_lits, lits, num_params, params));
}
if (m_fparams.m_smtlib_dump_lemmas) {
literal_buffer tmp;
neg_literals(num_lits, lits, tmp);
SASSERT(tmp.size() == num_lits);
display_lemma_as_smt_problem(tmp.size(), tmp.data(), false_literal, m_fparams.m_logic);
js = mk_justification(theory_axiom_justification(tid, *this, num_lits, lits, num_params, params));
}
mk_clause(num_lits, lits, js, k);
}

View file

@ -40,13 +40,14 @@ namespace smt {
return m_proof;
}
unit_resolution_justification::unit_resolution_justification(region & r,
unit_resolution_justification::unit_resolution_justification(context& ctx,
justification * js,
unsigned num_lits,
literal const * lits):
m_antecedent(js),
m_num_literals(num_lits) {
SASSERT(!js || js->in_region());
auto& r = ctx.get_region();
m_literals = new (r) literal[num_lits];
memcpy(m_literals, lits, sizeof(literal) * num_lits);
TRACE("unit_resolution_justification_bug", tout << literal_vector(num_lits, lits) << "\n";);
@ -101,6 +102,7 @@ namespace smt {
return m.mk_unit_resolution(prs.size(), prs.data());
}
void eq_conflict_justification::get_antecedents(conflict_resolution & cr) {
SASSERT(m_node1->get_root()->is_interpreted());
SASSERT(m_node2->get_root()->is_interpreted());
@ -235,8 +237,9 @@ namespace smt {
return nullptr;
}
simple_justification::simple_justification(region & r, unsigned num_lits, literal const * lits):
simple_justification::simple_justification(context& ctx, unsigned num_lits, literal const * lits):
m_num_literals(num_lits) {
region& r = ctx.get_region();
if (num_lits != 0) {
m_literals = new (r) literal[num_lits];
memcpy(m_literals, lits, sizeof(literal) * num_lits);
@ -291,6 +294,12 @@ namespace smt {
return m.mk_th_lemma(m_th_id, fact, prs.size(), prs.data(), m_params.size(), m_params.data());
}
void theory_propagation_justification::log(context& ctx) {
if (ctx.get_fparams().m_axioms2files)
ctx.display_lemma_as_smt_problem(m_num_literals, m_literals, m_consequent);
}
proof * theory_conflict_justification::mk_proof(conflict_resolution & cr) {
ptr_buffer<proof> prs;
if (!antecedent2proof(cr, prs))
@ -299,9 +308,16 @@ namespace smt {
return m.mk_th_lemma(m_th_id, m.mk_false(), prs.size(), prs.data(), m_params.size(), m_params.data());
}
ext_simple_justification::ext_simple_justification(region & r, unsigned num_lits, literal const * lits, unsigned num_eqs, enode_pair const * eqs):
simple_justification(r, num_lits, lits),
void theory_conflict_justification::log(context& ctx) {
if (ctx.get_fparams().m_axioms2files)
ctx.display_lemma_as_smt_problem(m_num_literals, m_literals);
}
ext_simple_justification::ext_simple_justification(context& ctx, unsigned num_lits, literal const * lits, unsigned num_eqs, enode_pair const * eqs):
simple_justification(ctx, num_lits, lits),
m_num_eqs(num_eqs) {
region& r = ctx.get_region();
m_eqs = new (r) enode_pair[num_eqs];
std::uninitialized_copy(eqs, eqs + num_eqs, m_eqs);
DEBUG_CODE({
@ -342,6 +358,13 @@ namespace smt {
ctx.literal2expr(m_consequent, fact);
return m.mk_th_lemma(m_th_id, fact, prs.size(), prs.data(), m_params.size(), m_params.data());
}
void ext_theory_propagation_justification::log(context& ctx) {
if (ctx.get_fparams().m_axioms2files)
ctx.display_lemma_as_smt_problem(m_num_literals, m_literals, m_num_eqs, m_eqs, m_consequent);
}
proof * ext_theory_conflict_justification::mk_proof(conflict_resolution & cr) {
ptr_buffer<proof> prs;
@ -351,6 +374,12 @@ namespace smt {
return m.mk_th_lemma(m_th_id, m.mk_false(), prs.size(), prs.data(), m_params.size(), m_params.data());
}
void ext_theory_conflict_justification::log(context& ctx) {
if (ctx.get_fparams().m_axioms2files)
ctx.display_lemma_as_smt_problem(m_num_literals, m_literals);
}
proof * ext_theory_eq_propagation_justification::mk_proof(conflict_resolution & cr) {
ptr_buffer<proof> prs;
if (!antecedent2proof(cr, prs))
@ -361,6 +390,9 @@ namespace smt {
return m.mk_th_lemma(m_th_id, fact, prs.size(), prs.data(), m_params.size(), m_params.data());
}
void ext_theory_eq_propagation_justification::log(context& ctx) {
}
theory_lemma_justification::theory_lemma_justification(family_id fid, context & ctx, unsigned num_lits, literal const * lits,
unsigned num_params, parameter* params):

View file

@ -49,7 +49,7 @@ namespace smt {
unsigned m_in_region:1; // true if the object was allocated in a region.
public:
justification(bool in_region = true):m_mark(false), m_in_region(in_region) {}
virtual ~justification() {}
virtual ~justification() = default;
/**
\brief This method should return true if the method del_eh needs to be invoked
@ -95,6 +95,7 @@ namespace smt {
virtual char const * get_name() const { return "unknown"; }
virtual void display_debug_info(conflict_resolution & cr, std::ostream & out) { /* do nothing */ }
};
class justification_proof_wrapper : public justification {
@ -118,7 +119,7 @@ namespace smt {
unsigned m_num_literals;
literal * m_literals;
public:
unit_resolution_justification(region & r, justification * js, unsigned num_lits, literal const * lits);
unit_resolution_justification(context& ctx, justification * js, unsigned num_lits, literal const * lits);
unit_resolution_justification(justification * js, unsigned num_lits, literal const * lits);
@ -137,6 +138,7 @@ namespace smt {
proof * mk_proof(conflict_resolution & cr) override;
char const * get_name() const override { return "unit-resolution"; }
};
class eq_conflict_justification : public justification {
@ -218,7 +220,7 @@ namespace smt {
bool antecedent2proof(conflict_resolution & cr, ptr_buffer<proof> & result);
public:
simple_justification(region & r, unsigned num_lits, literal const * lits);
simple_justification(context& ctx, unsigned num_lits, literal const * lits);
void get_antecedents(conflict_resolution & cr) override;
@ -234,10 +236,10 @@ namespace smt {
vector<parameter> m_params;
public:
simple_theory_justification(
family_id fid, region & r,
family_id fid, context& ctx,
unsigned num_lits, literal const * lits,
unsigned num_params, parameter* params):
simple_justification(r, num_lits, lits),
simple_justification(ctx, num_lits, lits),
m_th_id(fid), m_params(num_params, params) {}
bool has_del_eh() const override { return !m_params.empty(); }
@ -251,10 +253,10 @@ namespace smt {
class theory_axiom_justification : public simple_theory_justification {
public:
theory_axiom_justification(family_id fid, region & r,
theory_axiom_justification(family_id fid, context& ctx,
unsigned num_lits, literal const * lits,
unsigned num_params = 0, parameter* params = nullptr):
simple_theory_justification(fid, r, num_lits, lits, num_params, params) {}
simple_theory_justification(fid, ctx, num_lits, lits, num_params, params) {}
void get_antecedents(conflict_resolution & cr) override {}
@ -265,10 +267,11 @@ namespace smt {
class theory_propagation_justification : public simple_theory_justification {
literal m_consequent;
void log(context& ctx);
public:
theory_propagation_justification(family_id fid, region & r, unsigned num_lits, literal const * lits, literal consequent,
theory_propagation_justification(family_id fid, context& ctx, unsigned num_lits, literal const * lits, literal consequent,
unsigned num_params = 0, parameter* params = nullptr):
simple_theory_justification(fid, r, num_lits, lits, num_params, params), m_consequent(consequent) {}
simple_theory_justification(fid, ctx, num_lits, lits, num_params, params), m_consequent(consequent) { log(ctx); }
proof * mk_proof(conflict_resolution & cr) override;
@ -278,10 +281,11 @@ namespace smt {
};
class theory_conflict_justification : public simple_theory_justification {
void log(context& ctx);
public:
theory_conflict_justification(family_id fid, region & r, unsigned num_lits, literal const * lits,
theory_conflict_justification(family_id fid, context& ctx, unsigned num_lits, literal const * lits,
unsigned num_params = 0, parameter* params = nullptr):
simple_theory_justification(fid, r, num_lits, lits, num_params, params) {}
simple_theory_justification(fid, ctx, num_lits, lits, num_params, params) { log(ctx); }
proof * mk_proof(conflict_resolution & cr) override;
@ -299,7 +303,7 @@ namespace smt {
bool antecedent2proof(conflict_resolution & cr, ptr_buffer<proof> & result);
public:
ext_simple_justification(region & r, unsigned num_lits, literal const * lits,
ext_simple_justification(context& ctx, unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs);
void get_antecedents(conflict_resolution & cr) override;
@ -318,10 +322,10 @@ namespace smt {
vector<parameter> m_params;
public:
ext_theory_simple_justification(family_id fid, region & r, unsigned num_lits, literal const * lits,
ext_theory_simple_justification(family_id fid, context& ctx, unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs,
unsigned num_params = 0, parameter* params = nullptr):
ext_simple_justification(r, num_lits, lits, num_eqs, eqs), m_th_id(fid), m_params(num_params, params) {}
ext_simple_justification(ctx, num_lits, lits, num_eqs, eqs), m_th_id(fid), m_params(num_params, params) {}
bool has_del_eh() const override { return !m_params.empty(); }
@ -332,26 +336,33 @@ namespace smt {
class ext_theory_propagation_justification : public ext_theory_simple_justification {
literal m_consequent;
void log(context& ctx);
public:
ext_theory_propagation_justification(family_id fid, region & r,
ext_theory_propagation_justification(family_id fid, context & ctx,
unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs,
literal consequent,
unsigned num_params = 0, parameter* params = nullptr):
ext_theory_simple_justification(fid, r, num_lits, lits, num_eqs, eqs, num_params, params),
m_consequent(consequent) {}
ext_theory_simple_justification(fid, ctx, num_lits, lits, num_eqs, eqs, num_params, params),
m_consequent(consequent) {
log(ctx);
}
proof * mk_proof(conflict_resolution & cr) override;
char const * get_name() const override { return "ext-theory-propagation"; }
};
class ext_theory_conflict_justification : public ext_theory_simple_justification {
void log(context& ctx);
public:
ext_theory_conflict_justification(family_id fid, region & r, unsigned num_lits, literal const * lits,
ext_theory_conflict_justification(family_id fid, context& ctx, unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs,
unsigned num_params = 0, parameter* params = nullptr):
ext_theory_simple_justification(fid, r, num_lits, lits, num_eqs, eqs, num_params, params) {}
ext_theory_simple_justification(fid, ctx, num_lits, lits, num_eqs, eqs, num_params, params) {
log(ctx);
}
proof * mk_proof(conflict_resolution & cr) override;
@ -361,19 +372,20 @@ namespace smt {
class ext_theory_eq_propagation_justification : public ext_theory_simple_justification {
enode * m_lhs;
enode * m_rhs;
void log(context& ctx);
public:
ext_theory_eq_propagation_justification(
family_id fid, region & r,
family_id fid, context& ctx,
unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs,
enode * lhs, enode * rhs,
unsigned num_params = 0, parameter* params = nullptr):
ext_theory_simple_justification(fid, r, num_lits, lits, num_eqs, eqs, num_params, params), m_lhs(lhs), m_rhs(rhs) {}
ext_theory_simple_justification(fid, ctx, num_lits, lits, num_eqs, eqs, num_params, params), m_lhs(lhs), m_rhs(rhs) { log(ctx); }
ext_theory_eq_propagation_justification(
family_id fid, region & r,
family_id fid, context& ctx,
enode * lhs, enode * rhs):
ext_theory_simple_justification(fid, r, 0, nullptr, 0, nullptr, 0, nullptr), m_lhs(lhs), m_rhs(rhs) {}
ext_theory_simple_justification(fid, ctx, 0, nullptr, 0, nullptr, 0, nullptr), m_lhs(lhs), m_rhs(rhs) { log(ctx); }
proof * mk_proof(conflict_resolution & cr) override;

View file

@ -218,7 +218,7 @@ namespace smt {
TRACE("model_checker", tout << "Got some value " << sk_value << "\n";);
if (use_inv) {
unsigned sk_term_gen = 0;
unsigned sk_term_gen = 0;
expr * sk_term = m_model_finder.get_inv(q, i, sk_value, sk_term_gen);
if (sk_term != nullptr) {
TRACE("model_checker", tout << "Found inverse " << mk_pp(sk_term, m) << "\n";);
@ -233,21 +233,30 @@ namespace smt {
}
else {
expr * sk_term = get_term_from_ctx(sk_value);
func_decl * f = nullptr;
if (sk_term != nullptr) {
TRACE("model_checker", tout << "sk term " << mk_pp(sk_term, m) << "\n");
sk_value = sk_term;
}
// last ditch: am I an array?
else if (false && autil.is_as_array(sk_value, f) && cex->get_func_interp(f) && cex->get_func_interp(f)->get_array_interp(f)) {
sk_value = cex->get_func_interp(f)->get_array_interp(f);
}
}
if (contains_model_value(sk_value)) {
TRACE("model_checker", tout << "type compatible term " << mk_pp(sk_value, m) << "\n");
sk_value = get_type_compatible_term(sk_value);
}
func_decl * f = nullptr;
if (autil.is_as_array(sk_value, f) && cex->get_func_interp(f) && cex->get_func_interp(f)->get_interp()) {
expr_ref body(cex->get_func_interp(f)->get_interp(), m);
if (contains_model_value(body))
return false;
ptr_vector<sort> sorts(f->get_arity(), f->get_domain());
svector<symbol> names;
for (unsigned i = 0; i < f->get_arity(); ++i) {
for (unsigned i = 0; i < f->get_arity(); ++i)
names.push_back(symbol(i));
}
defined_names dn(m);
body = replace_value_from_ctx(body);
body = m.mk_lambda(sorts.size(), sorts.data(), names.data(), body);
@ -395,12 +404,14 @@ namespace smt {
m_fparams = alloc(smt_params, m_context->get_fparams());
m_fparams->m_relevancy_lvl = 0; // no relevancy since the model checking problems are quantifier free
m_fparams->m_case_split_strategy = CS_ACTIVITY; // avoid warning messages about smt.case_split >= 3.
m_fparams->m_arith_dump_lemmas = false;
m_fparams->m_axioms2files = false;
m_fparams->m_lemmas2console = false;
}
if (!m_aux_context) {
symbol logic;
params_ref p;
p.set_bool("arith.dump_lemmas", false);
p.set_bool("solver.axioms2files", false);
p.set_bool("solver.lemmas2console", false);
m_aux_context = m_context->mk_fresh(&logic, m_fparams.get(), p);
}
}
@ -563,16 +574,16 @@ namespace smt {
for (unsigned i = 0; i < n; ++i) {
proof* pr = nullptr;
expr* arg = args[i];
if (m.proofs_enabled()) {
if (m.proofs_enabled())
pr = m.mk_def_intro(arg);
}
m_context->internalize_assertion(arg, pr, gen);
}
}
TRACE("model_checker_bug_detail", tout << "instantiating... q:\n" << mk_pp(q, m) << "\n";
tout << "inconsistent: " << m_context->inconsistent() << "\n";
tout << "bindings:\n" << expr_ref_vector(m, num_decls, m_pinned_exprs.data() + offset) << "\n";);
tout << "bindings:\n" << expr_ref_vector(m, num_decls, m_pinned_exprs.data() + offset) << "\n";
tout << "def " << mk_pp(inst.m_def, m) << "\n";);
m_context->add_instance(q, nullptr, num_decls, bindings.data(), inst.m_def, gen, gen, gen, dummy);
TRACE("model_checker_bug_detail", tout << "after instantiating, inconsistent: " << m_context->inconsistent() << "\n";);
}

View file

@ -1157,7 +1157,7 @@ namespace smt {
ast_manager& m;
public:
qinfo(ast_manager& m) :m(m) {}
virtual ~qinfo() {}
virtual ~qinfo() = default;
virtual char const* get_kind() const = 0;
virtual bool is_equal(qinfo const* qi) const = 0;
virtual void display(std::ostream& out) const { out << "[" << get_kind() << "]"; }

View file

@ -136,7 +136,7 @@ namespace smt {
*/
class model_value_proc {
public:
virtual ~model_value_proc() {}
virtual ~model_value_proc() = default;
/**
\brief Fill result with the dependencies of this functor.
That is, to invoke mk_value, the dependencies in result must be constructed.

View file

@ -106,7 +106,7 @@ namespace smt {
class quantifier_manager_plugin {
public:
virtual ~quantifier_manager_plugin() {}
virtual ~quantifier_manager_plugin() = default;
virtual void set_manager(quantifier_manager & qm) = 0;

View file

@ -29,7 +29,7 @@ namespace smt {
void mark_as_relevant(relevancy_propagator & rp, expr * n);
void mark_args_as_relevant(relevancy_propagator & rp, app * n);
public:
virtual ~relevancy_eh() {}
virtual ~relevancy_eh() = default;
/**
\brief This method is invoked when n is marked as relevant.
*/
@ -87,7 +87,7 @@ namespace smt {
context & m_context;
public:
relevancy_propagator(context & ctx);
virtual ~relevancy_propagator() {}
virtual ~relevancy_propagator() = default;
context & get_context() { return m_context; }

View file

@ -294,7 +294,7 @@ namespace smt {
m_bound_kind(k),
m_atom(a) {
}
virtual ~bound() {}
virtual ~bound() = default;
theory_var get_var() const { return m_var; }
bound_kind get_bound_kind() const { return static_cast<bound_kind>(m_bound_kind); }
bool is_atom() const { return m_atom; }
@ -544,9 +544,6 @@ namespace smt {
unsigned small_lemma_size() const { return m_params.m_arith_small_lemma_size; }
bool relax_bounds() const { return m_params.m_arith_stronger_lemmas; }
bool skip_big_coeffs() const { return m_params.m_arith_skip_rows_with_big_coeffs; }
bool dump_lemmas() const { return m_params.m_arith_dump_lemmas; }
void dump_lemmas(literal l, antecedents const& ante);
void dump_lemmas(literal l, derived_bound const& ante);
bool process_atoms() const;
unsigned get_num_conflicts() const { return m_num_conflicts; }
var_kind get_var_kind(theory_var v) const { return m_data[v].kind(); }

View file

@ -563,7 +563,7 @@ namespace smt {
if (!m_util.is_zero(divisor)) {
// if divisor is zero, then idiv and mod are uninterpreted functions.
expr_ref div(m), mod(m), zero(m), abs_divisor(m), one(m);
expr_ref eqz(m), eq(m), lower(m), upper(m), qr(m);
expr_ref eqz(m), eq(m), lower(m), upper(m), qr(m), qr1(m), le(m), ge(m);
div = m_util.mk_idiv(dividend, divisor);
mod = m_util.mk_mod(dividend, divisor);
zero = m_util.mk_int(0);
@ -584,9 +584,24 @@ namespace smt {
mk_axiom(eqz, eq, false);
mk_axiom(eqz, lower, false);
mk_axiom(eqz, upper, !m_util.is_numeral(abs_divisor));
rational k;
m_arith_eq_adapter.mk_axioms(ensure_enode(qr), ensure_enode(mod));
m_arith_eq_adapter.mk_axioms(ensure_enode(qr), ensure_enode(dividend));
// non-linear divisors/mod have to be flattened for the non-linear solver to understand the terms.
// to ensure this use the rewriter. This is a hack required to fix a latent bug that affects the
// legacy arithmetic solver broadly. It is not something that the newer arithmetic solver suffers from.
qr1 = qr;
s(qr1);
if (qr != qr1) {
expr_ref eq(m.mk_eq(qr, qr1), m);
ctx.internalize(eq, false);
literal qeq = ctx.get_literal(eq);
ctx.mark_as_relevant(qeq);
ctx.mk_th_axiom(get_id(), 1, &qeq);
m_arith_eq_adapter.mk_axioms(ensure_enode(qr), ensure_enode(qr1));
}
if (m_util.is_zero(dividend)) {
mk_axiom(eqz, m.mk_eq(div, zero));
@ -1029,13 +1044,14 @@ namespace smt {
inf_numeral const & k1(a1->get_k());
atom_kind kind1 = a1->get_atom_kind();
TRACE("mk_bound_axioms", display_atom(tout << "making bound axioms for " << a1 << " ", a1, true); tout << "\n";);
typename atoms::iterator it = occs.begin();
typename atoms::iterator end = occs.end();
typename atoms::iterator lo_inf = end, lo_sup = end;
typename atoms::iterator hi_inf = end, hi_sup = end;
for (; it != end; ++it) {
atom * a2 = *it;
atom* a2 = *it;
inf_numeral const & k2(a2->get_k());
atom_kind kind2 = a2->get_atom_kind();
TRACE("mk_bound_axioms", display_atom(tout << "compare " << a2 << " ", a2, true); tout << "\n";);
@ -2978,23 +2994,7 @@ namespace smt {
}
}
template<typename Ext>
void theory_arith<Ext>::dump_lemmas(literal l, antecedents const& ante) {
if (dump_lemmas()) {
TRACE("arith", ante.display(tout) << " --> "; ctx.display_detailed_literal(tout, l); tout << "\n";);
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().data(),
ante.eqs().size(), ante.eqs().data(), l);
}
}
template<typename Ext>
void theory_arith<Ext>::dump_lemmas(literal l, derived_bound const& ante) {
if (dump_lemmas()) {
ctx.display_lemma_as_smt_problem(ante.lits().size(), ante.lits().data(),
ante.eqs().size(), ante.eqs().data(), l);
}
}
template<typename Ext>
void theory_arith<Ext>::assign_bound_literal(literal l, row const & r, unsigned idx, bool is_lower, inf_numeral & delta) {
@ -3006,28 +3006,23 @@ namespace smt {
ante.display(tout) << " --> ";
ctx.display_detailed_literal(tout, l);
tout << "\n";);
dump_lemmas(l, ante);
if (ante.lits().size() < small_lemma_size() && ante.eqs().empty()) {
literal_vector & lits = m_tmp_literal_vector2;
lits.reset();
lits.push_back(l);
literal_vector::const_iterator it = ante.lits().begin();
literal_vector::const_iterator end = ante.lits().end();
for (; it != end; ++it)
lits.push_back(~(*it));
for (auto const& lit : ante.lits())
lits.push_back(~lit);
justification * js = nullptr;
if (proofs_enabled()) {
if (proofs_enabled())
js = alloc(theory_lemma_justification, get_id(), ctx, lits.size(), lits.data(),
ante.num_params(), ante.params("assign-bounds"));
}
ctx.mk_clause(lits.size(), lits.data(), js, CLS_TH_LEMMA, nullptr);
}
else {
region & r = ctx.get_region();
ctx.assign(l, ctx.mk_justification(
ext_theory_propagation_justification(
get_id(), r, ante.lits().size(), ante.lits().data(),
get_id(), ctx, ante.lits().size(), ante.lits().data(),
ante.eqs().size(), ante.eqs().data(), l,
ante.num_params(), ante.params("assign-bounds"))));
}
@ -3048,19 +3043,15 @@ namespace smt {
int upper_idx;
is_row_useful_for_bound_prop(r, lower_idx, upper_idx);
if (lower_idx >= 0) {
if (lower_idx >= 0)
imply_bound_for_monomial(r, lower_idx, true);
}
else if (lower_idx == -1) {
else if (lower_idx == -1)
imply_bound_for_all_monomials(r, true);
}
if (upper_idx >= 0) {
if (upper_idx >= 0)
imply_bound_for_monomial(r, upper_idx, false);
}
else if (upper_idx == -1) {
else if (upper_idx == -1)
imply_bound_for_all_monomials(r, false);
}
// sneaking cheap eq detection in this loop
propagate_cheap_eq(r_idx);
@ -3090,13 +3081,11 @@ namespace smt {
template<typename Ext>
void theory_arith<Ext>::set_conflict(antecedents const& ante, antecedents& bounds, char const* proof_rule) {
set_conflict(ante.lits().size(), ante.lits().data(), ante.eqs().size(), ante.eqs().data(), bounds, proof_rule);
dump_lemmas(false_literal, ante);
}
template<typename Ext>
void theory_arith<Ext>::set_conflict(derived_bound const& ante, antecedents& bounds, char const* proof_rule) {
set_conflict(ante.lits().size(), ante.lits().data(), ante.eqs().size(), ante.eqs().data(), bounds, proof_rule);
dump_lemmas(false_literal, ante);
}
template<typename Ext>
@ -3130,7 +3119,7 @@ namespace smt {
record_conflict(num_literals, lits, num_eqs, eqs, bounds.num_params(), bounds.params(proof_rule));
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(get_id(), ctx.get_region(), num_literals, lits, num_eqs, eqs,
ext_theory_conflict_justification(get_id(), ctx, num_literals, lits, num_eqs, eqs,
bounds.num_params(), bounds.params(proof_rule))));
}

View file

@ -37,7 +37,7 @@ namespace smt {
return;
SASSERT(is_fixed(v));
// WARNINING: it is not safe to use get_value(v) here, since
// WARNING: it is not safe to use get_value(v) here, since
// get_value(v) may not satisfy v bounds at this point.
if (!lower_bound(v).is_rational())
return;
@ -328,7 +328,6 @@ namespace smt {
return;
}
context & ctx = get_context();
region & r = ctx.get_region();
enode * _x = get_enode(x);
enode * _y = get_enode(y);
eq_vector const& eqs = antecedents.eqs();
@ -336,7 +335,7 @@ namespace smt {
justification * js =
ctx.mk_justification(
ext_theory_eq_propagation_justification(
get_id(), r,
get_id(), ctx,
lits.size(), lits.data(),
eqs.size(), eqs.data(),
_x, _y,

View file

@ -487,13 +487,13 @@ namespace smt {
template<typename Ext>
class theory_arith<Ext>::gomory_cut_justification : public ext_theory_propagation_justification {
public:
gomory_cut_justification(family_id fid, region & r,
gomory_cut_justification(family_id fid, context& ctx,
unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs,
antecedents& bounds,
literal consequent):
ext_theory_propagation_justification(fid, r, num_lits, lits, num_eqs, eqs, consequent,
bounds.num_params(), bounds.params("gomory-cut")) {
ext_theory_propagation_justification(fid, ctx, num_lits, lits, num_eqs, eqs, consequent,
bounds.num_params(), bounds.params("gomory-cut")) {
}
// Remark: the assignment must be propagated back to arith
theory_id get_from_theory() const override { return null_theory_id; }
@ -676,19 +676,16 @@ namespace smt {
l = ctx.get_literal(bound);
IF_VERBOSE(10, verbose_stream() << "cut " << bound << "\n");
ctx.mark_as_relevant(l);
dump_lemmas(l, ante);
auto js = ctx.mk_justification(
gomory_cut_justification(
get_id(), ctx.get_region(),
get_id(), ctx,
ante.lits().size(), ante.lits().data(),
ante.eqs().size(), ante.eqs().data(), ante, l));
if (l == false_literal) {
if (l == false_literal)
ctx.mk_clause(0, nullptr, js, CLS_TH_LEMMA, nullptr);
}
else {
else
ctx.assign(l, js);
}
return true;
}
@ -714,7 +711,7 @@ namespace smt {
for (; it != end; ++it) {
if (!it->is_dead()) {
if (is_fixed(it->m_var)) {
// WARNINING: it is not safe to use get_value(it->m_var) here, since
// WARNING: it is not safe to use get_value(it->m_var) here, since
// get_value(it->m_var) may not satisfy it->m_var bounds at this point.
numeral aux = lcm_den * it->m_coeff;
consts += aux * lower_bound(it->m_var).get_rational();
@ -760,7 +757,7 @@ namespace smt {
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(), ante.lits().size(), ante.lits().data(),
get_id(), ctx, ante.lits().size(), ante.lits().data(),
ante.eqs().size(), ante.eqs().data(),
ante.num_params(), ante.params("gcd-test"))));
return false;
@ -840,7 +837,7 @@ namespace smt {
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(),
get_id(), ctx,
ante.lits().size(), ante.lits().data(), ante.eqs().size(), ante.eqs().data(),
ante.num_params(), ante.params("gcd-test"))));
return false;
@ -858,11 +855,9 @@ namespace smt {
return true;
if (m_eager_gcd)
return true;
typename vector<row>::const_iterator it = m_rows.begin();
typename vector<row>::const_iterator end = m_rows.end();
for (; it != end; ++it) {
theory_var v = it->get_base_var();
if (v != null_theory_var && is_int(v) && !get_value(v).is_int() && !gcd_test(*it)) {
for (auto const& e : m_rows) {
theory_var v = e.get_base_var();
if (v != null_theory_var && is_int(v) && !get_value(v).is_int() && !gcd_test(e)) {
if (m_params.m_arith_adaptive_gcd)
m_eager_gcd = true;
return false;
@ -883,10 +878,8 @@ namespace smt {
for (;;) {
vars.reset();
// Collect infeasible integer variables.
typename vector<row>::const_iterator it = m_rows.begin();
typename vector<row>::const_iterator end = m_rows.end();
for (; it != end; ++it) {
theory_var v = it->get_base_var();
for (auto const& e : m_rows) {
theory_var v = e.get_base_var();
if (v != null_theory_var && is_int(v) && !get_value(v).is_int() && !is_bounded(v) && !already_processed.contains(v)) {
vars.push_back(v);
already_processed.insert(v);
@ -1056,15 +1049,13 @@ namespace smt {
TRACE("arith_int_rows",
unsigned num = 0;
typename vector<row>::const_iterator it = m_rows.begin();
typename vector<row>::const_iterator end = m_rows.end();
for (; it != end; ++it) {
theory_var v = it->get_base_var();
for (auto const& e : m_rows) {
theory_var v = e.get_base_var();
if (v == null_theory_var)
continue;
if (is_int(v) && !get_value(v).is_int()) {
num++;
display_simplified_row(tout, *it);
display_simplified_row(tout, e);
tout << "\n";
}
}

View file

@ -54,6 +54,20 @@ namespace smt {
return r;
}
app * theory_array_base::mk_select_reduce(unsigned num_args, expr * * args) {
array_util util(m);
while (util.is_store(args[0])) {
bool are_distinct = false;
for (unsigned i = 1; i < num_args && !are_distinct; ++i)
are_distinct |= m.are_distinct(args[i], to_app(args[0])->get_arg(i));
if (!are_distinct)
break;
args[0] = to_app(to_app(args[0])->get_arg(0));
}
return mk_select(num_args, args);
}
app * theory_array_base::mk_store(unsigned num_args, expr * const * args) {
return m.mk_app(get_family_id(), OP_STORE, 0, nullptr, num_args, args);
}
@ -484,6 +498,8 @@ namespace smt {
return p->get_arg(0)->get_root() == n->get_root();
if (is_map(p))
return true;
if (is_store(p))
return true;
return false;
}

View file

@ -62,6 +62,7 @@ namespace smt {
bool is_select_arg(enode* r);
app * mk_select(unsigned num_args, expr * const * args);
app * mk_select_reduce(unsigned num_args, expr * * args);
app * mk_select(expr_ref_vector const& args) { return mk_select(args.size(), args.data()); }
app * mk_store(unsigned num_args, expr * const * args);
app * mk_default(expr* a);

View file

@ -330,7 +330,8 @@ namespace smt {
// Even if there was, as-array on interpreted
// functions will be incomplete.
// The instantiation operations are still sound to include.
found_unsupported_op(n);
m_as_array.push_back(node);
ctx.push_trail(push_back_vector(m_as_array));
instantiate_default_as_array_axiom(node);
}
else if (is_array_ext(n)) {
@ -604,6 +605,14 @@ namespace smt {
for (unsigned i = 0; i < lam->get_num_decls(); ++i)
args.push_back(mk_epsilon(lam->get_decl_sort(i)).first);
expr_ref val(mk_select(args), m);
ctx.get_rewriter()(val);
if (has_quantifiers(val)) {
expr_ref fn(m.mk_fresh_const("lambda-body", val->get_sort()), m);
expr_ref eq(m.mk_eq(fn, val), m);
ctx.assert_expr(eq);
ctx.internalize_assertions();
val = fn;
}
ctx.internalize(def, false);
ctx.internalize(val.get(), false);
return try_assign_eq(val.get(), def);
@ -807,12 +816,24 @@ namespace smt {
if (r == FC_DONE && m_bapa) {
r = m_bapa->final_check();
}
bool should_giveup = m_found_unsupported_op || has_propagate_up_trail();
bool should_giveup = m_found_unsupported_op || has_propagate_up_trail() || has_non_beta_as_array();
if (r == FC_DONE && should_giveup)
r = FC_GIVEUP;
return r;
}
bool theory_array_full::has_non_beta_as_array() {
for (enode* n : m_as_array) {
for (enode* p : n->get_parents())
if (!ctx.is_beta_redex(p, n)) {
TRACE("array", tout << "not a beta redex " << enode_pp(p, ctx) << "\n");
return true;
}
}
return false;
}
bool theory_array_full::instantiate_parent_stores_default(theory_var v) {
SASSERT(v != null_theory_var);
TRACE("array", tout << "v" << v << "\n";);

View file

@ -85,6 +85,8 @@ namespace smt {
bool has_large_domain(app* array_term);
bool has_unitary_domain(app* array_term);
std::pair<app*,func_decl*> mk_epsilon(sort* s);
enode_vector m_as_array;
bool has_non_beta_as_array();
bool instantiate_select_const_axiom(enode* select, enode* cnst);
bool instantiate_select_as_array_axiom(enode* select, enode* arr);

View file

@ -294,8 +294,7 @@ namespace smt {
m_trail_stack.push(add_var_pos_trail(b));
b->m_occs = new (get_region()) var_pos_occ(v, idx, b->m_occs);
}
else {
SASSERT(th_id == null_theory_id);
else if (th_id == null_theory_id) {
ctx.set_var_theory(l.var(), get_id());
SASSERT(ctx.get_var_theory(l.var()) == get_id());
bit_atom * b = new (get_region()) bit_atom();
@ -600,6 +599,8 @@ namespace smt {
TRACE("bv", tout << mk_bounded_pp(n, m) << "\n";);
process_args(n);
mk_enode(n);
m_bv2int.push_back(ctx.get_enode(n));
ctx.push_trail(push_back_vector<enode_vector>(m_bv2int));
if (!ctx.relevancy())
assert_bv2int_axiom(n);
}
@ -1497,24 +1498,34 @@ namespace smt {
unsigned sz = m_bits[v1].size();
bool changed = true;
TRACE("bv", tout << "bits size: " << sz << "\n";);
if (sz == 0) {
if (sz == 0 && !m_bv2int.empty()) {
// int2bv(bv2int(x)) = x when int2bv(bv2int(x)) has same sort as x
enode* n1 = get_enode(r1);
for (enode* bv2int : *n1) {
if (!m_util.is_bv2int(bv2int->get_expr()))
continue;
enode* bv2int_arg = bv2int->get_arg(0);
auto propagate_bv2int = [&](enode* bv2int) {
enode* bv2int_arg = get_arg(bv2int, 0);
for (enode* p : enode::parents(n1->get_root())) {
if (m_util.is_int2bv(p->get_expr()) && p->get_root() != bv2int_arg->get_root() && p->get_sort() == bv2int_arg->get_sort()) {
enode_pair_vector eqs;
eqs.push_back({n1, p->get_arg(0) });
eqs.push_back({n1, get_arg(p, 0) });
eqs.push_back({n1, bv2int});
justification * js = ctx.mk_justification(
ext_theory_eq_propagation_justification(get_id(), ctx.get_region(), 0, nullptr, eqs.size(), eqs.data(), p, bv2int_arg));
ext_theory_eq_propagation_justification(get_id(), ctx, 0, nullptr, eqs.size(), eqs.data(), p, bv2int_arg));
ctx.assign_eq(p, bv2int_arg, eq_justification(js));
break;
}
}
};
if (m_bv2int.size() < n1->get_class_size()) {
for (enode* bv2int : m_bv2int)
if (bv2int->get_root() == n1->get_root())
propagate_bv2int(bv2int);
}
else {
for (enode* bv2int : *n1) {
if (m_util.is_bv2int(bv2int->get_expr()))
propagate_bv2int(bv2int);
}
}
}
do {

View file

@ -42,7 +42,7 @@ namespace smt {
class atom {
public:
virtual ~atom() {}
virtual ~atom() = default;
virtual bool is_bit() const = 0;
};
@ -112,6 +112,7 @@ namespace smt {
svector<unsigned> m_wpos; // per var, watch position for fixed variable detection.
vector<zero_one_bits> m_zero_one_bits; // per var, see comment in the struct zero_one_bit
bool_var2atom m_bool_var2atom;
enode_vector m_bv2int;
typedef svector<theory_var> vars;
typedef std::pair<numeral, unsigned> value_sort_pair;

View file

@ -138,7 +138,7 @@ namespace smt {
enode* n2 = ensure_enode(bits2char);
justification* j =
ctx.mk_justification(
ext_theory_eq_propagation_justification(get_id(), ctx.get_region(), n1, n2));
ext_theory_eq_propagation_justification(get_id(), ctx, n1, n2));
ctx.assign_eq(n1, n2, eq_justification(j));
}
++m_stats.m_num_blast;
@ -267,7 +267,7 @@ namespace smt {
enode* n2 = ensure_enode(sum_bits);
justification* j =
ctx.mk_justification(
ext_theory_eq_propagation_justification(get_id(), ctx.get_region(), n1, n2));
ext_theory_eq_propagation_justification(get_id(), ctx, n1, n2));
ctx.assign_eq(n1, n2, eq_justification(j));
}

View file

@ -31,8 +31,8 @@ namespace smt {
class dt_eq_justification : public ext_theory_eq_propagation_justification {
public:
dt_eq_justification(family_id fid, region & r, literal antecedent, enode * lhs, enode * rhs):
ext_theory_eq_propagation_justification(fid, r, 1, &antecedent, 0, nullptr, lhs, rhs) {
dt_eq_justification(family_id fid, context& ctx, literal antecedent, enode * lhs, enode * rhs):
ext_theory_eq_propagation_justification(fid, ctx, 1, &antecedent, 0, nullptr, lhs, rhs) {
}
// Remark: the assignment must be propagated back to the datatype theory.
theory_id get_from_theory() const override { return null_theory_id; }
@ -122,9 +122,8 @@ namespace smt {
}
else {
SASSERT(ctx.get_assignment(antecedent) == l_true);
region & r = ctx.get_region();
enode * _rhs = ctx.get_enode(rhs);
justification * js = ctx.mk_justification(dt_eq_justification(get_id(), r, antecedent, lhs, _rhs));
justification * js = ctx.mk_justification(dt_eq_justification(get_id(), ctx, antecedent, lhs, _rhs));
TRACE("datatype", tout << "assigning... #" << lhs->get_owner_id() << " #" << _rhs->get_owner_id() << "\n";
tout << "v" << lhs->get_th_var(get_id()) << " v" << _rhs->get_th_var(get_id()) << "\n";);
TRACE("datatype_detail", display(tout););
@ -209,9 +208,8 @@ namespace smt {
l.neg();
SASSERT(ctx.get_assignment(l) == l_true);
enode_pair p(c, r->get_arg(0));
region & reg = ctx.get_region();
clear_mark();
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), reg, 1, &l, 1, &p)));
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), ctx, 1, &l, 1, &p)));
}
/**
@ -732,9 +730,8 @@ namespace smt {
if (res) {
// m_used_eqs should contain conflict
region & r = ctx.get_region();
clear_mark();
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), r, 0, nullptr, m_used_eqs.size(), m_used_eqs.data())));
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), ctx, 0, nullptr, m_used_eqs.size(), m_used_eqs.data())));
}
return res;
}
@ -859,10 +856,9 @@ namespace smt {
var_data * d2 = m_var_data[v2];
if (d2->m_constructor != nullptr) {
if (d1->m_constructor != nullptr && d1->m_constructor->get_decl() != d2->m_constructor->get_decl()) {
region & r = ctx.get_region();
enode_pair p(d1->m_constructor, d2->m_constructor);
SASSERT(d1->m_constructor->get_root() == d2->m_constructor->get_root());
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), r, 0, nullptr, 1, &p)));
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), ctx, 0, nullptr, 1, &p)));
}
if (d1->m_constructor == nullptr) {
m_trail_stack.push(set_ptr_trail<enode>(d1->m_constructor));
@ -972,14 +968,13 @@ namespace smt {
if (num_unassigned == 0) {
// conflict
SASSERT(!lits.empty());
region & reg = ctx.get_region();
TRACE("datatype_conflict", tout << mk_ismt2_pp(recognizer->get_expr(), m) << "\n";
for (literal l : lits)
ctx.display_detailed_literal(tout, l) << "\n";
for (auto const& p : eqs)
tout << enode_eq_pp(p, ctx);
);
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), reg, lits.size(), lits.data(), eqs.size(), eqs.data())));
ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), ctx, lits.size(), lits.data(), eqs.size(), eqs.data())));
}
else if (num_unassigned == 1) {
// propagate remaining recognizer
@ -997,9 +992,8 @@ namespace smt {
consequent = literal(ctx.enode2bool_var(r));
}
ctx.mark_as_relevant(consequent);
region & reg = ctx.get_region();
ctx.assign(consequent,
ctx.mk_justification(ext_theory_propagation_justification(get_id(), reg, lits.size(), lits.data(),
ctx.mk_justification(ext_theory_propagation_justification(get_id(), ctx, lits.size(), lits.data(),
eqs.size(), eqs.data(), consequent)));
}
else {

View file

@ -238,7 +238,6 @@ namespace smt {
void flush_eh() override;
void reset_eh() override;
bool dump_lemmas() const { return m_params.m_arith_dump_lemmas; }
void display(std::ostream & out) const override;
virtual void display_atom(std::ostream & out, atom * a) const;

View file

@ -539,7 +539,7 @@ namespace smt {
literal_vector & antecedents = m_tmp_literals;
antecedents.reset();
get_antecedents(source, target, antecedents);
ctx.assign(l, ctx.mk_justification(theory_propagation_justification(get_id(), ctx.get_region(), antecedents.size(), antecedents.data(), l)));
ctx.assign(l, ctx.mk_justification(theory_propagation_justification(get_id(), ctx, antecedents.size(), antecedents.data(), l)));
}
template<typename Ext>
@ -591,12 +591,7 @@ namespace smt {
get_antecedents(target, source, antecedents);
if (l != null_literal)
antecedents.push_back(l);
region & r = ctx.get_region();
ctx.set_conflict(ctx.mk_justification(theory_conflict_justification(get_id(), r, antecedents.size(), antecedents.data())));
if (dump_lemmas()) {
ctx.display_lemma_as_smt_problem(antecedents.size(), antecedents.data(), false_literal);
}
ctx.set_conflict(ctx.mk_justification(theory_conflict_justification(get_id(), ctx, antecedents.size(), antecedents.data())));
return;
}

View file

@ -350,8 +350,6 @@ namespace smt {
bool propagate_eqs() const { return m_params.m_arith_propagate_eqs; }
bool dump_lemmas() const { return m_params.m_arith_dump_lemmas; }
theory_var expand(bool pos, theory_var v, rational & k);
void new_eq_or_diseq(bool is_eq, theory_var v1, theory_var v2, justification& eq_just);

View file

@ -665,10 +665,6 @@ void theory_diff_logic<Ext>::new_edge(dl_var src, dl_var dst, unsigned num_edges
params.size(), params.data());
}
ctx.mk_clause(lits.size(), lits.data(), js, CLS_TH_LEMMA, nullptr);
if (dump_lemmas()) {
symbol logic(m_lia_or_lra == is_lia ? "QF_LIA" : "QF_LRA");
ctx.display_lemma_as_smt_problem(lits.size(), lits.data(), false_literal, logic);
}
#if 0
TRACE("arith",
@ -707,11 +703,6 @@ void theory_diff_logic<Ext>::set_neg_cycle_conflict() {
for (literal lit : lits) ctx.display_literal_info(tout, lit);
tout << "\n";);
if (dump_lemmas()) {
symbol logic(m_lia_or_lra == is_lia ? "QF_LIA" : "QF_LRA");
ctx.display_lemma_as_smt_problem(lits.size(), lits.data(), false_literal, logic);
}
vector<parameter> params;
if (m.proofs_enabled()) {
params.push_back(parameter(symbol("farkas")));
@ -723,7 +714,7 @@ void theory_diff_logic<Ext>::set_neg_cycle_conflict() {
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(),
get_id(), ctx,
lits.size(), lits.data(), 0, nullptr, params.size(), params.data())));
}

View file

@ -607,7 +607,7 @@ class theory_lra::imp {
return v;
}
bool const has_int() const { return lp().has_int_var(); }
bool has_int() const { return lp().has_int_var(); }
lpvar register_theory_var_in_lar_solver(theory_var v) {
lpvar lpv = lp().external_to_local(v);
@ -1241,6 +1241,7 @@ public:
context& c = ctx();
if (!k.is_zero()) {
mk_axiom(eq);
m_arith_eq_adapter.mk_axioms(th.ensure_enode(mod_r), th.ensure_enode(p));
mk_axiom(mk_literal(a.mk_ge(mod, zero)));
mk_axiom(mk_literal(a.mk_le(mod, upper)));
@ -2331,7 +2332,6 @@ public:
literal_vector m_core2;
void assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs, vector<parameter> const& params) {
dump_assign(lit, core, eqs);
if (core.size() < small_lemma_size() && eqs.empty()) {
m_core2.reset();
for (auto const& c : core) {
@ -2349,7 +2349,7 @@ public:
ctx().assign(
lit, ctx().mk_justification(
ext_theory_propagation_justification(
get_id(), ctx().get_region(), core.size(), core.data(),
get_id(), ctx(), core.size(), core.data(),
eqs.size(), eqs.data(), lit, params.size(), params.data())));
}
}
@ -2942,8 +2942,6 @@ public:
}
bool dump_lemmas() const { return params().m_arith_dump_lemmas; }
bool propagate_eqs() const { return params().m_arith_propagate_eqs && m_num_conflicts < params().m_arith_propagation_threshold; }
bound_prop_mode propagation_mode() const { return m_num_conflicts < params().m_arith_propagation_threshold ? params().m_arith_bound_prop : bound_prop_mode::BP_NONE; }
@ -3079,7 +3077,7 @@ public:
justification* js =
ctx().mk_justification(
ext_theory_eq_propagation_justification(
get_id(), ctx().get_region(), m_core.size(), m_core.data(), m_eqs.size(), m_eqs.data(), x, y));
get_id(), ctx(), m_core.size(), m_core.data(), m_eqs.size(), m_eqs.data(), x, y));
TRACE("arith",
for (auto c : m_core)
@ -3203,12 +3201,11 @@ public:
set_evidence(ev.ci(), m_core, m_eqs);
// SASSERT(validate_conflict(m_core, m_eqs));
dump_conflict(m_core, m_eqs);
if (is_conflict) {
ctx().set_conflict(
ctx().mk_justification(
ext_theory_conflict_justification(
get_id(), ctx().get_region(),
get_id(), ctx(),
m_core.size(), m_core.data(),
m_eqs.size(), m_eqs.data(), m_params.size(), m_params.data())));
}
@ -3414,11 +3411,6 @@ public:
}
};
void dump_conflict(literal_vector const& core, svector<enode_pair> const& eqs) {
if (dump_lemmas()) {
ctx().display_lemma_as_smt_problem(core.size(), core.data(), eqs.size(), eqs.data(), false_literal);
}
}
bool validate_conflict(literal_vector const& core, svector<enode_pair> const& eqs) {
if (params().m_arith_mode != arith_solver_id::AS_NEW_ARITH) return true;
@ -3432,13 +3424,6 @@ public:
return result;
}
void dump_assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs) {
if (dump_lemmas()) {
unsigned id = ctx().display_lemma_as_smt_problem(core.size(), core.data(), eqs.size(), eqs.data(), lit);
(void)id;
}
}
bool validate_assign(literal lit, literal_vector const& core, svector<enode_pair> const& eqs) {
if (params().m_arith_mode != arith_solver_id::AS_NEW_ARITH) return true;
scoped_arith_mode _sa(ctx().get_fparams());
@ -3523,16 +3508,15 @@ public:
case lp::lp_status::OPTIMAL: {
init_variable_values();
TRACE("arith", display(tout << st << " v" << v << " vi: " << vi << "\n"););
inf_rational val = get_value(v);
// inf_rational val(term_max.x, term_max.y);
auto val = value(v);
blocker = mk_gt(v);
return inf_eps(rational::zero(), val);
return val;
}
case lp::lp_status::FEASIBLE: {
inf_rational val = get_value(v);
auto val = value(v);
TRACE("arith", display(tout << st << " v" << v << " vi: " << vi << "\n"););
blocker = mk_gt(v);
return inf_eps(rational::zero(), val);
return val;
}
default:
SASSERT(st == lp::lp_status::UNBOUNDED);
@ -3549,23 +3533,19 @@ public:
rational r = val.x;
expr_ref e(m);
if (a.is_int(obj->get_sort())) {
if (r.is_int()) {
if (r.is_int())
r += rational::one();
}
else {
else
r = ceil(r);
}
e = a.mk_numeral(r, obj->get_sort());
e = a.mk_ge(obj, e);
}
else {
e = a.mk_numeral(r, obj->get_sort());
if (val.y.is_neg()) {
if (val.y.is_neg())
e = a.mk_ge(obj, e);
}
else {
else
e = a.mk_gt(obj, e);
}
}
TRACE("opt", tout << "v" << v << " " << val << " " << r << " " << e << "\n";);
return e;

View file

@ -1106,7 +1106,7 @@ namespace smt {
\brief propagate assignment to inequality.
This is a basic, non-optimized implementation based
on the assumption that inequalities are mostly units
and/or relatively few compared to number of argumets.
and/or relatively few compared to number of arguments.
*/
void theory_pb::assign_ineq(ineq& c, bool is_true) {
m_mpz_trail.push_back(c.m_max_sum);
@ -1486,9 +1486,9 @@ namespace smt {
class theory_pb::pb_justification : public theory_propagation_justification {
ineq& m_ineq;
public:
pb_justification(ineq& c, family_id fid, region & r,
pb_justification(ineq& c, family_id fid, context& ctx,
unsigned num_lits, literal const * lits, literal consequent):
theory_propagation_justification(fid, r, num_lits, lits, consequent),
theory_propagation_justification(fid, ctx, num_lits, lits, consequent),
m_ineq(c)
{}
ineq& get_ineq() { return m_ineq; }
@ -1504,7 +1504,7 @@ namespace smt {
SASSERT(validate_antecedents(lits));
ctx.assign(l, ctx.mk_justification(
pb_justification(
c, get_id(), ctx.get_region(), lits.size(), lits.data(), l)));
c, get_id(), ctx, lits.size(), lits.data(), l)));
}
@ -2008,7 +2008,7 @@ namespace smt {
SASSERT(validate_antecedents(m_antecedents));
TRACE("pb", tout << "assign " << m_antecedents << " ==> " << alit << "\n";);
ctx.assign(alit, ctx.mk_justification(theory_propagation_justification(get_id(), ctx.get_region(), m_antecedents.size(), m_antecedents.data(), alit, 0, nullptr)));
ctx.assign(alit, ctx.mk_justification(theory_propagation_justification(get_id(), ctx, m_antecedents.size(), m_antecedents.data(), alit, 0, nullptr)));
DEBUG_CODE(
m_antecedents.push_back(~alit);
@ -2029,7 +2029,7 @@ namespace smt {
literal lits[2] = { l1, l2 };
justification* js = nullptr;
if (proofs_enabled()) {
js = ctx.mk_justification(theory_axiom_justification(get_id(), ctx.get_region(), 2, lits));
js = ctx.mk_justification(theory_axiom_justification(get_id(), ctx, 2, lits));
}
return js;
}
@ -2037,7 +2037,7 @@ namespace smt {
justification* theory_pb::justify(literal_vector const& lits) {
justification* js = nullptr;
if (proofs_enabled()) {
js = ctx.mk_justification(theory_axiom_justification(get_id(), ctx.get_region(), lits.size(), lits.data()));
js = ctx.mk_justification(theory_axiom_justification(get_id(), ctx, lits.size(), lits.data()));
}
return js;
}

View file

@ -304,6 +304,7 @@ void theory_seq::init() {
m_ax.add_axiom5 = add_ax;
m_ax.mk_eq_empty2 = mk_eq_emp;
m_arith_value.init(&ctx);
m_max_unfolding_depth = ctx.get_fparams().m_seq_min_unfolding;
}
#define TRACEFIN(s) { TRACE("seq", tout << ">>" << s << "\n";); IF_VERBOSE(20, verbose_stream() << s << "\n"); }
@ -418,6 +419,10 @@ final_check_status theory_seq::final_check_eh() {
TRACEFIN("fixed_length");
return FC_CONTINUE;
}
if (solve_recfuns()) {
TRACEFIN("solve_recfun");
return FC_CONTINUE;
}
if (m_unhandled_expr) {
TRACEFIN("give_up");
TRACE("seq", tout << "unhandled: " << mk_pp(m_unhandled_expr, m) << "\n";);
@ -642,11 +647,9 @@ bool theory_seq::check_extensionality() {
\brief check negated contains constraints.
*/
bool theory_seq::check_contains() {
for (unsigned i = 0; !ctx.inconsistent() && i < m_ncs.size(); ++i) {
if (solve_nc(i)) {
for (unsigned i = 0; !ctx.inconsistent() && i < m_ncs.size(); ++i)
if (solve_nc(i))
m_ncs.erase_and_swap(i--);
}
}
return m_new_propagation || ctx.inconsistent();
}
@ -783,7 +786,7 @@ bool theory_seq::propagate_lit(dependency* dep, unsigned n, literal const* _lits
justification* js =
ctx.mk_justification(
ext_theory_propagation_justification(
get_id(), ctx.get_region(), lits.size(), lits.data(), eqs.size(), eqs.data(), lit));
get_id(), ctx, lits.size(), lits.data(), eqs.size(), eqs.data(), lit));
m_new_propagation = true;
ctx.assign(lit, js);
@ -804,14 +807,14 @@ void theory_seq::set_conflict(enode_pair_vector const& eqs, literal_vector const
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(), lits.size(), lits.data(), eqs.size(), eqs.data(), 0, nullptr)));
get_id(), ctx, lits.size(), lits.data(), eqs.size(), eqs.data(), 0, nullptr)));
validate_conflict(eqs, lits);
}
bool theory_seq::propagate_eq(dependency* dep, enode* n1, enode* n2) {
if (n1->get_root() == n2->get_root()) {
if (n1->get_root() == n2->get_root())
return false;
}
literal_vector lits;
enode_pair_vector eqs;
linearize(dep, eqs, lits);
@ -829,7 +832,7 @@ bool theory_seq::propagate_eq(dependency* dep, enode* n1, enode* n2) {
justification* js = ctx.mk_justification(
ext_theory_eq_propagation_justification(
get_id(), ctx.get_region(), lits.size(), lits.data(), eqs.size(), eqs.data(), n1, n2));
get_id(), ctx, lits.size(), lits.data(), eqs.size(), eqs.data(), n1, n2));
{
std::function<expr*(void)> fn = [&]() { return m.mk_eq(n1->get_expr(), n2->get_expr()); };
@ -985,9 +988,8 @@ bool theory_seq::is_var(expr* a) const {
bool theory_seq::add_solution(expr* l, expr* r, dependency* deps) {
if (l == r) {
if (l == r)
return false;
}
m_new_solution = true;
m_rep.update(l, r, deps);
enode* n1 = ensure_enode(l);
@ -1000,11 +1002,11 @@ bool theory_seq::add_solution(expr* l, expr* r, dependency* deps) {
}
bool theory_seq::propagate_max_length(expr* l, expr* r, dependency* deps) {
unsigned idx;
expr* s;
if (m_util.str.is_empty(l)) {
if (m_util.str.is_empty(l))
std::swap(l, r);
}
unsigned idx;
expr* s = nullptr;
rational hi;
if (m_sk.is_tail_u(l, s, idx) && has_length(s) && m_util.str.is_empty(r) && !upper_bound(s, hi)) {
propagate_lit(deps, 0, nullptr, m_ax.mk_le(mk_len(s), idx+1));
@ -1240,12 +1242,31 @@ bool theory_seq::get_length(expr* e, expr_ref& len, literal_vector& lits) {
return false;
}
/**
* solve for fold/map (recursive function that depends on a sequence)
* Assumption: the Seq argument of fold/map expands into a concatentation of units
* The assumption is enforced by tracking the length of the seq argument.
* This is ensured in relevant_eh.
* Under the assumption, evern occurrence of fold/map gets simplified by expanding
* arguments.
*/
bool theory_seq::solve_recfuns() {
for (unsigned i = 0; i < m_recfuns.size() && !ctx.inconsistent(); ++i) {
expr* t = m_recfuns[i];
dependency* dep = nullptr;
expr_ref r(m);
if (canonize(t, dep, r) && r != t) {
add_solution(t, r, dep);
m_recfuns.erase_and_swap(i--);
}
}
return m_new_propagation || ctx.inconsistent();
}
bool theory_seq::solve_nc(unsigned idx) {
nc const& n = m_ncs[idx];
literal len_gt = n.len_gt();
literal len_gt = n.len_gt();
expr_ref c(m);
expr* a = nullptr, *b = nullptr;
VERIFY(m_util.str.is_contains(n.contains(), a, b));
@ -1263,10 +1284,12 @@ bool theory_seq::solve_nc(unsigned idx) {
m_new_propagation = true;
return false;
case l_false:
break;
if (!m_sk.is_tail(a))
add_length_limit(a, m_max_unfolding_depth, true);
m_ax.unroll_not_contains(n.contains());
return true;
}
m_ax.unroll_not_contains(n.contains());
return true;
return false;
}
theory_seq::cell* theory_seq::mk_cell(cell* p, expr* e, dependency* d) {
@ -1456,7 +1479,7 @@ bool theory_seq::internalize_term(app* term) {
mk_var(ctx.get_enode(term));
return true;
}
if (m.is_bool(term) &&
(m_util.str.is_in_re(term) || m_sk.is_skolem(term))) {
bool_var bv = ctx.mk_bool_var(term);
@ -1515,10 +1538,23 @@ void theory_seq::add_length(expr* l) {
Add length limit restrictions to sequence s.
*/
void theory_seq::add_length_limit(expr* s, unsigned k, bool is_searching) {
if (m_sk.is_indexof_left(s))
if (m_util.str.is_concat(s)) {
for (expr* e : *to_app(s))
add_length_limit(e, k, is_searching);
return;
if (m_sk.is_indexof_right(s))
}
if (m_util.str.is_unit(s))
return;
if (m_util.str.is_empty(s))
return;
if (m_sk.is_skolem(s)) {
for (expr* e : *to_app(s))
if (m_util.is_seq(e) || m_sk.is_skolem(e))
add_length_limit(e, k, is_searching);
return;
}
expr_ref lim_e = m_ax.add_length_limit(s, k);
unsigned k0 = 0;
if (m_length_limit_map.find(s, k0)) {
@ -2500,8 +2536,8 @@ bool theory_seq::expand1(expr* e0, dependency*& eqs, expr_ref& result) {
dependency* deps = nullptr;
expr* e = m_rep.find(e0, deps);
expr* e1, *e2, *e3;
expr_ref arg1(m), arg2(m);
expr* e1, *e2, *e3, *e4;
expr_ref arg1(m), arg2(m), arg3(m), arg4(m);
if (m_util.str.is_concat(e, e1, e2)) {
arg1 = try_expand(e1, deps);
arg2 = try_expand(e2, deps);
@ -2546,6 +2582,30 @@ bool theory_seq::expand1(expr* e0, dependency*& eqs, expr_ref& result) {
if (!arg1 || !arg2) return true;
result = m_util.str.mk_index(arg1, arg2, e3);
}
else if (m_util.str.is_map(e, e1, e2)) {
arg2 = try_expand(e2, deps);
if (!arg2) return true;
result = m_util.str.mk_map(e1, arg2);
ctx.get_rewriter()(result);
}
else if (m_util.str.is_mapi(e, e1, e2, e3)) {
arg3 = try_expand(e3, deps);
if (!arg3) return true;
result = m_util.str.mk_mapi(e1, e2, arg3);
ctx.get_rewriter()(result);
}
else if (m_util.str.is_foldl(e, e1, e2, e3)) {
arg3 = try_expand(e3, deps);
if (!arg3) return true;
result = m_util.str.mk_foldl(e1, e2, arg3);
ctx.get_rewriter()(result);
}
else if (m_util.str.is_foldli(e, e1, e2, e3, e4)) {
arg4 = try_expand(e4, deps);
if (!arg4) return true;
result = m_util.str.mk_foldli(e1, e2, e3, arg4);
ctx.get_rewriter()(result);
}
#if 0
else if (m_util.str.is_nth_i(e, e1, e2)) {
arg1 = try_expand(e1, deps);
@ -2889,7 +2949,12 @@ void theory_seq::add_axiom(literal l1, literal l2, literal l3, literal l4, liter
}
void theory_seq::add_axiom(literal_vector & lits) {
TRACE("seq", ctx.display_literals_smt2(tout << "assert:", lits) << "\n";);
TRACE("seq", ctx.display_literals_verbose(tout << "assert " << lits << " :", lits) << "\n";);
for (literal lit : lits)
if (ctx.get_assignment(lit) == l_true)
return;
for (literal lit : lits)
ctx.mark_as_relevant(lit);
@ -2954,7 +3019,7 @@ bool theory_seq::propagate_eq(dependency* deps, literal_vector const& _lits, exp
justification* js =
ctx.mk_justification(
ext_theory_eq_propagation_justification(
get_id(), ctx.get_region(), lits.size(), lits.data(), eqs.size(), eqs.data(), n1, n2));
get_id(), ctx, lits.size(), lits.data(), eqs.size(), eqs.data(), n1, n2));
m_new_propagation = true;
@ -3164,6 +3229,7 @@ void theory_seq::push_scope_eh() {
m_nqs.push_scope();
m_ncs.push_scope();
m_lts.push_scope();
m_recfuns.push_scope();
m_regex.push_scope();
}
@ -3177,6 +3243,7 @@ void theory_seq::pop_scope_eh(unsigned num_scopes) {
m_nqs.pop_scope(num_scopes);
m_ncs.pop_scope(num_scopes);
m_lts.pop_scope(num_scopes);
m_recfuns.pop_scope(num_scopes);
m_regex.pop_scope(num_scopes);
m_rewrite.reset();
if (ctx.get_base_level() > ctx.get_scope_level() - num_scopes) {
@ -3203,6 +3270,7 @@ void theory_seq::relevant_eh(app* n) {
m_util.str.is_from_code(n) ||
m_util.str.is_to_code(n) ||
m_util.str.is_unit(n) ||
m_util.str.is_last_index(n) ||
m_util.str.is_length(n) ||
/* m_util.str.is_replace_all(n) || uncomment to enable axiomatization */
m_util.str.is_le(n)) {
@ -3214,6 +3282,15 @@ void theory_seq::relevant_eh(app* n) {
add_int_string(n);
}
expr* fn, *acc, *i, *s;
if (m_util.str.is_foldl(n, fn, acc, s) ||
m_util.str.is_foldli(n, fn, i, acc, s) ||
m_util.str.is_map(n, fn, s) ||
m_util.str.is_mapi(n, fn, i, s)) {
add_length_to_eqc(s);
m_recfuns.push_back(n);
}
if (m_util.str.is_ubv2s(n))
add_ubv_string(n);
@ -3276,7 +3353,7 @@ bool theory_seq::should_research(expr_ref_vector & unsat_core) {
}
}
if (k_min < UINT_MAX/4) {
if (k_min < get_fparams().m_seq_max_unfolding) {
m_max_unfolding_depth++;
k_min *= 2;
if (m_util.is_seq(s_min))
@ -3290,7 +3367,7 @@ bool theory_seq::should_research(expr_ref_vector & unsat_core) {
IF_VERBOSE(1, verbose_stream() << "(smt.seq :increase-depth " << m_max_unfolding_depth << ")\n");
return true;
}
else if (k_min != UINT_MAX && k_min >= UINT_MAX/4) {
else if (k_min != UINT_MAX && k_min >= get_fparams().m_seq_max_unfolding) {
throw default_exception("reached max unfolding");
}

View file

@ -222,7 +222,7 @@ namespace smt {
class apply {
public:
virtual ~apply() {}
virtual ~apply() = default;
virtual void operator()(theory_seq& th) = 0;
};
@ -328,6 +328,7 @@ namespace smt {
scoped_vector<ne> m_nqs; // set of current disequalities.
scoped_vector<nc> m_ncs; // set of non-contains constraints.
scoped_vector<expr*> m_lts; // set of asserted str.<, str.<= literals
scoped_vector<expr*> m_recfuns; // set of recursive functions that are defined by unfolding seq argument (map/fold)
bool m_lts_checked;
unsigned m_eq_id;
th_union_find m_find;
@ -484,6 +485,7 @@ namespace smt {
bool solve_nqs(unsigned i);
bool solve_ne(unsigned i);
bool solve_nc(unsigned i);
bool solve_recfuns();
bool check_ne_literals(unsigned idx, unsigned& num_undef_lits);
bool propagate_ne2lit(unsigned idx);
bool propagate_ne2eq(unsigned idx);

View file

@ -279,7 +279,7 @@ namespace smt {
enode* tcn = ensure_enode(tc_app);
if (ctx.get_assignment(tcn) != l_true) {
literal consequent = ctx.get_literal(tc_app);
justification* j = ctx.mk_justification(theory_propagation_justification(get_id(), ctx.get_region(), 1, &lit, consequent));
justification* j = ctx.mk_justification(theory_propagation_justification(get_id(), ctx, 1, &lit, consequent));
TRACE("special_relations", tout << "propagate: " << tc_app << "\n";);
ctx.assign(consequent, j);
new_assertion = true;
@ -469,7 +469,7 @@ namespace smt {
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(),
get_id(), ctx,
lits.size(), lits.data(), 0, nullptr, params.size(), params.data())));
}
@ -532,7 +532,7 @@ namespace smt {
literal_vector const& lits = r.m_explanation;
TRACE("special_relations", ctx.display_literals_verbose(tout << mk_pp(x->get_expr(), m) << " = " << mk_pp(y->get_expr(), m) << "\n", lits) << "\n";);
IF_VERBOSE(20, ctx.display_literals_verbose(verbose_stream() << mk_pp(x->get_expr(), m) << " = " << mk_pp(y->get_expr(), m) << "\n", lits) << "\n";);
eq_justification js(ctx.mk_justification(ext_theory_eq_propagation_justification(get_id(), ctx.get_region(), lits.size(), lits.data(), 0, nullptr,
eq_justification js(ctx.mk_justification(ext_theory_eq_propagation_justification(get_id(), ctx, lits.size(), lits.data(), 0, nullptr,
x, y)));
ctx.assign_eq(x, y, js);
}
@ -1149,8 +1149,8 @@ namespace smt {
void theory_special_relations::get_specrels(func_decl_set& rels) const {
for (auto [f, r] : m_relations)
rels.insert(m_util.get_relation(r->m_decl));
for (auto [f, r] : m_relations)
rels.insert(r->m_decl);
}
}

View file

@ -8436,6 +8436,14 @@ namespace smt {
}
}
bool existNegativeContains = false;
expr_ref_vector assignments(m);
ctx.get_assignments(assignments);
for (expr * a : assignments) {
expr * subterm;
if (m.is_not(a, subterm) && u.str.is_contains(subterm)) existNegativeContains = true;
}
if (!needToAssignFreeVars) {
// check string-int terms
@ -8506,9 +8514,11 @@ namespace smt {
// we're not done if some variable in a regex membership predicate was unassigned
if (regexOK) {
if (unused_internal_variables.empty()) {
TRACE("str", tout << "All variables are assigned. Done!" << std::endl;);
m_stats.m_solved_by = 2;
return FC_DONE;
if (!existNegativeContains) {
TRACE("str", tout << "All variables are assigned. Done!" << std::endl;);
m_stats.m_solved_by = 2;
return FC_DONE;
}
} else {
TRACE("str", tout << "Assigning decoy values to free internal variables." << std::endl;);
for (auto const &var : unused_internal_variables) {
@ -8561,9 +8571,6 @@ namespace smt {
}
TRACE("str", tout << "arithmetic solver done in final check" << std::endl;);
expr_ref_vector assignments(m);
ctx.get_assignments(assignments);
expr_ref_vector precondition(m);
expr_ref_vector cex(m);
lbool model_status = fixed_length_model_construction(assignments, precondition, free_variables, candidate_model, cex);

View file

@ -315,7 +315,7 @@ void theory_user_propagator::propagate_consequence(prop_info const& prop) {
if (m.is_false(prop.m_conseq)) {
js = ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(), m_lits.size(), m_lits.data(), m_eqs.size(), m_eqs.data(), 0, nullptr));
get_id(), ctx, m_lits.size(), m_lits.data(), m_eqs.size(), m_eqs.data(), 0, nullptr));
ctx.set_conflict(js);
}
else {

View file

@ -143,8 +143,8 @@ namespace smt {
char const* get_name() const override { return "user_propagate"; }
bool internalize_atom(app* atom, bool gate_ctx) override;
bool internalize_term(app* term) override;
void new_eq_eh(theory_var v1, theory_var v2) override { force_push(); if (m_eq_eh) m_eq_eh(m_user_context, this, var2expr(v1), var2expr(v2)); }
void new_diseq_eh(theory_var v1, theory_var v2) override { force_push(); if (m_diseq_eh) m_diseq_eh(m_user_context, this, var2expr(v1), var2expr(v2)); }
void new_eq_eh(theory_var v1, theory_var v2) override { if (m_eq_eh) force_push(), m_eq_eh(m_user_context, this, var2expr(v1), var2expr(v2)); }
void new_diseq_eh(theory_var v1, theory_var v2) override { if (m_diseq_eh) force_push(), m_diseq_eh(m_user_context, this, var2expr(v1), var2expr(v2)); }
bool use_diseqs() const override { return ((bool)m_diseq_eh); }
bool build_models() const override { return false; }
final_check_status final_check_eh() override;

View file

@ -204,12 +204,7 @@ namespace smt {
inc_conflicts();
literal_vector const& lits = m_nc_functor.get_lits();
IF_VERBOSE(20, ctx.display_literals_smt2(verbose_stream() << "conflict:\n", lits));
TRACE("utvpi", ctx.display_literals_smt2(tout << "conflict:\n", lits););
if (m_params.m_arith_dump_lemmas) {
symbol logic(m_lra ? (m_lia?"QF_LIRA":"QF_LRA") : "QF_LIA");
ctx.display_lemma_as_smt_problem(lits.size(), lits.data(), false_literal, logic);
}
TRACE("utvpi", ctx.display_literals_smt2(tout << "conflict:\n", lits););
vector<parameter> params;
if (m.proofs_enabled()) {
@ -222,7 +217,7 @@ namespace smt {
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(
get_id(), ctx.get_region(),
get_id(), ctx,
lits.size(), lits.data(), 0, nullptr, params.size(), params.data())));
m_nc_functor.reset();

View file

@ -283,7 +283,7 @@ namespace smt {
ctx.set_conflict(
ctx.mk_justification(
ext_theory_conflict_justification(get_id(), ctx.get_region(), lits.size(), lits.data(), 0, nullptr, 0, nullptr)));
ext_theory_conflict_justification(get_id(), ctx, lits.size(), lits.data(), 0, nullptr, 0, nullptr)));
}
bool theory_wmaxsat::max_unassigned_is_blocked() {
@ -328,10 +328,9 @@ namespace smt {
ctx.display_literals_verbose(tout, lits.size(), lits.data());
ctx.display_literal_verbose(tout << " --> ", lit););
region& r = ctx.get_region();
ctx.assign(lit, ctx.mk_justification(
ext_theory_propagation_justification(
get_id(), r, lits.size(), lits.data(), 0, nullptr, lit, 0, nullptr)));
get_id(), ctx, lits.size(), lits.data(), 0, nullptr, lit, 0, nullptr)));
}