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
Index() const32 Variable::Index() const
33 {
34 return fLS->IndexOf(this);
35 }
36
37
38 int32
GlobalIndex() const39 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*
LS() const51 Variable::LS() const
52 {
53 return fLS;
54 }
55
56
57 /**
58 * Gets the value.
59 *
60 * @return the value
61 */
62 double
Value() const63 Variable::Value() const
64 {
65 return fValue;
66 }
67
68
69 /**
70 * Sets the value.
71 *
72 * @param value the value
73 */
74 void
SetValue(double value)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
Min() const87 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
SetMin(double min)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
Max() const111 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
SetMax(double max)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
SetRange(double min,double max)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*
Label()146 Variable::Label()
147 {
148 return fLabel.String();
149 }
150
151
152 void
SetLabel(const char * label)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
ToString() const166 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*
IsEqual(Variable * var)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*
IsSmallerOrEqual(Variable * var)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*
IsGreaterOrEqual(Variable * var)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*
IsEqual(Variable * var,double penaltyNeg,double penaltyPos)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*
IsSmallerOrEqual(Variable * var,double penaltyNeg,double penaltyPos)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*
IsGreaterOrEqual(Variable * var,double penaltyNeg,double penaltyPos)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
IsValid()270 Variable::IsValid()
271 {
272 return fIsValid;
273 }
274
275
276 void
Invalidate()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 */
Variable(LinearSpec * ls)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
AddReference()307 Variable::AddReference()
308 {
309 fReferenceCount++;
310 return fReferenceCount;
311 }
312
313
314 int32
RemoveReference()315 Variable::RemoveReference()
316 {
317 fReferenceCount--;
318 return fReferenceCount;
319 }
320
321
322 /**
323 * Destructor.
324 * Removes the variable from its specification.
325 */
~Variable()326 Variable::~Variable()
327 {
328 if (fLS)
329 fLS->RemoveVariable(this, false);
330 }
331
332