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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (18 years, 7 months ago) by aw0a
File MIME type: text/x-csrc
File size: 15490 byte(s)
Setting up web subdirectory in repository
1 /*
2 * Discrete Variable Module
3 * by Vicente Rico-Ramirez
4 * Created: 06/96
5 * Version: $Revision: 1.12 $
6 * Version control file: $RCSfile: discrete.c,v $
7 * Date last modified: $Date: 1998/02/05 15:59:21 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the SLV solver.
11 *
12 * The SLV solver is free software; you can redistribute
13 * it and/or modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * The SLV solver is distributed in hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with the program; if not, write to the Free Software Foundation,
24 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
25 * COPYING. COPYING is found in ../compiler.
26 *
27 */
28
29 #include "utilities/ascConfig.h"
30 #include "utilities/ascMalloc.h"
31 #include "general/list.h"
32 #include "general/dstring.h"
33 #include "compiler/compiler.h"
34 #include "compiler/instance_enum.h"
35 #include "compiler/module.h"
36 #include "compiler/library.h"
37 #include "compiler/symtab.h"
38 #include "compiler/child.h"
39 #include "compiler/fractions.h"
40 #include "compiler/dimen.h"
41 #include "compiler/type_desc.h"
42 #include "compiler/atomvalue.h"
43 #include "compiler/parentchild.h"
44 #include "compiler/instquery.h"
45 #include "compiler/instance_io.h"
46 #include "solver/mtx.h"
47 #include "solver/slv_types.h"
48 #include "solver/var.h"
49 #include "solver/rel.h"
50 #include "solver/discrete.h"
51 #include "solver/conditional.h"
52 #include "solver/logrel.h"
53 #include "solver/bnd.h"
54 #include "solver/linsol.h"
55 #include "solver/linsolqr.h"
56 #include "solver/slv_server.h"
57 #include "solver/slv_common.h"
58 #include "solver/slv_client.h"
59 #include "solver/analyze.h"
60
61
62 #ifndef IPTR
63 #define IPTR(i) ((struct Instance *)(i))
64 #endif
65
66 /* useful symbol table things to know */
67 #define FIXED_V g_strings[0]
68 #define NOMINAL_V g_strings[1]
69
70 /*
71 * array of those symbol table entries we need.
72 */
73 static symchar * g_strings[2];
74
75 static const struct dis_discrete g_dis_defaults = {
76 e_dis_error_t, /* kind */
77 NULL, /* instance datom */
78 NULL, /* sos */
79 NULL, /* source */
80 NULL, /* whens */
81 -1, /* range */
82 -1, /* value */
83 -1, /* pre_value */
84 -1, /* mindex */
85 -1, /* sindex */
86 0 /* flags */
87 };
88
89
90 static struct dis_discrete *dis_copy(const struct dis_discrete *dis)
91 {
92 struct dis_discrete *newdis;
93 newdis = (struct dis_discrete *)ascmalloc( sizeof(struct dis_discrete) );
94 *newdis = *dis;
95 return(newdis);
96 }
97
98
99 struct dis_discrete *dis_create(SlvBackendToken instance,
100 struct dis_discrete *newdis)
101 {
102 if (newdis==NULL) {
103 newdis = dis_copy(&g_dis_defaults); /* malloc the discrete var */
104 } else {
105 *newdis = g_dis_defaults; /* init the space we've been sent */
106 }
107 assert(newdis!=NULL);
108 newdis->datom = instance;
109 return(newdis);
110 }
111
112
113 SlvBackendToken dis_instanceF(const struct dis_discrete *dis)
114 { if (dis==NULL || dis->datom==NULL) {
115 FPRINTF(stderr,"dis_instance called on bad dvar\n");
116 return NULL;
117 }
118 return dis->datom;
119 }
120
121 void dis_set_instanceF(struct dis_discrete *dis, SlvBackendToken i)
122 {
123 if (dis==NULL) {
124 FPRINTF(stderr,"dis_set_instance called on NULL dvar\n");
125 return;
126 }
127 dis->datom = i;
128 }
129
130
131 char *dis_make_name(const slv_system_t sys,const struct dis_discrete *dis)
132 {
133 return WriteInstanceNameString(IPTR(dis->datom),IPTR(slv_instance(sys)));
134 }
135
136
137 char *dis_make_xname(const struct dis_discrete *dis)
138 {
139 static char name[81];
140 char *res;
141 sprintf(name,"dis%d",dis_sindex(dis));
142 res=(char *)ascmalloc((strlen(name)+1)*sizeof(char));
143 sprintf(res,"%s",name);
144 return res;
145 }
146
147
148 void dis_write_name(const slv_system_t sys,
149 const struct dis_discrete *dis,FILE *fp)
150 {
151 if (dis == NULL || fp==NULL) return;
152 if (sys!=NULL) {
153 WriteInstanceName(fp,dis_instance(dis),slv_instance(sys));
154 } else {
155 WriteInstanceName(fp,dis_instance(dis),NULL);
156 }
157 }
158
159
160 void dis_destroy(struct dis_discrete *dis)
161 {
162 if (dis==NULL) return;
163 dis->datom = NULL;
164 if (dis->whens != NULL) {
165 gl_destroy(dis->whens);
166 dis->whens = NULL;
167 }
168 }
169
170
171 struct gl_list_t *dis_whens_list(struct dis_discrete *dis)
172 {
173 assert(dis);
174 return( dis->whens );
175 }
176
177
178 void dis_set_whens_list( struct dis_discrete *dis, struct gl_list_t *wlist)
179 {
180 assert(dis);
181 dis->whens = wlist;
182 }
183
184
185 enum discrete_kind dis_kindF(const struct dis_discrete *dis)
186 {
187 if (dis==NULL || dis->datom==NULL) {
188 FPRINTF(stderr,"dis_kind called on bad dis var\n");
189 return e_dis_error_t;
190 }
191 return dis->t;
192 }
193
194 void dis_set_kindF(struct dis_discrete *dis, enum discrete_kind kind)
195 {
196 if (dis==NULL || dis->datom==NULL) {
197 FPRINTF(stderr,"dis_set_kind called on bad dis var\n");
198 return;
199 }
200 dis->t = kind;
201 }
202
203
204 int32 dis_mindexF(const struct dis_discrete *dis)
205 {
206 if (dis==NULL || dis->datom==NULL) {
207 FPRINTF(stderr,"dis_mindex called on bad dis var\n");
208 return -1;
209 }
210 return dis->mindex;
211 }
212
213
214 void dis_set_mindexF(struct dis_discrete *dis, int32 index)
215 {
216 if (dis==NULL || dis->datom==NULL) {
217 FPRINTF(stderr,"dis_set_mindex called on bad dis var\n");
218 return;
219 }
220 dis->mindex = index;
221 }
222
223 int32 dis_sindexF(const struct dis_discrete *dis)
224 {
225 if (dis==NULL || dis->datom==NULL) {
226 FPRINTF(stderr,"dis_sindex called on bad dis var\n");
227 return -1;
228 }
229 return dis->sindex;
230 }
231
232
233 void dis_set_sindexF(struct dis_discrete *dis, int32 index)
234 {
235 if (dis==NULL || dis->datom==NULL) {
236 FPRINTF(stderr,"dis_set_sindex called on bad dis\n");
237 return;
238 }
239 dis->sindex = index;
240 }
241
242
243 int32 dis_value(const struct dis_discrete *dis)
244 {
245 if (dis==NULL || dis->datom==NULL) {
246 FPRINTF(stderr,"dis_value called on bad dis\n");
247 return 0;
248 }
249 return(dis->cur_value);
250 }
251
252
253 void dis_set_value(struct dis_discrete *dis, int32 value)
254 {
255 if (dis==NULL || dis->datom==NULL) {
256 FPRINTF(stderr,"dis_set_value called on bad dis\n");
257 return;
258 }
259 dis->pre_value = dis_value(dis);
260 dis->cur_value = value;
261 }
262
263
264 void dis_set_inst_and_field_value(struct dis_discrete *dis, int32 value)
265 {
266 if (dis==NULL || dis->datom==NULL) {
267 FPRINTF(stderr,"dis_set_inst_and_field_value called on bad dis\n");
268 return;
269 }
270 if (dis_const(dis)) {
271 return;
272 }
273 switch(dis->t) {
274 case e_dis_boolean_t:
275 dis->pre_value = dis_value(dis);
276 SetBooleanAtomValue(dis->datom,value,(unsigned)0);
277 dis->cur_value = GetBooleanAtomValue(dis->datom);
278 break;
279 case e_dis_integer_t:
280 dis->pre_value = dis_value(dis);
281 SetIntegerAtomValue(dis->datom,value,(unsigned)0);
282 dis->cur_value = GetIntegerAtomValue(dis->datom);
283 break;
284 case e_dis_symbol_t:
285 break;
286 default:
287 FPRINTF(stderr,"dis_set_inst_value called on bad dis\n");
288 return;
289 }
290 }
291
292
293 void dis_set_value_from_inst(struct dis_discrete *dis,
294 struct gl_list_t *symbol_list)
295 {
296 CONST char *symval;
297
298 if (dis==NULL || dis->datom==NULL) {
299 FPRINTF(stderr,"dis_set_value_from_inst called on bad dis\n");
300 return;
301 }
302 if (dis_const(dis)) {
303 return;
304 }
305 switch(dis->t) {
306 case e_dis_boolean_t:
307 dis->pre_value = dis_value(dis);
308 dis->cur_value = GetBooleanAtomValue(dis->datom);
309 break;
310 case e_dis_integer_t:
311 dis->pre_value = dis_value(dis);
312 dis->cur_value = GetIntegerAtomValue(dis->datom);
313 break;
314 case e_dis_symbol_t:
315 dis->pre_value = dis_value(dis);
316 symval = SCP(GetSymbolAtomValue(dis->datom));
317 dis->cur_value = GetIntFromSymbol(symval,symbol_list);
318 break;
319 default:
320 FPRINTF(stderr,"dis_set_value_from_inst called on bad dis\n");
321 return;
322 }
323 }
324
325
326 int32 dis_previous_value(const struct dis_discrete *dis)
327 {
328 if (dis==NULL || dis->datom==NULL) {
329 FPRINTF(stderr,"dis_previous_value called on bad dis\n");
330 return 0;
331 }
332 return(dis->pre_value);
333 }
334
335
336 void dis_set_previous_value(struct dis_discrete *dis, int32 value)
337 {
338 if (dis==NULL || dis->datom==NULL) {
339 FPRINTF(stderr,"dis_set_previous_value called on bad dis\n");
340 return;
341 }
342 dis->pre_value = value;
343 }
344
345
346
347 static struct TypeDescription *g_solver_dis_type;
348
349 boolean set_boolean_types(void)
350 {
351 boolean nerr = 0;
352 if( (g_solver_dis_type = FindType(AddSymbol(BOOLEAN_VAR_STR))) == NULL ) {
353 FPRINTF(stderr,"ERROR: (dis.c) set_boolean_types\n");
354 FPRINTF(stderr," Type boolean_var not defined.\n");
355 nerr++;
356 }
357 NOMINAL_V = AddSymbolL("nominal",7);
358 FIXED_V = AddSymbolL("fixed",5);
359 return nerr;
360 }
361
362
363 boolean boolean_var( SlvBackendToken inst)
364 {
365 struct TypeDescription *type;
366 if (!g_solver_dis_type) return FALSE;
367 type = InstanceTypeDesc(IPTR(inst));
368 return( type == MoreRefined(type,g_solver_dis_type) );
369 }
370
371
372 int32 dis_nominal(struct dis_discrete *dis)
373 {
374 struct Instance *c;
375 if (dis==NULL || dis->datom==NULL) {
376 FPRINTF(stderr,"dis_nominal called on bad dis\n");
377 return 1;
378 }
379 if (!boolean_var(dis->datom)) {
380 FPRINTF(stderr,"dis_nominal called on a non-boolean_var\n");
381 return 1;
382 }
383 c = ChildByChar(dis->datom,NOMINAL_V);
384 if( c == NULL ) {
385 FPRINTF(stderr,"ERROR: (dis) dis_nominal\n");
386 FPRINTF(stderr," No 'nominal' field in variable.\n");
387 WriteInstance(stderr,IPTR(dis->datom));
388 return 1;
389 }
390 return( GetBooleanAtomValue(c) );
391 }
392
393 void dis_set_nominal(struct dis_discrete *dis, int32 nominal)
394 {
395 struct Instance *c;
396 if (dis==NULL || dis->datom==NULL) {
397 FPRINTF(stderr,"dis_set_nominal called on bad dis\n");
398 return;
399 }
400 if (!boolean_var(dis->datom)) {
401 FPRINTF(stderr,"dis_set_nominal called on a non-boolean_var\n");
402 return;
403 }
404 c = ChildByChar(IPTR(dis->datom),NOMINAL_V);
405 if( c == NULL ) {
406 FPRINTF(stderr,"ERROR: (dis) dis_set_nominal\n");
407 FPRINTF(stderr," No 'nominal' field in variable.\n");
408 WriteInstance(stderr,IPTR(dis->datom));
409 return;
410 }
411 SetBooleanAtomValue(c,nominal,(unsigned)0);
412 }
413
414
415 uint32 dis_flagsF(const struct dis_discrete *dis)
416 {
417 return dis->flags;
418 }
419
420
421 void dis_set_flagsF(struct dis_discrete *dis, uint32 flags)
422 {
423 dis->flags = flags;
424 }
425
426 uint32 dis_fixed(struct dis_discrete *dis)
427 {
428 struct Instance *c;
429 if (dis==NULL || dis->datom==NULL) {
430 FPRINTF(stderr,"dis_fixed called on bad dis\n");
431 return FALSE;
432 }
433 if (!boolean_var(dis->datom)) {
434 if (dis_const(dis)) {
435 FPRINTF(stderr,"dis_fixed called on a dis constant\n");
436 return TRUE;
437 }
438 else {
439 FPRINTF(stderr,"dis_fixed called on a bad dis var\n");
440 return FALSE;
441 }
442 }
443 c = ChildByChar(IPTR(dis->datom),FIXED_V);
444 if( c == NULL ) {
445 FPRINTF(stderr,"ERROR: (dis) dis_fixed\n");
446 FPRINTF(stderr," No 'fixed' field in variable.\n");
447 WriteInstance(stderr,IPTR(dis->datom));
448 return FALSE;
449 }
450 dis_set_flagbit(dis,DIS_FIXED,GetBooleanAtomValue(c));
451 return( GetBooleanAtomValue(c) );
452 }
453
454
455 void dis_set_fixed(struct dis_discrete *dis, uint32 fixed)
456 {
457 struct Instance *c;
458 if (dis==NULL || dis->datom==NULL) {
459 FPRINTF(stderr,"dis_set_fixed called on bad dis var\n");
460 return;
461 }
462 if (!boolean_var(dis->datom)) {
463 if (dis_const(dis)) {
464 FPRINTF(stderr,"dis_set_fixed called on a dis constant\n");
465 return;
466 }
467 else {
468 FPRINTF(stderr,"dis_set_fixed called on a bad dvar\n");
469 return;
470 }
471 }
472 c = ChildByChar(IPTR(dis->datom),FIXED_V);
473 if( c == NULL ) {
474 FPRINTF(stderr,"ERROR: (dis) dis_set_fixed\n");
475 FPRINTF(stderr," No 'fixed' field in variable.\n");
476 WriteInstance(stderr,IPTR(dis->datom));
477 return;
478 }
479 SetBooleanAtomValue(c,fixed,(unsigned)0);
480 dis_set_flagbit(dis,DIS_FIXED,fixed);
481 }
482
483
484 extern uint32 dis_flagbit(const struct dis_discrete *dis,const uint32 one)
485 {
486 if (dis==NULL || dis->datom == NULL) {
487 FPRINTF(stderr,"ERROR: dis_flagbit called with bad dis.\n");
488 return 0;
489 }
490 return (dis->flags & one);
491 }
492
493 void dis_set_flagbit(struct dis_discrete *dis, uint32 field,uint32 one)
494 {
495 if (dis==NULL || dis->datom == NULL) {
496 FPRINTF(stderr,"ERROR: dis_set_flagbit called with bad dvar.\n");
497 return;
498 }
499 if (one) {
500 dis->flags |= field;
501 } else {
502 dis->flags &= ~field;
503 }
504 }
505
506 int32 dis_apply_filter(const struct dis_discrete *dis,
507 const dis_filter_t *filter)
508 {
509 if (dis==NULL || filter==NULL || dis->datom == NULL) {
510 FPRINTF(stderr,"dis_apply_filter miscalled with NULL\n");
511 return FALSE;
512 }
513 return ( (filter->matchbits & dis->flags) ==
514 (filter->matchbits & filter->matchvalue) );
515 }
516
517 /* global for use with the push function. Sets the ip to the
518 * value in g_dis_tag;
519 */
520 static void *g_dis_tag = NULL;
521
522 /*
523 * should be using vp instead of a global counter.
524 */
525 static
526 void *SetDisTags(struct Instance *i,VOIDPTR vp)
527 {
528 (void)vp;
529 if (i!=NULL && InstanceKind(i)==BOOLEAN_ATOM_INST) {
530 return g_dis_tag;
531 } else {
532 return NULL;
533 }
534 }
535
536 struct dis_discrete **dis_BackendTokens_to_dis(slv_system_t sys,
537 SlvBackendToken *atoms,
538 int32 len)
539 {
540 int32 i,distot,bvlen,count=0;
541 uint32 apos,ulen;
542 struct dis_discrete **result;
543 struct dis_discrete **dislist;
544 struct gl_list_t *oldips;
545 ulen = (uint32)len;
546
547 if (sys==NULL || atoms == NULL || len < 1) return NULL;
548 result = (struct dis_discrete **)malloc(len*sizeof(struct dis_discrete *));
549 if (result == NULL) return result;
550 /* init results to null */
551 for (i=0; i<len; i++) result[i] = NULL;
552 /* fill ips w/len in all the vars in tree. */
553 g_dis_tag = (void *)len;
554 distot = slv_get_num_master_dvars(sys) +
555 slv_get_num_master_disunatt(sys);
556 oldips = PushInterfacePtrs(slv_instance(sys),SetDisTags,distot,0,NULL);
557 /* fill ips of wanted atoms with i */
558 for (i=0; i<len; i++) {
559 if (GetInterfacePtr(atoms[i])==g_dis_tag &&
560 InstanceKind(atoms[i]) == BOOLEAN_ATOM_INST) {
561 /* guard a little */
562 SetInterfacePtr((struct Instance *)atoms[i],(void *)i);
563 } else {
564 /*
565 * the odds of g_dis_tag being a legal pointer are vanishingly
566 * small, so if we find an ATOM without g_dis_tag we assume it
567 * is outside the tree and shouldn't have been in the list.
568 */
569 FPRINTF(stderr,"dis_BackendTokens_to_dis called with bad token.\n");
570 }
571 }
572 /* run through the master lists and put the dis vars with their atoms */
573 dislist = slv_get_master_dvar_list(sys);
574 bvlen = slv_get_num_master_dvars(sys);
575 for (i = 0; i <bvlen; i++) {
576 apos = (uint32)GetInterfacePtr(dis_instance(dislist[i]));
577 if ( apos < ulen ) {
578 result[apos] = dislist[i];
579 count++;
580 }
581 }
582 dislist = slv_get_master_disunatt_list(sys);
583 bvlen = slv_get_num_master_disunatt(sys);
584 for (i = 0; i <bvlen; i++) {
585 apos = (uint32)GetInterfacePtr(dis_instance(dislist[i]));
586 if ( apos < ulen ) {
587 result[apos] = dislist[i];
588 count++;
589 }
590 }
591 if (count < len) {
592 FPRINTF(stderr,
593 "dis_BackendTokens_to_dis found less than expected dis vars\n");
594 FPRINTF(stderr,"len = %d, diss found = %d\n",len,count);
595 } else {
596 FPRINTF(stderr,
597 "dis_BackendTokens_to_dis found more than expected dis vars\n");
598 FPRINTF(stderr,"len = %d, diss found = %d\n",len,count);
599 }
600 PopInterfacePtrs(oldips,NULL,NULL);
601 return result;
602 }
603

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