mirror of
https://github.com/Z3Prover/z3
synced 2025-08-31 23:34:55 +00:00
Merge branch 'master' of http://github.com/z3prover/z3 into polysat
This commit is contained in:
commit
959f150e4a
104 changed files with 1666 additions and 1040 deletions
|
@ -2109,11 +2109,9 @@ namespace {
|
|||
for (; it2 != end2; ++it2) {
|
||||
enode * p2 = *it2;
|
||||
if (p2->get_decl() == f &&
|
||||
num_args == n->get_num_args() &&
|
||||
num_args == p2->get_num_args() &&
|
||||
m_context.is_relevant(p2) &&
|
||||
p2->is_cgr() &&
|
||||
i < num_args &&
|
||||
i < p2->get_num_args() &&
|
||||
p2->get_arg(i)->get_root() == p) {
|
||||
v->push_back(p2);
|
||||
}
|
||||
|
|
|
@ -27,21 +27,15 @@ enum class dyn_ack_strategy {
|
|||
};
|
||||
|
||||
struct dyn_ack_params {
|
||||
dyn_ack_strategy m_dack;
|
||||
bool m_dack_eq;
|
||||
double m_dack_factor;
|
||||
unsigned m_dack_threshold;
|
||||
unsigned m_dack_gc;
|
||||
double m_dack_gc_inv_decay;
|
||||
dyn_ack_strategy m_dack = dyn_ack_strategy::DACK_ROOT;
|
||||
bool m_dack_eq = false;
|
||||
double m_dack_factor = 0.1;
|
||||
unsigned m_dack_threshold = 10;
|
||||
unsigned m_dack_gc = 2000;
|
||||
double m_dack_gc_inv_decay = 0.8;
|
||||
|
||||
public:
|
||||
dyn_ack_params(params_ref const & p = params_ref()) :
|
||||
m_dack(dyn_ack_strategy::DACK_ROOT),
|
||||
m_dack_eq(false),
|
||||
m_dack_factor(0.1),
|
||||
m_dack_threshold(10),
|
||||
m_dack_gc(2000),
|
||||
m_dack_gc_inv_decay(0.8) {
|
||||
dyn_ack_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ def_module_params(module_name='smt',
|
|||
('arith.nl.delay', UINT, 500, 'number of calls to final check before invoking bounded nlsat check'),
|
||||
('arith.propagate_eqs', BOOL, True, 'propagate (cheap) equalities'),
|
||||
('arith.propagation_mode', UINT, 1, '0 - no propagation, 1 - propagate existing literals, 2 - refine finite bounds'),
|
||||
('arith.reflect', BOOL, True, 'reflect arithmetical operators to the congruence closure'),
|
||||
('arith.branch_cut_ratio', UINT, 2, 'branch/cut ratio for linear integer arithmetic'),
|
||||
('arith.int_eq_branch', BOOL, False, 'branching using derived integer equations'),
|
||||
('arith.ignore_int', BOOL, False, 'treat integer variables as real'),
|
||||
|
|
|
@ -35,7 +35,6 @@ void theory_arith_params::updt_params(params_ref const & _p) {
|
|||
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_reflect = p.arith_reflect();
|
||||
m_arith_eager_eq_axioms = p.arith_eager_eq_axioms();
|
||||
m_arith_auto_config_simplex = p.arith_auto_config_simplex();
|
||||
|
||||
|
|
|
@ -51,110 +51,64 @@ enum class arith_pivot_strategy {
|
|||
inline std::ostream& operator<<(std::ostream& out, arith_pivot_strategy st) { return out << (int)st; }
|
||||
|
||||
struct theory_arith_params {
|
||||
bool m_arith_eq2ineq;
|
||||
bool m_arith_process_all_eqs;
|
||||
arith_solver_id m_arith_mode;
|
||||
bool m_arith_auto_config_simplex; //!< force simplex solver in auto_config
|
||||
unsigned m_arith_blands_rule_threshold;
|
||||
bool m_arith_propagate_eqs;
|
||||
bound_prop_mode m_arith_bound_prop;
|
||||
bool m_arith_stronger_lemmas;
|
||||
bool m_arith_skip_rows_with_big_coeffs;
|
||||
unsigned m_arith_max_lemma_size;
|
||||
unsigned m_arith_small_lemma_size;
|
||||
bool m_arith_reflect;
|
||||
bool m_arith_ignore_int;
|
||||
unsigned m_arith_lazy_pivoting_lvl;
|
||||
unsigned m_arith_random_seed;
|
||||
bool m_arith_random_initial_value;
|
||||
int m_arith_random_lower;
|
||||
int m_arith_random_upper;
|
||||
bool m_arith_adaptive;
|
||||
double m_arith_adaptive_assertion_threshold;
|
||||
double m_arith_adaptive_propagation_threshold;
|
||||
bool m_arith_dump_lemmas;
|
||||
bool m_arith_eager_eq_axioms;
|
||||
unsigned m_arith_branch_cut_ratio;
|
||||
bool m_arith_int_eq_branching;
|
||||
bool m_arith_enum_const_mod;
|
||||
bool m_arith_eq2ineq = false;
|
||||
bool m_arith_process_all_eqs = false;
|
||||
arith_solver_id m_arith_mode = arith_solver_id::AS_NEW_ARITH;
|
||||
bool m_arith_auto_config_simplex = false; //!< force simplex solver in auto_config
|
||||
unsigned m_arith_blands_rule_threshold = 1000;
|
||||
bool m_arith_propagate_eqs = true;
|
||||
bound_prop_mode m_arith_bound_prop = bound_prop_mode::BP_REFINE;
|
||||
bool m_arith_stronger_lemmas = true;
|
||||
bool m_arith_skip_rows_with_big_coeffs = true;
|
||||
unsigned m_arith_max_lemma_size = 128;
|
||||
unsigned m_arith_small_lemma_size = 16;
|
||||
bool m_arith_reflect = true;
|
||||
bool m_arith_ignore_int = false;
|
||||
unsigned m_arith_lazy_pivoting_lvl = 0;
|
||||
unsigned m_arith_random_seed = 0;
|
||||
bool m_arith_random_initial_value = false;
|
||||
int m_arith_random_lower = -1000;
|
||||
int m_arith_random_upper = 1000;
|
||||
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;
|
||||
bool m_arith_enum_const_mod = false;
|
||||
|
||||
bool m_arith_gcd_test;
|
||||
bool m_arith_eager_gcd;
|
||||
bool m_arith_adaptive_gcd;
|
||||
unsigned m_arith_propagation_threshold;
|
||||
bool m_arith_gcd_test = true;
|
||||
bool m_arith_eager_gcd = false;
|
||||
bool m_arith_adaptive_gcd = false;
|
||||
unsigned m_arith_propagation_threshold = UINT_MAX;
|
||||
|
||||
arith_pivot_strategy m_arith_pivot_strategy;
|
||||
arith_pivot_strategy m_arith_pivot_strategy = arith_pivot_strategy::ARITH_PIVOT_SMALLEST;
|
||||
|
||||
// used in diff-logic
|
||||
bool m_arith_add_binary_bounds;
|
||||
arith_prop_strategy m_arith_propagation_strategy;
|
||||
bool m_arith_add_binary_bounds = false;
|
||||
arith_prop_strategy m_arith_propagation_strategy = arith_prop_strategy::ARITH_PROP_PROPORTIONAL;
|
||||
|
||||
// used arith_eq_adapter
|
||||
bool m_arith_eq_bounds;
|
||||
bool m_arith_lazy_adapter;
|
||||
bool m_arith_eq_bounds = false;
|
||||
bool m_arith_lazy_adapter = false;
|
||||
|
||||
// performance debugging flags
|
||||
bool m_arith_fixnum;
|
||||
bool m_arith_int_only;
|
||||
bool m_arith_fixnum = false;
|
||||
bool m_arith_int_only = false;
|
||||
|
||||
// non linear support
|
||||
bool m_nl_arith;
|
||||
bool m_nl_arith_gb;
|
||||
unsigned m_nl_arith_gb_threshold;
|
||||
bool m_nl_arith_gb_eqs;
|
||||
bool m_nl_arith_gb_perturbate;
|
||||
unsigned m_nl_arith_max_degree;
|
||||
bool m_nl_arith_branching;
|
||||
unsigned m_nl_arith_rounds;
|
||||
bool m_nl_arith = true;
|
||||
bool m_nl_arith_gb = true;
|
||||
unsigned m_nl_arith_gb_threshold = 512;
|
||||
bool m_nl_arith_gb_eqs = false;
|
||||
bool m_nl_arith_gb_perturbate = true;
|
||||
unsigned m_nl_arith_max_degree = 6;
|
||||
bool m_nl_arith_branching = true;
|
||||
unsigned m_nl_arith_rounds = 1024;
|
||||
|
||||
|
||||
|
||||
theory_arith_params(params_ref const & p = params_ref()):
|
||||
m_arith_eq2ineq(false),
|
||||
m_arith_process_all_eqs(false),
|
||||
m_arith_mode(arith_solver_id::AS_NEW_ARITH),
|
||||
m_arith_auto_config_simplex(false),
|
||||
m_arith_blands_rule_threshold(1000),
|
||||
m_arith_propagate_eqs(true),
|
||||
m_arith_bound_prop(bound_prop_mode::BP_REFINE),
|
||||
m_arith_stronger_lemmas(true),
|
||||
m_arith_skip_rows_with_big_coeffs(true),
|
||||
m_arith_max_lemma_size(128),
|
||||
m_arith_small_lemma_size(16),
|
||||
m_arith_reflect(true),
|
||||
m_arith_ignore_int(false),
|
||||
m_arith_lazy_pivoting_lvl(0),
|
||||
m_arith_random_seed(0),
|
||||
m_arith_random_initial_value(false),
|
||||
m_arith_random_lower(-1000),
|
||||
m_arith_random_upper(1000),
|
||||
m_arith_adaptive(false),
|
||||
m_arith_adaptive_assertion_threshold(0.2),
|
||||
m_arith_adaptive_propagation_threshold(0.4),
|
||||
m_arith_dump_lemmas(false),
|
||||
m_arith_eager_eq_axioms(true),
|
||||
m_arith_branch_cut_ratio(2),
|
||||
m_arith_int_eq_branching(false),
|
||||
m_arith_enum_const_mod(false),
|
||||
m_arith_gcd_test(true),
|
||||
m_arith_eager_gcd(false),
|
||||
m_arith_adaptive_gcd(false),
|
||||
m_arith_propagation_threshold(UINT_MAX),
|
||||
m_arith_pivot_strategy(arith_pivot_strategy::ARITH_PIVOT_SMALLEST),
|
||||
m_arith_add_binary_bounds(false),
|
||||
m_arith_propagation_strategy(arith_prop_strategy::ARITH_PROP_PROPORTIONAL),
|
||||
m_arith_eq_bounds(false),
|
||||
m_arith_lazy_adapter(false),
|
||||
m_arith_fixnum(false),
|
||||
m_arith_int_only(false),
|
||||
m_nl_arith(true),
|
||||
m_nl_arith_gb(true),
|
||||
m_nl_arith_gb_threshold(512),
|
||||
m_nl_arith_gb_eqs(false),
|
||||
m_nl_arith_gb_perturbate(true),
|
||||
m_nl_arith_max_degree(6),
|
||||
m_nl_arith_branching(true),
|
||||
m_nl_arith_rounds(1024) {
|
||||
theory_arith_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,34 +28,20 @@ enum array_solver_id {
|
|||
};
|
||||
|
||||
struct theory_array_params {
|
||||
bool m_array_canonize_simplify;
|
||||
bool m_array_simplify; // temporary hack for disabling array simplifier plugin.
|
||||
array_solver_id m_array_mode;
|
||||
bool m_array_weak;
|
||||
bool m_array_extensional;
|
||||
unsigned m_array_laziness;
|
||||
bool m_array_delay_exp_axiom;
|
||||
bool m_array_cg;
|
||||
bool m_array_always_prop_upward;
|
||||
bool m_array_lazy_ieq;
|
||||
unsigned m_array_lazy_ieq_delay;
|
||||
bool m_array_fake_support; // fake support for all array operations to pretend they are satisfiable.
|
||||
|
||||
theory_array_params():
|
||||
m_array_canonize_simplify(false),
|
||||
m_array_simplify(true),
|
||||
m_array_mode(array_solver_id::AR_FULL),
|
||||
m_array_weak(false),
|
||||
m_array_extensional(true),
|
||||
m_array_laziness(1),
|
||||
m_array_delay_exp_axiom(true),
|
||||
m_array_cg(false),
|
||||
m_array_always_prop_upward(true), // UPWARDs filter is broken... TODO: fix it
|
||||
m_array_lazy_ieq(false),
|
||||
m_array_lazy_ieq_delay(10),
|
||||
m_array_fake_support(false) {
|
||||
}
|
||||
bool m_array_canonize_simplify = false;
|
||||
bool m_array_simplify = true; // temporary hack for disabling array simplifier plugin.
|
||||
array_solver_id m_array_mode = array_solver_id::AR_FULL;
|
||||
bool m_array_weak = false;
|
||||
bool m_array_extensional = true;
|
||||
unsigned m_array_laziness = 1;
|
||||
bool m_array_delay_exp_axiom = true;
|
||||
bool m_array_cg = false;
|
||||
bool m_array_always_prop_upward = true;
|
||||
bool m_array_lazy_ieq = false;
|
||||
unsigned m_array_lazy_ieq_delay = 10;
|
||||
bool m_array_fake_support = false; // fake support for all array operations to pretend they are satisfiable.
|
||||
|
||||
theory_array_params() {}
|
||||
|
||||
void updt_params(params_ref const & _p);
|
||||
|
||||
|
|
|
@ -26,27 +26,17 @@ enum bv_solver_id {
|
|||
};
|
||||
|
||||
struct theory_bv_params {
|
||||
bv_solver_id m_bv_mode;
|
||||
bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted.
|
||||
bool m_bv_reflect;
|
||||
bool m_bv_lazy_le;
|
||||
bool m_bv_cc;
|
||||
bool m_bv_eq_axioms;
|
||||
unsigned m_bv_blast_max_size;
|
||||
bool m_bv_enable_int2bv2int;
|
||||
bool m_bv_watch_diseq;
|
||||
bool m_bv_delay;
|
||||
theory_bv_params(params_ref const & p = params_ref()):
|
||||
m_bv_mode(bv_solver_id::BS_BLASTER),
|
||||
m_hi_div0(false),
|
||||
m_bv_reflect(true),
|
||||
m_bv_lazy_le(false),
|
||||
m_bv_cc(false),
|
||||
m_bv_eq_axioms(true),
|
||||
m_bv_blast_max_size(INT_MAX),
|
||||
m_bv_enable_int2bv2int(true),
|
||||
m_bv_watch_diseq(false),
|
||||
m_bv_delay(true) {
|
||||
bv_solver_id m_bv_mode = bv_solver_id::BS_BLASTER;
|
||||
bool m_hi_div0 = false; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted.
|
||||
bool m_bv_reflect = true;
|
||||
bool m_bv_lazy_le = false;
|
||||
bool m_bv_cc = false;
|
||||
bool m_bv_eq_axioms = true;
|
||||
unsigned m_bv_blast_max_size = INT_MAX;
|
||||
bool m_bv_enable_int2bv2int = true;
|
||||
bool m_bv_watch_diseq = false;
|
||||
bool m_bv_delay = true;
|
||||
theory_bv_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,11 @@ Revision History:
|
|||
|
||||
|
||||
struct theory_pb_params {
|
||||
unsigned m_pb_conflict_frequency;
|
||||
bool m_pb_learn_complements;
|
||||
theory_pb_params(params_ref const & p = params_ref()):
|
||||
m_pb_conflict_frequency(1000),
|
||||
m_pb_learn_complements(true)
|
||||
{}
|
||||
unsigned m_pb_conflict_frequency = 1000;
|
||||
bool m_pb_learn_complements = true;
|
||||
theory_pb_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p);
|
||||
|
||||
|
|
|
@ -22,14 +22,10 @@ struct theory_seq_params {
|
|||
/*
|
||||
* Enable splitting guided by length constraints
|
||||
*/
|
||||
bool m_split_w_len;
|
||||
bool m_seq_validate;
|
||||
bool m_split_w_len = false;
|
||||
bool m_seq_validate = false;
|
||||
|
||||
|
||||
theory_seq_params(params_ref const & p = params_ref()):
|
||||
m_split_w_len(false),
|
||||
m_seq_validate(false)
|
||||
{
|
||||
theory_seq_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,108 +27,92 @@ struct theory_str_params {
|
|||
* This is a stronger version of the standard axiom.
|
||||
* The Z3str2 axioms can be simulated by setting this to false.
|
||||
*/
|
||||
bool m_StrongArrangements;
|
||||
bool m_StrongArrangements = true;
|
||||
|
||||
/*
|
||||
* If AggressiveLengthTesting is true, we manipulate the phase of length tester equalities
|
||||
* to prioritize trying concrete length options over choosing the "more" option.
|
||||
*/
|
||||
bool m_AggressiveLengthTesting;
|
||||
bool m_AggressiveLengthTesting = false;
|
||||
|
||||
/*
|
||||
* Similarly, if AggressiveValueTesting is true, we manipulate the phase of value tester equalities
|
||||
* to prioritize trying concrete value options over choosing the "more" option.
|
||||
*/
|
||||
bool m_AggressiveValueTesting;
|
||||
bool m_AggressiveValueTesting = false;
|
||||
|
||||
/*
|
||||
* If AggressiveUnrollTesting is true, we manipulate the phase of regex unroll tester equalities
|
||||
* to prioritize trying concrete unroll counts over choosing the "more" option.
|
||||
*/
|
||||
bool m_AggressiveUnrollTesting;
|
||||
bool m_AggressiveUnrollTesting = true;
|
||||
|
||||
/*
|
||||
* If UseFastLengthTesterCache is set to true,
|
||||
* length tester terms will not be generated from scratch each time they are needed,
|
||||
* but will be saved in a map and looked up.
|
||||
*/
|
||||
bool m_UseFastLengthTesterCache;
|
||||
bool m_UseFastLengthTesterCache = false;
|
||||
|
||||
/*
|
||||
* If UseFastValueTesterCache is set to true,
|
||||
* value tester terms will not be generated from scratch each time they are needed,
|
||||
* but will be saved in a map and looked up.
|
||||
*/
|
||||
bool m_UseFastValueTesterCache;
|
||||
bool m_UseFastValueTesterCache = true;
|
||||
|
||||
/*
|
||||
* If StringConstantCache is set to true,
|
||||
* all string constants in theory_str generated from anywhere will be cached and saved.
|
||||
*/
|
||||
bool m_StringConstantCache;
|
||||
bool m_StringConstantCache = true;
|
||||
|
||||
double m_OverlapTheoryAwarePriority;
|
||||
double m_OverlapTheoryAwarePriority = -0.1;
|
||||
|
||||
/*
|
||||
* RegexAutomata_DifficultyThreshold is the lowest difficulty above which Z3str3
|
||||
* will not eagerly construct an automaton for a regular expression term.
|
||||
*/
|
||||
unsigned m_RegexAutomata_DifficultyThreshold;
|
||||
unsigned m_RegexAutomata_DifficultyThreshold = 1000;
|
||||
|
||||
/*
|
||||
* RegexAutomata_IntersectionDifficultyThreshold is the lowest difficulty above which Z3str3
|
||||
* will not eagerly intersect automata to check unsatisfiability.
|
||||
*/
|
||||
unsigned m_RegexAutomata_IntersectionDifficultyThreshold;
|
||||
unsigned m_RegexAutomata_IntersectionDifficultyThreshold = 1000;
|
||||
|
||||
/*
|
||||
* RegexAutomata_FailedAutomatonThreshold is the number of failed attempts to build an automaton
|
||||
* after which a full automaton (i.e. with no length information) will be built regardless of difficulty.
|
||||
*/
|
||||
unsigned m_RegexAutomata_FailedAutomatonThreshold;
|
||||
unsigned m_RegexAutomata_FailedAutomatonThreshold = 10;
|
||||
|
||||
/*
|
||||
* RegexAutomaton_FailedIntersectionThreshold is the number of failed attempts to perform automaton
|
||||
* intersection after which intersection will always be performed regardless of difficulty.
|
||||
*/
|
||||
unsigned m_RegexAutomata_FailedIntersectionThreshold;
|
||||
unsigned m_RegexAutomata_FailedIntersectionThreshold = 10;
|
||||
|
||||
/*
|
||||
* RegexAutomaton_LengthAttemptThreshold is the number of attempts to satisfy length/path constraints
|
||||
* before which we begin checking unsatisfiability of a regex term.
|
||||
*/
|
||||
unsigned m_RegexAutomata_LengthAttemptThreshold;
|
||||
unsigned m_RegexAutomata_LengthAttemptThreshold = 10;
|
||||
/*
|
||||
* If FixedLengthRefinement is true and the fixed-length equation solver is enabled,
|
||||
* Z3str3 will use abstraction refinement to handle formulas that would result in disjunctions or expensive
|
||||
* reductions to fixed-length formulas.
|
||||
*/
|
||||
bool m_FixedLengthRefinement;
|
||||
bool m_FixedLengthRefinement = false;
|
||||
|
||||
/*
|
||||
* If FixedLengthNaiveCounterexamples is true and the fixed-length equation solver is enabled,
|
||||
* Z3str3 will only construct simple counterexamples to block unsatisfiable length assignments
|
||||
* instead of attempting to learn more complex lessons.
|
||||
*/
|
||||
bool m_FixedLengthNaiveCounterexamples;
|
||||
bool m_FixedLengthNaiveCounterexamples = true;
|
||||
|
||||
theory_str_params(params_ref const & p = params_ref()):
|
||||
m_StrongArrangements(true),
|
||||
m_AggressiveLengthTesting(false),
|
||||
m_AggressiveValueTesting(false),
|
||||
m_AggressiveUnrollTesting(true),
|
||||
m_UseFastLengthTesterCache(false),
|
||||
m_UseFastValueTesterCache(true),
|
||||
m_StringConstantCache(true),
|
||||
m_OverlapTheoryAwarePriority(-0.1),
|
||||
m_RegexAutomata_DifficultyThreshold(1000),
|
||||
m_RegexAutomata_IntersectionDifficultyThreshold(1000),
|
||||
m_RegexAutomata_FailedAutomatonThreshold(10),
|
||||
m_RegexAutomata_FailedIntersectionThreshold(10),
|
||||
m_RegexAutomata_LengthAttemptThreshold(10),
|
||||
m_FixedLengthRefinement(false),
|
||||
m_FixedLengthNaiveCounterexamples(true)
|
||||
{
|
||||
theory_str_params(params_ref const & p = params_ref()) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ namespace smt {
|
|||
case l_true:
|
||||
if (!m_proto_model->eval(n, res, false))
|
||||
return true;
|
||||
CTRACE("model", !m.is_true(res), tout << n << " evaluates to " << res << "\n";);
|
||||
CTRACE("model", !m.is_true(res), tout << n << " evaluates to " << res << "\n" << *m_proto_model << "\n";);
|
||||
if (m.is_false(res)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ namespace smt {
|
|||
case l_false:
|
||||
if (!m_proto_model->eval(n, res, false))
|
||||
return true;
|
||||
CTRACE("model", !m.is_false(res), tout << n << " evaluates to " << res << "\n";);
|
||||
CTRACE("model", !m.is_false(res), tout << n << " evaluates to " << res << "\n" << *m_proto_model << "\n";);
|
||||
if (m.is_true(res)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -389,19 +389,7 @@ namespace smt {
|
|||
if (q) {
|
||||
// the variables in q are maybe not consecutive.
|
||||
var_subst sub(m, false);
|
||||
expr_free_vars fv;
|
||||
fv(q);
|
||||
expr_ref_vector es(m);
|
||||
es.resize(fv.size());
|
||||
for (unsigned i = 0, j = 0; i < e->get_num_args(); ++i) {
|
||||
SASSERT(j < es.size());
|
||||
while (!fv[j]) {
|
||||
++j;
|
||||
SASSERT(j < es.size());
|
||||
}
|
||||
es[j++] = e->get_arg(i);
|
||||
}
|
||||
f = sub(q, es.size(), es.data());
|
||||
f = sub(q, e->get_num_args(), e->get_args());
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ Author:
|
|||
--*/
|
||||
|
||||
#include "ast/ast_ll_pp.h"
|
||||
#include "ast/bv_decl_plugin.h"
|
||||
#include "smt/theory_char.h"
|
||||
#include "smt/smt_context.h"
|
||||
#include "smt/smt_model_generator.h"
|
||||
|
@ -84,6 +85,11 @@ namespace smt {
|
|||
expr* n = nullptr;
|
||||
if (seq.is_char2int(term, n))
|
||||
new_char2int(v, n);
|
||||
else if (seq.is_char2bv(term, n))
|
||||
new_char2bv(term, n);
|
||||
else if (seq.is_bv2char(term, n))
|
||||
new_bv2char(v, n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -265,6 +271,34 @@ namespace smt {
|
|||
ctx.assign_eq(n1, n2, eq_justification(j));
|
||||
}
|
||||
|
||||
void theory_char::new_char2bv(expr* b, expr* c) {
|
||||
theory_var w = ctx.get_enode(c)->get_th_var(get_id());
|
||||
init_bits(w);
|
||||
auto const& bits = get_bits(w);
|
||||
bv_util bv(m);
|
||||
SASSERT(bits.size() == bv.get_bv_size(b));
|
||||
unsigned i = 0;
|
||||
for (auto bit1 : bits) {
|
||||
auto bit2 = mk_literal(bv.mk_bit2bool(b, i++));
|
||||
ctx.mk_th_axiom(get_id(), ~bit1, bit2);
|
||||
ctx.mk_th_axiom(get_id(), bit1, ~bit2);
|
||||
}
|
||||
}
|
||||
|
||||
void theory_char::new_bv2char(theory_var v, expr* b) {
|
||||
init_bits(v);
|
||||
auto const& bits = get_bits(v);
|
||||
bv_util bv(m);
|
||||
SASSERT(bits.size() == bv.get_bv_size(b));
|
||||
unsigned i = 0;
|
||||
for (auto bit1 : bits) {
|
||||
auto bit2 = mk_literal(bv.mk_bit2bool(b, i++));
|
||||
ctx.mk_th_axiom(get_id(), ~bit1, bit2);
|
||||
ctx.mk_th_axiom(get_id(), bit1, ~bit2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 1. Check that values of classes are unique.
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace smt {
|
|||
bool final_check();
|
||||
void new_const_char(theory_var v, unsigned c);
|
||||
void new_char2int(theory_var v, expr* c);
|
||||
void new_bv2char(theory_var v, expr* b);
|
||||
void new_char2bv(expr* n, expr* c);
|
||||
unsigned get_char_value(theory_var v);
|
||||
void internalize_le(literal lit, app* term);
|
||||
void internalize_is_digit(literal lit, app* term);
|
||||
|
|
|
@ -807,10 +807,10 @@ class theory_lra::imp {
|
|||
return st.vars()[0];
|
||||
}
|
||||
else if (is_one(st) && a.is_numeral(term)) {
|
||||
return get_one(a.is_int(term));
|
||||
return lp().local_to_external(get_one(a.is_int(term)));
|
||||
}
|
||||
else if (is_zero(st) && a.is_numeral(term)) {
|
||||
return get_zero(a.is_int(term));
|
||||
return lp().local_to_external(get_zero(a.is_int(term)));
|
||||
}
|
||||
else {
|
||||
init_left_side(st);
|
||||
|
|
|
@ -52,6 +52,8 @@ void user_propagator::propagate_cb(
|
|||
unsigned num_fixed, unsigned const* fixed_ids,
|
||||
unsigned num_eqs, unsigned const* eq_lhs, unsigned const* eq_rhs,
|
||||
expr* conseq) {
|
||||
if (ctx.lit_internalized(conseq) && ctx.get_assignment(ctx.get_literal(conseq)) == l_true)
|
||||
return;
|
||||
m_prop.push_back(prop_info(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, expr_ref(conseq, m)));
|
||||
}
|
||||
|
||||
|
@ -125,7 +127,10 @@ void user_propagator::propagate() {
|
|||
for (auto const& p : prop.m_eqs)
|
||||
m_eqs.push_back(enode_pair(get_enode(p.first), get_enode(p.second)));
|
||||
DEBUG_CODE(for (auto const& p : m_eqs) VERIFY(p.first->get_root() == p.second->get_root()););
|
||||
DEBUG_CODE(for (unsigned id : prop.m_ids) VERIFY(m_fixed.contains(id)););
|
||||
DEBUG_CODE(for (literal lit : m_lits) VERIFY(ctx.get_assignment(lit) == l_true););
|
||||
|
||||
|
||||
if (m.is_false(prop.m_conseq)) {
|
||||
js = ctx.mk_justification(
|
||||
ext_theory_conflict_justification(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue