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

Contents of /trunk/pygtk/interface/instance.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

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