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

Contents of /trunk/ascend4/solver/slvDOF.c

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

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