1 |
#include <iostream> |
2 |
#include <stdexcept> |
3 |
#include <sstream> |
4 |
|
5 |
extern "C"{ |
6 |
#include <utilities/ascConfig.h> |
7 |
#include <utilities/ascSignal.h> |
8 |
#include <utilities/ascMalloc.h> |
9 |
#include <general/dstring.h> |
10 |
#include <compiler/instance_enum.h> |
11 |
#include <compiler/fractions.h> |
12 |
#include <compiler/compiler.h> |
13 |
#include <compiler/dimen.h> |
14 |
#include <compiler/symtab.h> |
15 |
#include <compiler/instance_io.h> |
16 |
#include <compiler/instantiate.h> |
17 |
#include <compiler/bintoken.h> |
18 |
#include <compiler/instquery.h> |
19 |
#include <compiler/check.h> |
20 |
#include <compiler/name.h> |
21 |
#include <compiler/parentchild.h> |
22 |
#include <compiler/instance_name.h> |
23 |
#include <compiler/atomvalue.h> |
24 |
#include <utilities/readln.h> |
25 |
#include <compiler/plot.h> |
26 |
#include <compiler/expr_types.h> |
27 |
#include <compiler/find.h> |
28 |
#include <compiler/relation_type.h> |
29 |
#include <compiler/exprs.h> |
30 |
#include <compiler/relation.h> |
31 |
#include <compiler/relation_io.h> |
32 |
#include <compiler/functype.h> |
33 |
#include <compiler/instance_types.h> |
34 |
#include <compiler/relation_util.h> |
35 |
} |
36 |
|
37 |
#include "instance.h" |
38 |
#include "variable.h" |
39 |
#include "name.h" |
40 |
#include "set.h" |
41 |
#include "plot.h" |
42 |
#include "instanceinterfacedata.h" |
43 |
|
44 |
using namespace std; |
45 |
|
46 |
/** |
47 |
Create an instance of a type. @see Simulation for instantiation. |
48 |
*/ |
49 |
Instanc::Instanc(Instance *i) : i(i), name("unnamed1"){ |
50 |
if(i==NULL){ |
51 |
stringstream ss; |
52 |
ss << "Attempted to create Instance object will null 'Instance *', name " << name; |
53 |
throw runtime_error(ss.str()); |
54 |
} |
55 |
//throw runtime_error("Created unnamed instance"); |
56 |
// nothing else; |
57 |
} |
58 |
|
59 |
Instanc::Instanc(Instance *i, const SymChar &name) : i(i), name(name){ |
60 |
/*if(i==NULL){ |
61 |
stringstream ss; |
62 |
ss << "Attempted to create Instance object will null 'Instance *', name " << name; |
63 |
throw runtime_error(ss.str()); |
64 |
}*/ |
65 |
//cerr << "A NEW INSTANCE " << name << endl; |
66 |
} |
67 |
|
68 |
Instanc::Instanc(const Instanc&old) : i(old.i), name(old.name){ |
69 |
// nothing else |
70 |
} |
71 |
|
72 |
Instanc::Instanc() : name("unnamed2"){ |
73 |
throw runtime_error("Can't construct empty instances"); |
74 |
} |
75 |
|
76 |
/* |
77 |
Create a child instance given the parent |
78 |
*/ |
79 |
Instanc::Instanc(const Instanc &parent, const unsigned long &childnum) |
80 |
: i( InstanceChild(parent.i,childnum) ), name( ChildName(parent.i,childnum) ){ |
81 |
// cerr << "CREATED CHILD #" << childnum << ", named '" << getName() << "' OF " << parent.getName() << endl; |
82 |
} |
83 |
|
84 |
/** |
85 |
Destructor |
86 |
|
87 |
There's no data owned by this object, so nothing to be done here. |
88 |
*/ |
89 |
Instanc::~Instanc(){ |
90 |
//cerr << "DESTROYING INSTANC OBJECT" << endl; |
91 |
} |
92 |
|
93 |
const SymChar & |
94 |
Instanc::getName() const{ |
95 |
return name; |
96 |
} |
97 |
|
98 |
void |
99 |
Instanc::setName(SymChar name){ |
100 |
this->name=name; |
101 |
} |
102 |
|
103 |
Instance * |
104 |
Instanc::getInternalType() const{ |
105 |
return i; |
106 |
} |
107 |
|
108 |
const enum inst_t |
109 |
Instanc::getKind() const{ |
110 |
if(i==NULL)throw runtime_error("NULL instance in Instanc::getKind"); |
111 |
return InstanceKind(i); |
112 |
} |
113 |
|
114 |
/** |
115 |
Return the type of this instance as a string |
116 |
*/ |
117 |
const string |
118 |
Instanc::getKindStr() const{ |
119 |
enum inst_t k = getKind(); |
120 |
stringstream ss; |
121 |
|
122 |
switch(k){ |
123 |
case ERROR_INST: ss << "Error"; break; |
124 |
case SIM_INST: ss << "Simulation"; break; |
125 |
case MODEL_INST: ss << "Model"; break; |
126 |
case REL_INST: ss << "Numerical Relation"; break; |
127 |
case LREL_INST: ss << "Logical relation"; break; |
128 |
case WHEN_INST: ss << "WHEN"; break; |
129 |
case ARRAY_INT_INST: ss << "Indexed Array"; break; |
130 |
case ARRAY_ENUM_INST: ss << "Enumerated Array"; break; |
131 |
case REAL_INST: ss << "Real"; break; |
132 |
case INTEGER_INST: ss << "Integer"; break; |
133 |
case BOOLEAN_INST: ss << "Boolean"; break; |
134 |
case SYMBOL_INST: ss << "Symbol"; break; |
135 |
case SET_INST: ss << "Set"; break; |
136 |
case REAL_ATOM_INST: ss << "Real atom"; break; |
137 |
case INTEGER_ATOM_INST: ss << "Integer atom"; break; |
138 |
case BOOLEAN_ATOM_INST: ss << "Boolean atom"; break; |
139 |
case SYMBOL_ATOM_INST: ss << "Symbol atom"; break; |
140 |
case SET_ATOM_INST: ss << "Set atom"; break; |
141 |
case REAL_CONSTANT_INST: ss << "Real constant"; break; |
142 |
case BOOLEAN_CONSTANT_INST: ss << "Boolean constant"; break; |
143 |
case INTEGER_CONSTANT_INST: ss << "Integer constant"; break; |
144 |
case SYMBOL_CONSTANT_INST: ss << "Symbol constant"; break; |
145 |
case DUMMY_INST: ss << "Dummy"; break; |
146 |
default: |
147 |
throw runtime_error("Invalid instance type"); |
148 |
} |
149 |
|
150 |
ss << " instance"; |
151 |
return ss.str(); |
152 |
} |
153 |
|
154 |
const Type |
155 |
Instanc::getType() const{ |
156 |
try{ |
157 |
const TypeDescription *t = InstanceTypeDesc(i); |
158 |
if(t==NULL)throw runtime_error("No type defined"); |
159 |
|
160 |
return Type(t); |
161 |
}catch(runtime_error &e){ |
162 |
stringstream ss; |
163 |
ss << "Instance::getType: with name=" << getName() << ":" << e.what(); |
164 |
throw runtime_error(ss.str()); |
165 |
} |
166 |
} |
167 |
|
168 |
const bool |
169 |
Instanc::isAtom() const{ |
170 |
return getKind() & IATOM; |
171 |
//return IsAtomicInstance(i); |
172 |
} |
173 |
|
174 |
const bool |
175 |
Instanc::isFixed() const{ |
176 |
if(getKind()==REAL_ATOM_INST && getType().isRefinedSolverVar()){ |
177 |
return getChild("fixed").getBoolValue(); |
178 |
} |
179 |
throw runtime_error("Instanc::isFixed: Not a solver_var"); |
180 |
} |
181 |
|
182 |
/** Is the relation currently included in the simulation (ie active WHEN) */ |
183 |
const bool |
184 |
Instanc::isActive() const{ |
185 |
if(getKind()==REL_INST){ |
186 |
return getChild("included").getBoolValue(); |
187 |
} |
188 |
throw runtime_error("Instanc::isActive: Not a relation"); |
189 |
} |
190 |
|
191 |
const bool |
192 |
Instanc::isCompound() const{ |
193 |
return getKind() & ICOMP; |
194 |
} |
195 |
|
196 |
const bool |
197 |
Instanc::isRelation() const{ |
198 |
if(getKind()==REL_INST){ |
199 |
return true; |
200 |
} |
201 |
return false; |
202 |
} |
203 |
|
204 |
const bool |
205 |
Instanc::isLogicalRelation() const{ |
206 |
if(getKind()==LREL_INST){ |
207 |
return true; |
208 |
} |
209 |
return false; |
210 |
} |
211 |
|
212 |
const bool |
213 |
Instanc::isWhen() const{ |
214 |
if(getKind()==WHEN_INST)return true; |
215 |
return false; |
216 |
} |
217 |
|
218 |
const bool |
219 |
Instanc::isSet() const{ |
220 |
return (getKind() == SET_INST || getKind() == SET_ATOM_INST); |
221 |
} |
222 |
|
223 |
const bool |
224 |
Instanc::isSetInt() const{ |
225 |
return isSet() && getSetType()==integer_set; |
226 |
} |
227 |
|
228 |
const bool |
229 |
Instanc::isSetString() const{ |
230 |
return isSet() && getSetType()==string_set; |
231 |
} |
232 |
|
233 |
const bool |
234 |
Instanc::isSetEmpty() const{ |
235 |
return isSet() && getSetType()==empty_set; |
236 |
} |
237 |
|
238 |
const bool |
239 |
Instanc::isFund() const{ |
240 |
return getKind() & IFUND; |
241 |
//return IsFundamentalInstance(i); |
242 |
} |
243 |
|
244 |
const bool |
245 |
Instanc::isConst() const{ |
246 |
return getKind() & ICONS; |
247 |
//return IsConstantInstance(i); |
248 |
} |
249 |
|
250 |
const bool |
251 |
Instanc::isAssigned() const{ |
252 |
if(!isAtom()){ |
253 |
throw runtime_error("Instanc::isAssigned: not an Atom"); |
254 |
} |
255 |
return AtomAssigned(i); |
256 |
} |
257 |
|
258 |
const bool |
259 |
Instanc::isArray() const{ |
260 |
return getKind() & IARR; |
261 |
//return IsArrayInstance(i); |
262 |
} |
263 |
|
264 |
const bool |
265 |
Instanc::isChildless() const{ |
266 |
return getKind() & ICHILDLESS; |
267 |
//return IsChildlessInstance(i); |
268 |
} |
269 |
|
270 |
const bool |
271 |
Instanc::isBool() const{ |
272 |
switch(getKind()){ |
273 |
case BOOLEAN_INST: |
274 |
case BOOLEAN_ATOM_INST: |
275 |
case BOOLEAN_CONSTANT_INST: |
276 |
return true; |
277 |
default: |
278 |
return false; |
279 |
} |
280 |
} |
281 |
|
282 |
const bool |
283 |
Instanc::isInt() const{ |
284 |
switch(getKind()){ |
285 |
case INTEGER_INST: |
286 |
case INTEGER_ATOM_INST: |
287 |
case INTEGER_CONSTANT_INST: |
288 |
return true; |
289 |
default: |
290 |
return false; |
291 |
} |
292 |
} |
293 |
|
294 |
const bool |
295 |
Instanc::isReal() const{ |
296 |
switch(getKind()){ |
297 |
case REAL_INST: |
298 |
case REAL_ATOM_INST: |
299 |
case REAL_CONSTANT_INST: |
300 |
return true; |
301 |
default: |
302 |
return false; |
303 |
} |
304 |
} |
305 |
|
306 |
const bool |
307 |
Instanc::isSymbol() const{ |
308 |
switch(getKind()){ |
309 |
case SYMBOL_INST: |
310 |
case SYMBOL_ATOM_INST: |
311 |
case SYMBOL_CONSTANT_INST: |
312 |
return true; |
313 |
default: |
314 |
return false; |
315 |
} |
316 |
} |
317 |
|
318 |
const bool |
319 |
Instanc::isDefined() const{ |
320 |
if(!isAtom() && !isFund())throw runtime_error("Instanc::isDefined: not an atom/fund"); |
321 |
return AtomAssigned(i); |
322 |
} |
323 |
|
324 |
const bool |
325 |
Instanc::isModel() const{ |
326 |
cerr << "TESTING FOR MODEL TYPE" << endl; |
327 |
if(getKind()==MODEL_INST){ |
328 |
return true; |
329 |
} |
330 |
cerr << "RETURNOING FALSE" << endl; |
331 |
return false; |
332 |
} |
333 |
|
334 |
const double |
335 |
Instanc::getRealValue() const{ |
336 |
// Check that the instance has a real value: |
337 |
switch(getKind()){ |
338 |
case REAL_INST: |
339 |
case REAL_CONSTANT_INST: |
340 |
case REAL_ATOM_INST: |
341 |
//cerr << "REAL VALUE FOR " << getName() << endl; |
342 |
break; |
343 |
default: |
344 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not real-valued (%s)", \ |
345 |
getName().toString(),getKindStr().c_str()); |
346 |
return 0; |
347 |
} |
348 |
if(!isConst() && !isDefined()){ |
349 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined (%s)", \ |
350 |
getName().toString(),getKindStr().c_str()); |
351 |
return 0; |
352 |
} |
353 |
return RealAtomValue(i); |
354 |
} |
355 |
|
356 |
const bool |
357 |
Instanc::isDimensionless() const{ |
358 |
if(!isReal())return true; |
359 |
return Dimensions( RealAtomDims(i) ).isDimensionless(); |
360 |
} |
361 |
|
362 |
const Dimensions |
363 |
Instanc::getDimensions() const{ |
364 |
if(!isReal())throw runtime_error("Instanc::getDimensions: not a real-valued instance"); |
365 |
return Dimensions( RealAtomDims(i) ); |
366 |
} |
367 |
|
368 |
const bool |
369 |
Instanc::getBoolValue() const{ |
370 |
// Check that the instance has a bool value: |
371 |
switch(getKind()){ |
372 |
case BOOLEAN_INST: |
373 |
case BOOLEAN_ATOM_INST: |
374 |
case BOOLEAN_CONSTANT_INST: |
375 |
//cerr << "BOOL VALUE FOR " << getName() << endl; |
376 |
break; |
377 |
default: |
378 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not boolean-valued",getName().toString()); |
379 |
return false; |
380 |
} |
381 |
if(!isConst() && !isDefined()){ |
382 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString()); |
383 |
return false; |
384 |
} |
385 |
return GetBooleanAtomValue(i); |
386 |
} |
387 |
|
388 |
|
389 |
const long |
390 |
Instanc::getIntValue() const{ |
391 |
// Check that the instance has a bool value: |
392 |
switch(getKind()){ |
393 |
case INTEGER_INST: |
394 |
case INTEGER_ATOM_INST: |
395 |
case INTEGER_CONSTANT_INST: |
396 |
//cerr << "INT VALUE FOR " << getName() << endl; |
397 |
break; |
398 |
default: |
399 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not integer-valued",getName().toString()); |
400 |
return 0; |
401 |
} |
402 |
if(!isConst() && !isDefined()){ |
403 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString()); |
404 |
return 0; |
405 |
} |
406 |
return GetIntegerAtomValue(i); |
407 |
} |
408 |
|
409 |
const SymChar |
410 |
Instanc::getSymbolValue() const{ |
411 |
if(!isSymbol()){ |
412 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not symbol-valued",getName().toString()); |
413 |
return SymChar("ERROR"); |
414 |
} |
415 |
if(!isConst() && !isDefined()){ |
416 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString()); |
417 |
return SymChar("UNDEFINED"); |
418 |
} |
419 |
return SCP(GetSymbolAtomValue(i)); |
420 |
} |
421 |
|
422 |
void |
423 |
Instanc::setSymbolValue(const SymChar &sym){ |
424 |
stringstream ss; |
425 |
if(!isSymbol()){ |
426 |
ss << "Variable '" << getName().toString() << "' is not symbol-valued."; |
427 |
throw runtime_error(ss.str()); |
428 |
} |
429 |
if(isConst() && isDefined()){ |
430 |
ss << "Variable '" << getName().toString() << "' has already been defined."; |
431 |
throw runtime_error(ss.str()); |
432 |
} |
433 |
|
434 |
SetSymbolAtomValue(i,sym.getInternalType()); |
435 |
} |
436 |
|
437 |
const string |
438 |
Instanc::getRelationAsString(const Instanc &relative_to) const{ |
439 |
stringstream ss; |
440 |
if(isRelation()){ |
441 |
int len; |
442 |
char *str = WriteRelationString(i,relative_to.getInternalType() |
443 |
,NULL,NULL,relio_ascend,&len); |
444 |
ss << str; |
445 |
ascfree(str); |
446 |
}else{ |
447 |
throw runtime_error("getRelationString: Instance is not a relation"); |
448 |
} |
449 |
return ss.str(); |
450 |
} |
451 |
|
452 |
const double |
453 |
Instanc::getResidual() const{ |
454 |
if(!isRelation()){ |
455 |
throw runtime_error("getResidual: not a relation"); |
456 |
} |
457 |
struct RelationInstance * const ri = (struct RelationInstance * const) i; |
458 |
|
459 |
return RelationResidual( ri->ptr ); |
460 |
} |
461 |
|
462 |
/** |
463 |
Return the numerical value of an instance if it is an assigned atom. |
464 |
If it is a relation, return the string form of the relation (ie the equation) |
465 |
Else return the string 'undefined'. |
466 |
*/ |
467 |
const string |
468 |
Instanc::getValueAsString() const{ |
469 |
stringstream ss; |
470 |
|
471 |
if(isAssigned()){ |
472 |
if(isReal()){ |
473 |
ss << getRealValue(); |
474 |
}else if(isInt()){ |
475 |
ss << getIntValue(); |
476 |
}else if(isSymbol()){ |
477 |
ss << getSymbolValue(); |
478 |
}else if(isBool()){ |
479 |
ss << getBoolValue(); |
480 |
}else{ |
481 |
throw runtime_error("Invalid type in Instanc::getValueAsString"); |
482 |
} |
483 |
}else{ |
484 |
ss << "undefined"; |
485 |
} |
486 |
return ss.str(); |
487 |
} |
488 |
|
489 |
const bool |
490 |
Instanc::isPlottable() const{ |
491 |
if(plot_allowed(i)){ |
492 |
return true; |
493 |
} |
494 |
return false; |
495 |
} |
496 |
|
497 |
const enum set_kind |
498 |
Instanc::getSetType() const{ |
499 |
if(!isSet() || (!isConst() && !isDefined())){ |
500 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not set-valued or not defined",getName().toString()); |
501 |
} |
502 |
return SetKind(SetAtomList(i)); |
503 |
} |
504 |
|
505 |
/// Get the child instances :) |
506 |
vector<Instanc> & |
507 |
Instanc::getChildren() |
508 |
{ |
509 |
Type t = getType(); |
510 |
|
511 |
children = vector<Instanc>(); |
512 |
|
513 |
if(i==NULL)throw runtime_error("NULL 'i' in Instanc::getChildren"); |
514 |
|
515 |
unsigned long len = NumberChildren(i); |
516 |
if(!len)return children; |
517 |
//cerr << "FOUND " << len << " CHILDREN" << endl; |
518 |
|
519 |
if(isArray()){ |
520 |
for(unsigned long ci=1; ci<=len; ++ci){ |
521 |
Instanc c(*this, ci); |
522 |
if(!TypeShow(c.getType().getInternalType()))continue; |
523 |
children.push_back(c); |
524 |
} |
525 |
return children; |
526 |
/* stringstream ss; |
527 |
ss << "Instance '" << getName() << "' is an array, type '" << t.getName() << "'"; |
528 |
ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str()); */ |
529 |
} |
530 |
|
531 |
|
532 |
ChildListPtr clist = GetChildList(t.getInternalType()); |
533 |
if(!clist){ |
534 |
stringstream ss; |
535 |
ss << "Child list of instance '" << getName() << "' of type '" << t.getName() << "' (" << getKindStr() << ") is NULL"; |
536 |
ss << " (isChildless=" << isChildless() << ")"; |
537 |
ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str()); |
538 |
return children; |
539 |
//throw runtime_error(ss.str()); |
540 |
} |
541 |
|
542 |
/// FIXME 1-based array: |
543 |
for(unsigned long ci=1; ci<=len; ++ci){ |
544 |
if(!ChildVisible(clist,ci))continue; |
545 |
|
546 |
Instanc c( *this, ci ); |
547 |
//cerr << "FOUND CHILD #" << ci << ": " << c.getName() << endl; |
548 |
|
549 |
children.push_back(c); |
550 |
} |
551 |
return children; |
552 |
} |
553 |
|
554 |
Instanc |
555 |
Instanc::getChild(const SymChar &name) const{ |
556 |
struct Instance *c = ChildByChar(i,name.getInternalType()); |
557 |
stringstream ss; |
558 |
if(c==NULL){ |
559 |
ss << "Child '" << name << "' not found in " << getName(); |
560 |
throw runtime_error(ss.str()); |
561 |
} |
562 |
return Instanc(c,name); |
563 |
} |
564 |
|
565 |
Plot |
566 |
Instanc::getPlot() const{ |
567 |
if(isPlottable()){ |
568 |
return Plot(*this); |
569 |
} |
570 |
throw runtime_error("Not a plottable instance"); |
571 |
} |
572 |
|
573 |
void |
574 |
Instanc::write(){ |
575 |
WriteInstance(stderr,i); |
576 |
} |
577 |
|
578 |
//---------------------------- |
579 |
// SETTING VALUES of stuff |
580 |
|
581 |
void |
582 |
Instanc::setFixed(const bool &val){ |
583 |
if(isFixed()==val)return; |
584 |
getChild("fixed").setBoolValue(val); |
585 |
} |
586 |
|
587 |
void |
588 |
Instanc::setBoolValue(const bool &val, const unsigned &depth){ |
589 |
SetBooleanAtomValue(i, val, depth); |
590 |
} |
591 |
|
592 |
void |
593 |
Instanc::setRealValue(const double &val, const unsigned &depth){ |
594 |
SetRealAtomValue(i,val, depth); |
595 |
//ERROR_REPORTER_HERE(ASC_USER_NOTE,"Set %s to %f",getName().toString(),val); |
596 |
} |
597 |
|
598 |
/** |
599 |
Borrow the workings of this from tcltk UnitsProc.c |
600 |
*/ |
601 |
void |
602 |
Instanc::setRealValueWithUnits(double val, const char *units, const unsigned &depth){ |
603 |
|
604 |
if(isConst()){ |
605 |
ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Can't change the value of a constant"); |
606 |
return; |
607 |
} |
608 |
|
609 |
if(!isReal() || !isAtom()){ |
610 |
throw runtime_error("Instanc::setRealValueWithUnits: not a real-valued instance"); |
611 |
} |
612 |
|
613 |
if(units == NULL || strlen(units)==0 || strcmp(units,"*")==0){ |
614 |
// No units were specified, so the base (SI) units are implied. |
615 |
}else{ |
616 |
// We need to parse the units string |
617 |
UnitsM u = UnitsM(units); |
618 |
Dimensions d = u.getDimensions(); |
619 |
|
620 |
// If no dimensions yet assigned, assign them. Otheriwse check for consistency. |
621 |
if(getDimensions().isWild()){ |
622 |
// Set the dimensions for a wildcard atom: |
623 |
SetRealAtomDims(i, d.getInternalType()); |
624 |
}else if(d != getDimensions()){ |
625 |
throw runtime_error("Dimensionally incompatible units"); |
626 |
} |
627 |
|
628 |
// Not going to worry about FPEs here, let the program crash if it must. |
629 |
val = val * u.getConversion(); |
630 |
} |
631 |
|
632 |
SetRealAtomValue(i,val,depth); |
633 |
} |
634 |
|
635 |
/** |
636 |
Set the instance variable status. See @getVarStatus |
637 |
*/ |
638 |
void |
639 |
Instanc::setVarStatus(const VarStatus &s){ |
640 |
InstanceInterfaceData *d; |
641 |
d = (InstanceInterfaceData *)GetInterfacePtr(i); |
642 |
if(d==NULL && s!=ASCXX_VAR_STATUS_UNKNOWN){ |
643 |
d = new InstanceInterfaceData(); |
644 |
SetInterfacePtr(i,d); |
645 |
} |
646 |
d->status = s; |
647 |
} |
648 |
|
649 |
/** |
650 |
Return the instance variable status. |
651 |
This data is stored in the 'interface_ptr' of the instance, so |
652 |
that we can be sure we'll get it, regardless of which |
653 |
instance of an Instanc we have in our hands :-) |
654 |
*/ |
655 |
const VarStatus |
656 |
Instanc::getVarStatus() const{ |
657 |
InstanceInterfaceData *d; |
658 |
d = (InstanceInterfaceData *)GetInterfacePtr(i); |
659 |
if(d==NULL){ |
660 |
return ASCXX_VAR_STATUS_UNKNOWN; |
661 |
} |
662 |
return d->status; |
663 |
} |
664 |
|
665 |
|
666 |
|
667 |
/*------------------------------------------------------ |
668 |
Macros to declare |
669 |
setUpperBound |
670 |
setLowerBound |
671 |
setNominal |
672 |
and their 'get' equivalents |
673 |
*/ |
674 |
|
675 |
#define DEFINE_GET_REAL_CHILD(METHOD,CHILD) \ |
676 |
const double \ |
677 |
Instanc::get##METHOD() const{ \ |
678 |
Instanc c = getChild(CHILD); \ |
679 |
return c.getRealValue(); \ |
680 |
} |
681 |
|
682 |
#define DEFINE_SET_REAL_CHILD(METHOD,CHILD) \ |
683 |
void \ |
684 |
Instanc::set##METHOD(const double &v){ \ |
685 |
Instanc c = getChild(CHILD); \ |
686 |
c.setRealValue(v); \ |
687 |
} |
688 |
|
689 |
#define DEFINE_CHILD_METHODS(D) \ |
690 |
D(LowerBound,"lower_bound") \ |
691 |
D(UpperBound,"upper_bound") \ |
692 |
D(Nominal,"nominal") |
693 |
|
694 |
DEFINE_CHILD_METHODS(DEFINE_SET_REAL_CHILD) |
695 |
DEFINE_CHILD_METHODS(DEFINE_GET_REAL_CHILD) |
696 |
|
697 |
//------------------------------------------------------ |
698 |
|
699 |
const vector<Instanc> |
700 |
Instanc::getClique() const{ |
701 |
vector<Instanc> v; |
702 |
struct Instance *i1 = i; |
703 |
do{ |
704 |
v.push_back(Instanc(i1)); |
705 |
i1=NextCliqueMember(i1); |
706 |
}while(i1 != i); // ie we've gone around the circuit |
707 |
return v; |
708 |
} |
709 |
|
710 |
//------------------------------------------------------ |
711 |
// static properties |
712 |
SymChar |
713 |
Instanc::fixedsym = SymChar("fixed"); |
714 |
|
715 |
SymChar |
716 |
Instanc::solvervarsym = SymChar("solver_var"); |