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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (17 years, 8 months ago) by aw0a
File MIME type: text/x-csrc
File size: 39810 byte(s)
Setting up web subdirectory in repository
1 aw0a 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