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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (17 years, 6 months ago) by aw0a
File MIME type: text/x-csrc
File size: 98417 byte(s)
Setting up web subdirectory in repository
1 /*
2 * Problem Analysis Routines
3 * by Benjamin Andrew Allan
4 * 5/19/96
5 * Version: $Revision: 1.56 $
6 * Version control file: $RCSfile: analyze.c,v $
7 * Date last modified: $Date: 2003/08/23 18:43:12 $
8 * Last modified by: $Author: ballan $
9 * Copyright(C) 1996 Benjamin Andrew Allan
10 *
11 * This file is part of the ASCEND IV math programming system.
12 *
13 * The SLV solver is free software; you can redistribute
14 * it and/or modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) any later version.
17 *
18 * The SLV solver is distributed in hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with the program; if not, write to the Free Software Foundation,
25 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
26 * COPYING. COPYING is found in ../compiler.
27 *
28 *
29 * These functions are the start of a new design for feeding
30 * solvers from the ASCEND compiler or any arbitrary backend.
31 *
32 * The intention is that eventually the other code in the solver
33 * directory will really be for *solution algorithms* and the
34 * definition of a *problem* will come from here. In essence, most
35 * of what was solver/system.c will be here. Negotiating directly
36 * with the ASCEND instance hierarchy should not be a solver's
37 * job.
38 * The goal of this module is to CREATE a slv_system_t data structure
39 * capable of supporting code generation, an interactive interface, and
40 * in-core solvers, while being expandable in the future to out of core
41 * solvers/external-process solvers.
42 *
43 * A secondary goal is to have nonlinear solver files be independent of
44 * all the compiler directory files except ascmalloc.h.
45 * The present fly in the ointment is expr.h because of the objective fcns.
46 * The relman and exprman modules go away because they are indicative of
47 * functionality that belongs either in the compiler or rel.c.
48 * If we meet this goal, then it is a simple matter to connect any
49 * arbitrary compiler backend to the solver API by replacing the rel
50 * and var and analyze modules.
51 *
52 */
53
54 #include <stdarg.h>
55 #include "utilities/ascConfig.h"
56 #include "utilities/ascPanic.h"
57 #include "utilities/ascMalloc.h"
58 #include "general/list.h"
59 #include "general/dstring.h"
60 #include "compiler/compiler.h"
61 #include "compiler/symtab.h"
62 #include "compiler/instance_enum.h"
63 #include "compiler/fractions.h"
64 #include "compiler/dimen.h"
65 #include "compiler/atomvalue.h"
66 #include "compiler/parentchild.h"
67 #include "compiler/visitinst.h"
68 #include "compiler/types.h"
69 #include "compiler/exprs.h"
70 #include "compiler/sets.h"
71 #include "compiler/mathinst.h"
72 #include "compiler/instquery.h"
73 #include "compiler/instance_io.h"
74 #include "compiler/relation_type.h"
75 #include "compiler/find.h"
76 #include "compiler/extfunc.h"
77 #include "compiler/extcall.h"
78 #include "compiler/relation.h"
79 #include "compiler/functype.h"
80 #include "compiler/safe.h"
81 #include "compiler/relation_util.h"
82 #include "compiler/logical_relation.h"
83 #include "compiler/logrelation.h"
84 #include "compiler/logrel_util.h"
85 #include "compiler/case.h"
86 #include "compiler/when_util.h"
87 #include "solver/mtx.h"
88 #include "solver/slv_types.h"
89 #include "solver/var.h"
90 #define _SLV_SERVER_C_SEEN_
91 #include "solver/rel.h"
92 #include "solver/logrel.h"
93 #include "solver/discrete.h"
94 #include "solver/conditional.h"
95 #include "solver/bnd.h"
96 #include "solver/slv_server.h"
97 #include "solver/slv_common.h"
98 #include "solver/linsol.h"
99 #include "solver/linsolqr.h"
100 #include "solver/slv_client.h"
101 #include "solver/cond_config.h"
102 #include "solver/analyze.h"
103
104 /* stuff to get rid of */
105 #ifndef MAX_VAR_IN_LIST
106 #define MAX_VAR_IN_LIST 20
107 #endif /* MAX_VAR_IN_LIST */
108 #define DEBUG_ANALYSIS FALSE
109
110 /* symbol table entries we need */
111 #define INCLUDED_A g_strings[0]
112 #define FIXED_A g_strings[1]
113 #define BASIS_A g_strings[2]
114 static symchar *g_strings[3];
115
116
117 /*
118 * Forward declaration
119 */
120 static void ProcessModelsInWhens(struct Instance *, struct gl_list_t *,
121 struct gl_list_t *, struct gl_list_t *);
122
123 /*
124 * Global variable. Set to true by classify if need be
125 */
126 static int g_bad_rel_in_list;
127
128
129 /* used to give an integer value to each symbol used in a when */
130 struct gl_list_t *g_symbol_values_list = NULL;
131
132 struct varip {
133 struct var_variable *data; /* ptr to destination of data */
134 int index; /* master gl index */
135 int incident; /* set 0 in classify_instance,
136 1 make_master_lists */
137 int in_block; /* set 0 in classify_instance */
138 int fixed; /* set in classify_instance */
139 int solvervar; /* set in classify_instance */
140 int active; /* is this var a part of my problem */
141 int basis; /* set in classify_instance */
142 };
143
144
145 struct disvarip {
146 struct dis_discrete *data; /* ptr to destination of data */
147 int index; /* master gl index */
148 int fixed; /* set in classify_instance */
149 int isconst; /* is this dis var constant ? */
150 int distype; /* 0 boolean, 1 int, -1 symbol */
151 int value; /* integer value of the variable */
152 int incident; /* is it incident in a logrel */
153 int inwhen; /* is it in a when var list */
154 int booleanvar; /* Not sure if I need it */
155 int active; /* is this disvar a part of my problem */
156 };
157
158
159 struct relip {
160 struct rel_relation *data; /* ptr to destination of data */
161 long model; /* relation is in this model in model gllist */
162 /* set in CollectRelsAndWhens. = 1.. nmodels */
163 /* rel_relation models = u.r.model-1 */
164 int index; /* master gl list index */
165 int obj; /* is it an objective relation. set in classify_instance */
166 int ext; /* is it e_blackbox. set in classify_instance */
167 int included; /* set in classify_instance */
168 int cond; /* is it a conditional relation. set in classify_instance */
169 int inwhen; /* is it in a when */
170 int active; /* is this rel a part of my problem */
171 };
172
173 struct logrelip {
174 struct logrel_relation *data; /* ptr to destination of data */
175 long model; /* logrelation is in this model in model gllist */
176 int index; /* master gllist index */
177 int included; /* set in classify_instance */
178 int cond; /* is it a conditional logrelation. */
179 int inwhen; /* is it in a when */
180 int active; /* is this logrel a part of my problem */
181 };
182
183 struct whenip{
184 struct w_when *data; /* ptr to destination of data */
185 long model; /* when is in this model in model gllist */
186 int index; /* master gllist index */
187 int inwhen; /* is it in a when */
188 };
189
190 struct modip {
191 int index; /* set in make master lists. 1..nmodels */
192 int inwhen; /* is it in a when */
193 };
194
195 /* we will decorate the ascend instance tree with these in the interface
196 * pointers, but ONLY for the system build process and not persistently.
197 * DO NOT EVER UNDER ANY CIRCUMSTANCES EXPORT THIS DATA STRUCTURE.
198 */
199 struct solver_ipdata {
200 struct Instance *i; /* the kind of instance is the enum for union */
201 union {
202 struct modip m;
203 struct varip v;
204 struct disvarip dv;
205 struct relip r;
206 struct logrelip lr;
207 struct whenip w;
208 } u;
209 };
210
211 /* a handy cast for fetching things off gllists */
212 #define SIP(x) ((struct solver_ipdata *)(x))
213
214 /*
215 * a bridge buffer used so much we aren't going to free it, just reuse it
216 */
217 static struct reuse_t {
218 size_t ipcap; /* number of ips allocated in ipbuf */
219 size_t ipused; /* number of ips in use */
220 struct solver_ipdata *ipbuf;
221 } g_reuse = {0,0,NULL};
222
223 /*
224 * a data structure for bridge building only. hell of a scaffolding.
225 * all fields should be empty if construction is not in progress.
226 * In particular, do no operations that can throw an exception
227 * while manipulating a problem_t, as it is way too big to let leak.
228 */
229 struct problem_t {
230 /* the following are established by CountStuffInTree */
231 long nv; /* number of solvervar/solveratom */
232 long np; /* number of real ATOM instance parameters */
233 long nu; /* number of real ATOM instance uninteresting */
234 long ndv; /* number of discrete variables */
235 long nud; /* number of uninteresting discretes */
236 long nc; /* number of conditional relations */
237 long ncl; /* number of conditional logrelations */
238 long nr; /* number of algebraic relations */
239 long no; /* number of objective rels */
240 long nl; /* number of logical rels */
241 long nw; /* number of whens */
242 long ne; /* number of external rels subset overestimate*/
243 long nm; /* number of models */
244 /*
245 * The following gllists contain pointers to interface ptrs as
246 * locally defined.
247 * The lists will be in order found by a visit instance tree.
248 */
249 struct gl_list_t *vars; /* solvervar/solveratom. varips */
250 struct gl_list_t *pars; /* real ATOM instance parameters */
251 struct gl_list_t *unas; /* real ATOM instance of no 'apparent' use */
252 struct gl_list_t *models; /* models in tree. modips */
253 /*
254 * The following gllists contain pointers to interface ptrs as
255 * locally defined.
256 * The lists will be in order found by running over the models list.
257 */
258 struct gl_list_t *dvars; /* discrete variables */
259 struct gl_list_t *dunas; /* discrete variables of no use */
260 struct gl_list_t *whens; /* whens */
261 struct gl_list_t *cnds; /* conditional relations */
262 struct gl_list_t *logcnds; /* conditional logrelations */
263 struct gl_list_t *rels; /* ascend relations. relips */
264 struct gl_list_t *objrels; /* objective rels. relips */
265 struct gl_list_t *logrels; /* logical rels */
266 /* bridge ip data */
267 struct gl_list_t *oldips; /* buffer of oldip crap we're protecting */
268 /* misc stuff */
269 struct gl_list_t *tmplist; /* sort space */
270 /* stuff that will end up in the slv_system_t */
271 struct rel_relation *obj; /* DEFAULT objective relation, if any */
272 struct Instance *root; /* instance we construct system from */
273 struct gl_list_t *extrels; /* black box stub list */
274 /* stuff that should move elsewhere, but end up in slv_system_t */
275 mtx_region_t *blocks; /* array of partitions in reordered matrix */
276 int32 nblocks; /* size of array of partitions */
277 int nnz; /* free nonzeros in processed jacobian */
278 int nnztot; /* total nonzeros in processed relations */
279 int nnzobj; /* total nonzeros in objective gradients */
280 int nnzcond; /* total nonzeros in conditional relations */
281 int relincsize; /* total nonzeros in gradients */
282 int relincinuse; /* incidence given to relations so far */
283 int varincsize; /* total nonzeros in gradients (redundant) */
284 int varincinuse; /* incidence given to variables so far */
285 int ncol; /* free and incident vars */
286 int nrow; /* included relations */
287 /* conditional stuff */
288 int32 need_consistency; /* Conistency analysis is required ? */
289 /* logical relation stuff */
290 int lognnz; /* Summ of free boolean vars in inc logrels */
291 int lognrow; /* included logrelations */
292 int logncol; /* free and incident boolean vars */
293 int lrelinc; /* incident boolean vars */
294 int lrelincsize; /* Total summ of incidences (boolean vars)
295 in logrels*/
296 int lrelincinuse; /* incidence given to log relations so far */
297 /* data to go to slv_system_t */
298 struct rel_relation *reldata; /* rel data space, mass allocated */
299 struct rel_relation *objdata; /* objrel data space, mass allocated */
300 struct rel_relation *condata; /* cond rel data space, mass allocated*/
301 struct logrel_relation *lrdata; /* logrel data space, mass allocated */
302 struct logrel_relation *logcondata; /* cond logrel data space, allocated */
303 struct var_variable *vardata; /* svar data space, mass allocated */
304 struct var_variable *pardata; /* par data space, mass allocated */
305 struct var_variable *undata; /* data space, mass allocated */
306 struct dis_discrete *disdata; /* dis var data space, mass allocated */
307 struct dis_discrete *undisdata; /* data space, mass allocated */
308 struct w_when *whendata; /* when data space, mass allocated */
309 struct bnd_boundary *bnddata; /* boundaries data space, allocated */
310 struct var_variable **mastervl; /* master null-terminated list */
311 struct var_variable **solvervl; /* solvers null-terminated list */
312 struct dis_discrete **masterdl; /* master null-terminated list */
313 struct dis_discrete **solverdl; /* solvers null-terminated list */
314 struct rel_relation **masterrl; /* master null-terminated list */
315 struct rel_relation **solverrl; /* solvers null-terminated list */
316 struct rel_relation **mastercl; /* master null-terminated list */
317 struct rel_relation **solvercl; /* solvers null-terminated list */
318 struct rel_relation **masterol; /* master null-terminated list */
319 struct rel_relation **solverol; /* solvers null-terminated list */
320 struct logrel_relation **masterll; /* master null-terminated list */
321 struct logrel_relation **solverll; /* solvers null-terminated list */
322 struct logrel_relation **mastercll; /* master null-terminated list */
323 struct logrel_relation **solvercll; /* solvers null-terminated list */
324 struct w_when **masterwl; /* master null-terminated list */
325 struct w_when **solverwl; /* solvers null-terminated list */
326 struct bnd_boundary **masterbl; /* master null-terminated list */
327 struct bnd_boundary **solverbl; /* solvers null-terminated list */
328 struct var_variable **masterpl; /* master null-terminated list */
329 struct var_variable **solverpl; /* solvers null-terminated list */
330 struct var_variable **masterul; /* master null-terminated list */
331 struct var_variable **solverul; /* solvers null-terminated list */
332 struct dis_discrete **masterdul; /* master null-terminated list */
333 struct dis_discrete **solverdul; /* solvers null-terminated list */
334 struct var_variable **relincidence; /* rel_relation incidence source */
335 struct rel_relation **varincidence; /* var_variable incidence source */
336 struct dis_discrete **logrelinciden; /* logrel_relation incidence source */
337
338 struct ExtRelCache **erlist; /* external rel cache null terminated list */
339 };
340 /* we are making the ANSI assumption that this will be init to 0/NULL*/
341 /*
342 * container for globals during assembly.
343 * At present, the mastervl and solvervl are of the same length. This
344 * is purely coincidental and the long run intent is that there is one
345 * master list and that a problem coordinator would set up the
346 * solver var/rel lists blockwise as we go along. We may want to put
347 * block information in the rel/var structures.
348 */
349
350
351 /*
352 * The intent here is to do away with the old persistent interface pointer
353 * scheme by making the struct rel_relation *individually keep track of the
354 * map between the ascend RelationVariable list position and the
355 * solver's var list index (and hence the column in jacobian for jacobian
356 * involved clients).
357 * In this mapping each struct relation * has its var list and this list
358 * may contain RealAtomInstances that we don't consider variables.
359 * In the rel_relation we will have the variable index list
360 * which is an array of int32 the same length as the RelationVariable list.
361 * In the array position 0 corresponds to RelationVariable 1 since the
362 * compiler uses gl_lists. If in the variable index list we encounter
363 * a number < 0 we know that that RelationVariable doesn't map to what
364 * we consider a solver variable.
365 *
366 * In the near future we may also add to the struct rel_relation *an array,
367 * a, of int32 pairs like so:
368 * vlindex | rvindex | vlindex | rvindex
369 * and a length. This array could be built of the data for vars that pass
370 * a filter provided by the client. This way a client could help us avoid
371 * having to do if testing while stuffing jacobians.
372 * In this scheme stuffing a jacobian row (or whatever) would simply mean
373 * calling the compiler's derivative function (wrt RelationVariable list)
374 * which returns a vector d of values and then doing a loop:
375 * for( i = 0 ; i < length; i++) { coord.row fixed already
376 * coord.col = a[i++];
377 * mtx_fill_org_value(mtx,&coord,d[a[i]])
378 * }
379 * }
380 *
381 * One begins to wonder if there isn't a better way to do all this, but
382 * so far nothing has occurred.
383 * The best way would be to feed clients only the block of stuff they
384 * are interested in (no fixed, unattached vars or unincluded rels
385 * or vars/rels solved in previous partitions) so that the solver
386 * had no partitioning or var classification work to do except perhaps
387 * classifying things as basic/nonbasic.
388 */
389
390
391 /* return a pointer to the oncesizefitsall ips we're using.
392 * always returns nonnull because if we run out we exit
393 */
394 static struct solver_ipdata *analyze_getip(void)
395 {
396 if (g_reuse.ipbuf!=NULL && g_reuse.ipused < g_reuse.ipcap) {
397 return &(g_reuse.ipbuf[g_reuse.ipused++]);
398 } else {
399 Asc_Panic(2, "ananlyze_getip",
400 "Too many ips requested by analyze_getip\n");
401 exit(2);/* NOT REACHED. Needed to keep gcc from whining */
402 }
403 }
404
405 /*
406 * reallocates to the requested size (newcap) the ipbuf.
407 * if newcap = 0, frees ipbuf.
408 * if insufficient memory returns 1.
409 * if newcap > 0 and reset mem != 0, initializes ipbuf to 0s.
410 * Resets ipused to 0.
411 */
412 static
413 int resize_ipbuf(size_t newcap, int resetmem)
414 {
415 struct solver_ipdata *tmp;
416 if (newcap ==0) {
417 if (g_reuse.ipbuf != NULL) {
418 ascfree(g_reuse.ipbuf);
419 }
420 g_reuse.ipcap = g_reuse.ipused = 0;
421 g_reuse.ipbuf = NULL;
422 return 0;
423 }
424 if (newcap > g_reuse.ipcap) {
425 if ( g_reuse.ipcap >0 ) {
426 tmp = (struct solver_ipdata *)
427 ascrealloc(g_reuse.ipbuf,newcap*sizeof(struct solver_ipdata));
428 if (tmp == NULL) {
429 FPRINTF(ASCERR,"ERROR: (resize_ipbuf) Insufficient memory.\n");
430 return 1;
431 }
432 g_reuse.ipbuf = tmp;
433 g_reuse.ipcap = newcap;
434 } else {
435 tmp = (struct solver_ipdata *)
436 ascmalloc(newcap*sizeof(struct solver_ipdata));
437 if (tmp == NULL) {
438 FPRINTF(ASCERR,
439 "ERROR:(resize_ipbuf 1st call) Insufficient memory.\n");
440 return 1;
441 }
442 g_reuse.ipbuf = tmp;
443 g_reuse.ipcap = newcap;
444 }
445 }
446 if (resetmem) {
447 memset((char *)g_reuse.ipbuf,0,
448 g_reuse.ipcap*sizeof(struct solver_ipdata));
449 }
450 g_reuse.ipused = 0;
451 return 0;
452 }
453
454
455 /*
456 * checks size of request and returns a pointer to the next available
457 * chunk of incidence space. if too much requested or 0 requested returns
458 * NULL. p_data->relincidence must have been allocated for this to work.
459 */
460 static
461 struct var_variable **get_incidence_space(int len, struct problem_t *p_data)
462 {
463 struct var_variable **tmp;
464 if (p_data->relincidence == NULL) {
465 Asc_Panic(2,NULL,"get_incidence_space called prematurely. bye.\n");
466 }
467 if (len <1) return NULL;
468 if (p_data->relincinuse + len > p_data->relincsize) {
469 FPRINTF(ASCERR,"get_incidence_space called excessively.\n");
470 return NULL;
471 }
472 tmp = &(p_data->relincidence[p_data->relincinuse]);
473 p_data->relincinuse += len;
474 return tmp;
475 }
476
477 /*
478 * checks size of request and returns a pointer to the next available
479 * chunk of incidence space. if too much requested or 0 requested returns
480 * NULL. p_data->varincidence must have been allocated for this to work.
481 */
482 static
483 struct rel_relation **get_var_incidence_space(int len,
484 struct problem_t *p_data)
485 {
486 struct rel_relation **tmp;
487 if (p_data->varincidence == NULL) {
488 Asc_Panic(2,NULL,"get_var_incidence_space called prematurely. bye.\n");
489 }
490 if (len <1) return NULL;
491 if (p_data->varincinuse + len > p_data->varincsize) {
492 FPRINTF(ASCERR,"get_var_incidence_space called excessively.\n");
493 return NULL;
494 }
495 tmp = &(p_data->varincidence[p_data->varincinuse]);
496 p_data->varincinuse += len;
497 return tmp;
498 }
499
500
501 /*
502 * p_data->logrelinciden must have been allocated for this to work.
503 */
504 static
505 struct dis_discrete **get_logincidence_space(int len,
506 struct problem_t *p_data)
507 {
508 struct dis_discrete **tmp;
509 if (p_data->logrelinciden == NULL) {
510 Asc_Panic(2,NULL,"get_logincidence_space called prematurely. bye.\n");
511 }
512 if (len <1) return NULL;
513 if (p_data->lrelincinuse + len > p_data->lrelincsize) {
514 FPRINTF(ASCERR,"get_logincidence_space called excessively.\n");
515 return NULL;
516 }
517 tmp = &(p_data->logrelinciden[p_data->lrelincinuse]);
518 p_data->lrelincinuse += len;
519 return tmp;
520 }
521
522
523 /*
524 * InitTreeCounts(i); This resets the pointers and counters in
525 * p_data to null. p_data is supposed to be a temporary structure
526 * so the memory management of the pointers in p_data is the job
527 * of the caller.
528 * p_data->root is set to i.
529 */
530 static void InitTreeCounts(struct Instance *i,struct problem_t *p_data)
531 {
532 memset((char *)p_data,0,sizeof(struct problem_t));
533 p_data->root = i;
534 }
535
536 #define AVG_PARENTS 2
537 #define AVG_CHILDREN 4
538 #define AVG_RELATIONS 15
539 #define AVG_GROWTH 2
540 #define PART_THRESHOLD 1000
541
542
543
544 /*
545 * The following function should be moved out to the compiler
546 * under the guise of a supported attribute.
547 */
548 static int BooleanChildValue(struct Instance *i,symchar *sc)
549 {
550 if (i == NULL || sc == NULL || (i=ChildByChar(i,sc)) == NULL) {
551 return 0;
552 } else {
553 return ( GetBooleanAtomValue(i) );
554 }
555 }
556
557 static void CollectArrayRelsAndWhens(struct Instance *i, long modindex,
558 struct problem_t *p_data)
559 {
560 struct Instance *child;
561 struct solver_ipdata *rip;
562 unsigned long nch,c;
563
564 if (i==NULL) return;
565 nch = NumberChildren(i);
566 for (c=1;c<=nch;c++) {
567 child = InstanceChild(i,c);
568 if (child==NULL) continue;
569 switch (InstanceKind(child)) {
570 case REL_INST:
571 rip = SIP(GetInterfacePtr(child));
572 if (rip->u.r.model == 0) {
573 rip->u.r.model = modindex;
574 } else {
575 /* ah hah! found an array with two distinct MODEL parents! skip it */
576 break;
577 }
578 if (rip->u.r.cond) {
579 gl_append_ptr(p_data->cnds,(VOIDPTR)rip);
580 }
581 else {
582 if (rip->u.r.obj) {
583 gl_append_ptr(p_data->objrels,(VOIDPTR)rip);
584 } else {
585 gl_append_ptr(p_data->rels,(VOIDPTR)rip);
586 }
587 }
588 break;
589 case LREL_INST:
590 rip = SIP(GetInterfacePtr(child));
591 if (rip->u.lr.model == 0) {
592 rip->u.lr.model = modindex;
593 } else {
594 break;
595 }
596 if (rip->u.lr.cond) {
597 gl_append_ptr(p_data->logcnds,(VOIDPTR)rip);
598 }
599 else {
600 gl_append_ptr(p_data->logrels,(VOIDPTR)rip);
601 }
602 break;
603 case WHEN_INST:
604 rip = SIP(GetInterfacePtr(child));
605 if (rip->u.w.model == 0) {
606 rip->u.w.model = modindex;
607 } else {
608 break;
609 }
610 gl_append_ptr(p_data->whens,(VOIDPTR)rip);
611 break;
612 case ARRAY_ENUM_INST:
613 case ARRAY_INT_INST:
614 if (ArrayIsRelation(child) ||
615 ArrayIsLogRel(child) ||
616 ArrayIsWhen(child)) {
617 CollectArrayRelsAndWhens(child,modindex,p_data);
618 }
619 break;
620 default:
621 break;
622 }
623 }
624 }
625
626
627 /*
628 * Collect all the logrels/relations at the local scope of the MODEL
629 * associated with ip->i. Local scope includes arrays of logrels/relations,
630 * mainly because these arrays don't have interface pointers so we
631 * can't treat them separately.
632 */
633 static void CollectRelsAndWhens(struct solver_ipdata *ip,
634 long modindex,
635 struct problem_t *p_data)
636 {
637 struct Instance *child;
638 struct solver_ipdata *rip;
639 unsigned long nch,c;
640
641 if (ip->i==NULL) return;
642 nch = NumberChildren(ip->i);
643 for (c=1;c<=nch;c++) {
644 child = InstanceChild(ip->i,c);
645 if (child==NULL) continue;
646 switch (InstanceKind(child)) {
647 case REL_INST:
648 rip = SIP(GetInterfacePtr(child));
649 rip->u.r.model = modindex;
650 if (rip->u.r.cond) {
651 gl_append_ptr(p_data->cnds,(VOIDPTR)rip);
652 }
653 else {
654 if (rip->u.r.obj) {
655 gl_append_ptr(p_data->objrels,(VOIDPTR)rip);
656 } else {
657 gl_append_ptr(p_data->rels,(VOIDPTR)rip);
658 }
659 }
660 break;
661 case LREL_INST:
662 rip = SIP(GetInterfacePtr(child));
663 rip->u.lr.model = modindex;
664 if (rip->u.lr.cond) {
665 gl_append_ptr(p_data->logcnds,(VOIDPTR)rip);
666 }
667 else {
668 gl_append_ptr(p_data->logrels,(VOIDPTR)rip);
669 }
670 break;
671 case WHEN_INST:
672 rip = SIP(GetInterfacePtr(child));
673 rip->u.w.model = modindex;
674 gl_append_ptr(p_data->whens,(VOIDPTR)rip);
675 break;
676 case ARRAY_ENUM_INST:
677 case ARRAY_INT_INST:
678 if (ArrayIsRelation(child) ||
679 ArrayIsLogRel(child)||
680 ArrayIsWhen(child)) {
681 CollectArrayRelsAndWhens(child,modindex,p_data);
682 }
683 break;
684 default:
685 break;
686 }
687 }
688 }
689
690
691
692 /*
693 * Checks the problem extrels list to see whether a cache has been
694 * created for the given relation in the problem_t bridge.
695 * If not will return NULL, else
696 * will return the pointer to the cache. The nodestamp corresponding
697 * to this relation is returned regardless.
698 *
699 */
700 static struct ExtRelCache
701 *CheckIfCacheExists( struct Instance *relinst, int *nodestamp,
702 struct problem_t *p_data)
703 {
704 struct ExtCallNode *ext;
705 struct ExtRelCache *cache;
706 CONST struct relation *gut;
707 enum Expr_enum type;
708 unsigned long len,c;
709
710 gut = GetInstanceRelation(relinst,&type);
711 assert(type==e_blackbox);
712 ext = BlackBoxExtCall(gut);
713 *nodestamp = ExternalCallNodeStamp(ext);
714 len = gl_length(p_data->extrels);
715
716 for (c=1;c<=len;c++) {
717 cache = (struct ExtRelCache *)gl_fetch(p_data->extrels,c);
718 if (cache->nodestamp == *nodestamp) {
719 return cache;
720 }
721 }
722 return NULL;
723 }
724
725 /*
726 * analyze_CountRelation
727 * Call only with good relation instances.
728 * Count the instance into the required bin.
729 */
730 static void analyze_CountRelation(struct Instance *inst,
731 struct problem_t *p_data)
732 {
733 switch( RelationRelop(GetInstanceRelationOnly(inst)) ) {
734 case e_maximize:
735 case e_minimize:
736 p_data->no++;
737 break;
738 case e_less: case e_lesseq:
739 case e_greater: case e_greatereq:
740 case e_equal: case e_notequal:
741 if ( RelationIsCond(GetInstanceRelationOnly(inst)) ) {
742 p_data->nc++;
743 }
744 else {
745 p_data->nr++;
746 if ( GetInstanceRelationType(inst)==e_blackbox ) {
747 p_data->ne++;
748 }
749 }
750 break;
751 default:
752 FPRINTF(ASCERR,"ERROR: (analyze) analyze_CountRelation\n");
753 FPRINTF(ASCERR," Unknown relation type.\n");
754 }
755 }
756
757
758 /*
759 * GetIntFromSymbol
760 * Used for a WHEN statement. It intends to obtain an integer value
761 * from a symbol value. Each symbol value is storaged in a symbol list.
762 * It checks if the symval is already in the solver symbol list,
763 * if it is, returns the integer corresponding to the position of symval
764 * if it is not, appends the symval to the list and then returns the int
765 * This is terrible inefficient as the number of symbols grows.
766 * I am keeping it by now, are they going to be so many symbols in
767 * whens anyway ?
768 */
769
770 int GetIntFromSymbol(CONST char *symval,
771 struct gl_list_t *symbol_list)
772 {
773 struct SymbolValues *entry,*dummy;
774 unsigned long length;
775 int len,c,value;
776 int symbol_list_count;
777
778 if (symbol_list != NULL) {
779 len = gl_length(symbol_list);
780 for (c=1; c<= len; c++) {
781 dummy = (struct SymbolValues *)(gl_fetch(symbol_list,c));
782 if (!strcmp(dummy->name,symval)) {
783 return (dummy->value);
784 }
785 }
786 symbol_list_count = len;
787 } else {
788 symbol_list_count = 0;
789 symbol_list = gl_create(2L);
790 }
791 length = (unsigned long)strlen(symval);
792 length++;
793 symbol_list_count++;
794 entry = (struct SymbolValues *)ascmalloc(sizeof(struct SymbolValues));
795 entry->name = (char *)ascmalloc(length *sizeof(char));
796 strcpy(entry->name,symval);
797 entry->value = symbol_list_count;
798 value = entry->value;
799 gl_append_ptr(symbol_list,entry);
800 return value;
801 }
802
803 void DestroySymbolValuesList(struct gl_list_t *symbol_list)
804 {
805 struct SymbolValues *entry;
806 int len,c;
807 if (symbol_list != NULL) {
808 len = gl_length(symbol_list);
809 for (c=1; c<= len; c++) {
810 entry = (struct SymbolValues *)(gl_fetch(symbol_list,c));
811 ascfree((char *)entry->name); /* Do I need this ? */
812 ascfree((char *)entry);
813 }
814 gl_destroy(symbol_list);
815 symbol_list = NULL;
816 }
817 }
818
819
820
821
822 /*
823 * classify_instance : to be called by PushInterfacPtrs.
824 *
825 * This function classifies the given instance and appends into
826 * the necessary list in the p_data structure.
827 * It also sets returns a pointer to the caller for insertion into
828 * the interface_ptr slot.
829 *
830 * Note, we should be passing the ipbuf info via vp so we don't
831 * need the nasty global variable and can be more thread safe.
832 * vp is a struct problem_t.
833 */
834 static
835 void *classify_instance(struct Instance *inst, VOIDPTR vp)
836 {
837 struct solver_ipdata *ip;
838 struct problem_t *p_data;
839 CONST char *symval;
840 p_data = (struct problem_t *)vp;
841 switch( InstanceKind(inst) ) {
842 case REAL_ATOM_INST: /* Variable or parameter or real */
843 ip = analyze_getip();
844 ip->i = inst;
845 ip->u.v.incident = 0;
846 ip->u.v.in_block = 0;
847 ip->u.v.index = 0;
848 ip->u.v.active = 0;
849 if( solver_var(inst) ) {
850 ip->u.v.solvervar = 1; /* must set this regardless of what list */
851 ip->u.v.fixed = BooleanChildValue(inst,FIXED_A);
852 ip->u.v.basis = BooleanChildValue(inst,BASIS_A);
853 if (RelationsCount(inst)) {
854 gl_append_ptr(p_data->vars,(POINTER)ip);
855 } else {
856 gl_append_ptr(p_data->unas,(POINTER)ip);
857 }
858 } else {
859 ip->u.v.fixed = 1;
860 ip->u.v.solvervar=0;
861 if (solver_par(inst) && RelationsCount(inst)) {
862 gl_append_ptr(p_data->pars,(POINTER)ip);
863 } else {
864 gl_append_ptr(p_data->unas,(POINTER)ip);
865 }
866 }
867 return ip;
868 case BOOLEAN_ATOM_INST:
869 ip = analyze_getip();
870 ip->i = inst;
871 ip->u.dv.isconst = 0;
872 ip->u.dv.distype = 0;
873 ip->u.dv.incident = 0;
874 ip->u.dv.index = 0;
875 ip->u.dv.active = 0;
876 ip->u.dv.value = GetBooleanAtomValue(inst);
877 if( boolean_var(inst) ) {
878 ip->u.dv.booleanvar = 1;
879 ip->u.dv.fixed = BooleanChildValue(inst,FIXED_A);
880 } else {
881 ip->u.dv.fixed = 1;
882 ip->u.dv.booleanvar=0;
883 }
884 if( LogRelationsCount(inst) || WhensCount(inst) ) {
885 gl_append_ptr(p_data->dvars,(POINTER)ip);
886 if ( WhensCount(inst) ) {
887 ip->u.dv.inwhen = 1;
888 } else {
889 ip->u.dv.inwhen = 0;
890 }
891 } else {
892 gl_append_ptr(p_data->dunas,(POINTER)ip);
893 }
894 return ip;
895 case BOOLEAN_CONSTANT_INST:
896 if (WhensCount(inst)) {
897 ip = analyze_getip();
898 ip->i = inst;
899 ip->u.dv.isconst = 1;
900 ip->u.dv.distype = 0;
901 ip->u.dv.index = 0;
902 ip->u.dv.incident = 0;
903 ip->u.dv.booleanvar=0;
904 ip->u.dv.fixed = 1;
905 ip->u.dv.active = 0;
906 ip->u.dv.value = GetBooleanAtomValue(inst);
907 gl_append_ptr(p_data->dvars,(POINTER)ip);
908 return ip;
909 } else {
910 return NULL;
911 }
912 case INTEGER_ATOM_INST:
913 if (WhensCount(inst)) {
914 ip = analyze_getip();
915 ip->i = inst;
916 ip->u.dv.isconst = 0;
917 ip->u.dv.distype = 1;
918 ip->u.dv.index = 0;
919 ip->u.dv.incident = 0;
920 ip->u.dv.booleanvar=0;
921 ip->u.dv.fixed = 0;
922 ip->u.dv.active = 0;
923 ip->u.dv.value = GetIntegerAtomValue(inst);
924 gl_append_ptr(p_data->dvars,(POINTER)ip);
925 return ip;
926 } else {
927 return NULL;
928 }
929 case SYMBOL_ATOM_INST:
930 if (WhensCount(inst)) {
931 symval = SCP(GetSymbolAtomValue(inst));
932 if (symval == NULL) {
933 return NULL;
934 }
935 ip = analyze_getip();
936 ip->i = inst;
937 ip->u.dv.isconst = 0;
938 ip->u.dv.distype = -1;
939 ip->u.dv.index = 0;
940 ip->u.dv.incident = 0;
941 ip->u.dv.booleanvar=0;
942 ip->u.dv.fixed = 0;
943 ip->u.dv.active = 0;
944 if (g_symbol_values_list == NULL) {
945 g_symbol_values_list = gl_create(2L);
946 }
947 ip->u.dv.value = GetIntFromSymbol(symval,g_symbol_values_list);
948 gl_append_ptr(p_data->dvars,(POINTER)ip);
949 return ip;
950 } else {
951 return NULL;
952 }
953 case INTEGER_CONSTANT_INST:
954 if (WhensCount(inst)) {
955 ip = analyze_getip();
956 ip->i = inst;
957 ip->u.dv.isconst = 1;
958 ip->u.dv.distype = 1;
959 ip->u.dv.index = 0;
960 ip->u.dv.incident = 0;
961 ip->u.dv.booleanvar=0;
962 ip->u.dv.fixed = 1;
963 ip->u.dv.active = 0;
964 ip->u.dv.value = GetIntegerAtomValue(inst);
965 gl_append_ptr(p_data->dvars,(POINTER)ip);
966 return ip;
967 } else {
968 return NULL;
969 }
970 case SYMBOL_CONSTANT_INST:
971 if (WhensCount(inst)) {
972 symval = SCP(GetSymbolAtomValue(inst));
973 if (symval == NULL) {
974 return NULL;
975 }
976 ip = analyze_getip();
977 ip->i = inst;
978 ip->u.dv.isconst = 1;
979 ip->u.dv.distype = -1;
980 ip->u.dv.index = 0;
981 ip->u.dv.incident = 0;
982 ip->u.dv.booleanvar=0;
983 ip->u.dv.fixed = 1;
984 ip->u.dv.active = 0;
985 if (g_symbol_values_list == NULL) {
986 g_symbol_values_list = gl_create(2L);
987 }
988 ip->u.dv.value = GetIntFromSymbol(symval,g_symbol_values_list);
989 gl_append_ptr(p_data->dvars,(POINTER)ip);
990 return ip;
991 } else {
992 return NULL;
993 }
994 case REL_INST: /* Relation (or conditional or objective) */
995 ip = analyze_getip();
996 ip->i = inst;
997 ip->u.r.active = 1;
998 switch(RelationRelop(GetInstanceRelationOnly(inst))) {
999 case e_minimize:
1000 ip->u.r.obj = 1;
1001 break;
1002 case e_maximize:
1003 ip->u.r.obj = -1;
1004 break;
1005 default:
1006 ip->u.r.obj = 0;
1007 break;
1008 }
1009 if ( GetInstanceRelationType(inst)==e_blackbox ) {
1010 ip->u.r.ext = 1;
1011 } else {
1012 ip->u.r.ext = 0;
1013 }
1014 if ( RelationIsCond(GetInstanceRelationOnly(inst)) ) {
1015 ip->u.r.cond = 1;
1016 } else {
1017 ip->u.r.cond = 0;
1018 }
1019 if ( WhensCount(inst) ) {
1020 ip->u.r.inwhen = 1;
1021 } else {
1022 ip->u.r.inwhen = 0;
1023 }
1024 ip->u.r.included = BooleanChildValue(inst,INCLUDED_A);
1025 ip->u.r.model = 0;
1026 ip->u.r.index = 0;
1027 return ip;
1028 /* note we do NOT append it to lists here */
1029 case LREL_INST: /* LogRelation */
1030 ip = analyze_getip();
1031 ip->i = inst;
1032 ip->u.lr.active = 1;
1033 if ( LogRelIsCond(GetInstanceLogRel(inst)) ) {
1034 ip->u.lr.cond = 1;
1035 } else {
1036 ip->u.lr.cond = 0;
1037 }
1038 if ( WhensCount(inst) ) {
1039 ip->u.lr.inwhen = 1;
1040 } else {
1041 ip->u.lr.inwhen = 0;
1042 }
1043 ip->u.lr.included = BooleanChildValue(inst,INCLUDED_A);
1044 ip->u.lr.model = 0;
1045 ip->u.lr.index = 0;
1046 return ip;
1047 /* note we do NOT append it to lists here */
1048 case MODEL_INST:
1049 ip = analyze_getip();
1050 ip->i = inst;
1051 ip->u.m.index = 0;
1052 if ( WhensCount(inst) ) {
1053 ip->u.m.inwhen = 1;
1054 } else {
1055 ip->u.m.inwhen = 0;
1056 }
1057 gl_append_ptr(p_data->models,(POINTER)ip);
1058 return ip;
1059 case WHEN_INST:
1060 ip = analyze_getip();
1061 ip->i = inst;
1062 ip->u.w.index = 0;
1063 if ( WhensCount(inst) ) {
1064 ip->u.w.inwhen = 1;
1065 } else {
1066 ip->u.w.inwhen = 0;
1067 }
1068 return ip;
1069 /* note we do NOT append it to lists here */
1070 default:
1071 return NULL;
1072 }
1073 }
1074
1075 /*
1076 * make_problem
1077 *
1078 * Makes variable/relations/when lists and objective function by heuristic.
1079 * Now also makes a list of all relations that are objectives.
1080 * This does not affect the semantics of the previous objective
1081 * code.
1082 * Do NOTHING in this function which can lead to floating point
1083 * errors -- in particular because we must leave the interface ptrs
1084 * in the state they were found.
1085 */
1086 /*
1087 * This function sets g_bad_rel_in_list TRUE if it finds any unhappy
1088 * relations. All the rest of the code depends on ALL relations being
1089 * good, so don't disable the g_bad_rel_in_list feature.
1090 */
1091 static
1092 void CountStuffInTree(struct Instance *inst, struct problem_t *p_data)
1093 {
1094 CONST char *symval;
1095 if (inst!=NULL) {
1096 switch (InstanceKind(inst)) {
1097 case REL_INST:
1098 if( GetInstanceRelationOnly(inst) == NULL ||
1099 GetInstanceRelationType(inst) == e_undefined) {
1100 /* guard against null relations, unfinished ones */
1101 FPRINTF(ASCERR,"ERROR: CountStuffInTree found bad relation\n");
1102 WriteInstanceName(ASCERR,inst,p_data->root);
1103 FPRINTF(ASCERR,"\n");
1104 g_bad_rel_in_list = TRUE;
1105 return;
1106 }
1107 /* increment according to classification */
1108 analyze_CountRelation(inst,p_data);
1109 break;
1110 case REAL_ATOM_INST:
1111 if( solver_var(inst) && RelationsCount(inst)) {
1112 p_data->nv++;
1113 } else {
1114 if (solver_par(inst) && RelationsCount(inst)) {
1115 /* never passes right now */
1116 p_data->np++;
1117 } else {
1118 p_data->nu++;
1119 }
1120 }
1121 /* The use of RelationsCount is heuristic since vars may be
1122 * used in relations higher in the tree than the problem is rooted.
1123 */
1124 break;
1125 case BOOLEAN_ATOM_INST:
1126 if ( ( boolean_var(inst) && LogRelationsCount(inst) ) ||
1127 WhensCount(inst) ) {
1128 p_data->ndv++;
1129 }
1130 else {
1131 p_data->nud++;
1132 }
1133 break;
1134 case BOOLEAN_CONSTANT_INST:
1135 case INTEGER_ATOM_INST:
1136 case INTEGER_CONSTANT_INST:
1137 if (WhensCount(inst)) {
1138 p_data->ndv++;
1139 }
1140 break;
1141 case SYMBOL_ATOM_INST:
1142 case SYMBOL_CONSTANT_INST:
1143 if (WhensCount(inst)) {
1144 symval = SCP(GetSymbolAtomValue(inst));
1145 if (symval == NULL) {
1146 FPRINTF(ASCERR,"ERROR: CountStuffInTree found undefined symbol or symbol_constant in WHEN.\n");
1147 WriteInstanceName(ASCERR,inst,p_data->root);
1148 FPRINTF(ASCERR,"\n");
1149 g_bad_rel_in_list = TRUE;
1150 return;
1151 }
1152 p_data->ndv++;
1153 }
1154 break;
1155 case LREL_INST:
1156 if( GetInstanceLogRelOnly(inst) == NULL ) {
1157 FPRINTF(ASCERR,"ERROR: CountStuffInTree found bad logrel.\n");
1158 WriteInstanceName(ASCERR,inst,p_data->root);
1159 FPRINTF(ASCERR,"\n");
1160 g_bad_rel_in_list = TRUE;
1161 return;
1162 }
1163 if ( LogRelIsCond(GetInstanceLogRel(inst)) ) {
1164 p_data->ncl++;
1165 }
1166 else {
1167 p_data->nl++;
1168 }
1169 break;
1170 case WHEN_INST:
1171 p_data->nw++;
1172 break;
1173 case MODEL_INST:
1174 p_data->nm++;
1175 break;
1176 default:
1177 break;
1178 }
1179 }
1180 }
1181
1182
1183 /*
1184 * This takes the already derived counts,
1185 * allocates all the memory we need to allocate for master,
1186 * and builds the var/rel/MODEL/etc master lists.
1187 * filling in p_data and ips as far as possible.
1188 * Returns 0 normally, or 1 if insufficient memory, 2 if nothing to do.
1189 * If 1, then the user should deallocate any partial results in
1190 * a separate cleanup function for p_data->
1191 *
1192 * In particular, after this is done we have
1193 * vars with correct ip values for:
1194 * index;
1195 * incident;
1196 * in_block;
1197 * fixed; (as flag)
1198 * basis; (as flag)
1199 * solvervar; (as flag)
1200 * relations and conditional relations with correct ip values for:
1201 * index;
1202 * model;
1203 * obj; (0 constraint, -1 maximize, +1 minimize)
1204 * ext;
1205 * inwhen;
1206 * cond;
1207 * included; (as flag)
1208 * discrete vars with correct ip values for:
1209 * index;
1210 * incident;
1211 * isconst;
1212 * distype;
1213 * fixed; (as flag)
1214 * booleanvar; (as flag)
1215 * inwhen;
1216 * logrelations and conditional logrelations with correct ip values for:
1217 * index;
1218 * model;
1219 * included; (as flag)
1220 * inwhen;
1221 * cond;
1222 * whens with correct ip values for:
1223 * index;
1224 * model;
1225 * inwhen;
1226 * models with correct ip values for:
1227 * index;
1228 *
1229 * Note that these are all indexed from 1, being stored in gllists.
1230 */
1231 static int analyze_make_master_lists(struct problem_t *p_data)
1232 {
1233 long int c, len,v,vlen;
1234 CONST struct Instance *i;
1235 CONST struct relation *gut;
1236 CONST struct logrelation *lgut;
1237 struct solver_ipdata *vip;
1238 struct gl_list_t *scratch;
1239 size_t reqlen;
1240 int stat;
1241 reqlen =
1242 p_data->nr + p_data->no + p_data->nc + p_data->nl+ p_data->ncl+ /*rels*/
1243 p_data->nv + p_data->ndv +
1244 p_data->np + p_data->nu + p_data->nud + /* atoms */
1245 p_data->nw + /* when */
1246 p_data->nm; /* model */
1247 if (reqlen <1) {
1248 return 2;
1249 }
1250
1251 /* CREATE memory for ips */
1252 #ifdef NDEBUG
1253 stat = resize_ipbuf(reqlen,0);
1254 #else
1255 stat = resize_ipbuf(reqlen,1);
1256 #endif /* NDEBUG */
1257 if (stat) {
1258 FPRINTF(ASCERR,"Error: (analyze_make_master) Insufficient memory.\n");
1259 return 1;
1260 }
1261
1262 p_data->vars = gl_create(p_data->nv); /* variables */
1263 if (p_data->vars == NULL) return 1;
1264
1265 p_data->dvars = gl_create(p_data->ndv); /* discrete variables */
1266 if (p_data->dvars == NULL) return 1;
1267
1268 p_data->pars = gl_create(p_data->np); /* parameters */
1269 if (p_data->pars == NULL) return 1;
1270
1271 p_data->unas = gl_create(p_data->nu); /* unattached */
1272 if (p_data->unas == NULL) return 1;
1273
1274 p_data->dunas = gl_create(p_data->nud); /* discrete unattached */
1275 if (p_data->dunas == NULL) return 1;
1276
1277 p_data->cnds = gl_create(p_data->nc); /* conditional relations */
1278 if (p_data->cnds == NULL) return 1;
1279
1280 p_data->rels = gl_create(p_data->nr); /* relations */
1281 if (p_data->rels == NULL) return 1;
1282
1283 p_data->logrels = gl_create(p_data->nl); /* logical relations */
1284 if (p_data->logrels == NULL) return 1;
1285
1286 p_data->logcnds = gl_create(p_data->ncl); /* conditional logrelations */
1287 if (p_data->logcnds == NULL) return 1;
1288
1289 p_data->extrels = gl_create(p_data->ne); /* extrelations */
1290 if (p_data->extrels == NULL) return 1;
1291
1292 p_data->objrels = gl_create(p_data->no); /* objectives */
1293 if (p_data->objrels == NULL) return 1;
1294
1295 p_data->whens = gl_create(p_data->nw); /* whens */
1296 if (p_data->whens == NULL) return 1;
1297
1298 p_data->models = gl_create(p_data->nm); /* models */
1299 if (p_data->models == NULL) return 1;
1300
1301 /* decorate the instance tree with ips, collecting vars and models. */
1302 p_data->oldips = PushInterfacePtrs(p_data->root,classify_instance,
1303 g_reuse.ipcap,1,p_data);
1304 if (p_data->oldips == NULL) {
1305 FPRINTF(ASCERR,"Error: (analyze) Insufficient memory.\n");
1306 return 1;
1307 }
1308
1309 /*
1310 * collect relations, objectives, logrels and whens recording the
1311 * MODEL number in each rel's ip and setting incidence.
1312 */
1313 len = gl_length(p_data->models);
1314 for (c=1; c <= len; c++) {
1315 CollectRelsAndWhens(SIP(gl_fetch(p_data->models,c)),c,p_data);
1316 SIP(gl_fetch(p_data->models,c))->u.m.index = c;
1317 }
1318 if ((long)gl_length(p_data->rels) != p_data->nr ||
1319 (long)gl_length(p_data->objrels) != p_data->no ||
1320 (long)gl_length(p_data->logrels) != p_data->nl ||
1321 (long)gl_length(p_data->whens) != p_data->nw) {
1322 FPRINTF(ASCERR,
1323 "Warning: Mismatch in problem census and problem found\n");
1324 FPRINTF(ASCERR,"Rels: Counted %lu\t Found %ld\n",
1325 gl_length(p_data->rels), p_data->nr);
1326 FPRINTF(ASCERR,"Objs: Counted %lu\t Found %ld\n",
1327 gl_length(p_data->objrels), p_data->no);
1328 FPRINTF(ASCERR,"LogRels: Counted %lu\t Found %ld\n",
1329 gl_length(p_data->logrels),p_data->nl);
1330 FPRINTF(ASCERR,"Whens: Counted %lu\t Found %ld\n",
1331 gl_length(p_data->whens), p_data->nw);
1332 }
1333 /*
1334 * relation list is now grouped by model, and the order will be
1335 * invariant with hardware and ascend invocation so long as
1336 * set FIRSTCHOICE holds in compilation.
1337 */
1338 /* mark vars in constraints incident and index rels */
1339 len = gl_length(p_data->rels);
1340 for (c=1; c <= len; c++) {
1341 SIP(gl_fetch(p_data->rels,c))->u.r.index = c;
1342 gut = GetInstanceRelationOnly(SIP(gl_fetch(p_data->rels,c))->i);
1343 vlen = NumberVariables(gut);
1344 for( v = 1; v <= vlen; v++ ) {
1345 i = RelationVariable(gut,v);
1346 SIP(GetInterfacePtr(i))->u.v.incident = 1;
1347 }
1348 }
1349 /* mark vars in objectives incident */
1350 len = gl_length(p_data->objrels);
1351 for (c=1; c <= len; c++) {
1352 gut = GetInstanceRelationOnly(SIP(gl_fetch(p_data->objrels,c))->i);
1353 vlen = NumberVariables(gut);
1354 for( v = 1; v <= vlen; v++ ) {
1355 i = RelationVariable(gut,v);
1356 SIP(GetInterfacePtr(i))->u.v.incident = 1;
1357 }
1358 }
1359
1360 /* mark vars in conditional relations incident */
1361 len = gl_length(p_data->cnds);
1362 for (c=1; c <= len; c++) {
1363 SIP(gl_fetch(p_data->cnds,c))->u.r.index = c;
1364 gut = GetInstanceRelationOnly(SIP(gl_fetch(p_data->cnds,c))->i);
1365 vlen = NumberVariables(gut);
1366 for( v = 1; v <= vlen; v++ ) {
1367 i = RelationVariable(gut,v);
1368 SIP(GetInterfacePtr(i))->u.v.incident = 1;
1369 }
1370 }
1371
1372 /* mark dvars in logrels incident and index logrels */
1373 len = gl_length(p_data->logrels);
1374 for (c=1; c <= len; c++) {
1375 SIP(gl_fetch(p_data->logrels,c))->u.lr.index = c;
1376 lgut = GetInstanceLogRelOnly(SIP(gl_fetch(p_data->logrels,c))->i);
1377 vlen = NumberBoolVars(lgut);
1378 for( v = 1; v <= vlen; v++ ) {
1379 i = LogRelBoolVar(lgut,v);
1380 SIP(GetInterfacePtr(i))->u.dv.incident = 1;
1381 }
1382 }
1383
1384
1385 /* mark dvars in conditional logrels incident */
1386 len = gl_length(p_data->logcnds);
1387 for (c=1; c <= len; c++) {
1388 SIP(gl_fetch(p_data->logcnds,c))->u.lr.index = c;
1389 lgut = GetInstanceLogRelOnly(SIP(gl_fetch(p_data->logcnds,c))->i);
1390 vlen = NumberBoolVars(lgut);
1391 for( v = 1; v <= vlen; v++ ) {
1392 i = LogRelBoolVar(lgut,v);
1393 SIP(GetInterfacePtr(i))->u.dv.incident = 1;
1394 }
1395 }
1396
1397 /* mark index whens */
1398 len = gl_length(p_data->whens);
1399 for (c=1; c <= len; c++) {
1400 SIP(gl_fetch(p_data->whens,c))->u.w.index = c;
1401 }
1402 /*
1403 * now we need to move all the nonincident vars off the var list
1404 * onto the unas list. It is easiest to make a new list and copy
1405 * the existing var list to either it if keep or unas if punt.
1406 * the same goes for parameters that aren't incident.
1407 * We don't do exactly the same for discrete variables because
1408 * many of them are not incident but they are used in when's
1409 */
1410 len = gl_length(p_data->vars);
1411 p_data->tmplist = gl_create(len);
1412 if (p_data->tmplist == NULL) return 1;
1413 for (c=1; c <= len; c++) {
1414 /* dispose of var */
1415 vip = SIP(gl_fetch(p_data->vars,c));
1416 if ( vip->u.v.incident == 1) {
1417 gl_append_ptr(p_data->tmplist,vip);
1418 } else {
1419 gl_append_ptr(p_data->unas,vip);
1420 }
1421 }
1422 gl_destroy(p_data->vars); /* punt the old list */
1423 p_data->vars = p_data->tmplist; /* make shortened list var list */
1424 p_data->tmplist = NULL;
1425
1426 p_data->nv = gl_length(p_data->vars);
1427
1428 len = gl_length(p_data->pars);
1429 p_data->tmplist = gl_create(len);
1430 if (p_data->tmplist == NULL) {
1431 return 1;
1432 }
1433 for (c=1; c <= len; c++) {
1434 /* dispose of par */
1435 vip = SIP(gl_fetch(p_data->pars,c));
1436 if ( vip->u.v.incident == 1) {
1437 gl_append_ptr(p_data->tmplist,vip);
1438 } else {
1439 gl_append_ptr(p_data->unas,vip);
1440 }
1441 }
1442 gl_destroy(p_data->pars); /* punt the old list */
1443 p_data->pars = p_data->tmplist; /* make shortened list par list */
1444 p_data->tmplist = NULL;
1445
1446 p_data->np = gl_length(p_data->pars);
1447 p_data->nu = gl_length(p_data->unas);
1448
1449 /*
1450 * discrete variables: take the incident dis vars in logrels first,
1451 * then append the dis vars which are used only in whens
1452 */
1453 p_data->lrelinc = 0;
1454 len = gl_length(p_data->dvars);
1455 if ( len > 0) {
1456 p_data->tmplist = gl_create(len);
1457 scratch = gl_create(2L);
1458 if (p_data->tmplist == NULL) return 1;
1459 for (c=1; c <= len; c++) {
1460 /* dispose of incident discrete vars */
1461 vip = SIP(gl_fetch(p_data->dvars,c));
1462 if ( vip->u.dv.incident == 1) {
1463 gl_append_ptr(p_data->tmplist,vip);
1464 p_data->lrelinc++; /* Number of incident dis vars */
1465 } else {
1466 gl_append_ptr(scratch,vip);
1467 }
1468 }
1469 gl_destroy(p_data->dvars);
1470 p_data->dvars = p_data->tmplist;
1471 p_data->tmplist = NULL;
1472 /* append discrete non-boolean vars at the end of the list */
1473 len = gl_length(scratch);
1474 for (c=1; c <= len; c++) {
1475 vip = SIP(gl_fetch(scratch,c));
1476 gl_append_ptr(p_data->dvars,vip);
1477 }
1478 gl_destroy(scratch);
1479 scratch = NULL;
1480 }
1481
1482 /*
1483 * The following patch is to avoid the system to crash.
1484 * When multiple definitions of a solver_var have introduced into the
1485 * system, ASCEND may fail in identifying that a REAL_ATOM is a refinement
1486 * of a solver_var. This causes the system to think that, even that there
1487 * are relations into the system, there are no incidences in these relations
1488 * that fall into the category of a variable. As a consequence, the length
1489 * of the list of variables is zero. That of course will introduce
1490 * insanities while trying to build the slv system. Some
1491 * solutions to this problem are:
1492 *
1493 * The easier for us is just to alert the user and to force him/her to
1494 * reload all the type defintions again. That is the current solution
1495 *
1496 * The correct (but time consuming) solution is the implementation of a
1497 * SolverAtomInstance, which still needs parser and interpreter support
1498 *
1499 */
1500
1501 if (p_data->nr != 0 && p_data->nv==0) {
1502 FPRINTF(ASCERR, "\n");
1503 FPRINTF(ASCERR, "A L E R T\n");
1504 FPRINTF(ASCERR, "\n");
1505 FPRINTF(ASCERR, "Problem should contain at least one variable %s",
1506 "and one relation\n");
1507 FPRINTF(ASCERR, "\n");
1508 FPRINTF(ASCERR, "There are relations into the system, but the number \n");
1509 FPRINTF(ASCERR, "of variables is zero. That means that the existent \n");
1510 FPRINTF(ASCERR, "vars were not recognized as solver_vars. A possible \n");
1511 FPRINTF(ASCERR, "reason is that you have introduced conflicting \n");
1512 FPRINTF(ASCERR, "definitions of solver_var into the system. Please \n");
1513 FPRINTF(ASCERR, "delete all your types and reload your models \n");
1514 FPRINTF(ASCERR, "with the appropriate definition of solver_var\n");
1515 FPRINTF(ASCERR, "\n");
1516 FPRINTF(ASCERR, "Solver system will not be built.\n");
1517 FPRINTF(ASCERR, "\n");
1518 return 2;
1519 }
1520
1521 return 0;
1522 }
1523
1524
1525 /*
1526 * This function cleans up an errant problem_t or a good one that we're
1527 * done with. We should have set to null any pointers to memory we are
1528 * keeping elsewhere before calling this.
1529 */
1530 #define AFUN(ptr) if (ptr!=NULL) ascfree(ptr); (ptr) = NULL
1531 #define ADUN(ptr) if (ptr!=NULL) gl_destroy(ptr); (ptr) = NULL
1532 static void analyze_free_lists(struct problem_t *p_data)
1533 {
1534 /* memory containing gl_lists of atomic structure pointers */
1535 if (p_data->extrels != NULL) gl_free_and_destroy(p_data->extrels);
1536 /* gl_lists without memory items use ADUN */
1537 ADUN(p_data->vars);
1538 ADUN(p_data->dvars);
1539 ADUN(p_data->pars);
1540 ADUN(p_data->unas);
1541 ADUN(p_data->dunas);
1542 ADUN(p_data->rels);
1543 ADUN(p_data->objrels);
1544 ADUN(p_data->models);
1545 ADUN(p_data->cnds);
1546 ADUN(p_data->logrels);
1547 ADUN(p_data->logcnds);
1548 ADUN(p_data->whens);
1549 /* blocks of memory use AFUN */
1550 AFUN(p_data->blocks);
1551 AFUN(p_data->reldata);
1552 AFUN(p_data->objdata);
1553 AFUN(p_data->condata);
1554 AFUN(p_data->lrdata);
1555 AFUN(p_data->logcondata);
1556 AFUN(p_data->vardata);
1557 AFUN(p_data->pardata);
1558 AFUN(p_data->undata);
1559 AFUN(p_data->disdata);
1560 AFUN(p_data->undisdata);
1561 AFUN(p_data->whendata);
1562 AFUN(p_data->bnddata);
1563 AFUN(p_data->relincidence);
1564 AFUN(p_data->varincidence);
1565 AFUN(p_data->logrelinciden);
1566 AFUN(p_data->mastervl);
1567 AFUN(p_data->masterdl);
1568 AFUN(p_data->masterrl);
1569 AFUN(p_data->masterol);
1570 AFUN(p_data->mastercl);
1571 AFUN(p_data->masterll);
1572 AFUN(p_data->mastercll);
1573 AFUN(p_data->masterpl);
1574 AFUN(p_data->masterul);
1575 AFUN(p_data->masterdul);
1576 AFUN(p_data->masterwl);
1577 AFUN(p_data->masterbl);
1578 AFUN(p_data->solvervl);
1579 AFUN(p_data->solverdl);
1580 AFUN(p_data->solverrl);
1581 AFUN(p_data->solverol);
1582 AFUN(p_data->solvercl);
1583 AFUN(p_data->solverll);
1584 AFUN(p_data->solvercll);
1585 AFUN(p_data->solverpl);
1586 AFUN(p_data->solverul);
1587 AFUN(p_data->solverdul);
1588 AFUN(p_data->solverwl);
1589 AFUN(p_data->solverbl);
1590 AFUN(p_data->erlist);
1591 }
1592
1593
1594
1595 /*
1596 * When Processing
1597 */
1598
1599 /*
1600 * This function receives as argument the list of values of each of the
1601 * CASES of a WHEN statement. The values in the list can be integer values,
1602 * symbol values, or boolean values. So, the goal of this function is to
1603 * obtain an equivalent list of ONLY integer values for such a list. In this
1604 * way, for example, the boolean value TRUE is equivalent to the integer
1605 * 1. The function GentIntFromSymbol is used to generate an integer value
1606 * which will be equivalent to a symbol value
1607 */
1608 static
1609 void ProcessValueList(struct Set *ValueList, int *value,
1610 struct gl_list_t *symbol_list)
1611 {
1612 CONST struct Expr *expr;
1613 struct Set *s;
1614
1615 s = ValueList;
1616 if (ValueList!=NULL) {
1617 while (s != NULL) {
1618 expr = GetSingleExpr(s);
1619 switch(ExprType(expr)) {
1620 case e_boolean:
1621 *value = ExprBValue(expr);
1622 if (*value == 2) { /* ANY */
1623 *value = -2;
1624 }
1625 break;
1626 case e_int:
1627 *value = ExprIValue(expr);
1628 break;
1629 case e_symbol:
1630 *value = GetIntFromSymbol(SCP(ExprSymValue(expr)),symbol_list);
1631 break;
1632 default:
1633 break;
1634 }
1635 s = NextSet(s);
1636 value++;
1637 }
1638 } else {
1639 *value = -1; /* OTHERWISE */
1640 }
1641 }
1642
1643
1644 /*
1645 * The next two functions are used because in the function
1646 * ProcessSolverWhens, the existence of MODELS or ARRAYs inside
1647 * a When Statement requires a recursive analysis.
1648 * See the explanation of such a function
1649 */
1650 static
1651 void ProcessArraysInWhens(struct Instance *cur_inst,
1652 struct gl_list_t *rels,
1653 struct gl_list_t *logrels,
1654 struct gl_list_t *whens)
1655 {
1656 struct rel_relation *rel;
1657 struct logrel_relation *lrel;
1658 struct w_when *w;
1659 struct Instance *child;
1660 struct solver_ipdata *ip;
1661 unsigned long c,nch;
1662
1663 if (cur_inst==NULL) return;
1664 nch = NumberChildren(cur_inst);
1665 for (c=1;c<=nch;c++) {
1666 child = InstanceChild(cur_inst,c);
1667 if (child==NULL) continue;
1668 switch (InstanceKind(child)) {
1669 case REL_INST:
1670 ip = SIP(GetInterfacePtr(child));
1671 ip->u.r.active = 0;
1672 rel = ip->u.r.data;
1673 gl_append_ptr(rels,rel);
1674 break;
1675 case LREL_INST:
1676 ip = SIP(GetInterfacePtr(child));
1677 ip->u.lr.active = 0;
1678 lrel = ip->u.lr.data;
1679 gl_append_ptr(logrels,lrel);
1680 break;
1681 case WHEN_INST:
1682 ip = SIP(GetInterfacePtr(child));
1683 w = ip->u.w.data;
1684 gl_append_ptr(whens,w);
1685 when_set_inwhen(w,TRUE);
1686 break;
1687 case MODEL_INST:
1688 ProcessModelsInWhens(child,rels,logrels,whens);
1689 break;
1690 case ARRAY_ENUM_INST:
1691 case ARRAY_INT_INST:
1692 if (ArrayIsRelation(child) || ArrayIsWhen(child)
1693 || ArrayIsLogRel(child) || ArrayIsModel(child)) {
1694 ProcessArraysInWhens(child,rels,logrels,whens);
1695 }
1696 break;
1697 default:
1698 break;
1699 }
1700 }
1701 }
1702
1703 static
1704 void ProcessModelsInWhens(struct Instance *cur_inst, struct gl_list_t *rels,
1705 struct gl_list_t *logrels, struct gl_list_t *whens)
1706 {
1707 struct rel_relation *rel;
1708 struct logrel_relation *lrel;
1709 struct w_when *w;
1710 struct Instance *child;
1711 struct solver_ipdata *ip;
1712 unsigned long c,nch;
1713
1714 if (cur_inst==NULL) return;
1715 nch = NumberChildren(cur_inst);
1716 for (c=1;c<=nch;c++) {
1717 child = InstanceChild(cur_inst,c);
1718 if (child==NULL) continue;
1719 switch (InstanceKind(child)) {
1720 case REL_INST:
1721 ip = SIP(GetInterfacePtr(child));
1722 ip->u.r.active = 0;
1723 rel = ip->u.r.data;
1724 gl_append_ptr(rels,rel);
1725 break;
1726 case LREL_INST:
1727 ip = SIP(GetInterfacePtr(child));
1728 ip->u.lr.active = 0;
1729 lrel = ip->u.lr.data;
1730 gl_append_ptr(logrels,lrel);
1731 break;
1732 case WHEN_INST:
1733 ip = SIP(GetInterfacePtr(child));
1734 w = ip->u.w.data;
1735 gl_append_ptr(whens,w);
1736 when_set_inwhen(w,TRUE);
1737 break;
1738 case MODEL_INST:
1739 ProcessModelsInWhens(child,rels,logrels,whens);
1740 break;
1741 case ARRAY_ENUM_INST:
1742 case ARRAY_INT_INST:
1743 if (ArrayIsRelation(child) || ArrayIsWhen(child)
1744 || ArrayIsLogRel(child) || ArrayIsModel(child)) {
1745 ProcessArraysInWhens(child,rels,logrels,whens);
1746 }
1747 break;
1748 default:
1749 break;
1750 }
1751 }
1752 }
1753
1754
1755 /*
1756 * The goal of this function is to fill in the list of cases and variables
1757 * of a w_when structure with the appropriate data. The information required
1758 * is provided by the corresponding when Instance generated in the
1759 * compilation time. So, what we do is:
1760 * 1) Obtain the list of variables and the list of cases from each
1761 * WHEN intance.
1762 * The list of variables is actually a list of pointers to instances
1763 * 2) From each CASE, obtain also the list of references. This list of
1764 * references contains a list of pointers to each relation,logrelation and
1765 * model included inside the case.
1766 * 3) The pointers to the variables, relations, logrelations and models are
1767 * used to obtain the solver data associated with the compiled instances.
1768 * 4) Arrays and models are managed recursively with the two previous
1769 * functions.
1770 */
1771 static
1772 void ProcessSolverWhens(struct w_when *when,struct Instance *i)
1773 {
1774 struct gl_list_t *scratch;
1775 struct gl_list_t *wvars;
1776 struct gl_list_t *ref;
1777 struct gl_list_t *rels;
1778 struct gl_list_t *logrels;
1779 struct gl_list_t *whens;
1780 struct gl_list_t *diswhens;
1781 struct Set *ValueList;
1782 struct Instance *cur_inst;
1783 struct Case *cur_case;
1784 struct solver_ipdata *ip;
1785 struct dis_discrete *dvar;
1786 struct rel_relation *rel;
1787 struct logrel_relation *lrel;
1788 struct w_when *w;
1789 struct when_case *cur_sol_case;
1790 int c,r,len,lref;
1791 int *value;
1792
1793 scratch = GetInstanceWhenVars(i);
1794 len = gl_length(scratch);
1795 wvars = gl_create(len);
1796 when->dvars = wvars;
1797 for (c=1;c<=len;c++) {
1798 cur_inst = (struct Instance *)(gl_fetch(scratch,c));
1799 ip = SIP(GetInterfacePtr(cur_inst));
1800 dvar = ip->u.dv.data;
1801 if (dis_whens_list(dvar)==NULL) {
1802 diswhens = gl_create(2L);
1803 dis_set_whens_list(dvar,diswhens);
1804 } else {
1805 diswhens = dis_whens_list(dvar);
1806 }
1807 gl_append_ptr(diswhens,when);
1808 gl_append_ptr(when->dvars,dvar);
1809 }
1810
1811 scratch = GetInstanceWhenCases(i);
1812 len = gl_length(scratch);
1813 when->cases = gl_create(len);
1814 for (c=1;c<=len;c++) {
1815 cur_sol_case = when_case_create(NULL);
1816 cur_case = (struct Case *)(gl_fetch(scratch,c));
1817 ValueList = GetCaseValues(cur_case);
1818 value = &(cur_sol_case->values[0]);
1819 if (g_symbol_values_list == NULL) {
1820 g_symbol_values_list = gl_create(2L);
1821 }
1822 ProcessValueList(ValueList,value,g_symbol_values_list);
1823 ref = GetCaseReferences(cur_case);
1824 lref = gl_length(ref);
1825 rels = gl_create(lref); /* maybe allocating less than needed (models) */
1826 logrels = gl_create(lref); /* maybe allocating less than needed */
1827 whens = gl_create(lref); /* maybe allocating more than needed */
1828 for (r=1;r<=lref;r++) {
1829 cur_inst = (struct Instance *)(gl_fetch(ref,r));
1830 switch(InstanceKind(cur_inst)){
1831 case REL_INST:
1832 ip = SIP(GetInterfacePtr(cur_inst));
1833 ip->u.r.active = 0;
1834 rel = ip->u.r.data;
1835 gl_append_ptr(rels,rel);
1836 break;
1837 case LREL_INST:
1838 ip = SIP(GetInterfacePtr(cur_inst));
1839 ip->u.lr.active = 0;
1840 lrel = ip->u.lr.data;
1841 gl_append_ptr(logrels,lrel);
1842 break;
1843 case WHEN_INST:
1844 ip = SIP(GetInterfacePtr(cur_inst));
1845 w = ip->u.w.data;
1846 gl_append_ptr(whens,w);
1847 when_set_inwhen(w,TRUE);
1848 break;
1849 case MODEL_INST:
1850 ProcessModelsInWhens(cur_inst,rels,logrels,whens);
1851 break;
1852 default:
1853 break;
1854 }
1855 }
1856 when_case_set_rels_list(cur_sol_case,rels);
1857 when_case_set_logrels_list(cur_sol_case,logrels);
1858 when_case_set_whens_list(cur_sol_case,whens);
1859 when_case_set_active(cur_sol_case,FALSE);
1860 gl_append_ptr(when->cases,cur_sol_case);
1861 }
1862 }
1863
1864
1865 /*
1866 * Next two functions are for needed in the reconfiguration of
1867 * conditional models
1868 */
1869
1870 /*
1871 * return 1 if the discrete var is a member of the when var list, else
1872 * return 0
1873 */
1874 int dis_var_in_a_when(struct Instance *var, struct w_when *when)
1875 {
1876 struct Instance *winst;
1877
1878 winst = (struct Instance *)(when_instance(when));
1879 return VarFoundInWhen(var,winst);
1880 }
1881
1882
1883 /*
1884 * Determine if the conditional variable inst is part of the
1885 * variable list of some when in the when list.
1886 */
1887 int varinst_found_in_whenlist(slv_system_t sys, struct Instance *inst)
1888 {
1889 struct w_when **whenlist;
1890 struct w_when *when;
1891 int c;
1892
1893 whenlist = slv_get_solvers_when_list(sys);
1894 for (c=0; whenlist[c]!=NULL; c++) {
1895 when = whenlist[c];
1896 if (dis_var_in_a_when(inst,when)) {
1897 return 1;
1898 }
1899 }
1900 return 0;
1901 }
1902
1903
1904
1905 /*
1906 * Boundary Processing
1907 */
1908
1909 /*
1910 * Get the list or logrelation including a boundary (by means of a
1911 * SATISFIED term). This function look the structures in the compiler
1912 * side and make the same link in the solver side
1913 */
1914 static
1915 void GetListOfLogRels(struct bnd_boundary *bnd, struct Instance *inst)
1916 {
1917 struct gl_list_t *logrels;
1918 unsigned long c,len;
1919 struct Instance *i;
1920 struct logrel_relation *lrel;
1921 struct solver_ipdata *lrip;
1922
1923 len = LogRelationsCount(inst);
1924
1925 if (len>0) {
1926 logrels = gl_create(len);
1927 for (c=1; c<=len; c++) {
1928 i = LogRelationsForInstance(inst,c);
1929 lrip = SIP(GetInterfacePtr(i));
1930 lrel = lrip->u.lr.data;
1931 gl_append_ptr(logrels,lrel);
1932 }
1933 bnd_set_logrels(bnd,logrels);
1934 }
1935 return;
1936 }
1937
1938 /*
1939 * Get the tolerance used to define the satisfaction of a boundary
1940 * (Defined in the SATISFIED term)
1941 */
1942 static
1943 void GetTolerance(struct bnd_boundary *bnd)
1944 {
1945 struct gl_list_t *logrels;
1946 unsigned long c,len;
1947 struct logrel_relation *lrel;
1948 struct Instance *i,*rel;
1949 double tolerance;
1950
1951 rel = (struct Instance *)(rel_instance(bnd_rel(bnd_real_cond(bnd))));
1952 logrels = bnd_logrels(bnd);
1953 len = gl_length(logrels);
1954 for (c=1; c<=len; c++) {
1955 lrel = (struct logrel_relation *)(gl_fetch(logrels,c));
1956 i = (struct Instance *)(logrel_instance(lrel));
1957 if (FindTolInSatTermOfLogRel(i,rel,&tolerance )) {
1958 bnd_set_tolerance(bnd,tolerance);
1959 return;
1960 }
1961 }
1962 }
1963
1964
1965
1966
1967 /*
1968 * Here we roll the master lists and bridge data into relation/var/
1969 * logrelation/conditional/when etc. lists for the consumer.
1970 * Includes fixing up rel caches and initing flagbits as best we can.
1971 * includes setting master indices on rel/var/logrel/when etc.
1972 * returns 0 if ok, 1 if out of memory, 2 if the problem does not
1973 * contain at least one variable in one equation
1974 */
1975 static int analyze_make_solvers_lists(struct problem_t *p_data)
1976 {
1977 CONST struct relation *gut;
1978 CONST struct logrelation *lgut;
1979 struct ExtRelCache *cache;
1980 struct Instance *i;
1981 struct Instance *i_r;
1982 struct solver_ipdata *rip, *vip;
1983 struct solver_ipdata *lrip, *dvip, *wip;
1984 struct var_variable **incidence = NULL;
1985 struct rel_relation **varincidence = NULL;
1986 struct dis_discrete **logincidence = NULL;
1987 struct var_variable *var;
1988 struct rel_relation *rel;
1989 struct dis_discrete *dvar;
1990 struct logrel_relation *lrel;
1991 struct bnd_boundary *bnd;
1992 struct w_when *when;
1993 int order,nnzold, nodestamp;
1994 int logorder,lognnzold;
1995 int c,len,v,vlen,r,found;
1996 uint32 flags;
1997
1998 order = MAX(gl_length(p_data->vars),gl_length(p_data->rels));
1999 nnzold = p_data->nnz = p_data->nnztot
2000 = p_data->nnzobj = p_data->nnzcond = 0;
2001 p_data->nrow = 0; /* number of included relations */
2002 for (c=1,len = gl_length(p_data->rels); c <= len; c++) {
2003 rip = SIP(gl_fetch(p_data->rels,c));
2004 gut = GetInstanceRelationOnly(rip->i);
2005 vlen = NumberVariables(gut);
2006 p_data->nnztot += vlen;
2007 if (rip->u.r.included) {
2008 p_data->nrow++;
2009 nnzold = p_data->nnz;
2010 for( v = 1 ; v <= vlen; v++ ) {
2011 i = RelationVariable(gut,v);
2012 vip = SIP(GetInterfacePtr(i));
2013 if (!(vip->u.v.fixed)) {
2014 p_data->nnz++;
2015 }
2016 }
2017 if (p_data->nnz==nnzold) {
2018 FPRINTF(ASCWAR,"No free variables in included relation:\n");
2019 WriteInstanceName(ASCWAR,rip->i,p_data->root);
2020 }
2021 }
2022 }
2023 for (c=1,len = gl_length(p_data->objrels); c <= len; c++) {
2024 rip = SIP(gl_fetch(p_data->objrels,c));
2025 gut = GetInstanceRelationOnly(rip->i);
2026 vlen = NumberVariables(gut);
2027 p_data->nnzobj += vlen;
2028 }
2029
2030 /* Conditional relations */
2031 for (c=1,len = gl_length(p_data->cnds); c <= len; c++) {
2032 rip = SIP(gl_fetch(p_data->cnds,c));
2033 gut = GetInstanceRelationOnly(rip->i);
2034 vlen = NumberVariables(gut);
2035 p_data->nnzcond += vlen;
2036 }
2037
2038
2039 /*
2040 * calculate the number of free and incident variables, ncol
2041 * we put all the nonincident on the unas list, so just check fixed.
2042 */
2043 for (c=1,len = gl_length(p_data->vars); c <= len; c++) {
2044 vip = SIP(gl_fetch(p_data->vars,c));
2045 if (!(vip->u.v.fixed)) p_data->ncol++;
2046 }
2047 /*
2048 * now, at last we have cols jacobian in the order we want the lists to
2049 * be handed to the solvers.
2050 */
2051
2052
2053 logorder = MAX((unsigned long)p_data->lrelinc,gl_length(p_data->logrels));
2054 lognnzold = p_data->lognnz = p_data->lrelincsize = 0;
2055 p_data->lognrow = 0; /* number of included logrelations */
2056 for (c=1,len = gl_length(p_data->logrels); c <= len; c++) {
2057 lrip = SIP(gl_fetch(p_data->logrels,c));
2058 lgut = GetInstanceLogRelOnly(lrip->i);
2059 vlen = NumberBoolVars(lgut);
2060 p_data->lrelincsize += vlen;
2061 if (lrip->u.lr.included) {
2062 p_data->lognrow++;
2063 lognnzold = p_data->lognnz;
2064 for( v = 1 ; v <= vlen; v++ ) {
2065 i = LogRelBoolVar(lgut,v);
2066 dvip = SIP(GetInterfacePtr(i));
2067 if (!(dvip->u.dv.fixed)) {
2068 p_data->lognnz++;
2069 }
2070 }
2071 if (p_data->lognnz==lognnzold) {
2072 FPRINTF(ASCWAR,
2073 "No free boolean variables in included logrelation:\n");
2074 WriteInstanceName(ASCWAR,rip->i,p_data->root);
2075 }
2076 }
2077 }
2078
2079 /* Conditional logrelations */
2080 for (c=1,len = gl_length(p_data->logcnds); c <= len; c++) {
2081 lrip = SIP(gl_fetch(p_data->logcnds,c));
2082 lgut = GetInstanceLogRelOnly(lrip->i);
2083 vlen = NumberBoolVars(lgut);
2084 p_data->lrelincsize += vlen;
2085 }
2086
2087 if (!(p_data->nnztot+p_data->nnzobj) && !(p_data->lognnz)) {
2088 FPRINTF(ASCERR, "Problem should contain at least one variable %s",
2089 "and one relation\n");
2090 return 2;
2091 }
2092 /*
2093 * we want at least one variable in one obj or rel,
2094 * or at least one boolean variable in one logrel
2095 */
2096
2097
2098 /* calculate the number of free and incident boolean variables, logncol */
2099 for (c=1,len = p_data->lrelinc; c <= len; c++) {
2100 dvip = SIP(gl_fetch(p_data->dvars,c));
2101 if (!(dvip->u.dv.fixed)) p_data->logncol++;
2102 }
2103
2104
2105 /* now malloc and build things, remember to punt the matrix soon */
2106 /* remember we must NEVER free these things individually. */
2107
2108 #define ALLOCVARDATA(p,n) (p) = (struct var_variable *)( \
2109 ((n)>0) ? ascmalloc((n)*sizeof(struct var_variable)) : NULL)
2110 #define ALLOCRELDATA(p,n) (p) = (struct rel_relation *)( \
2111 ((n)>0) ? ascmalloc((n)*sizeof(struct rel_relation)) : NULL)
2112 #define ALLOCDISVARDATA(p,n) (p) = (struct dis_discrete *)( \
2113 ((n)>0) ? ascmalloc((n)*sizeof(struct dis_discrete)) : NULL)
2114 #define ALLOCLOGRELDATA(p,n) (p) = (struct logrel_relation *)( \
2115 ((n)>0) ? ascmalloc((n)*sizeof(struct logrel_relation)) : NULL)
2116 #define ALLOCWHENDATA(p,n) (p) = (struct w_when *)( \
2117 ((n)>0) ? ascmalloc((n)*sizeof(struct w_when)) : NULL)
2118 #define ALLOCBNDDATA(p,n) (p) = (struct bnd_boundary *)( \
2119 ((n)>0) ? ascmalloc((n)*sizeof(struct bnd_boundary)) : NULL)
2120 ALLOCVARDATA(p_data->vardata,p_data->nv);
2121 ALLOCVARDATA(p_data->pardata,p_data->np);
2122 ALLOCVARDATA(p_data->undata,p_data->nu);
2123 ALLOCDISVARDATA(p_data->disdata,p_data->ndv);
2124 ALLOCDISVARDATA(p_data->undisdata,p_data->nud);
2125 ALLOCRELDATA(p_data->reldata,p_data->nr);
2126 ALLOCRELDATA(p_data->objdata,p_data->no);
2127 ALLOCRELDATA(p_data->condata,p_data->nc);
2128 ALLOCLOGRELDATA(p_data->lrdata,p_data->nl);
2129 ALLOCLOGRELDATA(p_data->logcondata,p_data->ncl);
2130 ALLOCWHENDATA(p_data->whendata,p_data->nw);
2131 ALLOCBNDDATA(p_data->bnddata,p_data->nc+p_data->ncl);
2132
2133 #define ALLOCVARLIST(p,n) (p) = (struct var_variable **)( \
2134 ((n)>0) ? ascmalloc((n)*sizeof(struct var_variable *)) : NULL)
2135 #define ALLOCRELLIST(p,n) (p) = (struct rel_relation **)( \
2136 ((n)>0) ? ascmalloc((n)*sizeof(struct rel_relation *)) : NULL)
2137 #define ALLOCDISVARLIST(p,n) (p) = (struct dis_discrete **)( \
2138 ((n)>0) ? ascmalloc((n)*sizeof(struct dis_discrete *)) : NULL)
2139 #define ALLOCLOGRELLIST(p,n) (p) = (struct logrel_relation **)( \
2140 ((n)>0) ? ascmalloc((n)*sizeof(struct logrel_relation *)) : NULL)
2141 #define ALLOCWHENLIST(p,n) (p) = (struct w_when **)( \
2142 ((n)>0) ? ascmalloc((n)*sizeof(struct w_when *)) : NULL)
2143 #define ALLOCBNDLIST(p,n) (p) = (struct bnd_boundary **)( \
2144 ((n)>0) ? ascmalloc((n)*sizeof(struct bnd_boundary *)) : NULL)
2145 ALLOCVARLIST(p_data->mastervl,p_data->nv+1);
2146 ALLOCVARLIST(p_data->masterpl,p_data->np+1);
2147 ALLOCVARLIST(p_data->masterul,p_data->nu+1);
2148 ALLOCDISVARLIST(p_data->masterdl,p_data->ndv+1);
2149 ALLOCDISVARLIST(p_data->masterdul,p_data->nud+1);
2150 ALLOCRELLIST(p_data->masterrl,p_data->nr+1);
2151 ALLOCRELLIST(p_data->masterol,p_data->no+1);
2152 ALLOCRELLIST(p_data->mastercl,p_data->nc+1);
2153 ALLOCLOGRELLIST(p_data->masterll,p_data->nl+1);
2154 ALLOCLOGRELLIST(p_data->mastercll,p_data->ncl+1);
2155 ALLOCWHENLIST(p_data->masterwl,p_data->nw+1);
2156 ALLOCBNDLIST(p_data->masterbl,p_data->nc+p_data->ncl+1);
2157 ALLOCVARLIST(p_data->solvervl,p_data->nv+1);
2158 ALLOCVARLIST(p_data->solverpl,p_data->np+1);
2159 ALLOCVARLIST(p_data->solverul,p_data->nu+1);
2160 ALLOCDISVARLIST(p_data->solverdl,p_data->ndv+1);
2161 ALLOCDISVARLIST(p_data->solverdul,p_data->nud+1);
2162 ALLOCRELLIST(p_data->solverrl,p_data->nr+1);
2163 ALLOCRELLIST(p_data->solverol,p_data->no+1);
2164 ALLOCRELLIST(p_data->solvercl,p_data->nc+1);
2165 ALLOCLOGRELLIST(p_data->solverll,p_data->nl+1);
2166 ALLOCLOGRELLIST(p_data->solvercll,p_data->ncl+1);
2167 ALLOCWHENLIST(p_data->solverwl,p_data->nw+1);
2168 ALLOCBNDLIST(p_data->solverbl,p_data->nc+p_data->ncl+1);
2169
2170 ALLOCVARLIST(p_data->relincidence,p_data->nnztot+p_data->nnzobj +
2171 p_data->nnzcond);
2172 ALLOCDISVARLIST(p_data->logrelinciden,p_data->lrelincsize);
2173 #define CHECKPTRSIZE(n,p) if ((n)>0 && (p)==NULL) return 1
2174 #define CHECKPTR(p) if ((p)==NULL) return 1
2175 /* verify mem allocations. */
2176 CHECKPTRSIZE(p_data->nv,p_data->vardata);
2177 CHECKPTRSIZE(p_data->np,p_data->pardata);
2178 CHECKPTRSIZE(p_data->nu,p_data->undata);
2179 CHECKPTRSIZE(p_data->ndv,p_data->disdata);
2180 CHECKPTRSIZE(p_data->nud,p_data->undisdata);
2181 CHECKPTRSIZE(p_data->nr,p_data->reldata);
2182 CHECKPTRSIZE(p_data->no,p_data->objdata);
2183 CHECKPTRSIZE(p_data->nc,p_data->condata);
2184 CHECKPTRSIZE(p_data->nl,p_data->lrdata);
2185 CHECKPTRSIZE(p_data->ncl,p_data->logcondata);
2186 CHECKPTRSIZE(p_data->nw,p_data->whendata);
2187 CHECKPTRSIZE(p_data->nc+p_data->ncl,p_data->bnddata);
2188 CHECKPTR(p_data->mastervl);
2189 CHECKPTR(p_data->masterpl);
2190 CHECKPTR(p_data->masterul);
2191 CHECKPTR(p_data->masterdl);
2192 CHECKPTR(p_data->masterdul);
2193 CHECKPTR(p_data->masterrl);
2194 CHECKPTR(p_data->masterol);
2195 CHECKPTR(p_data->mastercl);
2196 CHECKPTR(p_data->masterll);
2197 CHECKPTR(p_data->mastercll);
2198 CHECKPTR(p_data->masterwl);
2199 CHECKPTR(p_data->masterbl);
2200 CHECKPTR(p_data->solvervl);
2201 CHECKPTR(p_data->solverpl);
2202 CHECKPTR(p_data->solverul);
2203 CHECKPTR(p_data->solverdl);
2204 CHECKPTR(p_data->solverdul);
2205 CHECKPTR(p_data->solverrl);
2206 CHECKPTR(p_data->solverol);
2207 CHECKPTR(p_data->solvercl);
2208 CHECKPTR(p_data->solverll);
2209 CHECKPTR(p_data->solvercll);
2210 CHECKPTR(p_data->solverwl);
2211 CHECKPTR(p_data->solverbl);
2212 CHECKPTR(p_data->relincidence);
2213 CHECKPTRSIZE(p_data->lrelincsize,p_data->logrelinciden);
2214 p_data->relincsize = p_data->nnztot+p_data->nnzobj + p_data->nnzcond;
2215 p_data->relincinuse = 0;
2216 p_data->lrelincinuse = 0;
2217
2218 /*
2219 * for c in varlist copy vardata. remember gllist # from 1 and data from 0
2220 */
2221 /*
2222 * for c in varlist set mastervl, solvervl pointer to point to data
2223 */
2224 vlen = gl_length(p_data->vars);
2225 for (v = 0; v < vlen; v++) {
2226 var = &(p_data->vardata[v]);
2227 vip = SIP(gl_fetch(p_data->vars,v+1));
2228 vip->u.v.data = var;
2229 var_set_instance(var,vip->i);
2230 var_set_mindex(var,v);
2231 var_set_sindex(var,v);
2232 flags = 0; /* all init to FALSE */
2233 /* turn on appropriate ones */
2234 if (vip->u.v.incident) flags |= VAR_INCIDENT;
2235 if (vip->u.v.in_block) flags |= VAR_INBLOCK;
2236 if (vip->u.v.fixed) flags |= VAR_FIXED;
2237 if (!vip->u.v.basis) flags |= VAR_NONBASIC;
2238 if (vip->u.v.solvervar) flags |= VAR_SVAR;
2239 var_set_flags(var,flags);
2240 p_data->mastervl[v] = var;
2241 p_data->solvervl[v] = var;
2242 }
2243 p_data->mastervl[vlen] = NULL; /* terminator */
2244 p_data->solvervl[vlen] = NULL; /* terminator */
2245 /*
2246 * for c in parlist copy pardata. remember gllist # from 1 and data from 0
2247 * for c in parlist set masterpl, solverpl pointer to point to data
2248 */
2249 vlen = gl_length(p_data->pars);
2250 for (v = 0; v < vlen; v++) {
2251 var = &(p_data->pardata[v]);
2252 vip = SIP(gl_fetch(p_data->pars,v+1));
2253 vip->u.v.data = var;
2254 var_set_instance(var,vip->i);
2255 var_set_mindex(var,v);
2256 var_set_sindex(var,v);
2257 flags = 0; /* all init to FALSE */
2258 /* turn on appropriate ones */
2259 if (vip->u.v.incident) flags |= VAR_INCIDENT;
2260 if (vip->u.v.in_block) flags |= VAR_INBLOCK;
2261 if (vip->u.v.fixed) flags |= VAR_FIXED;
2262 if (vip->u.v.solvervar) flags |= VAR_SVAR; /* shouldn't this be here? */
2263 var_set_flags(var,flags);
2264 p_data->masterpl[v] = var;
2265 p_data->solverpl[v] = var;
2266 }
2267 p_data->masterpl[vlen] = NULL; /* terminator */
2268 p_data->solverpl[vlen] = NULL; /* terminator */
2269 /*
2270 * for c in unalist copy undata. remember gllist # from 1 and data from 0
2271 * for c in unalist set masterul, solverul pointer to point to data
2272 */
2273 vlen = gl_length(p_data->unas);
2274 for (v = 0; v < vlen; v++) {
2275 var = &(p_data->undata[v]);
2276 vip = SIP(gl_fetch(p_data->unas,v+1));
2277 vip->u.v.data = var;
2278 var_set_instance(var,vip->i);
2279 var_set_mindex(var,v);
2280 var_set_sindex(var,v);
2281 flags = 0; /* all init to FALSE */
2282 /* turn on appropriate ones */
2283 if (vip->u.v.incident) flags |= VAR_INCIDENT;
2284 if (vip->u.v.fixed) flags |= VAR_FIXED;
2285 if (vip->u.v.solvervar) flags |= VAR_SVAR;
2286 /* others may be appropriate (PVAR) */
2287 var_set_flags(var,flags);
2288 p_data->masterul[v] = var;
2289 p_data->solverul[v] = var;
2290 }
2291 p_data->masterul[vlen] = NULL; /* terminator */
2292 p_data->solverul[vlen] = NULL; /* terminator */
2293
2294 /*
2295 * process the constraining relations
2296 * for v in rellist copy reldata and fix extrels.
2297 */
2298 vlen = gl_length(p_data->rels);
2299 for (v = 0; v < vlen; v++) {
2300 rel = &(p_data->reldata[v]);
2301 rip = SIP(gl_fetch(p_data->rels,v+1));
2302 rel = rel_create(rip->i,rel);
2303 rip->u.r.data = rel;
2304 rel_set_mindex(rel,v);
2305 rel_set_sindex(rel,v);
2306 rel_set_model(rel,rip->u.r.model-1);
2307 /* here set up the var list */
2308 gut = GetInstanceRelationOnly(rip->i);
2309 assert(gut!=NULL);
2310 len = NumberVariables(gut);
2311 if (len > 0) {
2312 incidence = get_incidence_space(len,p_data);
2313 for( c = 0; c < len; c++ ) {
2314 i = RelationVariable(gut,c+1);
2315 incidence[c] = SIP(GetInterfacePtr(i))->u.v.data;
2316 }
2317 rel_set_incidences(rel,len,incidence);
2318 } else {
2319 rel_set_incidences(rel,0,NULL);
2320 }
2321 if (rel_extnodeinfo(rel)) {
2322 cache = CheckIfCacheExists(rip->i,&nodestamp,p_data);
2323 if (cache) {
2324 rel_set_extcache(rel,cache);
2325 } else {
2326 cache = CreateCacheFromInstance(rip->i);
2327 gl_append_ptr(p_data->extrels,(POINTER)cache);
2328 rel_set_extcache(rel,cache);
2329 }
2330 }
2331 flags = 0; /* all init to FALSE */
2332 /* TURN ON APPROPRIATE ONES */
2333 if (rip->u.r.included) flags |= (REL_INCLUDED | REL_INBLOCK);
2334 if (rip->u.r.ext) flags |= REL_BLACKBOX;
2335 if (rip->u.r.active) flags |= ( REL_ACTIVE | REL_INVARIANT);
2336 if (rip->u.r.inwhen) flags |= REL_INWHEN;
2337 if ( RelationRelop(GetInstanceRelationOnly(rip->i)) == e_equal ) {
2338 flags |= REL_EQUALITY;
2339 }
2340 rel_set_flags(rel,flags);
2341 /* for c in rellist set masterrl, solverrl pointer to point to data */
2342 p_data->masterrl[v] = rel;
2343 p_data->solverrl[v] = rel;
2344 }
2345 p_data->masterrl[vlen] = NULL; /* terminator */
2346 p_data->solverrl[vlen] = NULL; /* terminator */
2347
2348 /* cobble together external rel list */
2349 len = gl_length(p_data->extrels);
2350 p_data->erlist = (struct ExtRelCache **)
2351 ascmalloc((1+len)*sizeof(struct ExtRelCache *));
2352 if (p_data->erlist==NULL) return 1;
2353 for (c=1; c <= len; c++) {
2354 p_data->erlist[c-1] = (struct ExtRelCache *)gl_fetch(p_data->extrels,c);
2355 }
2356 p_data->erlist[len] = NULL; /* terminator */
2357
2358 /*
2359 * for c in objlist copy objdata.
2360 * for c in objlist set masterrl, solverrl pointer to point to data.
2361 */
2362 /*
2363 * process the objective relations
2364 * for v in objlist copy objdata
2365 */
2366 vlen = gl_length(p_data->objrels);
2367 found = 0;
2368 for (v = 0; v < vlen; v++) {
2369 rel = &(p_data->objdata[v]);
2370 rip = SIP(gl_fetch(p_data->objrels,v+1));
2371 rel = rel_create(rip->i,rel);
2372 rip->u.r.data = rel;
2373 rel_set_mindex(rel,v);
2374 rel_set_sindex(rel,v);
2375 rel_set_model(rel,rip->u.r.model-1);
2376 /* here set up the var list */
2377 gut = GetInstanceRelationOnly(rip->i);
2378 assert(gut!=NULL);
2379 len = NumberVariables(gut);
2380 if (len > 0) {
2381 incidence = get_incidence_space(len,p_data);
2382 for( c = 0; c < len; c++ ) {
2383 i = RelationVariable(gut,c+1);
2384 incidence[c] = SIP(GetInterfacePtr(i))->u.v.data;
2385 }
2386 rel_set_incidences(rel,len,incidence);
2387 } else {
2388 rel_set_incidences(rel,0,NULL);
2389 }
2390 /* black box objectives not supported. skip it */
2391 flags = 0; /* all init to FALSE */
2392 /* TURN ON APPROPRIATE ONES */
2393 if (rip->u.r.included) {
2394 flags |= (REL_INCLUDED | REL_INBLOCK | REL_ACTIVE);
2395 }
2396 if (rip->u.r.obj < 0) flags |= REL_OBJNEGATE;
2397 rel_set_flags(rel,flags);
2398 /* for c in objrellist set masterol, solverol pointer to point to data */
2399 p_data->masterol[v] = rel;
2400 p_data->solverol[v] = rel;
2401 /* set objective to first included objective on list */
2402 if (!found && (rip->u.r.included)) {
2403 p_data->obj = rel;
2404 found = 1;
2405 }
2406 }
2407 p_data->masterol[vlen] = NULL; /* terminator */
2408 p_data->solverol[vlen] = NULL; /* terminator */
2409
2410 /*
2411 * process the conditional relations
2412 * for v in cndlist copy conddata .
2413 */
2414 vlen = gl_length(p_data->cnds);
2415 for (v = 0; v < vlen; v++) {
2416 rel = &(p_data->condata[v]);
2417 rip = SIP(gl_fetch(p_data->cnds,v+1));
2418 rel = rel_create(rip->i,rel);
2419 rip->u.r.data = rel;
2420 rel_set_mindex(rel,v);
2421 rel_set_sindex(rel,v);
2422 rel_set_model(rel,rip->u.r.model-1);
2423 gut = GetInstanceRelationOnly(rip->i);
2424 assert(gut!=NULL);
2425 len = NumberVariables(gut);
2426 if (len > 0) {
2427 incidence = get_incidence_space(len,p_data);
2428 for( c = 0; c < len; c++ ) {
2429 i = RelationVariable(gut,c+1);
2430 incidence[c] = SIP(GetInterfacePtr(i))->u.v.data;
2431 }
2432 rel_set_incidences(rel,len,incidence);
2433 } else {
2434 rel_set_incidences(rel,0,NULL);
2435 }
2436 flags = 0; /* all init to FALSE */
2437 /* TURN ON APPROPRIATE ONES */
2438 if (rip->u.r.included) {
2439 flags |= (REL_INCLUDED | REL_INBLOCK | REL_ACTIVE);
2440 }
2441 if (rip->u.r.cond) flags |= REL_CONDITIONAL;
2442 if ( RelationRelop(GetInstanceRelationOnly(rip->i)) == e_equal ) {
2443 flags |= REL_EQUALITY;
2444 }
2445 rel_set_flags(rel,flags);
2446 /* for c in rellist set masterrl, solverrl pointer to point to data */
2447 p_data->mastercl[v] = rel;
2448 p_data->solvercl[v] = rel;
2449 /* initially in same order */
2450 }
2451 p_data->mastercl[vlen] = NULL; /* terminator */
2452 p_data->solvercl[vlen] = NULL; /* terminator */
2453
2454
2455 /*
2456 * process discrete variables
2457 * for c in dvarlist copy disdata. gllist # from 1 and data from 0
2458 * for c in dvarlist set masterdl, solverdl pointer to point to data
2459 */
2460 vlen = gl_length(p_data->dvars);
2461 for (v = 0; v < vlen; v++) {
2462 dvar = &(p_data->disdata[v]);
2463 dvip = SIP(gl_fetch(p_data->dvars,v+1));
2464 /*
2465 dvip->u.dv.data = dvar;
2466 dis_set_instance(dvar,dvip->i); */
2467 /* from here */
2468 dis_create(dvip->i,dvar);
2469 dvip->u.dv.data = dvar;
2470 /* to here */
2471 dis_set_mindex(dvar,v);
2472 dis_set_sindex(dvar,v);
2473 dis_set_value(dvar,dvip->u.dv.value);
2474 dis_set_previous_value(dvar,dvip->u.dv.value);
2475 switch (dvip->u.dv.distype) {
2476 case 0:
2477 dis_set_kind(dvar,e_dis_boolean_t);
2478 break;
2479 case 1:
2480 dis_set_kind(dvar,e_dis_integer_t);
2481 break;
2482 case -1:
2483 dis_set_kind(dvar,e_dis_symbol_t);
2484 break;
2485 default:
2486 break;
2487 }
2488 flags = 0; /* all init to FALSE */
2489 /* turn on appropriate ones */
2490 if (dvip->u.dv.isconst) flags |= DIS_CONST;
2491 if (dvip->u.dv.incident) flags |= DIS_INCIDENT;
2492 if (dvip->u.dv.inwhen) flags |= DIS_INWHEN;
2493 if (dvip->u.dv.fixed) flags |= DIS_FIXED;
2494 if (dvip->u.dv.booleanvar) flags |= DIS_BVAR;
2495 if (dis_kind(dvar) == e_dis_boolean_t) flags |= DIS_BOOLEAN;
2496 dis_set_flags(dvar,flags);
2497 p_data->masterdl[v] = dvar;
2498 p_data->solverdl[v] = dvar;
2499 /* initially master and solver look the same */
2500 }
2501 p_data->masterdl[vlen] = NULL; /* terminator */
2502 p_data->solverdl[vlen] = NULL; /* terminator */
2503
2504 /*
2505 * for c in dunalist copy undisdata. gllist # from 1 and data from 0
2506 * for c in dunalist set masterdul, solverdul pointer to point to data
2507 */
2508 vlen = gl_length(p_data->dunas);
2509 for (v = 0; v < vlen; v++) {
2510 dvar = &(p_data->undisdata[v]);
2511 dvip = SIP(gl_fetch(p_data->dunas,v+1));
2512 dis_create(dvip->i,dvar);
2513 dvip->u.dv.data = dvar;
2514 dis_set_mindex(dvar,v);
2515 dis_set_sindex(dvar,v);
2516 flags = 0; /* all init to FALSE */
2517 /* turn on appropriate ones */
2518 if (dvip->u.dv.fixed) flags |= DIS_FIXED;
2519 if (dvip->u.dv.booleanvar) flags |= DIS_BVAR;
2520 dis_set_flags(dvar,flags);
2521 p_data->masterdul[v] = dvar;
2522 p_data->solverdul[v] = dvar;
2523 }
2524 p_data->masterdul[vlen] = NULL; /* terminator */
2525 p_data->solverdul[vlen] = NULL; /* terminator */
2526
2527
2528 /*
2529 * for c in logrellist copy lrdata.
2530 * for c in logrellist set masterll, solverll pointer to point to data.
2531 */
2532 /*
2533 * process the logical relations
2534 * for v in logrellist copy lrdata
2535 */
2536 vlen = gl_length(p_data->logrels);
2537 for (v = 0; v < vlen; v++) {
2538 lrel = &(p_data->lrdata[v]);
2539 lrip = SIP(gl_fetch(p_data->logrels,v+1));
2540 lrel = logrel_create(lrip->i,lrel);
2541 lrip->u.lr.data = lrel;
2542 logrel_set_mindex(lrel,v);
2543 logrel_set_sindex(lrel,v);
2544 logrel_set_model(lrel,lrip->u.lr.model-1);
2545 /* here set up the dis var list */
2546 lgut = GetInstanceLogRelOnly(lrip->i);
2547 assert(lgut!=NULL);
2548 len = NumberBoolVars(lgut);
2549 if (len > 0) {
2550 logincidence = get_logincidence_space(len,p_data);
2551 for( c = 0; c < len; c++ ) {
2552 i = LogRelBoolVar(lgut,c+1);
2553 logincidence[c] = SIP(GetInterfacePtr(i))->u.dv.data;
2554 }
2555 logrel_set_incidences(lrel,len,logincidence);
2556 } else {
2557 logrel_set_incidences(lrel,0,NULL);
2558 }
2559 flags = 0; /* all init to FALSE */
2560 /* TURN ON APPROPRIATE ONES */
2561 if (lrip->u.lr.included) flags |= LOGREL_INCLUDED;
2562 if (lrip->u.lr.active) flags |= LOGREL_ACTIVE;
2563 if (lrip->u.lr.inwhen) flags |= LOGREL_INWHEN;
2564 if ( LogRelRelop(GetInstanceLogRelOnly(lrip->i)) == e_boolean_eq ) {
2565 flags |= LOGREL_EQUALITY;
2566 }
2567 logrel_set_flags(lrel,flags);
2568 /* for c in logrellist set masterll, solverll pointer to point to data */
2569 p_data->masterll[v] = lrel;
2570 p_data->solverll[v] = lrel;
2571 }
2572 p_data->masterll[vlen] = NULL; /* terminator */
2573 p_data->solverll[vlen] = NULL; /* terminator */
2574
2575
2576 /*
2577 * process the conditional logrelations
2578 * for v in logcndlist copy logconddata
2579 */
2580 vlen = gl_length(p_data->logcnds);
2581 for (v = 0; v < vlen; v++) {
2582 lrel = &(p_data->logcondata[v]);
2583 lrip = SIP(gl_fetch(p_data->logcnds,v+1));
2584 lrel = logrel_create(lrip->i,lrel);
2585 lrip->u.lr.data = lrel;
2586 logrel_set_mindex(lrel,v);
2587 logrel_set_sindex(lrel,v);
2588 logrel_set_model(lrel,lrip->u.lr.model-1);
2589 lgut = GetInstanceLogRelOnly(lrip->i);
2590 assert(lgut!=NULL);
2591 len = NumberBoolVars(lgut);
2592 if (len > 0) {
2593 logincidence = get_logincidence_space(len,p_data);
2594 for( c = 0; c < len; c++ ) {
2595 i = LogRelBoolVar(lgut,c+1);
2596 logincidence[c] = SIP(GetInterfacePtr(i))->u.dv.data;
2597 }
2598 logrel_set_incidences(lrel,len,logincidence);
2599 } else {
2600 logrel_set_incidences(lrel,0,NULL);
2601 }
2602 flags = 0; /* all init to FALSE */
2603 /* TURN ON APPROPRIATE ONES */
2604 if (lrip->u.lr.included) flags |= (LOGREL_INCLUDED | LOGREL_ACTIVE);
2605 if (lrip->u.lr.cond) flags |= LOGREL_CONDITIONAL;
2606 if ( LogRelRelop(GetInstanceLogRelOnly(lrip->i)) == e_boolean_eq) {
2607 flags |= LOGREL_EQUALITY;
2608 }
2609 logrel_set_flags(lrel,flags);
2610 /* for c in lrellist set masterll, solverll pointer to point to data */
2611 p_data->mastercll[v] = lrel;
2612 p_data->solvercll[v] = lrel;
2613 /* initially in same order */
2614 }
2615 p_data->mastercll[vlen] = NULL; /* terminator */
2616 p_data->solvercll[vlen] = NULL; /* terminator */
2617
2618
2619 /*
2620 * process the boundaries
2621 * for v in cndlist and logcndlist, copy bnddata.
2622 */
2623 vlen = gl_length(p_data->cnds);
2624 len = gl_length(p_data->logcnds);
2625 /* real conditions */
2626 for (v = 0; v < vlen; v++) {
2627 bnd = &(p_data->bnddata[v]);
2628 bnd = bnd_create(bnd);
2629 bnd_set_kind(bnd,e_bnd_rel);
2630 rip = SIP(gl_fetch(p_data->cnds,v+1));
2631 bnd_real_cond(bnd) = bnd_rel(rip->u.r.data);
2632 bnd_set_mindex(bnd,v);
2633 bnd_set_sindex(bnd,v);
2634 bnd_set_model(bnd,rip->u.r.model-1);
2635 flags = 0; /* all init to FALSE */
2636 flags |= BND_REAL;
2637 bnd_set_flags(bnd,flags);
2638 /* for c in lrellist set masterbl, solverbl pointer to point to data */
2639 p_data->masterbl[v] = bnd;
2640 p_data->solverbl[v] = bnd;
2641 }
2642 /* logical conditions */
2643 for (v = vlen; v <vlen+len; v++) {
2644 bnd = &(p_data->bnddata[v]);
2645 bnd = bnd_create(bnd);
2646 bnd_set_kind(bnd,e_bnd_logrel);
2647 lrip = SIP(gl_fetch(p_data->logcnds,v-vlen+1));
2648 bnd_log_cond(bnd) = bnd_logrel(lrip->u.lr.data);
2649 bnd_set_mindex(bnd,v);
2650 bnd_set_sindex(bnd,v);
2651 bnd_set_model(bnd,lrip->u.lr.model-1);
2652 flags = 0; /* all init to FALSE */
2653 bnd_set_flags(bnd,flags);
2654 /* for c in lrellist set masterbl, solverbl pointer to point to data */
2655 p_data->masterbl[v] = bnd;
2656 p_data->solverbl[v] = bnd;
2657 }
2658 p_data->masterbl[vlen+len] = NULL; /* terminator */
2659 p_data->solverbl[vlen+len] = NULL; /* terminator */
2660
2661 /*
2662 * Finding list of logical relations using the condition, and the
2663 * tolerance (only for the case of real condition ). Defining some
2664 * flags
2665 */
2666
2667 for (v = 0; v < vlen; v++) {
2668 bnd = p_data->masterbl[v];
2669 rel = bnd_rel(bnd_real_cond(bnd));
2670 flags = bnd_flags(bnd);
2671 if(rel_equality(rel)) {
2672 flags |= BND_EQUALITY;
2673 }
2674 i = (struct Instance *)rel_instance(rel);
2675 GetListOfLogRels(bnd,i);
2676 if(bnd_logrels(bnd)!= NULL) {
2677 flags |= BND_IN_LOGREL;
2678 GetTolerance(bnd);
2679 }
2680 bnd_set_flags(bnd,flags);
2681 }
2682 for (v = vlen; v < vlen+len; v++) {
2683 bnd = p_data->masterbl[v];
2684 lrel = bnd_logrel(bnd_log_cond(bnd));
2685 flags = bnd_flags(bnd);
2686 if(logrel_equality(lrel)) {
2687 flags |= BND_EQUALITY;
2688 }
2689 i = (struct Instance *)logrel_instance(lrel);
2690 GetListOfLogRels(bnd,i);
2691 if(bnd_logrels(bnd)!= NULL) {
2692 flags |= BND_IN_LOGREL;
2693 }
2694 bnd_set_flags(bnd,flags);
2695 }
2696
2697 /*
2698 * for c in whenlist copy whendata.
2699 * for c in whenllist set masterwl, solverwl pointer to point to data.
2700 */
2701 /* process whens */
2702
2703 vlen = gl_length(p_data->whens);
2704 for (v = 0; v < vlen; v++) {
2705 when = &(p_data->whendata[v]);
2706 wip = SIP(gl_fetch(p_data->whens,v+1));
2707 when = when_create(wip->i,when);
2708 wip->u.w.data = when;
2709 when_set_mindex(when,v);
2710 when_set_sindex(when,v);
2711 when_set_model(when,wip->u.w.model-1);
2712 p_data->masterwl[v] = when;
2713 p_data->solverwl[v] = when;
2714 flags = 0;
2715 if (wip->u.w.inwhen) flags |= WHEN_INWHEN;
2716 when_set_flags(when,flags);
2717 }
2718 p_data->masterwl[vlen] = NULL; /* terminator */
2719 p_data->solverwl[vlen] = NULL; /* terminator */
2720
2721 /*
2722 * Get data from the when instance to fill the
2723 * list in the w_when instance
2724 */
2725
2726 for (v = 0; v < vlen; v++) {
2727 when = p_data->masterwl[v];
2728 i = (struct Instance *)(when_instance(when));
2729 ProcessSolverWhens(when,i);
2730 }
2731
2732 /* configure the problem */
2733
2734 if (vlen > 0) { /* we have whens */
2735 configure_conditional_problem(vlen,p_data->masterwl,
2736 p_data->solverrl,p_data->solverll,
2737 p_data->mastervl);
2738 /* Is consistency analysis required ? */
2739 p_data->need_consistency = 0;
2740 for (v = 0; v < vlen; v++) {
2741 when = p_data->masterwl[v];
2742 if (when_changes_structure(when)) {
2743 p_data->need_consistency = 1;
2744 break;
2745 }
2746 }
2747
2748 #if DEBUG_ANALYSIS
2749 if ( p_data->need_consistency == 0 ) {
2750 FPRINTF(ASCERR,"All alternativeS HAVE THE SAME STRUCTURE \n");
2751 FPRINTF(ASCERR,"Consistency analysis is not required \n");
2752 } else {
2753 FPRINTF(ASCERR,"Consistency analysis may be required \n");
2754 }
2755 FPRINTF(ASCERR,"\n");
2756 #endif /* DEBUG_ANALYSIS */
2757
2758 } else {
2759
2760 /*
2761 * All variables in active relations are set as active.
2762 * This is necessary because the existence of some variables
2763 * in conditional relations which should not be active.
2764 *
2765 * Before we were doing:
2766 *
2767 * for (v = 0;p_data->solvervl[v]!=NULL ; v++) {
2768 * var = p_data->solvervl[v];
2769 * var_set_active(var,TRUE);
2770 * }
2771 *
2772 * for (v = 0;p_data->solverdl[v]!=NULL ; v++) {
2773 * dvar = p_data->solverdl[v];
2774 * dis_set_active(dvar,TRUE);
2775 * }
2776 *
2777 * which do not considerate such situation
2778 */
2779
2780 set_active_vars_in_active_rels(p_data->solverrl);
2781 set_active_vars_in_active_rels(p_data->solverol);
2782 set_active_disvars_in_active_logrels(p_data->solverll);
2783
2784 /*
2785 * All the unattached are set active to keep an accurate
2786 * counting in the solver side.
2787 */
2788
2789 for (v = 0;p_data->solverul[v]!=NULL ; v++) {
2790 var = p_data->solverul[v];
2791 var_set_active(var,TRUE);
2792 }
2793
2794 for (v = 0;p_data->solverdul[v]!=NULL ; v++) {
2795 dvar = p_data->solverdul[v];
2796 dis_set_active(dvar,TRUE);
2797 }
2798 }
2799
2800 /*
2801 * Code to make the variables aware of the relation they are
2802 * incident in. KHT
2803 */
2804 vlen = gl_length(p_data->vars);
2805 for (v = 0; v < vlen; v++) {
2806 var = &(p_data->vardata[v]);
2807 i = var_instance(var);
2808 len = RelationsCount(i);
2809 p_data->varincsize += len;
2810 }
2811
2812 ALLOCRELLIST(p_data->varincidence,p_data->varincsize);
2813
2814 vlen = gl_length(p_data->vars);
2815 for (v = 0; v < vlen; v++) {
2816 var = &(p_data->vardata[v]);
2817 i = var_instance(var);
2818 len = RelationsCount(i);
2819 r = 0;
2820 if (len > 0) {
2821 varincidence = get_var_incidence_space(len,p_data);
2822 for( c = 1; c <= len; c++ ) {
2823 i_r = RelationsForAtom(i,c);
2824 if( i_r == rel_instance(GetInterfacePtr(i_r)) ) {
2825 varincidence[r] = SIP(GetInterfacePtr(i_r))->u.r.data;
2826 r++;
2827 }
2828 }
2829 }
2830 if (r > 0) {
2831 var_set_incidences(var,r,varincidence);
2832 } else {
2833 var_set_incidences(var,0,NULL);
2834 }
2835 }
2836 return 0;
2837 }
2838
2839
2840
2841 /*
2842 * hand off all the null terminated arrays to slv_system_t.
2843 * Also makes sure all solver_var have been assigned at least once,
2844 * since 0 is a really stupid starting value.
2845 */
2846 static
2847 int analyze_configure_system(slv_system_t sys,struct problem_t *p_data)
2848 {
2849 slv_set_var_buf(sys,p_data->vardata);
2850 p_data->vardata = NULL;
2851 slv_set_par_buf(sys,p_data->pardata);
2852 p_data->pardata = NULL;
2853 slv_set_dvar_buf(sys,p_data->disdata,gl_length(p_data->dvars));
2854 p_data->disdata = NULL;
2855 slv_set_rel_buf(sys,p_data->reldata);
2856 p_data->reldata = NULL;
2857 slv_set_condrel_buf(sys,p_data->condata);
2858 p_data->condata = NULL;
2859 slv_set_obj_buf(sys,p_data->objdata);
2860 p_data->objdata = NULL;
2861 slv_set_logrel_buf(sys,p_data->lrdata);
2862 p_data->lrdata = NULL;
2863 slv_set_condlogrel_buf(sys,p_data->logcondata);
2864 p_data->logcondata = NULL;
2865 slv_set_when_buf(sys,p_data->whendata,gl_length(p_data->whens));
2866 p_data->whendata = NULL;
2867 slv_set_bnd_buf(sys,p_data->bnddata,
2868 gl_length(p_data->cnds)+gl_length(p_data->logcnds));
2869 p_data->bnddata = NULL;
2870 slv_set_unattached_buf(sys,p_data->undata);
2871 p_data->undata = NULL;
2872 slv_set_disunatt_buf(sys,p_data->undisdata);
2873 p_data->undisdata = NULL;
2874 slv_set_incidence(sys,p_data->relincidence,p_data->relincsize);
2875 p_data->relincidence = NULL;
2876 slv_set_var_incidence(sys,p_data->varincidence,p_data->varincsize);
2877 p_data->varincidence = NULL;
2878 slv_set_logincidence(sys,p_data->logrelinciden,p_data->lrelincsize);
2879 p_data->logrelinciden = NULL;
2880 slv_set_symbol_list(sys,g_symbol_values_list);
2881 g_symbol_values_list = NULL;
2882 slv_set_master_var_list(sys,p_data->mastervl,gl_length(p_data->vars));
2883 p_data->mastervl = NULL;
2884 slv_set_master_par_list(sys,p_data->masterpl,gl_length(p_data->pars));
2885 p_data->masterpl = NULL;
2886 slv_set_master_dvar_list(sys,p_data->masterdl,gl_length(p_data->dvars));
2887 p_data->masterdl = NULL;
2888 slv_set_master_rel_list(sys,p_data->masterrl,gl_length(p_data->rels));
2889 p_data->masterrl = NULL;
2890 slv_set_master_condrel_list(sys,p_data->mastercl,gl_length(p_data->cnds));
2891 p_data->mastercl = NULL;
2892 slv_set_master_obj_list(sys,p_data->masterol,gl_length(p_data->objrels));
2893 p_data->masterol = NULL;
2894 slv_set_master_logrel_list(sys,p_data->masterll,
2895 gl_length(p_data->logrels));
2896 p_data->masterll = NULL;
2897 slv_set_master_condlogrel_list(sys,p_data->mastercll,
2898 gl_length(p_data->logcnds));
2899 p_data->mastercll = NULL;
2900 slv_set_master_when_list(sys,p_data->masterwl,gl_length(p_data->whens));
2901 p_data->masterwl = NULL;
2902 slv_set_master_bnd_list(sys,p_data->masterbl,
2903 gl_length(p_data->cnds)+gl_length(p_data->logcnds));
2904 p_data->masterbl = NULL;
2905 slv_set_master_unattached_list(sys,p_data->masterul,
2906 gl_length(p_data->unas));
2907 p_data->masterul = NULL;
2908 slv_set_master_disunatt_list(sys,p_data->masterdul,
2909 gl_length(p_data->dunas));
2910 p_data->masterdul = NULL;
2911
2912 slv_set_solvers_var_list(sys,p_data->solvervl,gl_length(p_data->vars));
2913 p_data->solvervl = NULL;
2914 slv_set_solvers_par_list(sys,p_data->solverpl,gl_length(p_data->pars));
2915 p_data->solverpl = NULL;
2916 slv_set_solvers_dvar_list(sys,p_data->solverdl,gl_length(p_data->dvars));
2917 p_data->solverdl = NULL;
2918 slv_set_solvers_rel_list(sys,p_data->solverrl,gl_length(p_data->rels));
2919 p_data->solverrl = NULL;
2920 slv_set_solvers_condrel_list(sys,p_data->solvercl,gl_length(p_data->cnds));
2921 p_data->solvercl = NULL;
2922 slv_set_solvers_obj_list(sys,p_data->solverol,gl_length(p_data->objrels));
2923 p_data->solverol = NULL;
2924 slv_set_solvers_logrel_list(sys,p_data->solverll,
2925 gl_length(p_data->logrels));
2926 p_data->solverll = NULL;
2927 slv_set_solvers_condlogrel_list(sys,p_data->solvercll,
2928 gl_length(p_data->logcnds));
2929 p_data->solvercll = NULL;
2930 slv_set_solvers_when_list(sys,p_data->solverwl,gl_length(p_data->whens));
2931 p_data->solverwl = NULL;
2932 slv_set_solvers_bnd_list(sys,p_data->solverbl,
2933 gl_length(p_data->cnds)+gl_length(p_data->logcnds));
2934 p_data->solverbl = NULL;
2935 slv_set_solvers_unattached_list(sys,p_data->solverul,
2936 gl_length(p_data->unas));
2937 p_data->solverul = NULL;
2938 slv_set_solvers_disunatt_list(sys,p_data->solverdul,
2939 gl_length(p_data->dunas));
2940 p_data->solverdul = NULL;
2941
2942 slv_set_obj_relation(sys,p_data->obj);
2943 p_data->obj = NULL;
2944
2945 slv_set_extrel_list(sys,p_data->erlist,gl_length(p_data->extrels));
2946 p_data->erlist = NULL;
2947
2948 slv_set_num_models(sys,p_data->nm);
2949 slv_set_need_consistency(sys,p_data->need_consistency);
2950
2951 PopInterfacePtrs(p_data->oldips,NULL,NULL);
2952 p_data->oldips = NULL;
2953 return 0;
2954 }
2955
2956 /*
2957 * fills in a slv_system_t via its object interface from the
2958 * ascend side of the world, establishing any protocols needed to
2959 * communicate with the instance tree.
2960 * Return is 0 if everything ok, nonzero OTHERWISE.
2961 * 1 = memory
2962 * 2 = bad instance
2963 */
2964 int analyze_make_problem(slv_system_t sys, struct Instance *inst)
2965 {
2966 int stat;
2967 struct problem_t thisproblem; /* need to malloc, free, or make &local */
2968 struct problem_t *p_data; /* need to malloc, free, or make &local */
2969 INCLUDED_A = AddSymbolL("included",8);
2970 FIXED_A = AddSymbolL("fixed",5);
2971 BASIS_A = AddSymbolL("basis",5);
2972
2973 p_data = &thisproblem;
2974 g_bad_rel_in_list = FALSE;
2975 InitTreeCounts(inst,p_data);
2976 /* take the census */
2977 VisitInstanceTreeTwo(inst,(VisitTwoProc)CountStuffInTree,TRUE,FALSE,
2978 (VOIDPTR)p_data);
2979 if (g_bad_rel_in_list) {
2980 p_data->root = NULL;
2981 return 2;
2982 }
2983
2984 /* decorate instances with temporary ips, collect them and etc */
2985 stat = analyze_make_master_lists(p_data);
2986 if (stat == 2) {
2987 analyze_free_lists(p_data);
2988 FPRINTF(ASCERR,"Error: (%s) Nothing to make a problem from.\n",__FILE__);
2989 return 2;
2990 }
2991 if (stat == 1) {
2992 analyze_free_lists(p_data);
2993 FPRINTF(ASCERR,"Error: (%s) Insufficient master memory.\n",__FILE__);
2994 return 1;
2995 }
2996 /* rearrange all the stuff we found and index things */
2997 stat = analyze_make_solvers_lists(p_data);
2998 if (stat == 2) {
2999 analyze_free_lists(p_data);
3000 FPRINTF(ASCERR,"Error: (%s) Nothing to make a problem from.\n",__FILE__);
3001 return 2;
3002 }
3003 if (stat == 1) {
3004 analyze_free_lists(p_data);
3005 FPRINTF(ASCERR,"Error: (%s) Insufficient solver memory.\n",__FILE__);
3006 return 1;
3007 }
3008
3009 /* tell the slv_system_t about it, and undecorate ips from instances */
3010 analyze_configure_system(sys,p_data);
3011 /* configure must set nulls in p_data for anything we want to keep */
3012 /* blow the temporary lists away */
3013 analyze_free_lists(p_data);
3014 return 0;
3015 }
3016
3017 extern void analyze_free_reused_mem(void)
3018 {
3019 resize_ipbuf((size_t)0,0);
3020 /* analyze_free_lists(); */
3021 }

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