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