3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 11:25:51 +00:00

mv util/lp to math/lp

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-06-03 16:46:19 -07:00
parent b6513b8e2d
commit 33cbd29ed0
150 changed files with 524 additions and 479 deletions

View file

@ -0,0 +1,121 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Nikolaj Bjorner (nbjorner)
Lev Nachmanson (levnach)
Revision History:
--*/
#include "math/lp/nla_basics_lemmas.h"
#include "math/lp/nla_core.h"
// #include "math/lp/factorization_factory_imp.h"
namespace nla {
monotone::monotone(core * c) : common(c) {}
void monotone::monotonicity_lemma() {
unsigned shift = random();
unsigned size = c().m_to_refine.size();
for(unsigned i = 0; i < size && !done(); i++) {
lpvar v = c().m_to_refine[(i + shift) % size];
monotonicity_lemma(c().m_emons[v]);
}
}
void monotone::negate_abs_a_le_abs_b(lpvar a, lpvar b, bool strict) {
rational av = val(a);
rational as = rational(nla::rat_sign(av));
rational bv = val(b);
rational bs = rational(nla::rat_sign(bv));
TRACE("nla_solver", tout << "av = " << av << ", bv = " << bv << "\n";);
SASSERT(as*av <= bs*bv);
llc mod_s = strict? (llc::LE): (llc::LT);
mk_ineq(as, a, mod_s); // |a| <= 0 || |a| < 0
if (a != b) {
mk_ineq(bs, b, mod_s); // |b| <= 0 || |b| < 0
mk_ineq(as, a, -bs, b, llc::GT); // negate |aj| <= |bj|
}
}
void monotone::assert_abs_val_a_le_abs_var_b(
const monomial& a,
const monomial& b,
bool strict) {
lpvar aj = var(a);
lpvar bj = var(b);
rational av = val(aj);
rational as = rational(nla::rat_sign(av));
rational bv = val(bj);
rational bs = rational(nla::rat_sign(bv));
// TRACE("nla_solver", tout << "rmv = " << rmv << ", jv = " << jv << "\n";);
mk_ineq(as, aj, llc::LT); // |aj| < 0
mk_ineq(bs, bj, llc::LT); // |bj| < 0
mk_ineq(as, aj, -bs, bj, strict? llc::LT : llc::LE); // |aj| < |bj|
}
void monotone::negate_abs_a_lt_abs_b(lpvar a, lpvar b) {
rational av = val(a);
rational as = rational(nla::rat_sign(av));
rational bv = val(b);
rational bs = rational(nla::rat_sign(bv));
TRACE("nla_solver", tout << "av = " << av << ", bv = " << bv << "\n";);
SASSERT(as*av < bs*bv);
mk_ineq(as, a, llc::LT); // |aj| < 0
mk_ineq(bs, b, llc::LT); // |bj| < 0
mk_ineq(as, a, -bs, b, llc::GE); // negate |aj| < |bj|
}
void monotone::monotonicity_lemma(monomial const& m) {
SASSERT(!check_monomial(m));
if (c().mon_has_zero(m.vars()))
return;
const rational prod_val = abs(c().product_value(m.vars()));
const rational m_val = abs(val(m));
if (m_val < prod_val)
monotonicity_lemma_lt(m, prod_val);
else if (m_val > prod_val)
monotonicity_lemma_gt(m, prod_val);
}
void monotone::monotonicity_lemma_gt(const monomial& m, const rational& prod_val) {
TRACE("nla_solver", tout << "prod_val = " << prod_val << "\n";);
add_empty_lemma();
for (lpvar j : m.vars()) {
c().add_abs_bound(j, llc::GT);
}
lpvar m_j = m.var();
c().add_abs_bound(m_j, llc::LE, prod_val);
TRACE("nla_solver", print_lemma(tout););
}
/** \brief enforce the inequality |m| >= product |m[i]| .
/\_i |m[i]| >= |val(m[i])| => |m| >= |product_i val(m[i])|
<=>
\/_i |m[i]| < |val(m[i])} or |m| >= |product_i val(m[i])|
*/
void monotone::monotonicity_lemma_lt(const monomial& m, const rational& prod_val) {
add_empty_lemma();
for (lpvar j : m.vars()) {
c().add_abs_bound(j, llc::LT);
}
lpvar m_j = m.var();
c().add_abs_bound(m_j, llc::GE, prod_val);
TRACE("nla_solver", print_lemma(tout););
}
}