/[ascend]/trunk/base/generic/compiler/mergeinst.c
ViewVC logotype

Contents of /trunk/base/generic/compiler/mergeinst.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 89 - (show annotations) (download) (as text)
Wed Dec 7 15:44:43 2005 UTC (14 years, 2 months ago) by johnpye
File MIME type: text/x-csrc
File size: 35864 byte(s)
Small changes to eliminate GCC warnings
1 /*
2 * Ascend Instance Merge Implementation
3 * by Tom Epperly
4 * 9/3/89
5 * Version: $Revision: 1.16 $
6 * Version control file: $RCSfile: mergeinst.c,v $
7 * Date last modified: $Date: 1998/03/17 22:09:08 $
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/ascPanic.h"
33 #include "utilities/ascMalloc.h"
34 #include "general/list.h"
35 #include "general/dstring.h"
36 #include "compiler/compiler.h"
37 #include "compiler/bit.h"
38 #include "compiler/symtab.h"
39 #include "compiler/fractions.h"
40 #include "compiler/dimen.h"
41 #include "compiler/functype.h"
42 #include "compiler/types.h"
43 #include "compiler/child.h"
44 #include "compiler/childinfo.h"
45 #include "compiler/type_desc.h"
46 #include "compiler/instance_enum.h"
47 #include "compiler/instance_name.h"
48 #include "compiler/instance_io.h"
49 #include "compiler/instmacro.h"
50 #include "compiler/visitinst.h"
51 #include "compiler/extinst.h"
52 #include "compiler/parentchild.h"
53 #include "compiler/instance_types.h"
54 #include "compiler/instquery.h"
55 #include "compiler/linkinst.h"
56 #include "compiler/destroyinst.h"
57 #include "compiler/createinst.h"
58 #include "compiler/refineinst.h"
59 #include "compiler/atomvalue.h"
60 #include "compiler/atomsize.h"
61 #include "compiler/check.h"
62 #include "compiler/dump.h"
63 #include "compiler/prototype.h"
64 #include "compiler/pending.h"
65 #include "compiler/find.h"
66 #include "compiler/relation_type.h"
67 #include "compiler/relation.h"
68 #include "compiler/logical_relation.h"
69 #include "compiler/logrelation.h"
70 #include "compiler/relation_util.h"
71 #include "compiler/logrel_util.h"
72 #include "compiler/rel_common.h"
73 #include "compiler/case.h"
74 #include "compiler/when_util.h"
75 #include "compiler/universal.h"
76 #include "compiler/cmpfunc.h"
77 #include "general/pool.h"
78 #include "compiler/tmpnum.h"
79 #include "compiler/setinstval.h"
80 #include "compiler/mergeinst.h"
81
82 #ifndef lint
83 static CONST char MergeInstModuleID[] = "$Id: mergeinst.c,v 1.16 1998/03/17 22:09:08 ballan Exp $";
84 #endif
85
86 /* forward declarations */
87 static
88 struct Instance *RecursiveMergeInstance(struct Instance *, struct Instance *);
89
90 /*
91 * Issue merge illegal message.
92 */
93 void BadMerge(FILE *fp, char *m1,
94 CONST struct Instance *i1, CONST struct Instance *i2, char *m2)
95 {
96 FPRINTF(fp,"%sInstance 1 IS_A %s (ptr=%p)\nInstance 2 IS_A %s (ptr=%p)\n%s",
97 m1, SCP(InstanceType(i1)), (void *)InstanceTypeDesc(i1),
98 SCP(InstanceType(i2)), (void *)InstanceTypeDesc(i2),m2);
99 }
100
101 /*
102 * Issue merge really illegal message.
103 */
104 void ReallyBadMerge(FILE *fp, char *m1,
105 CONST struct Instance *i1, CONST struct Instance *i2,
106 char *m2)
107 {
108 FPRINTF(fp, "%sInstance 1 IS_A %s(%d)\nInstance 2 IS_A %s(%d)\n%s",
109 m1, SCP(InstanceType(i1)), InstanceKind(i1),
110 SCP(InstanceType(i2)), InstanceKind(i2),m2);
111 }
112
113 /*
114 * this function tries to guess which of i1,i2 to keep, based on
115 * memory if d1,d2 ==, or on MoreRefined if d1,d2 !=.
116 * Returns 1 or 2 if one should be kept.
117 * Returns 0 if unconformable.
118 * This function needs to change to deal with parameterized
119 * types correctly, and then perhaps MergeInstances needs
120 * to be revisited. Basuckly, we need to have a function that
121 * returns EqualAsFarAsBuilt result about parametric i's being merged.
122 */
123 static
124 int KeepWhichInstance(struct TypeDescription *d1,
125 struct TypeDescription *d2,
126 struct Instance *i1, struct Instance *i2)
127 {
128 if (d1==d2){ /* heuristic based on memory usage */
129 #ifdef MEM_DECREASE
130 if (i1>i2) {
131 return 1;
132 } else {
133 return 2;
134 }
135 #else
136 if (i1<i2){
137 return 1;
138 } else {
139 return 2;
140 }
141 #endif
142 } else {
143 register struct TypeDescription *morerefined;
144 morerefined = MoreRefined(d1,d2);
145 if (morerefined==d1) return 1;
146 if (morerefined==d2) return 2;
147 assert(morerefined==NULL);
148 return 0;
149 }
150 }
151
152 static
153 int MergeValues(struct Instance *i1, struct Instance *i2)
154 /*********************************************************************\
155 Check to make sure the values of i1 and i2 are conformable. The
156 instance i1 will be set to the most refined value. Parts of i2 may
157 be cannibalized. Merging value on constants here has a clique side effect.
158 Returns 0 if happy, 1 or other if not.
159 \*********************************************************************/
160 {
161 register CONST dim_type *dim;
162 assert(i1&&i2&&i1->t==i2->t);
163 AssertMemory(i1);
164 AssertMemory(i2);
165 switch(i1->t){
166 case REAL_ATOM_INST:
167 dim = CheckDimensionsMatch(RA_INST(i1)->dimen,RA_INST(i2)->dimen);
168 if (dim==NULL) {
169 FPRINTF(ASCERR,"Dimensional mismatch.\n");
170 return 1;
171 }
172 RA_INST(i1)->dimen = dim;
173 if ((RA_INST(i1)->depth < RA_INST(i2)->depth)||
174 ((RA_INST(i1)->depth == RA_INST(i2)->depth)&&
175 (RA_INST(i1)->assigned < RA_INST(i2)->assigned))){
176 RA_INST(i1)->depth = RA_INST(i2)->depth;
177 RA_INST(i1)->assigned = RA_INST(i2)->assigned;
178 RA_INST(i1)->value = RA_INST(i2)->value;
179 }
180 return 0;
181 case REAL_CONSTANT_INST:
182 dim = CheckDimensionsMatch(RC_INST(i1)->dimen,RC_INST(i2)->dimen);
183 if (dim==NULL) {
184 FPRINTF(ASCERR,"Constant dimensional mismatch.\n");
185 return 1;
186 }
187 /* dimens compatible, but must check that values are before changing */
188 if ( CIASS(i1) && CIASS(i2) &&
189 (RC_INST(i1)->value != RC_INST(i2)->value) ) {
190 FPRINTF(ASCERR,"Real constant value mismatch.\n");
191 return 1;
192 }
193 /* now known compatible somehow */
194 if (!CIASS(i1) && CIASS(i2)) {
195 /* set i1val if needed */
196 SetRealAtomValue(INST(i1),RC_INST(i2)->value,0);
197 }
198 /* nonwild one, if such, goes. Note use of Set and not ->dimen. */
199 if (!IsWild(dim) && dim != RC_INST(i1)->dimen) {
200 SetRealAtomDims(INST(i1),dim); /* nonwild i2 dim -> i1 */
201 }
202 return 0;
203 case BOOLEAN_ATOM_INST:
204 if ((BA_INST(i1)->depth < BA_INST(i2)->depth)||
205 ((BA_INST(i1)->depth == BA_INST(i2)->depth)&&
206 (BA_INST(i1)->assigned < BA_INST(i2)->assigned))){
207 BA_INST(i1)->value = BA_INST(i2)->value;
208 BA_INST(i1)->assigned = BA_INST(i2)->assigned;
209 BA_INST(i1)->depth = BA_INST(i2)->depth;
210 }
211 return 0;
212 case BOOLEAN_CONSTANT_INST:
213 if ( CIASS(i1) && CIASS(i2) && (BCV(i1) != BCV(i2)) ) {
214 FPRINTF(ASCERR,"Boolean constant value mismatch.\n");
215 return 1;
216 } /* else compatible */
217 if (!CIASS(i1) && CIASS(i2)) {
218 SetBooleanAtomValue(INST(i1),BCV(i2),0);
219 }
220 return 0;
221 case INTEGER_ATOM_INST:
222 if ((IA_INST(i1)->depth < IA_INST(i2)->depth)||
223 ((IA_INST(i1)->depth == IA_INST(i2)->depth)&&
224 (IA_INST(i1)->assigned < IA_INST(i2)->assigned))){
225 IA_INST(i1)->value = IA_INST(i2)->value;
226 IA_INST(i1)->assigned = IA_INST(i2)->assigned;
227 IA_INST(i1)->depth = IA_INST(i2)->depth;
228 }
229 return 0;
230 case INTEGER_CONSTANT_INST:
231 if (CIASS(i1) && CIASS(i2)
232 && IC_INST(i1)->value != IC_INST(i2)->value ){
233 FPRINTF(ASCERR,"Integer constant value mismatch.\n");
234 return 1;
235 } /* else compatible */
236 if (!CIASS(i1) && CIASS(i2)) {
237 SetIntegerAtomValue(INST(i1),IC_INST(i2)->value,0);
238 }
239 return 0;
240 case SET_ATOM_INST:
241 if (SA_INST(i2)->list!=NULL){
242 if (SA_INST(i1)->list!=NULL){
243 if (SetsEqual(SA_INST(i1)->list,SA_INST(i2)->list)){
244 /* heuristic to save the one with the lower address */
245 #ifdef MEM_DECREASE
246 if (SA_INST(i2)->list > SA_INST(i1)->list){
247 register struct set_t *temp;
248 temp = SA_INST(i2)->list;
249 SA_INST(i2)->list = SA_INST(i1)->list;
250 SA_INST(i1)->list = temp;
251 }
252 #else
253 if (SA_INST(i2)->list < SA_INST(i1)->list){
254 register struct set_t *temp;
255 temp = SA_INST(i2)->list;
256 SA_INST(i2)->list = SA_INST(i1)->list;
257 SA_INST(i1)->list = temp;
258 }
259 #endif
260 return 0;
261 } else {
262 FPRINTF(ASCERR,"Set value mismatch.\n ");
263 WriteInstanceName(ASCERR,i1,NULL);
264 FPRINTF(ASCERR," = \n ");
265 WriteAtomValue(ASCERR,i1);
266 FPRINTF(ASCERR,"\n ");
267 WriteInstanceName(ASCERR,i2,NULL);
268 FPRINTF(ASCERR," = \n ");
269 WriteAtomValue(ASCERR,i2);
270 FPRINTF(ASCERR,"\n");
271 return 1;
272 }
273 } else {
274 SA_INST(i1)->list = SA_INST(i2)->list;
275 SA_INST(i2)->list = NULL;
276 }
277 }
278 return 0;
279 case SYMBOL_ATOM_INST:
280 if (SYMA_INST(i2)->value!=NULL){
281 if (SYMA_INST(i1)->value!=NULL)
282 return (SYMA_INST(i1)->value != SYMA_INST(i2)->value);
283 else{
284 SYMA_INST(i1)->value = SYMA_INST(i2)->value;
285 }
286 }
287 return 0;
288 case SYMBOL_CONSTANT_INST:
289 if (SYMC_INST(i2)->value!=NULL){
290 if (SYMC_INST(i1)->value!=NULL) {
291 return ( SYMC_INST(i1)->value != SYMC_INST(i2)->value);
292 } else{
293 SetSymbolAtomValue(INST(i1),SYMC_INST(i2)->value);
294 }
295 }
296 return 0;
297 case REAL_INST:
298 dim = CheckDimensionsMatch(R_INST(i1)->dimen,R_INST(i2)->dimen);
299 if (dim==NULL) {
300 FPRINTF(ASCERR,"Dimensional mismatch.\n");
301 return 1;
302 }
303 R_INST(i1)->dimen = dim;
304 if ((R_INST(i1)->depth < R_INST(i2)->depth)||
305 ((R_INST(i1)->depth == R_INST(i2)->depth)&&
306 (R_INST(i1)->assigned < R_INST(i2)->assigned))){
307 R_INST(i1)->depth = R_INST(i2)->depth;
308 R_INST(i1)->assigned = R_INST(i2)->assigned;
309 R_INST(i1)->value = R_INST(i2)->value;
310 }
311 return 0;
312 case INTEGER_INST:
313 if ((I_INST(i1)->depth < I_INST(i2)->depth)||
314 ((I_INST(i1)->depth == I_INST(i2)->depth)&&
315 (I_INST(i1)->assigned < I_INST(i2)->assigned))){
316 I_INST(i1)->value = I_INST(i2)->value;
317 I_INST(i1)->assigned = I_INST(i2)->assigned;
318 I_INST(i1)->depth = I_INST(i2)->depth;
319 }
320 return 0;
321 case BOOLEAN_INST:
322 if ((B_INST(i1)->depth < B_INST(i2)->depth)||
323 ((B_INST(i1)->depth == B_INST(i2)->depth)&&
324 (B_INST(i1)->assigned < B_INST(i2)->assigned))){
325 B_INST(i1)->value = B_INST(i2)->value;
326 B_INST(i1)->assigned = B_INST(i2)->assigned;
327 B_INST(i1)->depth = B_INST(i2)->depth;
328 }
329 return 0;
330 case SET_INST:
331 if (S_INST(i2)->list!=NULL){
332 if (S_INST(i1)->list!=NULL){
333 if (SetsEqual(S_INST(i1)->list,S_INST(i2)->list)){
334 /* heuristic to save the one with the lower address */
335 #ifdef MEM_DECREASE
336 if (S_INST(i2)->list > S_INST(i1)->list){
337 register struct set_t *temp;
338 temp = S_INST(i2)->list;
339 S_INST(i2)->list = S_INST(i1)->list;
340 S_INST(i1)->list = temp;
341 }
342 #else
343 if (S_INST(i2)->list < S_INST(i1)->list){
344 register struct set_t *temp;
345 temp = S_INST(i2)->list;
346 S_INST(i2)->list = S_INST(i1)->list;
347 S_INST(i1)->list = temp;
348 }
349 #endif
350 return 0;
351 }
352 else return 1;
353 }
354 else{
355 S_INST(i1)->list = S_INST(i2)->list;
356 S_INST(i2)->list = NULL;
357 }
358 }
359 return 0;
360 case SYMBOL_INST:
361 if (SYM_INST(i2)->value!=NULL){
362 if (SYM_INST(i1)->value!=NULL)
363 return (SYM_INST(i1)->value != SYM_INST(i2)->value);
364 else{
365 SYM_INST(i1)->value = SYM_INST(i2)->value;
366 }
367 }
368 return 0;
369 default:
370 Asc_Panic(2, NULL, "Error in MergeValues in instance.c. Unknown type.\n");
371 exit(2);/* Needed to keep gcc from whining */
372 }
373 }
374
375 /* called on only things w/ atom children */
376 static
377 void MergeCommonChildren(struct Instance **i1,
378 struct Instance **i2,
379 unsigned long int num)
380 {
381 while (num--){
382 (void)MergeValues(*(i1++),*(i2++));
383 }
384 }
385
386 /* also called only on things with atom children */
387 static
388 void MergeUncommonChildren(struct Instance *i1, struct Instance *i2)
389 /*********************************************************************\
390 This procedure assumes that i1 is more refined that i2 and that i1
391 has more children that i2.
392 \*********************************************************************/
393 {
394 unsigned long c,len;
395 struct InstanceName name;
396 struct Instance *child1,*child2;
397 len = NumberChildren(i2);
398 for(c=1;c<=len;c++){
399 child2 = InstanceChild(i2,c);
400 name = ChildName(i2,c);
401 child1 = InstanceChild(i1,ChildSearch(i1,&name));
402 (void)MergeValues(child1,child2);
403 }
404 }
405
406 /* merge ATOM children */
407 static
408 void MergeChildrenValues(struct Instance *i1, struct Instance *i2)
409 /*********************************************************************\
410 This procedure will merge the values of the children of atoms i1 and
411 i2. It is assumed that i1 is conformable with i2 and that i1 is
412 as refined or more refined that i2.
413 \*********************************************************************/
414 {
415 assert(i1&&i2&&InstanceKind(i1)==InstanceKind(i2));
416 if (NumberChildren(i1)==NumberChildren(i2)){
417 switch(InstanceKind(i1)) {
418 case REL_INST:
419 MergeCommonChildren(REL_CHILD(i1,0),REL_CHILD(i2,0),NumberChildren(i1));
420 break;
421 case LREL_INST:
422 MergeCommonChildren(LREL_CHILD(i1,0),LREL_CHILD(i2,0),
423 NumberChildren(i1));
424 break;
425 case REAL_ATOM_INST:
426 MergeCommonChildren(RA_CHILD(i1,0),RA_CHILD(i2,0),NumberChildren(i1));
427 break;
428 case BOOLEAN_ATOM_INST:
429 MergeCommonChildren(BA_CHILD(i1,0),BA_CHILD(i2,0),NumberChildren(i1));
430 break;
431 case INTEGER_ATOM_INST:
432 MergeCommonChildren(IA_CHILD(i1,0),IA_CHILD(i2,0),NumberChildren(i1));
433 break;
434 case SET_ATOM_INST:
435 MergeCommonChildren(SA_CHILD(i1,0),SA_CHILD(i2,0),NumberChildren(i1));
436 break;
437 case SYMBOL_ATOM_INST:
438 MergeCommonChildren(SYMA_CHILD(i1,0),SYMA_CHILD(i2,0),
439 NumberChildren(i1));
440 break;
441 default:
442 Asc_Panic(2, NULL, "Wrong type passed to MergeChildrenValues.\n");
443 }
444 } else {
445 MergeUncommonChildren(i1,i2);
446 }
447 }
448
449 /* this innocent little thing is killing us. */
450 static
451 void MergeParentLists(struct gl_list_t *l1,
452 struct gl_list_t *l2,
453 struct Instance *old,
454 struct Instance *new)
455 {
456 register unsigned long c,len;
457 register struct Instance *parent;
458 len = gl_length(l2);
459 for(c=1;c<=len;c++){
460 parent = INST(gl_fetch(l2,c));
461 if (gl_search(l1,(char *)parent,(CmpFunc)CmpParents)==0)
462 gl_insert_sorted(l1,(char *)parent,(CmpFunc)CmpParents);
463 ChangeParent(parent,old,new);
464 }
465 gl_destroy(l2);
466 }
467
468 static
469 void MergeParents(struct Instance *i1, struct Instance *i2)
470 {
471 /*
472 * Change i2's parents to i1's parents.
473 */
474 assert(i1&&i2&&InstanceKind(i1)==InstanceKind(i2));
475 switch(InstanceKind(i1)) {
476 case MODEL_INST:
477 MergeParentLists(MOD_INST(i1)->parents,MOD_INST(i2)->parents,i2,i1);
478 MOD_INST(i2)->parents = gl_create(0L);
479 break;
480 case REAL_ATOM_INST:
481 MergeParentLists(RA_INST(i1)->parents,RA_INST(i2)->parents,i2,i1);
482 RA_INST(i2)->parents = gl_create(0L);
483 break;
484 case BOOLEAN_ATOM_INST:
485 MergeParentLists(BA_INST(i1)->parents,BA_INST(i2)->parents,i2,i1);
486 BA_INST(i2)->parents = gl_create(0L);
487 break;
488 case INTEGER_ATOM_INST:
489 MergeParentLists(IA_INST(i1)->parents,IA_INST(i2)->parents,i2,i1);
490 IA_INST(i2)->parents = gl_create(0L);
491 break;
492 case SET_ATOM_INST:
493 MergeParentLists(SA_INST(i1)->parents,SA_INST(i2)->parents,i2,i1);
494 SA_INST(i2)->parents = gl_create(0L);
495 break;
496 case SYMBOL_ATOM_INST:
497 MergeParentLists(SYMA_INST(i1)->parents,SYMA_INST(i2)->parents,i2,i1);
498 SYMA_INST(i2)->parents = gl_create(0L);
499 break;
500 case REAL_CONSTANT_INST:
501 MergeParentLists(RC_INST(i1)->parents,RC_INST(i2)->parents,i2,i1);
502 RC_INST(i2)->parents = gl_create(0L);
503 break;
504 case BOOLEAN_CONSTANT_INST:
505 MergeParentLists(BC_INST(i1)->parents,BC_INST(i2)->parents,i2,i1);
506 BC_INST(i2)->parents = gl_create(0L);
507 break;
508 case INTEGER_CONSTANT_INST:
509 MergeParentLists(IC_INST(i1)->parents,IC_INST(i2)->parents,i2,i1);
510 IC_INST(i2)->parents = gl_create(0L);
511 break;
512 case SYMBOL_CONSTANT_INST:
513 MergeParentLists(SYMC_INST(i1)->parents,SYMC_INST(i2)->parents,i2,i1);
514 SYMC_INST(i2)->parents = gl_create(0L);
515 break;
516 case REL_INST:
517 assert((NumberParents(i1)==1)&&(NumberParents(i2)==1));
518 ChangeParent(RELN_INST(i2)->parent[0],i2,i1);
519 AddParent(i1,RELN_INST(i2)->parent[0]);
520 RELN_INST(i2)->parent[0] = NULL;
521 break;
522 case LREL_INST:
523 assert((NumberParents(i1)==1)&&(NumberParents(i2)==1));
524 ChangeParent(LRELN_INST(i2)->parent[0],i2,i1);
525 AddParent(i1,LRELN_INST(i2)->parent[0]);
526 LRELN_INST(i2)->parent[0] = NULL;
527 break;
528 case WHEN_INST:
529 assert((NumberParents(i1)==1)&&(NumberParents(i2)==1));
530 ChangeParent(W_INST(i2)->parent[0],i2,i1);
531 AddParent(i1,W_INST(i2)->parent[0]);
532 W_INST(i2)->parent[0] = NULL;
533 break;
534 case ARRAY_INT_INST:
535 case ARRAY_ENUM_INST:
536 MergeParentLists(ARY_INST(i1)->parents,ARY_INST(i2)->parents,i2,i1);
537 ARY_INST(i2)->parents = gl_create(0L);
538 break;
539 case REAL_INST:
540 case INTEGER_INST:
541 case BOOLEAN_INST:
542 case SET_INST:
543 case SYMBOL_INST:
544 case DUMMY_INST:
545 Asc_Panic(2, NULL, "Shouldn't be called on fundamental/dummy type.\n");
546 default:
547 Asc_Panic(2, NULL, "Unknown instance type passed to MergeParents.\n");
548 }
549 }
550
551 static
552 int InClique(struct Instance *i1, struct Instance *i2)
553 {
554 register struct Instance *ptr;
555 ptr = i1;
556 do{
557 if (ptr==i2) return 1;
558 ptr = NextCliqueMember(ptr);
559 } while(ptr!=i1);
560 return 0;
561 }
562
563 /* wire together cliques, but does not mess with refinements */
564 void MergeCliques(struct Instance *i1, struct Instance *i2)
565 {
566 register struct Instance *tmp;
567 if (!InClique(i1,i2)){
568 tmp = NextCliqueMember(i1);
569 SetNextCliqueMember(i1,NextCliqueMember(i2));
570 SetNextCliqueMember(i2,tmp);
571 }
572 }
573
574 static
575 struct Instance *MergeConstants(struct Instance *i1, struct Instance *i2)
576 {
577 struct TypeDescription *desc;
578 switch(KeepWhichInstance(InstanceTypeDesc(i1),
579 InstanceTypeDesc(i2),
580 INST(i1),INST(i2))){
581 case 1: /* keep instance 1 */
582 if (MergeValues(i1,i2)) return NULL; /* check instance values */
583 /* no interface pointers, no children */
584 MergeParents(i1,i2);
585 MergeCliques(i1,i2);
586 if((i2->t==BOOLEAN_CONSTANT_INST)||(i2->t==INTEGER_CONSTANT_INST)||
587 (i2->t==SYMBOL_CONSTANT_INST)) {
588 FixWhens(i2,i1);
589 }
590 desc = InstanceTypeDesc(i2);
591 if (GetUniversalFlag(desc)) {
592 ChangeUniversalInstance(GetUniversalTable(),INST(i2),INST(i1));
593 }
594 DestroyInstance(i2,NULL);
595 return i1;
596 case 2: /* keep instance 2 */
597 if (MergeValues(i2,i1)) return NULL; /* check instance values */
598 MergeParents(i2,i1);
599 MergeCliques(i2,i1);
600 if((i1->t==BOOLEAN_CONSTANT_INST)||
601 (i1->t==INTEGER_CONSTANT_INST)||
602 (i1->t==SYMBOL_CONSTANT_INST)) {
603 FixWhens(i1,i2);
604 }
605 desc = InstanceTypeDesc(i1);
606 if (GetUniversalFlag(desc)) {
607 ChangeUniversalInstance(GetUniversalTable(),INST(i1),INST(i2));
608 }
609 DestroyInstance(i1,NULL);
610 return i2;
611 default: /* unconformable types or something wrong */
612 assert(MoreRefined(InstanceTypeDesc(i1),InstanceTypeDesc(i2))==NULL);
613 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of constants.\n",
614 INST(i1), INST(i2),"");
615 DifferentVersionCheck(InstanceTypeDesc(i1),InstanceTypeDesc(i2));
616 return NULL;
617 }
618 }
619
620 static
621 struct Instance *MergeAtoms(struct Instance *i1, struct Instance *i2)
622 {
623 struct TypeDescription *desc;
624 switch(KeepWhichInstance(InstanceTypeDesc(i1),
625 InstanceTypeDesc(i2),
626 INST(i1),INST(i2))){
627 case 1: /* keep instance 1 */
628 if (MergeValues(i1,i2)) return NULL; /* check instance values */
629 if (InterfacePtrATS!=NULL)
630 (*InterfacePtrATS)(i1,i2);
631 MergeChildrenValues(i1,i2);
632 MergeParents(i1,i2);
633 MergeCliques(i1,i2);
634 switch (i2->t) {
635 case REAL_ATOM_INST:
636 FixRelations(RA_INST(i2),RA_INST(i1));
637 break;
638 case BOOLEAN_ATOM_INST:
639 FixLogRelations(i2,i1);
640 FixWhens(i2,i1);
641 break;
642 case INTEGER_ATOM_INST:
643 case SYMBOL_ATOM_INST:
644 FixWhens(i2,i1);
645 break;
646 default:
647 break;
648 }
649 desc = InstanceTypeDesc(i2);
650 if (GetUniversalFlag(desc)) {
651 ChangeUniversalInstance(GetUniversalTable(),INST(i2),INST(i1));
652 }
653 DestroyInstance(i2,NULL);
654 return i1;
655 case 2: /* keep instance 2 */
656 if (MergeValues(i2,i1)) return NULL; /* check instance values */
657 if (InterfacePtrATS!=NULL) {
658 (*InterfacePtrATS)(i2,i1);
659 }
660 MergeChildrenValues(i2,i1);
661 MergeParents(i2,i1);
662 MergeCliques(i2,i1);
663 switch (i1->t) {
664 case REAL_ATOM_INST:
665 FixRelations(RA_INST(i1),RA_INST(i2));
666 break;
667 case BOOLEAN_ATOM_INST:
668 FixLogRelations(i1,i2);
669 FixWhens(i1,i2);
670 break;
671 case INTEGER_ATOM_INST:
672 case SYMBOL_ATOM_INST:
673 FixWhens(i1,i2);
674 break;
675 default:
676 break;
677 }
678 desc = InstanceTypeDesc(i1);
679 if (GetUniversalFlag(desc)) {
680 ChangeUniversalInstance(GetUniversalTable(),INST(i1),INST(i2));
681 }
682 DestroyInstance(i1,NULL);
683 return i2;
684 default: /* unconformable types or something wrong */
685 assert(MoreRefined(InstanceTypeDesc(i1),InstanceTypeDesc(i2))==NULL);
686 BadMerge(ASCERR,"Unconformable ARE_THE_SAME.\n",
687 INST(i1), INST(i2),"");
688 DifferentVersionCheck(InstanceTypeDesc(i1),InstanceTypeDesc(i2));
689 return NULL;
690 }
691 }
692
693 static
694 void MergeModelValues(struct ModelInstance *i1, struct ModelInstance *i2)
695 {
696 /*
697 * assumes that i1 is more refined. Checks the bitlists.
698 */
699 register unsigned long c,len;
700 len = BLength(i2->executed);
701 for(c=0;c<len;c++)
702 if (!ReadBit(i2->executed,c)) ClearBit(i1->executed,c);
703 }
704
705 static
706 void RemoveParent(struct Instance *child, struct Instance *parent)
707 {
708 unsigned long pos;
709 if((pos = SearchForParent(child,parent))!=0)
710 DeleteParent(child,pos);
711 }
712
713 static
714 void MergeCommonModelChildren(struct Instance **i1,
715 struct Instance **i2,
716 unsigned long int num,
717 struct Instance *newparent,
718 struct Instance *oldparent)
719 {
720 while (num--){
721 if ((*i1 != NULL)&&(*i2 != NULL)){
722 (void)RecursiveMergeInstance(*i1,*i2);
723 }
724 else if (*i2 != NULL){
725 RemoveParent(*i2,oldparent);
726 if (SearchForParent(*i2,newparent)==0)
727 AddParent(*i2,newparent);
728 *i1 = *i2;
729 *i2 = NULL;
730 }
731 i1++;
732 i2++;
733 }
734 }
735
736 static
737 void MergeUncommonModelChildren(struct Instance *i1, struct Instance *i2)
738 {
739 unsigned long c,len,pos;
740 struct Instance *child1,*child2;
741 struct InstanceName name;
742 len = NumberChildren(i2);
743 for(c=1;c<=len;c++){
744 child2 = InstanceChild(i2,c);
745 name = ChildName(i2,c);
746 child1 = InstanceChild(i1,pos=ChildSearch(i1,&name));
747 if ((child1 != NULL)&&(child2 != NULL))
748 (void)RecursiveMergeInstance(child1,child2);
749 else if (child2 != NULL){
750 StoreChildPtr(i1,pos,child2);
751 StoreChildPtr(i2,c,NULL);
752 RemoveParent(child2,i2);
753 if (SearchForParent(child2,i1)==0) AddParent(child2,i1);
754 }
755 }
756 }
757
758 static
759 void MergeModelChildren(struct ModelInstance *i1, struct ModelInstance *i2)
760 {
761 /*
762 * assumes that i1 is more refined that i2.
763 */
764 if (NumberChildren(INST(i1))==NumberChildren(INST(i2))) {
765 MergeCommonModelChildren(MOD_CHILD(i1,0),MOD_CHILD(i2,0),
766 NumberChildren(INST(i1)),INST(i1),INST(i2));
767 } else {
768 MergeUncommonModelChildren(INST(i1),INST(i2));
769 }
770 }
771
772 static
773 struct Instance *MergeModels(struct ModelInstance *i1,
774 struct ModelInstance *i2)
775 {
776 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
777 case 1:
778 if (InterfacePtrATS!=NULL) {
779 (*InterfacePtrATS)(INST(i1),INST(i2));
780 }
781 FixExternalVars(INST(i1),INST(i2));
782 FixWhens(INST(i1),INST(i2));
783 MergeModelValues(i1,i2);
784 MergeModelChildren(i1,i2);
785 MergeParents(INST(i1),INST(i2));
786 MergeCliques(INST(i1),INST(i2));
787 if (GetUniversalFlag(i2->desc))
788 ChangeUniversalInstance(GetUniversalTable(),INST(i2),INST(i1));
789 DestroyInstance(INST(i2),NULL);
790 return INST(i1);
791 case 2:
792 if (InterfacePtrATS!=NULL) {
793 (*InterfacePtrATS)(INST(i2),INST(i1));
794 }
795 FixExternalVars(INST(i2),INST(i1));
796 FixWhens(INST(i2),INST(i1));
797 MergeModelValues(i2,i1);
798 MergeModelChildren(i2,i1);
799 MergeParents(INST(i2),INST(i1));
800 MergeCliques(INST(i2),INST(i1));
801 if (GetUniversalFlag(i1->desc))
802 ChangeUniversalInstance(GetUniversalTable(),INST(i1),INST(i2));
803 DestroyInstance(INST(i1),NULL);
804 return INST(i2);
805 default:
806 assert(MoreRefined(i1->desc,i2->desc)==NULL);
807 BadMerge(ASCERR,"Unconformable ARE_THE_SAME.\n",INST(i1),INST(i2),"");
808 DifferentVersionCheck(i1->desc,i2->desc);
809 return NULL;
810 }
811 }
812
813 static
814 struct Instance *MergeRelations(struct RelationInstance *i1,
815 struct RelationInstance *i2)
816 {
817 if (i1->desc==i2->desc){
818 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
819 case 1:
820 if (InterfacePtrATS!=NULL) {
821 (*InterfacePtrATS)(INST(i1),INST(i2));
822 }
823 /* add check to make sure equations are equal.
824 * A sufficient check is that they have the same
825 * union *share in the struct relation. For
826 * token relations, a sufficient check is that
827 * token arrays be the same size and varlists
828 * be the same size. This is uncheckable at
829 * present because the merge of relations and
830 * whens possibly occurs before the merge of
831 * locally defined variables and sets.
832 * To ensure correctness, we must merge all the
833 * local variables and sets successfully, then
834 * relations may be merged without even checking
835 * because if two relations had an incompatibility
836 * it would have showed up in the vars/sets checking.
837 */
838 MergeChildrenValues(INST(i1),INST(i2));
839 MergeParents(INST(i1),INST(i2));
840 FixLogRelations(INST(i1),INST(i2));
841 FixWhens(INST(i1),INST(i2));
842 DestroyInstance(INST(i2),NULL);
843 return INST(i1);
844 case 2:
845 if (InterfacePtrATS!=NULL) {
846 (*InterfacePtrATS)(INST(i2),INST(i1));
847 }
848 /* add check to make sure equations are equal */
849 MergeChildrenValues(INST(i2),INST(i1));
850 MergeParents(INST(i2),INST(i1));
851 FixLogRelations(INST(i2),INST(i1));
852 FixWhens(INST(i2),INST(i1));
853 DestroyInstance(INST(i1),NULL);
854 return INST(i2);
855 default:
856 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of relations!\n",
857 INST(i1), INST(i2),"");
858 DifferentVersionCheck(i1->desc,i2->desc);
859 return NULL;
860 }
861 }
862 else{
863 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of relations!\n",
864 INST(i1), INST(i2),"");
865 DifferentVersionCheck(i1->desc,i2->desc);
866 return NULL;
867 }
868 }
869
870 static
871 struct Instance *MergeLogRelations(struct LogRelInstance *i1,
872 struct LogRelInstance *i2)
873 {
874 if (i1->desc==i2->desc){
875 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
876 case 1:
877 if (InterfacePtrATS!=NULL) {
878 (*InterfacePtrATS)(INST(i1),INST(i2));
879 }
880 /* add check to make sure logical equations are equal */
881 MergeChildrenValues(INST(i1),INST(i2));
882 MergeParents(INST(i1),INST(i2));
883 FixLogRelations(INST(i1),INST(i2));
884 FixWhens(INST(i1),INST(i2));
885 DestroyInstance(INST(i2),NULL);
886 return INST(i1);
887 case 2:
888 if (InterfacePtrATS!=NULL) {
889 (*InterfacePtrATS)(INST(i2),INST(i1));
890 }
891 /* add check to make sure logical equations are equal */
892 MergeChildrenValues(INST(i2),INST(i1));
893 MergeParents(INST(i2),INST(i1));
894 FixLogRelations(INST(i2),INST(i1));
895 FixWhens(INST(i2),INST(i1));
896 DestroyInstance(INST(i1),NULL);
897 return INST(i2);
898 default:
899 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of logical relations!\n",
900 INST(i1), INST(i2),"");
901 DifferentVersionCheck(i1->desc,i2->desc);
902 return NULL;
903 }
904 } else {
905 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of logical relations!\n",
906 INST(i1), INST(i2),"");
907 DifferentVersionCheck(i1->desc,i2->desc);
908 return NULL;
909 }
910 }
911
912 static
913 struct Instance *MergeWhens(struct WhenInstance *i1,
914 struct WhenInstance *i2)
915 {
916 if (i1->desc==i2->desc){
917 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
918 case 1:
919 if (InterfacePtrATS!=NULL) {
920 (*InterfacePtrATS)(INST(i1),INST(i2));
921 }
922 MergeParents(INST(i1),INST(i2));
923 FixWhens(INST(i1),INST(i2));
924 DestroyInstance(INST(i2),NULL);
925 return INST(i1);
926 case 2:
927 if (InterfacePtrATS!=NULL) {
928 (*InterfacePtrATS)(INST(i2),INST(i1));
929 }
930 MergeParents(INST(i2),INST(i1));
931 FixWhens(INST(i2),INST(i1));
932 DestroyInstance(INST(i1),NULL);
933 return INST(i2);
934 default:
935 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of whens!\n",
936 INST(i1),INST(i2),"");
937 DifferentVersionCheck(i1->desc,i2->desc);
938 return NULL;
939 }
940 } else {
941 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of whens!\n",
942 INST(i1),INST(i2),"");
943 DifferentVersionCheck(i1->desc,i2->desc);
944 return NULL;
945 }
946 }
947
948
949 static
950 int CheckArrayChildren(struct gl_list_t *l1,
951 struct gl_list_t *l2,
952 enum inst_t t)
953 {
954 register unsigned long c,len;
955 register struct ArrayChild *child1,*child2;
956 if ((l1==NULL)||(l2==NULL)) return 0;
957 len = gl_length(l1);
958 if (gl_length(l2)!=len) return 1;
959 for(c=1;c<=len;c++){
960 child1 = (struct ArrayChild *)gl_fetch(l1,c);
961 child2 = (struct ArrayChild *)gl_fetch(l2,c);
962 if (t == ARRAY_INT_INST){
963 if (CmpIntIndex(child1,child2)!=0) {
964 return 1;
965 }
966 } else {
967 if (CmpStrIndex(child1,child2)!=0) {
968 return 1;
969 }
970 }
971 }
972 return 0;
973 }
974
975 static
976 void MergeArrayChildren(struct ArrayInstance *i1, struct ArrayInstance *i2)
977 {
978 unsigned long c,len;
979 struct ArrayChild *ptr1,*ptr2;
980 if ((i1->children != NULL)&&(i2->children != NULL)){
981 len = gl_length(i1->children);
982 for(c=1;c<=len;c++){
983 ptr1 = (struct ArrayChild *)gl_fetch(i1->children,c);
984 ptr2 = (struct ArrayChild *)gl_fetch(i2->children,c);
985 (void)RecursiveMergeInstance(ptr1->inst,ptr2->inst);
986 }
987 } else {
988 if (i2->children != NULL){
989 i1->children = i2->children;
990 i2->children = NULL;
991 len = gl_length(i1->children);
992 for(c=1;c<=len;c++){
993 ptr1 = (struct ArrayChild *)gl_fetch(i1->children,c);
994 RemoveParent(ptr1->inst,INST(i2));
995 if (SearchForParent(ptr1->inst,INST(i1))==0) {
996 AddParent(ptr1->inst,INST(i1));
997 }
998 }
999 }
1000 }
1001 }
1002
1003 static
1004 struct Instance *MergeArrays(struct ArrayInstance *i1,
1005 struct ArrayInstance *i2)
1006 {
1007 assert(i1&&i2&&i1->t==i2->t);
1008 if ((i1->desc == i2->desc)&&(i1->indirected == i2->indirected)){
1009 if (CheckArrayChildren(i1->children,i2->children,i1->t)){
1010 Asc_Panic(2, NULL, "Arrays have different children.\n");/*NOTREACHED*/
1011 }
1012 switch (KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
1013 case 1:
1014 MergeArrayChildren(i1,i2);
1015 MergeParents(INST(i1),INST(i2));
1016 DestroyInstance(INST(i2),NULL);
1017 return INST(i1);
1018 case 2:
1019 MergeArrayChildren(i2,i1);
1020 MergeParents(INST(i2),INST(i1));
1021 DestroyInstance(INST(i1),NULL);
1022 return INST(i2);
1023 default:
1024 Asc_Panic(2, NULL,
1025 "Bizarre error that should never occur.\n");/*NOTREACHED*/
1026 }
1027 } else {
1028 Asc_Panic(2, NULL, "Unconformable arrays.\n");/*NOTREACHED*/
1029 }
1030 exit(2);/* NOT REACHED. Needed to keep gcc from whining */
1031 }
1032
1033 static
1034 void CheckClique(struct Instance *i)
1035 {
1036 struct TypeDescription *type;
1037 struct Instance *ptr;
1038 if (i!=NULL){
1039 ptr = i;
1040 type = InstanceTypeDesc(i);
1041 while((ptr=NextCliqueMember(ptr)) != i){
1042 if (InstanceTypeDesc(ptr)!=type) {
1043 /* NULL is correct arginst because parameterized
1044 * instances are never in cliques with other than
1045 * themselves.
1046 */
1047 ptr = RefineInstance(ptr,type,NULL);
1048 }
1049 }
1050 }
1051 }
1052
1053 /* basically checks arealikes recursively after merge */
1054 void PostMergeCheck(struct Instance *i)
1055 {
1056 /* This can't use VisitInstanceTree because it could be called recursively
1057 * by RefineInstance when it refines a universal type
1058 */
1059 unsigned long nc,c;
1060 struct Instance *child;
1061 if (i==NULL) return;
1062 AssertMemory(i);
1063 CheckClique(i);
1064 if (NotAtom(i)){ /* wrong -- atoms and constants can have cliques. fix me */
1065 nc = NumberChildren(i);
1066 for(c=1;c<=nc;c++) {
1067 child = InstanceChild(i,c);
1068 if (child != NULL) {
1069 PostMergeCheck(child);
1070 }
1071 }
1072 }
1073 }
1074
1075 static
1076 struct Instance *RecursiveMergeInstance(struct Instance *i1,
1077 struct Instance *i2)
1078 {
1079 struct Instance *result;
1080 assert(i1&&i2);
1081 if (i1==i2) {
1082 return i1;
1083 }
1084 if ( i1->t == i2->t ) {
1085 switch( i1->t ) {
1086 case MODEL_INST:
1087 result = MergeModels(MOD_INST(i1),MOD_INST(i2));
1088 break;
1089 case REAL_CONSTANT_INST:
1090 case BOOLEAN_CONSTANT_INST:
1091 case INTEGER_CONSTANT_INST:
1092 case SYMBOL_CONSTANT_INST:
1093 result = MergeConstants(i1,i2);
1094 break;
1095 case REAL_ATOM_INST:
1096 case BOOLEAN_ATOM_INST:
1097 case INTEGER_ATOM_INST:
1098 case SET_ATOM_INST:
1099 case SYMBOL_ATOM_INST:
1100 result = MergeAtoms(i1,i2);
1101 break;
1102 case REL_INST:
1103 result = MergeRelations(RELN_INST(i1),RELN_INST(i2));
1104 break;
1105 case LREL_INST:
1106 result = MergeLogRelations(LRELN_INST(i1),LRELN_INST(i2));
1107 break;
1108 case WHEN_INST:
1109 result = MergeWhens(W_INST(i1),W_INST(i2));
1110 break;
1111 case ARRAY_INT_INST:
1112 case ARRAY_ENUM_INST:
1113 result = MergeArrays(ARY_INST(i1),ARY_INST(i2));
1114 break;
1115 case REAL_INST:
1116 case INTEGER_INST:
1117 case BOOLEAN_INST:
1118 case SET_INST:
1119 case SYMBOL_INST:
1120 FPRINTF(ASCERR,"Attempt to merge fundamental instance type.\n");
1121 FPRINTF(ASCERR,"This operation is not allowed.\n");
1122 result = NULL;
1123 break;
1124 default:
1125 Asc_Panic(2, NULL,
1126 "Unknown instance type passed to RecursiveMergeInstance.\n");
1127 result = NULL;
1128 break;
1129 }
1130 /* CheckClique(result); moved to a PostMergeCheck */
1131 return result;
1132 } else {
1133 Asc_Panic(2, NULL, "Attempt to merge unconformable types in children.\n");
1134 exit(2);/* Needed to keep gcc from whining */
1135 }
1136 }
1137
1138 struct Instance *MergeInstances(struct Instance *i1, struct Instance *i2)
1139 {
1140 assert(i1&&i2);
1141 if (i1==i2) return i1;
1142 AssertMemory(i1);
1143 AssertMemory(i2);
1144 if (InstanceKind(i1)==InstanceKind(i2)){
1145 if (InstanceKind(i1)==MODEL_INST) {
1146 if (GetModelParameterCount(InstanceTypeDesc(i1)) != 0 ||
1147 GetModelParameterCount(InstanceTypeDesc(i2)) != 0 ) {
1148 /* We need to relax this for == types where i1,i2 have
1149 * exactly equal arguments, typewise.
1150 */
1151 BadMerge(ASCERR,"Attempt to merge parameterized types.\n",
1152 INST(i1), INST(i2), "Both instances remain unchanged.\n");
1153 return NULL;
1154 }
1155 }
1156 if (MoreRefined(InstanceTypeDesc(i1),InstanceTypeDesc(i2))!=NULL) {
1157 return RecursiveMergeInstance(i1,i2);
1158 } else {
1159 BadMerge(ASCERR,"Attempt to merge unconformable types.\n",
1160 INST(i1),INST(i2), "Both instances remain unchanged.\n");
1161 DifferentVersionCheck(InstanceTypeDesc(i1),
1162 InstanceTypeDesc(i2));
1163 return NULL;
1164 }
1165 } else{
1166 ReallyBadMerge(ASCERR,"Attempt to merge very unconformable types.\n",
1167 INST(i1),INST(i2), "Both instances remain unchanged.\n");
1168 return NULL;
1169 }
1170 }
1171

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