mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 11:25:51 +00:00
na (#4254)
* remove level of indirection for context and ast_manager in smt_theory Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * add request by #4252 Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * move to def Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * int Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fix #4251 Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fix #4255 * fix #4257 * add code to debug #4246 * restore new solver as default * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fix #4246 Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
becf423c77
commit
fdc87f286f
18 changed files with 269 additions and 231 deletions
|
@ -91,12 +91,11 @@ void basics::basic_sign_lemma_model_based_one_mon(const monic& m, int product_si
|
|||
TRACE("nla_solver_bl", tout << "zero product sign: " << pp_mon(_(), m)<< "\n"; );
|
||||
generate_zero_lemmas(m);
|
||||
} else {
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
for(lpvar j: m.vars()) {
|
||||
negate_strict_sign(j);
|
||||
}
|
||||
c().mk_ineq(m.var(), product_sign == 1? llc::GT : llc::LT);
|
||||
TRACE("nla_solver", c().print_lemma(tout); tout << "\n";);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +157,7 @@ bool basics::basic_sign_lemma(bool derived) {
|
|||
// the value of the i-th monic has to be equal to the value of the k-th monic modulo sign
|
||||
// but it is not the case in the model
|
||||
void basics::generate_sign_lemma(const monic& m, const monic& n, const rational& sign) {
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
TRACE("nla_solver",
|
||||
tout << "m = " << pp_mon_with_vars(_(), m);
|
||||
tout << "n = " << pp_mon_with_vars(_(), n);
|
||||
|
@ -168,12 +167,11 @@ void basics::generate_sign_lemma(const monic& m, const monic& n, const rational&
|
|||
TRACE("nla_solver", tout << "m exp = "; _().print_explanation(_().current_expl(), tout););
|
||||
explain(n);
|
||||
TRACE("nla_solver", tout << "n exp = "; _().print_explanation(_().current_expl(), tout););
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
}
|
||||
// try to find a variable j such that val(j) = 0
|
||||
// and the bounds on j contain 0 as an inner point
|
||||
lpvar basics::find_best_zero(const monic& m, unsigned_vector & fixed_zeros) const {
|
||||
lpvar zero_j = -1;
|
||||
lpvar zero_j = null_lpvar;
|
||||
for (unsigned j : m.vars()){
|
||||
if (val(j).is_zero()){
|
||||
if (c().var_is_fixed_to_zero(j))
|
||||
|
@ -186,15 +184,14 @@ lpvar basics::find_best_zero(const monic& m, unsigned_vector & fixed_zeros) cons
|
|||
return zero_j;
|
||||
}
|
||||
void basics::add_trival_zero_lemma(lpvar zero_j, const monic& m) {
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
c().mk_ineq(zero_j, llc::NE);
|
||||
c().mk_ineq(m.var(), llc::EQ);
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
}
|
||||
void basics::generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, int sign_of_zj) {
|
||||
TRACE("nla_solver_bl", tout << "sign_of_zj = " << sign_of_zj << "\n";);
|
||||
// we know all the signs
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
c().mk_ineq(zero_j, (sign_of_zj == 1? llc::GT : llc::LT));
|
||||
for (unsigned j : m.vars()){
|
||||
if (j != zero_j) {
|
||||
|
@ -202,13 +199,11 @@ void basics::generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, in
|
|||
}
|
||||
}
|
||||
negate_strict_sign(m.var());
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
}
|
||||
void basics::add_fixed_zero_lemma(const monic& m, lpvar j) {
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
c().explain_fixed_var(j);
|
||||
c().mk_ineq(m.var(), llc::EQ);
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
}
|
||||
void basics::negate_strict_sign(lpvar j) {
|
||||
TRACE("nla_solver_details", tout << pp_var(c(), j) << "\n";);
|
||||
|
@ -234,7 +229,7 @@ bool basics::basic_lemma_for_mon_zero(const monic& rm, const factorization& f) {
|
|||
return true;
|
||||
#if 0
|
||||
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
c().explain_fixed_var(var(rm));
|
||||
std::unordered_set<lpvar> processed;
|
||||
for (auto j : f) {
|
||||
|
@ -242,7 +237,6 @@ bool basics::basic_lemma_for_mon_zero(const monic& rm, const factorization& f) {
|
|||
c().mk_ineq(var(j), llc::EQ);
|
||||
}
|
||||
explain(rm);
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -304,7 +298,7 @@ bool basics::basic_lemma_for_mon_non_zero_derived(const monic& rm, const factori
|
|||
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
|
||||
if (! c().var_is_separated_from_zero(var(rm)))
|
||||
return false;
|
||||
int zero_j = -1;
|
||||
lpvar zero_j = null_lpvar;
|
||||
for (auto j : f) {
|
||||
if ( c().var_is_fixed_to_zero(var(j))) {
|
||||
zero_j = var(j);
|
||||
|
@ -312,14 +306,13 @@ bool basics::basic_lemma_for_mon_non_zero_derived(const monic& rm, const factori
|
|||
}
|
||||
}
|
||||
|
||||
if (zero_j == -1) {
|
||||
if (zero_j == null_lpvar) {
|
||||
return false;
|
||||
}
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
c().explain_fixed_var(zero_j);
|
||||
c().explain_var_separated_from_zero(var(rm));
|
||||
explain(rm);
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
return true;
|
||||
}
|
||||
// use the fact that
|
||||
|
@ -337,7 +330,7 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm
|
|||
return false;
|
||||
}
|
||||
bool mon_var_is_sep_from_zero = c().var_is_separated_from_zero(mon_var);
|
||||
lpvar jl = -1;
|
||||
lpvar jl = null_lpvar;
|
||||
for (auto fc : f ) {
|
||||
lpvar j = var(fc);
|
||||
if (abs(val(j)) == abs_mv && c().vars_are_equiv(j, mon_var) &&
|
||||
|
@ -346,10 +339,10 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (jl == static_cast<lpvar>(-1))
|
||||
if (jl == null_lpvar)
|
||||
return false;
|
||||
|
||||
lpvar not_one_j = -1;
|
||||
lpvar not_one_j = null_lpvar;
|
||||
for (auto j : f ) {
|
||||
if (var(j) == jl) {
|
||||
continue;
|
||||
|
@ -360,11 +353,11 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm
|
|||
}
|
||||
}
|
||||
|
||||
if (not_one_j == static_cast<lpvar>(-1)) {
|
||||
if (not_one_j == null_lpvar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
// mon_var = 0
|
||||
if (mon_var_is_sep_from_zero)
|
||||
c().explain_var_separated_from_zero(mon_var);
|
||||
|
@ -379,7 +372,6 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm
|
|||
// not_one_j = -1
|
||||
c().mk_ineq(not_one_j, llc::EQ, -rational(1));
|
||||
explain(rm);
|
||||
TRACE("nla_solver", c().print_lemma(tout); );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -426,7 +418,7 @@ bool basics::proportion_lemma_derived(const monic& rm, const factorization& fact
|
|||
}
|
||||
// if there are no zero factors then |m| >= |m[factor_index]|
|
||||
void basics::generate_pl_on_mon(const monic& m, unsigned factor_index) {
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
unsigned mon_var = m.var();
|
||||
rational mv = val(mon_var);
|
||||
rational sm = rational(nla::rat_sign(mv));
|
||||
|
@ -443,7 +435,6 @@ void basics::generate_pl_on_mon(const monic& m, unsigned factor_index) {
|
|||
c().mk_ineq(sm, mon_var, -sj, j, llc::GE );
|
||||
}
|
||||
}
|
||||
TRACE("nla_solver", c().print_lemma(tout); );
|
||||
}
|
||||
|
||||
// none of the factors is zero and the product is not zero
|
||||
|
@ -451,13 +442,13 @@ void basics::generate_pl_on_mon(const monic& m, unsigned factor_index) {
|
|||
void basics::generate_pl(const monic& m, const factorization& fc, int factor_index) {
|
||||
TRACE("nla_solver", tout << "factor_index = " << factor_index << ", m = "
|
||||
<< pp_mon(c(), m);
|
||||
tout << ", fc = "; c().print_factorization(fc, tout);
|
||||
tout << ", fc = " << c().pp(fc);
|
||||
tout << "orig mon = "; c().print_monic(c().emons()[m.var()], tout););
|
||||
if (fc.is_mon()) {
|
||||
generate_pl_on_mon(m, factor_index);
|
||||
return;
|
||||
}
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
int fi = 0;
|
||||
rational mv = var_val(m);
|
||||
rational sm = rational(nla::rat_sign(mv));
|
||||
|
@ -479,7 +470,6 @@ void basics::generate_pl(const monic& m, const factorization& fc, int factor_ind
|
|||
explain(fc);
|
||||
explain(m);
|
||||
}
|
||||
TRACE("nla_solver", c().print_lemma(tout); );
|
||||
}
|
||||
|
||||
bool basics::is_separated_from_zero(const factorization& f) const {
|
||||
|
@ -506,7 +496,7 @@ bool basics::factorization_has_real(const factorization& f) const {
|
|||
void basics::basic_lemma_for_mon_zero_model_based(const monic& rm, const factorization& f) {
|
||||
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
|
||||
SASSERT(var_val(rm).is_zero()&& ! c().rm_check(rm));
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
if (!is_separated_from_zero(f)) {
|
||||
c().mk_ineq(var(rm), llc::NE);
|
||||
for (auto j : f) {
|
||||
|
@ -519,7 +509,6 @@ void basics::basic_lemma_for_mon_zero_model_based(const monic& rm, const factori
|
|||
}
|
||||
}
|
||||
explain(f);
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
}
|
||||
|
||||
void basics::basic_lemma_for_mon_model_based(const monic& rm) {
|
||||
|
@ -553,16 +542,16 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const mo
|
|||
if (abs_mv == rational::zero()) {
|
||||
return false;
|
||||
}
|
||||
lpvar jl = -1;
|
||||
lpvar jl = null_lpvar;
|
||||
for (auto j : m.vars() ) {
|
||||
if (abs(val(j)) == abs_mv) {
|
||||
jl = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jl == static_cast<lpvar>(-1))
|
||||
if (jl == null_lpvar)
|
||||
return false;
|
||||
lpvar not_one_j = -1;
|
||||
lpvar not_one_j = null_lpvar;
|
||||
for (auto j : m.vars() ) {
|
||||
if (j == jl) {
|
||||
continue;
|
||||
|
@ -573,11 +562,11 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const mo
|
|||
}
|
||||
}
|
||||
|
||||
if (not_one_j == static_cast<lpvar>(-1)) {
|
||||
if (not_one_j == null_lpvar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
// mon_var = 0
|
||||
c().mk_ineq(mon_var, llc::EQ);
|
||||
|
||||
|
@ -592,13 +581,13 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const mo
|
|||
|
||||
// not_one_j = -1
|
||||
c().mk_ineq(not_one_j, llc::EQ, -rational(1));
|
||||
TRACE("nla_solver", c().print_lemma(tout); );
|
||||
return true;
|
||||
}
|
||||
|
||||
// use the fact
|
||||
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
|
||||
bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(const monic& m) {
|
||||
lpvar not_one = -1;
|
||||
lpvar not_one = null_lpvar;
|
||||
rational sign(1);
|
||||
TRACE("nla_solver_bl", tout << "m = "; c().print_monic(m, tout););
|
||||
for (auto j : m.vars()){
|
||||
|
@ -610,7 +599,7 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(co
|
|||
sign = - sign;
|
||||
continue;
|
||||
}
|
||||
if (not_one == static_cast<lpvar>(-1)) {
|
||||
if (not_one == null_lpvar) {
|
||||
not_one = j;
|
||||
continue;
|
||||
}
|
||||
|
@ -618,25 +607,24 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(co
|
|||
return false;
|
||||
}
|
||||
|
||||
if (not_one + 1) { // we found the only not_one
|
||||
if (not_one != null_lpvar) { // we found the only not_one
|
||||
if (var_val(m) == val(not_one) * sign) {
|
||||
TRACE("nla_solver", tout << "the whole equal to the factor" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
add_lemma();
|
||||
|
||||
new_lemma lemma(c());
|
||||
for (auto j : m.vars()){
|
||||
if (not_one == j) continue;
|
||||
c().mk_ineq(j, llc::NE, val(j));
|
||||
}
|
||||
|
||||
if (not_one == static_cast<lpvar>(-1)) {
|
||||
if (not_one == null_lpvar) {
|
||||
c().mk_ineq(m.var(), llc::EQ, sign);
|
||||
} else {
|
||||
c().mk_ineq(m.var(), -sign, not_one, llc::EQ);
|
||||
}
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -654,16 +642,16 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic
|
|||
if (abs_mv == rational::zero()) {
|
||||
return false;
|
||||
}
|
||||
lpvar jl = -1;
|
||||
lpvar jl = null_lpvar;
|
||||
for (auto j : f ) {
|
||||
if (abs(val(j)) == abs_mv) {
|
||||
jl = var(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jl == static_cast<lpvar>(-1))
|
||||
if (jl == null_lpvar)
|
||||
return false;
|
||||
lpvar not_one_j = -1;
|
||||
lpvar not_one_j = null_lpvar;
|
||||
for (auto j : f ) {
|
||||
if (var(j) == jl) {
|
||||
continue;
|
||||
|
@ -674,11 +662,11 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic
|
|||
}
|
||||
}
|
||||
|
||||
if (not_one_j == static_cast<lpvar>(-1)) {
|
||||
if (not_one_j == null_lpvar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
// mon_var = 0
|
||||
c().mk_ineq(mon_var, llc::EQ);
|
||||
|
||||
|
@ -696,7 +684,6 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic
|
|||
explain(rm);
|
||||
explain(f);
|
||||
|
||||
TRACE("nla_solver", c().print_lemma(tout); );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -710,14 +697,26 @@ void basics::basic_lemma_for_mon_neutral_model_based(const monic& rm, const fact
|
|||
basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(rm, f);
|
||||
}
|
||||
}
|
||||
// use the fact
|
||||
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
|
||||
|
||||
/**
|
||||
|
||||
- m := f1*f2*..
|
||||
- f_i are factors of m
|
||||
- at most one variable among f_i evaluates to something else than -1, +1.
|
||||
- m = sign * f_i
|
||||
- sign = sign of f_1 * .. * f_{i-1} * f_{i+1} ... = +/- 1
|
||||
- lemma:
|
||||
/\_{j != i} f_j = val(f_j) => m = sign * f_i
|
||||
or
|
||||
/\ f_j = val(f_j) => m = sign if all factors evaluate to +/- 1
|
||||
|
||||
*/
|
||||
bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const monic& m, const factorization& f) {
|
||||
rational sign = sign_to_rat(m.rsign());
|
||||
rational sign(1);
|
||||
SASSERT(m.rsign() == canonize_sign(f));
|
||||
TRACE("nla_solver_bl", tout << pp_mon_with_vars(_(), m) <<"\nf = "; c().print_factorization(f, tout); tout << "sign = " << sign << '\n'; );
|
||||
lpvar not_one = -1;
|
||||
for (auto j : f){
|
||||
TRACE("nla_solver_bl", tout << pp_mon_with_vars(_(), m) <<"\nf = " << c().pp(f) << "sign = " << sign << '\n'; );
|
||||
lpvar not_one = null_lpvar;
|
||||
for (auto j : f) {
|
||||
TRACE("nla_solver_bl", tout << "j = "; c().print_factor_with_vars(j, tout););
|
||||
auto v = val(j);
|
||||
if (v == rational(1)) {
|
||||
|
@ -729,7 +728,7 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const
|
|||
continue;
|
||||
}
|
||||
|
||||
if (not_one == static_cast<lpvar>(-1)) {
|
||||
if (not_one == null_lpvar) {
|
||||
not_one = var(j);
|
||||
continue;
|
||||
}
|
||||
|
@ -738,48 +737,41 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (not_one + 1) {
|
||||
// we found the only not_one
|
||||
if (var_val(m) == val(not_one) * sign) {
|
||||
TRACE("nla_solver", tout << "the whole is equal to the factor" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (not_one == null_lpvar && var_val(m) == sign) {
|
||||
// we have +-ones only in the factorization
|
||||
if (var_val(m) == sign) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (not_one != null_lpvar && var_val(m) == val(not_one) * sign) {
|
||||
TRACE("nla_solver", tout << "the whole is equal to the factor" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
|
||||
TRACE("nla_solver_bl", tout << "not_one = " << not_one << "\n";);
|
||||
|
||||
add_lemma();
|
||||
new_lemma lemma(c());
|
||||
|
||||
for (auto j : f){
|
||||
for (auto j : f) {
|
||||
lpvar var_j = var(j);
|
||||
if (not_one == var_j) continue;
|
||||
TRACE("nla_solver_bl", tout << "j = "; c().print_factor_with_vars(j, tout););
|
||||
c().mk_ineq(var_j, llc::NE, val(var_j));
|
||||
}
|
||||
|
||||
if (not_one == static_cast<lpvar>(-1)) {
|
||||
if (not_one == null_lpvar) {
|
||||
c().mk_ineq(m.var(), llc::EQ, sign);
|
||||
} else {
|
||||
c().mk_ineq(m.var(), -sign, not_one, llc::EQ);
|
||||
}
|
||||
explain(m);
|
||||
explain(f);
|
||||
TRACE("nla_solver",
|
||||
c().print_lemma(tout);
|
||||
tout << "m = " << pp_mon_with_vars(c(), m);
|
||||
);
|
||||
TRACE("nla_solver", tout << "m = " << pp_mon_with_vars(c(), m););
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void basics::basic_lemma_for_mon_non_zero_model_based_mf(const factorization& f) {
|
||||
TRACE("nla_solver_bl", c().print_factorization(f, tout););
|
||||
int zero_j = -1;
|
||||
TRACE("nla_solver_bl", tout << c().pp(f););
|
||||
lpvar zero_j = null_lpvar;
|
||||
for (auto j : f) {
|
||||
if (val(j).is_zero()) {
|
||||
zero_j = var(j);
|
||||
|
@ -787,11 +779,10 @@ void basics::basic_lemma_for_mon_non_zero_model_based_mf(const factorization& f)
|
|||
}
|
||||
}
|
||||
|
||||
if (zero_j == -1) { return; }
|
||||
add_lemma();
|
||||
if (zero_j == null_lpvar) { return; }
|
||||
new_lemma lemma(c());
|
||||
c().mk_ineq(zero_j, llc::NE);
|
||||
c().mk_ineq(f.mon().var(), llc::EQ);
|
||||
TRACE("nla_solver", c().print_lemma(tout););
|
||||
}
|
||||
|
||||
// x = 0 or y = 0 -> xy = 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue