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

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