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

Contents of /trunk/pygtk/instance.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 732 - (show annotations) (download) (as text)
Tue Jul 4 14:40:17 2006 UTC (17 years, 10 months ago) by johnpye
File MIME type: text/x-c++src
File size: 15917 byte(s)
Added general-purpose text-information dialog to PyGTK interface.
Added reporting of clique of a variable to PyGTK GUI.
Changed 'fixable' and 'new bounds' to use the new dialog.
Removed 'set<...>' from ascpy.i (it wasn't working), changed to vector<...>.
Exported a couple of var incidences fns to the DLL/SO.
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 double
311 Instanc::getRealValue() const{
312 // Check that the instance has a real value:
313 switch(getKind()){
314 case REAL_INST:
315 case REAL_CONSTANT_INST:
316 case REAL_ATOM_INST:
317 //cerr << "REAL VALUE FOR " << getName() << endl;
318 break;
319 default:
320 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not real-valued (%s)", \
321 getName().toString(),getKindStr().c_str());
322 return 0;
323 }
324 if(!isConst() && !isDefined()){
325 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined (%s)", \
326 getName().toString(),getKindStr().c_str());
327 return 0;
328 }
329 return RealAtomValue(i);
330 }
331
332 const bool
333 Instanc::isDimensionless() const{
334 if(!isReal())return true;
335 return Dimensions( RealAtomDims(i) ).isDimensionless();
336 }
337
338 const Dimensions
339 Instanc::getDimensions() const{
340 if(!isReal())throw runtime_error("Instanc::getDimensions: not a real-valued instance");
341 return Dimensions( RealAtomDims(i) );
342 }
343
344 const bool
345 Instanc::getBoolValue() const{
346 // Check that the instance has a bool value:
347 switch(getKind()){
348 case BOOLEAN_INST:
349 case BOOLEAN_ATOM_INST:
350 case BOOLEAN_CONSTANT_INST:
351 //cerr << "BOOL VALUE FOR " << getName() << endl;
352 break;
353 default:
354 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not boolean-valued",getName().toString());
355 return false;
356 }
357 if(!isConst() && !isDefined()){
358 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
359 return false;
360 }
361 return GetBooleanAtomValue(i);
362 }
363
364
365 const long
366 Instanc::getIntValue() const{
367 // Check that the instance has a bool value:
368 switch(getKind()){
369 case INTEGER_INST:
370 case INTEGER_ATOM_INST:
371 case INTEGER_CONSTANT_INST:
372 //cerr << "INT VALUE FOR " << getName() << endl;
373 break;
374 default:
375 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not integer-valued",getName().toString());
376 return 0;
377 }
378 if(!isConst() && !isDefined()){
379 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
380 return 0;
381 }
382 return GetIntegerAtomValue(i);
383 }
384
385 const SymChar
386 Instanc::getSymbolValue() const{
387 if(!isSymbol()){
388 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not symbol-valued",getName().toString());
389 return SymChar("ERROR");
390 }
391 if(!isConst() && !isDefined()){
392 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
393 return SymChar("UNDEFINED");
394 }
395 return SCP(GetSymbolAtomValue(i));
396 }
397
398 const string
399 Instanc::getRelationAsString(const Instanc &relative_to) const{
400 stringstream ss;
401 if(isRelation()){
402 int len;
403 char *str = WriteRelationString(i,relative_to.getInternalType()
404 ,NULL,NULL,relio_ascend,&len);
405 ss << str;
406 ascfree(str);
407 }else{
408 throw runtime_error("getRelationString: Instance is not a relation");
409 }
410 return ss.str();
411 }
412
413 const double
414 Instanc::getResidual() const{
415 if(!isRelation()){
416 throw runtime_error("getResidual: not a relation");
417 }
418 struct RelationInstance * const ri = (struct RelationInstance * const)i;
419
420 return RelationResidual( ri->ptr );
421 }
422
423 /**
424 Return the numerical value of an instance if it is an assigned atom.
425 If it is a relation, return the string form of the relation (ie the equation)
426 Else return the string 'undefined'.
427 */
428 const string
429 Instanc::getValueAsString() const{
430 stringstream ss;
431
432 if(isAssigned()){
433 if(isReal()){
434 ss << getRealValue();
435 }else if(isInt()){
436 ss << getIntValue();
437 }else if(isSymbol()){
438 ss << getSymbolValue();
439 }else if(isBool()){
440 ss << getBoolValue();
441 }else{
442 throw runtime_error("Invalid type in Instanc::getValueAsString");
443 }
444 }else{
445 ss << "undefined";
446 }
447 return ss.str();
448 }
449
450 const bool
451 Instanc::isPlottable() const{
452 if(plot_allowed(i)){
453 return true;
454 }
455 return false;
456 }
457
458 const enum set_kind
459 Instanc::getSetType() const{
460 if(!isSet() || (!isConst() && !isDefined())){
461 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not set-valued or not defined",getName().toString());
462 }
463 return SetKind(SetAtomList(i));
464 }
465
466 /// Get the child instances :)
467 vector<Instanc> &
468 Instanc::getChildren()
469 {
470 Type t = getType();
471
472 children = vector<Instanc>();
473
474 if(i==NULL)throw runtime_error("NULL 'i' in Instanc::getChildren");
475
476 unsigned long len = NumberChildren(i);
477 if(!len)return children;
478 //cerr << "FOUND " << len << " CHILDREN" << endl;
479
480 if(isArray()){
481 for(unsigned long ci=1; ci<=len; ++ci){
482 Instanc c(*this, ci);
483 if(!TypeShow(c.getType().getInternalType()))continue;
484 children.push_back(c);
485 }
486 return children;
487 /* stringstream ss;
488 ss << "Instance '" << getName() << "' is an array, type '" << t.getName() << "'";
489 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str()); */
490 }
491
492
493 ChildListPtr clist = GetChildList(t.getInternalType());
494 if(!clist){
495 stringstream ss;
496 ss << "Child list of instance '" << getName() << "' of type '" << t.getName() << "' (" << getKindStr() << ") is NULL";
497 ss << " (isChildless=" << isChildless() << ")";
498 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str());
499 return children;
500 //throw runtime_error(ss.str());
501 }
502
503 /// FIXME 1-based array:
504 for(unsigned long ci=1; ci<=len; ++ci){
505 if(!ChildVisible(clist,ci))continue;
506
507 Instanc c( *this, ci );
508 //cerr << "FOUND CHILD #" << ci << ": " << c.getName() << endl;
509
510 children.push_back(c);
511 }
512 return children;
513 }
514
515 Instanc
516 Instanc::getChild(const SymChar &name) const{
517 struct Instance *c = ChildByChar(i,name.getInternalType());
518 if(c==NULL)throw runtime_error("Child not found");
519 return Instanc(c);
520 }
521
522 Plot
523 Instanc::getPlot() const{
524 if(isPlottable()){
525 return Plot(*this);
526 }
527 throw runtime_error("Not a plottable instance");
528 }
529
530 void
531 Instanc::write(){
532 WriteInstance(stderr,i);
533 }
534
535 //----------------------------
536 // SETTING VALUES of stuff
537
538 void
539 Instanc::setFixed(const bool &val){
540 if(isFixed()==val)return;
541 getChild("fixed").setBoolValue(val);
542 }
543
544 void
545 Instanc::setBoolValue(const bool &val, const unsigned &depth){
546 SetBooleanAtomValue(i, val, depth);
547 }
548
549 void
550 Instanc::setRealValue(const double &val, const unsigned &depth){
551 SetRealAtomValue(i,val, depth);
552 //ERROR_REPORTER_HERE(ASC_USER_NOTE,"Set %s to %f",getName().toString(),val);
553 }
554
555 /**
556 Borrow the workings of this from tcltk UnitsProc.c
557 */
558 void
559 Instanc::setRealValueWithUnits(double val, const char *units, const unsigned &depth){
560
561 if(isConst()){
562 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Can't change the value of a constant");
563 return;
564 }
565
566 if(!isReal() || !isAtom()){
567 throw runtime_error("Instanc::setRealValueWithUnits: not a real-valued instance");
568 }
569
570 if(units == NULL || strlen(units)==0 || strcmp(units,"*")==0){
571 // No units were specified, so the base (SI) units are implied.
572 }else{
573 // We need to parse the units string
574 UnitsM u = UnitsM(units);
575 Dimensions d = u.getDimensions();
576
577 // If no dimensions yet assigned, assign them. Otheriwse check for consistency.
578 if(getDimensions().isWild()){
579 // Set the dimensions for a wildcard atom:
580 SetRealAtomDims(i, d.getInternalType());
581 }else if(d != getDimensions()){
582 throw runtime_error("Dimensionally incompatible units");
583 }
584
585 // Not going to worry about FPEs here, let the program crash if it must.
586 val = val * u.getConversion();
587 }
588
589 SetRealAtomValue(i,val,depth);
590 }
591
592 /**
593 Set the instance variable status. See @getVarStatus
594 */
595 void
596 Instanc::setVarStatus(const VarStatus &s){
597 InstanceInterfaceData *d;
598 d = (InstanceInterfaceData *)GetInterfacePtr(i);
599 if(d==NULL && s!=ASCXX_VAR_STATUS_UNKNOWN){
600 d = new InstanceInterfaceData();
601 SetInterfacePtr(i,d);
602 }
603 d->status = s;
604 }
605
606 /**
607 Return the instance variable status.
608 This data is stored in the 'interface_ptr' of the instance, so
609 that we can be sure we'll get it, regardless of which
610 instance of an Instanc we have in our hands :-)
611 */
612 const VarStatus
613 Instanc::getVarStatus() const{
614 InstanceInterfaceData *d;
615 d = (InstanceInterfaceData *)GetInterfacePtr(i);
616 if(d==NULL){
617 return ASCXX_VAR_STATUS_UNKNOWN;
618 }
619 return d->status;
620 }
621
622
623
624 /*------------------------------------------------------
625 Macros to declare
626 setUpperBound
627 setLowerBound
628 setNominal
629 and their 'get' equivalents
630 */
631
632 #define DEFINE_GET_REAL_CHILD(METHOD,CHILD) \
633 const double \
634 Instanc::get##METHOD() const{ \
635 Instanc c = getChild(CHILD); \
636 return c.getRealValue(); \
637 }
638
639 #define DEFINE_SET_REAL_CHILD(METHOD,CHILD) \
640 void \
641 Instanc::set##METHOD(const double &v){ \
642 Instanc c = getChild(CHILD); \
643 c.setRealValue(v); \
644 }
645
646 #define DEFINE_CHILD_METHODS(D) \
647 D(LowerBound,"lower_bound") \
648 D(UpperBound,"upper_bound") \
649 D(Nominal,"nominal")
650
651 DEFINE_CHILD_METHODS(DEFINE_SET_REAL_CHILD)
652 DEFINE_CHILD_METHODS(DEFINE_GET_REAL_CHILD)
653
654 //------------------------------------------------------
655
656 const vector<Instanc>
657 Instanc::getClique() const{
658 vector<Instanc> v;
659 struct Instance *i1 = i;
660 do{
661 v.push_back(Instanc(i1));
662 i1=NextCliqueMember(i1);
663 }while(i1 != i); // ie we've gone around the circuit
664 return v;
665 }
666
667 //------------------------------------------------------
668 // static properties
669 SymChar
670 Instanc::fixedsym = SymChar("fixed");
671
672 SymChar
673 Instanc::solvervarsym = SymChar("solver_var");

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