/[ascend]/trunk/pygtk/instance.cpp
ViewVC logotype

Contents of /trunk/pygtk/instance.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22