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

Contents of /trunk/pygtk/instance.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 774 - (show annotations) (download) (as text)
Fri Jul 14 08:01:48 2006 UTC (13 years, 7 months ago) by johnpye
File MIME type: text/x-c++src
File size: 16099 byte(s)
Added the ability to run methods on sub-models within a simulation. Use the right-click context menu.
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 const bool
183 Instanc::isCompound() const{
184 return getKind() & ICOMP;
185 }
186
187 const bool
188 Instanc::isRelation() const{
189 switch(getKind()){
190 case REL_INST:
191 case LREL_INST:
192 return true;
193 default:
194 return false;
195 }
196 }
197
198 const bool
199 Instanc::isWhen() const{
200 if(getKind()==WHEN_INST)return true;
201 return false;
202 }
203
204 const bool
205 Instanc::isSet() const{
206 return (getKind() == SET_INST || getKind() == SET_ATOM_INST);
207 }
208
209 const bool
210 Instanc::isSetInt() const{
211 return isSet() && getSetType()==integer_set;
212 }
213
214 const bool
215 Instanc::isSetString() const{
216 return isSet() && getSetType()==string_set;
217 }
218
219 const bool
220 Instanc::isSetEmpty() const{
221 return isSet() && getSetType()==empty_set;
222 }
223
224 const bool
225 Instanc::isFund() const{
226 return getKind() & IFUND;
227 //return IsFundamentalInstance(i);
228 }
229
230 const bool
231 Instanc::isConst() const{
232 return getKind() & ICONS;
233 //return IsConstantInstance(i);
234 }
235
236 const bool
237 Instanc::isAssigned() const{
238 if(!isAtom()){
239 throw runtime_error("Instanc::isAssigned: not an Atom");
240 }
241 return AtomAssigned(i);
242 }
243
244 const bool
245 Instanc::isArray() const{
246 return getKind() & IARR;
247 //return IsArrayInstance(i);
248 }
249
250 const bool
251 Instanc::isChildless() const{
252 return getKind() & ICHILDLESS;
253 //return IsChildlessInstance(i);
254 }
255
256 const bool
257 Instanc::isBool() const{
258 switch(getKind()){
259 case BOOLEAN_INST:
260 case BOOLEAN_ATOM_INST:
261 case BOOLEAN_CONSTANT_INST:
262 return true;
263 default:
264 return false;
265 }
266 }
267
268 const bool
269 Instanc::isInt() const{
270 switch(getKind()){
271 case INTEGER_INST:
272 case INTEGER_ATOM_INST:
273 case INTEGER_CONSTANT_INST:
274 return true;
275 default:
276 return false;
277 }
278 }
279
280 const bool
281 Instanc::isReal() const{
282 switch(getKind()){
283 case REAL_INST:
284 case REAL_ATOM_INST:
285 case REAL_CONSTANT_INST:
286 return true;
287 default:
288 return false;
289 }
290 }
291
292 const bool
293 Instanc::isSymbol() const{
294 switch(getKind()){
295 case SYMBOL_INST:
296 case SYMBOL_ATOM_INST:
297 case SYMBOL_CONSTANT_INST:
298 return true;
299 default:
300 return false;
301 }
302 }
303
304 const bool
305 Instanc::isDefined() const{
306 if(!isAtom() && !isFund())throw runtime_error("Instanc::isDefined: not an atom/fund");
307 return AtomAssigned(i);
308 }
309
310 const bool
311 Instanc::isModel() const{
312 cerr << "TESTING FOR MODEL TYPE" << endl;
313 if(getKind()==MODEL_INST){
314 return true;
315 }
316 cerr << "RETURNOING FALSE" << endl;
317 return false;
318 }
319
320 const double
321 Instanc::getRealValue() const{
322 // Check that the instance has a real value:
323 switch(getKind()){
324 case REAL_INST:
325 case REAL_CONSTANT_INST:
326 case REAL_ATOM_INST:
327 //cerr << "REAL VALUE FOR " << getName() << endl;
328 break;
329 default:
330 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not real-valued (%s)", \
331 getName().toString(),getKindStr().c_str());
332 return 0;
333 }
334 if(!isConst() && !isDefined()){
335 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined (%s)", \
336 getName().toString(),getKindStr().c_str());
337 return 0;
338 }
339 return RealAtomValue(i);
340 }
341
342 const bool
343 Instanc::isDimensionless() const{
344 if(!isReal())return true;
345 return Dimensions( RealAtomDims(i) ).isDimensionless();
346 }
347
348 const Dimensions
349 Instanc::getDimensions() const{
350 if(!isReal())throw runtime_error("Instanc::getDimensions: not a real-valued instance");
351 return Dimensions( RealAtomDims(i) );
352 }
353
354 const bool
355 Instanc::getBoolValue() const{
356 // Check that the instance has a bool value:
357 switch(getKind()){
358 case BOOLEAN_INST:
359 case BOOLEAN_ATOM_INST:
360 case BOOLEAN_CONSTANT_INST:
361 //cerr << "BOOL VALUE FOR " << getName() << endl;
362 break;
363 default:
364 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not boolean-valued",getName().toString());
365 return false;
366 }
367 if(!isConst() && !isDefined()){
368 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
369 return false;
370 }
371 return GetBooleanAtomValue(i);
372 }
373
374
375 const long
376 Instanc::getIntValue() const{
377 // Check that the instance has a bool value:
378 switch(getKind()){
379 case INTEGER_INST:
380 case INTEGER_ATOM_INST:
381 case INTEGER_CONSTANT_INST:
382 //cerr << "INT VALUE FOR " << getName() << endl;
383 break;
384 default:
385 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not integer-valued",getName().toString());
386 return 0;
387 }
388 if(!isConst() && !isDefined()){
389 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
390 return 0;
391 }
392 return GetIntegerAtomValue(i);
393 }
394
395 const SymChar
396 Instanc::getSymbolValue() const{
397 if(!isSymbol()){
398 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not symbol-valued",getName().toString());
399 return SymChar("ERROR");
400 }
401 if(!isConst() && !isDefined()){
402 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
403 return SymChar("UNDEFINED");
404 }
405 return SCP(GetSymbolAtomValue(i));
406 }
407
408 const string
409 Instanc::getRelationAsString(const Instanc &relative_to) const{
410 stringstream ss;
411 if(isRelation()){
412 int len;
413 char *str = WriteRelationString(i,relative_to.getInternalType()
414 ,NULL,NULL,relio_ascend,&len);
415 ss << str;
416 ascfree(str);
417 }else{
418 throw runtime_error("getRelationString: Instance is not a relation");
419 }
420 return ss.str();
421 }
422
423 const double
424 Instanc::getResidual() const{
425 if(!isRelation()){
426 throw runtime_error("getResidual: not a relation");
427 }
428 struct RelationInstance * const ri = (struct RelationInstance * const)i;
429
430 return RelationResidual( ri->ptr );
431 }
432
433 /**
434 Return the numerical value of an instance if it is an assigned atom.
435 If it is a relation, return the string form of the relation (ie the equation)
436 Else return the string 'undefined'.
437 */
438 const string
439 Instanc::getValueAsString() const{
440 stringstream ss;
441
442 if(isAssigned()){
443 if(isReal()){
444 ss << getRealValue();
445 }else if(isInt()){
446 ss << getIntValue();
447 }else if(isSymbol()){
448 ss << getSymbolValue();
449 }else if(isBool()){
450 ss << getBoolValue();
451 }else{
452 throw runtime_error("Invalid type in Instanc::getValueAsString");
453 }
454 }else{
455 ss << "undefined";
456 }
457 return ss.str();
458 }
459
460 const bool
461 Instanc::isPlottable() const{
462 if(plot_allowed(i)){
463 return true;
464 }
465 return false;
466 }
467
468 const enum set_kind
469 Instanc::getSetType() const{
470 if(!isSet() || (!isConst() && !isDefined())){
471 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not set-valued or not defined",getName().toString());
472 }
473 return SetKind(SetAtomList(i));
474 }
475
476 /// Get the child instances :)
477 vector<Instanc> &
478 Instanc::getChildren()
479 {
480 Type t = getType();
481
482 children = vector<Instanc>();
483
484 if(i==NULL)throw runtime_error("NULL 'i' in Instanc::getChildren");
485
486 unsigned long len = NumberChildren(i);
487 if(!len)return children;
488 //cerr << "FOUND " << len << " CHILDREN" << endl;
489
490 if(isArray()){
491 for(unsigned long ci=1; ci<=len; ++ci){
492 Instanc c(*this, ci);
493 if(!TypeShow(c.getType().getInternalType()))continue;
494 children.push_back(c);
495 }
496 return children;
497 /* stringstream ss;
498 ss << "Instance '" << getName() << "' is an array, type '" << t.getName() << "'";
499 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str()); */
500 }
501
502
503 ChildListPtr clist = GetChildList(t.getInternalType());
504 if(!clist){
505 stringstream ss;
506 ss << "Child list of instance '" << getName() << "' of type '" << t.getName() << "' (" << getKindStr() << ") is NULL";
507 ss << " (isChildless=" << isChildless() << ")";
508 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str());
509 return children;
510 //throw runtime_error(ss.str());
511 }
512
513 /// FIXME 1-based array:
514 for(unsigned long ci=1; ci<=len; ++ci){
515 if(!ChildVisible(clist,ci))continue;
516
517 Instanc c( *this, ci );
518 //cerr << "FOUND CHILD #" << ci << ": " << c.getName() << endl;
519
520 children.push_back(c);
521 }
522 return children;
523 }
524
525 Instanc
526 Instanc::getChild(const SymChar &name) const{
527 struct Instance *c = ChildByChar(i,name.getInternalType());
528 if(c==NULL)throw runtime_error("Child not found");
529 return Instanc(c);
530 }
531
532 Plot
533 Instanc::getPlot() const{
534 if(isPlottable()){
535 return Plot(*this);
536 }
537 throw runtime_error("Not a plottable instance");
538 }
539
540 void
541 Instanc::write(){
542 WriteInstance(stderr,i);
543 }
544
545 //----------------------------
546 // SETTING VALUES of stuff
547
548 void
549 Instanc::setFixed(const bool &val){
550 if(isFixed()==val)return;
551 getChild("fixed").setBoolValue(val);
552 }
553
554 void
555 Instanc::setBoolValue(const bool &val, const unsigned &depth){
556 SetBooleanAtomValue(i, val, depth);
557 }
558
559 void
560 Instanc::setRealValue(const double &val, const unsigned &depth){
561 SetRealAtomValue(i,val, depth);
562 //ERROR_REPORTER_HERE(ASC_USER_NOTE,"Set %s to %f",getName().toString(),val);
563 }
564
565 /**
566 Borrow the workings of this from tcltk UnitsProc.c
567 */
568 void
569 Instanc::setRealValueWithUnits(double val, const char *units, const unsigned &depth){
570
571 if(isConst()){
572 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Can't change the value of a constant");
573 return;
574 }
575
576 if(!isReal() || !isAtom()){
577 throw runtime_error("Instanc::setRealValueWithUnits: not a real-valued instance");
578 }
579
580 if(units == NULL || strlen(units)==0 || strcmp(units,"*")==0){
581 // No units were specified, so the base (SI) units are implied.
582 }else{
583 // We need to parse the units string
584 UnitsM u = UnitsM(units);
585 Dimensions d = u.getDimensions();
586
587 // If no dimensions yet assigned, assign them. Otheriwse check for consistency.
588 if(getDimensions().isWild()){
589 // Set the dimensions for a wildcard atom:
590 SetRealAtomDims(i, d.getInternalType());
591 }else if(d != getDimensions()){
592 throw runtime_error("Dimensionally incompatible units");
593 }
594
595 // Not going to worry about FPEs here, let the program crash if it must.
596 val = val * u.getConversion();
597 }
598
599 SetRealAtomValue(i,val,depth);
600 }
601
602 /**
603 Set the instance variable status. See @getVarStatus
604 */
605 void
606 Instanc::setVarStatus(const VarStatus &s){
607 InstanceInterfaceData *d;
608 d = (InstanceInterfaceData *)GetInterfacePtr(i);
609 if(d==NULL && s!=ASCXX_VAR_STATUS_UNKNOWN){
610 d = new InstanceInterfaceData();
611 SetInterfacePtr(i,d);
612 }
613 d->status = s;
614 }
615
616 /**
617 Return the instance variable status.
618 This data is stored in the 'interface_ptr' of the instance, so
619 that we can be sure we'll get it, regardless of which
620 instance of an Instanc we have in our hands :-)
621 */
622 const VarStatus
623 Instanc::getVarStatus() const{
624 InstanceInterfaceData *d;
625 d = (InstanceInterfaceData *)GetInterfacePtr(i);
626 if(d==NULL){
627 return ASCXX_VAR_STATUS_UNKNOWN;
628 }
629 return d->status;
630 }
631
632
633
634 /*------------------------------------------------------
635 Macros to declare
636 setUpperBound
637 setLowerBound
638 setNominal
639 and their 'get' equivalents
640 */
641
642 #define DEFINE_GET_REAL_CHILD(METHOD,CHILD) \
643 const double \
644 Instanc::get##METHOD() const{ \
645 Instanc c = getChild(CHILD); \
646 return c.getRealValue(); \
647 }
648
649 #define DEFINE_SET_REAL_CHILD(METHOD,CHILD) \
650 void \
651 Instanc::set##METHOD(const double &v){ \
652 Instanc c = getChild(CHILD); \
653 c.setRealValue(v); \
654 }
655
656 #define DEFINE_CHILD_METHODS(D) \
657 D(LowerBound,"lower_bound") \
658 D(UpperBound,"upper_bound") \
659 D(Nominal,"nominal")
660
661 DEFINE_CHILD_METHODS(DEFINE_SET_REAL_CHILD)
662 DEFINE_CHILD_METHODS(DEFINE_GET_REAL_CHILD)
663
664 //------------------------------------------------------
665
666 const vector<Instanc>
667 Instanc::getClique() const{
668 vector<Instanc> v;
669 struct Instance *i1 = i;
670 do{
671 v.push_back(Instanc(i1));
672 i1=NextCliqueMember(i1);
673 }while(i1 != i); // ie we've gone around the circuit
674 return v;
675 }
676
677 //------------------------------------------------------
678 // static properties
679 SymChar
680 Instanc::fixedsym = SymChar("fixed");
681
682 SymChar
683 Instanc::solvervarsym = SymChar("solver_var");

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