z3-z3-4.13.0.src.math.lp.nla_defs.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2017 Microsoft Corporation
Author:
Lev Nachmanson (levnach)
Nikolaj Bjorner (nbjorner)
--*/
#pragma once
#include "math/lp/lp_types.h"
#include "math/lp/column_info.h"
#include "math/lp/explanation.h"
namespace nla {
typedef lp::constraint_index lpci;
typedef lp::lconstraint_kind llc;
typedef lp::explanation expl_set;
typedef unsigned lpvar;
struct from_index_dummy{};
class signed_var {
unsigned m_sv;
public:
// constructor, sign = true means minus
signed_var(lpvar v, bool sign): m_sv((v << 1) + (sign ? 1 : 0)) {}
explicit signed_var(unsigned sv) : m_sv(sv) {}
// constructor
bool sign() const { return 0 != (m_sv & 0x1); }
lpvar var() const { return m_sv >> 1; }
unsigned index() const { return m_sv; }
void neg() { m_sv = m_sv ^ 1; }
friend signed_var operator~(signed_var const& sv) {
return signed_var(sv.var(), !sv.sign());
}
bool operator==(signed_var const& other) const {
return m_sv == other.m_sv;
}
bool operator!=(signed_var const& other) const {
return m_sv != other.m_sv;
}
rational rsign() const { return sign() ? rational::minus_one() : rational::one(); }
std::ostream& display(std::ostream& out) const {
return out << (sign()?"-":"") << var();
}
};
inline std::ostream& operator<<(std::ostream& out, signed_var const& sv) { return sv.display(out); }
/*
* represents definition m_v = coeff* v1*v2*...*vn,
* where m_vs = [v1, v2, .., vn]
*/
class monic_coeff {
svector m_vs;
rational m_coeff;
public:
monic_coeff(const svector& vs, rational const& coeff): m_vs(vs), m_coeff(coeff) {}
rational const& coeff() const { return m_coeff; }
const svector & vars() const { return m_vs; }
};
template bool has_zero(const T& product) {
for (const rational & t : product) {
if (t.is_zero())
return true;
}
return false;
}
template
bool uniform_le(const T& a, const T& b, unsigned & strict_i) {
SASSERT(a.size() == b.size());
strict_i = -1;
bool z_b = false;
for (unsigned i = 0; i < a.size(); i++) {
if (a[i] > b[i]){
return false;
}
SASSERT(!a[i].is_neg());
if (a[i] < b[i]){
strict_i = i;
} else if (b[i].is_zero()) {
z_b = true;
}
}
if (z_b) {strict_i = -1;}
return true;
}
inline rational sign_to_rat(bool s) { return rational(s? -1 : 1); }
}