/[ascend]/trunk/ascend/compiler/linkinst.c
ViewVC logotype

Contents of /trunk/ascend/compiler/linkinst.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2689 - (show annotations) (download) (as text)
Mon Mar 4 11:28:19 2013 UTC (9 years, 4 months ago) by jpye
File MIME type: text/x-csrc
File size: 16941 byte(s)
Fixes bug 567, for the moment. More tests surely required.
1 /* ASCEND modelling environment
2 Copyright (C) 2006 Carnegie Mellon University
3 Copyright (C) 1996 Ben Allan
4 Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *//*
19 @file
20 Ascend Instance Tree Link Management
21 *//*
22 based in instance.c by Tom Epperly
23 9/3/89
24 Last in CVS: $Revision: 1.13 $ $Date: 1998/02/05 16:36:59 $ $Author: ballan $
25 */
26
27 #include <stdarg.h>
28 #include <ascend/general/platform.h>
29 #include <ascend/general/panic.h>
30 #include <ascend/general/ascMalloc.h>
31 #include <ascend/general/list.h>
32 #include <ascend/general/dstring.h>
33
34 #include "symtab.h"
35 #include "functype.h"
36 #include "expr_types.h"
37 #include "instance_name.h"
38 #include "instance_io.h"
39 #include "check.h"
40 #include "dump.h"
41 #include "child.h"
42 #include "type_desc.h"
43 #include "prototype.h"
44 #include "pending.h"
45 #include "find.h"
46 #include "rel_blackbox.h"
47 #include "vlist.h"
48 #include "relation.h"
49 #include "logical_relation.h"
50 #include "logrelation.h"
51 #include "relation_util.h"
52 #include "logrel_util.h"
53 #include "rel_common.h"
54 #include "case.h"
55 #include "when_util.h"
56 #include "universal.h"
57 #include <ascend/general/pool.h>
58 #include "instance_types.h"
59 /* new */
60 #include "atomsize.h"
61 #include "atomvalue.h"
62 #include "cmpfunc.h"
63 #include "destroyinst.h"
64 #include "instmacro.h"
65 #include "instquery.h"
66 #include "linkinst.h"
67 #include "mathinst.h"
68 #include "parentchild.h"
69
70 #define PANIC_ILLEGAL_INSTANCE Asc_Panic(2, __FUNCTION__, "invalid instance type")
71
72 /** this gets used in interactive merge/refinement and destruction. */
73 void ChangeRelationPointers(struct Instance *rel, struct Instance *old,
74 struct Instance *new
75 ){
76 //if(NULL==new)CONSOLE_DEBUG("Want to remove reference to var %p in relation %p",old,rel);
77 assert(rel!=NULL);
78 assert(rel->t==REL_INST);
79 AssertMemory(rel);
80 if (RELN_INST(rel)->ptr!=NULL) {
81 /* FIXME: ChangeRelationPointers needs verification. all rel types have the rel->varlist that needs repair, then each rel type has specifics to fix up. */
82 switch (RELN_INST(rel)->type) {
83 case e_token:
84 ModifyTokenRelationPointers(rel,RELN_INST(rel)->ptr,old,new);
85 return;
86 case e_glassbox:
87 ModifyGlassBoxRelPointers(rel,RELN_INST(rel)->ptr,old,new);
88 return;
89 case e_blackbox:
90 ModifyBlackBoxRelPointers(rel,RELN_INST(rel)->ptr,old,new);
91 return;
92 case e_undefined:
93 default:
94 PANIC_ILLEGAL_INSTANCE;
95 }
96 }
97 }
98
99 void ChangeLogRelPointers(struct Instance *lrel, struct Instance *old,
100 struct Instance *new
101 ){
102 struct gl_list_t *varlist,*rellist;
103 struct Instance *inst;
104 struct logrelation *logrel;
105
106 logrel = LRELN_INST(lrel)->ptr;
107 varlist = logrel->bvars;
108 rellist = logrel->satrels;
109
110 if (new == NULL) {
111 inst = old;
112 }
113 else {
114 inst = new;
115 }
116 assert(lrel->t==LREL_INST);
117 AssertMemory(lrel);
118 switch(inst->t){
119 case BOOLEAN_ATOM_INST:
120 if (logrel!=NULL){
121 ModifyLogRelPointers(varlist,logrel,old,new);
122 return;
123 }
124 break;
125 case REL_INST:
126 case LREL_INST:
127 if (logrel!=NULL){
128 ModifyLogRelPointers(rellist,logrel,old,new);
129 return;
130 }
131 break;
132 default:
133 PANIC_ILLEGAL_INSTANCE;
134 }
135 }
136
137 void ChangeWhenPointers(struct Instance *when, struct Instance *old,
138 struct Instance *new
139 ){
140 struct gl_list_t *varlist,*caselist,*reflist;
141 struct Instance *scratch;
142 struct Case *cur_case;
143 unsigned long c,len,pos;
144
145 varlist = W_INST(when)->bvar;
146 caselist = W_INST(when)->cases;
147 len = gl_length(caselist);
148
149 if (new == NULL) {
150 scratch = old;
151 }
152 else {
153 scratch = new;
154 }
155 assert(when->t==WHEN_INST);
156 AssertMemory(when);
157 switch(scratch->t){
158 case BOOLEAN_ATOM_INST:
159 case INTEGER_ATOM_INST:
160 case SYMBOL_ATOM_INST:
161 case BOOLEAN_CONSTANT_INST:
162 case INTEGER_CONSTANT_INST:
163 case SYMBOL_CONSTANT_INST:
164 if (varlist!=NULL){
165 ModifyWhenPointers(varlist,old,new);
166 return;
167 }
168 case MODEL_INST:
169 case WHEN_INST:
170 case REL_INST:
171 case LREL_INST:
172 for(c=1;c<=len;c++) {
173 cur_case = (struct Case *)gl_fetch(caselist,c);
174 reflist = GetCaseReferences(cur_case);
175 if (reflist != NULL) {
176 if (0 != (pos = gl_search(reflist,old,(CmpFunc)CmpP)))
177 ModifyWhenPointers(reflist,old,new);
178 }
179 }
180 return;
181 default:
182 PANIC_ILLEGAL_INSTANCE;
183 }
184 }
185
186 /**
187 Tell parent to change pointers to oldchild to pointers to newchild.
188 */
189 void ChangeParent(struct Instance *parent, struct Instance *oldchild,
190 struct Instance *newchild
191 ){
192 register unsigned long c,length;
193 AssertMemory(parent);
194 length = NumberChildren(parent);
195 for(c=1;c<=length;c++){
196 if (InstanceChild(parent,c)==oldchild) {
197 StoreChildPtr(parent,c,newchild);
198 }
199 }
200 }
201
202 void ReDirectParents(struct Instance *old, struct Instance *new){
203 register struct Instance *parent;
204 register unsigned long index1,length;
205 length = NumberParents(new);
206 for(index1=1;index1<=length;index1++) {
207 parent = InstanceParent(new,index1);
208 ChangeParent(parent,old,new);
209 }
210 }
211
212 void ReDirectChildren(struct Instance *old, struct Instance *new){
213 register struct Instance *child;
214 register unsigned long c,length,pos;
215 length = NumberChildren(new);
216 for(c=1;c<=length;c++){
217 if ((child = InstanceChild(new,c))!=NULL){
218 if ((pos = SearchForParent(child,old))!=0){
219 DeleteParent(child,pos);
220 AddParent(child,new);
221 }
222 }
223 }
224 }
225
226
227 void ReorderChildrenPtrs(register struct Instance **c,
228 register CONST ChildListPtr old, register CONST ChildListPtr new,
229 register unsigned long int olen, register unsigned long int nlen
230 ){
231 register unsigned nzero;
232 if (olen==0) return;
233 nzero = nlen-olen;
234 while (nlen > 0) {
235 if (ChildStrPtr(new,nlen) == ChildStrPtr(old,olen)) {
236 /* move pointer at olen-1 to nlen-1 and put NULL in olen-1 */
237 c[--nlen] = c[--olen];
238 c[olen] = NULL;
239 if (olen==0)return;
240 } else {
241 nlen--;
242 if (--nzero==0) return;
243 }
244 }
245 }
246
247 /**
248 Remove old from the clique put new in its place.
249 */
250 void FixCliques(struct Instance *old, struct Instance *new){
251 register struct Instance *ptr,*next;
252 ptr = new;
253 /* SetNextCliqueMember(ptr,NextCliqueMember(old)); not needed */
254 while((next=NextCliqueMember(ptr))!=old)
255 ptr = next;
256 SetNextCliqueMember(ptr,new);
257 /* SetNextCliqueMember(old,old); illegal since old is no longer allocated */
258 }
259
260
261 /* this is called to tell relations about a change in variable location
262 * e.g. If two atoms are merged, point all the relations that know about
263 * ATOM old to ATOM new.
264 */
265 void FixRelations(struct RealAtomInstance *old, struct RealAtomInstance *new)
266 {
267 register unsigned long c,len;
268 AssertMemory(old);
269 AssertMemory(new);
270 if ((new->relations==NULL)||(new->relations==old->relations)){
271 /* new had no relations or new has the identical relation list */
272 new->relations = old->relations;
273 if ((len=RelationsCount(INST(new)))>0){
274 for(c=1;c<=len;c++) {
275 ChangeRelationPointers(RelationsForAtom(INST(new),c),
276 INST(old),INST(new));
277 }
278 }
279 } else {
280 len=RelationsCount(INST(old));
281 if (len>0) {
282 for(c=1;c<=len;c++){
283 ChangeRelationPointers(RelationsForAtom(INST(old),c),
284 INST(old),INST(new));
285 AddRelation(INST(new),RelationsForAtom(INST(old),c));
286 }
287 }
288 if (old->relations) {
289 gl_destroy(old->relations);
290 }
291 }
292 old->relations=NULL;
293 }
294
295
296 static
297 void FixLogRelationsIf(struct Instance *old, struct Instance *new){
298 register unsigned long c,len;
299 if ((len=LogRelationsCount(new))>0){
300 for(c=1;c<=len;c++) {
301 ChangeLogRelPointers(LogRelationsForInstance(new,c),old,new);
302 }
303 }
304 }
305
306 static
307 void FixLogRelationsElse(struct Instance *old, struct Instance *new){
308 register unsigned long c,len;
309 if ((len=LogRelationsCount(INST(old)))>0){
310 for(c=1;c<=len;c++){
311 ChangeLogRelPointers(LogRelationsForInstance(old,c),old,new);
312 AddLogRel(new,LogRelationsForInstance(old,c));
313 }
314 }
315 }
316
317
318 void FixLogRelations(struct Instance *old,
319 struct Instance *new
320 ){
321 switch(old->t){
322 case BOOLEAN_ATOM_INST:
323 AssertMemory(BA_INST(old));
324 AssertMemory(BA_INST(new));
325 if((BA_INST(new)->logrelations==NULL) ||
326 (BA_INST(new)->logrelations==BA_INST(old)->logrelations)) {
327 BA_INST(new)->logrelations = BA_INST(old)->logrelations;
328 FixLogRelationsIf(old,new);
329 }
330 else {
331 FixLogRelationsElse(old,new);
332 if (BA_INST(old)->logrelations) gl_destroy(BA_INST(old)->logrelations);
333 }
334 BA_INST(old)->logrelations=NULL;
335 break;
336 case REL_INST:
337 AssertMemory(RELN_INST(old));
338 AssertMemory(RELN_INST(new));
339 if((RELN_INST(new)->logrels==NULL) ||
340 (RELN_INST(new)->logrels==RELN_INST(old)->logrels)) {
341 RELN_INST(new)->logrels = RELN_INST(old)->logrels;
342 FixLogRelationsIf(old,new);
343 }
344 else {
345 FixLogRelationsElse(old,new);
346 if (RELN_INST(old)->logrels) gl_destroy(RELN_INST(old)->logrels);
347 }
348 RELN_INST(old)->logrels=NULL;
349 break;
350 case LREL_INST:
351 AssertMemory(LRELN_INST(old));
352 AssertMemory(LRELN_INST(new));
353 if((LRELN_INST(new)->logrels==NULL) ||
354 (LRELN_INST(new)->logrels==LRELN_INST(old)->logrels)) {
355 LRELN_INST(new)->logrels = LRELN_INST(old)->logrels;
356 FixLogRelationsIf(old,new);
357 }
358 else {
359 FixLogRelationsElse(old,new);
360 if (LRELN_INST(old)->logrels) gl_destroy(LRELN_INST(old)->logrels);
361 }
362 LRELN_INST(old)->logrels=NULL;
363 break;
364 default:
365 PANIC_ILLEGAL_INSTANCE;
366 }
367 }
368
369 static
370 void FixWhensIf(struct Instance *old, struct Instance *new){
371 register unsigned long c,len;
372 if ((len=WhensCount(new))>0){
373 for(c=1;c<=len;c++) {
374 ChangeWhenPointers(WhensForInstance(new,c),old,new);
375 }
376 }
377 }
378
379 static
380 void FixWhensElse(struct Instance *old, struct Instance *new){
381 register unsigned long c,len;
382 if ((len=WhensCount(INST(old)))>0){
383 for(c=1;c<=len;c++){
384 ChangeWhenPointers(WhensForInstance(old,c),old,new);
385 AddWhen(new,WhensForInstance(old,c));
386 }
387 }
388 }
389
390 void FixWhens(struct Instance *old, struct Instance *new){
391 switch(old->t){
392 case BOOLEAN_ATOM_INST:
393 AssertMemory(BA_INST(old));
394 AssertMemory(BA_INST(new));
395 if((BA_INST(new)->whens==NULL) ||
396 (BA_INST(new)->whens==BA_INST(old)->whens)) {
397 BA_INST(new)->whens = BA_INST(old)->whens;
398 FixWhensIf(old,new);
399 }
400 else{
401 FixWhensElse(old,new);
402 if (BA_INST(old)->whens) gl_destroy(BA_INST(old)->whens);
403 }
404 BA_INST(old)->whens=NULL;
405 break;
406 case INTEGER_ATOM_INST:
407 AssertMemory(IA_INST(old));
408 AssertMemory(IA_INST(new));
409 if((IA_INST(new)->whens==NULL) ||
410 (IA_INST(new)->whens==IA_INST(old)->whens)) {
411 IA_INST(new)->whens = IA_INST(old)->whens;
412 FixWhensIf(old,new);
413 }
414 else{
415 FixWhensElse(old,new);
416 if (IA_INST(old)->whens) gl_destroy(IA_INST(old)->whens);
417 }
418 IA_INST(old)->whens=NULL;
419 break;
420 case SYMBOL_ATOM_INST:
421 AssertMemory(SYMA_INST(old));
422 AssertMemory(SYMA_INST(new));
423 if((SYMA_INST(new)->whens==NULL) ||
424 (SYMA_INST(new)->whens==SYMA_INST(old)->whens)) {
425 SYMA_INST(new)->whens = SYMA_INST(old)->whens;
426 FixWhensIf(old,new);
427 }
428 else{
429 FixWhensElse(old,new);
430 if (SYMA_INST(old)->whens) gl_destroy(SYMA_INST(old)->whens);
431 }
432 SYMA_INST(old)->whens=NULL;
433 break;
434 case BOOLEAN_CONSTANT_INST:
435 AssertMemory(BC_INST(old));
436 AssertMemory(BC_INST(new));
437 if((BC_INST(new)->whens==NULL) ||
438 (BC_INST(new)->whens==BC_INST(old)->whens)) {
439 BC_INST(new)->whens = BC_INST(old)->whens;
440 FixWhensIf(old,new);
441 }
442 else{
443 FixWhensElse(old,new);
444 if (BC_INST(old)->whens) gl_destroy(BC_INST(old)->whens);
445 }
446 BC_INST(old)->whens=NULL;
447 break;
448 case INTEGER_CONSTANT_INST:
449 AssertMemory(IC_INST(old));
450 AssertMemory(IC_INST(new));
451 if((IC_INST(new)->whens==NULL) ||
452 (IC_INST(new)->whens==IC_INST(old)->whens)) {
453 IC_INST(new)->whens = IC_INST(old)->whens;
454 FixWhensIf(old,new);
455 }
456 else{
457 FixWhensElse(old,new);
458 if (IC_INST(old)->whens) gl_destroy(IC_INST(old)->whens);
459 }
460 IC_INST(old)->whens=NULL;
461 break;
462 case SYMBOL_CONSTANT_INST:
463 AssertMemory(SYMC_INST(old));
464 AssertMemory(SYMC_INST(new));
465 if((SYMC_INST(new)->whens==NULL) ||
466 (SYMC_INST(new)->whens==SYMC_INST(old)->whens)) {
467 SYMC_INST(new)->whens = SYMC_INST(old)->whens;
468 FixWhensIf(old,new);
469 }
470 else{
471 FixWhensElse(old,new);
472 if (SYMC_INST(old)->whens) gl_destroy(SYMC_INST(old)->whens);
473 }
474 SYMC_INST(old)->whens=NULL;
475 break;
476 case MODEL_INST:
477 AssertMemory(MOD_INST(old));
478 AssertMemory(MOD_INST(new));
479 if((MOD_INST(new)->whens==NULL) ||
480 (MOD_INST(new)->whens==MOD_INST(old)->whens)) {
481 MOD_INST(new)->whens = MOD_INST(old)->whens;
482 FixWhensIf(old,new);
483 }
484 else{
485 FixWhensElse(old,new);
486 if (MOD_INST(old)->whens) gl_destroy(MOD_INST(old)->whens);
487 }
488 MOD_INST(old)->whens=NULL;
489 break;
490 case REL_INST:
491 AssertMemory(RELN_INST(old));
492 AssertMemory(RELN_INST(new));
493 if((RELN_INST(new)->whens==NULL) ||
494 (RELN_INST(new)->whens==RELN_INST(old)->whens)) {
495 RELN_INST(new)->whens = RELN_INST(old)->whens;
496 FixWhensIf(old,new);
497 }
498 else{
499 FixWhensElse(old,new);
500 if (RELN_INST(old)->whens) gl_destroy(RELN_INST(old)->whens);
501 }
502 RELN_INST(old)->whens=NULL;
503 break;
504 case LREL_INST:
505 AssertMemory(LRELN_INST(old));
506 AssertMemory(LRELN_INST(new));
507 if((LRELN_INST(new)->whens==NULL) ||
508 (LRELN_INST(new)->whens==LRELN_INST(old)->whens)) {
509 LRELN_INST(new)->whens = LRELN_INST(old)->whens;
510 FixWhensIf(old,new);
511 }
512 else{
513 FixWhensElse(old,new);
514 if (LRELN_INST(old)->whens) gl_destroy(LRELN_INST(old)->whens);
515 }
516 LRELN_INST(old)->whens=NULL;
517 break;
518 case WHEN_INST:
519 AssertMemory(W_INST(old));
520 AssertMemory(W_INST(new));
521 if((W_INST(new)->whens==NULL) ||
522 (W_INST(new)->whens==W_INST(old)->whens)) {
523 W_INST(new)->whens = W_INST(old)->whens;
524 FixWhensIf(old,new);
525 }
526 else{
527 FixWhensElse(old,new);
528 if (W_INST(old)->whens) gl_destroy(W_INST(old)->whens);
529 }
530 W_INST(old)->whens=NULL;
531 break;
532 default:
533 PANIC_ILLEGAL_INSTANCE;
534 }
535 }
536
537
538 void FixWhensForRefinement(struct Instance *old, struct Instance *new){
539 switch(new->t){
540 case BOOLEAN_ATOM_INST:
541 AssertMemory(BA_INST(new));
542 if(BA_INST(new)->whens!=NULL) {
543 FixWhensIf(old,new);
544 }
545 break;
546 case INTEGER_ATOM_INST:
547 AssertMemory(IA_INST(new));
548 if(IA_INST(new)->whens!=NULL) {
549 FixWhensIf(old,new);
550 }
551 break;
552 case SYMBOL_ATOM_INST:
553 AssertMemory(SYMA_INST(new));
554 if(SYMA_INST(new)->whens!=NULL) {
555 FixWhensIf(old,new);
556 }
557 break;
558 case BOOLEAN_CONSTANT_INST:
559 AssertMemory(BC_INST(new));
560 if(BC_INST(new)->whens!=NULL) {
561 FixWhensIf(old,new);
562 }
563 break;
564 case INTEGER_CONSTANT_INST:
565 AssertMemory(IC_INST(new));
566 if(IC_INST(new)->whens!=NULL) {
567 FixWhensIf(old,new);
568 }
569 break;
570 case SYMBOL_CONSTANT_INST:
571 AssertMemory(SYMC_INST(new));
572 if(SYMC_INST(new)->whens!=NULL) {
573 FixWhensIf(old,new);
574 }
575 break;
576 case MODEL_INST:
577 AssertMemory(MOD_INST(new));
578 if(MOD_INST(new)->whens!=NULL) {
579 FixWhensIf(old,new);
580 }
581 break;
582 case REL_INST:
583 AssertMemory(RELN_INST(new));
584 if(RELN_INST(new)->whens!=NULL) {
585 FixWhensIf(old,new);
586 }
587 break;
588 case LREL_INST:
589 AssertMemory(LRELN_INST(new));
590 if(LRELN_INST(new)->whens!=NULL) {
591 FixWhensIf(old,new);
592 }
593 break;
594 case WHEN_INST:
595 AssertMemory(W_INST(new));
596 if(W_INST(new)->whens!=NULL) {
597 FixWhensIf(old,new);
598 }
599 break;
600 default:
601 PANIC_ILLEGAL_INSTANCE;
602 }
603 }
604

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