1 /* 2 4ti2 -- A software package for algebraic, geometric and combinatorial 3 problems on linear spaces. 4 5 Copyright (C) 2006 4ti2 team. 6 Main author(s): Matthias Walter. 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2 11 of the License, or (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 */ 22 23 #ifndef _4ti2_zsolve__Variables_ 24 #define _4ti2_zsolve__Variables_ 25 26 #include <iostream> 27 #include <vector> 28 #include <cassert> 29 30 #include "zsolve/Integer.h" 31 32 namespace _4ti2_zsolve_ 33 { 34 35 template <typename T> class VariableProperty 36 { 37 protected: 38 int m_column_id; 39 bool m_is_free; 40 T m_upper_bound; 41 T m_lower_bound; 42 43 public: VariableProperty(const int column,const bool free,const T & lower,const T & upper)44 VariableProperty (const int column, const bool free, const T& lower, const T& upper) 45 { 46 set (column, free, lower, upper); 47 } 48 VariableProperty(const VariableProperty & other)49 VariableProperty (const VariableProperty& other) 50 { 51 set (other.m_column_id, other.m_is_free, other.m_lower_bound, other.m_upper_bound); 52 } 53 is_symmetric() const54 bool is_symmetric () const 55 { 56 return m_upper_bound + m_lower_bound == 0; 57 } 58 set_bound(bool set_lower,const T & value)59 void set_bound (bool set_lower, const T& value) 60 { 61 if (m_is_free) 62 return; 63 64 if (set_lower) 65 m_lower_bound = value; 66 else 67 m_upper_bound = value; 68 } 69 set(const VariableProperty & other)70 void set (const VariableProperty& other) 71 { 72 set (other.m_column_id, other.m_is_free, other.m_lower_bound, other.m_upper_bound); 73 } 74 set(const int column,const bool free,const T & lower,const T & upper)75 void set (const int column, const bool free, const T& lower, const T& upper) 76 { 77 m_column_id = column; 78 m_is_free = free; 79 m_lower_bound = lower; 80 m_upper_bound = upper; 81 82 } 83 set(const bool free,const T & lower=1,const T & upper=-1)84 void set (const bool free, const T& lower = 1, const T& upper = -1) 85 { 86 m_is_free = free; 87 m_lower_bound = lower; 88 m_upper_bound = upper; 89 } 90 setSign(int sign)91 void setSign (int sign) 92 { 93 if (sign == 2) 94 { 95 m_is_free = false; 96 if (m_lower_bound == 0) 97 m_lower_bound = 1; 98 if (m_upper_bound == 0) 99 m_upper_bound = -1; 100 } 101 else if (sign == 1) 102 { 103 m_is_free = false; 104 m_lower_bound = 0; 105 if (m_upper_bound == 0) 106 m_upper_bound = -1; 107 } 108 else if (sign == -1) 109 { 110 m_is_free = false; 111 m_upper_bound = 0; 112 if (m_lower_bound == 0) 113 m_lower_bound = 1; 114 } 115 else 116 set (true, 1, -1); 117 } 118 sign()119 int sign () 120 { 121 if (m_is_free) 122 return 0; 123 if ((m_lower_bound == 0 && m_upper_bound == 0) || (m_lower_bound != 0 && m_upper_bound != 0)) 124 return 2; 125 else if (m_lower_bound == 0) 126 return 1; 127 else 128 return -1; 129 } 130 setLower(const T & lower)131 void setLower (const T& lower) 132 { 133 if (lower <= 0) 134 m_is_free = false; 135 m_lower_bound = lower; 136 } 137 setUpper(const T & upper)138 void setUpper (const T& upper) 139 { 140 if (upper >= 0) 141 m_is_free = false; 142 m_upper_bound = upper; 143 } 144 free() const145 bool free () const 146 { 147 return m_is_free; 148 } 149 column() const150 int column () const 151 { 152 return m_column_id; 153 } 154 lower() const155 T lower () const 156 { 157 return m_lower_bound; 158 } 159 upper() const160 T upper () const 161 { 162 return m_upper_bound; 163 } 164 compare(const VariableProperty & other) const165 int compare (const VariableProperty& other) const 166 { 167 int max = (m_column_id > other.m_column_id ? m_column_id : other.m_column_id) + 1; 168 int c1 = m_column_id < 0 ? max - m_column_id : m_column_id; 169 int c2 = other.m_column_id < 0 ? max - other.m_column_id : other.m_column_id; 170 171 return c1 - c2; 172 } 173 count_infinity() const174 int count_infinity () const 175 { 176 int result = 2; 177 if (m_lower_bound <= 0) 178 result--; 179 if (m_upper_bound >= 0) 180 result--; 181 return result; 182 } 183 get_range()184 T get_range () 185 { 186 T result = 0; 187 if (m_upper_bound > 0) 188 result += m_upper_bound; 189 if (m_lower_bound < 0) 190 result -= m_lower_bound; 191 return result; 192 } 193 check_bounds(const T & value)194 bool check_bounds (const T& value) 195 { 196 if (m_lower_bound <= 0 && value < m_lower_bound) 197 return false; 198 if (m_upper_bound >= 0 && value > m_upper_bound) 199 return false; 200 return true; 201 } 202 check_consistency() const203 bool check_consistency () const 204 { 205 return m_column_id >= -2; 206 } 207 lower_space() const208 int lower_space () const 209 { 210 return m_lower_bound < 0 ? integer_space (m_lower_bound) : 1; 211 } 212 upper_space() const213 int upper_space () const 214 { 215 return m_upper_bound > 0 ? integer_space (m_upper_bound) : 1; 216 } 217 upper(std::ostream & out) const218 std::ostream& upper (std::ostream& out) const 219 { 220 if (m_upper_bound >= 0) 221 out << m_upper_bound; 222 else 223 out << "+"; 224 return out; 225 } 226 lower(std::ostream & out) const227 std::ostream& lower (std::ostream& out) const 228 { 229 if (m_lower_bound <= 0) 230 out << m_lower_bound; 231 else 232 out << "-"; 233 return out; 234 } 235 dump(std::ostream & out) const236 std::ostream& dump (std::ostream& out) const 237 { 238 out << m_column_id; 239 out << (m_is_free ? " 1 " : " 0 "); 240 out << m_lower_bound; 241 out << " "; 242 out << m_upper_bound; 243 return out; 244 } 245 }; 246 247 template <typename T> class VariableProperties 248 { 249 protected: 250 std::vector <VariableProperty <T> *> m_variable_properties; 251 252 public: VariableProperties(size_t variables,bool free,const T & lower,const T & upper)253 VariableProperties (size_t variables, bool free, const T& lower, const T& upper) 254 { 255 m_variable_properties.resize (variables); 256 for (size_t i = 0; i < variables; i++) 257 { 258 m_variable_properties[i] = new VariableProperty <T> (i, free, lower, upper); 259 } 260 } 261 VariableProperties(VariableProperties<T> * other)262 VariableProperties (VariableProperties <T>* other) 263 { 264 m_variable_properties.resize (other->variables ()); 265 for (size_t i = 0; i < other->variables (); i++) 266 { 267 m_variable_properties[i] = new VariableProperty <T> (other->get_variable (i)); 268 } 269 } 270 ~VariableProperties()271 ~VariableProperties () 272 { 273 for (size_t i = 0; i < m_variable_properties.size (); i++) 274 delete m_variable_properties[i]; 275 m_variable_properties.clear (); 276 } 277 get_variable(size_t index)278 VariableProperty <T>& get_variable (size_t index) 279 { 280 return *m_variable_properties[index]; 281 } 282 variables() const283 size_t variables () const 284 { 285 return m_variable_properties.size (); 286 } 287 swap(size_t a,size_t b)288 void swap (size_t a, size_t b) 289 { 290 VariableProperty <T> * temp = m_variable_properties[a]; 291 m_variable_properties[a] = m_variable_properties[b]; 292 m_variable_properties[b] = temp; 293 } 294 check_consistency() const295 bool check_consistency () const 296 { 297 for (size_t i = 0; i < m_variable_properties.size (); i++) 298 if (!m_variable_properties[i].check_consistency ()) 299 return false; 300 return true; 301 } 302 }; 303 304 } // namespace _4ti2_zsolve_ 305 306 #endif 307