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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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