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