mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	rename new_lemma to lemma_builder
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
		
							parent
							
								
									2f2289eaff
								
							
						
					
					
						commit
						5bda42e104
					
				
					 17 changed files with 135 additions and 115 deletions
				
			
		|  | @ -110,7 +110,7 @@ namespace nla { | |||
|             dep.get_upper_dep(range, ex); | ||||
|             if (is_too_big(upper)) | ||||
|                 return false; | ||||
|             new_lemma lemma(c(), "propagate value - upper bound of range is below value"); | ||||
|             lemma_builder lemma(c(), "propagate value - upper bound of range is below value"); | ||||
|             lemma &= ex; | ||||
|             lemma |= ineq(v, cmp, upper);  | ||||
|             TRACE(nla_solver, dep.display(tout << c().val(v) << " > ", range) << "\n" << lemma << "\n";); | ||||
|  | @ -124,7 +124,7 @@ namespace nla { | |||
|             dep.get_lower_dep(range, ex); | ||||
|             if (is_too_big(lower)) | ||||
|                 return false; | ||||
|             new_lemma lemma(c(), "propagate value - lower bound of range is above value"); | ||||
|             lemma_builder lemma(c(), "propagate value - lower bound of range is above value"); | ||||
|             lemma &= ex; | ||||
|             lemma |= ineq(v, cmp, lower);  | ||||
|             TRACE(nla_solver, dep.display(tout << c().val(v) << " < ", range) << "\n" << lemma << "\n";); | ||||
|  | @ -196,7 +196,7 @@ namespace nla { | |||
|             // p even, range.upper < 0, v^p >= 0 -> infeasible
 | ||||
|             if (p % 2 == 0 && rational(dep.upper(range)).is_neg()) { | ||||
|                 ++c().lra.settings().stats().m_nla_propagate_bounds; | ||||
|                 new_lemma lemma(c(), "range requires a non-negative upper bound"); | ||||
|                 lemma_builder lemma(c(), "range requires a non-negative upper bound"); | ||||
|                 lemma &= ex; | ||||
|                 return true; | ||||
|             } | ||||
|  | @ -208,7 +208,7 @@ namespace nla { | |||
|                 if ((p % 2 == 1) || c().val(v).is_pos()) { | ||||
|                     ++c().lra.settings().stats().m_nla_propagate_bounds; | ||||
|                     auto le = dep.upper_is_open(range) ? llc::LT : llc::LE; | ||||
|                     new_lemma lemma(c(), "propagate value - root case - upper bound of range is below value"); | ||||
|                     lemma_builder lemma(c(), "propagate value - root case - upper bound of range is below value"); | ||||
|                     lemma &= ex; | ||||
|                     lemma |= ineq(v, le, r); | ||||
|                     return true; | ||||
|  | @ -218,7 +218,7 @@ namespace nla { | |||
|                     ++c().lra.settings().stats().m_nla_propagate_bounds; | ||||
|                     SASSERT(!r.is_neg()); | ||||
|                     auto ge = dep.upper_is_open(range) ? llc::GT : llc::GE; | ||||
|                     new_lemma lemma(c(), "propagate value - root case - upper bound of range is below negative value"); | ||||
|                     lemma_builder lemma(c(), "propagate value - root case - upper bound of range is below negative value"); | ||||
|                     lemma &= ex; | ||||
|                     lemma |= ineq(v, ge, -r); | ||||
|                     return true; | ||||
|  | @ -242,7 +242,7 @@ namespace nla { | |||
|                 auto le = dep.lower_is_open(range) ? llc::LT : llc::LE; | ||||
|                 lp::explanation ex; | ||||
|                 dep.get_lower_dep(range, ex); | ||||
|                 new_lemma lemma(c(), "propagate value - root case - lower bound of range is above value"); | ||||
|                 lemma_builder lemma(c(), "propagate value - root case - lower bound of range is above value"); | ||||
|                 lemma &= ex; | ||||
|                 lemma |= ineq(v, ge, r); | ||||
|                 if (p % 2 == 0) | ||||
|  | @ -380,7 +380,7 @@ namespace nla { | |||
|             return false; | ||||
|         lp::explanation exp; | ||||
|         c().lra.get_infeasibility_explanation(exp); | ||||
|         new_lemma lemma(c(), "propagate fixed - infeasible lra"); | ||||
|         lemma_builder lemma(c(), "propagate fixed - infeasible lra"); | ||||
|         lemma &= exp; | ||||
|         return true; | ||||
|     } | ||||
|  |  | |||
|  | @ -83,7 +83,7 @@ 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 { | ||||
|         new_lemma lemma(c(), __FUNCTION__); | ||||
|         lemma_builder lemma(c(), __FUNCTION__); | ||||
|         for (lpvar j: m.vars()) { | ||||
|             negate_strict_sign(lemma, j); | ||||
|         } | ||||
|  | @ -149,7 +149,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) { | ||||
|     new_lemma lemma(c(), "sign lemma"); | ||||
|     lemma_builder lemma(c(), "sign lemma"); | ||||
|     TRACE(nla_solver, | ||||
|           tout << "m = " << pp_mon_with_vars(_(), m); | ||||
|           tout << "n = " << pp_mon_with_vars(_(), n); | ||||
|  | @ -175,7 +175,7 @@ lpvar basics::find_best_zero(const monic& m, unsigned_vector & fixed_zeros) cons | |||
| } | ||||
| 
 | ||||
| void basics::add_trivial_zero_lemma(lpvar zero_j, const monic& m) { | ||||
|     new_lemma lemma(c(), "x = 0 => x*y = 0"); | ||||
|     lemma_builder lemma(c(), "x = 0 => x*y = 0"); | ||||
|     lemma |= ineq(zero_j,  llc::NE, 0); | ||||
|     lemma |= ineq(m.var(), llc::EQ, 0); | ||||
| } | ||||
|  | @ -183,7 +183,7 @@ void basics::add_trivial_zero_lemma(lpvar zero_j, const monic& m) { | |||
| 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
 | ||||
|     new_lemma lemma(c(), "strict case 0"); | ||||
|     lemma_builder lemma(c(), "strict case 0"); | ||||
|     lemma |= ineq(zero_j, sign_of_zj == 1? llc::GT : llc::LT, 0); | ||||
|     for (unsigned j : m.vars()) { | ||||
|         if (j != zero_j) { | ||||
|  | @ -194,12 +194,12 @@ void basics::generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, in | |||
| } | ||||
| 
 | ||||
| void basics::add_fixed_zero_lemma(const monic& m, lpvar j) { | ||||
|     new_lemma lemma(c(), "fixed zero"); | ||||
|     lemma_builder lemma(c(), "fixed zero"); | ||||
|     lemma.explain_fixed(j); | ||||
|     lemma |= ineq(m.var(), llc::EQ, 0); | ||||
| } | ||||
| 
 | ||||
| void basics::negate_strict_sign(new_lemma& lemma, lpvar j) { | ||||
| void basics::negate_strict_sign(lemma_builder& lemma, lpvar j) { | ||||
|     TRACE(nla_solver_details, tout << pp_var(c(), j) << " " << val(j).is_zero() << "\n";); | ||||
|     if (!val(j).is_zero()) { | ||||
|         int sign = nla::rat_sign(val(j)); | ||||
|  | @ -226,7 +226,7 @@ bool basics::basic_lemma_for_mon_zero(const monic& rm, const factorization& f) { | |||
|             return false; | ||||
|     } | ||||
|     TRACE(nla_solver, c().trace_print_monic_and_factorization(rm, f, tout);); | ||||
|     new_lemma lemma(c(), "xy = 0 -> x = 0 or y = 0"); | ||||
|     lemma_builder lemma(c(), "xy = 0 -> x = 0 or y = 0"); | ||||
|     lemma.explain_fixed(var(rm)); | ||||
|     std::unordered_set<lpvar> processed; | ||||
|     for (auto j : f) { | ||||
|  | @ -298,7 +298,7 @@ bool basics::basic_lemma_for_mon_non_zero_derived(const monic& rm, const factori | |||
|     for (auto fc : f) { | ||||
|         if (!c().var_is_fixed_to_zero(var(fc)))  | ||||
|             continue; | ||||
|         new_lemma lemma(c(), "x = 0 or y = 0 -> xy = 0"); | ||||
|         lemma_builder lemma(c(), "x = 0 or y = 0 -> xy = 0"); | ||||
|         lemma.explain_fixed(var(fc)); | ||||
|         lemma.explain_var_separated_from_zero(var(rm)); | ||||
|         lemma &= rm; | ||||
|  | @ -345,7 +345,7 @@ bool basics::basic_lemma_for_mon_neutral_derived(const monic& rm, const factoriz | |||
| 
 | ||||
|     //    (mon_var != 0 || u != 0) & mon_var = +/- u =>
 | ||||
|     //    v = 1 or v = -1
 | ||||
|     new_lemma lemma(c(), "|xa| = |x| & x != 0 -> |a| = 1"); | ||||
|     lemma_builder lemma(c(), "|xa| = |x| & x != 0 -> |a| = 1"); | ||||
|     lemma.explain_var_separated_from_zero(mon_var_is_sep_from_zero ? mon_var : u);     | ||||
|     lemma.explain_equiv(mon_var, u);         | ||||
|     lemma |= ineq(v, llc::EQ, 1);         | ||||
|  | @ -387,7 +387,7 @@ void basics::proportion_lemma_model_based(const monic& rm, const factorization& | |||
| */ | ||||
| void basics::generate_pl_on_mon(const monic& m, unsigned k) { | ||||
|     SASSERT(!c().has_real(m)); | ||||
|     new_lemma lemma(c(), "generate_pl_on_mon"); | ||||
|     lemma_builder lemma(c(), "generate_pl_on_mon"); | ||||
|     unsigned mon_var = m.var(); | ||||
|     rational mv = val(mon_var); | ||||
|     SASSERT(abs(mv) < abs(val(m.vars()[k]))); | ||||
|  | @ -423,7 +423,7 @@ void basics::generate_pl(const monic& m, const factorization& fc, int factor_ind | |||
|         generate_pl_on_mon(m, factor_index); | ||||
|         return; | ||||
|     } | ||||
|     new_lemma lemma(c(), "generate_pl"); | ||||
|     lemma_builder lemma(c(), "generate_pl"); | ||||
|     int fi = 0; | ||||
|     rational mv = var_val(m); | ||||
|     rational sm = rational(nla::rat_sign(mv)); | ||||
|  | @ -459,7 +459,7 @@ bool basics::is_separated_from_zero(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)); | ||||
|     new_lemma lemma(c(), "xy = 0 -> x = 0 or y = 0"); | ||||
|     lemma_builder lemma(c(), "xy = 0 -> x = 0 or y = 0"); | ||||
|     if (!is_separated_from_zero(f)) { | ||||
|         lemma |= ineq(var(rm), llc::NE, 0); | ||||
|         for (auto j : f) { | ||||
|  | @ -511,7 +511,7 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(co | |||
|     if (!can_create_lemma_for_mon_neutral_from_factors_to_monic_model_based(m, m, not_one, sign)) | ||||
|         return false; | ||||
|         | ||||
|     new_lemma lemma(c(), __FUNCTION__); | ||||
|     lemma_builder lemma(c(), __FUNCTION__); | ||||
|     for (auto j : m.vars()) { | ||||
|         if (not_one != j)  | ||||
|             lemma |= ineq(j, llc::NE, val(j)); | ||||
|  | @ -556,7 +556,7 @@ bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic | |||
|     // v = 1
 | ||||
|     // v = -1
 | ||||
| 
 | ||||
|     new_lemma lemma(c(), __FUNCTION__); | ||||
|     lemma_builder lemma(c(), __FUNCTION__); | ||||
|     lemma |= ineq(mon_var, llc::EQ, 0);         | ||||
|     lemma |= ineq(term(u, rational(val(u) == -val(mon_var) ? 1 : -1), mon_var), llc::NE, 0); | ||||
|     lemma |= ineq(v, llc::EQ, 1); | ||||
|  | @ -641,7 +641,7 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const | |||
|             return false; | ||||
|     TRACE(nla_solver_bl, tout << "not_one = " << not_one << "\n";); | ||||
|          | ||||
|     new_lemma lemma(c(), __FUNCTION__); | ||||
|     lemma_builder lemma(c(), __FUNCTION__); | ||||
| 
 | ||||
|     for (auto j : f) { | ||||
|         lpvar var_j = var(j); | ||||
|  | @ -665,7 +665,7 @@ void basics::basic_lemma_for_mon_non_zero_model_based(const monic& rm, const fac | |||
|     TRACE(nla_solver_bl, c().trace_print_monic_and_factorization(rm, f, tout);); | ||||
|     for (auto j : f) { | ||||
|         if (val(j).is_zero()) { | ||||
|             new_lemma lemma(c(), "x = 0 => x*... = 0"); | ||||
|             lemma_builder lemma(c(), "x = 0 => x*... = 0"); | ||||
|             lemma |= ineq(var(j), llc::NE, 0); | ||||
|             lemma |= ineq(f.mon().var(), llc::EQ, 0); | ||||
|             lemma &= f; | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
| 
 | ||||
| namespace nla { | ||||
| class core; | ||||
| class new_lemma; | ||||
| class lemma_builder; | ||||
| struct basics: common { | ||||
|     basics(core *core); | ||||
|     bool basic_sign_lemma_on_two_monics(const monic& m, const monic& n); | ||||
|  | @ -84,7 +84,7 @@ struct basics: common { | |||
|     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 negate_strict_sign(new_lemma& lemma, lpvar j); | ||||
|     void negate_strict_sign(lemma_builder& lemma, lpvar j); | ||||
|     // x != 0 or y = 0 => |xy| >= |y|
 | ||||
|     void proportion_lemma_model_based(const monic& rm, const factorization& factorization); | ||||
|     // if there are no zero factors then |m| >= |m[factor_index]|
 | ||||
|  |  | |||
|  | @ -350,7 +350,7 @@ bool core::explain_coeff_upper_bound(const lp::lar_term::ival& p, rational& boun | |||
| } | ||||
|      | ||||
| // return true iff the negation of the ineq can be derived from the constraints
 | ||||
| bool core::explain_ineq(new_lemma& lemma, const lp::lar_term& t, llc cmp, const rational& rs) { | ||||
| bool core::explain_ineq(lemma_builder& lemma, const lp::lar_term& t, llc cmp, const rational& rs) { | ||||
|     // check that we have something like 0 < 0, which is always false and can be safely
 | ||||
|     // removed from the lemma
 | ||||
|          | ||||
|  | @ -410,7 +410,7 @@ bool core::explain_by_equiv(const lp::lar_term& t, lp::explanation& e) const { | |||
|     return true;             | ||||
| } | ||||
| 
 | ||||
| void core::mk_ineq_no_expl_check(new_lemma& lemma, lp::lar_term& t, llc cmp, const rational& rs) { | ||||
| void core::mk_ineq_no_expl_check(lemma_builder& lemma, lp::lar_term& t, llc cmp, const rational& rs) { | ||||
|     TRACE(nla_solver_details, lra.print_term_as_indices(t, tout << "t = ");); | ||||
|     lemma |= ineq(cmp, t, rs); | ||||
|     CTRACE(nla_solver, ineq_holds(ineq(cmp, t, rs)), print_ineq(ineq(cmp, t, rs), tout) << "\n";); | ||||
|  | @ -429,7 +429,7 @@ llc apply_minus(llc cmp) { | |||
| }    | ||||
|      | ||||
| // the monics should be equal by modulo sign but this is not so in the model
 | ||||
| void core::fill_explanation_and_lemma_sign(new_lemma& lemma, const monic& a, const monic & b, rational const& sign) { | ||||
| void core::fill_explanation_and_lemma_sign(lemma_builder& lemma, const monic& a, const monic & b, rational const& sign) { | ||||
|     SASSERT(sign == 1 || sign == -1); | ||||
|     lemma &= a; | ||||
|     lemma &= b; | ||||
|  | @ -899,7 +899,7 @@ bool core::divide(const monic& bc, const factor& c, factor & b) const { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| void core::negate_factor_equality(new_lemma& lemma, const factor& c, | ||||
| void core::negate_factor_equality(lemma_builder& lemma, const factor& c, | ||||
|                                   const factor& d) { | ||||
|     if (c == d) | ||||
|         return; | ||||
|  | @ -910,7 +910,7 @@ void core::negate_factor_equality(new_lemma& lemma, const factor& c, | |||
|     lemma |= ineq(term(i, rational(iv == jv ? -1 : 1), j), llc::NE, 0);     | ||||
| } | ||||
|      | ||||
| void core::negate_factor_relation(new_lemma& lemma, const rational& a_sign, const factor& a, const rational& b_sign, const factor& b) { | ||||
| void core::negate_factor_relation(lemma_builder& lemma, const rational& a_sign, const factor& a, const rational& b_sign, const factor& b) { | ||||
|     rational a_fs = sign_to_rat(canonize_sign(a)); | ||||
|     rational b_fs = sign_to_rat(canonize_sign(b)); | ||||
|     llc cmp = a_sign*val(a) < b_sign*val(b)? llc::GE : llc::LE; | ||||
|  | @ -1040,11 +1040,11 @@ rational core::val(const factorization& f) const { | |||
|     return r; | ||||
| } | ||||
| 
 | ||||
| new_lemma::new_lemma(core& c, char const* name):name(name), c(c) { | ||||
| lemma_builder::lemma_builder(core& c, char const* name):name(name), c(c) { | ||||
|     c.m_lemmas.push_back(lemma()); | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::operator|=(ineq const& ineq) { | ||||
| lemma_builder& lemma_builder::operator|=(ineq const& ineq) { | ||||
|     if (!c.explain_ineq(*this, ineq.term(), ineq.cmp(), ineq.rs())) { | ||||
|         CTRACE(nla_solver, c.ineq_holds(ineq), c.print_ineq(ineq, tout) << "\n";); | ||||
|         SASSERT(c.m_use_nra_model || !c.ineq_holds(ineq)); | ||||
|  | @ -1054,7 +1054,7 @@ new_lemma& new_lemma::operator|=(ineq const& ineq) { | |||
| } | ||||
|      | ||||
| 
 | ||||
| new_lemma::~new_lemma() { | ||||
| lemma_builder::~lemma_builder() { | ||||
|     static int i = 0; | ||||
|     (void)i; | ||||
|     (void)name; | ||||
|  | @ -1067,22 +1067,22 @@ new_lemma::~new_lemma() { | |||
|     TRACE(nla_solver, tout << name << " " << (++i) << "\n" << *this; ); | ||||
| } | ||||
| 
 | ||||
| lemma& new_lemma::current() const { | ||||
| lemma& lemma_builder::current() const { | ||||
|     return c.m_lemmas.back(); | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::operator&=(lp::explanation const& e) { | ||||
| lemma_builder& lemma_builder::operator&=(lp::explanation const& e) { | ||||
|     expl().add_expl(e); | ||||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::operator&=(const monic& m) { | ||||
| lemma_builder& lemma_builder::operator&=(const monic& m) { | ||||
|     for (lpvar j : m.vars()) | ||||
|         *this &= j; | ||||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::operator&=(const factor& f) { | ||||
| lemma_builder& lemma_builder::operator&=(const factor& f) { | ||||
|     if (f.type() == factor_type::VAR)  | ||||
|         *this &= f.var(); | ||||
|     else  | ||||
|  | @ -1090,7 +1090,7 @@ new_lemma& new_lemma::operator&=(const factor& f) { | |||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::operator&=(const factorization& f) { | ||||
| lemma_builder& lemma_builder::operator&=(const factorization& f) { | ||||
|     if (f.is_mon()) | ||||
|         return *this; | ||||
|     for (const auto& fc : f) { | ||||
|  | @ -1099,19 +1099,19 @@ new_lemma& new_lemma::operator&=(const factorization& f) { | |||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::operator&=(lpvar j) { | ||||
| lemma_builder& lemma_builder::operator&=(lpvar j) { | ||||
|     c.m_evars.explain(j, expl()); | ||||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::explain_fixed(lpvar j) { | ||||
| lemma_builder& lemma_builder::explain_fixed(lpvar j) { | ||||
|     SASSERT(c.var_is_fixed(j)); | ||||
|     explain_existing_lower_bound(j); | ||||
|     explain_existing_upper_bound(j); | ||||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::explain_equiv(lpvar a, lpvar b) { | ||||
| lemma_builder& lemma_builder::explain_equiv(lpvar a, lpvar b) { | ||||
|     SASSERT(abs(c.val(a)) == abs(c.val(b))); | ||||
|     if (c.vars_are_equiv(a, b)) { | ||||
|         *this &= a; | ||||
|  | @ -1123,7 +1123,7 @@ new_lemma& new_lemma::explain_equiv(lpvar a, lpvar b) { | |||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::explain_var_separated_from_zero(lpvar j) { | ||||
| lemma_builder& lemma_builder::explain_var_separated_from_zero(lpvar j) { | ||||
|     SASSERT(c.var_is_separated_from_zero(j)); | ||||
|     if (c.lra.column_has_upper_bound(j) &&  | ||||
|         (c.lra.get_upper_bound(j)< lp::zero_of_type<lp::impq>()))  | ||||
|  | @ -1133,7 +1133,7 @@ new_lemma& new_lemma::explain_var_separated_from_zero(lpvar j) { | |||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::explain_existing_lower_bound(lpvar j) { | ||||
| lemma_builder& lemma_builder::explain_existing_lower_bound(lpvar j) { | ||||
|     SASSERT(c.has_lower_bound(j)); | ||||
|     lp::explanation ex; | ||||
|     c.lra.push_explanation(c.lra.get_column_lower_bound_witness(j), ex); | ||||
|  | @ -1142,7 +1142,7 @@ new_lemma& new_lemma::explain_existing_lower_bound(lpvar j) { | |||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| new_lemma& new_lemma::explain_existing_upper_bound(lpvar j) { | ||||
| lemma_builder& lemma_builder::explain_existing_upper_bound(lpvar j) { | ||||
|     SASSERT(c.has_upper_bound(j)); | ||||
|     lp::explanation ex; | ||||
|     c.lra.push_explanation(c.lra.get_column_upper_bound_witness(j), ex); | ||||
|  | @ -1150,7 +1150,7 @@ new_lemma& new_lemma::explain_existing_upper_bound(lpvar j) { | |||
|     return *this; | ||||
| } | ||||
|      | ||||
| std::ostream& new_lemma::display(std::ostream & out) const { | ||||
| std::ostream& lemma_builder::display(std::ostream & out) const { | ||||
|     auto const& lemma = current(); | ||||
| 
 | ||||
|     for (auto p : lemma.expl()) { | ||||
|  | @ -1175,7 +1175,7 @@ std::ostream& new_lemma::display(std::ostream & out) const { | |||
|     return out; | ||||
| } | ||||
|      | ||||
| void core::negate_relation(new_lemma& lemma, unsigned j, const rational& a) { | ||||
| void core::negate_relation(lemma_builder& lemma, unsigned j, const rational& a) { | ||||
|     SASSERT(val(j) != a); | ||||
|     lemma |= ineq(j, val(j) < a ? llc::GE : llc::LE, a);    | ||||
| } | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ bool try_insert(const A& elem, B& collection) { | |||
| 
 | ||||
| class core { | ||||
|     friend struct common; | ||||
|     friend class new_lemma; | ||||
|     friend class lemma_builder; | ||||
|     friend class grobner; | ||||
|     friend class order; | ||||
|     friend struct basics; | ||||
|  | @ -263,7 +263,7 @@ public: | |||
|                         std::ostream& out); | ||||
| 
 | ||||
|          | ||||
|     void mk_ineq_no_expl_check(new_lemma& lemma, lp::lar_term& t, llc cmp, const rational& rs); | ||||
|     void mk_ineq_no_expl_check(lemma_builder& lemma, lp::lar_term& t, llc cmp, const rational& rs); | ||||
|      | ||||
|     void maybe_add_a_factor(lpvar i, | ||||
|                             const factor& c, | ||||
|  | @ -273,7 +273,7 @@ public: | |||
| 
 | ||||
|     llc apply_minus(llc cmp); | ||||
|      | ||||
|     void fill_explanation_and_lemma_sign(new_lemma& lemma, const monic& a, const monic & b, rational const& sign); | ||||
|     void fill_explanation_and_lemma_sign(lemma_builder& lemma, const monic& a, const monic & b, rational const& sign); | ||||
| 
 | ||||
|     svector<lpvar> reduce_monic_to_rooted(const svector<lpvar> & vars, rational & sign) const; | ||||
| 
 | ||||
|  | @ -319,7 +319,7 @@ public: | |||
|     bool var_is_separated_from_zero(lpvar j) const; | ||||
| 
 | ||||
|     bool vars_are_equiv(lpvar a, lpvar b) const;     | ||||
|     bool explain_ineq(new_lemma& lemma, const lp::lar_term& t, llc cmp, const rational& rs); | ||||
|     bool explain_ineq(lemma_builder& lemma, const lp::lar_term& t, llc cmp, const rational& rs); | ||||
|     bool explain_upper_bound(const lp::lar_term& t, const rational& rs, lp::explanation& e) const; | ||||
|     bool explain_lower_bound(const lp::lar_term& t, const rational& rs, lp::explanation& e) const; | ||||
|     bool explain_coeff_lower_bound(const lp::lar_term::ival& p, rational& bound, lp::explanation& e) const; | ||||
|  | @ -370,9 +370,9 @@ public: | |||
|     bool rm_check(const monic&) const; | ||||
|     std::unordered_map<unsigned, unsigned_vector> get_rm_by_arity(); | ||||
| 
 | ||||
|     void negate_relation(new_lemma& lemma, unsigned j, const rational& a); | ||||
|     void negate_factor_equality(new_lemma& lemma, const factor& c, const factor& d);     | ||||
|     void negate_factor_relation(new_lemma& lemma, const rational& a_sign, const factor& a, const rational& b_sign, const factor& b); | ||||
|     void negate_relation(lemma_builder& lemma, unsigned j, const rational& a); | ||||
|     void negate_factor_equality(lemma_builder& lemma, const factor& c, const factor& d);     | ||||
|     void negate_factor_relation(lemma_builder& lemma, const rational& a_sign, const factor& a, const rational& b_sign, const factor& b); | ||||
| 
 | ||||
|     bool  find_bfc_to_refine_on_monic(const monic&, factorization & bf); | ||||
|      | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ namespace nla { | |||
|         auto monotonicity1 = [&](auto x1, auto& x1val, auto y1, auto& y1val, auto& q1, auto& q1val, | ||||
|             auto x2, auto& x2val, auto y2, auto& y2val, auto& q2, auto& q2val) { | ||||
|                 if (y1val >= y2val && y2val > 0 && 0 <= x1val && x1val <= x2val && q1val > q2val) { | ||||
|                     new_lemma lemma(c, "y1 >= y2 > 0 & 0 <= x1 <= x2 => x1/y1 <= x2/y2"); | ||||
|                     lemma_builder lemma(c, "y1 >= y2 > 0 & 0 <= x1 <= x2 => x1/y1 <= x2/y2"); | ||||
|                     lemma |= ineq(term(y1, rational(-1), y2), llc::LT, 0); | ||||
|                     lemma |= ineq(y2, llc::LE, 0); | ||||
|                     lemma |= ineq(x1, llc::LT, 0); | ||||
|  | @ -69,7 +69,7 @@ namespace nla { | |||
|         auto monotonicity2 = [&](auto x1, auto& x1val, auto y1, auto& y1val, auto& q1, auto& q1val, | ||||
|             auto x2, auto& x2val, auto y2, auto& y2val, auto& q2, auto& q2val) { | ||||
|                 if (y2val <= y1val && y1val < 0 && x1val >= x2val && x2val >= 0 && q1val > q2val) { | ||||
|                     new_lemma lemma(c, "y2 <= y1 < 0 & x1 >= x2 >= 0 => x1/y1 <= x2/y2"); | ||||
|                     lemma_builder lemma(c, "y2 <= y1 < 0 & x1 >= x2 >= 0 => x1/y1 <= x2/y2"); | ||||
|                     lemma |= ineq(term(y1, rational(-1), y2), llc::LT, 0); | ||||
|                     lemma |= ineq(y1, llc::GE, 0); | ||||
|                     lemma |= ineq(term(x1, rational(-1), x2), llc::LT, 0); | ||||
|  | @ -83,7 +83,7 @@ namespace nla { | |||
|         auto monotonicity3 = [&](auto x1, auto& x1val, auto y1, auto& y1val, auto& q1, auto& q1val, | ||||
|             auto x2, auto& x2val, auto y2, auto& y2val, auto& q2, auto& q2val) { | ||||
|                 if (y2val <= y1val && y1val < 0 && x1val <= x2val && x2val <= 0 && q1val < q2val) { | ||||
|                     new_lemma lemma(c, "y2 <= y1 < 0 & x1 <= x2 <= 0 => x1/y1 >= x2/y2"); | ||||
|                     lemma_builder lemma(c, "y2 <= y1 < 0 & x1 <= x2 <= 0 => x1/y1 >= x2/y2"); | ||||
|                     lemma |= ineq(term(y1, rational(-1), y2), llc::LT, 0); | ||||
|                     lemma |= ineq(y1, llc::GE, 0); | ||||
|                     lemma |= ineq(term(x1, rational(-1), x2), llc::GT, 0); | ||||
|  | @ -187,14 +187,14 @@ namespace nla { | |||
|             rational hi = yv * div_v + yv - 1; | ||||
|             rational lo = yv * div_v; | ||||
|             if (xv > hi) { | ||||
|                 new_lemma lemma(c, "y = yv & x <= yv * div(xv, yv) + yv - 1 => div(p, y) <= div(xv, yv)"); | ||||
|                 lemma_builder lemma(c, "y = yv & x <= yv * div(xv, yv) + yv - 1 => div(p, y) <= div(xv, yv)"); | ||||
|                 lemma |= ineq(y, llc::NE, yv);  | ||||
|                 lemma |= ineq(x, llc::GT, hi);  | ||||
|                 lemma |= ineq(q, llc::LE, div_v);   | ||||
|                 return; | ||||
|             } | ||||
|             if (xv < lo) { | ||||
|                 new_lemma lemma(c, "y = yv & x >= yv * div(xv, yv) => div(xv, yv) <= div(x, y)"); | ||||
|                 lemma_builder lemma(c, "y = yv & x >= yv * div(xv, yv) => div(xv, yv) <= div(x, y)"); | ||||
|                 lemma |= ineq(y, llc::NE, yv); | ||||
|                 lemma |= ineq(x, llc::LT, lo); | ||||
|                 lemma |= ineq(q, llc::GE, div_v); | ||||
|  |  | |||
|  | @ -142,7 +142,7 @@ namespace nla { | |||
|             ineq new_eq(v, llc::EQ, rational::zero()); | ||||
|             if (c().ineq_holds(new_eq)) | ||||
|                 return false; | ||||
|             new_lemma lemma(c(), "pdd-eq"); | ||||
|             lemma_builder lemma(c(), "pdd-eq"); | ||||
|             add_dependencies(lemma, eq); | ||||
|             lemma |= new_eq; | ||||
|             return true; | ||||
|  | @ -159,7 +159,7 @@ namespace nla { | |||
|             ineq new_eq(term(a, v), llc::EQ, b); | ||||
|             if (c().ineq_holds(new_eq)) | ||||
|                 return false; | ||||
|             new_lemma lemma(c(), "pdd-eq"); | ||||
|             lemma_builder lemma(c(), "pdd-eq"); | ||||
|             add_dependencies(lemma, eq); | ||||
|             lemma |= new_eq; | ||||
|             return true; | ||||
|  | @ -202,7 +202,7 @@ namespace nla { | |||
|             if (c().ineq_holds(i)) | ||||
|                 return false; | ||||
| 
 | ||||
|         new_lemma lemma(c(), "pdd-factored"); | ||||
|         lemma_builder lemma(c(), "pdd-factored"); | ||||
|         add_dependencies(lemma, eq); | ||||
|         for (auto const& i : ineqs) | ||||
|             lemma |= i; | ||||
|  | @ -219,7 +219,7 @@ namespace nla { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     void grobner::add_dependencies(new_lemma& lemma, const dd::solver::equation& eq) { | ||||
|     void grobner::add_dependencies(lemma_builder& lemma, const dd::solver::equation& eq) { | ||||
|         lp::explanation exp; | ||||
|         explain(eq, exp); | ||||
|         lemma &= exp; | ||||
|  | @ -344,7 +344,7 @@ namespace nla { | |||
|         } | ||||
|         evali.get_interval<dd::w_dep::with_deps>(e.poly(), i_wd);   | ||||
|         std::function<void (const lp::explanation&)> f = [this](const lp::explanation& e) { | ||||
|             new_lemma lemma(m_core, "pdd"); | ||||
|             lemma_builder lemma(m_core, "pdd"); | ||||
|             lemma &= e; | ||||
|         }; | ||||
|         if (di.check_interval_for_conflict_on_zero(i_wd, e.dep(), f)) { | ||||
|  | @ -686,7 +686,7 @@ namespace nla { | |||
| 
 | ||||
|     bool grobner::add_nla_conflict(const dd::solver::equation& eq) { | ||||
|         if (is_nla_conflict(eq)) { | ||||
|             new_lemma lemma(m_core,"nla-conflict"); | ||||
|             lemma_builder lemma(m_core,"nla-conflict"); | ||||
|             lp::explanation exp; | ||||
|             explain(eq, exp); | ||||
|             lemma &= exp; | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ namespace nla { | |||
|         bool propagate_linear_equations(); | ||||
|         bool propagate_linear_equations(dd::solver::equation const& eq); | ||||
|          | ||||
|         void add_dependencies(new_lemma& lemma, dd::solver::equation const& eq); | ||||
|         void add_dependencies(lemma_builder& lemma, dd::solver::equation const& eq); | ||||
|         void explain(dd::solver::equation const& eq, lp::explanation& exp); | ||||
| 
 | ||||
|         bool add_horner_conflict(dd::solver::equation const& eq); | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ bool intervals::check_nex(const nex* n, u_dependency* initial_deps) { | |||
|     m_core->lp_settings().stats().m_cross_nested_forms++; | ||||
|     scoped_dep_interval i(get_dep_intervals()); | ||||
|     std::function<void (const lp::explanation&)> f = [this](const lp::explanation& e) { | ||||
|         new_lemma lemma(*m_core, "check_nex"); | ||||
|         lemma_builder lemma(*m_core, "check_nex"); | ||||
|         lemma &= e; | ||||
|     }; | ||||
|     if (!interval_of_expr<e_with_deps::without_deps>(n, 1, i, f)) { | ||||
|  |  | |||
|  | @ -54,7 +54,7 @@ void monotone::monotonicity_lemma(monic const& m) { | |||
|      | ||||
| */ | ||||
| void monotone::monotonicity_lemma_gt(const monic& m) { | ||||
|     new_lemma lemma(c(), "monotonicity > "); | ||||
|     lemma_builder lemma(c(), "monotonicity > "); | ||||
|     rational product(1); | ||||
|     for (lpvar j : m.vars()) { | ||||
|         auto v = c().val(j); | ||||
|  | @ -76,7 +76,7 @@ void monotone::monotonicity_lemma_gt(const monic& m) { | |||
|     x <= -2 & y >= 3 => x*y <= -6 | ||||
| */ | ||||
| void monotone::monotonicity_lemma_lt(const monic& m) { | ||||
|     new_lemma lemma(c(), "monotonicity <"); | ||||
|     lemma_builder lemma(c(), "monotonicity <"); | ||||
|     rational product(1); | ||||
|     for (lpvar j : m.vars()) { | ||||
|         auto v = c().val(j); | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include "math/lp/nla_core.h" | ||||
| #include "math/lp/nla_common.h" | ||||
| #include "math/lp/factorization_factory_imp.h" | ||||
| #include "util/trail.h" | ||||
| 
 | ||||
| namespace nla { | ||||
| 
 | ||||
|  | @ -83,17 +84,33 @@ void order::order_lemma_on_binomial(const monic& ac) { | |||
| void order::order_lemma_on_binomial_sign(const monic& xy, lpvar x, lpvar y, int sign) { | ||||
|     if (!c().var_is_int(x) && val(x).is_big()) | ||||
|         return; | ||||
|     if (&xy == m_last_binom) | ||||
|         return; | ||||
|     c().trail().push(value_trail(m_last_binom, &xy)); | ||||
|     // throttle!!!
 | ||||
| 
 | ||||
|     SASSERT(!_().mon_has_zero(xy.vars())); | ||||
|     int sy = rat_sign(val(y)); | ||||
|     new_lemma lemma(c(), __FUNCTION__); | ||||
|     lemma_builder lemma(c(), __FUNCTION__); | ||||
|     lemma |= ineq(y,                                   sy == 1      ? llc::LE : llc::GE, 0); // negate sy
 | ||||
|     lemma |= ineq(x,                                   sy*sign == 1 ? llc::GT : llc::LT , val(x));  | ||||
|     lemma |= ineq(term(xy.var(), - val(x), y), sign == 1    ? llc::LE : llc::GE, 0); | ||||
| } | ||||
| 
 | ||||
| bool order::throttle_monic(const monic& ac, std::string const & debug_location ) { // todo - remove debug location!
 | ||||
|     // Check if throttling is enabled
 | ||||
|     if (!c().params().arith_nl_thrl()) | ||||
|         return false; | ||||
|      | ||||
|     // Check if this monic has already been processed using its variable ID
 | ||||
|     if (m_processed_monics.contains(ac.var())) { | ||||
|         TRACE(nla_solver, tout << "throttled at " << debug_location << "\n";); | ||||
|         return true; | ||||
|     } | ||||
|      | ||||
|     // Mark this monic as processed and add to trail for backtracking
 | ||||
|     m_processed_monics.insert(ac.var()); | ||||
|     c().trail().push(insert_map(m_processed_monics, ac.var())); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // We look for monics e = m.rvars()[k]*d and see if we can create an order lemma for m and  e
 | ||||
| void order::order_lemma_on_factor_binomial_explore(const monic& ac, bool k) { | ||||
|     TRACE(nla_solver, tout << "ac = " <<  pp_mon_with_vars(c(), ac);); | ||||
|  | @ -170,7 +187,7 @@ void order::generate_mon_ol(const monic& ac, | |||
|     SASSERT(ab_cmp != llc::LT || (var_val(ac) >= var_val(bd) && val(a)*c_sign < val(b)*d_sign)); | ||||
|     SASSERT(ab_cmp != llc::GT || (var_val(ac) <= var_val(bd) && val(a)*c_sign > val(b)*d_sign)); | ||||
|      | ||||
|     new_lemma lemma(_(), __FUNCTION__); | ||||
|     lemma_builder lemma(_(), __FUNCTION__); | ||||
|     lemma |= ineq(term(c_sign, c), llc::LE, 0); | ||||
|     lemma &= c; // this explains c == +- d
 | ||||
|     lemma |= ineq(term(c_sign, a, -d_sign * b.rat_sign(), b.var()), negate(ab_cmp), 0); | ||||
|  | @ -220,7 +237,7 @@ void order::order_lemma_on_factorization(const monic& m, const factorization& ab | |||
|     if (mv != fv && !c().has_real(m)) {             | ||||
|         bool gt = mv > fv; | ||||
|         for (unsigned j = 0, k = 1; j < 2; j++, k--) { | ||||
|             new_lemma lemma(_(), __FUNCTION__); | ||||
|             lemma_builder lemma(_(), __FUNCTION__); | ||||
|             order_lemma_on_ab(lemma, m, rsign, var(ab[k]), var(ab[j]), gt); | ||||
|             lemma &= ab; | ||||
|             lemma &= m; | ||||
|  | @ -255,7 +272,7 @@ void order::generate_ol_eq(const monic& ac, | |||
|                         const monic& bc, | ||||
|                         const factor& b) { | ||||
|      | ||||
|     new_lemma lemma(_(), __FUNCTION__); | ||||
|     lemma_builder lemma(_(), __FUNCTION__); | ||||
|     IF_VERBOSE(100,  | ||||
|                verbose_stream()  | ||||
|                << var_val(ac) << "(" << mul_val(ac) << "): " << ac  | ||||
|  | @ -280,7 +297,7 @@ void order::generate_ol(const monic& ac, | |||
|                         const monic& bc, | ||||
|                         const factor& b) { | ||||
|      | ||||
|     new_lemma lemma(_(), __FUNCTION__); | ||||
|     lemma_builder lemma(_(), __FUNCTION__); | ||||
|     TRACE(nla_solver, _().trace_print_ol(ac, a, c, bc, b, tout););         | ||||
|     IF_VERBOSE(10, verbose_stream() << var_val(ac) << "(" << mul_val(ac) << "): " << ac  | ||||
|                << " " << var_val(bc) << "(" << mul_val(bc) << "): " << bc << "\n" | ||||
|  | @ -335,7 +352,7 @@ bool order::order_lemma_on_ac_and_bc_and_factors(const monic& ac, | |||
|    given: sign * m = ab | ||||
|    lemma b != val(b) || sign*m <= a*val(b) | ||||
| */ | ||||
| void order::order_lemma_on_ab_gt(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b) { | ||||
| void order::order_lemma_on_ab_gt(lemma_builder& lemma, const monic& m, const rational& sign, lpvar a, lpvar b) { | ||||
|     SASSERT(sign * var_val(m) > val(a) * val(b)); | ||||
|     // negate b == val(b)
 | ||||
|     lemma |= ineq(b, llc::NE, val(b)); | ||||
|  | @ -346,7 +363,7 @@ void order::order_lemma_on_ab_gt(new_lemma& lemma, const monic& m, const rationa | |||
|    given: sign * m = ab | ||||
|    lemma b != val(b) || sign*m >= a*val(b) | ||||
| */ | ||||
| void order::order_lemma_on_ab_lt(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b) { | ||||
| void order::order_lemma_on_ab_lt(lemma_builder& lemma, const monic& m, const rational& sign, lpvar a, lpvar b) { | ||||
|     TRACE(nla_solver, tout << "sign = " << sign << ", m = "; c().print_monic(m, tout) << ", a = "; c().print_var(a, tout) << | ||||
|           ", b = "; c().print_var(b, tout) << "\n";); | ||||
|     SASSERT(sign * var_val(m) < val(a) * val(b)); | ||||
|  | @ -356,7 +373,7 @@ void order::order_lemma_on_ab_lt(new_lemma& lemma, const monic& m, const rationa | |||
|     lemma |= ineq(term(sign, m.var(), -val(b), a), llc::GE, 0); | ||||
| } | ||||
| 
 | ||||
| void order::order_lemma_on_ab(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b, bool gt) { | ||||
| void order::order_lemma_on_ab(lemma_builder& lemma, const monic& m, const rational& sign, lpvar a, lpvar b, bool gt) { | ||||
|     if (gt) | ||||
|         order_lemma_on_ab_gt(lemma, m, sign, a, b); | ||||
|     else  | ||||
|  |  | |||
|  | @ -9,17 +9,19 @@ | |||
| #pragma once | ||||
| #include "math/lp/factorization.h" | ||||
| #include "math/lp/nla_common.h" | ||||
| #include "util/hashtable.h" | ||||
| #include "util/hash.h" | ||||
| 
 | ||||
| namespace nla { | ||||
| class core; | ||||
| class new_lemma; | ||||
| class lemma_builder; | ||||
| class order: common { | ||||
| public: | ||||
|     order(core *c) : common(c) {} | ||||
|     void order_lemma(); | ||||
|      | ||||
|     monic const* m_last_binom = nullptr; | ||||
| 
 | ||||
|     int_hashtable<int_hash, default_eq<int>> m_processed_monics; | ||||
|     bool throttle_monic(const monic&, const std::string & debug_location); | ||||
|    private: | ||||
| 
 | ||||
|     bool order_lemma_on_ac_and_bc_and_factors(const monic& ac, | ||||
|  | @ -41,9 +43,9 @@ public: | |||
|     void order_lemma_on_factorization(const monic& rm, const factorization& ab); | ||||
|      | ||||
| 
 | ||||
|     void order_lemma_on_ab_gt(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b); | ||||
|     void order_lemma_on_ab_lt(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b); | ||||
|     void order_lemma_on_ab(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b, bool gt); | ||||
|     void order_lemma_on_ab_gt(lemma_builder& lemma, const monic& m, const rational& sign, lpvar a, lpvar b); | ||||
|     void order_lemma_on_ab_lt(lemma_builder& lemma, const monic& m, const rational& sign, lpvar a, lpvar b); | ||||
|     void order_lemma_on_ab(lemma_builder& lemma, const monic& m, const rational& sign, lpvar a, lpvar b, bool gt); | ||||
|     void order_lemma_on_factor_binomial_explore(const monic& m, bool k); | ||||
|     void order_lemma_on_factor_binomial_rm(const monic& ac, bool k, const monic& bd); | ||||
|     void order_lemma_on_binomial_ac_bd(const monic& ac, bool k, const monic& bd, const factor& b, lpvar d); | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ namespace nla { | |||
|         lemmas.reset(); | ||||
| 
 | ||||
|         auto x_exp_0 = [&]() { | ||||
|             new_lemma lemma(c, "x != 0 => x^0 = 1"); | ||||
|             lemma_builder lemma(c, "x != 0 => x^0 = 1"); | ||||
|             lemma |= ineq(x, llc::EQ, rational::zero()); | ||||
|             lemma |= ineq(y, llc::NE, rational::zero()); | ||||
|             lemma |= ineq(r, llc::EQ, rational::one()); | ||||
|  | @ -97,7 +97,7 @@ namespace nla { | |||
|         }; | ||||
| 
 | ||||
|         auto zero_exp_y = [&]() { | ||||
|             new_lemma lemma(c, "y != 0 => 0^y = 0"); | ||||
|             lemma_builder lemma(c, "y != 0 => 0^y = 0"); | ||||
|             lemma |= ineq(x, llc::NE, rational::zero()); | ||||
|             lemma |= ineq(y, llc::EQ, rational::zero()); | ||||
|             lemma |= ineq(r, llc::EQ, rational::zero()); | ||||
|  | @ -105,14 +105,14 @@ namespace nla { | |||
|         }; | ||||
| 
 | ||||
|         auto x_gt_0 = [&]() { | ||||
|             new_lemma lemma(c, "x > 0 => x^y > 0"); | ||||
|             lemma_builder lemma(c, "x > 0 => x^y > 0"); | ||||
|             lemma |= ineq(x, llc::LE, rational::zero()); | ||||
|             lemma |= ineq(r, llc::GT, rational::zero()); | ||||
|             return l_false; | ||||
|         }; | ||||
| 
 | ||||
|         auto y_lt_1 = [&]() { | ||||
|             new_lemma lemma(c, "x > 1, y < 0 => x^y < 1"); | ||||
|             lemma_builder lemma(c, "x > 1, y < 0 => x^y < 1"); | ||||
|             lemma |= ineq(x, llc::LE, rational::one()); | ||||
|             lemma |= ineq(y, llc::GE, rational::zero()); | ||||
|             lemma |= ineq(r, llc::LT, rational::one()); | ||||
|  | @ -120,7 +120,7 @@ namespace nla { | |||
|         }; | ||||
| 
 | ||||
|         auto y_gt_1 = [&]() { | ||||
|             new_lemma lemma(c, "x > 1, y > 0 => x^y > 1"); | ||||
|             lemma_builder lemma(c, "x > 1, y > 0 => x^y > 1"); | ||||
|             lemma |= ineq(x, llc::LE, rational::one()); | ||||
|             lemma |= ineq(y, llc::LE, rational::zero()); | ||||
|             lemma |= ineq(r, llc::GT, rational::one()); | ||||
|  | @ -128,7 +128,7 @@ namespace nla { | |||
|         }; | ||||
| 
 | ||||
|         auto x_ge_3 = [&]() { | ||||
|             new_lemma lemma(c, "x >= 3, y != 0 => x^y > ln(x)y + 1"); | ||||
|             lemma_builder lemma(c, "x >= 3, y != 0 => x^y > ln(x)y + 1"); | ||||
|             lemma |= ineq(x, llc::LT, rational(3)); | ||||
|             lemma |= ineq(y, llc::EQ, rational::zero()); | ||||
|             lemma |= ineq(lp::lar_term(r, rational::minus_one(), y), llc::GT, rational::one()); | ||||
|  | @ -172,21 +172,21 @@ namespace nla { | |||
|                 if (rval == r2val) | ||||
|                     return l_true; | ||||
|                 if (c.random() % 2 == 0) { | ||||
|                     new_lemma lemma(c, "x == x0, y == y0 => r = x0^y0"); | ||||
|                     lemma_builder lemma(c, "x == x0, y == y0 => r = x0^y0"); | ||||
|                     lemma |= ineq(x, llc::NE, xval); | ||||
|                     lemma |= ineq(y, llc::NE, yval); | ||||
|                     lemma |= ineq(r, llc::EQ, r2val); | ||||
|                     return l_false; | ||||
|                 } | ||||
|                 if (yval > 0 && r2val > rval) { | ||||
|                     new_lemma lemma(c, "x >= x0 > 0, y >= y0 > 0 => r >= x0^y0"); | ||||
|                     lemma_builder lemma(c, "x >= x0 > 0, y >= y0 > 0 => r >= x0^y0"); | ||||
|                     lemma |= ineq(x, llc::LT, xval); | ||||
|                     lemma |= ineq(y, llc::LT, yval); | ||||
|                     lemma |= ineq(r, llc::GE, r2val); | ||||
|                     return l_false; | ||||
|                 } | ||||
|                 if (r2val < rval) { | ||||
|                     new_lemma lemma(c, "0 < x <= x0, y <= y0 => r <= x0^y0"); | ||||
|                     lemma_builder lemma(c, "0 < x <= x0, y <= y0 => r <= x0^y0"); | ||||
|                     lemma |= ineq(x, llc::LE, rational::zero()); | ||||
|                     lemma |= ineq(x, llc::GT, xval); | ||||
|                     lemma |= ineq(y, llc::GT, yval); | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ private: | |||
| 
 | ||||
|     core & c() { return m_tang.c(); } | ||||
| 
 | ||||
|     void explain(new_lemma& lemma) { | ||||
|     void explain(lemma_builder& lemma) { | ||||
|         if (!m_is_mon) { | ||||
|             lemma &= m_m; | ||||
|             lemma &= m_x; | ||||
|  | @ -70,7 +70,7 @@ private: | |||
|     } | ||||
| 
 | ||||
|     void generate_plane(const point & pl) { | ||||
|         new_lemma lemma(c(), "generate tangent plane"); | ||||
|         lemma_builder lemma(c(), "generate tangent plane"); | ||||
|         c().negate_relation(lemma, m_jx, m_x.rat_sign()*pl.x); | ||||
|         c().negate_relation(lemma, m_jy, m_y.rat_sign()*pl.y); | ||||
| #if Z3DEBUG | ||||
|  | @ -91,7 +91,7 @@ private: | |||
|     } | ||||
| 
 | ||||
|     void generate_line1() { | ||||
|         new_lemma lemma(c(), "tangent line 1"); | ||||
|         lemma_builder lemma(c(), "tangent line 1"); | ||||
|         // Should be  v = val(m_x)*val(m_y), and val(factor) = factor.rat_sign()*var(factor.var())
 | ||||
|         lemma |= ineq(m_jx, llc::NE, c().val(m_jx)); | ||||
|         lemma |= ineq(lp::lar_term(m_j,  - m_y.rat_sign() * m_xy.x,  m_jy), llc::EQ, 0); | ||||
|  | @ -99,7 +99,7 @@ private: | |||
|     } | ||||
| 
 | ||||
|     void generate_line2() {             | ||||
|         new_lemma lemma(c(), "tangent line 2"); | ||||
|         lemma_builder lemma(c(), "tangent line 2"); | ||||
|         lemma |= ineq(m_jy, llc::NE, c().val(m_jy)); | ||||
|         lemma |= ineq(lp::lar_term(m_j, - m_x.rat_sign() * m_xy.y, m_jx), llc::EQ, 0); | ||||
|         explain(lemma); | ||||
|  |  | |||
|  | @ -69,27 +69,27 @@ namespace nla { | |||
|     // all constraints are assumed added to the lemma
 | ||||
|     // correctness of the lemma can be checked at this point.
 | ||||
|     //
 | ||||
|     class new_lemma { | ||||
|     class lemma_builder { | ||||
|         char const* name; | ||||
|         core& c; | ||||
|         lemma& current() const; | ||||
|          | ||||
|     public: | ||||
|         new_lemma(core& c, char const* name); | ||||
|         ~new_lemma(); | ||||
|         lemma_builder(core& c, char const* name); | ||||
|         ~lemma_builder(); | ||||
|         lemma& operator()() { return current(); } | ||||
|         std::ostream& display(std::ostream& out) const; | ||||
|         new_lemma& operator&=(lp::explanation const& e); | ||||
|         new_lemma& operator&=(const monic& m); | ||||
|         new_lemma& operator&=(const factor& f); | ||||
|         new_lemma& operator&=(const factorization& f); | ||||
|         new_lemma& operator&=(lpvar j); | ||||
|         new_lemma& operator|=(ineq const& i); | ||||
|         new_lemma& explain_fixed(lpvar j); | ||||
|         new_lemma& explain_equiv(lpvar u, lpvar v); | ||||
|         new_lemma& explain_var_separated_from_zero(lpvar j); | ||||
|         new_lemma& explain_existing_lower_bound(lpvar j); | ||||
|         new_lemma& explain_existing_upper_bound(lpvar j);     | ||||
|         lemma_builder& operator&=(lp::explanation const& e); | ||||
|         lemma_builder& operator&=(const monic& m); | ||||
|         lemma_builder& operator&=(const factor& f); | ||||
|         lemma_builder& operator&=(const factorization& f); | ||||
|         lemma_builder& operator&=(lpvar j); | ||||
|         lemma_builder& operator|=(ineq const& i); | ||||
|         lemma_builder& explain_fixed(lpvar j); | ||||
|         lemma_builder& explain_equiv(lpvar u, lpvar v); | ||||
|         lemma_builder& explain_var_separated_from_zero(lpvar j); | ||||
|         lemma_builder& explain_existing_lower_bound(lpvar j); | ||||
|         lemma_builder& explain_existing_upper_bound(lpvar j);     | ||||
|          | ||||
|         lp::explanation& expl() { return current().expl(); } | ||||
|          | ||||
|  | @ -97,7 +97,7 @@ namespace nla { | |||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     inline std::ostream& operator<<(std::ostream& out, new_lemma const& l) { | ||||
|     inline std::ostream& operator<<(std::ostream& out, lemma_builder const& l) { | ||||
|         return l.display(out); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -228,7 +228,7 @@ struct solver::imp { | |||
|                 ex.push_back(idx); | ||||
|                 TRACE(nra, lra.display_constraint(tout << "ex: " << idx << ": ", idx) << "\n";); | ||||
|             } | ||||
|             nla::new_lemma lemma(m_nla_core, __FUNCTION__); | ||||
|             nla::lemma_builder lemma(m_nla_core, __FUNCTION__); | ||||
|             lemma &= ex; | ||||
|             m_nla_core.set_use_nra_model(true); | ||||
|             break; | ||||
|  | @ -416,7 +416,7 @@ struct solver::imp { | |||
|                 dm.linearize(static_cast<u_dependency*>(c), lv); | ||||
|             for (auto ci : lv) | ||||
|                 ex.push_back(ci); | ||||
|             nla::new_lemma lemma(m_nla_core, __FUNCTION__); | ||||
|             nla::lemma_builder lemma(m_nla_core, __FUNCTION__); | ||||
|             lemma &= ex; | ||||
|             break; | ||||
|         } | ||||
|  |  | |||
|  | @ -65,6 +65,7 @@ def_module_params(module_name='smt', | |||
|                           ('arith.nl.order', BOOL, True, 'run order lemmas'), | ||||
|                           ('arith.nl.expp', BOOL, False, 'expensive patching'), | ||||
|                           ('arith.nl.tangents', BOOL, True, 'run tangent lemmas'), | ||||
|                           ('arith.nl.thrl', BOOL, True, 'throttle repeated lemmas - debug, remove later!!!'), | ||||
|                           ('arith.nl.horner', BOOL, True, 'run horner\'s heuristic'), | ||||
|                           ('arith.nl.horner_subs_fixed', UINT, 2, '0 - no subs, 1 - substitute, 2 - substitute fixed zeros only'), | ||||
|                           ('arith.nl.horner_frequency', UINT, 4, 'horner\'s call frequency'), | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue