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

Contents of /trunk/pygtk/instance.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 876 - (show annotations) (download) (as text)
Sat Oct 7 06:55:11 2006 UTC (16 years, 8 months ago) by johnpye
File MIME type: text/x-c++src
File size: 16893 byte(s)
Slightly simplified access to child instances from python
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");

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