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

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