/[ascend]/trunk/ipslv-temp/analyze.all_but_eachpair.c
ViewVC logotype

Contents of /trunk/ipslv-temp/analyze.all_but_eachpair.c

Parent Directory Parent Directory | Revision Log Revision Log


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