/[ascend]/trunk/ascend4/solver/cond_config.c
ViewVC logotype

Annotation of /trunk/ascend4/solver/cond_config.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (17 years, 8 months ago) by aw0a
File MIME type: text/x-csrc
File size: 56406 byte(s)
Setting up web subdirectory in repository
1 aw0a 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 "solver/mtx.h"
39     #include "solver/slv_types.h"
40     #include "solver/var.h"
41     #include "solver/discrete.h"
42     #include "solver/conditional.h"
43     #include "solver/linsolqr.h"
44     #define _SLV_SERVER_C_SEEN_
45     #include "compiler/extcall.h"
46     #include "solver/rel.h"
47     #include "solver/logrel.h"
48     #include "solver/bnd.h"
49     #include "solver/slv_server.h"
50     #include "solver/system.h"
51     #include "solver/analyze.h"
52     #include "solver/cond_config.h"
53     #include "solver/linsol.h"
54     #include "solver/slv_common.h"
55     #include "solver/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;
935     int32 aux,vin,vindex;
936    
937     index = (int32 *)ascmalloc(vlen*sizeof(int32));
938     ordered_index = (int32 *)ascmalloc(vlen*sizeof(int32));
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 = (int32 *)ascmalloc(ninc*sizeof(int32));
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;
1203     int32 num_inc, v, vv, vindex, 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 = (int32 *)ascmalloc(rlen*sizeof(int32));
1210     ordered_num_rel = (int32 *)ascmalloc(rlen*sizeof(int32));
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, rind;
1300     int32 index, 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 = (int32 *)ascmalloc(rlen*sizeof(int32));
1307     ordered_num_inc = (int32 *)ascmalloc(rlen*sizeof(int32));
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