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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (17 years, 6 months ago) by aw0a
File MIME type: text/x-csrc
File size: 17898 byte(s)
Setting up web subdirectory in repository
1 /*
2 * SLV: Ascend Numeric Solver
3 * by Karl Michael Westerberg
4 * Created: 2/6/90
5 * Version: $Revision: 1.31 $
6 * Version control file: $RCSfile: var.c,v $
7 * Date last modified: $Date: 1998/02/19 13:31:36 $
8 * Last modified by: $Author: mthomas $
9 *
10 * This file is part of the SLV solver.
11 *
12 * Copyright (C) 1990 Karl Michael Westerberg
13 * Copyright (C) 1993 Joseph Zaher
14 * Copyright (C) 1994 Joseph Zaher, Benjamin Andrew Allan
15 *
16 * The SLV solver is free software; you can redistribute
17 * it and/or modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of the
19 * License, or (at your option) any later version.
20 *
21 * The SLV solver is distributed in hope that it will be
22 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with the program; if not, write to the Free Software Foundation,
28 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
29 * COPYING. COPYING is found in ../compiler.
30 *
31 */
32
33 #include "utilities/ascConfig.h"
34 #include "utilities/ascMalloc.h"
35 #include "general/dstring.h"
36 #include "general/list.h"
37 #include "compiler/compiler.h"
38 #include "compiler/symtab.h"
39 #include "compiler/instance_enum.h"
40 #include "compiler/fractions.h"
41 #include "compiler/module.h"
42 #include "compiler/library.h"
43 #include "compiler/dimen.h"
44 #include "compiler/child.h"
45 #include "compiler/type_desc.h"
46 #include "compiler/atomvalue.h"
47 #include "compiler/parentchild.h"
48 #include "compiler/instquery.h"
49 #include "compiler/instance_io.h"
50 #include "solver/mtx.h"
51 #include "solver/slv_types.h"
52 #include "solver/rel.h"
53 #include "solver/var.h"
54 #include "solver/discrete.h"
55 #include "solver/conditional.h"
56 #include "solver/logrel.h"
57 #include "solver/bnd.h"
58 #include "solver/slv_server.h"
59 #include "solver/slv_common.h"
60 #include "solver/linsol.h"
61 #include "solver/linsolqr.h"
62 #include "solver/slv_client.h"
63
64 /* useful cast */
65 #define IPTR(i) ((struct Instance *)(i))
66
67 /* useful symbol table things to know */
68 #define FIXED_V g_strings[0]
69 #define LOWER_V g_strings[1]
70 #define UPPER_V g_strings[2]
71 #define RELAXED_V g_strings[3]
72 #define NOMINAL_V g_strings[4]
73 #define INTERFACE_V g_strings[5]
74
75 /*
76 * array of those symbol table entries we need.
77 */
78 static symchar * g_strings[6];
79
80 SlvBackendToken var_instanceF(const struct var_variable *var)
81 { if (var==NULL || var->ratom==NULL) {
82 FPRINTF(stderr,"var_instance called on bad var\n");
83 return NULL;
84 }
85 return var->ratom;
86 }
87
88 void var_set_instanceF(struct var_variable *var, SlvBackendToken i)
89 {
90 if (var==NULL) {
91 FPRINTF(stderr,"var_set_instance called on NULL var\n");
92 return;
93 }
94 var->ratom = i;
95 }
96
97
98 char *var_make_name(const slv_system_t sys,const struct var_variable *var)
99 {
100 return WriteInstanceNameString(IPTR(var->ratom),IPTR(slv_instance(sys)));
101 }
102
103 char *var_make_xname(const struct var_variable *var)
104 {
105 static char name[81];
106 char *res;
107 sprintf(name,"x%d",var_sindex(var));
108 res=(char *)ascmalloc((strlen(name)+1)*sizeof(char));
109 sprintf(res,"%s",name);
110 return res;
111 }
112
113 void var_write_name(const slv_system_t sys,
114 const struct var_variable *var,FILE *fp)
115 {
116 if (var == NULL || fp==NULL) return;
117 if (sys!=NULL) {
118 WriteInstanceName(fp,var_instance(var),slv_instance(sys));
119 } else {
120 WriteInstanceName(fp,var_instance(var),NULL);
121 }
122 }
123
124 void var_destroy(struct var_variable *var)
125 {
126 if (var==NULL) return;
127 var->ratom = NULL;
128 ascfree((POINTER)var->incidence);
129 }
130
131
132 int32 var_mindexF(const struct var_variable *var)
133 {
134 if (var==NULL || var->ratom==NULL) {
135 FPRINTF(stderr,"var_set_mindex called on bad var\n");
136 return -1;
137 }
138 return var->mindex;
139 }
140
141 void var_set_mindexF(struct var_variable *var, int32 index)
142 {
143 if (var==NULL || var->ratom==NULL) {
144 FPRINTF(stderr,"var_set_mindex called on bad var\n");
145 return;
146 }
147 var->mindex = index;
148 }
149
150 int32 var_sindexF(const struct var_variable *var)
151 {
152 if (var==NULL || var->ratom==NULL) {
153 FPRINTF(stderr,"var_set_sindex called on bad var\n");
154 return -1;
155 }
156 return var->sindex;
157 }
158
159 void var_set_sindexF(struct var_variable *var, int32 index)
160 {
161 if (var==NULL || var->ratom==NULL) {
162 FPRINTF(stderr,"var_set_sindex called on bad var\n");
163 return;
164 }
165 var->sindex = index;
166 }
167
168 real64 var_value(const struct var_variable *var)
169 {
170 if (var==NULL || var->ratom==NULL) {
171 FPRINTF(stderr,"var_value called on bad var\n");
172 return 0.0;
173 }
174 return( RealAtomValue(var->ratom) );
175 }
176
177 void var_set_value(struct var_variable *var, real64 value)
178 {
179 if (var==NULL || var->ratom==NULL) {
180 FPRINTF(stderr,"var_set_value called on bad var\n");
181 return;
182 }
183 SetRealAtomValue(var->ratom,value,(unsigned)0);
184 }
185
186 real64 var_nominal(struct var_variable *var)
187 {
188 struct Instance *c;
189 if (var==NULL || var->ratom==NULL) {
190 FPRINTF(stderr,"var_nominal called on bad var\n");
191 return 1.0;
192 }
193 c = ChildByChar(var->ratom,NOMINAL_V);
194 if( c == NULL ) {
195 FPRINTF(stderr,"ERROR: (var) var_nominal\n");
196 FPRINTF(stderr," No 'nominal' field in variable.\n");
197 WriteInstance(stderr,IPTR(var->ratom));
198 return 1.0;
199 }
200 return( RealAtomValue(c) );
201 }
202
203 void var_set_nominal(struct var_variable *var, real64 nominal)
204 {
205 struct Instance *c;
206 if (var==NULL || var->ratom==NULL) {
207 FPRINTF(stderr,"var_set_nominal called on bad var\n");
208 return;
209 }
210 c = ChildByChar(IPTR(var->ratom),NOMINAL_V);
211 if( c == NULL ) {
212 FPRINTF(stderr,"ERROR: (var) var_set_nominal\n");
213 FPRINTF(stderr," No 'nominal' field in variable.\n");
214 WriteInstance(stderr,IPTR(var->ratom));
215 return;
216 }
217 SetRealAtomValue(c,nominal,(unsigned)0);
218 }
219
220
221 real64 var_lower_bound(struct var_variable *var)
222 {
223 struct Instance *c;
224 if (var==NULL || var->ratom==NULL) {
225 FPRINTF(stderr,"var_lower_bound called on bad var\n");
226 return 0.0;
227 }
228 c = ChildByChar(IPTR(var->ratom),LOWER_V);
229 if( c == NULL ) {
230 FPRINTF(stderr,"ERROR: (var) var_lower_bound\n");
231 FPRINTF(stderr," No 'lower_bound' field in variable.\n");
232 WriteInstance(stderr,IPTR(var->ratom));
233 return 0.0;
234 }
235 return( RealAtomValue(c) );
236 }
237
238 void var_set_lower_bound(struct var_variable *var, real64 lower_bound)
239 {
240 struct Instance *c;
241 if (var==NULL || var->ratom==NULL) {
242 FPRINTF(stderr,"var_set_lower_bound called on bad var\n");
243 return;
244 }
245 c = ChildByChar(IPTR(var->ratom),LOWER_V);
246 if( c == NULL ) {
247 FPRINTF(stderr,"ERROR: (var) var_set_lower_bound\n");
248 FPRINTF(stderr," No 'lower_bound' field in variable.\n");
249 WriteInstance(stderr,IPTR(var->ratom));
250 return;
251 }
252 SetRealAtomValue(c,lower_bound,(unsigned)0);
253 }
254
255
256 real64 var_upper_bound(struct var_variable *var)
257 {
258 struct Instance *c;
259 if (var==NULL || var->ratom==NULL) {
260 FPRINTF(stderr,"var_upper_bound called on bad var\n");
261 return 0.0;
262 }
263 c = ChildByChar(IPTR(var->ratom),UPPER_V);
264 if( c == NULL ) {
265 FPRINTF(stderr,"ERROR: (var) var_upper_bound\n");
266 FPRINTF(stderr," No 'upper_bound' field in variable.\n");
267 WriteInstance(stderr,IPTR(var->ratom));
268 return 0.0;
269 }
270 return( RealAtomValue(c) );
271 }
272
273 void var_set_upper_bound(var,upper_bound)
274 struct var_variable *var;
275 real64 upper_bound;
276 {
277 struct Instance *c;
278 if (var==NULL || var->ratom==NULL) {
279 FPRINTF(stderr,"var_set_upper_bound called on bad var\n");
280 return;
281 }
282 c = ChildByChar(IPTR(var->ratom),UPPER_V);
283 if( c == NULL ) {
284 FPRINTF(stderr,"ERROR: (var) var_set_upper_bound\n");
285 FPRINTF(stderr," No 'upper_bound' field in variable.\n");
286 WriteInstance(stderr,IPTR(var->ratom));
287 return;
288 }
289 SetRealAtomValue(c,upper_bound,(unsigned)0);
290 }
291
292 uint32 var_flagsF(const struct var_variable *var)
293 {
294 return var->flags;
295 }
296
297 void var_set_flagsF(struct var_variable *var, uint32 flags)
298 {
299 var->flags = flags;
300 }
301
302 uint32 var_fixed(struct var_variable *var)
303 {
304 struct Instance *c;
305 if (var==NULL || var->ratom==NULL) {
306 FPRINTF(stderr,"var_fixed called on bad var\n");
307 return FALSE;
308 }
309 c = ChildByChar(IPTR(var->ratom),FIXED_V);
310 if( c == NULL ) {
311 FPRINTF(stderr,"ERROR: (var) var_fixed\n");
312 FPRINTF(stderr," No 'fixed' field in variable.\n");
313 WriteInstance(stderr,IPTR(var->ratom));
314 return FALSE;
315 }
316 var_set_flagbit(var,VAR_FIXED,GetBooleanAtomValue(c));
317 return( GetBooleanAtomValue(c) );
318 }
319
320 void var_set_fixed(struct var_variable *var, uint32 fixed)
321 {
322 struct Instance *c;
323 if (var==NULL || var->ratom==NULL) {
324 FPRINTF(stderr,"var_set_fixed called on bad var\n");
325 return;
326 }
327 c = ChildByChar(IPTR(var->ratom),FIXED_V);
328 if( c == NULL ) {
329 FPRINTF(stderr,"ERROR: (var) var_set_fixed\n");
330 FPRINTF(stderr," No 'fixed' field in variable.\n");
331 WriteInstance(stderr,IPTR(var->ratom));
332 return;
333 }
334 SetBooleanAtomValue(c,fixed,(unsigned)0);
335 var_set_flagbit(var,VAR_FIXED,fixed);
336 }
337
338 uint32 var_relaxed(struct var_variable *var)
339 {
340 struct Instance *c;
341 if (var==NULL || var->ratom==NULL) {
342 FPRINTF(stderr,"var_relaxed called on bad var\n");
343 return FALSE;
344 }
345 c = ChildByChar((var->ratom),RELAXED_V);
346 if( c == NULL ) {
347 FPRINTF(stderr,"ERROR: (var) var_relaxed\n");
348 FPRINTF(stderr," No 'relaxed' field in variable.\n");
349 WriteInstance(stderr,(var->ratom));
350 return FALSE;
351 }
352 var_set_flagbit(var,VAR_RELAXED,GetBooleanAtomValue(c));
353 return( GetBooleanAtomValue(c) );
354 }
355
356 void var_set_relaxed(struct var_variable *var, uint32 fixed)
357 {
358 struct Instance *c;
359 if (var==NULL || var->ratom==NULL) {
360 FPRINTF(stderr,"var_set_relaxed called on bad var\n");
361 return;
362 }
363 c = ChildByChar(IPTR(var->ratom),RELAXED_V);
364 if( c == NULL ) {
365 FPRINTF(stderr,"ERROR: (var) var_set_relaxed\n");
366 FPRINTF(stderr," No 'relaxed' field in variable.\n");
367 WriteInstance(stderr,IPTR(var->ratom));
368 return;
369 }
370 SetBooleanAtomValue(c,fixed,(unsigned)0);
371 var_set_flagbit(var,VAR_RELAXED,fixed);
372 }
373
374 uint32 var_interface(struct var_variable *var)
375 {
376 struct Instance *c;
377 if (var==NULL || var->ratom==NULL) {
378 FPRINTF(stderr,"var_interface called on bad var\n");
379 return FALSE;
380 }
381 c = ChildByChar(IPTR(var->ratom),INTERFACE_V);
382 if( c == NULL ) {
383 FPRINTF(stderr,"ERROR: (var) var_interface\n");
384 FPRINTF(stderr," No 'interface' field in variable.\n");
385 WriteInstance(stderr,IPTR(var->ratom));
386 return 0;
387 }
388 var_set_flagbit(var,VAR_INTERFACE,GetBooleanAtomValue(c));
389 return( GetIntegerAtomValue(c) );
390 }
391
392 extern uint32 var_flagbit(const struct var_variable *var,const uint32 one)
393 {
394 if (var==NULL || var->ratom == NULL) {
395 FPRINTF(stderr,"ERROR: var_flagbit called with bad var.\n");
396 return 0;
397 }
398 return (var->flags & one);
399 }
400
401 void var_set_flagbit(struct var_variable *var, uint32 field,uint32 one)
402 {
403 if (var==NULL || var->ratom == NULL) {
404 FPRINTF(stderr,"ERROR: var_set_flagbit called with bad var.\n");
405 return;
406 }
407 if (one) {
408 var->flags |= field;
409 } else {
410 var->flags &= ~field;
411 }
412 }
413
414 int32 var_apply_filter(const struct var_variable *var,
415 const var_filter_t *filter)
416 {
417 if (var==NULL || filter==NULL || var->ratom == NULL) {
418 FPRINTF(stderr,"var_apply_filter miscalled with NULL\n");
419 return FALSE;
420 }
421 /* AND to mask off irrelevant bits in flags and match value, then compare */
422 return ( (filter->matchbits & var->flags) ==
423 (filter->matchbits & filter->matchvalue)
424 );
425 }
426
427
428 int32 var_n_incidencesF(struct var_variable *var)
429 {
430 if (var!=NULL) return var->n_incidences;
431 FPRINTF(stderr,"var_n_incidences miscalled with NULL\n");
432 return 0;
433 }
434 void var_set_incidencesF(struct var_variable *var,int32 n,
435 struct rel_relation **i)
436 {
437 if(var!=NULL && n >=0) {
438 if (n && i==NULL) {
439 FPRINTF(stderr,"var_set_incidence miscalled with NULL ilist\n");
440 }
441 var->n_incidences = n;
442 var->incidence = i;
443 return;
444 }
445 FPRINTF(stderr,"var_set_incidence miscalled with NULL or n < 0\n");
446 }
447 const struct rel_relation **var_incidence_list( struct var_variable *var)
448 {
449 if (var==NULL) return NULL;
450 return( (const struct rel_relation **)var->incidence );
451 }
452
453 struct rel_relation **var_incidence_list_to_modify( struct var_variable *var)
454 {
455 if (var==NULL) return NULL;
456 return( (struct rel_relation **)var->incidence );
457 }
458
459
460
461 /*
462 * global for use with the push function. Sets the ip to the
463 * value in g_var_tag;
464 * should be using vp instead of a global counter.
465 */
466 static void *g_var_tag = NULL;
467 static void * SetVarTags(struct Instance *i,VOIDPTR vp)
468 {
469 (void)vp;
470 if (i!=NULL && InstanceKind(i)==REAL_ATOM_INST) {
471 return g_var_tag;
472 } else {
473 return NULL;
474 }
475 }
476
477 struct var_variable **var_BackendTokens_to_vars(slv_system_t sys,
478 SlvBackendToken *atoms, int32 len)
479 {
480 int32 i,vartot,vlen,count=0;
481 uint32 apos,ulen;
482 struct var_variable **result;
483 struct var_variable **vlist;
484 struct gl_list_t *oldips;
485 if (sys==NULL || atoms == NULL || len < 1) {
486 return NULL;
487 }
488 ulen = (uint32)len;
489 result = (struct var_variable **)malloc(len*sizeof(struct var_variable *));
490 if (result == NULL) return result;
491 /* init results to null */
492 for (i=0; i<len; i++) result[i] = NULL;
493 /* fill ips w/len in all the vars in tree. */
494 g_var_tag = (void *)len;
495 vartot = slv_get_num_master_vars(sys) +
496 slv_get_num_master_pars(sys) +
497 slv_get_num_master_unattached(sys);
498 oldips = PushInterfacePtrs(slv_instance(sys),SetVarTags,vartot,0,NULL);
499 /* fill ips of wanted atoms with i */
500 for (i=0; i<len; i++) {
501 if (GetInterfacePtr(atoms[i])==g_var_tag &&
502 InstanceKind(atoms[i]) == REAL_ATOM_INST) {
503 /* guard a little */
504 SetInterfacePtr((struct Instance *)atoms[i],(void *)i);
505 } else {
506 /* the odds of g_var_tag being a legal pointer are vanishingly
507 small, so if we find an ATOM without g_var_tag we assume it
508 is outside the tree and shouldn't have been in the list. */
509 FPRINTF(stderr,"var_BackendTokens_to_vars called with bad token.\n");
510 }
511 }
512 /* run through the master lists and put the vars with their atoms */
513 vlist = slv_get_master_var_list(sys);
514 vlen = slv_get_num_master_vars(sys);
515 for (i = 0; i <vlen; i++) {
516 apos = (uint32)GetInterfacePtr(var_instance(vlist[i]));
517 if ( apos < ulen ) {
518 result[apos] = vlist[i];
519 count++;
520 }
521 }
522 vlist = slv_get_master_par_list(sys);
523 vlen = slv_get_num_master_pars(sys);
524 for (i = 0; i <vlen; i++) {
525 apos = (uint32)GetInterfacePtr(var_instance(vlist[i]));
526 if ( apos < ulen ) {
527 result[apos] = vlist[i];
528 count++;
529 }
530 }
531 vlist = slv_get_master_unattached_list(sys);
532 vlen = slv_get_num_master_unattached(sys);
533 for (i = 0; i <vlen; i++) {
534 apos = (uint32)GetInterfacePtr(var_instance(vlist[i]));
535 if ( apos < ulen ) {
536 result[apos] = vlist[i];
537 count++;
538 }
539 }
540 if (count < len) {
541 FPRINTF(stderr,
542 "var_BackendTokens_to_vars found less than expected vars\n");
543 FPRINTF(stderr,"len = %d, vars found = %d\n",len,count);
544 } else {
545 FPRINTF(stderr,
546 "var_BackendTokens_to_vars found more than expected vars\n");
547 FPRINTF(stderr,"len = %d, vars found = %d\n",len,count);
548 }
549 PopInterfacePtrs(oldips,NULL,NULL);
550 return result;
551 }
552
553 static struct TypeDescription *g_solver_var_type;
554 static struct TypeDescription *g_solver_int_type;
555 static struct TypeDescription *g_solver_binary_type;
556 static struct TypeDescription *g_solver_semi_type;
557
558 boolean set_solver_types(void) {
559 boolean nerr = 0;
560 if( (g_solver_var_type = FindType(AddSymbol(SOLVER_VAR_STR))) == NULL ) {
561 FPRINTF(stderr,"ERROR: (var.c) set_solver_types\n");
562 FPRINTF(stderr," Type solver_var not defined.\n");
563 FPRINTF(stderr," Solvers will not work.\n");
564 nerr++;
565 }
566 if( (g_solver_int_type = FindType(AddSymbol(SOLVER_INT_STR))) == NULL ) {
567 FPRINTF(stderr,"ERROR: (var.c) set_solver_types\n");
568 FPRINTF(stderr," Type solver_int not defined.\n");
569 FPRINTF(stderr," MPS will not work.\n");
570 nerr++;
571 }
572 g_solver_binary_type = FindType(AddSymbol(SOLVER_BINARY_STR));
573 if( g_solver_binary_type == NULL) {
574 FPRINTF(stderr,"ERROR: (var.c) set_solver_types\n");
575 FPRINTF(stderr," Type solver_binary not defined.\n");
576 FPRINTF(stderr," MPS will not work.\n");
577 nerr++;
578 }
579 if( (g_solver_semi_type = FindType(AddSymbol(SOLVER_SEMI_STR))) == NULL ) {
580 FPRINTF(stderr,"ERROR: (var.c) set_solver_types\n");
581 FPRINTF(stderr," Type solver_semi not defined.\n");
582 FPRINTF(stderr," MPS will not work.\n");
583 nerr++;
584 }
585
586 LOWER_V = AddSymbolL("lower_bound",11);
587 UPPER_V = AddSymbolL("upper_bound",11);
588 RELAXED_V = AddSymbolL("relaxed",7);
589 NOMINAL_V = AddSymbolL("nominal",7);
590 FIXED_V = AddSymbolL("fixed",5);
591 INTERFACE_V = AddSymbolL("interface",9);
592
593 return nerr;
594 }
595
596 boolean solver_var( SlvBackendToken inst)
597 {
598 struct TypeDescription *type;
599
600 if (!g_solver_var_type) return FALSE;
601 type = InstanceTypeDesc(IPTR(inst));
602 return( type == MoreRefined(type,g_solver_var_type) );
603 }
604
605 boolean solver_int( SlvBackendToken inst)
606 {
607 struct TypeDescription *type;
608
609 if (!g_solver_int_type) return FALSE;
610 type = InstanceTypeDesc(IPTR(inst));
611 return( type == MoreRefined(type,g_solver_int_type) );
612 }
613
614 boolean solver_binary( SlvBackendToken inst)
615 {
616 struct TypeDescription *type;
617
618 if (!g_solver_binary_type) return FALSE;
619 type = InstanceTypeDesc(IPTR(inst));
620 return( type == MoreRefined(type,g_solver_binary_type) );
621 }
622
623 boolean solver_semi( SlvBackendToken inst)
624 {
625 struct TypeDescription *type;
626
627 if (!g_solver_semi_type) return FALSE;
628 type = InstanceTypeDesc(IPTR(inst));
629 return( type == MoreRefined(type,g_solver_semi_type) );
630 }
631

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