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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (17 years, 8 months ago) by aw0a
File MIME type: text/x-csrc
File size: 15490 byte(s)
Setting up web subdirectory in repository
1 aw0a 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