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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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