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

Contents of /trunk/base/generic/solver/slvDOF.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 708 - (show annotations) (download) (as text)
Tue Jun 27 07:34:31 2006 UTC (17 years, 11 months ago) by johnpye
File MIME type: text/x-csrc
File size: 39702 byte(s)
Replaced some references to ascmalloc with ASC_NEW_ARRAY
1 /*
2 * SlvDOF: ASCEND Degrees of freedom manager
3 * by Benjamin Andrew Allan and Vicente Rico-Ramirez
4 * Created: 7/11/94
5 * Version: $Revision: 1.24 $
6 * Version control file: $RCSfile: slvDOF.c,v $
7 * Date last modified: $Date: 1998/04/09 21:56:09 $
8 * Last modified by: $Author: rv2a $
9 *
10 * This file is part of the SLV solver.
11 *
12 * Copyright (C) 1996 Benjamin Andrew Allan
13 *
14 * The SLV solver is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The SLV solver is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING. COPYING is found in ../compiler.
28 *
29 */
30
31 #include <stdarg.h>
32 #include <utilities/ascConfig.h>
33 #include <utilities/ascSignal.h>
34 #include <compiler/compiler.h>
35 #include <utilities/ascMalloc.h>
36 #include <utilities/ascPanic.h>
37 #include <general/list.h>
38 #include <utilities/mem.h>
39 #include "mtx.h"
40 #include "slv_types.h"
41 #include "var.h"
42 #include "rel.h"
43 #include "discrete.h"
44 #include "conditional.h"
45 #include "logrel.h"
46 #include "bnd.h"
47 #include "relman.h"
48 #include "cond_config.h"
49 #include "slv_common.h"
50 #include "linsol.h"
51 #include "linsolqr.h"
52 #include "slv_client.h"
53 #include "slv_stdcalls.h"
54 #include "slvDOF.h"
55 #include <general/mathmacros.h>
56
57 #define SLVDOF(s) ((slvDOF_system_t)(s))
58
59 #define DEBUG FALSE
60 #define DEBUG_CONSISTENCY_ANALYSIS FALSE
61 #define ELDEBUG 0 /* print debug statements in eligible code */
62 #define KILL 0
63 struct jacobian_data {
64 mtx_matrix_t mtx; /* Transpose gradient of residuals */
65 mtx_region_t reg; /* Current block region */
66 };
67
68 typedef struct slvDOF_system_structure *slvDOF_system_t;
69
70 struct slvDOF_system_structure {
71
72 /**
73 *** Problem definition
74 **/
75 slv_system_t slv; /* slv_system_t back-link */
76 struct var_variable **vlist; /* Variable list (NULL terminated) */
77 struct rel_relation **rlist; /* Relation list (NULL terminated) */
78
79 /**
80 *** Solver information
81 **/
82 unsigned char *rows; /* marks on rows */
83 unsigned char *cols; /* marks on cols */
84 int32 *rowlist; /* list of newly marked rows */
85 int32 *collist; /* list of newly marked cols */
86 int integrity; /* ? Has the system been created */
87 slv_parameters_t p; /* Parameters */
88 slv_status_t s; /* Status (as of iteration end) */
89 int32 cap; /* Order of matrix/vectors */
90 int32 rank; /* Symbolic rank of problem */
91 int32 vused; /* Free and incident variables */
92 int32 vtotal; /* all variables */
93 int32 rused; /* Included relations */
94 int32 rtot; /* rellist len */
95 double clock; /* CPU time */
96
97 /**
98 *** Calculated data (scaled)
99 **/
100 struct jacobian_data J; /* linearized system */
101 };
102
103 /**
104 *** Integrity checks
105 *** ----------------
106 *** check_system(sys)
107 **/
108
109 #define OK ((int)13695914)
110 #define DESTROYED ((int)15784619)
111 static int check_system(slvDOF_system_t sys)
112 /**
113 *** Checks sys for NULL and for integrity.
114 **/
115 {
116 if( sys == NULL ) {
117 FPRINTF(stderr,"ERROR: (slvDOF) check_system\n");
118 FPRINTF(stderr," NULL system handle.\n");
119 return 1;
120 }
121
122 switch( sys->integrity ) {
123 case OK:
124 return 0;
125 case DESTROYED:
126 FPRINTF(stderr,"ERROR: (slvDOF) check_system\n");
127 FPRINTF(stderr," System was recently destroyed.\n");
128 return 1;
129 default:
130 FPRINTF(stderr,"ERROR: (slvDOF) check_system\n");
131 FPRINTF(stderr," System reused or never allocated.\n");
132 return 1;
133 }
134 }
135
136
137 /**
138 *** General input/output routines
139 *** -----------------------------
140 *** print_var_name(out,sys,var)
141 *** print_rel_name(out,sys,rel)
142 **/
143 #define print_var_name(a,b,c) slv_print_var_name((a),(b->slv),(c))
144 #define print_rel_name(a,b,c) slv_print_rel_name((a),(b->slv),(c))
145
146 /**
147 *** Array/vector operations
148 *** ----------------------------
149 *** destroy_array(p)
150 *** create_array(len,type)
151 *** zero_array(arr,len,type)
152 **/
153
154 #define destroy_array(p) \
155 if( (p) != NULL ) ascfree((p))
156 #define create_array(len,type) \
157 ((len) > 0 ? (type *)ascmalloc((len)*sizeof(type)) : NULL)
158 #define create_zero_array(len,type) \
159 ((len) > 0 ? (type *)asccalloc((len),sizeof(type)) : NULL)
160
161 /**
162 *** External routines
163 *** -----------------
164 *** See slv.h
165 **/
166
167 static
168 slvDOF_system_t slvDOF_create()
169 {
170 slvDOF_system_t sys;
171
172 sys = (slvDOF_system_t)asccalloc(1,sizeof(struct slvDOF_system_structure) );
173 sys->integrity = OK;
174 sys->p.output.more_important = stdout;
175 sys->p.output.less_important = NULL;
176 sys->p.partition = TRUE;
177 sys->s.ok = TRUE;
178 sys->s.costsize = 0;
179 sys->s.cost = NULL; /*redundant, but sanity preserving */
180
181 return(sys);
182 }
183
184 static void destroy_matrices(slvDOF_system_t sys)
185 {
186 if( sys->J.mtx ) {
187 mtx_destroy(sys->J.mtx);
188 }
189 destroy_array(sys->rows);
190 destroy_array(sys->cols);
191 destroy_array(sys->rowlist);
192 destroy_array(sys->collist);
193 }
194
195 static
196 int slvDOF_destroy(slvDOF_system_t sys)
197 {
198 if (check_system(sys)) return 1;
199 destroy_matrices(sys);
200 sys->integrity = DESTROYED;
201 if (sys->s.cost) ascfree(sys->s.cost);
202 ascfree( (POINTER)sys );
203 return 0;
204 }
205
206
207 #ifdef THIS_IS_AN_UNUSED_FUNCTION
208 static
209 void slvDOF_get_parameters(sys,parameters)
210 slvDOF_system_t sys;
211 slv_parameters_t *parameters;
212 {
213 check_system(sys);
214 mem_copy_cast(&(sys->p),parameters,sizeof(slv_parameters_t));
215 }
216 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
217
218 #ifdef THIS_IS_AN_UNUSED_FUNCTION
219 static
220 void slvDOF_set_parameters(sys,parameters)
221 slvDOF_system_t sys;
222 slv_parameters_t *parameters;
223 {
224 check_system(sys);
225 mem_copy_cast(parameters,&(sys->p),sizeof(slv_parameters_t));
226 }
227 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
228
229 #ifdef THIS_IS_AN_UNUSED_FUNCTION
230 static
231 void slvDOF_get_status(sys,status)
232 slvDOF_system_t sys;
233 slv_status_t *status;
234 {
235 check_system(sys);
236 mem_copy_cast(&(sys->s),status,sizeof(slv_status_t));
237 }
238 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
239
240 /**
241 *** Performs structural analysis on the system, setting the flags in
242 *** status. The problem must be set up, the relation/variable list
243 *** must be non-NULL. sys->cap, vtotal, rtot must be set.
244 **/
245 static void create_matrices(slv_system_t server,slvDOF_system_t sys)
246 {
247 var_filter_t vfilter;
248 rel_filter_t rfilter;
249
250 sys->J.mtx = mtx_create();
251 mtx_set_order(sys->J.mtx,sys->cap);
252
253 /**
254 *** The server has marked incidence flags already.
255 **/
256 /* count included equalities */
257 rfilter.matchbits = (REL_INCLUDED | REL_EQUALITY | REL_ACTIVE);
258 rfilter.matchvalue = (REL_INCLUDED | REL_EQUALITY | REL_ACTIVE);
259 sys->rused = slv_count_solvers_rels(server,&rfilter);
260
261 /* count free and incident solver vars */
262 vfilter.matchbits = (VAR_FIXED | VAR_INCIDENT | VAR_SVAR | VAR_ACTIVE);
263 vfilter.matchvalue = (VAR_INCIDENT | VAR_SVAR | VAR_ACTIVE);
264 sys->vused = slv_count_solvers_vars(server,&vfilter);
265
266 if (slv_std_make_incidence_mtx(server,sys->J.mtx,&vfilter,&rfilter)) {
267 Asc_Panic(2, "create_matrices",
268 "ABORT! slv_std_make_indicidence_mtx failed");
269 }
270 /* Symbolic analysis */
271 sys->rtot = slv_get_num_solvers_rels(server);
272 sys->vtotal = slv_get_num_solvers_vars(server);
273 mtx_output_assign(sys->J.mtx,sys->rtot,sys->vtotal);
274 /* symbolic rank is set */
275 sys->rank = mtx_symbolic_rank(sys->J.mtx);
276
277 /* create integer,char workspaces. */
278 sys->rows = (unsigned char *)asccalloc(sys->cap,1);
279 sys->cols = (unsigned char *)asccalloc(sys->cap,1);
280 sys->rowlist = ASC_NEW_ARRAY(int32,sys->rtot);
281 sys->collist = ASC_NEW_ARRAY(int32,sys->vtotal);
282
283 /* Initialize Status */
284 sys->s.over_defined = (sys->rused > sys->vused);
285 sys->s.under_defined = (sys->rused < sys->vused);
286 sys->s.struct_singular = (sys->rank < sys->rused);
287 sys->s.block.number_of = mtx_number_of_blocks(sys->J.mtx);
288 }
289
290 static int slvDOF_presolve(slv_system_t server, slvDOF_system_t sys)
291 {
292 check_system(sys);
293 sys->vlist = slv_get_solvers_var_list(server);
294 sys->rlist = slv_get_solvers_rel_list(server);
295 if( sys->vlist == NULL ) {
296 FPRINTF(stderr,"ERROR: (slvDOF) slvDOF_presolve\n");
297 FPRINTF(stderr," Variable list not found.\n");
298 return 1;
299 } else if( sys->rlist == NULL ) {
300 FPRINTF(stderr,"ERROR: (slvDOF) slvDOF_presolve\n");
301 FPRINTF(stderr," Relation list not found.\n");
302 return 1;
303 }
304
305 sys->rtot= slv_get_num_solvers_rels(server);
306 sys->vtotal= slv_get_num_solvers_vars(server);
307 sys->cap = MAX(sys->rtot,sys->vtotal);
308
309 destroy_matrices(sys);
310 create_matrices(server,sys);
311
312 /* Reset status */
313 sys->s.iteration = 0;
314 sys->s.cpu_elapsed = 0.0;
315 sys->s.converged = sys->s.diverged = sys->s.inconsistent = FALSE;
316 sys->s.block.previous_total_size = 0;
317 sys->s.block.current_block = -1;
318 return 0;
319 }
320
321 /* this can be coded recursively, but it's a dumb idea.
322 * see dof.pas:partition_calculated_region.
323 */
324 /* Note: it would be easy to return the list of unreachable relations
325 * (those assigned to ineligible vars) as well. no known use for it though.
326 */
327 int slvDOF_eligible(slv_system_t server, int32 **vil) {
328
329 mtx_matrix_t mtx;
330 int32 *va, *rowlist, *collist;
331 unsigned char *rows=NULL, *cols=NULL;
332 int32 rmax,cmax,mmax,ccur,r,c,rt,ct,ft,rank,vsize;
333 int i,newrows,newcols;
334 struct rel_relation **rp;
335 struct var_variable **vp;
336 var_filter_t vfilter;
337 mtx_coord_t coord;
338 slvDOF_system_t sys;
339
340 if (server==NULL || vil == NULL) {
341 FPRINTF(stderr,"slvDOF_eligible called with NULL.\n");
342 return 0;
343 }
344
345 sys = slvDOF_create();
346
347 *vil = NULL; /* zero return pointer ahead of time */
348 if (sys==NULL) {
349 FPRINTF(stderr,"slvDOF_eligible insufficient memory.\n");
350 return 0;
351 }
352 if (slvDOF_presolve(server,sys)) {
353 FPRINTF(stderr,"slvDOF_eligible failed presolve.");
354 /* need to destroy memory here */
355 slvDOF_destroy(sys);
356 return 0;
357 }
358
359 vp = sys->vlist;
360 rp = sys->rlist;
361 rowlist = sys->rowlist;
362 collist = sys->collist;
363 rows = sys->rows;
364 cols = sys->cols;
365 /* nonsingular and not empty; no list */
366 rmax = sys->rused;
367 rank = sys->rank;
368 if (NULL == (mtx=sys->J.mtx)) return 0; /* there is no jacobian-- wierd */
369 if (!mtx_check_matrix(mtx)) return 0; /* jacobian bad, very wierd */
370
371 cmax=sys->vtotal;
372 mmax=sys->cap;
373
374 rt=ct=ft=0;
375 /* col marks:
376 0 unvisited/ineligible
377 1 visited
378 row marks:
379 0 unvisited
380 1 visited
381 */
382 /* initing things. */
383 newcols = newrows = 0; /* next available ptrs in rellist,collist */
384 /* add free incident unassigned vars to the collist. since
385 * fake and fixed cols never have incidence, we will never
386 * mark them, nor fake or unincluded rows.
387 */
388 vfilter.matchbits = (VAR_INCIDENT | VAR_FIXED | VAR_SVAR | VAR_ACTIVE);
389 vfilter.matchvalue = (VAR_INCIDENT | VAR_SVAR | VAR_ACTIVE);
390 for (ccur=rank; ccur < mmax; ccur++) {
391 i = mtx_col_to_org(mtx,ccur);
392 if ( i < cmax ) { /* if col real */
393 if (var_apply_filter(vp[i],&vfilter)) {
394 collist[newcols++] = ccur;
395 cols[ccur] = 1;
396 ct++;
397 #if ELDEBUG
398 PRINTF("marking free unassigned col %d\n",ccur);
399 #endif
400 }
401 }
402 }
403 /* now mark up everyone who might be eligible */
404 do {
405 while (newcols > 0) {
406 /* mark all rows crossing newly marked cols */
407 /* should we allow incidence in unassigned rows to count?
408 * we do.
409 */
410 coord.col = collist[--newcols];
411 #if ELDEBUG
412 PRINTF("scanning col %d\n",coord.col);
413 #endif
414 coord.row = mtx_FIRST;
415 while (mtx_next_in_col(mtx,&coord,mtx_ALL_ROWS),
416 coord.row != mtx_LAST ) {
417 #if ELDEBUG
418 PRINTF("found row: %d rel:%d\n",coord.col,
419 mtx_row_to_org(mtx,coord.row));
420 #endif
421 if (!rows[coord.row]) { /* if not here before, mark row */
422 rows[coord.row] = 1;
423 rowlist[newrows++] = coord.row;
424 rt++;
425 }
426 }
427 }
428 while (newrows > 0) {
429 /* set new mark flag on assigned col of new rows */
430 r = rowlist[--newrows];
431 if (!cols[r]) {
432 #if ELDEBUG
433 PRINTF("marking col %d\n",r);
434 #endif
435 cols[r] = 1;
436 collist[newcols++] = r;
437 ct++;
438 }
439 }
440 } while (newcols>0);
441 /* now remove the FALSE positive eligible vars */
442 for (r = 0; r < rank; r++) {
443 /* assignments in unreachable rows are ineligible */
444 if (!rows[r] && cols[r]) {
445 #if ELDEBUG
446 PRINTF("removing col %d with unassignable row from eligibles.\n",r);
447 #endif
448 cols[r] = 0;
449 ct--;
450 }
451 }
452 #if ELDEBUG
453 PRINTF("ct= %d, rt= %d\n",ct,rt);
454 #endif
455 va = *vil = create_zero_array(1+ct,int32);
456 vsize = ct;
457 va[ct]=(-1);
458 ct=0;
459
460 /* make up col report */
461 for (c=0;c<mmax;c++) {
462 if (cols[c]==1) {
463 #if ELDEBUG
464 PRINTF("recording marked col %d\n",c);
465 if (ct<vsize) {;
466 #endif
467 va[ct] = mtx_col_to_org(mtx,c);
468 ct++;
469 #if ELDEBUG
470 } else {
471 PRINTF("unexpectedly ");
472 }
473 PRINTF("got eligible col %d\n",c);
474 #endif
475 }
476 }
477 #if ELDEBUG
478 PRINTF("last ct %d\n",ct-1);
479 #endif
480 slvDOF_destroy(sys);
481 return 1;
482 }
483
484 /* this can be coded recursively, but it's a bad idea.
485 see dof.pas:find_swap_vars if you can find the pascal version.
486 Turn your head sideways and you see it is the same code as
487 find eligible with different output and skipping all the debug.
488 */
489
490 int slvDOF_structsing(slv_system_t server, int32 rwhy, int32 **vover,
491 int32 **rcomb, int32 **vfixed) {
492 mtx_matrix_t mtx;
493 const struct var_variable **fv=NULL;
494 int32 *va, *ra, *fa, *rowlist, *collist;
495 unsigned char *rows=NULL, *cols=NULL;
496 int32 rmax,cmax,mmax,rcur,r,c,rt,ct,ft,rank,var,varmax;
497 int i,newrows,newcols;
498 struct rel_relation **rp;
499 struct var_variable **vp;
500 var_filter_t vfilter;
501 mtx_coord_t coord;
502 slvDOF_system_t sys;
503
504
505 if (server==NULL || vover == NULL || rcomb == NULL || vfixed == NULL) {
506 FPRINTF(stderr,"slvDOF_structsing called with NULL.\n");
507 return 0;
508 }
509
510 sys = slvDOF_create();
511
512 if (sys == NULL) {
513 FPRINTF(stderr,"slvDOF_structsing insufficient memory.\n");
514 return 0;
515 }
516 if (slvDOF_presolve(server,sys)) {
517 FPRINTF(stderr,"slvDOF_structsing failed presolve.");
518 slvDOF_destroy(sys);
519 return 0;
520 }
521
522 *vfixed = *vover = *rcomb = NULL; /* zero return pointers ahead of time */
523 vp = sys->vlist;
524 rp = sys->rlist;
525 rowlist = sys->rowlist;
526 collist = sys->collist;
527 rows = sys->rows;
528 cols = sys->cols;
529 /* nonsingular and not empty; no list */
530 rmax = sys->rused;
531 rank = sys->rank;
532 if (sys->rank == rmax && rmax > 0) {
533 slvDOF_destroy(sys);
534 return 0;
535 }
536 if ((mtx=sys->J.mtx)==NULL) return 0; /* there is no jacobian-- wierd */
537 if (!mtx_check_matrix(mtx)) return 0; /* jacobian bad, very wierd */
538
539 cmax=sys->vused;
540 mmax=sys->cap;
541
542 rt=ct=ft=0;
543 if (rwhy > -1) rwhy = mtx_row_to_org(mtx,rwhy);
544 /* col marks:
545 0 unvisited/ineligible
546 1 visited
547 row marks:
548 0 unvisited
549 1 visited
550 */
551 vfilter.matchbits = (VAR_INCIDENT | VAR_FIXED | VAR_SVAR | VAR_ACTIVE);
552 vfilter.matchvalue = vfilter.matchbits;
553 /* initing things. */
554 newcols = newrows = 0; /* next available ptrs in rellist,collist */
555 /* add included unassigned user-interesting equations to rellist.
556 * ignore fake and unincluded rows.
557 */
558 for (rcur = rank; rcur < mmax; rcur++) {
559 i = mtx_row_to_org(mtx,rcur);
560 if ( i < sys->rtot && (rwhy == -1 || rcur == rwhy)) { /* if row real */
561 if (rel_included(rp[i]) && rel_active(rp[i])) {
562 rowlist[newrows++] = rcur;
563 rows[rcur] = 1;
564 rt++;
565 }
566 }
567 }
568 /* now mark up everyone who might be singular */
569 do {
570 while (newrows > 0) {
571 /* mark all cols crossing newly marked rows */
572 coord.row = rowlist[--newrows];
573 coord.col = mtx_FIRST;
574 while (mtx_next_in_row(mtx,&coord,mtx_ALL_COLS),
575 coord.col != mtx_LAST ) {
576 if (coord.row==coord.col) continue; /* skip assigned var of row */
577 if (!cols[coord.col]) { /* if not here before, mark col */
578 cols[coord.col] = 1;
579 collist[newcols++] = coord.col;
580 ct++;
581 }
582 }
583 }
584 while (newcols > 0) {
585 /* set new mark flag on assigned row of new cols */
586 c = collist[--newcols];
587 if (!rows[c]) {
588 rows[c] = 1;
589 rowlist[newrows++] = c;
590 rt++;
591 }
592 }
593 } while (newrows>0);
594
595 va = *vover = create_zero_array(1+ct,int32);
596 ra = *rcomb = create_zero_array(1+rt,int32);
597 va[ct] = ra[rt] = (-1);
598 rt = ct = 0;
599
600 /* mark also the fixed columns in marked equations while making row report */
601 for (r=0; r<mmax; r++) {
602 if (rows[r]>0) {
603 ra[rt] = i = mtx_row_to_org(mtx,r);
604 rt++;
605 fv = rel_incidence_list(rp[i]);
606 varmax = rel_n_incidences(rp[i]);
607 if ( fv != NULL && varmax >0) {
608 for (var = 0; var<varmax; var++) {
609 if (var_apply_filter(fv[var],&vfilter)) {
610 cols[mtx_org_to_col(mtx,var_sindex(fv[var]))] = 1;
611 }
612 }
613 }
614 }
615 }
616 /* make up free singular col report */
617 for (c = 0; c < cmax; c++) {
618 if (cols[c] == 1) {
619 va[ct] = mtx_col_to_org(mtx,c);
620 ct++;
621 }
622 }
623
624 /* make up overspecified cols report */
625 for (c=cmax;c<mmax;c++) {
626 if (cols[c]) ft++;
627 }
628 fa = *vfixed = create_zero_array(1+ft,int32);
629 fa[ft] = (-1);
630 ft=0;
631 for (c = cmax; c < mmax; c++) {
632 if (cols[c]>0) {
633 fa[ft++] = mtx_col_to_org(mtx,c);
634 }
635 }
636 slvDOF_destroy(sys);
637 return 1;
638 }
639
640
641 /*
642 * CONDITIONAL MODELING
643 *
644 * Global Search Consistency Analysis
645 * ---------------------------------------------------------
646 * This Analysis performs a combinatorial search (over all the
647 * alternative sets of equations) to find a consitent
648 * partitioning of the variables (appropriate selection of
649 * degrees of freedom). It checks first if the analysis is
650 * necessary (checks which conditional statements may
651 * change the structure of the system) and it will only consider
652 * for the analysis those statements which may change the structure
653 * of the system.
654 */
655
656
657 /* auxiliar structures */
658 struct bool_values {
659 int32 *pre_val; /* previous values of dis_discrete */
660 int32 *cur_val; /* current values of dis_discrete */
661 };
662
663 /*
664 * In each step of the combinatorial search it is necessary to find out
665 * if the alternative being analyzed is square, underspecified,
666 * structurally singular or overspecified.
667 *
668 * status = 1 ==> underspecified
669 * status = 2 ==> square
670 * status = 3 ==> structurally singular
671 * status = 4 ==> overspecifed
672 * status = 5 ==> Error !! ( insufficient memory, NULL argument,
673 * failed to presolve)
674 *
675 * If the system is underspecified, we will get the number of the
676 * degrees of freedom for the alternative
677 *
678 */
679
680 int32 slvDOF_status(slv_system_t server, int32 *status, int32 *dof)
681 {
682 slvDOF_system_t sys;
683
684 if (server==NULL) {
685 FPRINTF(ASCERR,"slvDOF_status called with NULL.\n");
686 (*status) = 5;
687 return 0;
688 }
689 (*dof) = 0;
690 sys = slvDOF_create();
691
692 if (sys == NULL) {
693 FPRINTF(ASCERR,"slvDOF_status insufficient memory.\n");
694 (*status) = 5;
695 return 0;
696 }
697 if (slvDOF_presolve(server,sys)) {
698 FPRINTF(ASCERR,"slvDOF_status failed presolve.");
699 (*status) = 5;
700 slvDOF_destroy(sys);
701 return 0;
702 }
703
704 if (sys->rank < sys->rused) {
705 (*status) = 3;
706 (*dof) = 0;
707 slvDOF_destroy(sys);
708 return 1;
709 }
710
711 if (sys->rused > sys->vused) {
712 (*status) = 4;
713 slvDOF_destroy(sys);
714 return 1;
715 }
716
717 if ((sys->vused==sys->rused) && (sys->rank ==sys->rused)) {
718 (*status) = 2;
719 slvDOF_destroy(sys);
720 return 1;
721 }
722
723 if (sys->vused > sys->rused) {
724 (*status) = 1;
725 (*dof) = sys->vused - sys->rused;
726 slvDOF_destroy(sys);
727 return 1;
728 }
729
730 return 1;
731 }
732
733
734 /*
735 * the first element of cur_cases is in position one. The result is
736 * the same array, but ordered and starting in position zero
737 */
738 static int32 *reorder_cases(int32 *cur_cases, int32 ncases)
739 {
740 int32 cur_case,pos = 0,tmp_num,c,ind;
741 int32 *result;
742
743 result = create_array(ncases,int32);
744 for (c=1; c<=ncases; c++) {
745 tmp_num = 0;
746 for (ind=1; ind<=ncases; ind++) {
747 cur_case = cur_cases[ind];
748 if (tmp_num < cur_case) {
749 pos = ind;
750 tmp_num = cur_case;
751 }
752 }
753 cur_cases[pos] = 0;
754 result[ncases-c] = tmp_num;
755 }
756
757 destroy_array(cur_cases);
758 return result;
759 }
760
761 /*
762 * Get the eligible var list for each alternative
763 * Return:
764 * 1 means everything went right
765 * 0 means the analysis has failed with the current parititioning
766 * -1 means a memory problem has occurred
767 */
768 static int32 get_eligible_vars(slv_system_t server,struct gl_list_t *disvars,
769 int *combinations, int32 *terminate)
770 {
771 struct var_variable **vslist;
772 struct var_variable **vmlist;
773 struct var_variable *mvar, *svar;
774 var_filter_t vfilter;
775 int32 *cur_cases;
776 int32 *correct_cases;
777 int32 *vars;
778 int32 v, count = 0, ind;
779 int32 ncases;
780 int32 mnum;
781 int32 status,dof;
782
783 vslist = slv_get_solvers_var_list(server);
784 vmlist = slv_get_master_var_list(server);
785 mnum = slv_get_num_master_vars(server);
786 for (v=0; v<mnum; v++) {
787 mvar = vmlist[v];
788 var_set_eligible_in_subregion(mvar,FALSE);
789 }
790
791 cur_cases = cases_matching(disvars,&ncases);
792 correct_cases = reorder_cases(cur_cases,ncases);
793 set_active_rels_in_subregion(server,correct_cases,ncases,disvars);
794 set_active_vars_in_subregion(server);
795 destroy_array(correct_cases);
796
797 #if DEBUG_CONSISTENCY_ANALYSIS
798 FPRINTF(ASCERR,"Analyzing alternative:\n");
799 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
800
801 if (!slvDOF_status(server,(&status),(&dof))) {
802 FPRINTF(ASCERR,"ERROR in combinatorial search\n");
803 FPRINTF(ASCERR,"Combinatorial search aborted\n");
804 return -1;
805 } else {
806 if (status == 3) {
807 #if DEBUG_CONSISTENCY_ANALYSIS
808 FPRINTF(ASCERR,"Alternative is structurally singular\n");
809 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
810 (*terminate) = 0;
811 return 0;
812 } else {
813 if (status == 4) {
814 #if DEBUG_CONSISTENCY_ANALYSIS
815 FPRINTF(ASCERR,"Alternative is overspecified\n");
816 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
817 (*terminate) = 0;
818 return 0;
819 }
820 }
821 }
822
823 if (status == 1) {
824 (*terminate) = 0;
825 #if DEBUG_CONSISTENCY_ANALYSIS
826 FPRINTF(ASCERR,"Alternative has % d degrees of freedom.\n",dof);
827 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
828 if (slvDOF_eligible(server,&(vars))) {
829 count = 0;
830 while (vars[count] != -1) {
831 ind = vars[count];
832 svar = vslist[ind];
833 v = var_mindex(svar);
834 mvar = vmlist[v];
835 var_set_eligible_in_subregion(mvar,TRUE);
836 count++;
837 }
838 destroy_array(vars);
839 }
840 if (dof > count) {
841 #if DEBUG_CONSISTENCY_ANALYSIS
842 FPRINTF(ASCERR,
843 "Alternative does not have enough number of eligible vars\n");
844 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
845 return 0;
846 }
847 }
848
849 if (status == 2) {
850 #if DEBUG_CONSISTENCY_ANALYSIS
851 FPRINTF(ASCERR,"Alternative is square.\n");
852 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
853 }
854
855 vfilter.matchbits = (VAR_ACTIVE | VAR_INCIDENT | VAR_SVAR
856 | VAR_ELIGIBLE_IN_SUBREGION);
857 vfilter.matchvalue = (VAR_ACTIVE | VAR_INCIDENT | VAR_SVAR);
858
859 for (v=0; v<mnum; v++) {
860 mvar = vmlist[v];
861 if(var_apply_filter(mvar,&vfilter)) {
862 var_set_eligible(mvar,FALSE);
863 }
864 var_set_eligible_in_subregion(mvar,FALSE);
865 }
866 (*combinations)++;
867 return 1;
868 }
869
870 /*
871 * Get the eligible set of variables for each of the combinations generated
872 * by modifying the values of the boolean variables
873 * Return:
874 * 1 means everything went right
875 * 0 means the analysis has failed with the current parititioning
876 * -1 means a memory problem has occurred
877 */
878 static int32 do_search_consistency_combinations(slv_system_t server,
879 struct gl_list_t *disvars,
880 int32 dlen, int32 d,
881 int32 *combinations,
882 int32 *terminate)
883 {
884 struct dis_discrete *cur_dis;
885 int32 dpo, result;
886
887 if(d < dlen) {
888 dpo = d + 1;
889 cur_dis = (struct dis_discrete *)(gl_fetch(disvars,d));
890 dis_set_boolean_value(cur_dis,TRUE);
891 result = do_search_consistency_combinations(server,disvars,dlen,
892 dpo,combinations,terminate);
893 if (result != 1) {
894 return result;
895 }
896
897 dis_set_boolean_value(cur_dis,FALSE);
898 result = do_search_consistency_combinations(server,disvars,dlen,
899 dpo,combinations,terminate);
900 if (result != 1) {
901 return result;
902 }
903
904 } else {
905 if (d == dlen) {
906 cur_dis = (struct dis_discrete *)(gl_fetch(disvars,d));
907 dis_set_boolean_value(cur_dis,TRUE);
908 result = get_eligible_vars(server,disvars,combinations,terminate);
909 if (result != 1) {
910 return result;
911 }
912 dis_set_boolean_value(cur_dis,FALSE);
913 result = get_eligible_vars(server,disvars,combinations,terminate);
914 if (result != 1) {
915 return result;
916 }
917 } else {
918 FPRINTF(ASCERR,"ERROR: do_search_consistency_combinations \n");
919 FPRINTF(ASCERR," Wrong discrete var index as argument \n");
920 }
921 }
922 return 1;
923 }
924
925 /*
926 * Storing original values of boolean variables
927 */
928 static void storing_original_bool_values(struct gl_list_t *bollist,
929 struct bool_values *bval)
930 {
931 struct dis_discrete *dvar;
932 int32 d, dlen;
933
934 dlen = gl_length(bollist);
935 bval->pre_val = create_array(dlen,int32);
936 bval->cur_val = create_array(dlen,int32);
937 for (d=1; d<=dlen; d++){
938 dvar = (struct dis_discrete *)gl_fetch(bollist,d);
939 bval->cur_val[d-1] = dis_value(dvar);
940 bval->pre_val[d-1] = dis_previous_value(dvar);
941 }
942 }
943
944 /*
945 * Restoring original values of boolean variables
946 */
947 static void restoring_original_bool_values(struct gl_list_t *bollist,
948 struct bool_values *bval)
949 {
950 struct dis_discrete *dvar;
951 int32 d, dlen;
952
953 dlen = gl_length(bollist);
954 for (d=1; d<=dlen; d++){
955 dvar = (struct dis_discrete *)gl_fetch(bollist,d);
956 dis_set_boolean_value(dvar,bval->cur_val[d-1]);
957 dis_set_value(dvar,bval->cur_val[d-1]);
958 dis_set_previous_value(dvar,bval->pre_val[d-1]);
959 }
960 destroy_array(bval->cur_val);
961 destroy_array(bval->pre_val);
962 }
963
964 /*
965 * Restoring orignal configuration of the system
966 */
967 static void restore_configuration(slv_system_t server,
968 struct gl_list_t *bollist)
969
970 {
971 int32 *cur_cases, *correct_cases;
972 int32 ncases;
973
974 cur_cases = cases_matching(bollist,&ncases);
975 correct_cases = reorder_cases(cur_cases,ncases);
976 set_active_rels_in_subregion(server,correct_cases,ncases,bollist);
977 set_active_vars_in_subregion(server);
978 destroy_array(correct_cases);
979 }
980
981 /*
982 * Perform a combinatorial consistency analysis for all the alternatives
983 * that we can get from the combination of boolean values for the boolean
984 * variables given in the list passed as argument
985 */
986
987 static int32 perform_combinatorial_consistency_analysis(slv_system_t server,
988 struct gl_list_t *bollist,
989 int32 *terminate)
990 {
991 struct var_variable **vmlist;
992 struct var_variable *mvar;
993 var_filter_t vfilter;
994 int32 *globeli = NULL;
995 int32 d, dlen, max_comb, combinations;
996 int32 mnum, v, elnum;
997 int32 result;
998 int32 iter;
999
1000 /*
1001 * Initializing eligible bit for variables
1002 */
1003 vmlist = slv_get_master_var_list(server);
1004 mnum = slv_get_num_master_vars(server);
1005 for (v=0; v<mnum; v++) {
1006 mvar = vmlist[v];
1007 var_set_eligible(mvar,TRUE);
1008 }
1009
1010 dlen = gl_length(bollist);
1011
1012 max_comb = 1;
1013 for (d = 1; d<=dlen; d++) {
1014 max_comb = max_comb * 2;
1015 }
1016
1017 d = 1;
1018 combinations = 0;
1019 #if DEBUG_CONSISTENCY_ANALYSIS
1020 FPRINTF(ASCERR,"S e a r c h i n g \n");
1021 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1022 result = do_search_consistency_combinations(server,bollist,dlen,d,
1023 &(combinations),terminate);
1024
1025 if (result != 1) {
1026 #if DEBUG_CONSISTENCY_ANALYSIS
1027 FPRINTF(ASCERR,"returning failed search after S e a r c h i n g\n");
1028 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1029 return result;
1030 }
1031
1032 /*
1033 * Getting the "globally" eligible variables
1034 */
1035 vfilter.matchbits = (VAR_INCIDENT | VAR_SVAR | VAR_ELIGIBLE | VAR_FIXED);
1036 vfilter.matchvalue = (VAR_INCIDENT | VAR_SVAR | VAR_ELIGIBLE);
1037 elnum = slv_count_master_vars(server,&vfilter);
1038
1039 if (elnum > 0) {
1040 globeli = ASC_NEW_ARRAY(int32,elnum);
1041 elnum = 0;
1042 for (v=0; v<mnum; v++) {
1043 mvar = vmlist[v];
1044 if(var_apply_filter(mvar,&vfilter)) {
1045 #if DEBUG_CONSISTENCY_ANALYSIS
1046 FPRINTF(ASCERR,"Eligible index = %d \n",v);
1047 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1048 globeli[elnum] = v;
1049 elnum++;
1050 }
1051 }
1052 }
1053
1054 /*
1055 * Recursively analysis
1056 */
1057
1058 if ((*terminate) == 1) {
1059 if (elnum != 0) {
1060 #if DEBUG_CONSISTENCY_ANALYSIS
1061 FPRINTF(ASCERR,"ERROR: All alternatives are square but the \n");
1062 FPRINTF(ASCERR," Eligible set is not null\n");
1063 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1064 destroy_array(globeli);
1065 }
1066 return 1;
1067 } else {
1068 if (elnum == 0) {
1069 #if DEBUG_CONSISTENCY_ANALYSIS
1070 FPRINTF(ASCERR,"No globally eligible variables to be fixed.\n");
1071 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1072 return 0;
1073 }
1074
1075 for (v=0; v<elnum; v++) {
1076 iter = 1;
1077 mvar = vmlist[globeli[v]];
1078 var_set_fixed(mvar,TRUE);
1079 var_set_potentially_fixed(mvar,TRUE);
1080 #if DEBUG_CONSISTENCY_ANALYSIS
1081 FPRINTF(ASCERR,"Fixing index = %d \n",globeli[v]);
1082 FPRINTF(ASCERR,"N e s t e d S e a r c h \n");
1083 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1084 result = perform_combinatorial_consistency_analysis(server,bollist,
1085 &iter);
1086 if (result != 1) {
1087 #if DEBUG_CONSISTENCY_ANALYSIS
1088 FPRINTF(ASCERR,"%d eliminated\n",globeli[v]);
1089 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1090 var_set_fixed(mvar,FALSE);
1091 var_set_potentially_fixed(mvar,FALSE);
1092 continue;
1093 } else {
1094 if (iter == 1) {
1095 (*terminate) = 1;
1096 #if DEBUG_CONSISTENCY_ANALYSIS
1097 FPRINTF(ASCERR,"%d Acepted \n",globeli[v]);
1098 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1099 destroy_array(globeli);
1100 return 1;
1101 } else {
1102 var_set_fixed(mvar,FALSE);
1103 var_set_potentially_fixed(mvar,FALSE);
1104 continue;
1105 }
1106 }
1107 }
1108 destroy_array(globeli);
1109 #if DEBUG_CONSISTENCY_ANALYSIS
1110 FPRINTF(ASCERR,"returning 0 after nested search\n");
1111 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1112 return 0;
1113 }
1114 }
1115
1116 /*
1117 * Perform a combinatorial consistency analysis for all the alternatives
1118 * that we can get from the combination of boolean values for the boolean
1119 * variables given in the list passed as argument
1120 */
1121
1122 static int32 get_globally_consistent_set(slv_system_t server,
1123 struct gl_list_t *bollist,
1124 int32 **eliset)
1125 {
1126 struct var_variable **vmlist;
1127 struct var_variable *mvar;
1128 var_filter_t vfilter;
1129 int32 d, dlen, max_comb, combinations;
1130 int32 mnum, v, elnum;
1131 int32 terminate;
1132 int32 result;
1133
1134 /*
1135 * Initializing eligible bit for variables
1136 */
1137 vmlist = slv_get_master_var_list(server);
1138 mnum = slv_get_num_master_vars(server);
1139 for (v=0; v<mnum; v++) {
1140 mvar = vmlist[v];
1141 var_set_eligible(mvar,TRUE);
1142 }
1143
1144 dlen = gl_length(bollist);
1145
1146 max_comb = 1;
1147 for (d = 1; d<=dlen; d++) {
1148 max_comb = max_comb * 2;
1149 }
1150
1151 /*
1152 * initializing
1153 */
1154 *eliset = NULL;
1155 terminate = 1;
1156
1157 d = 1;
1158 combinations = 0;
1159 result = do_search_consistency_combinations(server,bollist,dlen,d,
1160 &(combinations),&terminate);
1161 if (result != 1) {
1162 if (terminate == 0) {
1163 #if DEBUG_CONSISTENCY_ANALYSIS
1164 FPRINTF(ASCERR,"ERROR: some alternatives are either singular or\n");
1165 FPRINTF(ASCERR,"overspecified. All the alternatives have to be\n");
1166 FPRINTF(ASCERR,
1167 "either square or underspecified to complete the analysis\n");
1168 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1169 }
1170 return 0;
1171 }
1172
1173 /*
1174 * Getting the "globally" eligible variables
1175 */
1176 vfilter.matchbits = (VAR_INCIDENT | VAR_SVAR | VAR_ELIGIBLE | VAR_FIXED);
1177 vfilter.matchvalue = (VAR_INCIDENT | VAR_SVAR | VAR_ELIGIBLE);
1178 elnum = slv_count_master_vars(server,&vfilter);
1179
1180 *eliset = (int32 *)ascmalloc((elnum+1)*sizeof(int32));
1181 elnum = 0;
1182 for (v=0; v<mnum; v++) {
1183 mvar = vmlist[v];
1184 if(var_apply_filter(mvar,&vfilter)) {
1185 (*eliset)[elnum] = v;
1186 elnum++;
1187 }
1188 }
1189 (*eliset)[elnum] = -1;
1190
1191 if (elnum == 0) {
1192 if (terminate == 0) {
1193 #if DEBUG_CONSISTENCY_ANALYSIS
1194 FPRINTF(ASCERR,
1195 "Some alternatives are underspecified, but there does\n");
1196 FPRINTF(ASCERR,"not exist a set of eligible variables consistent \n");
1197 FPRINTF(ASCERR,"with all the alternatives\n");
1198 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1199 } else {
1200 #if DEBUG_CONSISTENCY_ANALYSIS
1201 FPRINTF(ASCERR,"All alternatives are already square\n");
1202 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1203 }
1204 return 0;
1205 } else {
1206 if (terminate == 1) {
1207 #if DEBUG_CONSISTENCY_ANALYSIS
1208 FPRINTF(ASCERR,"All alternatives are square but the \n");
1209 FPRINTF(ASCERR,"Eligible set is not null\n");
1210 #endif /* DEBUG_CONSISTENCY_ANALYSIS */
1211 }
1212 }
1213 return 1;
1214 }
1215
1216
1217 /*
1218 * Get the list of boolean variables which can potentially cause
1219 * a change in the structure of the problem
1220 */
1221 static
1222 struct gl_list_t *get_list_of_booleans_for_analysis(slv_system_t server)
1223 {
1224 dis_filter_t dfilter;
1225 struct dis_discrete **boolist;
1226 struct dis_discrete *dvar;
1227 struct gl_list_t *bana;
1228 struct gl_list_t *whens;
1229 struct w_when *when;
1230 int32 d, dnum, w, wlen, numdcs;
1231
1232 boolist = slv_get_solvers_dvar_list(server);
1233 dnum = slv_get_num_solvers_dvars(server);
1234 for (d=0; d<dnum; d++) {
1235 dvar = boolist[d];
1236 if(dis_inwhen(dvar) && dis_boolean(dvar)) {
1237 whens = dis_whens_list(dvar);
1238 if ( (whens != NULL) && (gl_length(whens) != 0)) {
1239 dis_set_changes_structure(dvar,FALSE);
1240 wlen = gl_length(whens);
1241 for (w=1; w<=wlen; w++) {
1242 when = (struct w_when *)gl_fetch(whens,w);
1243 if (when_changes_structure(when)) {
1244 dis_set_changes_structure(dvar,TRUE);
1245 break;
1246 }
1247 }
1248 } else {
1249 dis_set_changes_structure(dvar,FALSE);
1250 }
1251 }
1252 }
1253
1254 dfilter.matchbits = (DIS_CHANGES_STRUCTURE);
1255 dfilter.matchvalue = (DIS_CHANGES_STRUCTURE);
1256 numdcs = slv_count_solvers_dvars(server,&dfilter);
1257
1258 bana = gl_create(numdcs);
1259 for (d=0;d<dnum; d++) {
1260 dvar = boolist[d];
1261 if (dis_changes_structure(dvar)) {
1262 gl_append_ptr(bana,dvar);
1263 }
1264 }
1265
1266 return bana;
1267 }
1268
1269 /*
1270 * Get a set of eligible variables consitent for all the alternative
1271 * configurations
1272 */
1273 int32 get_globally_consistent_eligible(slv_system_t server,int32 **eliset)
1274 {
1275
1276 struct dis_discrete **boolist;
1277 struct dis_discrete *dvar;
1278 struct gl_list_t *bana;
1279 struct bool_values bval;
1280 int32 need_consistency_analysis;
1281 int32 result, d, dnum;
1282
1283 if (server==NULL || eliset == NULL) {
1284 FPRINTF(ASCERR," get_globally_consistent_eligible called with NULL.\n");
1285 return 0;
1286 }
1287
1288 boolist = slv_get_solvers_dvar_list(server);
1289 dnum = slv_get_num_solvers_dvars(server);
1290 need_consistency_analysis = slv_need_consistency(server);
1291
1292 if(boolist == NULL ) {
1293 FPRINTF(ASCERR,"ERROR: get_globally_consistent_eligible\n");
1294 FPRINTF(ASCERR," Discrete Variable list was never set.\n");
1295 return 0;
1296 }
1297
1298 if (!(need_consistency_analysis)) {
1299 FPRINTF(ASCERR,"Global analysis is not required\n");
1300 FPRINTF(ASCERR,"All the alternatives have the same structure \n");
1301 return 1;
1302 }
1303
1304 bana = get_list_of_booleans_for_analysis(server);
1305
1306 if (bana == NULL) {
1307 FPRINTF(ASCERR,"ERROR: get_globally_consistent_eligible \n");
1308 FPRINTF(ASCERR," List of boolean vars could not be found\n");
1309 return 0;
1310 }
1311
1312 storing_original_bool_values(bana,&(bval));
1313 result = get_globally_consistent_set(server,bana,eliset);
1314
1315 restoring_original_bool_values(bana,&(bval));
1316 restore_configuration(server,bana);
1317 for (d=0;d<dnum; d++) {
1318 dvar = boolist[d];
1319 if (dis_changes_structure(dvar)) {
1320 dis_set_changes_structure(dvar,FALSE);
1321 }
1322 }
1323 gl_destroy(bana);
1324
1325 if (result == 1) {
1326 return 1;
1327 } else {
1328 return 0;
1329 }
1330
1331 }
1332
1333 /*
1334 * Main function of the consistency analysis.
1335 */
1336 int32 consistency_analysis(slv_system_t server,int32 **fixed)
1337 {
1338
1339 struct dis_discrete **boolist;
1340 struct dis_discrete *dvar;
1341 struct var_variable **vmlist;
1342 struct var_variable *mvar;
1343 struct gl_list_t *bana;
1344 var_filter_t vfilter;
1345 struct bool_values bval;
1346 int32 need_consistency_analysis;
1347 int32 result, elnum, mnum, v;
1348 int32 terminate;
1349 int32 d, dnum;
1350
1351 if (server==NULL || fixed == NULL) {
1352 FPRINTF(ASCERR,"consistency_analysis called with NULL.\n");
1353 return 0;
1354 }
1355
1356 boolist = slv_get_solvers_dvar_list(server);
1357 dnum = slv_get_num_solvers_dvars(server);
1358 need_consistency_analysis = slv_need_consistency(server);;
1359
1360 if(boolist == NULL ) {
1361 FPRINTF(ASCERR,"ERROR: consistency_analysis\n");
1362 FPRINTF(ASCERR," Discrete Variable list was never set.\n");
1363 return 0;
1364 }
1365
1366 if (!(need_consistency_analysis)) {
1367 FPRINTF(ASCERR,"Consistency analysis is not required\n");
1368 FPRINTF(ASCERR,"All the alternatives have the same structure \n");
1369 return 1;
1370 }
1371
1372 bana = get_list_of_booleans_for_analysis(server);
1373
1374 if (bana == NULL || gl_length(bana) == 0) {
1375 FPRINTF(ASCERR,"ERROR: consistency_analysis\n");
1376 FPRINTF(ASCERR," List of boolean vars could not be found\n");
1377 return 0;
1378 }
1379
1380 storing_original_bool_values(bana,&(bval));
1381
1382 /*
1383 * initializing
1384 */
1385 *fixed = NULL;
1386 terminate = 1;
1387
1388 vmlist = slv_get_master_var_list(server);
1389 mnum = slv_get_num_master_vars(server);
1390
1391 vfilter.matchbits = (VAR_POTENTIALLY_FIXED);
1392 vfilter.matchvalue = (VAR_POTENTIALLY_FIXED);
1393
1394 result = perform_combinatorial_consistency_analysis(server,bana,&terminate);
1395 if (result == 1) {
1396 /*
1397 * Getting the set of eligible variables
1398 */
1399 elnum = slv_count_master_vars(server,&vfilter);
1400 *fixed = (int32 *)ascmalloc((elnum+1)*sizeof(int32));
1401 elnum = 0;
1402 for (v=0; v<mnum; v++) {
1403 mvar = vmlist[v];
1404 if(var_apply_filter(mvar,&vfilter)) {
1405 var_set_fixed(mvar,FALSE);
1406 var_set_potentially_fixed(mvar,FALSE);
1407 (*fixed)[elnum] = v;
1408 elnum++;
1409 }
1410 }
1411 (*fixed)[elnum] = -1;
1412
1413 for (d=0;d<dnum; d++) {
1414 dvar = boolist[d];
1415 if (dis_changes_structure(dvar)) {
1416 dis_set_changes_structure(dvar,FALSE);
1417 }
1418 }
1419 restoring_original_bool_values(bana,&(bval));
1420 restore_configuration(server,bana);
1421 gl_destroy(bana);
1422 return 1;
1423 } else {
1424 for (v=0; v<mnum; v++) {
1425 mvar = vmlist[v];
1426 if(var_apply_filter(mvar,&vfilter)) {
1427 var_set_fixed(mvar,FALSE);
1428 var_set_potentially_fixed(mvar,FALSE);
1429 }
1430 }
1431
1432 for (d=0;d<dnum; d++) {
1433 dvar = boolist[d];
1434 if (dis_changes_structure(dvar)) {
1435 dis_set_changes_structure(dvar,FALSE);
1436 }
1437 }
1438 restoring_original_bool_values(bana,&(bval));
1439 restore_configuration(server,bana);
1440 gl_destroy(bana);
1441 return 0;
1442 }
1443
1444 }
1445
1446

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