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

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