mirror of
https://github.com/Z3Prover/z3
synced 2025-06-25 15:23:41 +00:00
throttle tangent plane lemmas
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
740c6945c6
commit
521f6a6543
4 changed files with 69 additions and 12 deletions
|
@ -84,7 +84,7 @@ 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) {
|
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())
|
if (!c().var_is_int(x) && val(x).is_big())
|
||||||
return;
|
return;
|
||||||
if (throttle_monic(xy))
|
if (throttle_monic(xy, std::string(__FILE__)+ "," + std::to_string(__LINE__)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SASSERT(!_().mon_has_zero(xy.vars()));
|
SASSERT(!_().mon_has_zero(xy.vars()));
|
||||||
|
@ -95,14 +95,16 @@ void order::order_lemma_on_binomial_sign(const monic& xy, lpvar x, lpvar y, int
|
||||||
lemma |= ineq(term(xy.var(), - val(x), y), sign == 1 ? llc::LE : llc::GE, 0);
|
lemma |= ineq(term(xy.var(), - val(x), y), sign == 1 ? llc::LE : llc::GE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool order::throttle_monic(const monic& ac) {
|
bool order::throttle_monic(const monic& ac, std::string const & debug_location ) {
|
||||||
// Check if this monic has already been processed using its variable ID
|
// Check if this monic has already been processed using its variable ID
|
||||||
if (m_processed_binoms.contains(ac.var()))
|
if (m_processed_monics.contains(ac.var())) {
|
||||||
|
std::cout << "throttled at " << debug_location << "\n";
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Mark this monic as processed and add to trail for backtracking
|
// Mark this monic as processed and add to trail for backtracking
|
||||||
m_processed_binoms.insert(ac.var());
|
m_processed_monics.insert(ac.var());
|
||||||
c().trail().push(insert_map(m_processed_binoms, ac.var()));
|
c().trail().push(insert_map(m_processed_monics, ac.var()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +112,7 @@ bool order::throttle_monic(const monic& ac) {
|
||||||
void order::order_lemma_on_factor_binomial_explore(const monic& ac, bool k) {
|
void order::order_lemma_on_factor_binomial_explore(const monic& ac, bool k) {
|
||||||
TRACE(nla_solver, tout << "ac = " << pp_mon_with_vars(c(), ac););
|
TRACE(nla_solver, tout << "ac = " << pp_mon_with_vars(c(), ac););
|
||||||
SASSERT(ac.size() == 2);
|
SASSERT(ac.size() == 2);
|
||||||
|
|
||||||
if (throttle_monic(ac))
|
|
||||||
return;
|
|
||||||
|
|
||||||
lpvar c_var = ac.vars()[k];
|
lpvar c_var = ac.vars()[k];
|
||||||
|
|
||||||
for (monic const& bd : _().emons().get_products_of(c_var)) {
|
for (monic const& bd : _().emons().get_products_of(c_var)) {
|
||||||
|
@ -363,6 +362,8 @@ void order::order_lemma_on_ab_gt(new_lemma& lemma, const monic& m, const rationa
|
||||||
lemma b != val(b) || sign*m >= a*val(b)
|
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(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b) {
|
||||||
|
if (throttle_monic(m, std::string(__FILE__)+ "," + std::to_string(__LINE__)))
|
||||||
|
return;
|
||||||
TRACE(nla_solver, tout << "sign = " << sign << ", m = "; c().print_monic(m, tout) << ", a = "; c().print_var(a, tout) <<
|
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";);
|
", b = "; c().print_var(b, tout) << "\n";);
|
||||||
SASSERT(sign * var_val(m) < val(a) * val(b));
|
SASSERT(sign * var_val(m) < val(a) * val(b));
|
||||||
|
@ -373,6 +374,8 @@ void order::order_lemma_on_ab_lt(new_lemma& lemma, const monic& m, const rationa
|
||||||
}
|
}
|
||||||
|
|
||||||
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(new_lemma& lemma, const monic& m, const rational& sign, lpvar a, lpvar b, bool gt) {
|
||||||
|
if (throttle_monic(m, std::string(__FILE__)+ "," + std::to_string(__LINE__)))
|
||||||
|
return;
|
||||||
if (gt)
|
if (gt)
|
||||||
order_lemma_on_ab_gt(lemma, m, sign, a, b);
|
order_lemma_on_ab_gt(lemma, m, sign, a, b);
|
||||||
else
|
else
|
||||||
|
|
|
@ -20,8 +20,8 @@ public:
|
||||||
order(core *c) : common(c) {}
|
order(core *c) : common(c) {}
|
||||||
void order_lemma();
|
void order_lemma();
|
||||||
|
|
||||||
int_hashtable<int_hash, default_eq<int>> m_processed_binoms;
|
int_hashtable<int_hash, default_eq<int>> m_processed_monics;
|
||||||
bool throttle_monic(const monic&);
|
bool throttle_monic(const monic&, const std::string & debug_location);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool order_lemma_on_ac_and_bc_and_factors(const monic& ac,
|
bool order_lemma_on_ac_and_bc_and_factors(const monic& ac,
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
--*/
|
--*/
|
||||||
#include "math/lp/nla_tangent_lemmas.h"
|
#include "math/lp/nla_tangent_lemmas.h"
|
||||||
#include "math/lp/nla_core.h"
|
#include "math/lp/nla_core.h"
|
||||||
|
#include "util/trail.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace nla {
|
namespace nla {
|
||||||
|
|
||||||
|
@ -70,6 +72,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_plane(const point & pl) {
|
void generate_plane(const point & pl) {
|
||||||
|
// Throttle plane generation based on m_xy.var() and m_below
|
||||||
|
if (m_tang.throttle_plane(m_j, m_below, std::string(__FILE__) + "," + std::to_string(__LINE__)))
|
||||||
|
return;
|
||||||
|
|
||||||
new_lemma lemma(c(), "generate tangent plane");
|
new_lemma lemma(c(), "generate tangent plane");
|
||||||
c().negate_relation(lemma, m_jx, m_x.rat_sign()*pl.x);
|
c().negate_relation(lemma, m_jx, m_x.rat_sign()*pl.x);
|
||||||
c().negate_relation(lemma, m_jy, m_y.rat_sign()*pl.y);
|
c().negate_relation(lemma, m_jy, m_y.rat_sign()*pl.y);
|
||||||
|
@ -193,5 +199,20 @@ void tangents::tangent_lemma() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tangents::throttle_plane(unsigned var, bool below, std::string const & debug_location) {
|
||||||
|
tangent_key key(var, below);
|
||||||
|
|
||||||
|
// Check if this (var, below) pair has already been processed
|
||||||
|
if (m_processed_planes.contains(key)) {
|
||||||
|
std::cout << "throttled plane at " << debug_location << " for var=" << var << ", below=" << below << "\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark this (var, below) pair as processed and add to trail for backtracking
|
||||||
|
m_processed_planes.insert(key);
|
||||||
|
c().trail().push(insert_map(m_processed_planes, key));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,37 @@
|
||||||
#include "util/rational.h"
|
#include "util/rational.h"
|
||||||
#include "math/lp/factorization.h"
|
#include "math/lp/factorization.h"
|
||||||
#include "math/lp/nla_common.h"
|
#include "math/lp/nla_common.h"
|
||||||
|
#include "util/hashtable.h"
|
||||||
|
#include "util/hash.h"
|
||||||
|
|
||||||
namespace nla {
|
namespace nla {
|
||||||
class core;
|
class core;
|
||||||
|
|
||||||
|
// Key for throttling tangent plane generation: (var, below)
|
||||||
|
struct tangent_key {
|
||||||
|
unsigned var;
|
||||||
|
bool below;
|
||||||
|
|
||||||
|
tangent_key(unsigned v, bool b) : var(v), below(b) {}
|
||||||
|
tangent_key() : var(0), below(false) {}
|
||||||
|
|
||||||
|
bool operator==(const tangent_key& other) const {
|
||||||
|
return var == other.var && below == other.below;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tangent_key_hash {
|
||||||
|
unsigned operator()(const tangent_key& k) const {
|
||||||
|
return hash_u(k.var) ^ (k.below ? 1 : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tangent_key_eq {
|
||||||
|
bool operator()(const tangent_key& a, const tangent_key& b) const {
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct point {
|
struct point {
|
||||||
rational x;
|
rational x;
|
||||||
rational y;
|
rational y;
|
||||||
|
@ -41,7 +68,13 @@ inline std::ostream& operator<<(std::ostream& out, point const& a) { return out
|
||||||
|
|
||||||
|
|
||||||
struct tangents : common {
|
struct tangents : common {
|
||||||
|
// Hashtable to throttle tangent plane generation
|
||||||
|
hashtable<tangent_key, tangent_key_hash, tangent_key_eq> m_processed_planes;
|
||||||
|
|
||||||
tangents(core *core);
|
tangents(core *core);
|
||||||
void tangent_lemma();
|
void tangent_lemma();
|
||||||
|
|
||||||
|
// Throttling function similar to order::throttle_monic
|
||||||
|
bool throttle_plane(unsigned var, bool below, std::string const & debug_location);
|
||||||
}; // end of tangents
|
}; // end of tangents
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue