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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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