1 /* 2 * Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz 3 * Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz 4 * Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de> 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include "Variable.h" 10 11 #include <math.h> 12 13 #include "Constraint.h" 14 #include "LinearSpec.h" 15 16 // Toggle debug output 17 //#define DEBUG_VARIABLE 18 19 #ifdef DEBUG_VARIABLE 20 # define STRACE(x) debug_printf x 21 #else 22 # define STRACE(x) ; 23 #endif 24 25 26 /** 27 * Gets index of the variable. 28 * 29 * @return the index of the variable 30 */ 31 int32 32 Variable::Index() const 33 { 34 return fLS->IndexOf(this); 35 } 36 37 38 int32 39 Variable::GlobalIndex() const 40 { 41 return fLS->GlobalIndexOf(this); 42 } 43 44 45 /** 46 * Gets the current linear specification. 47 * 48 * @return the current linear specification 49 */ 50 LinearSpec* 51 Variable::LS() const 52 { 53 return fLS; 54 } 55 56 57 /** 58 * Gets the value. 59 * 60 * @return the value 61 */ 62 double 63 Variable::Value() const 64 { 65 return fValue; 66 } 67 68 69 /** 70 * Sets the value. 71 * 72 * @param value the value 73 */ 74 void 75 Variable::SetValue(double value) 76 { 77 fValue = value; 78 } 79 80 81 /** 82 * Gets the minimum value of the variable. 83 * 84 * @return the minimum value of variable 85 */ 86 double 87 Variable::Min() const 88 { 89 return fMin; 90 } 91 92 93 /** 94 * Sets the minimum value of the variable. 95 * 96 * @param min minimum value 97 */ 98 void 99 Variable::SetMin(double min) 100 { 101 SetRange(min, fMax); 102 } 103 104 105 /** 106 * Gets the maximum value of the variable. 107 * 108 * @return the maximum value of variable 109 */ 110 double 111 Variable::Max() const 112 { 113 return fMax; 114 } 115 116 117 /** 118 * Sets the maximum value of the variable. 119 * 120 * @param max maximum value 121 */ 122 void 123 Variable::SetMax(double max) 124 { 125 SetRange(fMin, max); 126 } 127 128 129 /** 130 * Sets the minimum and maximum values of the variable. 131 * 132 * @param min minimum value 133 * @param max maximum value 134 */ 135 void 136 Variable::SetRange(double min, double max) 137 { 138 fMin = min; 139 fMax = max; 140 if (fIsValid) 141 fLS->UpdateRange(this); 142 } 143 144 145 const char* 146 Variable::Label() 147 { 148 return fLabel.String(); 149 } 150 151 152 void 153 Variable::SetLabel(const char* label) 154 { 155 fLabel = label; 156 } 157 158 159 /** 160 * Returns index of the variable as String. 161 * E.g. "Var2" 162 * 163 * @return the <code>String</code> index of the variable 164 */ 165 BString 166 Variable::ToString() const 167 { 168 BString string = "x"; 169 string << Index() << " "; 170 if (fLabel) { 171 string << fLabel << ": "; 172 if (!fIsValid) 173 string << "(invalid)"; 174 } else { 175 if (!fIsValid) 176 string << "(invalid," << (addr_t)this << ")"; 177 else 178 string << Index() << ": "; 179 } 180 string << Value(); 181 BString pointerString; 182 pointerString.SetToFormat("%p", this); 183 string << " (" << pointerString << ")"; 184 return string; 185 } 186 187 188 /** 189 * Adds a constraint that sets this variable equal to the given one. 190 * 191 * @param var variable that should have the same value 192 * @return the new equality constraint 193 */ 194 Constraint* 195 Variable::IsEqual(Variable* var) 196 { 197 if (!fIsValid) 198 return NULL; 199 200 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0); 201 } 202 203 204 /** 205 * Adds a constraint that sets this variable smaller or equal to the given one. 206 * 207 * @param var variable that should have a larger or equal value 208 * @return the new constraint 209 */ 210 Constraint* 211 Variable::IsSmallerOrEqual(Variable* var) 212 { 213 if (!fIsValid) 214 return NULL; 215 216 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0); 217 } 218 219 220 /** 221 * Adds a constraint that sets this variable greater or equal to the given one. 222 * 223 * @param var variable that should have a smaller or equal value 224 * @return the new constraint 225 */ 226 Constraint* 227 Variable::IsGreaterOrEqual(Variable* var) 228 { 229 if (!fIsValid) 230 return NULL; 231 232 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0); 233 } 234 235 236 Constraint* 237 Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos) 238 { 239 if (!fIsValid) 240 return NULL; 241 242 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0, 243 penaltyNeg, penaltyPos); 244 } 245 246 247 Constraint* 248 Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 249 { 250 if (!fIsValid) 251 return NULL; 252 253 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0, penaltyNeg, 254 penaltyPos); 255 } 256 257 258 Constraint* 259 Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 260 { 261 if (!fIsValid) 262 return NULL; 263 264 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0, penaltyNeg, 265 penaltyPos); 266 } 267 268 269 bool 270 Variable::IsValid() 271 { 272 return fIsValid; 273 } 274 275 276 void 277 Variable::Invalidate() 278 { 279 STRACE(("Variable::Invalidate() on %s\n", BString(*this).String())); 280 281 if (!fIsValid) 282 return; 283 284 fIsValid = false; 285 fLS->RemoveVariable(this, false); 286 } 287 288 289 /** 290 * Constructor. 291 */ 292 Variable::Variable(LinearSpec* ls) 293 : 294 fLS(ls), 295 fValue(NAN), 296 fMin(-20000), 297 fMax(20000), 298 fLabel(NULL), 299 fIsValid(false), 300 fReferenceCount(0) 301 { 302 303 } 304 305 306 int32 307 Variable::AddReference() 308 { 309 fReferenceCount++; 310 return fReferenceCount; 311 } 312 313 314 int32 315 Variable::RemoveReference() 316 { 317 fReferenceCount--; 318 return fReferenceCount; 319 } 320 321 322 /** 323 * Destructor. 324 * Removes the variable from its specification. 325 */ 326 Variable::~Variable() 327 { 328 if (fLS) 329 fLS->RemoveVariable(this, false); 330 } 331 332