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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2689 - (show annotations) (download) (as text)
Mon Mar 4 11:28:19 2013 UTC (9 years, 4 months ago) by jpye
File MIME type: text/x-csrc
File size: 35677 byte(s)
Fixes bug 567, for the moment. More tests surely required.
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 #if 0
769 char *n1 = WriteInstanceNameString(i1,NULL);
770 char *n2 = WriteInstanceNameString(i2,NULL);
771 CONSOLE_DEBUG("Merging models '%s' and '%s'",n1,n2);
772 ASC_FREE(n1);
773 ASC_FREE(n2);
774 #endif
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 char *n1 = WriteInstanceNameString(i1,NULL);
818 char *n2 = WriteInstanceNameString(i2,NULL);
819 CONSOLE_DEBUG("Merging relations '%s' and '%s'",n2,n2);
820 ASC_FREE(n1);
821 ASC_FREE(n2);
822
823 if(i1->desc==i2->desc){
824 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
825 case 1:
826 if (InterfacePtrATS!=NULL) {
827 (*InterfacePtrATS)(INST(i1),INST(i2));
828 }
829 /* add check to make sure equations are equal.
830 * A sufficient check is that they have the same
831 * union *share in the struct relation. For
832 * token relations, a sufficient check is that
833 * token arrays be the same size and varlists
834 * be the same size. This is uncheckable at
835 * present because the merge of relations and
836 * whens possibly occurs before the merge of
837 * locally defined variables and sets.
838 * To ensure correctness, we must merge all the
839 * local variables and sets successfully, then
840 * relations may be merged without even checking
841 * because if two relations had an incompatibility
842 * it would have showed up in the vars/sets checking.
843 */
844 MergeChildrenValues(INST(i1),INST(i2));
845 MergeParents(INST(i1),INST(i2));
846 FixLogRelations(INST(i1),INST(i2));
847 FixWhens(INST(i1),INST(i2));
848 DestroyInstance(INST(i2),NULL);
849 return INST(i1);
850 case 2:
851 if(InterfacePtrATS!=NULL) {
852 (*InterfacePtrATS)(INST(i2),INST(i1));
853 }
854 /* add check to make sure equations are equal */
855 MergeChildrenValues(INST(i2),INST(i1));
856 MergeParents(INST(i2),INST(i1));
857 FixLogRelations(INST(i2),INST(i1));
858 FixWhens(INST(i2),INST(i1));
859 DestroyInstance(INST(i1),NULL);
860 return INST(i2);
861 default:
862 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of relations!\n",
863 INST(i1), INST(i2),"");
864 DifferentVersionCheck(i1->desc,i2->desc);
865 return NULL;
866 }
867 }
868 else{
869 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of relations!\n",
870 INST(i1), INST(i2),"");
871 DifferentVersionCheck(i1->desc,i2->desc);
872 return NULL;
873 }
874 }
875
876 static
877 struct Instance *MergeLogRelations(struct LogRelInstance *i1,
878 struct LogRelInstance *i2)
879 {
880 if (i1->desc==i2->desc){
881 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
882 case 1:
883 if (InterfacePtrATS!=NULL) {
884 (*InterfacePtrATS)(INST(i1),INST(i2));
885 }
886 /* add check to make sure logical equations are equal */
887 MergeChildrenValues(INST(i1),INST(i2));
888 MergeParents(INST(i1),INST(i2));
889 FixLogRelations(INST(i1),INST(i2));
890 FixWhens(INST(i1),INST(i2));
891 DestroyInstance(INST(i2),NULL);
892 return INST(i1);
893 case 2:
894 if (InterfacePtrATS!=NULL) {
895 (*InterfacePtrATS)(INST(i2),INST(i1));
896 }
897 /* add check to make sure logical equations are equal */
898 MergeChildrenValues(INST(i2),INST(i1));
899 MergeParents(INST(i2),INST(i1));
900 FixLogRelations(INST(i2),INST(i1));
901 FixWhens(INST(i2),INST(i1));
902 DestroyInstance(INST(i1),NULL);
903 return INST(i2);
904 default:
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 } else {
911 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of logical relations!\n",
912 INST(i1), INST(i2),"");
913 DifferentVersionCheck(i1->desc,i2->desc);
914 return NULL;
915 }
916 }
917
918 static
919 struct Instance *MergeWhens(struct WhenInstance *i1,
920 struct WhenInstance *i2)
921 {
922 if (i1->desc==i2->desc){
923 switch(KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
924 case 1:
925 if (InterfacePtrATS!=NULL) {
926 (*InterfacePtrATS)(INST(i1),INST(i2));
927 }
928 MergeParents(INST(i1),INST(i2));
929 FixWhens(INST(i1),INST(i2));
930 DestroyInstance(INST(i2),NULL);
931 return INST(i1);
932 case 2:
933 if (InterfacePtrATS!=NULL) {
934 (*InterfacePtrATS)(INST(i2),INST(i1));
935 }
936 MergeParents(INST(i2),INST(i1));
937 FixWhens(INST(i2),INST(i1));
938 DestroyInstance(INST(i1),NULL);
939 return INST(i2);
940 default:
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 } else {
947 BadMerge(ASCERR,"Unconformable ARE_THE_SAME of whens!\n",
948 INST(i1),INST(i2),"");
949 DifferentVersionCheck(i1->desc,i2->desc);
950 return NULL;
951 }
952 }
953
954
955 static
956 int CheckArrayChildren(struct gl_list_t *l1,
957 struct gl_list_t *l2,
958 enum inst_t t)
959 {
960 register unsigned long c,len;
961 register struct ArrayChild *child1,*child2;
962 if ((l1==NULL)||(l2==NULL)) return 0;
963 len = gl_length(l1);
964 if (gl_length(l2)!=len) return 1;
965 for(c=1;c<=len;c++){
966 child1 = (struct ArrayChild *)gl_fetch(l1,c);
967 child2 = (struct ArrayChild *)gl_fetch(l2,c);
968 if (t == ARRAY_INT_INST){
969 if (CmpIntIndex(child1,child2)!=0) {
970 return 1;
971 }
972 } else {
973 if (CmpStrIndex(child1,child2)!=0) {
974 return 1;
975 }
976 }
977 }
978 return 0;
979 }
980
981 static
982 void MergeArrayChildren(struct ArrayInstance *i1, struct ArrayInstance *i2)
983 {
984 unsigned long c,len;
985 struct ArrayChild *ptr1,*ptr2;
986 if ((i1->children != NULL)&&(i2->children != NULL)){
987 len = gl_length(i1->children);
988 for(c=1;c<=len;c++){
989 ptr1 = (struct ArrayChild *)gl_fetch(i1->children,c);
990 ptr2 = (struct ArrayChild *)gl_fetch(i2->children,c);
991 (void)RecursiveMergeInstance(ptr1->inst,ptr2->inst);
992 }
993 } else {
994 if (i2->children != NULL){
995 i1->children = i2->children;
996 i2->children = NULL;
997 len = gl_length(i1->children);
998 for(c=1;c<=len;c++){
999 ptr1 = (struct ArrayChild *)gl_fetch(i1->children,c);
1000 RemoveParent(ptr1->inst,INST(i2));
1001 if (SearchForParent(ptr1->inst,INST(i1))==0) {
1002 AddParent(ptr1->inst,INST(i1));
1003 }
1004 }
1005 }
1006 }
1007 }
1008
1009 static
1010 struct Instance *MergeArrays(struct ArrayInstance *i1,
1011 struct ArrayInstance *i2)
1012 {
1013 assert(i1&&i2&&i1->t==i2->t);
1014 if ((i1->desc == i2->desc)&&(i1->indirected == i2->indirected)){
1015 if (CheckArrayChildren(i1->children,i2->children,i1->t)){
1016 ASC_PANIC("Arrays have different children.\n");/*NOTREACHED*/
1017 }
1018 switch (KeepWhichInstance(i1->desc,i2->desc,INST(i1),INST(i2))){
1019 case 1:
1020 MergeArrayChildren(i1,i2);
1021 MergeParents(INST(i1),INST(i2));
1022 DestroyInstance(INST(i2),NULL);
1023 return INST(i1);
1024 case 2:
1025 MergeArrayChildren(i2,i1);
1026 MergeParents(INST(i2),INST(i1));
1027 DestroyInstance(INST(i1),NULL);
1028 return INST(i2);
1029 default:
1030 Asc_Panic(2, NULL,
1031 "Bizarre error that should never occur.\n");/*NOTREACHED*/
1032 }
1033 } else {
1034 ASC_PANIC("Unconformable arrays.\n");/*NOTREACHED*/
1035 }
1036 exit(2);/* NOT REACHED. Needed to keep gcc from whining */
1037 }
1038
1039 static
1040 void CheckClique(struct Instance *i)
1041 {
1042 struct TypeDescription *type;
1043 struct Instance *ptr;
1044 if (i!=NULL){
1045 ptr = i;
1046 type = InstanceTypeDesc(i);
1047 while((ptr=NextCliqueMember(ptr)) != i){
1048 if (InstanceTypeDesc(ptr)!=type) {
1049 /* NULL is correct arginst because parameterized
1050 * instances are never in cliques with other than
1051 * themselves.
1052 */
1053 ptr = RefineInstance(ptr,type,NULL);
1054 }
1055 }
1056 }
1057 }
1058
1059 /* basically checks arealikes recursively after merge */
1060 void PostMergeCheck(struct Instance *i)
1061 {
1062 /* This can't use VisitInstanceTree because it could be called recursively
1063 * by RefineInstance when it refines a universal type
1064 */
1065 unsigned long nc,c;
1066 struct Instance *child;
1067 if (i==NULL) return;
1068 AssertMemory(i);
1069 CheckClique(i);
1070 if (NotAtom(i)){ /* wrong -- atoms and constants can have cliques. fix me */
1071 nc = NumberChildren(i);
1072 for(c=1;c<=nc;c++) {
1073 child = InstanceChild(i,c);
1074 if (child != NULL) {
1075 PostMergeCheck(child);
1076 }
1077 }
1078 }
1079 }
1080
1081 static
1082 struct Instance *RecursiveMergeInstance(struct Instance *i1,
1083 struct Instance *i2)
1084 {
1085 struct Instance *result;
1086 assert(i1&&i2);
1087 if (i1==i2) {
1088 return i1;
1089 }
1090
1091 #if 0
1092 char *n1 = WriteInstanceNameString(i1,NULL);
1093 char *n2 = WriteInstanceNameString(i2,NULL);
1094 CONSOLE_DEBUG("Merging '%s' and '%s'",n1,n2);
1095 ASC_FREE(n1);
1096 ASC_FREE(n2);
1097 #endif
1098
1099 if ( i1->t == i2->t ) {
1100 switch( i1->t ) {
1101 case MODEL_INST:
1102 result = MergeModels(MOD_INST(i1),MOD_INST(i2));
1103 break;
1104 case REAL_CONSTANT_INST:
1105 case BOOLEAN_CONSTANT_INST:
1106 case INTEGER_CONSTANT_INST:
1107 case SYMBOL_CONSTANT_INST:
1108 result = MergeConstants(i1,i2);
1109 break;
1110 case REAL_ATOM_INST:
1111 case BOOLEAN_ATOM_INST:
1112 case INTEGER_ATOM_INST:
1113 case SET_ATOM_INST:
1114 case SYMBOL_ATOM_INST:
1115 result = MergeAtoms(i1,i2);
1116 break;
1117 case REL_INST:
1118 result = MergeRelations(RELN_INST(i1),RELN_INST(i2));
1119 break;
1120 case LREL_INST:
1121 result = MergeLogRelations(LRELN_INST(i1),LRELN_INST(i2));
1122 break;
1123 case WHEN_INST:
1124 result = MergeWhens(W_INST(i1),W_INST(i2));
1125 break;
1126 case ARRAY_INT_INST:
1127 case ARRAY_ENUM_INST:
1128 result = MergeArrays(ARY_INST(i1),ARY_INST(i2));
1129 break;
1130 case REAL_INST:
1131 case INTEGER_INST:
1132 case BOOLEAN_INST:
1133 case SET_INST:
1134 case SYMBOL_INST:
1135 FPRINTF(ASCERR,"Attempt to merge fundamental instance type.\n");
1136 FPRINTF(ASCERR,"This operation is not allowed.\n");
1137 result = NULL;
1138 break;
1139 default:
1140 Asc_Panic(2, NULL,
1141 "Unknown instance type passed to RecursiveMergeInstance.\n");
1142 result = NULL;
1143 break;
1144 }
1145 /* CheckClique(result); moved to a PostMergeCheck */
1146 return result;
1147 } else {
1148 ASC_PANIC("Attempt to merge unconformable types in children.\n");
1149
1150 }
1151 }
1152
1153 struct Instance *MergeInstances(struct Instance *i1, struct Instance *i2){
1154 assert(i1&&i2);
1155 if(i1==i2) return i1;
1156 AssertMemory(i1);
1157 AssertMemory(i2);
1158 if(InstanceKind(i1)==InstanceKind(i2)){
1159 if(InstanceKind(i1)==MODEL_INST) {
1160 if(GetModelParameterCount(InstanceTypeDesc(i1)) != 0 ||
1161 GetModelParameterCount(InstanceTypeDesc(i2)) != 0 ) {
1162 /* We need to relax this for == types where i1,i2 have
1163 * exactly equal arguments, typewise.
1164 */
1165 BadMerge(ASCERR,"Attempt to merge parameterized types.\n",
1166 INST(i1), INST(i2), "Both instances remain unchanged.\n");
1167 return NULL;
1168 }
1169 }
1170 if(MoreRefined(InstanceTypeDesc(i1),InstanceTypeDesc(i2))!=NULL) {
1171 return RecursiveMergeInstance(i1,i2);
1172 }else{
1173 BadMerge(ASCERR,"Attempt to merge unconformable types.\n",
1174 INST(i1),INST(i2), "Both instances remain unchanged.\n");
1175 DifferentVersionCheck(InstanceTypeDesc(i1),
1176 InstanceTypeDesc(i2));
1177 return NULL;
1178 }
1179 }else{
1180 ReallyBadMerge(ASCERR,"Attempt to merge very unconformable types.\n",
1181 INST(i1),INST(i2), "Both instances remain unchanged.\n");
1182 return NULL;
1183 }
1184 }
1185

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