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

Annotation of /trunk/base/generic/compiler/refineinst.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 669 - (hide annotations) (download) (as text)
Wed Jun 21 07:00:45 2006 UTC (13 years, 2 months ago) by johnpye
File MIME type: text/x-csrc
File size: 25947 byte(s)
Merged changes from DAE branch (revisions 702 to 819) back into trunk.
This adds the Integration API to the ASCEND solver (in base/generic).
Also provides pre-alpha support for 'IDA' from the SUNDIALS suite, a DAE solver.
Many other minor code clean-ups, including adoption of new 'ASC_NEW' and friends (to replace 'ascmalloc')
Added some very sketchy stuff providing 'DIFF(...)' syntax, although it is anticipated that this will be removed.
1 aw0a 1 /*
2     * Ascend Instance Refinement Functions
3     * by Tom Epperly & Ben Allan1
4     * 9/3/89
5     * Version: $Revision: 1.10 $
6     * Version control file: $RCSfile: refineinst.c,v $
7     * Date last modified: $Date: 1998/02/05 16:37:32 $
8     * Last modified by: $Author: ballan $
9     *
10     * This file is part of the Ascend Language Interpreter.
11     *
12     * Copyright (C) 1996 Ben Allan
13     * based on instance.c
14     * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
15     *
16     * The Ascend Language Interpreter is free software; you can redistribute
17     * it and/or modify it under the terms of the GNU General Public License as
18     * published by the Free Software Foundation; either version 2 of the
19     * License, or (at your option) any later version.
20     *
21     * The Ascend Language Interpreter is distributed in hope that it will be
22     * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
23     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24     * General Public License for more details.
25     *
26     * You should have received a copy of the GNU General Public License
27     * along with the program; if not, write to the Free Software Foundation,
28     * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
29     * COPYING.
30     *
31     */
32     #include <stdarg.h>
33 johnpye 399 #include <utilities/ascConfig.h>
34     #include <utilities/ascPanic.h>
35     #include <utilities/ascMalloc.h>
36     #include <general/pool.h>
37     #include <general/list.h>
38     #include <general/dstring.h>
39     #include "compiler.h"
40     #include "bit.h"
41     #include "symtab.h"
42     #include "fractions.h"
43     #include "dimen.h"
44     #include "functype.h"
45 johnpye 669 #include "expr_types.h"
46 johnpye 399 #include "instance_enum.h"
47     #include "stattypes.h"
48     #include "slist.h"
49     #include "instance_name.h"
50     #include "instance_io.h"
51     #include "check.h"
52     #include "dump.h"
53     #include "child.h"
54     #include "type_desc.h"
55     #include "prototype.h"
56     #include "pending.h"
57     #include "find.h"
58     #include "relation_type.h"
59     #include "relation.h"
60     #include "logical_relation.h"
61     #include "logrelation.h"
62     #include "relation_util.h"
63     #include "logrel_util.h"
64     #include "rel_common.h"
65     #include "case.h"
66     #include "when_util.h"
67     #include "universal.h"
68     #include "setinstval.h"
69     #include "instance_types.h"
70 aw0a 1 /* new */
71 johnpye 399 #include "atomsize.h"
72     #include "atomvalue.h"
73     #include "cmpfunc.h"
74     #include "copyinst.h"
75     #include "createinst.h"
76     #include "destroyinst.h"
77     #include "extinst.h"
78     #include "instmacro.h"
79     #include "instquery.h"
80     #include "linkinst.h"
81     #include "mergeinst.h"
82     #include "parentchild.h"
83     #include "instantiate.h"
84     #include "refineinst.h"
85 aw0a 1
86     #ifndef lint
87     static CONST char RefineInstModuleID[] = "$Id: refineinst.c,v 1.10 1998/02/05 16:37:32 ballan Exp $";
88     #endif
89    
90    
91     /* checks children, and does some value copying in the process */
92     static void CheckChild(struct Instance *old, struct Instance *new)
93     {
94     register CONST dim_type *dimp;
95     assert(old->t==new->t);
96     switch(old->t){
97     case REAL_INST:
98     dimp = CheckDimensionsMatch(R_INST(old)->dimen,R_INST(new)->dimen);
99     if (dimp==NULL){
100     FPRINTF(ASCERR,"Dimensional mismatch in CheckChild.\n");
101     R_INST(new)->dimen = R_INST(old)->dimen;
102     }
103     else
104     R_INST(new)->dimen = dimp;
105     if (R_INST(old)->assigned > R_INST(new)->assigned){
106     R_INST(new)->assigned = R_INST(old)->assigned;
107     R_INST(new)->depth = R_INST(old)->depth;
108     R_INST(new)->value = R_INST(old)->value;
109     }
110     break;
111     case BOOLEAN_INST:
112     if (B_INST(old)->assigned > B_INST(new)->assigned){
113     B_INST(new)->assigned = B_INST(old)->assigned;
114     B_INST(new)->depth = B_INST(old)->depth;
115     B_INST(new)->value = B_INST(old)->value;
116     }
117     break;
118     case INTEGER_INST:
119     if ((I_INST(old)->assigned)&&!(I_INST(new)->assigned)){
120     I_INST(new)->assigned = I_INST(old)->assigned;
121     I_INST(new)->value = I_INST(old)->value;
122     }
123     break;
124     case SET_INST:
125     #ifndef NDEBUG
126     if ((S_INST(old)->list)&&(S_INST(new)->list))
127     assert(SetsEqual(S_INST(old)->list,S_INST(new)->list));
128     #endif
129     if ((S_INST(old)->list!=NULL)&&(S_INST(new)->list==NULL)){
130     S_INST(new)->list = S_INST(old)->list;
131     S_INST(old)->list = NULL;
132     }
133     break;
134     case SYMBOL_INST:
135     #ifndef NDEBUG
136     if ((SYM_INST(new)->value!=NULL)&&(SYM_INST(new)->value!=NULL)) {
137     assert(SYM_INST(new)->value == SYM_INST(old)->value);
138     }
139     #endif
140     if ((SYM_INST(old)->value!=NULL)&&(SYM_INST(new)->value==NULL)) {
141     SYM_INST(new)->value = SYM_INST(old)->value;
142     }
143     break;
144     default:
145     Asc_Panic(2, NULL, "Incorrect type passed to CheckChild.\n");/*NOTREACHED*/
146     }
147     }
148    
149     static
150     void CheckAtomValuesOne(register struct Instance **old,
151     register struct Instance **new,
152     register unsigned long int num)
153     {
154     while(num--)
155     CheckChild(*(old++),*(new++));
156     }
157    
158     static
159     void CheckAtomValuesTwo(struct Instance *old, struct Instance *new)
160     {
161     register unsigned long c,num_children,pos;
162     struct InstanceName name;
163     num_children = NumberChildren(old);
164     for(c=1;c<=num_children;c++){
165     name = ChildName(old,c);
166     pos = ChildSearch(new,&name);
167     CheckChild(InstanceChild(old,c),InstanceChild(new,pos));
168     }
169     }
170    
171    
172     /* As constants never change size, this always returns the given i
173     unless it becomes universal and is replaced by already existing.
174     But note, the IRT universal with already existing universal inst case
175     never reaches here because it == ATS and is trapped in RefineInstance.
176     We do not handle that case for this reason. */
177     static struct Instance *RefineRealConstant(struct RealConstantInstance *i,
178     struct TypeDescription *type)
179     {
180     register CONST dim_type *dimp;
181     unsigned what=0;
182     /* bit game: bit 0 = update val,1 = update dim, bits 8,16= err in val/dim */
183    
184     assert(MoreRefined(type,i->desc)==type); /* refinement possible? */
185     AssertMemory(i);
186     if (i->desc==type) return INST(i); /* if same type already, no work */
187     if (ShortCutMakeUniversalInstance(type)) {
188     /* NOT REACHED. see RefineRealAtom for expl. */
189     FPRINTF(ASCERR,"Program logic error in RefineRealConstant.\n");
190     FPRINTF(ASCERR,"Please report this message to %s.\n",ASC_BIG_BUGMAIL);
191     return INST(i);
192     }
193     /* Work: new type is more refined, at least in the library */
194     /* check for value and dimensions compatibility */
195     if (!CIASS(i)) {
196     if (ConstantDefaulted(type) ) {
197     what |= 1;
198     } /* else not assigned and not defaulted is fine. just leave value as is */
199     } else {
200     if ( (ConstantDefaulted(type) && i->value != GetConstantDefReal(type))
201     || !(ConstantDefaulted(type)) ) {
202     what |= 16;
203     /* we're hosed, type, value incompatible.possibly ahead of type. */
204     } /* else shut up and do not assign */
205     }
206    
207     /* check dimensions */
208     dimp = GetConstantDimens(type);
209     if ( !(IsWild(dimp)) ) { /* do we get type's dims? */
210     if (IsWild(i->dimen)) { /* we do */
211     what |=2;
212     } else {
213     if( CheckDimensionsMatch(dimp,i->dimen)==NULL) {
214     what |= 8; /* hosed, dims mismatch */
215     } /* else dims already where they belong, shutup. */
216     }
217     } else { /* type is wild */
218     if (!IsWild(i->dimen)) what |= 8;
219     /* the instance can't be ahead of wild. funny implicit type case. */
220     }
221     if (what & 24) { /* something messed up */
222     if (what & 16) {
223     FPRINTF(ASCERR,"Value conflict in RefineRealConstant.\n");
224     }
225     if (what & 8) {
226     FPRINTF(ASCERR,"Dimensional conflict in RefineRealConstant.\n");
227     }
228     FPRINTF(ASCERR,"Unable to refine instance.\n");
229     } else { /* ok, fix it up */
230     if (what & 1) {
231     SetRealAtomValue(INST(i),GetConstantDefReal(type),0);
232     }
233     if (what & 2) {
234     SetRealAtomDims(INST(i),dimp);
235     }
236     if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
237     /* don't have to check universal table cause that was already up top */
238     AddUniversalInstance(GetUniversalTable(),type,INST(i));
239     }
240     /* else don't need to change universal table, cause we didn't move */
241     /* no move, so no parent update either */
242     i->desc = type; /* finally somebody make the refinement */
243     }
244     return INST(i); /* always returns i */
245     }
246    
247     /*
248     * When the type of i is < type given, i will _always_
249     * end up being blown away, either by merging with a UNIVERSAL
250     * instance or by the copy to the new type. This needs to be
251     * rewritten so that atoms with the same size (number children)
252     * are always recycled rather than malloc/free'd.
253     */
254     static struct Instance *RefineRealAtom(struct RealAtomInstance *i,
255     struct TypeDescription *type)
256     {
257     struct RealAtomInstance *new;
258     register struct gl_list_t *tmp;
259     register CONST dim_type *dimp;
260     assert(MoreRefined(type,i->desc)==type);
261     AssertMemory(i);
262     if (i->desc==type) return INST(i);
263     /* The following line is a bug. It should be
264     new=SCMUI(); merge parents; destroy(i); return new;
265     It is not provoked because any existing universal atoms to
266     refine up to are filtered out at the RefineInstance function.
267     Therefore the following if never passes.
268     As is, this fails to do the refinement at all if SCMUI passes.
269    
270     Another bug is that if this function was ever called with
271     an atom to be refined up to an existing universal, the parents
272     lists would not be properly merged.
273     If any place other than RefineInstance called from RefineClique
274     ever calls this function, this stuff must be fixed.
275    
276     In fact, since it never passes, we're going to comment it out.
277     */
278     /*
279     *if (ShortCutMakeUniversalInstance(type)) {
280     * return INST(i);
281     */ /* NOT REACHED */
282     /*}
283     */
284     new = RA_INST(CreateRealInstance(type));
285     /* check value */
286     if (i->assigned > new->assigned){ /* old value is been assigned */
287     new->depth = i->depth;
288     new->assigned = i->assigned;
289     new->value = i->value;
290     }
291     /* check dimensions */
292     if ((dimp = CheckDimensionsMatch(i->dimen,new->dimen))==NULL){
293     FPRINTF(ASCERR,"Dimensional conflict in RefineRealAtom.\n");
294     FPRINTF(ASCERR,"Unable to refine instance.\n");
295     DestroyInstance(INST(new),NULL);
296     return INST(i);
297     }
298     else {
299     new->dimen = dimp;
300     }
301     /* move interface pointer */
302     new->interface_ptr = i->interface_ptr;
303     i->interface_ptr = NULL;
304     if (InterfaceNotify!=NULL)
305     (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
306     /* fix cliques */
307     new->alike_ptr = i->alike_ptr;
308     i->alike_ptr = INST(i);
309     FixCliques(INST(i),INST(new));
310     /* swap parent lists */
311     tmp = new->parents;
312     new->parents = i->parents;
313     i->parents = tmp;
314     /* fix any relations which point to this instance */
315     FixRelations(i,new);
316     /* check children values */
317     if (NumberChildren(INST(i))==NumberChildren(INST(new))) {
318     CheckAtomValuesOne(RA_CHILD(i,0),RA_CHILD(new,0),NumberChildren(INST(i)));
319     } else {
320     CheckAtomValuesTwo(INST(i),INST(new));
321     }
322     ReDirectParents(INST(i),INST(new));
323     /* fix universal stuff */
324     if (GetUniversalFlag(i->desc)) {
325     ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
326     }
327     DestroyInstance(INST(i),NULL);
328     AssertMemory(new);
329     return INST(new);
330     }
331    
332     static struct Instance *
333     RefineBooleanConstant(struct BooleanConstantInstance *i,
334     struct TypeDescription *type)
335     {
336     assert(MoreRefined(type,i->desc)==type);
337     AssertMemory(i);
338     if (i->desc==type) return INST(i);
339     if (ShortCutMakeUniversalInstance(type)) {
340     /* NOT REACHED */
341     return INST(i);
342     }
343     /* check value */
344     if (!CIASS(i) ) {
345     if (ConstantDefaulted(type) ) {
346     SetBooleanAtomValue(INST(i),GetConstantDefBoolean(type),0);
347     }
348     } else {
349 jds 101 /* the following will fail if your compiler doesn't use 1 for TRUE */
350     if ((unsigned)BCV(i) != GetConstantDefBoolean(type) ) {
351 aw0a 1 FPRINTF(ASCERR,"Value conflict in RefineBooleanConstant.\n");
352     FPRINTF(ASCERR,"Unable to refine instance.\n");
353     return INST(i);
354     }
355     }
356     if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
357     /* don't have to check universal table cause that was already up top */
358     AddUniversalInstance(GetUniversalTable(),type,INST(i));
359     }
360     /* else don't need to change universal table, cause we didn't move */
361     /* no move, so no parent update either */
362     i->desc = type; /* finally somebody make the refinement */
363     return INST(i);
364     }
365    
366     static struct Instance *RefineBooleanAtom(struct BooleanAtomInstance *i,
367     struct TypeDescription *type)
368     {
369     register struct BooleanAtomInstance *new;
370     register struct gl_list_t *tmp;
371     assert(MoreRefined(type,i->desc)==type);
372     AssertMemory(i);
373     if (i->desc==type) return INST(i);
374     if (ShortCutMakeUniversalInstance(type)) return INST(i);
375     new = BA_INST(CreateBooleanInstance(type));
376     /* check value */
377     if (i->assigned > new->assigned){ /* old value has been assigned */
378     new->depth = i->depth;
379     new->assigned = i->assigned;
380     new->value = i->value;
381     }
382     /* move interface pointer */
383     new->interface_ptr = i->interface_ptr;
384     i->interface_ptr = NULL;
385     if (InterfaceNotify!=NULL)
386     (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
387     /* fix cliques */
388     new->alike_ptr = i->alike_ptr;
389     i->alike_ptr = INST(i);
390     FixCliques(INST(i),INST(new));
391     tmp = new->parents;
392     new->parents = i->parents;
393     i->parents = tmp;
394     /* fix any logical relation which points to this instance */
395     FixLogRelations(INST(i),INST(new));
396     /* fix any when which points to this instance */
397     FixWhens(INST(i),INST(new));
398     /* check children values */
399     if (NumberChildren(INST(i))==NumberChildren(INST(new)))
400     CheckAtomValuesOne(BA_CHILD(i,0),BA_CHILD(new,0),NumberChildren(INST(i)));
401     else
402     CheckAtomValuesTwo(INST(i),INST(new));
403     ReDirectParents(INST(i),INST(new));
404     /* fix universal stuff */
405     if (GetUniversalFlag(i->desc))
406     ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
407     DestroyInstance(INST(i),NULL);
408     AssertMemory(new);
409     return INST(new);
410     }
411    
412     static struct Instance
413     *RefineIntegerConstant(struct IntegerConstantInstance *i,
414     struct TypeDescription *type)
415     {
416     assert(MoreRefined(type,i->desc)==type);
417     AssertMemory(i);
418     if (i->desc==type) return INST(i);
419     if (ShortCutMakeUniversalInstance(type)) {
420     /* NOT REACHED */
421     return INST(i);
422     }
423     /* check value */
424     if (!CIASS(i)) {
425     if (ConstantDefaulted(type) ) {
426     SetIntegerAtomValue(INST(i),GetConstantDefInteger(type),0);
427     }
428     } else {
429     if (i->value != GetConstantDefInteger(type) ) {
430     FPRINTF(ASCERR,"Value conflict in RefineIntegerConstant.\n");
431     FPRINTF(ASCERR,"Unable to refine instance.\n");
432     return INST(i);
433     }
434     }
435     if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
436     /* don't have to check universal table cause that was already up top */
437     AddUniversalInstance(GetUniversalTable(),type,INST(i));
438     }
439     /* else don't need to change universal table, cause we didn't move */
440     /* no move, so no parent update either */
441     i->desc = type; /* finally somebody make the refinement */
442     return INST(i);
443     }
444    
445     static struct Instance *RefineIntegerAtom(struct IntegerAtomInstance *i,
446     struct TypeDescription *type)
447     {
448     register struct gl_list_t *tmp;
449     register struct IntegerAtomInstance *new;
450     assert(MoreRefined(type,i->desc)==type);
451     AssertMemory(i);
452     if (i->desc==type) return INST(i);
453     if (ShortCutMakeUniversalInstance(type)) return INST(i);
454     new = IA_INST(CreateIntegerInstance(type));
455     /* check value */
456     if (i->assigned > new->assigned){ /* old value is been assigned */
457     new->depth = i->depth;
458     new->assigned = i->assigned;
459     new->value = i->value;
460     }
461     /* move interface pointer */
462     new->interface_ptr = i->interface_ptr;
463     i->interface_ptr = NULL;
464     if (InterfaceNotify!=NULL)
465     (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
466     /* fix cliques */
467     new->alike_ptr = i->alike_ptr;
468     i->alike_ptr = INST(i);
469     FixCliques(INST(i),INST(new));
470     tmp = new->parents;
471     new->parents = i->parents;
472     i->parents = tmp;
473     /* fix any when which points to this instance */
474     FixWhens(INST(i),INST(new));
475     /* check children values */
476     if (NumberChildren(INST(i))==NumberChildren(INST(new)))
477     CheckAtomValuesOne(IA_CHILD(i,0),IA_CHILD(new,0),NumberChildren(INST(i)));
478     else
479     CheckAtomValuesTwo(INST(i),INST(new));
480     ReDirectParents(INST(i),INST(new));
481     /* fix universal stuff */
482     if (GetUniversalFlag(i->desc))
483     ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
484     DestroyInstance(INST(i),NULL);
485     AssertMemory(new);
486     return INST(new);
487     }
488    
489     /* this function REASSIGNS a set value. since when is that legal? ! */
490     static struct Instance *RefineSet(struct SetAtomInstance *i,
491     struct TypeDescription *type)
492     {
493     register struct gl_list_t *tmp;
494     register struct SetAtomInstance *new;
495     assert(MoreRefined(type,i->desc)==type);
496     AssertMemory(i);
497     if (i->desc==type) return INST(i);
498     if (ShortCutMakeUniversalInstance(type)) return INST(i);
499     new = SA_INST(CreateSetInstance(type,i->int_set));
500     /* check value */
501     if (i->list!=NULL){
502     new->list = i->list;
503     i->list = NULL;
504     }
505     /* move interface pointer */
506     new->interface_ptr = i->interface_ptr;
507     i->interface_ptr = NULL;
508     if (InterfaceNotify!=NULL)
509     (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
510     /* fix cliques */
511     new->alike_ptr = i->alike_ptr;
512     i->alike_ptr = INST(i);
513     FixCliques(INST(i),INST(new));
514     tmp = new->parents;
515     new->parents = i->parents;
516     i->parents = tmp;
517     /* check children values */
518     if (NumberChildren(INST(i))==NumberChildren(INST(new)))
519     CheckAtomValuesOne(SA_CHILD(i,0),SA_CHILD(new,0),NumberChildren(INST(i)));
520     else
521     CheckAtomValuesTwo(INST(i),INST(new));
522     ReDirectParents(INST(i),INST(new));
523     /* fix universal stuff */
524     if (GetUniversalFlag(i->desc))
525     ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
526     DestroyInstance(INST(i),NULL);
527     AssertMemory(new);
528     return INST(new);
529     }
530    
531     static struct Instance *RefineSymbolConstant(struct SymbolConstantInstance *i,
532     struct TypeDescription *type)
533     {
534     assert(MoreRefined(type,i->desc)==type);
535     AssertMemory(i);
536     if (i->desc==type) return INST(i);
537     if (ShortCutMakeUniversalInstance(type)) {
538     /* NOT REACHED*/
539     return INST(i);
540     }
541     if (i->value==NULL ) {
542     if (ConstantDefaulted(type) ) {
543     SetSymbolAtomValue(INST(i),GetConstantDefSymbol(type));
544     }
545     } else {
546     if ( SYMC_INST(i)->value != GetConstantDefSymbol(type) ) {
547     FPRINTF(ASCERR,"Value conflict in RefineSymbolConstant.\n");
548     FPRINTF(ASCERR,"Unable to refine instance.\n");
549     return INST(i);
550     }
551     }
552     if (GetUniversalFlag(type) && !GetUniversalFlag(i->desc)) {
553     /* don't have to check universal table cause that was already up top */
554     AddUniversalInstance(GetUniversalTable(),type,INST(i));
555     }
556     i->desc = type;
557     return INST(i);
558     }
559    
560     static struct Instance *RefineSymbolAtom(struct SymbolAtomInstance *i,
561     struct TypeDescription *type)
562     {
563     register struct gl_list_t *tmp;
564     register struct SymbolAtomInstance *new;
565     assert(MoreRefined(type,i->desc)==type);
566     AssertMemory(i);
567     if (i->desc==type) return INST(i);
568     if (ShortCutMakeUniversalInstance(type)) return INST(i);
569     new = SYMA_INST(CreateSymbolInstance(type));
570     /* check value */
571     if (i->value!=NULL){
572     new->value = i->value;
573     }
574     /* move interface pointer */
575     new->interface_ptr = i->interface_ptr;
576     i->interface_ptr = NULL;
577     if (InterfaceNotify!=NULL)
578     (*InterfaceNotify)(new->interface_ptr,INST(i),INST(new));
579     /* fix cliques */
580     new->alike_ptr = i->alike_ptr;
581     i->alike_ptr = INST(i);
582     FixCliques(INST(i),INST(new));
583     tmp = new->parents;
584     new->parents = i->parents;
585     i->parents = tmp;
586     /* fix any when which points to this instance */
587     FixWhens(INST(i),INST(new));
588     /* check children values */
589     if (NumberChildren(INST(i))==NumberChildren(INST(new)))
590     CheckAtomValuesOne(SYMA_CHILD(i,0),SYMA_CHILD(new,0),
591     NumberChildren(INST(i)));
592     else
593     CheckAtomValuesTwo(INST(i),INST(new));
594     ReDirectParents(INST(i),INST(new));
595     /* fix universal stuff */
596     if (GetUniversalFlag(i->desc))
597     ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(new));
598     DestroyInstance(INST(i),NULL);
599     AssertMemory(new);
600     return INST(new);
601     }
602    
603     /*
604     * This function morphs the type and expands the bit list if the
605     * refined to type is a new UNIVERSAL or a non-UNIVERSAL type >
606     * the type of i. If the new type requires more children,
607     * i is realloc'd.
608     * If needed, adds the inst to the pending list again.
609     * Does not reinvoke the instantiator (which should be obvious).
610     *
611     * around UNIVERSAL an arginst !=NULL needs work. fix me.
612     */
613     static
614     struct Instance *RefineModel(struct ModelInstance *i,
615     struct TypeDescription *type,
616     struct ModelInstance *arginst)
617     {
618     struct TypeDescription *oldtype;
619     register unsigned long new_length,old_length;
620     register struct ModelInstance *result;
621     assert(MoreRefined(type,i->desc)==type);
622     AssertMemory(i);
623     AssertMemory(type);
624     if (i->desc==type) {
625     return INST(i);
626     }
627     /* we assume at this point that the sanity of the refinement
628     * move has been checked.
629     */
630     oldtype = i->desc;
631     /* pop i into pendings if needed */
632     new_length = gl_length(GetList(GetStatementList(type)));
633     if (new_length > BLength(i->executed)){
634     i->executed = ExpandFBList(i->executed,new_length);
635     if (!InstanceInList(INST(i))) {
636     /* i is necessarily a model instance at this point */
637     AddBelow(NULL,INST(i));
638     /* add PENDING model */
639     }
640     }
641     new_length = ChildListLen(GetChildList(type));
642     old_length = ChildListLen(GetChildList(i->desc));
643     if (new_length > old_length){
644     /* resize the instance */
645     result = MOD_INST(ascrealloc((char *)i,
646     (unsigned)sizeof(struct ModelInstance)+
647     (unsigned)new_length*
648     (unsigned)sizeof(struct Instance *)));
649     if (result!=i) {
650     /* if realloc moved the instance, need to update all connections to
651     * the instance from before it was refined to point at the new memory.
652     */
653     PendingInstanceRealloced(INST(i),INST(result)); /* change pending list */
654     if (InterfaceNotify!=NULL)
655     (*InterfaceNotify)(result->interface_ptr,INST(i),INST(result));
656     /* fix external relations variables */
657     FixExternalVars(INST(i),INST(result));
658     /* fix whens */
659     FixWhensForRefinement(INST(i),INST(result));
660     ReDirectParents(INST(i),INST(result));
661     ReDirectChildren(INST(i),INST(result));
662     /* fix cliques */
663     FixCliques(INST(i),INST(result));
664     /* fix universal stuff */
665     if (GetUniversalFlag(result->desc)) {
666     ChangeUniversalInstance(GetUniversalTable(),INST(i),INST(result));
667     }
668     }
669     /* init spaces of expanded instance to NULL */
670     ZeroNewChildrenEntries(MOD_CHILD(result,old_length),new_length-old_length);
671     ReorderChildrenPtrs(MOD_CHILD(result,0),
672     GetChildList(result->desc),
673     GetChildList(type),
674     old_length,
675     new_length);
676     result->desc = type;
677     ReConfigureInstFromArgs(INST(result),INST(arginst));
678     } else {
679     result = i;
680     result->desc = type;
681     }
682     /* add new universal type entry */
683     if (GetUniversalFlag(type)) {
684     AddUniversalInstance(GetUniversalTable(),type,INST(result));
685     }
686     /* fix the reference counts in the library */
687     DeleteTypeDesc(oldtype);
688     CopyTypeDesc(type);
689     AssertMemory(result);
690     return INST(result);
691     }
692    
693    
694     struct Instance *RefineInstance(struct Instance *i,
695     struct TypeDescription *type,
696     struct Instance *arginst)
697     {
698     struct TypeDescription *desc;
699     assert((i!=NULL)&&(type!=NULL));
700     AssertMemory(i);
701     /* oy, arginst will need some fancy footwork here. fix me */
702     if (GetUniversalFlag(type)&&
703     LookupInstance(GetUniversalTable(),type)){
704     desc = InstanceTypeDesc(i);
705     if (GetUniversalFlag(desc)){
706     ChangeUniversalInstance(GetUniversalTable(),
707     i,
708     LookupInstance(GetUniversalTable(),type));
709     }
710     i = MergeInstances(i,LookupInstance(GetUniversalTable(),type));
711     PostMergeCheck(i);
712     return i;
713     }
714     /* if the above if/Merge are not there, then bugs in the Refine<type>
715     * functions switched below will destroy type and memory integrity.
716     * See RefineRealAtom for details.
717     * No universal instance matching type both can and does exist .
718     */
719     switch(i->t) {
720     case MODEL_INST:
721     return RefineModel(MOD_INST(i),type,MOD_INST(arginst));
722     case REAL_ATOM_INST:
723     return RefineRealAtom(RA_INST(i),type);
724     case BOOLEAN_ATOM_INST:
725     return RefineBooleanAtom(BA_INST(i),type);
726     case INTEGER_ATOM_INST:
727     return RefineIntegerAtom(IA_INST(i),type);
728     case SET_ATOM_INST:
729     return RefineSet(SA_INST(i),type);
730     case SYMBOL_ATOM_INST:
731     return RefineSymbolAtom(SYMA_INST(i),type);
732     case REAL_CONSTANT_INST:
733     return RefineRealConstant(RC_INST(i),type);
734     case BOOLEAN_CONSTANT_INST:
735     return RefineBooleanConstant(BC_INST(i),type);
736     case INTEGER_CONSTANT_INST:
737     return RefineIntegerConstant(IC_INST(i),type);
738     case SYMBOL_CONSTANT_INST:
739     return RefineSymbolConstant(SYMC_INST(i),type);
740     case ARRAY_INT_INST:
741     case ARRAY_ENUM_INST:
742     case REL_INST:
743     case LREL_INST:
744     case WHEN_INST:
745     case SIM_INST:
746     /* at the current time these are meaningless */
747     Asc_Panic(2, NULL,
748     "At the current time these refining"
749     " an array,when or relation is undefined");
750     case REAL_INST:
751     case INTEGER_INST:
752     case BOOLEAN_INST:
753     case SET_INST:
754     case SYMBOL_INST:
755     case DUMMY_INST:
756     Asc_Panic(2, NULL,
757     "It is illegal to call RefineInstance on a fundamental atom.");
758     default:
759     Asc_Panic(2, NULL, "RefineInstance called on unknown instance type.\n");
760     }
761     exit(2);/* NOT REACHED. Needed to keep gcc from whining */
762     }
763    
764    
765     struct Instance *RefineClique(struct Instance *i,
766     struct TypeDescription *type,
767     struct Instance *arginst)
768     {
769     struct Instance *ptr;
770     AssertMemory(i);
771     /* assert that it is conformable and that type is more refined */
772     assert(MoreRefined(InstanceTypeDesc(i),type)==type);
773     if (arginst != NULL) {
774     assert(MoreRefined(InstanceTypeDesc(arginst),type)==type);
775     }
776     ptr = i = RefineInstance(i,type,arginst);
777     while ( (ptr = NextCliqueMember(ptr)) != i){
778     assert(ptr!=NULL);
779     ptr = RefineInstance(ptr,type,arginst);
780     }
781     return i;
782     }
783    

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