1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 2006 Carnegie Mellon University |
3 |
Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
4 |
|
5 |
This program is free software; you can redistribute it and/or |
6 |
modify it under the terms of the GNU General Public License |
7 |
as published by the Free Software Foundation; either version 2 |
8 |
of the License, or (at your option) any later version. |
9 |
|
10 |
This program is distributed in the hope that it will be useful, |
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
GNU General Public License for more details. |
14 |
|
15 |
You should have received a copy of the GNU General Public License |
16 |
along with this program; if not, write to the Free Software |
17 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 |
*//** |
19 |
@file |
20 |
Ascend Instance Tree Type Implementation |
21 |
*//* |
22 |
by Tom Epperly |
23 |
9/3/89 |
24 |
Last in CVS: $Revision: 1.10 $ $Date: 1998/05/06 17:33:36 $ $Author: ballan $ |
25 |
*/ |
26 |
|
27 |
#include <stdarg.h> |
28 |
#include <ascend/general/platform.h> |
29 |
#include <ascend/general/ascMalloc.h> |
30 |
#include <ascend/general/panic.h> |
31 |
#include <ascend/general/pool.h> |
32 |
#include <ascend/general/list.h> |
33 |
#include <ascend/general/dstring.h> |
34 |
|
35 |
#include "symtab.h" |
36 |
#include "functype.h" |
37 |
#include "expr_types.h" |
38 |
#include "child.h" |
39 |
#include "type_desc.h" |
40 |
#include "instance_name.h" |
41 |
#include "instance_io.h" |
42 |
#include "instmacro.h" |
43 |
#include "extinst.h" |
44 |
#include "instquery.h" |
45 |
#include "instance_types.h" |
46 |
#include "linkinst.h" |
47 |
#include "destroyinst.h" |
48 |
#include "createinst.h" |
49 |
#include "refineinst.h" |
50 |
#include "atomvalue.h" |
51 |
#include "atomsize.h" |
52 |
#include "check.h" |
53 |
#include "dump.h" |
54 |
#include "childinfo.h" |
55 |
#include "prototype.h" |
56 |
#include "pending.h" |
57 |
#include "find.h" |
58 |
#include "rel_blackbox.h" |
59 |
#include "vlist.h" |
60 |
#include "relation.h" |
61 |
#include "logical_relation.h" |
62 |
#include "logrelation.h" |
63 |
#include "relation_util.h" |
64 |
#include "logrel_util.h" |
65 |
#include "rel_common.h" |
66 |
#include "case.h" |
67 |
#include "when_util.h" |
68 |
#include "universal.h" |
69 |
#include "cmpfunc.h" |
70 |
#include "tmpnum.h" |
71 |
#include "mathinst.h" |
72 |
|
73 |
static const char panic_msg[]="Incorrect type '%s' passed"; |
74 |
#define PANIC_INCORRECT_TYPE(i) ASC_PANIC(panic_msg,instance_typename(i)) |
75 |
|
76 |
enum Expr_enum GetInstanceRelationType(CONST struct Instance *i) |
77 |
{ |
78 |
AssertMemory(i); |
79 |
if (i->t == REL_INST) { |
80 |
return RELN_INST(i)->type; /* the implementation kind */ |
81 |
}else{ |
82 |
PANIC_INCORRECT_TYPE(i); |
83 |
} |
84 |
} |
85 |
|
86 |
CONST struct relation *GetInstanceRelationOnly(CONST struct Instance *i) |
87 |
{ |
88 |
AssertMemory(i); |
89 |
if (i->t == REL_INST) { |
90 |
return RELN_INST(i)->ptr; |
91 |
}else{ |
92 |
PANIC_INCORRECT_TYPE(i); |
93 |
} |
94 |
} |
95 |
|
96 |
CONST struct relation *GetInstanceRelation(CONST struct Instance *i, |
97 |
enum Expr_enum *type) |
98 |
{ |
99 |
AssertMemory(i); |
100 |
if (i->t == REL_INST) { |
101 |
*type = RELN_INST(i)->type; |
102 |
return RELN_INST(i)->ptr; |
103 |
}else{ |
104 |
PANIC_INCORRECT_TYPE(i); |
105 |
} |
106 |
} |
107 |
|
108 |
struct relation *GetInstanceRelToModify(struct Instance *i, |
109 |
enum Expr_enum *type) |
110 |
{ |
111 |
AssertMemory(i); |
112 |
if (i->t == REL_INST) { |
113 |
*type = RELN_INST(i)->type; |
114 |
return RELN_INST(i)->ptr; |
115 |
}else{ |
116 |
PANIC_INCORRECT_TYPE(i); |
117 |
|
118 |
} |
119 |
} |
120 |
|
121 |
|
122 |
CONST struct logrelation *GetInstanceLogRel(CONST struct Instance *i) |
123 |
{ |
124 |
AssertMemory(i); |
125 |
if (i->t == LREL_INST) { |
126 |
return LRELN_INST(i)->ptr; |
127 |
}else{ |
128 |
PANIC_INCORRECT_TYPE(i); |
129 |
|
130 |
} |
131 |
} |
132 |
|
133 |
struct logrelation *GetInstanceLogRelToModify(struct Instance *i) |
134 |
{ |
135 |
AssertMemory(i); |
136 |
if (i->t == LREL_INST) { |
137 |
return LRELN_INST(i)->ptr; |
138 |
}else{ |
139 |
PANIC_INCORRECT_TYPE(i); |
140 |
|
141 |
} |
142 |
} |
143 |
|
144 |
CONST struct logrelation *GetInstanceLogRelOnly(CONST struct Instance *i) |
145 |
{ |
146 |
AssertMemory(i); |
147 |
if (InstanceKind(i) == LREL_INST) { |
148 |
return LRELN_INST(i)->ptr; |
149 |
}else{ |
150 |
PANIC_INCORRECT_TYPE(i); |
151 |
|
152 |
} |
153 |
} |
154 |
|
155 |
/** |
156 |
Returns list of vars/models/equations in a mathematical relationship. |
157 |
May want to include the models/relations from the cases of a when. |
158 |
*/ |
159 |
struct gl_list_t *GetInstanceOperands(CONST struct Instance *i) |
160 |
{ |
161 |
CONST struct gl_list_t *list = NULL; |
162 |
CONST struct gl_list_t *list2 = NULL; |
163 |
struct gl_list_t *result = NULL; |
164 |
unsigned long c,len; |
165 |
CONST struct relation *rel; |
166 |
CONST struct logrelation *lrel; |
167 |
void *p; |
168 |
|
169 |
if (i == NULL) { |
170 |
return NULL; |
171 |
} |
172 |
switch (InstanceKind(i)) { |
173 |
case REL_INST: |
174 |
rel = GetInstanceRelationOnly(i); |
175 |
if (rel != NULL) { |
176 |
list = RelationVarList(rel); |
177 |
} |
178 |
break; |
179 |
case LREL_INST: |
180 |
lrel = GetInstanceLogRel(i); |
181 |
if (lrel != NULL) { |
182 |
list = LogRelBoolVarList(lrel); |
183 |
list2 = LogRelSatRelList(lrel); |
184 |
} |
185 |
break; |
186 |
case WHEN_INST: |
187 |
list = GetInstanceWhenVars(i); |
188 |
break; |
189 |
default: |
190 |
return NULL; |
191 |
} |
192 |
len = 0; |
193 |
len += (list != NULL) ? gl_length(list) : 0; |
194 |
len += (list2 != NULL) ? gl_length(list2) : 0; |
195 |
result = gl_create(len); |
196 |
if (list != NULL) { |
197 |
for (c=1; c <= len; c++) { |
198 |
p = gl_fetch(list,c); |
199 |
if (p!=NULL) { |
200 |
gl_append_ptr(result,p); |
201 |
} |
202 |
} |
203 |
} |
204 |
if (list2 != NULL) { |
205 |
for (c=1; c <= len; c++) { |
206 |
p = gl_fetch(list2,c); |
207 |
if (p!=NULL) { |
208 |
gl_append_ptr(result,p); |
209 |
} |
210 |
} |
211 |
} |
212 |
return result; |
213 |
} |
214 |
|
215 |
struct gl_list_t *GetInstanceWhenVars(CONST struct Instance *i) |
216 |
{ |
217 |
AssertMemory(i); |
218 |
if (i->t == WHEN_INST) { |
219 |
return W_INST(i)->bvar; |
220 |
}else{ |
221 |
PANIC_INCORRECT_TYPE(i); |
222 |
|
223 |
} |
224 |
} |
225 |
|
226 |
struct gl_list_t *GetInstanceWhenCases(CONST struct Instance *i) |
227 |
{ |
228 |
AssertMemory(i); |
229 |
if (i->t == WHEN_INST) { |
230 |
return W_INST(i)->cases; |
231 |
}else{ |
232 |
PANIC_INCORRECT_TYPE(i); |
233 |
} |
234 |
} |
235 |
|
236 |
struct gl_list_t *GetInstanceWhens(CONST struct Instance *i) |
237 |
{ |
238 |
AssertMemory(i); |
239 |
switch(i->t) { |
240 |
case BOOLEAN_ATOM_INST: |
241 |
return BA_INST(i)->whens; |
242 |
case INTEGER_ATOM_INST: |
243 |
return IA_INST(i)->whens; |
244 |
case SYMBOL_ATOM_INST: |
245 |
return SYMA_INST(i)->whens; |
246 |
case BOOLEAN_CONSTANT_INST: |
247 |
return BC_INST(i)->whens; |
248 |
case INTEGER_CONSTANT_INST: |
249 |
return IC_INST(i)->whens; |
250 |
case SYMBOL_CONSTANT_INST: |
251 |
return SYMC_INST(i)->whens; |
252 |
case MODEL_INST: |
253 |
return MOD_INST(i)->whens; |
254 |
case REL_INST: |
255 |
return RELN_INST(i)->whens; |
256 |
case LREL_INST: |
257 |
return LRELN_INST(i)->whens; |
258 |
case WHEN_INST: |
259 |
return W_INST(i)->whens; |
260 |
default: |
261 |
PANIC_INCORRECT_TYPE(i); |
262 |
} |
263 |
} |
264 |
|
265 |
void SetWhenVarList(struct Instance *i,struct gl_list_t *whenvars) |
266 |
{ |
267 |
AssertMemory(i); |
268 |
if (i->t == WHEN_INST) { |
269 |
W_INST(i)->bvar = whenvars; |
270 |
}else{ |
271 |
PANIC_INCORRECT_TYPE(i); |
272 |
} |
273 |
} |
274 |
|
275 |
void SetWhenCases(struct Instance *i,struct gl_list_t *whencases) |
276 |
{ |
277 |
AssertMemory(i); |
278 |
if (i->t == WHEN_INST) { |
279 |
W_INST(i)->cases = whencases; |
280 |
}else{ |
281 |
PANIC_INCORRECT_TYPE(i); |
282 |
} |
283 |
} |
284 |
|
285 |
/** |
286 |
This is a tricky function. If we are attempting to set |
287 |
a new relation, and if the i->ptr is not NULL, i.e. a |
288 |
relation structure was already assigned, we must *not* force |
289 |
the assignment, and destroy the old relation. Unfortunately |
290 |
at this stage, we would have to back up todo undo the |
291 |
AddRelations etc. So we punt. |
292 |
*/ |
293 |
void SetInstanceRelation(struct Instance *i, struct relation *rel, |
294 |
enum Expr_enum type) |
295 |
{ |
296 |
AssertMemory(i); |
297 |
if(i->t==REL_INST){ |
298 |
if(RELN_INST(i)->ptr==NULL){ |
299 |
/* CONSOLE_DEBUG("RelationInstance %p points to relation at %p",i,rel); */ |
300 |
RELN_INST(i)->ptr = rel; |
301 |
RELN_INST(i)->type = type; |
302 |
}else{ |
303 |
Asc_Panic(2, __FUNCTION__, "Attempt to reassign RelationPointer."); |
304 |
} |
305 |
}else{ |
306 |
PANIC_INCORRECT_TYPE(i); |
307 |
} |
308 |
} |
309 |
|
310 |
void SetInstanceLogRel(struct Instance *i, struct logrelation *lrel){ |
311 |
AssertMemory(i); |
312 |
if(i->t==LREL_INST){ |
313 |
if(LRELN_INST(i)->ptr==NULL){ |
314 |
LRELN_INST(i)->ptr = lrel; |
315 |
}else{ |
316 |
Asc_Panic(2, __FUNCTION__, "Attempted reassignment to logrel ptr"); |
317 |
} |
318 |
}else{ |
319 |
PANIC_INCORRECT_TYPE(i); |
320 |
} |
321 |
} |
322 |
|
323 |
/*------------------------------------------------------------------------------ |
324 |
RELATION LIST STUFF |
325 |
*/ |
326 |
|
327 |
unsigned long RelationsCount(CONST struct Instance *i) |
328 |
{ |
329 |
assert(i!=NULL); |
330 |
AssertMemory(i); |
331 |
switch(i->t) { |
332 |
case REAL_ATOM_INST: |
333 |
if (RA_INST(i)->relations!=NULL) { |
334 |
return gl_length(RA_INST(i)->relations); |
335 |
}else{ |
336 |
return 0; |
337 |
} |
338 |
default: |
339 |
ASC_PANIC("RelationsCount called with inappropriate argument."); |
340 |
|
341 |
} |
342 |
} |
343 |
|
344 |
struct Instance *RelationsForAtom(CONST struct Instance *i, |
345 |
unsigned long int c) |
346 |
{ |
347 |
assert((i!=NULL)&&(c>0)&&(c<=RelationsCount(i))); |
348 |
AssertMemory(i); |
349 |
switch(i->t){ |
350 |
case REAL_ATOM_INST: |
351 |
if (RA_INST(i)->relations!=NULL) { |
352 |
return INST(gl_fetch(RA_INST(i)->relations,c)); |
353 |
}else{ |
354 |
ASC_PANIC("c out of bounds in RelationsForAtom."); |
355 |
} |
356 |
break; |
357 |
default: |
358 |
Asc_Panic(2, NULL, |
359 |
"RelationsForAtom called with inappropriate argument."); |
360 |
break; |
361 |
} |
362 |
exit(2);/* NOT REACHED. Needed to keep gcc from whining */ |
363 |
} |
364 |
|
365 |
void AddRelation(struct Instance *i, struct Instance *reln){ |
366 |
//unsigned long len; |
367 |
assert(i); |
368 |
assert(reln); |
369 |
assert(reln->t==REL_INST); |
370 |
AssertMemory(i); |
371 |
switch(i->t){ |
372 |
case REAL_ATOM_INST: |
373 |
/* CONSOLE_DEBUG("ADD RelationInstance %p to RealAtomInstance %p",reln,i); */ |
374 |
if (RA_INST(i)->relations==NULL) { |
375 |
RA_INST(i)->relations = gl_create(AVG_RELATIONS); |
376 |
} |
377 |
//len = gl_length(RA_INST(i)->relations); |
378 |
if (gl_search(RA_INST(i)->relations,(char*)reln,(CmpFunc)CmpRelations)==0){ |
379 |
gl_append_ptr(RA_INST(i)->relations,(VOIDPTR)reln); |
380 |
} |
381 |
break; |
382 |
default: |
383 |
PANIC_INCORRECT_TYPE(i); |
384 |
} |
385 |
} |
386 |
|
387 |
void RemoveRelation(struct Instance *i, struct Instance *reln) |
388 |
{ |
389 |
register unsigned long c; |
390 |
assert(i&&reln&&(reln->t==REL_INST)); |
391 |
AssertMemory(i); |
392 |
switch(i->t) { |
393 |
case REAL_ATOM_INST: |
394 |
if (RA_INST(i)->relations==NULL) { |
395 |
return; |
396 |
} |
397 |
c = gl_search(RA_INST(i)->relations,(char *)reln,(CmpFunc)CmpRelations); |
398 |
if (c>0) { |
399 |
gl_delete(RA_INST(i)->relations,c,0); |
400 |
} |
401 |
break; |
402 |
default: |
403 |
PANIC_INCORRECT_TYPE(i); |
404 |
} |
405 |
} |
406 |
|
407 |
/*------------------------------------------------------------------------------ |
408 |
LOGICAL RELATION LIST STUFF |
409 |
*/ |
410 |
|
411 |
unsigned long LogRelationsCount(CONST struct Instance *i) |
412 |
{ |
413 |
assert(i!=NULL); |
414 |
AssertMemory(i); |
415 |
switch(i->t) { |
416 |
case BOOLEAN_ATOM_INST: |
417 |
if (BA_INST(i)->logrelations!=NULL) { |
418 |
return gl_length(BA_INST(i)->logrelations); |
419 |
}else{ |
420 |
return 0; |
421 |
} |
422 |
case REL_INST: |
423 |
if (RELN_INST(i)->logrels!=NULL) { |
424 |
return gl_length(RELN_INST(i)->logrels); |
425 |
}else{ |
426 |
return 0; |
427 |
} |
428 |
case LREL_INST: |
429 |
if (LRELN_INST(i)->logrels!=NULL) { |
430 |
return gl_length(LRELN_INST(i)->logrels); |
431 |
}else{ |
432 |
return 0; |
433 |
} |
434 |
default: |
435 |
PANIC_INCORRECT_TYPE(i); |
436 |
} |
437 |
} |
438 |
|
439 |
struct Instance *LogRelationsForInstance(CONST struct Instance *i, |
440 |
unsigned long int c) |
441 |
{ |
442 |
assert((i!=NULL)&&(c>0)&&(c<=LogRelationsCount(i))); |
443 |
AssertMemory(i); |
444 |
switch(i->t){ |
445 |
case BOOLEAN_ATOM_INST: |
446 |
if (BA_INST(i)->logrelations!=NULL) { |
447 |
return INST(gl_fetch(BA_INST(i)->logrelations,c)); |
448 |
}else{ |
449 |
ASC_PANIC("c out of bounds in LogRelationsForInstance.\n"); |
450 |
} |
451 |
case REL_INST: |
452 |
if (RELN_INST(i)->logrels!=NULL) { |
453 |
return INST(gl_fetch(RELN_INST(i)->logrels,c)); |
454 |
}else{ |
455 |
ASC_PANIC("c out of bounds in LogRelationsForInstance.\n"); |
456 |
} |
457 |
case LREL_INST: |
458 |
if (LRELN_INST(i)->logrels!=NULL) { |
459 |
return INST(gl_fetch(LRELN_INST(i)->logrels,c)); |
460 |
}else{ |
461 |
ASC_PANIC("c out of bounds in LogRelationsForInstance.\n"); |
462 |
} |
463 |
default: |
464 |
PANIC_INCORRECT_TYPE(i); |
465 |
} |
466 |
exit(2);/* NOT REACHED. Needed to keep gcc from whining */ |
467 |
} |
468 |
|
469 |
void AddLogRel(struct Instance *i, struct Instance *lreln) |
470 |
{ |
471 |
//unsigned long len; |
472 |
assert(i&&lreln&&(lreln->t==LREL_INST)); |
473 |
AssertMemory(i); |
474 |
switch(i->t){ |
475 |
case BOOLEAN_ATOM_INST: |
476 |
if (BA_INST(i)->logrelations==NULL) { |
477 |
BA_INST(i)->logrelations = gl_create(AVG_LOGRELS); |
478 |
} |
479 |
//len = gl_length(BA_INST(i)->logrelations); |
480 |
if (gl_search(BA_INST(i)->logrelations, |
481 |
(char *)lreln,(CmpFunc)CmpLogRelations)==0) { |
482 |
gl_append_ptr(BA_INST(i)->logrelations,(VOIDPTR)lreln); |
483 |
} |
484 |
break; |
485 |
case REL_INST: |
486 |
if (RELN_INST(i)->logrels==NULL) { |
487 |
RELN_INST(i)->logrels = gl_create(AVG_LOGRELS); |
488 |
} |
489 |
//len = gl_length(RELN_INST(i)->logrels); |
490 |
if (gl_search(RELN_INST(i)->logrels, |
491 |
(char *)lreln,(CmpFunc)CmpLogRelations)==0) { |
492 |
gl_append_ptr(RELN_INST(i)->logrels,(VOIDPTR)lreln); |
493 |
} |
494 |
break; |
495 |
case LREL_INST: |
496 |
if (LRELN_INST(i)->logrels==NULL) { |
497 |
LRELN_INST(i)->logrels = gl_create(AVG_LOGRELS); |
498 |
} |
499 |
//len = gl_length(LRELN_INST(i)->logrels); |
500 |
if (gl_search(LRELN_INST(i)->logrels, |
501 |
(char *)lreln,(CmpFunc)CmpLogRelations)==0) { |
502 |
gl_append_ptr(LRELN_INST(i)->logrels,(VOIDPTR)lreln); |
503 |
} |
504 |
break; |
505 |
default: |
506 |
PANIC_INCORRECT_TYPE(i); |
507 |
} |
508 |
} |
509 |
|
510 |
void RemoveLogRel(struct Instance *i, struct Instance *lreln) |
511 |
{ |
512 |
register unsigned long c; |
513 |
assert(i&&lreln&&(lreln->t==LREL_INST)); |
514 |
AssertMemory(i); |
515 |
switch(i->t) { |
516 |
case BOOLEAN_ATOM_INST: |
517 |
if (BA_INST(i)->logrelations==NULL) { |
518 |
return; |
519 |
} |
520 |
c = gl_search(BA_INST(i)->logrelations, |
521 |
(char *)lreln,(CmpFunc)CmpLogRelations); |
522 |
if (c>0) { |
523 |
gl_delete(BA_INST(i)->logrelations,c,0); |
524 |
} |
525 |
break; |
526 |
case REL_INST: |
527 |
if (RELN_INST(i)->logrels==NULL) { |
528 |
return; |
529 |
} |
530 |
c = gl_search(RELN_INST(i)->logrels, |
531 |
(char *)lreln,(CmpFunc)CmpLogRelations); |
532 |
if (c>0) { |
533 |
gl_delete(RELN_INST(i)->logrels,c,0); |
534 |
} |
535 |
break; |
536 |
case LREL_INST: |
537 |
if (LRELN_INST(i)->logrels==NULL) { |
538 |
return; |
539 |
} |
540 |
c = gl_search(LRELN_INST(i)->logrels, |
541 |
(char *)lreln,(CmpFunc)CmpLogRelations); |
542 |
if (c>0) { |
543 |
gl_delete(LRELN_INST(i)->logrels,c,0); |
544 |
} |
545 |
break; |
546 |
default: |
547 |
PANIC_INCORRECT_TYPE(i); |
548 |
} |
549 |
} |
550 |
|
551 |
/*------------------------------------------------------------------------------ |
552 |
'WHEN' LIST STUFF |
553 |
*/ |
554 |
|
555 |
unsigned long WhensCount(struct Instance *i) |
556 |
{ |
557 |
assert(i!=NULL); |
558 |
AssertMemory(i); |
559 |
switch(i->t) { |
560 |
case BOOLEAN_ATOM_INST: |
561 |
if (BA_INST(i)->whens!=NULL) { |
562 |
return gl_length(BA_INST(i)->whens); |
563 |
}else{ |
564 |
return 0; |
565 |
} |
566 |
case INTEGER_ATOM_INST: |
567 |
if (IA_INST(i)->whens!=NULL) { |
568 |
return gl_length(IA_INST(i)->whens); |
569 |
}else{ |
570 |
return 0; |
571 |
} |
572 |
case SYMBOL_ATOM_INST: |
573 |
if (SYMA_INST(i)->whens!=NULL) { |
574 |
return gl_length(SYMA_INST(i)->whens); |
575 |
}else{ |
576 |
return 0; |
577 |
} |
578 |
case BOOLEAN_CONSTANT_INST: |
579 |
if (BC_INST(i)->whens!=NULL) { |
580 |
return gl_length(BC_INST(i)->whens); |
581 |
}else{ |
582 |
return 0; |
583 |
} |
584 |
case INTEGER_CONSTANT_INST: |
585 |
if (IC_INST(i)->whens!=NULL) { |
586 |
return gl_length(IC_INST(i)->whens); |
587 |
}else{ |
588 |
return 0; |
589 |
} |
590 |
case SYMBOL_CONSTANT_INST: |
591 |
if (SYMC_INST(i)->whens!=NULL) { |
592 |
return gl_length(SYMC_INST(i)->whens); |
593 |
}else{ |
594 |
return 0; |
595 |
} |
596 |
case MODEL_INST: |
597 |
if (MOD_INST(i)->whens!=NULL) { |
598 |
return gl_length(MOD_INST(i)->whens); |
599 |
}else{ |
600 |
return 0; |
601 |
} |
602 |
case REL_INST: |
603 |
if (RELN_INST(i)->whens!=NULL) { |
604 |
return gl_length(RELN_INST(i)->whens); |
605 |
}else{ |
606 |
return 0; |
607 |
} |
608 |
case LREL_INST: |
609 |
if (LRELN_INST(i)->whens!=NULL) { |
610 |
return gl_length(LRELN_INST(i)->whens); |
611 |
}else{ |
612 |
return 0; |
613 |
} |
614 |
case WHEN_INST: |
615 |
if (W_INST(i)->whens!=NULL) { |
616 |
return gl_length(W_INST(i)->whens); |
617 |
}else{ |
618 |
return 0; |
619 |
} |
620 |
default: |
621 |
PANIC_INCORRECT_TYPE(i); |
622 |
} |
623 |
} |
624 |
|
625 |
|
626 |
struct Instance *WhensForInstance(struct Instance *i, |
627 |
unsigned long int c) |
628 |
{ |
629 |
assert((i!=NULL)&&(c>0)&&(c<=WhensCount(i))); |
630 |
AssertMemory(i); |
631 |
switch(i->t) { |
632 |
case BOOLEAN_ATOM_INST: |
633 |
if (BA_INST(i)->whens!=NULL) |
634 |
return INST(gl_fetch(BA_INST(i)->whens,c)); |
635 |
else{ |
636 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
637 |
} |
638 |
case INTEGER_ATOM_INST: |
639 |
if (IA_INST(i)->whens!=NULL) { |
640 |
return INST(gl_fetch(IA_INST(i)->whens,c)); |
641 |
}else{ |
642 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
643 |
} |
644 |
case SYMBOL_ATOM_INST: |
645 |
if (SYMA_INST(i)->whens!=NULL) { |
646 |
return INST(gl_fetch(SYMA_INST(i)->whens,c)); |
647 |
}else{ |
648 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
649 |
} |
650 |
case BOOLEAN_CONSTANT_INST: |
651 |
if (BC_INST(i)->whens!=NULL) { |
652 |
return INST(gl_fetch(BC_INST(i)->whens,c)); |
653 |
}else{ |
654 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
655 |
} |
656 |
case INTEGER_CONSTANT_INST: |
657 |
if (IC_INST(i)->whens!=NULL) { |
658 |
return INST(gl_fetch(IC_INST(i)->whens,c)); |
659 |
}else{ |
660 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
661 |
} |
662 |
case SYMBOL_CONSTANT_INST: |
663 |
if (SYMC_INST(i)->whens!=NULL) { |
664 |
return INST(gl_fetch(SYMC_INST(i)->whens,c)); |
665 |
}else{ |
666 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
667 |
} |
668 |
case MODEL_INST: |
669 |
if (MOD_INST(i)->whens!=NULL) { |
670 |
return INST(gl_fetch(MOD_INST(i)->whens,c)); |
671 |
}else{ |
672 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
673 |
} |
674 |
case REL_INST: |
675 |
if (RELN_INST(i)->whens!=NULL) { |
676 |
return INST(gl_fetch(RELN_INST(i)->whens,c)); |
677 |
}else{ |
678 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
679 |
} |
680 |
case LREL_INST: |
681 |
if (LRELN_INST(i)->whens!=NULL) { |
682 |
return INST(gl_fetch(LRELN_INST(i)->whens,c)); |
683 |
}else{ |
684 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
685 |
} |
686 |
case WHEN_INST: |
687 |
if (W_INST(i)->whens!=NULL) { |
688 |
return INST(gl_fetch(W_INST(i)->whens,c)); |
689 |
}else{ |
690 |
ASC_PANIC("c out of bounds in WhensForInstance.\n"); |
691 |
} |
692 |
default: |
693 |
PANIC_INCORRECT_TYPE(i); |
694 |
} |
695 |
exit(2);/* NOT REACHED. Needed to keep gcc from whining */ |
696 |
} |
697 |
|
698 |
|
699 |
void AddWhen(struct Instance *i, struct Instance *when) |
700 |
{ |
701 |
//unsigned long len; |
702 |
assert(i&&when&&(when->t==WHEN_INST)); |
703 |
AssertMemory(i); |
704 |
switch(i->t){ |
705 |
case BOOLEAN_ATOM_INST: |
706 |
if (BA_INST(i)->whens==NULL) |
707 |
BA_INST(i)->whens = gl_create(AVG_WHEN); |
708 |
//len = gl_length(BA_INST(i)->whens); |
709 |
if (gl_search(BA_INST(i)->whens, |
710 |
(char *)when,(CmpFunc)CmpWhens)==0) |
711 |
gl_append_ptr(BA_INST(i)->whens,(VOIDPTR)when); |
712 |
break; |
713 |
case INTEGER_ATOM_INST: |
714 |
if (IA_INST(i)->whens==NULL) |
715 |
IA_INST(i)->whens = gl_create(AVG_WHEN); |
716 |
//len = gl_length(IA_INST(i)->whens); |
717 |
if (gl_search(IA_INST(i)->whens, |
718 |
(char *)when,(CmpFunc)CmpWhens)==0) |
719 |
gl_append_ptr(IA_INST(i)->whens,(VOIDPTR)when); |
720 |
break; |
721 |
case SYMBOL_ATOM_INST: |
722 |
if (SYMA_INST(i)->whens==NULL) |
723 |
SYMA_INST(i)->whens = gl_create(AVG_WHEN); |
724 |
//len = gl_length(SYMA_INST(i)->whens); |
725 |
if (gl_search(SYMA_INST(i)->whens, |
726 |
(char *)when,(CmpFunc)CmpWhens)==0) |
727 |
gl_append_ptr(SYMA_INST(i)->whens,(VOIDPTR)when); |
728 |
break; |
729 |
case BOOLEAN_CONSTANT_INST: |
730 |
if (BC_INST(i)->whens==NULL) |
731 |
BC_INST(i)->whens = gl_create(AVG_WHEN); |
732 |
//len = gl_length(BC_INST(i)->whens); |
733 |
if (gl_search(BC_INST(i)->whens, |
734 |
(char *)when,(CmpFunc)CmpWhens)==0) |
735 |
gl_append_ptr(BC_INST(i)->whens,(VOIDPTR)when); |
736 |
break; |
737 |
case INTEGER_CONSTANT_INST: |
738 |
if (IC_INST(i)->whens==NULL) |
739 |
IC_INST(i)->whens = gl_create(AVG_WHEN); |
740 |
//len = gl_length(IC_INST(i)->whens); |
741 |
if (gl_search(IC_INST(i)->whens, |
742 |
(char *)when,(CmpFunc)CmpWhens)==0) |
743 |
gl_append_ptr(IC_INST(i)->whens,(VOIDPTR)when); |
744 |
break; |
745 |
case SYMBOL_CONSTANT_INST: |
746 |
if (SYMC_INST(i)->whens==NULL) |
747 |
SYMC_INST(i)->whens = gl_create(AVG_WHEN); |
748 |
//len = gl_length(SYMC_INST(i)->whens); |
749 |
if (gl_search(SYMC_INST(i)->whens, |
750 |
(char *)when,(CmpFunc)CmpWhens)==0) |
751 |
gl_append_ptr(SYMC_INST(i)->whens,(VOIDPTR)when); |
752 |
break; |
753 |
case MODEL_INST: |
754 |
if (MOD_INST(i)->whens==NULL) |
755 |
MOD_INST(i)->whens = gl_create(AVG_WHEN); |
756 |
//len = gl_length(MOD_INST(i)->whens); |
757 |
if (gl_search(MOD_INST(i)->whens, |
758 |
(char *)when,(CmpFunc)CmpWhens)==0) |
759 |
gl_append_ptr(MOD_INST(i)->whens,(VOIDPTR)when); |
760 |
break; |
761 |
case REL_INST: |
762 |
if (RELN_INST(i)->whens==NULL) |
763 |
RELN_INST(i)->whens = gl_create(AVG_WHEN); |
764 |
//len = gl_length(RELN_INST(i)->whens); |
765 |
if (gl_search(RELN_INST(i)->whens, |
766 |
(char *)when,(CmpFunc)CmpWhens)==0) |
767 |
gl_append_ptr(RELN_INST(i)->whens,(VOIDPTR)when); |
768 |
break; |
769 |
case LREL_INST: |
770 |
if (LRELN_INST(i)->whens==NULL) |
771 |
LRELN_INST(i)->whens = gl_create(AVG_WHEN); |
772 |
//len = gl_length(LRELN_INST(i)->whens); |
773 |
if (gl_search(LRELN_INST(i)->whens, |
774 |
(char *)when,(CmpFunc)CmpWhens)==0) |
775 |
gl_append_ptr(LRELN_INST(i)->whens,(VOIDPTR)when); |
776 |
break; |
777 |
case WHEN_INST: |
778 |
if (W_INST(i)->whens==NULL) |
779 |
W_INST(i)->whens = gl_create(AVG_WHEN); |
780 |
//len = gl_length(W_INST(i)->whens); |
781 |
if (gl_search(W_INST(i)->whens, |
782 |
(char *)when,(CmpFunc)CmpWhens)==0) |
783 |
gl_append_ptr(W_INST(i)->whens,(VOIDPTR)when); |
784 |
break; |
785 |
default: |
786 |
PANIC_INCORRECT_TYPE(i); |
787 |
} |
788 |
} |
789 |
|
790 |
void RemoveWhen(struct Instance *i, struct Instance *when) |
791 |
{ |
792 |
register unsigned long c; |
793 |
assert(i&&when&&(when->t==WHEN_INST)); |
794 |
AssertMemory(i); |
795 |
switch(i->t) { |
796 |
case BOOLEAN_ATOM_INST: |
797 |
if (BA_INST(i)->whens==NULL) return; |
798 |
c = gl_search(BA_INST(i)->whens, |
799 |
(char *)when,(CmpFunc)CmpWhens); |
800 |
if (c>0) gl_delete(BA_INST(i)->whens,c,0); |
801 |
break; |
802 |
case INTEGER_ATOM_INST: |
803 |
if (IA_INST(i)->whens==NULL) return; |
804 |
c = gl_search(IA_INST(i)->whens, |
805 |
(char *)when,(CmpFunc)CmpWhens); |
806 |
if (c>0) gl_delete(IA_INST(i)->whens,c,0); |
807 |
break; |
808 |
case SYMBOL_ATOM_INST: |
809 |
if (SYMA_INST(i)->whens==NULL) return; |
810 |
c = gl_search(SYMA_INST(i)->whens, |
811 |
(char *)when,(CmpFunc)CmpWhens); |
812 |
if (c>0) gl_delete(SYMA_INST(i)->whens,c,0); |
813 |
break; |
814 |
case BOOLEAN_CONSTANT_INST: |
815 |
if (BC_INST(i)->whens==NULL) return; |
816 |
c = gl_search(BC_INST(i)->whens, |
817 |
(char *)when,(CmpFunc)CmpWhens); |
818 |
if (c>0) gl_delete(BC_INST(i)->whens,c,0); |
819 |
break; |
820 |
case INTEGER_CONSTANT_INST: |
821 |
if (IC_INST(i)->whens==NULL) return; |
822 |
c = gl_search(IC_INST(i)->whens, |
823 |
(char *)when,(CmpFunc)CmpWhens); |
824 |
if (c>0) gl_delete(IC_INST(i)->whens,c,0); |
825 |
break; |
826 |
case SYMBOL_CONSTANT_INST: |
827 |
if (SYMC_INST(i)->whens==NULL) return; |
828 |
c = gl_search(SYMC_INST(i)->whens, |
829 |
(char *)when,(CmpFunc)CmpWhens); |
830 |
if (c>0) gl_delete(SYMC_INST(i)->whens,c,0); |
831 |
break; |
832 |
case MODEL_INST: |
833 |
if (MOD_INST(i)->whens==NULL) return; |
834 |
c = gl_search(MOD_INST(i)->whens, |
835 |
(char *)when,(CmpFunc)CmpWhens); |
836 |
if (c>0) gl_delete(MOD_INST(i)->whens,c,0); |
837 |
break; |
838 |
case REL_INST: |
839 |
if (RELN_INST(i)->whens==NULL) return; |
840 |
c = gl_search(RELN_INST(i)->whens, |
841 |
(char *)when,(CmpFunc)CmpWhens); |
842 |
if (c>0) gl_delete(RELN_INST(i)->whens,c,0); |
843 |
break; |
844 |
case LREL_INST: |
845 |
if (LRELN_INST(i)->whens==NULL) return; |
846 |
c = gl_search(LRELN_INST(i)->whens, |
847 |
(char *)when,(CmpFunc)CmpWhens); |
848 |
if (c>0) gl_delete(LRELN_INST(i)->whens,c,0); |
849 |
break; |
850 |
case WHEN_INST: |
851 |
if (W_INST(i)->whens==NULL) return; |
852 |
c = gl_search(W_INST(i)->whens, |
853 |
(char *)when,(CmpFunc)CmpWhens); |
854 |
if (c>0) gl_delete(W_INST(i)->whens,c,0); |
855 |
break; |
856 |
default: |
857 |
PANIC_INCORRECT_TYPE(i); |
858 |
} |
859 |
} |
860 |
|
861 |
|