/[ascend]/trunk/base/generic/solver/cond_config.c
ViewVC logotype

Contents of /trunk/base/generic/solver/cond_config.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 669 - (show annotations) (download) (as text)
Wed Jun 21 07:00:45 2006 UTC (17 years, 3 months ago) by johnpye
File MIME type: text/x-csrc
File size: 56231 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 /*
2 * Conditional Modeling Configuration
3 * by Vicente Rico-Ramirez
4 * Created: 04/97
5 * Version: $Revision: 1.11 $
6 * Version control file: $RCSfile: cond_config.c,v $
7 * Date last modified: $Date: 2000/01/25 02:26:51 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the SLV solver.
11 *
12 * The SLV solver is free software; you can redistribute
13 * it and/or modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * The SLV solver is distributed in hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with the program; if not, write to the Free Software Foundation,
24 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
25 * COPYING. COPYING is found in ../compiler.
26 *
27 */
28 #include <stdarg.h>
29 #include <utilities/ascConfig.h>
30 #include <utilities/ascPanic.h>
31 #include <utilities/ascMalloc.h>
32 #include <compiler/compiler.h>
33 #include <compiler/instance_enum.h>
34 #include <compiler/check.h>
35 #include <general/list.h>
36 #include <general/dstring.h>
37 #include <general/tm_time.h>
38 #include "mtx.h"
39 #include "slv_types.h"
40 #include "var.h"
41 #include "discrete.h"
42 #include "conditional.h"
43 #include "linsolqr.h"
44 #define _SLV_SERVER_C_SEEN_
45 #include <compiler/extcall.h>
46 #include "rel.h"
47 #include "logrel.h"
48 #include "bnd.h"
49 #include "slv_server.h"
50 #include "system.h"
51 #include "analyze.h"
52 #include "cond_config.h"
53 #include "linsol.h"
54 #include "slv_common.h"
55 #include "slv_client.h"
56
57 #define IPTR(i) ((struct Instance *) (i))
58 #define USEDCODE 0
59 #define DEBUG FALSE
60 #define CASE_NUMBER FALSE
61 #define DEBUG_PRE_ANALYSIS FALSE
62
63 /*
64 * Configuration of Conditional Models
65 */
66
67
68 /*
69 * structure dynamically allocated/reallocated to store the number of
70 * matched cases in a list of when statements
71 */
72
73 struct ds_case_list {
74 int32 length,capacity;
75 int32 *case_number;
76 };
77
78 /*
79 * forward declarations
80 */
81 void analyze_when(struct w_when *);
82 static void simplified_analyze_when(struct w_when *);
83 static void cases_matching_in_when_list(struct gl_list_t *,
84 struct ds_case_list *,
85 int32 *);
86 /*
87 * global variable for finding the number of cases in a when and
88 * enumerating the cases
89 */
90 static int32 g_case_number = 0;
91
92 /*
93 * Set the ACTIVE bit to value for all the relations
94 * included in the case
95 */
96 static void set_rels_status_in_case(struct when_case *cur_case,
97 uint32 value)
98 {
99 struct gl_list_t *rels;
100 struct rel_relation *rel;
101 int32 r,rlen;
102
103 rels = when_case_rels_list(cur_case);
104 rlen = gl_length(rels);
105 for(r=1;r<=rlen;r++) {
106 rel = (struct rel_relation *)(gl_fetch(rels,r));
107 rel_set_active(rel,value);
108 }
109 }
110
111
112 /*
113 * Set the ACTIVE bit to value for all the logrelations
114 * included in the case
115 */
116 static void set_logrels_status_in_case(struct when_case *cur_case,
117 uint32 value)
118 {
119 struct gl_list_t *logrels;
120 struct logrel_relation *lrel;
121 int32 lr,lrlen;
122
123 logrels = when_case_logrels_list(cur_case);
124 if (logrels==NULL) return;
125 lrlen = gl_length(logrels);
126 for(lr=1;lr<=lrlen;lr++) {
127 lrel = (struct logrel_relation *)(gl_fetch(logrels,lr));
128 logrel_set_active(lrel,value);
129 }
130 }
131
132 /*
133 * Set the ACTIVE bit to value for all the relations and logrelations
134 * included in a when (implicitly or explcitly).
135 */
136 void set_rels_status_in_when(struct w_when *when, uint32 value)
137 {
138 struct gl_list_t *cases;
139 struct gl_list_t *whens;
140 struct w_when *nested_when;
141 struct when_case *cur_case;
142 int32 c,clen,w,wlen;
143
144 cases = when_cases_list(when);
145 clen = gl_length(cases);
146 for (c=1;c<=clen;c++){
147 cur_case = (struct when_case *)(gl_fetch(cases,c));
148 when_case_set_active(cur_case,value);
149 set_rels_status_in_case(cur_case,value);
150 set_logrels_status_in_case(cur_case,value);
151 whens = when_case_whens_list(cur_case);
152 wlen = gl_length(whens); /* nested whens */
153 for (w=1;w<=wlen;w++){
154 nested_when = (struct w_when *)(gl_fetch(whens,w));
155 set_rels_status_in_when(nested_when,value); /* recursion */
156 }
157 }
158 }
159
160
161 /*
162 * After a case is found to apply for the current values of the
163 * conditional variables, the rel_relations and logrel_relations
164 * in such a case are set ACTIVE.
165 * If a WHEN is found in a CASE, the analysis of the WHEN is done
166 * recursively.
167 */
168
169 static void apply_case(struct when_case *cur_case)
170 {
171 struct gl_list_t *rels;
172 struct gl_list_t *logrels;
173 struct gl_list_t *whens;
174 struct rel_relation *rel;
175 struct logrel_relation *lrel;
176 struct w_when *when;
177 int32 r,rlen,w,wlen,lr,lrlen;
178
179 rels = when_case_rels_list(cur_case);
180 if (rels != NULL) {
181 rlen = gl_length(rels);
182 for(r=1;r<=rlen;r++) {
183 rel = (struct rel_relation *)(gl_fetch(rels,r));
184 rel_set_active(rel,TRUE);
185 }
186 }
187 logrels = when_case_logrels_list(cur_case);
188 if (logrels != NULL) {
189 lrlen = gl_length(logrels);
190 for(lr=1;lr<=lrlen;lr++) {
191 lrel = (struct logrel_relation *)(gl_fetch(logrels,lr));
192 logrel_set_active(lrel,TRUE);
193 }
194 }
195 whens = when_case_whens_list(cur_case);
196 if (whens != NULL) {
197 wlen = gl_length(whens);
198 for(w=1;w<=wlen;w++) {
199 when = (struct w_when *)(gl_fetch(whens,w));
200 analyze_when(when);
201 }
202 }
203 }
204
205 /*
206 * Compare current values of the conditional variables with
207 * the set of values in a CASE, and try to find is such
208 * values are the same. If they are, then the previous function
209 * is called.
210 */
211
212
213 static int32 analyze_case(struct when_case *cur_case,
214 struct gl_list_t *dvars)
215 {
216
217 struct dis_discrete *dvar;
218 int32 d,dlen;
219 int32 values[MAX_VAR_IN_LIST];
220 int32 *value;
221 int32 *case_values,index;
222
223 value = &(values[0]);
224 case_values = when_case_values_list(cur_case);
225 for(index =0; index<MAX_VAR_IN_LIST; index++) {
226 *value = *case_values;
227 value++;
228 case_values++;
229 }
230 dlen = gl_length(dvars);
231 for (d=1;d<=dlen;d++) {
232 dvar = (struct dis_discrete *)(gl_fetch(dvars,d));
233 if ( (values[d-1]!= -2) && (values[d-1]!= dis_value(dvar)) ) {
234 return 0;
235 }
236 }
237 apply_case(cur_case);
238 when_case_set_active(cur_case,TRUE); /* Case active */
239 return 1;
240 }
241
242
243 /*
244 * This function will determine which case of a WHEN statement
245 * applies for the current values of the conditional variables.
246 * The relations in that case are set ACTIVE
247 */
248
249 void analyze_when(struct w_when *when)
250 {
251 struct gl_list_t *dvars;
252 struct gl_list_t *cases;
253 int32 values[MAX_VAR_IN_LIST];
254 struct when_case *cur_case;
255 int32 c,clen;
256 int32 case_match;
257 int32 *value;
258 int32 *case_values;
259
260 dvars = when_dvars_list(when);
261 cases = when_cases_list(when);
262 clen = gl_length(cases);
263 case_match =0;
264 for (c=1;c<=clen;c++){
265 if(case_match==1){
266 break;
267 }
268 cur_case = (struct when_case *)(gl_fetch(cases,c));
269 value = &(values[0]);
270 case_values = when_case_values_list(cur_case);
271 *value = *case_values;
272 if (values[0]!=-1) {
273 case_match = analyze_case(cur_case,dvars);
274 } else {
275 if (case_match==0) {
276 apply_case(cur_case);
277 when_case_set_active(cur_case,TRUE); /* Otherwise case active */
278 case_match = 1;
279 }
280 }
281 }
282 if (case_match == 0) {
283 FPRINTF(ASCERR,"No case matched in when\n");
284 }
285 }
286
287
288 /*
289 * Simplified functions.
290 * The following functions also perform the analysis of a WHEN structure,
291 * but it only set ACTIVE/INACTIVE those CASEs included in the WHENs, they
292 * do not mess up with relations or logrels. It's a shorthand of the analysis
293 * while finding the different subregions that have to be analyzed when the
294 * iteration solution scheme of a conditional model hits a boundary. We
295 * can use the previous functions, but we would be doing extra work.
296 *
297 */
298
299
300 /*
301 * Set as Inactive all of cases found in a w_when.
302 */
303 static void disactive_cases_in_when(struct w_when *when)
304 {
305 struct gl_list_t *cases;
306 struct gl_list_t *case_whens;
307 struct when_case *cur_case;
308 struct w_when *cur_when;
309 int32 c,clen,w,wlen;
310
311 cases = when_cases_list(when);
312 if (cases == NULL) return;
313 clen = gl_length(cases);
314 for (c=1;c<=clen;c++){
315 cur_case = (struct when_case *)(gl_fetch(cases,c));
316 when_case_set_active(cur_case,FALSE); /* Case not active */
317 case_whens = when_case_whens_list(cur_case);
318 if (case_whens != NULL) {
319 wlen = gl_length(case_whens);
320 for (w=1;w<=wlen;w++) {
321 cur_when = (struct w_when *)(gl_fetch(case_whens,w));
322 disactive_cases_in_when(cur_when);
323 }
324 }
325 }
326 }
327
328 /* After a case is found to apply for the current values of the
329 * conditional variables, it checks for nested WHENs inside the CASE.
330 * If a WHEN is found in a CASE, the analysis of the WHEN is done
331 * recursively.
332 */
333
334 static void simplified_apply_case(struct when_case *cur_case)
335 {
336
337 struct gl_list_t *whens;
338 struct w_when *when;
339 int32 w,wlen;
340
341 whens = when_case_whens_list(cur_case);
342 if (whens != NULL) {
343 wlen = gl_length(whens);
344 for(w=1;w<=wlen;w++) {
345 when = (struct w_when *)(gl_fetch(whens,w));
346 simplified_analyze_when(when);
347 }
348 }
349 }
350
351
352 /*
353 * Compare current values of the conditional variables with
354 * the set of values in a CASE, and try to find is such
355 * values are the same. If they are, then the previous function
356 * is called.
357 */
358 static int32 simplified_analyze_case(struct when_case *cur_case,
359 struct gl_list_t *dvars)
360 {
361
362 struct dis_discrete *dvar;
363 int32 d,dlen;
364 int32 values[MAX_VAR_IN_LIST];
365 int32 *value;
366 int32 *case_values,index;
367
368 value = &(values[0]);
369 case_values = when_case_values_list(cur_case);
370 for(index =0; index<MAX_VAR_IN_LIST; index++) {
371 *value = *case_values;
372 value++;
373 case_values++;
374 }
375 dlen = gl_length(dvars);
376 for (d=1;d<=dlen;d++) {
377 dvar = (struct dis_discrete *)(gl_fetch(dvars,d));
378 if ( (values[d-1]!= -2) && (values[d-1]!= dis_value(dvar)) ) {
379 return 0;
380 }
381 }
382 simplified_apply_case(cur_case);
383 when_case_set_active(cur_case,TRUE); /* Case active */
384 return 1;
385 }
386
387
388 /*
389 * This function will determine which case of a WHEN statement
390 * applies for the current values of the conditional variables.
391 * That case will be set ACTIVE
392 */
393
394 static void simplified_analyze_when(struct w_when *when)
395 {
396 struct gl_list_t *dvars;
397 struct gl_list_t *cases;
398 int32 values[MAX_VAR_IN_LIST];
399 struct when_case *cur_case;
400 int32 c,clen;
401 int32 case_match;
402 int32 *value;
403 int32 *case_values;
404
405 dvars = when_dvars_list(when);
406 cases = when_cases_list(when);
407 clen = gl_length(cases);
408 case_match =0;
409 for (c=1;c<=clen;c++){
410 if(case_match==1){
411 break;
412 }
413 cur_case = (struct when_case *)(gl_fetch(cases,c));
414 value = &(values[0]);
415 case_values = when_case_values_list(cur_case);
416 *value = *case_values;
417 if (values[0]!=-1) {
418 case_match = simplified_analyze_case(cur_case,dvars);
419 } else {
420 if (case_match==0) {
421 simplified_apply_case(cur_case);
422 when_case_set_active(cur_case,TRUE); /* Otherwise case active */
423 case_match = 1;
424 }
425 }
426 }
427 if (case_match == 0) {
428 FPRINTF(ASCERR,"No case matched in when\n");
429 }
430 }
431
432
433
434 /*
435 * Set the ACTIVE bit to TRUE for all the rels included in the
436 * rel list.
437 */
438 void set_active_rels_in_list(struct rel_relation **rlist)
439 {
440 int32 c;
441 struct rel_relation *rel;
442
443 for (c = 0; rlist[c]!= NULL; c++) {
444 rel = rlist[c];
445 rel_set_active(rel,TRUE);
446 }
447 }
448
449 /*
450 * Sets the INVARIANT bit to TRUE for all the rels in the rel list which
451 * are ACTIVE and INCLUDED AND EUQALITY. Sets it to FALSE otherwise
452 */
453 void set_active_rels_as_invariant(struct rel_relation **rlist)
454 {
455 int32 c;
456 struct rel_relation *rel;
457
458 for (c = 0; rlist[c]!= NULL; c++) {
459 rel = rlist[c];
460 if (rel_active(rel) && rel_included(rel) && rel_equality(rel)) {
461 rel_set_invariant(rel,TRUE);
462 } else {
463 rel_set_invariant(rel,FALSE);
464 }
465 }
466 }
467
468
469 /*
470 * Sets the ACTIVE bit to TRUE for all the logrels included in the
471 * logrel list.
472 */
473 void set_active_logrels_in_list(struct logrel_relation **lrlist)
474 {
475 int32 c;
476 struct logrel_relation *lrel;
477
478 for (c = 0; lrlist[c]!= NULL; c++) {
479 lrel = lrlist[c];
480 logrel_set_active(lrel,TRUE);
481 }
482 }
483
484
485 /*
486 * Sets the ACTIVE bit to FALSE for all the vars included in the
487 * var list
488 */
489 void set_inactive_vars_in_list(struct var_variable **vlist)
490 {
491 int32 c;
492 struct var_variable *var;
493
494 for (c = 0; vlist[c]!= NULL; c++) {
495 var = vlist[c];
496 var_set_active(var,FALSE);
497 }
498 }
499
500 /*
501 * Sets the ACTIVE_AT_BND bit to FALSE for all the vars included in the
502 * var list
503 */
504 static void set_inactive_vars_at_bnd_in_list(struct var_variable **vlist)
505 {
506 int32 c;
507 struct var_variable *var;
508
509 for (c = 0; vlist[c]!= NULL; c++) {
510 var = vlist[c];
511 var_set_active_at_bnd(var,FALSE);
512 }
513 }
514
515
516 /*
517 * Set the INVARIAT bit to value for all the rels included in the
518 * rel list.
519 */
520 void set_invariant_in_rels_list(struct rel_relation **rlist,uint32 value)
521 {
522 int32 c;
523 struct rel_relation *rel;
524
525 for (c = 0; rlist[c]!= NULL; c++) {
526 rel = rlist[c];
527 rel_set_invariant(rel,value);
528 }
529 }
530
531 /*
532 * Set the IN_CUR_SUBREGION bit to value for all the rels included in the
533 * rel list.
534 */
535 void set_in_cur_subregion_in_rels_list(struct rel_relation **rlist,
536 uint32 value)
537 {
538 int32 c;
539 struct rel_relation *rel;
540
541 for (c = 0; rlist[c]!= NULL; c++) {
542 rel = rlist[c];
543 rel_set_in_cur_subregion(rel,value);
544 }
545 }
546
547
548 /*
549 * Set the ACTIVE bit to FALSE for all the discrete vars included in the
550 * discrete var list
551 */
552 void set_inactive_disvars_in_list(struct dis_discrete **dvlist)
553 {
554 int32 c;
555 struct dis_discrete *dvar;
556
557 for (c = 0; dvlist[c]!= NULL; c++) {
558 dvar = dvlist[c];
559 dis_set_active(dvar,FALSE);
560 }
561 }
562
563
564 /*
565 * Set the ACTIVE bit to TRUE for all the variables included in
566 * ACTIVE relations.
567 */
568 void set_active_vars_in_active_rels(struct rel_relation **solverrl)
569 {
570 struct var_variable *var;
571 struct rel_relation *rel;
572 struct var_variable **incidence;
573 int32 v,c,vlen;
574
575 for (v = 0; solverrl[v]!=NULL; v++) {
576 rel = solverrl[v];
577 if (rel_active(rel)) {
578 vlen = rel_n_incidences(rel);
579 incidence = rel_incidence_list_to_modify(rel);
580 for(c=0; c<vlen;c++) {
581 var = incidence[c];
582 var_set_active(var,TRUE);
583 }
584 }
585 }
586 }
587
588 /*
589 * Set the ACTIVE_AT_BND bit to TRUE for all the variables included in
590 * ACTIVE relations.
591 */
592 static
593 void set_active_vars_at_bnd_in_active_rels(struct rel_relation **solverrl)
594 {
595 struct var_variable *var;
596 struct rel_relation *rel;
597 struct var_variable **incidence;
598 int32 v,c,vlen;
599
600 for (v = 0; solverrl[v]!=NULL; v++) {
601 rel = solverrl[v];
602 if (rel_active(rel)) {
603 vlen = rel_n_incidences(rel);
604 incidence = rel_incidence_list_to_modify(rel);
605 for(c=0; c<vlen;c++) {
606 var = incidence[c];
607 var_set_active_at_bnd(var,TRUE);
608 }
609 }
610 }
611 }
612
613
614 /*
615 * Set the ACTIVE bit to TRUE for all the discrete variables included in
616 * ACTIVE logrelations.
617 */
618 void set_active_disvars_in_active_logrels(struct logrel_relation **solverll)
619 {
620 struct dis_discrete *dvar;
621 struct logrel_relation *lrel;
622 struct dis_discrete **incidence;
623 int32 v,c,vlen;
624
625 for (v = 0; solverll[v]!=NULL; v++) {
626 lrel = solverll[v];
627 if (logrel_active(lrel)) {
628 vlen = logrel_n_incidences(lrel);
629 incidence = logrel_incidence_list_to_modify(lrel);
630 for(c=0; c<vlen;c++) {
631 dvar = incidence[c];
632 dis_set_active(dvar,TRUE);
633 }
634 }
635 }
636 }
637
638
639 /*
640 * Set the ACTIVE_AT_BDN bit to TRUE for all the variables incident in all
641 * the relations of all the subregions neighboring a boundary(ies)
642 */
643 void set_active_vars_at_bnd(slv_system_t sys, struct gl_list_t *disvars)
644 {
645 struct rel_relation **solverrl;
646 struct var_variable **solvervl;
647 struct dis_discrete *dis;
648 struct gl_list_t *whens;
649 struct w_when *when;
650 int32 d,dlen,w,wlen;
651
652 solverrl = slv_get_solvers_rel_list(sys);
653 solvervl = slv_get_solvers_var_list(sys);
654
655 if (disvars == NULL) {
656 return;
657 }
658 dlen = gl_length(disvars);
659
660 /*
661 * set active rels in the whens including the disvars,
662 * then set active vars in active rels
663 */
664 for (d=1;d<=dlen;d++) {
665 dis = (struct dis_discrete *)(gl_fetch(disvars,d));
666 whens = dis_whens_list(dis);
667 if (whens == NULL) {
668 continue;
669 }
670 wlen = gl_length(whens);
671 for (w=1;w<=wlen;w++) {
672 when = (struct w_when *)(gl_fetch(whens,w));
673 set_rels_status_in_when(when,TRUE);
674 }
675 }
676 set_inactive_vars_at_bnd_in_list(solvervl);
677 set_active_vars_at_bnd_in_active_rels(solverrl);
678 }
679
680
681
682 /*
683 * Set the INVARIANT flag to TRUE for all the relations invariant with
684 * respect to the current boundary(ies)
685 */
686 void identify_invariant_rels_at_bnd(slv_system_t sys,
687 struct gl_list_t *disvars)
688 {
689 struct rel_relation **solverrl;
690 struct dis_discrete *dis;
691 struct gl_list_t *whens;
692 struct w_when *when;
693 int32 d,dlen,w,wlen;
694
695 solverrl = slv_get_solvers_rel_list(sys);
696
697 if (disvars == NULL) {
698 return;
699 }
700 dlen = gl_length(disvars);
701
702 for (d=1;d<=dlen;d++) {
703 dis = (struct dis_discrete *)(gl_fetch(disvars,d));
704 whens = dis_whens_list(dis);
705 if (whens == NULL) {
706 continue;
707 }
708 wlen = gl_length(whens);
709 for (w=1;w<=wlen;w++) {
710 when = (struct w_when *)(gl_fetch(whens,w));
711 set_rels_status_in_when(when,FALSE);
712 }
713 }
714 set_invariant_in_rels_list(solverrl,FALSE);
715 set_active_rels_as_invariant(solverrl);
716 }
717
718 /*
719 * find if the current case is included in the array of cases
720 */
721 static int32 case_in_array_of_cases(int32 num_case, int32 *cases, int32 ncases)
722 {
723 int32 n;
724
725 for (n=0; n<ncases; n++) {
726 if (num_case == cases[n]) {
727 return 1;
728 }
729 }
730 return 0;
731 }
732
733 /*
734 * find if a some case of the array of cases belongs to some of the
735 * nested whens of a when statement
736 */
737 static int32 case_in_nested_whens(int32 *cases, int32 ncases,
738 struct when_case *cur_case)
739 {
740 struct gl_list_t *case_list;
741 struct gl_list_t *whens;
742 struct w_when *nested_when;
743 struct when_case *nested_case;
744 int32 c,clen,w,wlen;
745 int32 num_case;
746
747
748 whens = when_case_whens_list(cur_case);
749 wlen = gl_length(whens); /* nested whens */
750 for (w=1;w<=wlen;w++){
751 nested_when = (struct w_when *)(gl_fetch(whens,w));
752 case_list = when_cases_list(nested_when);
753 clen = gl_length(case_list);
754 for (c=1; c<=clen; c++) {
755 nested_case = (struct when_case *)(gl_fetch(case_list,c));
756 num_case = when_case_case_number(cur_case);
757 if (num_case == -1) {
758 if (case_in_nested_whens(cases,ncases,nested_case)) { /* recursion */
759 return 1;
760 }
761 } else {
762 if(case_in_array_of_cases(num_case,cases,ncases)) {
763 return 1;
764 }
765 }
766 }
767 }
768
769 return 0;
770 }
771
772 /*
773 * If some case of the when belong to the list of cases, the rels
774 * in such a case are set as active
775 */
776 static void set_active_rels_in_cases(int32 *cases, int32 ncases,
777 struct w_when *when)
778 {
779 struct gl_list_t *case_list;
780 struct gl_list_t *whens;
781 struct w_when *nested_when;
782 struct when_case *cur_case;
783 int32 c,clen,w,wlen;
784 int32 num_case;
785
786 case_list = when_cases_list(when);
787 clen = gl_length(case_list);
788 for (c=1;c<=clen;c++){
789 cur_case = (struct when_case *)(gl_fetch(case_list,c));
790 num_case = when_case_case_number(cur_case);
791 if (num_case == -1) { /* nested whens in case */
792 if (case_in_nested_whens(cases,ncases,cur_case)) {
793 when_case_set_active(cur_case,TRUE);
794 set_rels_status_in_case(cur_case,TRUE);
795 set_logrels_status_in_case(cur_case,TRUE);
796 whens = when_case_whens_list(cur_case);
797 wlen = gl_length(whens); /* nested whens */
798 for (w=1;w<=wlen;w++){
799 nested_when = (struct w_when *)(gl_fetch(whens,w));
800 set_active_rels_in_cases(cases,ncases,nested_when); /* recursion */
801 }
802 }
803 } else {
804 if(case_in_array_of_cases(num_case,cases,ncases)) {
805 when_case_set_active(cur_case,TRUE);
806 set_rels_status_in_case(cur_case,TRUE);
807 set_logrels_status_in_case(cur_case,TRUE);
808 }
809 }
810 }
811 }
812
813 /*
814 * get the list of whens for each discrete variable in disvars,
815 * set all the relation in those whens as inactive, and then
816 * set as active the relations corresponding to the cases passed
817 * as argument in cases.
818 */
819 void set_active_rels_in_subregion(slv_system_t sys, int32 *cases,
820 int32 ncases, struct gl_list_t *disvars)
821 {
822 struct rel_relation **solverrl;
823 struct dis_discrete *dis;
824 struct gl_list_t *whens;
825 struct w_when *when;
826 int32 d,dlen,w,wlen;
827
828 solverrl = slv_get_solvers_rel_list(sys);
829
830 if (disvars == NULL) {
831 return;
832 }
833 dlen = gl_length(disvars);
834
835 for (d=1;d<=dlen;d++) {
836 dis = (struct dis_discrete *)(gl_fetch(disvars,d));
837 whens = dis_whens_list(dis);
838 if (whens == NULL) {
839 continue;
840 }
841 wlen = gl_length(whens);
842 for (w=1;w<=wlen;w++) {
843 when = (struct w_when *)(gl_fetch(whens,w));
844 set_rels_status_in_when(when,FALSE); /* initialize the active flag */
845 }
846
847 for (w=1;w<=wlen;w++) {
848 when = (struct w_when *)(gl_fetch(whens,w));
849 set_active_rels_in_cases(cases,ncases,when);
850 }
851 }
852 }
853
854 /*
855 * For each relation active, included, equality and not invariant, set the
856 * flag in_cur_subregion as TRUE
857 */
858 static void set_variant_rels_in_subregion(struct rel_relation **rlist)
859 {
860 int32 c;
861 struct rel_relation *rel;
862
863 for (c = 0; rlist[c]!= NULL; c++) {
864 rel = rlist[c];
865 if (rel_active(rel) && (!rel_invariant(rel))
866 && rel_included(rel) && rel_equality(rel)) {
867 rel_set_in_cur_subregion(rel,TRUE);
868 }
869 }
870 }
871
872 /*
873 * For each relation active and not invariant, set the flag
874 * in_cur_subregion as TRUE. First, the same flag is initialized
875 * to FALSE for all of the relations
876 */
877 void identify_variant_rels_in_subregion(slv_system_t sys)
878 {
879 struct rel_relation **solverrl;
880 solverrl = slv_get_solvers_rel_list(sys);
881
882 /* initialize in_cur_subregion flag */
883 set_in_cur_subregion_in_rels_list(solverrl,FALSE);
884
885 set_variant_rels_in_subregion(solverrl);
886 }
887
888
889 /*
890 * Set the ACTIVE bit flag as TRUE, for all of the variables
891 * incident in the currently active variables. Used for analysis
892 * in a subregion.
893 */
894 void set_active_vars_in_subregion(slv_system_t sys)
895 {
896 struct rel_relation **solverrl;
897 struct var_variable **solvervl;
898
899 solverrl = slv_get_solvers_rel_list(sys);
900 solvervl = slv_get_solvers_var_list(sys);
901
902 set_inactive_vars_in_list(solvervl);
903 set_active_vars_in_active_rels(solverrl);
904 }
905
906
907 /*
908 * ------------------------------------------------
909 * STRUCTURALCOMPARISON OF CONDITIONAL ALTERNATIVES
910 * ------------------------------------------------
911 *
912 * The following subroutines compare the structure (incidence
913 * pattern) of the different alternatives in a conditional
914 * model. So, alternatives that have the same incidence
915 * pattern can be identified and the combinatorial cosistency
916 * analysis (proper selection of the degrees of freedom in a
917 * conditional model) can be simplified. This current
918 * implementation does not handle nested WHENs. So, if a WHEN have
919 * a nested WHEN, the outter most WHEN is considered as a WHEN
920 * which will change the incidence pattern. This can be modified
921 * at any time, of course.
922 */
923
924 /*
925 * Order the list of incidences of a relation according to the
926 * master index.
927 */
928 static int32 *order_incidences_of_relation(struct var_variable **var_list,
929 int32 vlen)
930 {
931 struct var_variable *var;
932 int32 *index;
933 int32 *ordered_index;
934 int32 v,vind,vcount = 0;
935 int32 aux,vin,vindex = 0;
936
937 index = ASC_NEW_ARRAY(int32,vlen);
938 ordered_index = ASC_NEW_ARRAY(int32,vlen);
939
940 for (v=0; v<vlen; v++) {
941 var = var_list[v];
942 index[v] = var_mindex(var);
943 }
944
945 aux = 0;
946 while (aux < vlen) {
947 for (v=0; v<vlen; v++) {
948 vcount = index[aux];
949 if (vcount >=0) {
950 break;
951 }
952 }
953 for (vin=0; vin<vlen; vin++) {
954 vind = index[vin];
955 if (vind >=0) {
956 if (vcount >= vind ) {
957 vcount = vind;
958 vindex = vin;
959 }
960 }
961 }
962 index[vindex] = -1;
963 ordered_index[aux] = vcount;
964 aux++;
965 }
966
967 ascfree(index);
968 return ordered_index;
969 }
970
971
972 /*
973 * Compare structure of two CASEs of a WHEN
974 */
975 static int32 compare_alternative_cases(struct when_case *cur_case1,
976 struct when_case *cur_case2)
977 {
978 struct gl_list_t *rel_list1, *rel_list2;
979 struct rel_relation *rel1, *rel2;
980 struct var_variable **inc1, **inc2;
981 int32 numcase1, numcase2;
982 int32 nrel1, nrel2;
983 int32 nvar1, nvar2;
984 int32 v,r, ind1, ind2;
985 int32 nivr1, nivr2;
986 int32 *ninc1, *ninc2;
987 int32 *ord_ind1, *ord_ind2;
988
989 numcase1 = when_case_case_number(cur_case1);
990 numcase2 = when_case_case_number(cur_case2);
991 #if DEBUG_PRE_ANALYSIS
992 FPRINTF(ASCERR,"Making comparison of CASEs:\n");
993 FPRINTF(ASCERR,"case A = %d case B = %d \n",numcase1,numcase2);
994 #endif /* DEBUG_PRE_ANALYSIS */
995
996 nrel1 = when_case_num_rels(cur_case1);
997 nrel2 = when_case_num_rels(cur_case2);
998
999 if (nrel1 != nrel2) {
1000 #if DEBUG_PRE_ANALYSIS
1001 FPRINTF(ASCERR,"CASEs have different number of relations\n");
1002 FPRINTF(ASCERR,"case A = %d case B = %d\n",nrel1,nrel2);
1003 #endif /* DEBUG_PRE_ANALYSIS */
1004 return 0;
1005 }
1006
1007 nvar1 = when_case_num_inc_var(cur_case1);
1008 nvar2 = when_case_num_inc_var(cur_case2);
1009
1010 if (nvar1 != nvar2) {
1011 #if DEBUG_PRE_ANALYSIS
1012 FPRINTF(ASCERR,"CASEs have different number of incidences\n");
1013 FPRINTF(ASCERR,"case A = %d case B = %d\n",nvar1,nvar2);
1014 #endif /* DEBUG_PRE_ANALYSIS */
1015 return 0;
1016 }
1017
1018 ninc1 = when_case_ind_inc(cur_case1);
1019 ninc2 = when_case_ind_inc(cur_case2);
1020
1021 for (v=0; v<nvar1; v++) {
1022 ind1 = ninc1[v];
1023 ind2 = ninc2[v];
1024
1025 if (ind1 != ind2) {
1026 #if DEBUG_PRE_ANALYSIS
1027 FPRINTF(ASCERR,"Incidences are different in CASEs\n");
1028 FPRINTF(ASCERR,"index in case A =%d index in case B =%d\n",ind1,ind2);
1029 #endif /* DEBUG_PRE_ANALYSIS */
1030 return 0;
1031 }
1032 }
1033
1034 rel_list1 = when_case_rels_list(cur_case1);
1035 rel_list2 = when_case_rels_list(cur_case2);
1036
1037 for (r=1; r<=nrel1; r++) {
1038 rel1 = (struct rel_relation *)(gl_fetch(rel_list1,r));
1039 rel2 = (struct rel_relation *)(gl_fetch(rel_list2,r));
1040 nivr1 = rel_n_incidences(rel1);
1041 nivr2 = rel_n_incidences(rel2);
1042 if (nivr1 != nivr2) {
1043 #if DEBUG_PRE_ANALYSIS
1044 FPRINTF(ASCERR,"relations of different CASEs have different ");
1045 FPRINTF(ASCERR,"number of incidences\n");
1046 FPRINTF(ASCERR,"No. in rel of A = %d No. in rel of B = %d\n",
1047 nivr1,nivr2);
1048 #endif /* DEBUG_PRE_ANALYSIS */
1049 return 0;
1050 }
1051 inc1 = rel_incidence_list_to_modify(rel1);
1052 inc2 = rel_incidence_list_to_modify(rel1);
1053 ord_ind1 = order_incidences_of_relation(inc1,nivr1);
1054 ord_ind2 = order_incidences_of_relation(inc2,nivr2);
1055 for (v=0; v<nivr1; v++) {
1056 ind1 = ord_ind1[v];
1057 ind2 = ord_ind2[v];
1058 if (ind1 != ind2) {
1059 #if DEBUG_PRE_ANALYSIS
1060 FPRINTF(ASCERR,"relations of different CASEs have different \n");
1061 FPRINTF(ASCERR,"Incidences\n");
1062 FPRINTF(ASCERR,"index in rel of A =%d index in rel pf B =%d\n",
1063 ind1,ind2);
1064 #endif /* DEBUG_PRE_ANALYSIS */
1065 ascfree(ord_ind1);
1066 ascfree(ord_ind2);
1067 return 0;
1068 }
1069 }
1070 ascfree(ord_ind1);
1071 ascfree(ord_ind2);
1072 }
1073
1074 #if DEBUG_PRE_ANALYSIS
1075 FPRINTF(ASCERR,"CASEs have the same structure \n");
1076 #endif /* DEBUG_PRE_ANALYSIS */
1077 return 1;
1078 }
1079
1080 /*
1081 * Compares the structure (number of equations, variables, incidence
1082 * pattern, etc) of the different CASEs of a WHEN statement
1083 */
1084 static int32 compare_alternative_structures_in_when(struct w_when *when)
1085 {
1086 struct when_case *cur_case1;
1087 struct when_case *cur_case2;
1088 struct gl_list_t *cases;
1089 int32 c,clen;
1090
1091 cases = when_cases_list(when);
1092 if (cases == NULL) {
1093 FPRINTF(ASCERR,"WARNING: No list of cases in When\n");
1094 return 1;
1095 }
1096
1097 clen = gl_length (cases);
1098
1099 if (clen >1) {
1100 cur_case1 = (struct when_case *)(gl_fetch(cases,1));
1101 for (c=2; c<=clen; c++) {
1102 cur_case2 = (struct when_case *)(gl_fetch(cases,c));
1103 if (!compare_alternative_cases(cur_case1,cur_case2)) {
1104 #if DEBUG_PRE_ANALYSIS
1105 FPRINTF(ASCERR,"CASEs have different structure\n");
1106 #endif /* DEBUG_PRE_ANALYSIS */
1107 return 0;
1108 }
1109 }
1110 return 1;
1111 } else {
1112 if (clen == 1 ) {
1113 return 0;
1114 } else {
1115 return 1;
1116 }
1117 }
1118 }
1119
1120 /*
1121 * Define values for the flag incident_in_case of the variables in the
1122 * master list
1123 */
1124 static void set_incident_in_case_status(struct var_variable **vlist,
1125 uint32 value)
1126 {
1127 int32 c;
1128 struct var_variable *var;
1129
1130 for (c = 0; vlist[c]!= NULL; c++) {
1131 var = vlist[c];
1132 var_set_incident_in_case(var,value);
1133 }
1134 }
1135
1136 /*
1137 * Get the list of master indices of the variables incident in a
1138 * CASE
1139 */
1140 static void get_incidences_in_case(struct when_case *cur_case,
1141 struct var_variable **mastervl)
1142 {
1143 struct gl_list_t *rels;
1144 struct rel_relation *rel;
1145 struct var_variable **var_list;
1146 struct var_variable *var;
1147 int32 *inc;
1148 int32 rlen, vlen, r,v;
1149 int32 ninc;
1150
1151 rels = when_case_rels_list(cur_case);
1152 set_incident_in_case_status(mastervl,FALSE);
1153 if (rels != NULL) {
1154 rlen = gl_length(rels);
1155 for (r=1;r<=rlen;r++) {
1156 rel = (struct rel_relation *)(gl_fetch(rels,r));
1157 vlen = rel_n_incidences(rel);
1158 var_list = rel_incidence_list_to_modify(rel);
1159 for (v=0; v<vlen; v++) {
1160 var = var_list[v];
1161 var_set_incident_in_case(var,TRUE);
1162 }
1163 }
1164 }
1165 ninc = 0;
1166 for (v=0; mastervl[v]!= NULL; v++) {
1167 var = mastervl[v];
1168 if (var_incident_in_case(var)) {
1169 ninc++;
1170 }
1171 }
1172
1173 if (ninc>0) {
1174 inc = ASC_NEW_ARRAY(int32,ninc);
1175 ninc = 0;
1176 for (v=0; mastervl[v]!= NULL; v++) {
1177 var = mastervl[v];
1178 if (var_incident_in_case(var)) {
1179 inc[ninc] = var_mindex(var);
1180 ninc++;
1181 }
1182 }
1183 when_case_set_num_inc_var(cur_case,ninc);
1184 when_case_set_ind_inc(cur_case,inc);
1185 #if DEBUG_PRE_ANALYSIS
1186 FPRINTF(ASCERR,"Number of incidences = %d \n",ninc);
1187 #endif /* DEBUG_PRE_ANALYSIS */
1188 } else {
1189 when_case_set_num_inc_var(cur_case,0);
1190 }
1191 }
1192
1193
1194 /*
1195 * Order a list of relations according to the index of the incidences
1196 */
1197 static void order_relations_by_incidences(struct gl_list_t *scratch)
1198 {
1199 struct rel_relation *rel;
1200 struct rel_relation **array_rel;
1201 struct var_variable **var_list;
1202 int32 r,rlen,rin,rind = 0;
1203 int32 num_inc = 0, v, vv, vindex = 0, vind;
1204 int32 glob_count, n1, n2;
1205 int32 *num_rel, *ordered_num_rel;
1206 int32 **var_ind;
1207
1208 rlen = gl_length(scratch);
1209 num_rel = ASC_NEW_ARRAY(int32,rlen);
1210 ordered_num_rel = ASC_NEW_ARRAY(int32,rlen);
1211 var_ind = (int32 **)ascmalloc(rlen*sizeof(int32 *));
1212 array_rel = (struct rel_relation **)ascmalloc
1213 (rlen*sizeof(struct rel_relation *));
1214
1215 for (r=1; r<=rlen; r++) {
1216 num_rel[r-1] = r;
1217 ordered_num_rel[r-1] = r;
1218 rel = (struct rel_relation *)(gl_fetch(scratch,r));
1219 array_rel[r-1] = rel;
1220 var_list = rel_incidence_list_to_modify(rel);
1221 num_inc = rel_n_incidences(rel);
1222 var_ind[r-1] = order_incidences_of_relation(var_list,num_inc);
1223 }
1224
1225 v=0;
1226 glob_count = 0;
1227 while (glob_count <rlen) {
1228 for (r=0; r <rlen; r++) {
1229 vindex = var_ind[r][v];
1230 if (num_rel[r] > 0) {
1231 vindex = var_ind[r][v];
1232 rind =r;
1233 break;
1234 }
1235 }
1236 for (rin=0; rin<rlen; rin++) {
1237 vind = var_ind[rin][v];
1238 if (num_rel[rin] > 0) {
1239 if (rin != rind) {
1240 if (vindex > vind ) {
1241 vindex = vind;
1242 rind = rin;
1243 } else {
1244 if (vindex == vind) {
1245 for(vv=0; vv<num_inc; vv++) {
1246 n1 = var_ind[rind][v];
1247 n2 = var_ind[rin][v];
1248 if (n1 != n2) {
1249 if (n1 > n2) {
1250 rind = rin;
1251 }
1252 break;
1253 }
1254 }
1255 }
1256 }
1257 }
1258 }
1259 }
1260 num_rel[rind] = -1;
1261 ordered_num_rel[glob_count] = rind;
1262 glob_count = glob_count + 1;
1263 }
1264
1265 gl_reset(scratch);
1266
1267 for (r=0; r<rlen; r++) {
1268 for (rin=0; rin<rlen; rin++) {
1269 if (r == ordered_num_rel[rin]) {
1270 rel = array_rel[rin];
1271 gl_append_ptr(scratch,rel);
1272 break;
1273 }
1274 }
1275 }
1276
1277 ascfree(num_rel);
1278 ascfree(ordered_num_rel);
1279 for (r=0; r<rlen; r++) {
1280 ascfree(var_ind[r]);
1281 }
1282 ascfree(var_ind);
1283 ascfree(array_rel);
1284 }
1285
1286 /*
1287 * Order the list of relations of a CASE according to the number of
1288 * incidences and index of the incidences
1289 */
1290 static void order_relations_in_case(struct when_case *cur_case)
1291 {
1292 struct gl_list_t *rels;
1293 struct gl_list_t *new_rels;
1294 struct gl_list_t *tmp;
1295 struct gl_list_t *scratch;
1296 struct rel_relation *rel;
1297 int32 *num_inc;
1298 int32 *ordered_num_inc;
1299 int32 r, rin, rlen, rcount = 0, rind;
1300 int32 index = 0, aux, glob_count;
1301
1302 rels = when_case_rels_list(cur_case);
1303 if (rels != NULL) {
1304 rlen = gl_length(rels);
1305 if (rlen > 1) {
1306 num_inc = ASC_NEW_ARRAY(int32,rlen);
1307 ordered_num_inc = ASC_NEW_ARRAY(int32,rlen);
1308 new_rels = gl_create(rlen);
1309 tmp = gl_create(rlen);
1310 for (r=1;r<=rlen;r++) { /* get number of incidences */
1311 rel = (struct rel_relation *)(gl_fetch(rels,r));
1312 num_inc[r-1] = rel_n_incidences(rel);
1313 }
1314
1315 /* order number of incidences */
1316 aux = 0;
1317 while (aux < rlen) {
1318 for (r=0;r<rlen;r++) {
1319 rcount = num_inc[r];
1320 if (rcount >= 0) {
1321 break;
1322 }
1323 }
1324 for (rin=0; rin<rlen; rin++) {
1325 rind = num_inc[rin];
1326 if (rind >=0) {
1327 if (rcount >= rind ) {
1328 rcount = rind;
1329 index = rin;
1330 }
1331 }
1332 }
1333 num_inc[index] = -1;
1334 ordered_num_inc[aux] = rcount;
1335 aux++;
1336 }
1337
1338 /* order relations in same order as number of incidences */
1339 for (r=0;r<rlen;r++) {
1340 num_inc[r] = ordered_num_inc[r];
1341 }
1342 for (r=0; r<rlen; r++) {
1343 rcount = ordered_num_inc[r];
1344 for (rin=0; rin<rlen;rin++) {
1345 if (num_inc[rin] >= 0) {
1346 rel = (struct rel_relation *)(gl_fetch(rels,rin+1));
1347 rind = rel_n_incidences(rel);
1348 if (rcount == rind) {
1349 gl_append_ptr(new_rels,rel);
1350 num_inc[rin] = -1;
1351 break;
1352 }
1353 }
1354 }
1355 }
1356
1357 /*
1358 * order relations with same order of incidences according to
1359 * the master indices of their incidences
1360 */
1361 glob_count = 0;
1362 aux = 0;
1363 while(glob_count<rlen) {
1364 for (r=aux; r<rlen; r++) {
1365 rcount = ordered_num_inc[r];
1366 if ((r+1) < rlen) {
1367 rind = ordered_num_inc[r+1];
1368 if (rcount == rind) {
1369 glob_count = glob_count+1;
1370 continue;
1371 } else {
1372 break;
1373 }
1374 } else {
1375 break;
1376 }
1377 }
1378 if (aux != glob_count) {
1379 scratch = gl_create(glob_count - aux + 1);
1380 for (r=aux; r<=glob_count; r++) {
1381 rel = (struct rel_relation *)(gl_fetch(rels,r+1));
1382 gl_append_ptr(scratch,rel);
1383 }
1384 order_relations_by_incidences(scratch);
1385 for (r=1; r<=glob_count - aux + 1; r++) {
1386 rel = (struct rel_relation *)(gl_fetch(scratch,r));
1387 gl_append_ptr(tmp,rel);
1388 }
1389 gl_destroy(scratch);
1390 } else {
1391 rel = (struct rel_relation *)(gl_fetch(rels,glob_count+1));
1392 gl_append_ptr(tmp,rel);
1393 }
1394 aux = glob_count+1;
1395 glob_count = aux;
1396 }
1397 /*
1398 * set ordered list of relations
1399 */
1400 when_case_set_rels_list(cur_case,tmp);
1401
1402 ascfree(num_inc);
1403 ascfree(ordered_num_inc);
1404 gl_destroy(rels);
1405 gl_destroy(new_rels);
1406 }
1407 }
1408 }
1409
1410
1411 /*
1412 * Analyzes (get number of relations and variables, get global list of
1413 * incident variables, order relation and variables by master index)
1414 * a CASE of a WHEN statement
1415 */
1416 static int32 analyze_structure_of_case(struct when_case *cur_case,
1417 struct var_variable **mastervl)
1418 {
1419 struct gl_list_t *rels;
1420 struct gl_list_t *whens;
1421 int32 rlen;
1422 int32 wlen;
1423
1424 whens = when_case_whens_list(cur_case);
1425 #if DEBUG_PRE_ANALYSIS
1426 FPRINTF(ASCERR,"case # = %d \n",when_case_case_number(cur_case));
1427 #endif /* DEBUG_PRE_ANALYSIS */
1428 /*
1429 * No nested WHENs right now
1430 * Here we'll need to recursively call
1431 * the analysis of the nested when and
1432 * the internal structure of the WHEN
1433 */
1434
1435 if (whens != NULL) {
1436 wlen = gl_length(whens);
1437 if (wlen > 0) {
1438 #if DEBUG_PRE_ANALYSIS
1439 FPRINTF(ASCERR,"CASE contains nested WHENs\n");
1440 #endif /* DEBUG_PRE_ANALYSIS */
1441 return 0;
1442 }
1443 }
1444
1445 rels = when_case_rels_list(cur_case);
1446 if (rels != NULL) {
1447 rlen = gl_length(rels);
1448 #if DEBUG_PRE_ANALYSIS
1449 FPRINTF(ASCERR,"Number of relations = %d \n",rlen);
1450 #endif /* DEBUG_PRE_ANALYSIS */
1451 when_case_set_num_rels(cur_case,rlen);
1452 order_relations_in_case(cur_case);
1453 get_incidences_in_case(cur_case,mastervl);
1454 } else {
1455 when_case_set_num_rels(cur_case,0);
1456 when_case_set_num_inc_var(cur_case,0);
1457 }
1458 return 1;
1459 }
1460
1461
1462 /*
1463 * analyzes the structure of the different alternatives (CASES)
1464 * in a WHEN statement so that we can find out later if it is
1465 * necessary to perform a combinatorial search for a consistent
1466 * variable partitioning
1467 */
1468
1469 static int32 analyze_alternative_structures_in_when(struct w_when *when,
1470 struct var_variable **mastervl)
1471 {
1472 struct when_case *cur_case;
1473 struct gl_list_t *cases;
1474 int32 c,clen;
1475
1476 cases = when_cases_list(when);
1477 if (cases == NULL) {
1478 FPRINTF(ASCERR,"WARNING: No list of cases in When\n");
1479 return 1;
1480 }
1481
1482 clen = gl_length (cases);
1483
1484 for (c=1; c<=clen; c++) {
1485 cur_case = (struct when_case *)(gl_fetch(cases,c));
1486 if (!analyze_structure_of_case(cur_case,mastervl)) {
1487 when_set_changes_structure(when,TRUE);
1488 #if DEBUG_PRE_ANALYSIS
1489 FPRINTF(ASCERR,"WHEN CHANGES structure\n");
1490 FPRINTF(ASCERR,"\n");
1491 #endif /* DEBUG_PRE_ANALYSIS */
1492 return 0;
1493 }
1494 }
1495
1496 if (!compare_alternative_structures_in_when(when)) {
1497 when_set_changes_structure(when,TRUE);
1498 #if DEBUG_PRE_ANALYSIS
1499 FPRINTF(ASCERR,"WHEN CHANGES structure\n");
1500 FPRINTF(ASCERR,"\n");
1501 #endif /* DEBUG_PRE_ANALYSIS */
1502 return 0;
1503 }
1504 when_set_changes_structure(when,FALSE);
1505 #if DEBUG_PRE_ANALYSIS
1506 FPRINTF(ASCERR,"WHEN DOES NOT CHANGE structure\n");
1507 FPRINTF(ASCERR,"\n");
1508 #endif /* DEBUG_PRE_ANALYSIS */
1509 return 1;
1510 }
1511
1512
1513 /*
1514 *-------------------------------------------
1515 * ENUMERATION OF CASES
1516 *------------------------------------------
1517 */
1518
1519 /*
1520 * Finds the number of cases in a when. This number will include nested
1521 * cases (in nested when statements). It also assigns a identifier number
1522 * to each case in the when statement. If this number is equal to -1
1523 * for some case, it implies that the case contains nested whens and it
1524 * is necessary to perform a recursive analysis to find the numbers of the
1525 * cases embedded in the current case.
1526 * In general, the number assigned to each of the cases is only for
1527 * identification purposes, so, 1,2,3, whatever, does not matter, we only
1528 * want to distinguish among them. The identification number depends
1529 * on the order of the whens in the master when list, which is not
1530 * expected to change unless we destroy the system.
1531 *
1532 * This function uses the global variable g_case_number. Any caller
1533 * function has to reinitialize that global variable if it is required.
1534 */
1535 void enumerate_cases_in_when(struct w_when *when)
1536 {
1537 struct when_case *cur_case;
1538 struct w_when *casewhen;
1539 struct gl_list_t *cases;
1540 struct gl_list_t *whens;
1541 int32 w,wlen,c,clen;
1542 int32 scratch;
1543 int32 cur_num_cases; /* number of cases in current when */
1544
1545 scratch = g_case_number;
1546
1547 cases = when_cases_list(when);
1548 if (cases == NULL) {
1549 FPRINTF(ASCERR,"WARNING: No list of cases in When\n");
1550 return;
1551 }
1552
1553 clen = gl_length (cases);
1554 for (c=1; c<=clen; c++) {
1555 cur_case = (struct when_case *)(gl_fetch(cases,c));
1556 whens = when_case_whens_list(cur_case);
1557 if ( (whens == NULL) || (gl_length(whens) == 0) ) {
1558 g_case_number++;
1559 when_case_set_case_number(cur_case,g_case_number);
1560 #if CASE_NUMBER
1561 FPRINTF(ASCERR,"Case number = %d \n",
1562 when_case_case_number(cur_case));
1563 #endif /* CASE NUMBER*/
1564 } else {
1565 wlen = gl_length(whens);
1566 for (w=1;w<=wlen;w++) {
1567 when_case_set_case_number(cur_case,-1); /* nested cases */
1568 casewhen = (struct w_when *)(gl_fetch(whens,w));
1569 enumerate_cases_in_when (casewhen);
1570 }
1571 }
1572 }
1573 cur_num_cases = g_case_number - scratch;
1574 when_set_num_cases(when,cur_num_cases);
1575 }
1576
1577
1578 #define alloc_case_array(ncases,type) \
1579 ((ncases) > 0 ? (type *)ascmalloc((ncases)*sizeof(type)) : NULL)
1580 #define copy_case_num(from,too,nnums) \
1581 asc_memcpy((from),(too),(nnums)*sizeof(int32))
1582
1583 /*
1584 * Appends a case_number onto the list
1585 */
1586 static void append_case_number( struct ds_case_list *cl, int32 case_number)
1587 {
1588 if( cl->length == cl->capacity ) {
1589 int32 newcap;
1590 int32 *newlist;
1591 newcap = cl->capacity + 40;
1592 newlist = alloc_case_array(newcap,int);
1593 copy_case_num((char *)cl->case_number,(char *)newlist,cl->length);
1594 if( cl->case_number != NULL )
1595 ascfree(cl->case_number);
1596 cl->case_number = newlist;
1597 cl->capacity = newcap;
1598 }
1599 cl->case_number[cl->length++] = case_number;
1600 }
1601
1602
1603 #if USEDCODE
1604 /*
1605 * Removes the case_number at given index from the list.
1606 *
1607 * Currently not in use
1608 */
1609 static void remove_case_number( struct ds_case_list *cl, int32 ndx)
1610 {
1611 copy_case_num((char *)(cl->case_number+ndx+1),
1612 (char *)(cl->case_number+ndx), --(cl->length) - ndx);
1613 }
1614 #endif /* USEDCODE */
1615
1616
1617
1618 /*
1619 * Get the case number of the matching cases in a when statement. If
1620 * such number is -1, that means that the case contains nested whens
1621 * (and therefore nested cases) and the search is done recursively
1622 */
1623 static void cases_matching_in_when(struct w_when *when,
1624 struct ds_case_list *cl,
1625 int32 *ncases)
1626 {
1627 struct gl_list_t *cases;
1628 struct gl_list_t *whens_in_case;
1629 struct when_case *cur_case;
1630 int32 c,clen,case_number;
1631
1632 cases = when_cases_list(when);
1633 if (cases == NULL) {
1634 return;
1635 }
1636 clen = gl_length(cases);
1637 for (c=1;c<=clen;c++) {
1638 cur_case = (struct when_case *)(gl_fetch(cases,c));
1639 if (when_case_active(cur_case)){
1640 case_number = when_case_case_number(cur_case);
1641 if (case_number == -1) {
1642 whens_in_case = when_case_whens_list(cur_case);
1643 cases_matching_in_when_list(whens_in_case,cl,ncases);
1644 } else {
1645 append_case_number(cl,case_number);
1646 (*ncases)++;
1647 }
1648 }
1649 }
1650 }
1651
1652
1653 /*
1654 * Disentagle a list of whens and analyze each one of them, looking
1655 * for the number of matching cases.
1656 */
1657 static void cases_matching_in_when_list(struct gl_list_t *whens,
1658 struct ds_case_list *cl,
1659 int32 *ncases)
1660 {
1661 struct w_when *when;
1662 int32 w,wlen;
1663
1664 if (whens == NULL) {
1665 return;
1666 }
1667 wlen = gl_length(whens);
1668 for (w=1;w<=wlen;w++) {
1669 when = (struct w_when *)(gl_fetch(whens,w));
1670 if (!when_visited(when)) {
1671 cases_matching_in_when(when,cl,ncases);
1672 }
1673 when_set_visited(when,TRUE);
1674 }
1675 }
1676
1677 /*
1678 * Given a list of discrete variables, finds which cases apply
1679 * in the whens depending on those variables.
1680 * The caller funtion should modify the values of these discrete
1681 * variables so that we can make combinatorial search. Also,
1682 * the list should contain discrete variables IN_WHEN.
1683 * This functions assumes that the cases in the whens have been
1684 * previously enumerated. Need to check performance regarding the
1685 * visiting of cases when some of the whens are nested.
1686 */
1687 int32 *cases_matching(struct gl_list_t *disvars, int32 *ncases)
1688 {
1689 struct ds_case_list cl;
1690 struct dis_discrete *dis;
1691 struct w_when *when;
1692 struct gl_list_t *whens;
1693 int32 d,dlen,w,wlen;
1694
1695 if (disvars == NULL) {
1696 return NULL;
1697 }
1698 dlen = gl_length(disvars);
1699
1700
1701 (*ncases) = 0;
1702 cl.length = cl.capacity = 0;
1703 cl.case_number = NULL;
1704 append_case_number(&cl,0);
1705
1706 /*
1707 * First make sure that all of the Whens has the flag VISITED off,
1708 * then disactive the cases, and then analyze the whens.
1709 */
1710 for (d=1;d<=dlen;d++) {
1711 dis = (struct dis_discrete *)(gl_fetch(disvars,d));
1712 whens = dis_whens_list(dis);
1713 if (whens == NULL) {
1714 continue;
1715 }
1716 wlen = gl_length(whens);
1717 for (w=1;w<=wlen;w++) {
1718 when = (struct w_when *)(gl_fetch(whens,w));
1719 when_set_visited(when,FALSE);
1720 disactive_cases_in_when(when);
1721 simplified_analyze_when(when);
1722 }
1723 }
1724
1725 /*
1726 * Then get the list of matched cases in each when
1727 */
1728
1729 for (d=1;d<=dlen;d++) {
1730 dis = (struct dis_discrete *)(gl_fetch(disvars,d));
1731 whens = dis_whens_list(dis);
1732 if (whens == NULL) {
1733 continue;
1734 }
1735 wlen = gl_length(whens);
1736 if (wlen > 0) {
1737 cases_matching_in_when_list(whens,&cl,ncases);
1738 }
1739 }
1740
1741 return cl.case_number;
1742 }
1743
1744
1745 /*
1746 * configure_conditional_problem
1747 * analyze the when statements included in our problem so that, we
1748 * determine which rels, vars, disvars, and logrels are currently
1749 * active. It is called by analyze.c at the time of the system
1750 * building. For reconfiguration of the system call
1751 * reanalyze_solver_lists
1752 */
1753 void configure_conditional_problem(int32 numwhens,
1754 struct w_when **whenlist,
1755 struct rel_relation **solverrl,
1756 struct logrel_relation **solverll,
1757 struct var_variable **mastervl)
1758 {
1759 int32 w,result;
1760 struct w_when *when;
1761
1762 /* Enumerate cases in when's */
1763 g_case_number = 0;
1764 for (w = 0; w < numwhens; w++) {
1765 when = whenlist[w];
1766 if (!when_inwhen(when)) {
1767 enumerate_cases_in_when(when);
1768 }
1769 }
1770
1771 /* get structure of the different alternatives */
1772 for (w = 0; w < numwhens; w++) {
1773 when = whenlist[w];
1774 result = analyze_alternative_structures_in_when(when,mastervl);
1775 }
1776
1777 /*
1778 *All rel_relations and logrel_relations explicitly or implicitly
1779 * (models) inside a w_when are deactivated
1780 */
1781 for (w = 0; w < numwhens; w++) {
1782 when = whenlist[w];
1783 if (!when_inwhen(when)) {
1784 set_rels_status_in_when(when,FALSE);
1785 }
1786 }
1787
1788 /* All of the rels which are ACTIVE, are also INVARIANT */
1789 set_active_rels_as_invariant(solverrl);
1790
1791 /*
1792 * Analyze whens and find active relations and logrelations
1793 * in each of them
1794 */
1795
1796 for (w = 0; w < numwhens; w++) {
1797 when = whenlist[w];
1798 if (!when_inwhen(when)) {
1799 analyze_when(when);
1800 }
1801 }
1802
1803 /* All variables in active relations are
1804 * set as active */
1805 set_active_vars_in_active_rels(solverrl);
1806 set_active_disvars_in_active_logrels(solverll);
1807 }
1808
1809 /*
1810 * Reconfiguration/Rebuilding of Conditional Models
1811 */
1812
1813 /*
1814 * After a change of the value of some conditional variable present
1815 * in a When, the solver lists of variables, relations and logrelations
1816 * are reanalyzed to set the bit ACTIVE for the vars, rels and
1817 * logrels corresponding to a possible new configuration.
1818 */
1819 void reanalyze_solver_lists(slv_system_t sys)
1820 {
1821 struct rel_relation **solverrl;
1822 struct rel_relation **solverol;
1823 struct logrel_relation **solverll;
1824 struct var_variable **solvervl;
1825 struct dis_discrete **solverdl;
1826 struct dis_discrete **dislist;
1827 struct w_when **whenlist;
1828 struct w_when *when;
1829 struct dis_discrete *dvar;
1830 struct gl_list_t *symbol_list;
1831 int32 c;
1832
1833 solverrl = slv_get_solvers_rel_list(sys);
1834 solverol = slv_get_solvers_obj_list(sys);
1835 solverll = slv_get_solvers_logrel_list(sys);
1836 solvervl = slv_get_solvers_var_list(sys);
1837 solverdl = slv_get_solvers_dvar_list(sys);
1838 whenlist = slv_get_solvers_when_list(sys);
1839 dislist = slv_get_master_dvar_list(sys);
1840 symbol_list = slv_get_symbol_list(sys);
1841
1842 set_inactive_vars_in_list(solvervl);
1843 set_inactive_disvars_in_list(solverdl);
1844 set_active_rels_in_list(solverrl);
1845 set_active_logrels_in_list(solverll);
1846
1847 for (c=0; dislist[c]!=NULL; c++) {
1848 dvar = dislist[c];
1849 dis_set_value_from_inst(dvar,symbol_list);
1850 }
1851
1852 for (c=0; whenlist[c]!=NULL ; c++) {
1853 when = whenlist[c];
1854 if (!when_inwhen(when)) {
1855 set_rels_status_in_when(when,FALSE);
1856 }
1857 }
1858
1859 /* All of the rels which are ACTIVE, are also INVARIANT */
1860 set_active_rels_as_invariant(solverrl);
1861
1862 for (c=0; whenlist[c]!=NULL; c++) {
1863 when = whenlist[c];
1864 if (!when_inwhen(when)) { /* nested whens are analyzed recursively */
1865 analyze_when(when);
1866 }
1867 }
1868 set_active_vars_in_active_rels(solverrl);
1869 set_active_vars_in_active_rels(solverol);
1870 set_active_disvars_in_active_logrels(solverll);
1871 }
1872
1873
1874 /*
1875 * Returns 1 if the system is reanalyzed. O if nothing happens.
1876 * System will be reanalyzed if a boolean variable included in some
1877 * when of slv_system has been modified.
1878 * There is a bit of insanity in using the IPTR here, since we are
1879 * supossed to work only with the structures in the solver side.
1880 * The reason is that this function is receiving the information from
1881 * the user interface, which is working in the compiler side.
1882 */
1883
1884 int32 system_reanalyze(slv_system_t sys, SlvBackendToken inst)
1885 {
1886 if (inst==NULL) {
1887 reanalyze_solver_lists(sys);
1888 return 1;
1889 }
1890 if (varinst_found_in_whenlist(sys,IPTR(inst))) {
1891 reanalyze_solver_lists(sys);
1892 return 1;
1893 } else {
1894 return 0;
1895 }
1896 }
1897
1898
1899 /*
1900 * The next four functions are not currently in use, but they may
1901 * in the future. See the header
1902 */
1903
1904 /*
1905 * Build the rel solver list from the master list in the case of our
1906 * problem contains when's. This function is not currently in use. It
1907 * could be use to build a solver rel list of ACTIVE relations, by
1908 * using a master rel list with all of the relations in it. These
1909 * ACTIVE relations could be INCLUDED or UNINCLUDED. It returns the
1910 * number of relation in the list.
1911 */
1912 int32 build_rel_solver_from_master(struct rel_relation **masterrl,
1913 struct rel_relation **solverrl)
1914 {
1915 struct var_variable *var;
1916 struct rel_relation *rel;
1917 struct var_variable **incidence;
1918 int32 rel_active;
1919 int32 v,c,vlen;
1920
1921 rel_active = 0;
1922
1923 /* create the solver list of active relations */
1924
1925 for (v = 0; masterrl[v]!=NULL; v++) {
1926 rel = masterrl[v];
1927 if (rel_active(rel)) {
1928 rel_set_sindex(rel,rel_active);
1929 solverrl[rel_active] = rel;
1930 vlen = rel_n_incidences(rel);
1931 incidence = rel_incidence_list_to_modify(rel);
1932 for(c=0; c<vlen;c++) {
1933 var = incidence[c];
1934 var_set_active(var,TRUE);
1935 }
1936 rel_active++;
1937 }
1938 }
1939 solverrl[rel_active] = NULL; /* terminator */
1940 return rel_active;
1941 }
1942
1943
1944 /*
1945 * Build the logrel solver list from the master list in the case of our
1946 * problem contains when's. This function is not currently in use. It
1947 * could be use to build a solver logrel list of ACTIVE logrelations, by
1948 * using a master logrel list with all of the logrelations in it. These
1949 * ACTIVE logrelations could be INCLUDED or UNINCLUDED. It returns the
1950 * number of logrelation in the list.
1951 */
1952 int32 build_logrel_solver_from_master(struct logrel_relation **masterll,
1953 struct logrel_relation **solverll)
1954 {
1955 struct dis_discrete *dvar;
1956 struct logrel_relation *lrel;
1957 struct dis_discrete **incidence;
1958 int32 lrel_active;
1959 int32 v,c,vlen;
1960
1961 lrel_active = 0;
1962
1963 /* create the solver list of active logrelations */
1964
1965 for (v = 0; masterll[v]!=NULL; v++) {
1966 lrel = masterll[v];
1967 if (logrel_active(lrel)) {
1968 logrel_set_sindex(lrel,lrel_active);
1969 solverll[lrel_active] = lrel;
1970 vlen = logrel_n_incidences(lrel);
1971 incidence = logrel_incidence_list_to_modify(lrel);
1972 for(c=0; c<vlen;c++) {
1973 dvar = incidence[c];
1974 dis_set_active(dvar,TRUE);
1975 }
1976 lrel_active++;
1977 }
1978 }
1979 solverll[lrel_active] = NULL; /* terminator */
1980 return lrel_active;
1981 }
1982
1983
1984 /*
1985 * Build the var solver list from the master list in the case of our
1986 * problem contains when's. This function is not currently in use. It
1987 * could be use to build a solver var list of ACTIVE variables (Vars
1988 * incident in ACTIVE relations). It returns the number of variables
1989 * in the list.
1990 */
1991 int32 build_var_solver_from_master(struct var_variable **mastervl,
1992 struct var_variable **solvervl)
1993 {
1994 struct var_variable *var;
1995 int32 var_active;
1996 int32 v;
1997
1998 var_active = 0;
1999
2000 /* create the solver list of active variables */
2001
2002 for (v = 0; mastervl[v]!=NULL; v++) {
2003 var = mastervl[v];
2004 if (var_active(var)) {
2005 var_set_sindex(var,var_active);
2006 solvervl[var_active] = var;
2007 var_active++;
2008 }
2009 }
2010 solvervl[var_active] = NULL; /* terminator */
2011 return var_active;
2012 }
2013
2014
2015 /*
2016 * Build the discrete var solver list from the master list in the case
2017 * of our problem contains when's. This function is not currently in use.
2018 * It could be use to build a solver discrete var list of ACTIVE discrete
2019 * variables (Discrete Vars incident in ACTIVE logrelations). It returns
2020 * the number of discrete variables in the list.
2021 */
2022 int32 build_disvar_solver_from_master(struct dis_discrete **masterdl,
2023 struct dis_discrete **solverdl)
2024 {
2025 struct dis_discrete *dvar;
2026 int32 dvar_active;
2027 int32 v;
2028
2029 dvar_active = 0;
2030
2031 /* create the solver list of active discrete variables */
2032
2033 for (v = 0; masterdl[v]!=NULL; v++) {
2034 dvar = masterdl[v];
2035 if (dis_active(dvar)) {
2036 dis_set_sindex(dvar,dvar_active);
2037 solverdl[dvar_active] = dvar;
2038 dvar_active++;
2039 }
2040 }
2041 solverdl[dvar_active] = NULL; /* terminator */
2042 return dvar_active;
2043 }
2044
2045
2046 #if USEDCODE
2047
2048 /**
2049 ** Not currently in use, but maybe someday :) . It creates the solver
2050 ** lists based in the master lists. The solver lists build based on
2051 ** this function contains only ACTIVE vars, rels and logrels.
2052 ** We are using the function system_reanalyze instead
2053 **/
2054
2055 void rebuild_solvers_from_masters(slv_system_t sys)
2056 {
2057 struct rel_relation **masterrl;
2058 struct rel_relation **solverrl;
2059 struct logrel_relation **masterll;
2060 struct logrel_relation **solverll;
2061 struct var_variable **mastervl;
2062 struct var_variable **solvervl;
2063 struct dis_discrete **masterdl;
2064 struct dis_discrete **solverdl;
2065 struct w_when **whenlist;
2066 struct w_when *when;
2067 struct dis_discrete *dvar;
2068 struct gl_list_t *symbol_list;
2069 int32 c,len;
2070 int32 nrel_active, nlrel_active;
2071 int32 nvar_active, ndvar_active;
2072
2073 masterrl = slv_get_master_rel_list(sys);
2074 masterll = slv_get_master_logrel_list(sys);
2075 mastervl = slv_get_master_var_list(sys);
2076 masterdl = slv_get_master_dvar_list(sys);
2077 whenlist = slv_get_solvers_when_list(sys);
2078 symbol_list = slv_get_symbol_list(sys);
2079
2080 if( (solvervl = slv_get_solvers_var_list(sys))!=NULL ) {
2081 ascfree(solvervl);
2082 }
2083
2084 if( (solverrl = slv_get_solvers_rel_list(sys))!=NULL ) {
2085 ascfree(solverrl);
2086 }
2087
2088 set_inactive_vars_in_list(mastervl);
2089 set-active_rels_in_list(masterrl);
2090 set_inactive_disvars_in_list(masterdl);
2091 set_active_logrels_in_list(masterll);
2092
2093 for (c=0; masterdl[c]!=NULL; c++) {
2094 dvar = masterdl[c];
2095 dis_set_value_from_inst(dvar,symbol_list);
2096 }
2097
2098 for (c=0; whenlist[c]!=NULL ; c++) {
2099 when = whenlist[c];
2100 if (!when_inwhen(when)) {
2101 set_rels_status_in_when(when,FALSE);
2102 }
2103 }
2104
2105 for (c=0; whenlist[c]!=NULL; c++) {
2106 when = whenlist[c];
2107 if (!when_inwhen(when)) {
2108 analyze_when(when);
2109 }
2110 }
2111
2112 nrel_active = build_rel_solver_from_master(masterrl,solverrl);
2113 nvar_active = build_var_solver_from_master(mastervl,solvervl);
2114
2115 slv_set_solvers_rel_list(sys,solverrl,nrel_active);
2116 slv_set_solvers_var_list(sys,solvervl,nvar_active);
2117
2118 nlrel_active = build_logrel_solver_from_master(masterll,solverll);
2119 ndvar_active = build_disvar_solver_from_master(masterdl,solverdl);
2120
2121 slv_set_solvers_logrel_list(sys,solverll,nlrel_active);
2122 slv_set_solvers_dvar_list(sys,solverdl,ndvar_active);
2123 }
2124
2125 #endif /* USEDCODE */
2126
2127
2128
2129

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