mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
fixes
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
6c72f39142
commit
d774ba9da1
|
@ -46,7 +46,7 @@ void basics::generate_zero_lemmas(const monic& m) {
|
||||||
}
|
}
|
||||||
TRACE("nla_solver_details", tout << "zero_j = " << zero_j << ", sign = " << sign << "\n";);
|
TRACE("nla_solver_details", tout << "zero_j = " << zero_j << ", sign = " << sign << "\n";);
|
||||||
if (sign == 0) { // have to generate a non-convex lemma
|
if (sign == 0) { // have to generate a non-convex lemma
|
||||||
add_trival_zero_lemma(zero_j, m);
|
add_trivial_zero_lemma(zero_j, m);
|
||||||
} else { // here we know the sign of zero_j
|
} else { // here we know the sign of zero_j
|
||||||
generate_strict_case_zero_lemma(m, zero_j, sign);
|
generate_strict_case_zero_lemma(m, zero_j, sign);
|
||||||
}
|
}
|
||||||
|
@ -171,11 +171,13 @@ lpvar basics::find_best_zero(const monic& m, unsigned_vector & fixed_zeros) cons
|
||||||
}
|
}
|
||||||
return zero_j;
|
return zero_j;
|
||||||
}
|
}
|
||||||
void basics::add_trival_zero_lemma(lpvar zero_j, const monic& m) {
|
|
||||||
new_lemma lemma(c(), "x = 0 or x != 0");
|
void basics::add_trivial_zero_lemma(lpvar zero_j, const monic& m) {
|
||||||
|
new_lemma lemma(c(), "x = 0 => x*y = 0");
|
||||||
c().mk_ineq(zero_j, llc::NE);
|
c().mk_ineq(zero_j, llc::NE);
|
||||||
c().mk_ineq(m.var(), llc::EQ);
|
c().mk_ineq(m.var(), llc::EQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
void basics::generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, int sign_of_zj) {
|
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";);
|
TRACE("nla_solver_bl", tout << "sign_of_zj = " << sign_of_zj << "\n";);
|
||||||
// we know all the signs
|
// we know all the signs
|
||||||
|
@ -305,6 +307,9 @@ bool basics::basic_lemma_for_mon_non_zero_derived(const monic& rm, const factori
|
||||||
}
|
}
|
||||||
// use the fact that
|
// use the fact that
|
||||||
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
|
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
|
||||||
|
// it holds for integers, and for reals for a pair of factors
|
||||||
|
// |x*a| = |x| & x != 0 -> |a| = 1
|
||||||
|
|
||||||
bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm, const factorization& f) {
|
bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm, const factorization& f) {
|
||||||
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
|
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
|
||||||
|
|
||||||
|
@ -319,8 +324,10 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm
|
||||||
}
|
}
|
||||||
bool mon_var_is_sep_from_zero = c().var_is_separated_from_zero(mon_var);
|
bool mon_var_is_sep_from_zero = c().var_is_separated_from_zero(mon_var);
|
||||||
lpvar jl = null_lpvar, not_one_j = null_lpvar;
|
lpvar jl = null_lpvar, not_one_j = null_lpvar;
|
||||||
|
bool all_int = true;
|
||||||
for (auto fc : f) {
|
for (auto fc : f) {
|
||||||
lpvar j = var(fc);
|
lpvar j = var(fc);
|
||||||
|
all_int &= c().var_is_int(j);
|
||||||
if (j == null_lpvar && abs(val(j)) == abs_mv &&
|
if (j == null_lpvar && abs(val(j)) == abs_mv &&
|
||||||
c().vars_are_equiv(j, mon_var) &&
|
c().vars_are_equiv(j, mon_var) &&
|
||||||
(mon_var_is_sep_from_zero || c().var_is_separated_from_zero(j)))
|
(mon_var_is_sep_from_zero || c().var_is_separated_from_zero(j)))
|
||||||
|
@ -332,6 +339,8 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm
|
||||||
}
|
}
|
||||||
if (jl == null_lpvar || not_one_j == null_lpvar)
|
if (jl == null_lpvar || not_one_j == null_lpvar)
|
||||||
return false;
|
return false;
|
||||||
|
if (!all_int && f.size() > 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
new_lemma lemma(c(), "|xa| = |x| & x != 0 -> |a| = 1");
|
new_lemma lemma(c(), "|xa| = |x| & x != 0 -> |a| = 1");
|
||||||
// mon_var = 0
|
// mon_var = 0
|
||||||
|
@ -518,9 +527,10 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const mo
|
||||||
if (abs_mv == rational::zero()) {
|
if (abs_mv == rational::zero()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lpvar jl = null_lpvar;
|
lpvar jl = null_lpvar, not_one_j = null_lpvar;
|
||||||
lpvar not_one_j = null_lpvar;
|
bool all_int = true;
|
||||||
for (auto j : m.vars()) {
|
for (auto j : m.vars()) {
|
||||||
|
all_int &= c().var_is_int(j);
|
||||||
if (jl == null_lpvar && abs(val(j)) == abs_mv)
|
if (jl == null_lpvar && abs(val(j)) == abs_mv)
|
||||||
jl = j;
|
jl = j;
|
||||||
else if (jl == j)
|
else if (jl == j)
|
||||||
|
@ -531,6 +541,9 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const mo
|
||||||
if (jl == null_lpvar || not_one_j == null_lpvar)
|
if (jl == null_lpvar || not_one_j == null_lpvar)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!all_int && m.size() > 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
new_lemma lemma(c(), __FUNCTION__);
|
new_lemma lemma(c(), __FUNCTION__);
|
||||||
// mon_var = 0
|
// mon_var = 0
|
||||||
c().mk_ineq(mon_var, llc::EQ);
|
c().mk_ineq(mon_var, llc::EQ);
|
||||||
|
@ -616,11 +629,11 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic
|
||||||
if (abs_mv == rational::zero()) {
|
if (abs_mv == rational::zero()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lpvar jl = null_lpvar;
|
lpvar jl = null_lpvar, not_one_j = null_lpvar;
|
||||||
lpvar not_one_j = null_lpvar;
|
bool all_int = true;
|
||||||
|
|
||||||
for (auto fc : f) {
|
for (auto fc : f) {
|
||||||
lpvar j = var(fc);
|
lpvar j = var(fc);
|
||||||
|
all_int &= c().var_is_int(j);
|
||||||
if (j == null_lpvar && abs(val(fc)) == abs_mv)
|
if (j == null_lpvar && abs(val(fc)) == abs_mv)
|
||||||
jl = j;
|
jl = j;
|
||||||
else if (j == jl)
|
else if (j == jl)
|
||||||
|
@ -630,6 +643,8 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic
|
||||||
}
|
}
|
||||||
if (jl == null_lpvar || not_one_j == null_lpvar)
|
if (jl == null_lpvar || not_one_j == null_lpvar)
|
||||||
return false;
|
return false;
|
||||||
|
if (!all_int && f.size() > 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
new_lemma lemma(c(), __FUNCTION__);
|
new_lemma lemma(c(), __FUNCTION__);
|
||||||
// mon_var = 0
|
// mon_var = 0
|
||||||
|
@ -735,23 +750,22 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const
|
||||||
|
|
||||||
void basics::basic_lemma_for_mon_non_zero_model_based_mf(const factorization& f) {
|
void basics::basic_lemma_for_mon_non_zero_model_based_mf(const factorization& f) {
|
||||||
TRACE("nla_solver_bl", tout << c().pp(f););
|
TRACE("nla_solver_bl", tout << c().pp(f););
|
||||||
lpvar zero_j = null_lpvar;
|
|
||||||
for (auto j : f) {
|
for (auto j : f) {
|
||||||
if (val(j).is_zero()) {
|
if (val(j).is_zero()) {
|
||||||
zero_j = var(j);
|
lpvar zero_j = var(j);
|
||||||
break;
|
new_lemma lemma(c(), "x = 0 => x*... = 0");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zero_j == null_lpvar) { return; }
|
|
||||||
new_lemma lemma(c(), __FUNCTION__);
|
|
||||||
c().mk_ineq(zero_j, llc::NE);
|
c().mk_ineq(zero_j, llc::NE);
|
||||||
c().mk_ineq(f.mon().var(), llc::EQ);
|
c().mk_ineq(f.mon().var(), llc::EQ);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// x = 0 or y = 0 -> xy = 0
|
// x = 0 or y = 0 -> xy = 0
|
||||||
void basics::basic_lemma_for_mon_non_zero_model_based(const monic& rm, const factorization& f) {
|
void basics::basic_lemma_for_mon_non_zero_model_based(const monic& rm, const factorization& f) {
|
||||||
TRACE("nla_solver_bl", c().trace_print_monic_and_factorization(rm, f, tout););
|
TRACE("nla_solver_bl", c().trace_print_monic_and_factorization(rm, f, tout););
|
||||||
|
# NSB code review:
|
||||||
|
# the two branches are the same
|
||||||
if (f.is_mon())
|
if (f.is_mon())
|
||||||
basic_lemma_for_mon_non_zero_model_based_mf(f);
|
basic_lemma_for_mon_non_zero_model_based_mf(f);
|
||||||
else
|
else
|
||||||
|
|
|
@ -76,7 +76,7 @@ struct basics: common {
|
||||||
lpvar find_best_zero(const monic& m, unsigned_vector & fixed_zeros) const;
|
lpvar find_best_zero(const monic& m, unsigned_vector & fixed_zeros) const;
|
||||||
bool try_get_non_strict_sign_from_bounds(lpvar j, int& sign) const;
|
bool try_get_non_strict_sign_from_bounds(lpvar j, int& sign) const;
|
||||||
void get_non_strict_sign(lpvar j, int& sign) const;
|
void get_non_strict_sign(lpvar j, int& sign) const;
|
||||||
void add_trival_zero_lemma(lpvar zero_j, const monic& m);
|
void add_trivial_zero_lemma(lpvar zero_j, const monic& m);
|
||||||
void generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, int sign_of_zj);
|
void generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, int sign_of_zj);
|
||||||
|
|
||||||
void add_fixed_zero_lemma(const monic& m, lpvar j);
|
void add_fixed_zero_lemma(const monic& m, lpvar j);
|
||||||
|
|
Loading…
Reference in a new issue