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

Annotation of /trunk/pygtk/instance.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 569 - (hide annotations) (download) (as text)
Tue May 9 00:10:03 2006 UTC (19 years, 7 months ago) by johnpye
File MIME type: text/x-c++src
File size: 15812 byte(s)
Changing from 'tcltk98' to 'tcltk', in progress.
1 johnpye 132 #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 johnpye 172 #include <compiler/plot.h>
27 johnpye 207 #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 johnpye 273 #include <compiler/functype.h>
34     #include <compiler/instance_types.h>
35     #include <compiler/relation_util.h>
36 johnpye 132 }
37    
38     #include "instance.h"
39     #include "variable.h"
40     #include "name.h"
41     #include "set.h"
42 johnpye 176 #include "plot.h"
43 johnpye 255 #include "instanceinterfacedata.h"
44 johnpye 132
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 johnpye 190 Instanc::Instanc(const Instanc &parent, const unsigned long &childnum)
79 johnpye 132 : 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 johnpye 190 }
92 johnpye 132
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 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not real-valued (%s)", \
306 johnpye 132 getName().toString(),getKindStr().c_str());
307     return 0;
308     }
309     if(!isConst() && !isDefined()){
310 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined (%s)", \
311 johnpye 132 getName().toString(),getKindStr().c_str());
312     return 0;
313     }
314 johnpye 190 return RealAtomValue(i);
315 johnpye 132 }
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 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not boolean-valued",getName().toString());
340 johnpye 132 return false;
341     }
342     if(!isConst() && !isDefined()){
343 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
344 johnpye 132 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 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not integer-valued",getName().toString());
361 johnpye 132 return 0;
362     }
363     if(!isConst() && !isDefined()){
364 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
365 johnpye 132 return 0;
366     }
367     return GetIntegerAtomValue(i);
368     }
369    
370     const SymChar
371     Instanc::getSymbolValue() const{
372     if(!isSymbol()){
373 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not symbol-valued",getName().toString());
374 johnpye 132 return SymChar("ERROR");
375     }
376     if(!isConst() && !isDefined()){
377 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not defined",getName().toString());
378 johnpye 132 return SymChar("UNDEFINED");
379     }
380     return SCP(GetSymbolAtomValue(i));
381     }
382    
383 johnpye 215 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 johnpye 273
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 johnpye 569
408 johnpye 207 /**
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 johnpye 175 const string
414     Instanc::getValueAsString() const{
415     stringstream ss;
416 johnpye 207
417 johnpye 215 if(isAssigned()){
418 johnpye 175 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 johnpye 190 const bool
436 johnpye 172 Instanc::isPlottable() const{
437     if(plot_allowed(i)){
438     return true;
439     }
440     return false;
441     }
442    
443 johnpye 190 const enum set_kind
444 johnpye 132 Instanc::getSetType() const{
445     if(!isSet() || (!isConst() && !isDefined())){
446 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Variable '%s' is not set-valued or not defined",getName().toString());
447 johnpye 132 }
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 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str()); */
475 johnpye 132 }
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 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_WARNING,ss.str().c_str());
484 johnpye 132 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 johnpye 176 Plot
508     Instanc::getPlot() const{
509     if(isPlottable()){
510     return Plot(*this);
511     }
512     throw runtime_error("Not a plottable instance");
513     }
514    
515 johnpye 132 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 johnpye 190 //ERROR_REPORTER_HERE(ASC_USER_NOTE,"Set %s to %f",getName().toString(),val);
538 johnpye 132 }
539    
540     /**
541 johnpye 569 Borrow the workings of this from tcltk UnitsProc.c
542 johnpye 132 */
543     void
544     Instanc::setRealValueWithUnits(double val, const char *units, const unsigned &depth){
545    
546     if(isConst()){
547 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Can't change the value of a constant");
548 johnpye 132 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 johnpye 190
562 johnpye 132 // 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 johnpye 190
570 johnpye 132 // 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 johnpye 255 /**
578     Set the instance variable status. See @getVarStatus
579     */
580 johnpye 569 void
581 johnpye 255 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 johnpye 569 /**
592 johnpye 255 Return the instance variable status.
593     This data is stored in the 'interface_ptr' of the instance, so
594 johnpye 569 that we can be sure we'll get it, regardless of which
595 johnpye 255 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 johnpye 268 return d->status;
605 johnpye 255 }
606    
607 johnpye 268
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 johnpye 271 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 johnpye 132 // 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