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