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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2018 - (show annotations) (download) (as text)
Wed Apr 29 03:38:10 2009 UTC (11 years, 2 months ago) by jpye
File MIME type: text/x-csrc
File size: 23548 byte(s)
Fixed compile for new header file locations <ascend/compiler/xxx.h> etc.
1 /*
2 * Ascend Instance Tree Search Implementation
3 * by Tom Epperly
4 * Created: 1/24/90
5 * Version: $Revision: 1.24 $
6 * Version control file: $RCSfile: find.c,v $
7 * Date last modified: $Date: 1998/03/26 20:39:44 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
13 *
14 * The Ascend Language Interpreter is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The Ascend Language Interpreter is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING.
28 *
29 */
30
31 #include <stdarg.h>
32 #include <math.h>
33 #include <ascend/utilities/ascConfig.h>
34 #include <ascend/utilities/ascMalloc.h>
35 #include <ascend/utilities/ascPanic.h>
36 #include <ascend/general/pool.h>
37 #include <ascend/general/list.h>
38 #include <ascend/general/dstring.h>
39
40 #include "symtab.h"
41 #include "functype.h"
42 #include "expr_types.h"
43 #include "child.h"
44 #include "type_desc.h"
45 #include "instance_enum.h"
46 #include "instance_name.h"
47 #include "instance_io.h"
48 #include "mathinst.h"
49 #include "name.h"
50 #include "nameio.h"
51 #include "evaluate.h"
52 #include "atomvalue.h"
53 #include "instquery.h"
54 #include "arrayinst.h"
55 #include "parentchild.h"
56 #include "value_type.h"
57 #include "forvars.h"
58 #include "setinstval.h"
59 #include "find.h"
60 #include "safe.h"
61 #include "relation_util.h"
62 #include "logical_relation.h"
63 #include "logrelation.h"
64 #include "logrel_util.h"
65
66
67 #define NAMELISTSIZE 20L
68 #define DEFTOLERANCE 1e-08
69
70 #ifndef lint
71 static CONST char FindRCSid[]="$Id: find.c,v 1.24 1998/03/26 20:39:44 ballan Exp $";
72 #endif /* lint */
73
74 CONST struct Instance *g_EvaluationContext=NULL;
75 struct for_table_t *g_EvaluationForTable=NULL;
76 int ListMode=0; /* 0 = set or normal mode; 1 = list mode */
77 int EvaluatingSets=0; /* 1 = in process of set evaluation */
78 int g_DeclarativeContext=0; /* 0 = declarative processing
79 * !0 = procedural processing.
80 */
81
82 int GetDeclarativeContextF()
83 {
84 return g_DeclarativeContext;
85 }
86
87 void SetDeclarativeContextF(int n,char *file,int line)
88 {
89 g_DeclarativeContext = n;
90 FPRINTF(ASCERR,"SDC=%d at %s:%d\n",n,file,line);
91 }
92
93
94 struct Instance *GetEvaluationContextF(void)
95 {
96 return (struct Instance *)g_EvaluationContext;
97 }
98 void SetEvaluationContextF(CONST struct Instance *i
99 #if (EVALDEBUG == 1 || EVALDEBUG == 3)
100 , char *file, int line
101 #endif
102 )
103 {
104 #if (EVALDEBUG == 1 || EVALDEBUG == 3)
105 FPRINTF(ASCERR,"setEvalContext:0x%p %s:%d\n",i,file,line);
106 #endif /*evaldebug*/
107 g_EvaluationContext = i;
108 }
109 struct for_table_t *GetEvaluationForTableF(void)
110 {
111 return g_EvaluationForTable;
112 }
113 void SetEvaluationForTableF(struct for_table_t *ft
114 #if (EVALDEBUG == 2 || EVALDEBUG == 3)
115 , char *file, int line
116 #endif
117 )
118 {
119 #if (EVALDEBUG == 2 || EVALDEBUG == 3)
120 FPRINTF(ASCERR,"setEvalForTable:0x%p %s:%d\n",ft,file,line);
121 #endif /* evaldebug */
122 g_EvaluationForTable = ft;
123 }
124
125 /*
126 * checks to see whether the integer atom or integer inst
127 * is a legal set index and bitches if not.
128 * as currently used, will always return errors when
129 * we are in the declarative section because ATOM i
130 * is _always_ mutable now that we have integer constants.
131 */
132 static int ProcessIntegersInSets(CONST struct Instance *i)
133 {
134 if (i!=NULL) {
135 if (AtomMutable(i)&&(GetDeclarativeContext()==0)){
136 FPRINTF(ASCERR, "Error: variable integer used as set index\n");
137 WriteInstanceName(ASCERR,i,NULL);
138 FPRINTF(ASCERR,"\n");
139 return 1;
140 }
141 else return 0;
142 }
143 return 2;
144 }
145
146 static struct gl_list_t *RealFindInstances(CONST struct Instance *i,
147 CONST struct Name *n,
148 enum find_errors *errval);
149
150 struct value_t InstanceEvaluateName(CONST struct Name *nptr)
151 {
152 struct gl_list_t *list;
153 struct Instance *inst;
154 struct value_t result;
155 unsigned long c,len;
156 enum find_errors errval;
157 struct for_var_t *ptr;
158 symchar *name;
159
160 if (GetEvaluationForTable()!=NULL){
161 /* check FOR vars list before user vars */
162 AssertMemory(GetEvaluationForTable());
163 if ((name = SimpleNameIdPtr(nptr))!=NULL){
164 if ((ptr = FindForVar(GetEvaluationForTable(),name))!=NULL){
165 switch(GetForKind(ptr)){
166 case f_integer:
167 return CreateIntegerValue(GetForInteger(ptr),1);
168 case f_symbol:
169 return CreateSymbolValue(GetForSymbol(ptr),1);
170 case f_set:
171 return CreateSetValue(CopySet(GetForSet(ptr)));
172 default:
173 FPRINTF(ASCERR,"Untyped for variable.\n");
174 return CreateErrorValue(undefined_value);
175 }
176 }
177 }
178 }
179 /* didn't find or bomb, so must be in user vars */
180 if (GetEvaluationContext()==NULL) return CreateErrorValue(incorrect_name);
181 AssertMemory(GetEvaluationContext());
182 list = RealFindInstances(GetEvaluationContext(),nptr,&errval);
183 if (list==NULL){
184 assert(errval!=correct_instance);
185 switch(errval){
186 case unmade_instance:
187 return CreateErrorValue(name_unfound);
188 case undefined_instance:
189 return CreateErrorValue(undefined_value);
190 case impossible_instance:
191 return CreateErrorValue(incorrect_name);
192 default: /*NOTREACHED*/
193 break;
194 }
195 /*NOTREACHED*/
196 } else{
197 /* found user's variable */
198 AssertMemory(list);
199 if (gl_length(list)==1){
200 inst = (struct Instance *)gl_fetch(list,1);
201 AssertMemory(inst);
202 gl_destroy(list);
203 switch(InstanceKind(inst)){
204 case REAL_INST:
205 case REAL_ATOM_INST:
206 case REAL_CONSTANT_INST:
207 if (AtomAssigned(inst)) {
208 return CreateRealValue(RealAtomValue(inst),RealAtomDims(inst),
209 IsConstantInstance(inst));
210 } else {
211 return CreateErrorValue(undefined_value);
212 }
213 case BOOLEAN_INST:
214 case BOOLEAN_ATOM_INST:
215 case BOOLEAN_CONSTANT_INST:
216 if (AtomAssigned(inst)) {
217 return CreateBooleanValue(GetBooleanAtomValue(inst),
218 IsConstantInstance(inst));
219 } else {
220 return CreateErrorValue(undefined_value);
221 }
222 case INTEGER_CONSTANT_INST:
223 if (inst !=NULL && AtomAssigned(inst)) {
224 return CreateIntegerValue(GetIntegerAtomValue(inst),1);
225 } else {
226 return CreateErrorValue(undefined_value);
227 }
228 case INTEGER_ATOM_INST:
229 case INTEGER_INST:
230 if (EvaluatingSets){
231 int piis;
232 piis = ProcessIntegersInSets(inst);
233 if(piis==1) {
234 return CreateErrorValue(type_conflict);
235 }
236 if(piis==2) {
237 return CreateErrorValue(incorrect_name);
238 }
239 }
240 if (AtomAssigned(inst)) {
241 return CreateIntegerValue(GetIntegerAtomValue(inst),0);
242 } else {
243 return CreateErrorValue(undefined_value);
244 }
245 case SET_ATOM_INST:
246 if (ListMode) {
247 /* more kaa-ism. client should be checking this. not us. */
248 FPRINTF(ASCERR,"Set atoms are not allowed in lists! (ListMode==1)\n");
249 return CreateErrorValue(illegal_set_use);
250 }
251 if (AtomAssigned(inst)) {
252 return CreateSetValue(CopySet(SetAtomList(inst)));
253 } else {
254 return CreateErrorValue(undefined_value);
255 }
256 case SYMBOL_INST:
257 case SYMBOL_ATOM_INST:
258 case SYMBOL_CONSTANT_INST:
259 if (AtomAssigned(inst)) {
260 return CreateSymbolValue(GetSymbolAtomValue(inst),
261 IsConstantInstance(inst));
262 } else {
263 return CreateErrorValue(undefined_value);
264 }
265 case SET_INST:
266 if (ListMode) {
267 /* more kaa-ism. client should be checking this. not us. */
268 FPRINTF(ASCERR,"Sets instances are not allowed in lists! (ListMode==1)\n");
269 return CreateErrorValue(illegal_set_use);
270 }
271 if (AtomAssigned(inst)) {
272 return CreateSetValue(CopySet(SetAtomList(inst)));
273 } else {
274 return CreateErrorValue(undefined_value);
275 }
276 default:
277 return CreateErrorValue(incorrect_name);
278 }
279 } else {
280 /* BUG BAA this block may be incorrect. what is it? Looks like kaaism*/
281 if (GetDeclarativeContext()==0) {
282 /* find out if this is ever called in instantiation */
283 FPRINTF(ASCERR,"BAA debug: please tell ballan@cs.cmu.edu you saw:\n");
284 WriteName(ASCERR,nptr);
285 FPRINTF(ASCERR,"\nin compiling what MODEL.\n");
286 }
287 result = CreateEmptyListValue();
288 len = gl_length(list);
289 for(c=1; c<=len; c++){
290 inst = (struct Instance *)gl_fetch(list,c);
291 AssertMemory(inst);
292 /* Don't know why only integers should be valid in lists.
293 * He who introduces crap should at least be complete about it.
294 * Somewhere there's probably a client not doing proper checking
295 * trying to pawn it off on us to do here. That client is now broken.
296 */
297 #define OLDCRAP 0
298 #if OLDCRAP /* integer only */
299 switch(InstanceKind(inst)) {
300 case INTEGER_ATOM_INST:
301 if (AtomAssigned(inst)) {
302 AppendToListValue(result,
303 CreateIntegerValue(GetIntegerAtomValue(inst),
304 IsConstantInstance(inst)));
305 } else {
306 return CreateErrorValue(undefined_value);
307 }
308 break;
309 case SET_ATOM_INST:
310 case SYMBOL_ATOM_INST:
311 case INTEGER_INST:
312 case SET_INST:
313 case SYMBOL_INST:
314 default:
315 gl_destroy(list);
316 DestroyValue(&result);
317 return CreateErrorValue(incorrect_name);
318 }
319 #else
320 /* extended oldcrap to include this. baa. 3/98 */
321 switch(InstanceKind(inst)) {
322 case REAL_ATOM_INST:
323 case REAL_CONSTANT_INST:
324 if (AtomAssigned(inst)) {
325 AppendToListValue(result,
326 CreateRealValue(RealAtomValue(inst),
327 RealAtomDims(inst),
328 IsConstantInstance(inst)));
329 } else {
330 return CreateErrorValue(undefined_value);
331 }
332 break;
333 case INTEGER_ATOM_INST:
334 case INTEGER_CONSTANT_INST:
335 if (AtomAssigned(inst)) {
336 AppendToListValue(result,
337 CreateIntegerValue(GetIntegerAtomValue(inst),
338 IsConstantInstance(inst)));
339 } else {
340 return CreateErrorValue(undefined_value);
341 }
342 break;
343 case SET_ATOM_INST:
344 if (AtomAssigned(inst)) {
345 AppendToListValue(result,
346 CreateSetValue(CopySet(SetAtomList(inst))));
347 } else {
348 return CreateErrorValue(undefined_value);
349 }
350 break;
351 case SYMBOL_ATOM_INST:
352 case SYMBOL_CONSTANT_INST:
353 if (AtomAssigned(inst)) {
354 AppendToListValue(result,
355 CreateSymbolValue(GetSymbolAtomValue(inst),
356 IsConstantInstance(inst)));
357 } else {
358 return CreateErrorValue(undefined_value);
359 }
360 break;
361 /* ok, we will uniformly reject lists of subatomics, though
362 * it is arbitrary and inconsistent to do so.
363 */
364 case INTEGER_INST:
365 case SET_INST:
366 case SYMBOL_INST:
367 default:
368 gl_destroy(list);
369 DestroyValue(&result);
370 return CreateErrorValue(incorrect_name);
371 }
372 #endif
373 }
374 gl_destroy(list);
375 return result;
376 }
377 }
378 /* we need to verify that this is not reached */
379 FPRINTF(ASCERR,"InstanceEvaluateName returning unexpectedly\n");
380 return CreateErrorValue(incorrect_name);
381 }
382
383
384
385 /* Specially to evaluate name of relations, logrelations in SATISFIED
386 * expressions
387 */
388 struct value_t InstanceEvaluateSatisfiedName(CONST struct Name *nptr,
389 double tol)
390 {
391 struct gl_list_t *list;
392 struct Instance *inst;
393 enum find_errors errval;
394 struct for_var_t *ptr;
395 symchar *name;
396 CONST struct relation *rel;
397 enum Expr_enum relop;
398 enum safe_err status = safe_ok;
399 double res;
400 int logres;
401
402 if (GetEvaluationForTable()!=NULL){
403 AssertMemory(GetEvaluationForTable());
404 if ((name = SimpleNameIdPtr(nptr))!=NULL){
405 if ((ptr = FindForVar(GetEvaluationForTable(),name))!=NULL){
406 switch(GetForKind(ptr)){
407 case f_integer:
408 return CreateIntegerValue(GetForInteger(ptr),1);
409 case f_symbol:
410 return CreateSymbolValue(GetForSymbol(ptr),1);
411 case f_set:
412 return CreateSetValue(CopySet(GetForSet(ptr)));
413 default:
414 FPRINTF(ASCERR,"Untyped for variable.\n");
415 return CreateErrorValue(undefined_value);
416 }
417 }
418 }
419 }
420 if (GetEvaluationContext()==NULL) return CreateErrorValue(incorrect_name);
421 AssertMemory(GetEvaluationContext());
422 list = RealFindInstances(GetEvaluationContext(),nptr,&errval);
423 if (list==NULL){
424 assert(errval!=correct_instance);
425 switch(errval){
426 case unmade_instance:
427 return CreateErrorValue(name_unfound);
428 case undefined_instance:
429 return CreateErrorValue(undefined_value);
430 case impossible_instance:
431 return CreateErrorValue(incorrect_name);
432 default: /*NOTREACHED*/
433 break;
434 }
435 /*NOTREACHED*/
436 }
437 else{
438 AssertMemory(list);
439 if (gl_length(list)==1){
440 inst = (struct Instance *)gl_fetch(list,1);
441 AssertMemory(inst);
442 gl_destroy(list);
443 switch(InstanceKind(inst)){
444 case REL_INST:
445 status = RelationCalcResidualPostfixSafe(inst,&res);
446 if (status != safe_ok) {
447 FPRINTF(ASCERR,
448 "Something wrong while calculating a residual in Sat Expr\n");
449 return CreateErrorValue(undefined_value);
450 }
451 rel = GetInstanceRelationOnly(inst);
452 relop = RelationRelop(rel);
453 switch(relop) {
454 case e_equal:
455 if (tol != DBL_MAX) {
456 if(fabs(tol)>fabs(res)) {
457 return CreateBooleanValue(1,0);
458 }
459 else {
460 return CreateBooleanValue(0,0);
461 }
462 }
463 else {
464 if((DEFTOLERANCE)>fabs(res)) {
465 return CreateBooleanValue(1,0);
466 }
467 else {
468 return CreateBooleanValue(0,0);
469 }
470 }
471 case e_notequal:
472 if (tol != DBL_MAX) {
473 if(fabs(tol)>fabs(res)) {
474 return CreateBooleanValue(0,0);
475 }
476 else {
477 return CreateBooleanValue(1,0);
478 }
479 }
480 else {
481 if((DEFTOLERANCE)>fabs(res)) {
482 return CreateBooleanValue(0,0);
483 }
484 else {
485 return CreateBooleanValue(1,0);
486 }
487 }
488 case e_greater:
489 if (tol != DBL_MAX) {
490 if(fabs(tol)<res) {
491 return CreateBooleanValue(1,0);
492 }
493 else {
494 return CreateBooleanValue(0,0);
495 }
496 }
497 else {
498 if((DEFTOLERANCE)<res) {
499 return CreateBooleanValue(1,0);
500 }
501 else {
502 return CreateBooleanValue(0,0);
503 }
504 }
505 case e_greatereq:
506 if (tol != DBL_MAX) {
507 if(-fabs(tol)<res) {
508 return CreateBooleanValue(1,0);
509 }
510 else {
511 return CreateBooleanValue(0,0);
512 }
513 }
514 else {
515 if(-(DEFTOLERANCE)<res) {
516 return CreateBooleanValue(1,0);
517 }
518 else {
519 return CreateBooleanValue(0,0);
520 }
521 }
522 case e_less:
523 if (tol != DBL_MAX) {
524 if(-fabs(tol)>res) {
525 return CreateBooleanValue(1,0);
526 }
527 else {
528 return CreateBooleanValue(0,0);
529 }
530 }
531 else {
532 if(-(DEFTOLERANCE)>res) {
533 return CreateBooleanValue(1,0);
534 }
535 else {
536 return CreateBooleanValue(0,0);
537 }
538 }
539 case e_lesseq:
540 if (tol != DBL_MAX) {
541 if(fabs(tol)>res) {
542 return CreateBooleanValue(1,0);
543 }
544 else {
545 return CreateBooleanValue(0,0);
546 }
547 }
548 else {
549 if((DEFTOLERANCE)>res) {
550 return CreateBooleanValue(1,0);
551 }
552 else {
553 return CreateBooleanValue(0,0);
554 }
555 }
556 default:
557 FPRINTF(ASCERR,
558 "Something wrong while calculating a residual in Sat Expr\n");
559 return CreateErrorValue(incorrect_name);
560 }
561 case LREL_INST:
562 if (LogRelCalcResidual(inst,&logres)) {
563 FPRINTF(ASCERR,
564 "Something wrong while calculating a log residual in Sat Expr\n");
565 return CreateErrorValue(undefined_value);
566 }
567 return CreateBooleanValue(logres,0);
568 default:
569 return CreateErrorValue(incorrect_name);
570 }
571 }
572 else {
573 FPRINTF(ASCERR,"InstanceEvaluateSatisfiedName returning unexpectedly\n");
574 gl_destroy(list);
575 return CreateErrorValue(undefined_value);
576 }
577 }
578 /* we need to verify that this is not reached */
579 FPRINTF(ASCERR,"InstanceEvaluateSatisfiedName returning unexpectedly\n");
580 return CreateErrorValue(incorrect_name);
581 }
582
583
584 static struct gl_list_t *FindArrayChildren(struct gl_list_t *list,
585 CONST struct set_t *sptr,
586 enum find_errors *errval)
587 {
588 struct gl_list_t *result;
589 struct Instance *i,*child;
590 struct InstanceName rec;
591 struct TypeDescription *desc;
592 unsigned long c1,len1,c2,len2,pos;
593 switch(SetKind(sptr)){
594 case empty_set: return gl_create(0);
595 case string_set:
596 SetInstanceNameType(rec,StrArrayIndex);
597 len2 = Cardinality(sptr);
598 len1 = gl_length(list);
599 result = gl_create(len1*len2);
600 for(c1=1; c1<=len1; c1++){
601 i = (struct Instance *)gl_fetch(list,c1);
602 if (InstanceKind(i)==ARRAY_ENUM_INST){
603 if (NextToExpand(i)!=1){
604 for(c2=1; c2<=len2; c2++){
605 SetInstanceNameStrIndex(rec,FetchStrMember(sptr,c2));
606 if ((pos = ChildSearch(i,&rec))==0){
607 gl_destroy(result);
608 desc = InstanceTypeDesc(i);
609 if ( GetArrayBaseIsRelation(desc) || GetArrayBaseIsLogRel(desc)){
610 *errval = unmade_instance;
611 } else {
612 *errval = impossible_instance;
613 }
614 return NULL;
615 } else {
616 child = InstanceChild(i,pos);
617 if (child!=NULL){
618 gl_append_ptr(result,(VOIDPTR)child);
619 } else {
620 gl_destroy(result);
621 *errval = unmade_instance;
622 return NULL;
623 }
624 }
625 }
626 } else {
627 gl_destroy(result);
628 *errval = unmade_instance;
629 return NULL;
630 }
631 } else {
632 gl_destroy(result);
633 *errval = impossible_instance;
634 return NULL;
635 }
636 }
637 return result;
638 case integer_set:
639 SetInstanceNameType(rec,IntArrayIndex);
640 len2 = Cardinality(sptr);
641 len1 = gl_length(list);
642 result = gl_create(len1*len2);
643 for(c1=1; c1<=len1; c1++){
644 i = (struct Instance *)gl_fetch(list,c1);
645 if (InstanceKind(i)==ARRAY_INT_INST){
646 if (NextToExpand(i)!=1){
647 for (c2=1; c2<=len2; c2++){
648 SetInstanceNameIntIndex(rec,FetchIntMember(sptr,c2));
649 if ((pos = ChildSearch(i,&rec))==0){
650 gl_destroy(result);
651 desc = InstanceTypeDesc(i);
652 if (GetArrayBaseIsRelation(desc) || GetArrayBaseIsLogRel(desc)) {
653 *errval = unmade_instance;
654 } else {
655 *errval = impossible_instance;
656 }
657 return NULL;
658 } else {
659 child = InstanceChild(i,pos);
660 if (child!=NULL){
661 gl_append_ptr(result,(VOIDPTR)child);
662 } else{
663 gl_destroy(result);
664 *errval = unmade_instance;
665 return NULL;
666 }
667 }
668 }
669 } else {
670 gl_destroy(result);
671 *errval = unmade_instance;
672 return NULL;
673 }
674 } else {
675 gl_destroy(result);
676 *errval = impossible_instance;
677 return NULL;
678 }
679 }
680 return result;
681 }
682 /*NOTREACHED*/
683 return NULL;
684 }
685
686 static
687 struct gl_list_t *FindNextNameElement(CONST struct Name *n,
688 struct gl_list_t *list,
689 enum find_errors *errval)
690 {
691 unsigned long pos,c,len;
692 struct InstanceName rec;
693 struct Instance *current,*child;
694 struct value_t setvalue,oldvalue;
695 CONST struct Set *sptr;
696 struct gl_list_t *result;
697
698 *errval = correct_instance;
699 if (NameId(n)){
700 result = gl_create(NAMELISTSIZE);
701 SetInstanceNameType(rec,StrName);
702 SetInstanceNameStrPtr(rec,NameIdPtr(n));
703 len = gl_length(list);
704 for(c=1; c<=len; c++){
705 current = (struct Instance *)gl_fetch(list,c);
706 pos = ChildSearch(current,&rec);
707 if (pos!=0){
708 child = InstanceChild(current,pos);
709 if (child!=NULL){
710 gl_append_ptr(result,(VOIDPTR)child);
711 } else{
712 *errval = unmade_instance;
713 gl_destroy(result);
714 return NULL;
715 }
716 } else{
717 *errval = unmade_instance;
718 /* it would seem this ought to be undefined_instance,
719 * but maybe refinement causes insanity. -- in which case
720 * it should be a caller policy to wait, rather than our
721 * job to anticipate policy and short circuit things here.
722 */
723 gl_destroy(result);
724 return NULL;
725 }
726 }
727 return result;
728 } else {
729 sptr = NameSetPtr(n);
730 setvalue = EvaluateSet(sptr,InstanceEvaluateName);
731 switch(ValueKind(setvalue)){
732 case integer_value:
733 case symbol_value:
734 case list_value:
735 oldvalue = setvalue;
736 if (ListMode) {
737 setvalue = CreateOrderedSetFromList(oldvalue);
738 } else {
739 setvalue = CreateSetFromList(oldvalue);
740 }
741 DestroyValue(&oldvalue);
742 /* intended to fall through to next case */
743 case set_value:
744 result = FindArrayChildren(list,SetValue(setvalue),errval);
745 DestroyValue(&setvalue);
746 return result;
747 case error_value:
748 switch(ErrorValue(setvalue)){
749 case illegal_set_use:
750 *errval = impossible_instance;
751 break;
752 default:
753 *errval = undefined_instance;
754 break;
755 /* more needs to be added here */
756 }
757 DestroyValue(&setvalue);
758 return NULL;
759 default:
760 ASC_PANIC("Need to add to FindNextNameElement.\n");
761
762 }
763 }
764 }
765
766 static
767 struct gl_list_t *RealFindInstances(CONST struct Instance *i,
768 CONST struct Name *n,
769 enum find_errors *errval)
770 {
771 struct gl_list_t *result,*next;
772 result = gl_create(NAMELISTSIZE);
773 gl_append_ptr(result,(VOIDPTR)i);
774 while(n!=NULL){
775 next = FindNextNameElement(n,result,errval);
776 gl_destroy(result);
777 if (next!=NULL){
778 result = next;
779 n = NextName(n);
780 } else {
781 return NULL;
782 }
783 }
784 return result;
785 }
786
787 struct gl_list_t *FindInstances(CONST struct Instance *i,
788 CONST struct Name *n,
789 enum find_errors *errval)
790 {
791 struct gl_list_t *result;
792 *errval = impossible_instance;
793 if (i == NULL) return NULL;
794 AssertMemory(i);
795 assert(GetEvaluationContext()==NULL);
796 SetEvaluationContext(i);
797 *errval = correct_instance;
798 result = RealFindInstances(i,n,errval);
799 SetEvaluationContext(NULL);
800 return result;
801 }
802
803 struct gl_list_t *FindInstancesFromNames(CONST struct Instance *i,
804 CONST struct gl_list_t *names,
805 enum find_errors *err,
806 unsigned long *errpos)
807 {
808 unsigned long pos, len;
809 struct gl_list_t *result, *tmp;
810 struct Name *n;
811
812 *errpos = 0;
813 len = gl_length(names);
814 if (len == 0) {
815 *err = correct_instance;
816 return NULL;
817 }
818 result = gl_create(len);
819 for (pos = 1; pos <= len; pos++) {
820 n = (struct Name *)gl_fetch(names,pos);
821 if (n == NULL) {
822 gl_destroy(result);
823 *err = impossible_instance;
824 *errpos = pos;
825 return NULL;
826 }
827 tmp = FindInstances(i,n,err);
828 if (tmp == NULL) {
829 gl_destroy(result);
830 *errpos = pos;
831 return NULL;
832 }
833 if (gl_length(tmp) != 1) {
834 gl_destroy(tmp);
835 gl_destroy(result);
836 *err = impossible_instance;
837 *errpos = pos;
838 return NULL;
839 }
840 gl_append_ptr(result,gl_fetch(tmp,1));
841 gl_destroy(tmp);
842 }
843
844 return result;
845 }

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