z3-z3-4.13.0.src.math.lp.lp_utils.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
Abstract:
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include
#include "math/lp/numeric_pair.h"
#include "math/lp/lp_types.h"
#include "util/debug.h"
#include
#include
template
std::ostream& print_vector(const C & t, std::ostream & out) {
for (const auto & p : t)
out << p << " ";
return out;
}
template
std::ostream& print_vector_of_ptrs(const C & t, std::ostream & out) {
for (const auto & p : t)
out << (*p) << ", ";
return out;
}
template
bool contains(const C & collection, const D & key) {
return collection.find(key) != collection.end();
}
template
std::ostream& print_vector(const C * t, unsigned size, std::ostream & out) {
for (unsigned i = 0; i < size; i++ )
out << t[i] << " ";
out << std::endl;
return out;
}
template
bool try_get_value(const std::unordered_map & map, const A& key, B & val) {
const auto it = map.find(key);
if (it == map.end()) return false;
val = it->second;
return true;
}
template
bool contains(const std::unordered_map & map, const A& key) {
return map.find(key) != map.end();
}
#ifdef Z3DEBUG
#define Z3DEBUG 1
#endif
namespace lp {
template
bool is_non_decreasing(const K& v) {
auto a = v.begin();
if (a == v.end())
return true; // v is empty
auto b = v.begin();
b++;
for (; b != v.end(); a++, b++) {
if (*a > *b)
return false;
}
return true;
}
template
std::ostream& print_linear_combination_customized(const vector> & coeffs, std::function var_str, std::ostream & out) {
bool first = true;
for (const auto & it : coeffs) {
T val = it.first;
if (first) {
first = false;
if (val.is_neg()) {
out << "- ";
val = -val;
}
} else {
if (val.is_pos()) {
out << " + ";
} else {
out << " - ";
val = -val;
}
}
if (val != 1) {
out << T_to_string(val);
}
out << var_str(it.second);
}
return out;
}
template
std::ostream& print_linear_combination_of_column_indices_only(const vector> & coeffs, std::ostream & out) {
return print_linear_combination_customized(
coeffs,
[](unsigned j) {
std::stringstream ss;
ss << "j" << j;
return ss.str();},
out);
}
template
std::ostream& print_linear_combination_indices_only(const T & coeffs, std::ostream & out) {
vector> cfs;
for (const auto & it : coeffs) {
cfs.push_back(std::make_pair(it.coeff(), it.var()));
}
return print_linear_combination_of_column_indices_only(cfs, out);
}
inline void throw_exception(std::string && str) {
throw default_exception(std::move(str));
}
typedef z3_exception exception;
#define lp_assert(_x_) { SASSERT(_x_); }
template inline X zero_of_type() { return numeric_traits::zero(); }
template inline X one_of_type() { return numeric_traits::one(); }
template inline bool is_zero(const X & v) { return numeric_traits::is_zero(v); }
template inline bool is_pos(const X & v) { return numeric_traits::is_pos(v); }
template inline bool is_neg(const X & v) { return numeric_traits::is_neg(v); }
template inline bool is_integer(const X & v) { return numeric_traits::is_int(v); }
template inline X ceil_ratio(const X & a, const X & b) { return numeric_traits::ceil_ratio(a, b); }
template inline X floor_ratio(const X & a, const X & b) { return numeric_traits::floor_ratio(a, b); }
// returns true if a factor of b
template
bool is_proper_factor(const T & a, const T & b) {
if (a.size() >= b.size())
return false;
SASSERT(lp::is_non_decreasing(a) && lp::is_non_decreasing(b));
auto i = a.begin();
auto j = b.begin();
while (true) {
if (i == a.end()) {
return true;
}
if (j == b.end()) {
return false;
}
if (*i == *j) {
i++;j++;
continue;
}
j++;
}
}
// b / a, where a is a factor of b and both vectors are sorted
template
svector vector_div(const T & b, const T & a) {
SASSERT(lp::is_non_decreasing(a));
SASSERT(lp::is_non_decreasing(b));
SASSERT(is_proper_factor(a, b));
svector r;
auto i = a.begin();
auto j = b.begin();
while (true) {
if (j == b.end()) {
break;
}
if (i == a.end()) {
r.push_back(*j);
j++;
continue;
}
if (*i == *j) {
i++;j++;
continue;
}
r.push_back(*j);
j++;
}
return r;
}
} // namespace lp
namespace std {
template<>
struct hash {
inline size_t operator()(const rational & v) const {
return v.hash();
}
};
}
template
inline void hash_combine(std::size_t & seed, const T & v) {
seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std {
template struct hash> {
inline size_t operator()(const pair & v) const {
size_t seed = 0;
hash_combine(seed, v.first);
hash_combine(seed, v.second);
return seed;
}
};
template<>
struct hash> {
inline size_t operator()(const lp::numeric_pair & v) const {
size_t seed = 0;
hash_combine(seed, v.x);
hash_combine(seed, v.y);
return seed;
}
};
inline
void intersect_set(std::unordered_set& p, const std::unordered_set& w) {
for (auto it = p.begin(); it != p.end(); ) {
auto iit = it;
iit ++;
if (w.find(*it) == w.end())
p.erase(it);
it = iit;
}
}
}