/*++ Copyright (c) 2017 Microsoft Corporation Module Name: Abstract: Author: Lev Nachmanson (levnach) Revision History: --*/ #pragma once #include #include "util/lp/numeric_pair.h" #include "util/debug.h" #include template void print_vector(const C & t, std::ostream & out) { for (const auto & p : t) out << p << " "; out << std::endl; } template void print_vector(const C * t, unsigned size, std::ostream & out) { for (unsigned i = 0; i < size; i++ ) out << t[i] << " "; out << std::endl; } 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 lp_for_z3 #ifdef Z3DEBUG #define Z3DEBUG 1 #endif namespace lp { template void print_linear_combination_of_column_indices_only(const T & coeffs, std::ostream & out) { bool first = true; for (const auto & it : coeffs) { auto val = it.coeff(); if (first) { first = false; } else { if (val.is_pos()) { out << " + "; } else { out << " - "; val = -val; } } if (val == 1) out << " "; else out << T_to_string(val); out << "x" << it.var(); } } inline void throw_exception(std::string && str) { throw default_exception(std::move(str)); } typedef z3_exception exception; #define lp_assert(_x_) { SASSERT(_x_); } inline void lp_unreachable() { lp_assert(false); } 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); } template inline bool precise() { return numeric_traits::precise(); } } 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; } }; } #else // else of #if lp_for_z3 #include #include //include "util/numerics/mpq.h" //include "util/numerics/numeric_traits.h" //include "util/numerics/double.h" #ifdef __CLANG__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmismatched-tags" #endif namespace std { template<> struct hash { inline size_t operator()(const lp::mpq & v) const { return v.hash(); } }; } namespace lp { template inline bool precise() { return numeric_traits::precise();} 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_int(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(v); } template inline double get_double(const X & v) { return numeric_traits::get_double(v); } template inline T zero_of_type() {return numeric_traits::zero();} inline void throw_exception(std::string str) { throw exception(str); } template inline T from_string(std::string const & ) { lp_unreachable();} template <> double inline from_string(std::string const & str) { return atof(str.c_str());} template <> mpq inline from_string(std::string const & str) { return mpq(atof(str.c_str())); } } // closing lp 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; } }; } // std #ifdef __CLANG__ #pragma clang diagnostic pop #endif #endif