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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 808 - (hide annotations) (download) (as text)
Fri Aug 4 09:08:16 2006 UTC (17 years, 1 month ago) by johnpye
File MIME type: text/x-csrc
File size: 56306 byte(s)
Some debug output in cond_config.
Working on adding PyGTK GUI functionality to show inactive relaitons.
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 johnpye 399 #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 aw0a 1 #define _SLV_SERVER_C_SEEN_
45 johnpye 399 #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 aw0a 1
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 johnpye 808 /**
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 aw0a 1 struct gl_list_t *rels;
100     struct rel_relation *rel;
101     int32 r,rlen;
102    
103 johnpye 808 CONSOLE_DEBUG("...");
104    
105 aw0a 1 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 johnpye 808 if(!value){
110     CONSOLE_DEBUG("INACTIVE REL AT %p",rel);
111     }
112 aw0a 1 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 johnpye 89 int32 v,vind,vcount = 0;
940     int32 aux,vin,vindex = 0;
941 aw0a 1
942 johnpye 669 index = ASC_NEW_ARRAY(int32,vlen);
943     ordered_index = ASC_NEW_ARRAY(int32,vlen);
944 aw0a 1
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 johnpye 669 inc = ASC_NEW_ARRAY(int32,ninc);
1180 aw0a 1 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 johnpye 89 int32 r,rlen,rin,rind = 0;
1208     int32 num_inc = 0, v, vv, vindex = 0, vind;
1209 aw0a 1 int32 glob_count, n1, n2;
1210     int32 *num_rel, *ordered_num_rel;
1211     int32 **var_ind;
1212    
1213     rlen = gl_length(scratch);
1214 johnpye 669 num_rel = ASC_NEW_ARRAY(int32,rlen);
1215     ordered_num_rel = ASC_NEW_ARRAY(int32,rlen);
1216 aw0a 1 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 johnpye 89 int32 r, rin, rlen, rcount = 0, rind;
1305     int32 index = 0, aux, glob_count;
1306 aw0a 1
1307     rels = when_case_rels_list(cur_case);
1308     if (rels != NULL) {
1309     rlen = gl_length(rels);
1310     if (rlen > 1) {
1311 johnpye 669 num_inc = ASC_NEW_ARRAY(int32,rlen);
1312     ordered_num_inc = ASC_NEW_ARRAY(int32,rlen);
1313 aw0a 1 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