/[ascend]/trunk/base/generic/compiler/logrel_io.c
ViewVC logotype

Annotation of /trunk/base/generic/compiler/logrel_io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 708 - (hide annotations) (download) (as text)
Tue Jun 27 07:34:31 2006 UTC (18 years ago) by johnpye
File MIME type: text/x-csrc
File size: 24121 byte(s)
Replaced some references to ascmalloc with ASC_NEW_ARRAY
1 aw0a 1 /*
2     * Logical Relation Output Routines
3     * by Vicente Rico-Ramirez
4     * Version: $Revision: 1.13 $
5     * Version control file: $RCSfile: logrel_io.c,v $
6     * Date last modified: $Date: 1997/10/28 19:20:39 $
7     * Last modified by: $Author: mthomas $
8     *
9     * This file is part of the Ascend Language Interpreter.
10     *
11     * The Ascend Language Interpreter is free software; you can redistribute
12     * it and/or modify it under the terms of the GNU General Public License as
13     * published by the Free Software Foundation; either version 2 of the
14     * License, or (at your option) any later version.
15     *
16     * The Ascend Language Interpreter is distributed in hope that it will be
17     * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19     * General Public License for more details.
20     *
21     * You should have received a copy of the GNU General Public License
22     * along with the program; if not, write to the Free Software Foundation,
23     * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
24     * COPYING.
25     *
26     */
27    
28     #include <stdarg.h>
29 johnpye 399 #include <utilities/ascConfig.h>
30     #include <utilities/ascMalloc.h>
31     #include <utilities/ascPanic.h>
32     #include <general/list.h>
33     #include <general/dstring.h>
34     #include "compiler.h"
35     #include "fractions.h"
36     #include "dimen.h"
37     #include "functype.h"
38 johnpye 669 #include "expr_types.h"
39 johnpye 399 #include "find.h"
40     #include "instance_enum.h"
41     #include "instance_io.h"
42     #include "logical_relation.h"
43     #include "logrelation.h"
44     #include "logrel_util.h"
45     #include "logrel_io.h"
46     #include "instquery.h"
47     #include "parentchild.h"
48     #include "mathinst.h"
49     #include "visitinst.h"
50     #include "tmpnum.h"
51 aw0a 1
52    
53     static char g_log_shortbuf[256];
54     #define SBL255 g_log_shortbuf
55    
56     /* Logical Operators */
57     static
58     void WriteLogOp(FILE *f, enum Expr_enum t)
59     {
60     switch(t){
61     case e_and: FPRINTF(f,"AND"); break;
62     case e_not: FPRINTF(f,"NOT"); break;
63     case e_or: FPRINTF(f,"OR"); break;
64     case e_boolean_eq: FPRINTF(f,"=="); break;
65     case e_boolean_neq: FPRINTF(f,"!="); break;
66     default:
67     Asc_Panic(2, NULL, "Unknown term in WriteLogOp.\n");/*NOTREACHED*/
68     }
69     }
70    
71     /* appends operators to dynamic symbol */
72     static void WriteLogOpDS(Asc_DString *dsPtr, enum Expr_enum t)
73     {
74     assert(dsPtr!=NULL);
75     switch(t){
76     case e_and:
77     Asc_DStringAppend(dsPtr,"AND",3);
78     break;
79     case e_not:
80     Asc_DStringAppend(dsPtr,"NOT",3);
81     break;
82     case e_or:
83     Asc_DStringAppend(dsPtr,"OR",2);
84     break;
85     case e_boolean_eq:
86     Asc_DStringAppend(dsPtr,"==",2);
87     break;
88     case e_boolean_neq:
89     Asc_DStringAppend(dsPtr,"!=",2);
90     break;
91     default:
92     FPRINTF(ASCERR,"Unknown term in WriteLogOpDS.\n");
93     Asc_DStringAppend(dsPtr,"ERROR",5);
94     break;
95     }
96     }
97    
98    
99     static
100     void WriteLogTerm(FILE *f,
101     CONST struct logrelation *lrel,
102     CONST struct logrel_term *term,
103     CONST struct Instance *inst)
104     {
105     struct Instance *cur_var;
106     struct Instance *rel;
107     int bvalue;
108    
109     switch(LogRelTermType(term)){
110     case e_var:
111     cur_var = LogRelBoolVar(lrel,LogTermBoolVarNumber(term));
112     WriteInstanceName(f,cur_var,inst);
113     break;
114     case e_satisfied:
115     FPRINTF(f,"SATISFIED(");
116     rel = LogRelRelation(lrel,LogTermSatRelNumber(term));
117     WriteInstanceName(f,rel,inst);
118     if (LogTermSatTolerance(term) != DBL_MAX) {
119     FPRINTF(f,",");
120     FPRINTF(f,"%g",LogTermSatTolerance(term));
121     }
122     FPRINTF(f,")");
123     break;
124     case e_int:
125     FPRINTF(f,"%d",LogTermInteger(term));
126     break;
127     case e_boolean:
128     bvalue = LogTermBoolean(term);
129     if (bvalue){
130     FPRINTF(f,"TRUE");
131     }
132     else {
133     FPRINTF(f,"FALSE");
134     }
135     break;
136     case e_and:
137     case e_or:
138     WriteLogOp(f,LogRelTermType(term));
139     break;
140     case e_not: FPRINTF(f,"NOT"); break;
141     default:
142     Asc_Panic(2, NULL, "Unknown term type in WriteLogTerm.\n");/*NOTREACHED*/
143     }
144     }
145    
146     static
147     void WriteLogTermDS(Asc_DString *dsPtr,
148     CONST struct logrelation *lrel,
149     CONST struct logrel_term *term,
150     CONST struct Instance *inst)
151     {
152     struct Instance *cur_var;
153     struct Instance *rel;
154     int bvalue;
155     switch(LogRelTermType(term)){
156     case e_var:
157     cur_var = LogRelBoolVar(lrel,LogTermBoolVarNumber(term));
158     WriteInstanceNameDS(dsPtr,cur_var,inst);
159     break;
160     case e_satisfied:
161     Asc_DStringAppend(dsPtr,"SATISFIED(",10);
162     rel = LogRelRelation(lrel,LogTermSatRelNumber(term));
163     WriteInstanceNameDS(dsPtr,rel,inst);
164     if (LogTermSatTolerance(term) != DBL_MAX) {
165     Asc_DStringAppend(dsPtr,",",1);
166     sprintf(SBL255,"%g",LogTermSatTolerance(term));
167     Asc_DStringAppend(dsPtr,SBL255,-1);
168     }
169     Asc_DStringAppend(dsPtr,")",1);
170     break;
171     case e_int:
172     sprintf(SBL255,"%d",LogTermInteger(term));
173     Asc_DStringAppend(dsPtr,SBL255,-1);
174     break;
175     case e_boolean:
176     bvalue = LogTermBoolean(term);
177     if (bvalue){
178     Asc_DStringAppend(dsPtr,"TRUE",4);
179     }
180     else {
181     Asc_DStringAppend(dsPtr,"FALSE",5);
182     }
183     break;
184     case e_and:
185     case e_or:
186     WriteLogOpDS(dsPtr,LogRelTermType(term));
187     break;
188     case e_not:
189     Asc_DStringAppend(dsPtr,"NOT",3);
190     break;
191     default:
192     FPRINTF(ASCERR,"Unknown term in WriteLogTermDS.\n");
193     Asc_DStringAppend(dsPtr,"ERROR",5);
194     break;
195     }
196     }
197    
198     static
199     void WriteLogSidePostfix(FILE *f,
200     CONST struct logrelation *lr,
201     int side,
202     CONST struct Instance *ref)
203     {
204     unsigned c,len;
205     CONST struct logrel_term *term;
206     len = LogRelLength(lr,side);
207     for(c=1;c<=len;c++){
208     term = LogRelTerm(lr,c,side);
209     WriteLogTerm(f,lr,term,ref);
210     if(c<len) PUTC(' ',f);
211     }
212     }
213    
214     static
215     void WriteLogSidePostfixDS(Asc_DString *dsPtr,
216     CONST struct logrelation *lr,
217     int side,
218     CONST struct Instance *ref)
219     {
220     unsigned c,len;
221     CONST struct logrel_term *term;
222     len = LogRelLength(lr,side);
223     for(c=1;c<=len;c++){
224     term = LogRelTerm(lr,c,side);
225     WriteLogTermDS(dsPtr,lr,term,ref);
226     if(c<len) Asc_DStringAppend(dsPtr," ",1);
227     }
228     }
229    
230     void WriteLogRelPostfix(FILE *f,
231     CONST struct Instance *lrelinst,
232     CONST struct Instance *ref)
233     {
234     CONST struct logrelation *lr;
235    
236     lr = GetInstanceLogRel(lrelinst);
237     switch(LogRelRelop(lr)){
238     case e_boolean_eq:
239     case e_boolean_neq:
240     WriteLogSidePostfix(f,lr,1,ref);
241     PUTC(' ',f);
242     WriteLogSidePostfix(f,lr,0,ref);
243     PUTC(' ',f);
244     WriteLogOp(f,LogRelRelop(lr));
245     break;
246     default:
247     FPRINTF(ASCERR,"Unexpected boolean Relop in WriteLogRelPostfix\n");
248     break;
249     }
250     }
251    
252     char *WriteLogRelPostfixToString( CONST struct Instance *lrelinst,
253     CONST struct Instance *ref)
254     {
255     CONST struct logrelation *lr;
256     char *result;
257     static Asc_DString ds;
258     Asc_DString *dsPtr;
259    
260     lr = GetInstanceLogRel(lrelinst);
261     dsPtr = &ds;
262     Asc_DStringInit(dsPtr);
263    
264     switch(LogRelRelop(lr)){
265     case e_boolean_eq:
266     case e_boolean_neq:
267     WriteLogSidePostfixDS(dsPtr,lr,1,ref);
268     Asc_DStringAppend(dsPtr," ",1);
269     WriteLogSidePostfixDS(dsPtr,lr,0,ref);
270     Asc_DStringAppend(dsPtr," ",1);
271     WriteLogOpDS(dsPtr,LogRelRelop(lr));
272     break;
273     default:
274     FPRINTF(ASCERR,"Unexpected boolean Relop in WriteLogRelPostfixToString\n");
275     break;
276     }
277     result = Asc_DStringResult(dsPtr);
278     Asc_DStringFree(dsPtr);
279     return result;
280     }
281    
282     struct logrel_stack {
283     struct logrel_stack *next;
284     unsigned long pos;
285     int first;
286     };
287    
288     static struct logrel_stack *g_logrel_stack=NULL;
289    
290     static
291     void ClearLogRelStack(void)
292     {
293     struct logrel_stack *next;
294     while(g_logrel_stack!=NULL){
295     next =g_logrel_stack->next;
296     ascfree((char *)g_logrel_stack);
297     g_logrel_stack = next;
298     }
299     }
300    
301     static
302     void PushLogRel(unsigned long int pos, int first)
303     {
304     struct logrel_stack *next;
305     next = g_logrel_stack;
306     g_logrel_stack = (struct logrel_stack *)
307     ascmalloc(sizeof(struct logrel_stack));
308     g_logrel_stack->next = next;
309     g_logrel_stack->pos = pos;
310     g_logrel_stack->first = first;
311     }
312    
313     static
314     int LogRelNotEmptyStack(void)
315     {
316     return g_logrel_stack!=NULL;
317     }
318    
319     static
320     int LogrelFirstTop(void)
321     {
322     assert(g_logrel_stack!=NULL);
323     return g_logrel_stack->first;
324     }
325    
326     static
327     unsigned long PopLogRel(void)
328     {
329     struct logrel_stack *next;
330     unsigned long result;
331     assert(g_logrel_stack!=NULL);
332     next = g_logrel_stack->next;
333     result = g_logrel_stack->pos;
334     ascfree((char *)g_logrel_stack);
335     g_logrel_stack = next;
336     return result;
337     }
338    
339     static
340     unsigned long LogRelLeftHandSide(CONST struct logrelation *lr,
341     unsigned long int pos,
342     int side)
343     {
344     unsigned long depth=1;
345     CONST struct logrel_term *term;
346     pos--;
347     while(depth){
348     term = LogRelTerm(lr,pos,side);
349     switch(LogRelTermType(term)){
350     case e_int:
351     case e_boolean:
352     case e_satisfied:
353     case e_var:
354     depth--;
355     break;
356     case e_not:
357     break;
358     case e_and:
359     case e_or:
360     depth++;
361     break;
362     default:
363     Asc_Panic(2, NULL,
364     "Don't know this type of logical relation type.\n"
365     "(%d) in function LogRelLeftHandSide\n",
366     LogRelTermType(term));
367     }
368     pos--;
369     }
370     return pos;
371     }
372    
373     /* a little function to tell us about precedence */
374     static
375     unsigned LogPriority(enum Expr_enum t)
376     {
377     switch(t){
378     case e_var:
379     case e_int:
380     case e_satisfied:
381     return 0;
382    
383     case e_and:
384     return 1;
385    
386     case e_or:
387     return 2;
388    
389     case e_not:
390     return 3;
391    
392     default:
393     return 0; /* 0=good idea? */
394     }
395     /*NOTREACHED*/
396     }
397    
398     int LogExprNeedParentheses(enum Expr_enum parent_op, enum Expr_enum child_op, int rhs)
399     {
400     unsigned parent_p,child_p;
401     switch(child_op){
402     case e_var:
403     case e_int:
404     case e_boolean:
405     case e_satisfied:
406     return 0;
407     default:
408     parent_p = LogPriority(parent_op);
409     child_p = LogPriority(child_op);
410     if (parent_p > child_p) return 1;
411     if (parent_p < child_p) return 0;
412     if ((parent_op == e_not)&&rhs) return 1;
413     return 0;
414     }
415     }
416    
417     static
418     void WriteLogSide(FILE *f,
419     CONST struct logrelation *lr,
420     int side,
421     CONST struct Instance *ref)
422     {
423     unsigned long pos,lhs;
424     int first;
425     enum Expr_enum t;
426     CONST struct logrel_term *term;
427     struct Instance *cur_var;
428     struct Instance *rel;
429     int bvalue;
430     ClearLogRelStack();
431     PushLogRel(LogRelLength(lr,side),1);
432     while(LogRelNotEmptyStack()){
433     first = LogrelFirstTop(); /* check if this is the first visit */
434     pos = PopLogRel(); /* check the top */
435     term = LogRelTerm(lr,pos,side);
436     switch(t = LogRelTermType(term)){
437     case e_var:
438     cur_var = LogRelBoolVar(lr,LogTermBoolVarNumber(term));
439     WriteInstanceName(f,cur_var,ref);
440     break;
441     case e_int:
442     FPRINTF(f,"%d",LogTermInteger(term));
443     break;
444     case e_boolean:
445     bvalue = LogTermBoolean(term);
446     if (bvalue){
447     FPRINTF(f,"TRUE");
448     }
449     else {
450     FPRINTF(f,"FALSE");
451     }
452     break;
453     case e_satisfied:
454     if(first) {
455     FPRINTF(f,"SATISFIED(");
456     rel = LogRelRelation(lr,LogTermSatRelNumber(term));
457     WriteInstanceName(f,rel,ref);
458     if (LogTermSatTolerance(term) != DBL_MAX) {
459     FPRINTF(f,",");
460     FPRINTF(f,"%g",LogTermSatTolerance(term));
461     }
462     FPRINTF(f,")");
463     }
464     else{
465     PUTC(')',f);
466     }
467     break;
468     case e_and:
469     case e_or:
470     switch(first){
471     case 1:
472     PushLogRel(pos,2);
473     lhs = LogRelLeftHandSide(lr,pos,side);
474     term = LogRelTerm(lr,lhs,side);
475     if (LogExprNeedParentheses(t,LogRelTermType(term),0))
476     PUTC('(',f);
477     PushLogRel(lhs,1);
478     break;
479     case 2:
480     term = LogRelTerm(lr,LogRelLeftHandSide(lr,pos,side),side);
481     if (LogExprNeedParentheses(t,LogRelTermType(term),0))
482     PUTC(')',f);
483     PUTC(' ',f);
484     WriteLogOp(f,t);
485     PUTC(' ',f);
486     PushLogRel(pos,0);
487     term = LogRelTerm(lr,pos-1,side);
488     if (LogExprNeedParentheses(t,LogRelTermType(term),1))
489     PUTC('(',f);
490     PushLogRel(pos-1,1);
491     break;
492     case 0:
493     term = LogRelTerm(lr,pos-1,side);
494     if (LogExprNeedParentheses(t,LogRelTermType(term),1))
495     PUTC(')',f);
496     break;
497     }
498     break;
499     case e_not:
500     if (first){
501     FPRINTF(f,"NOT");
502     PushLogRel(pos,0);
503     PUTC('(',f);
504     PushLogRel(pos-1,1);
505     }
506     else{
507     PUTC(')',f);
508     }
509     break;
510     default:
511     Asc_Panic(2, NULL,
512     "Don't know this type of logical relation type.\n"
513     "function WriteLogSide\n");;
514     }
515     }
516     }
517    
518     static
519     void WriteLogSideDS(Asc_DString *dsPtr, CONST struct logrelation *lr, int side,
520     CONST struct Instance *ref)
521     {
522     unsigned long pos,lhs;
523     int first;
524     enum Expr_enum t;
525     CONST struct logrel_term *term;
526     struct Instance *cur_var;
527     struct Instance *rel;
528     int bvalue;
529     ClearLogRelStack();
530     PushLogRel(LogRelLength(lr,side),1);
531     while(LogRelNotEmptyStack()){
532     first = LogrelFirstTop(); /* check if this is the first visit */
533     pos = PopLogRel(); /* check the top */
534     term = LogRelTerm(lr,pos,side);
535     switch(t = LogRelTermType(term)){
536     case e_var:
537     cur_var = LogRelBoolVar(lr,LogTermBoolVarNumber(term));
538     WriteInstanceNameDS(dsPtr,cur_var,ref);
539     break;
540     case e_int:
541     sprintf(SBL255,"%d",LogTermInteger(term));
542     Asc_DStringAppend(dsPtr,SBL255,-1);
543     break;
544     case e_boolean:
545     bvalue = LogTermBoolean(term);
546     if (bvalue){
547     Asc_DStringAppend(dsPtr,"TRUE",4);
548     }
549     else {
550     Asc_DStringAppend(dsPtr,"FALSE",5);
551     }
552     break;
553     case e_satisfied:
554     if(first) {
555     Asc_DStringAppend(dsPtr,"SATISFIED(",10);
556     rel = LogRelRelation(lr,LogTermSatRelNumber(term));
557     WriteInstanceNameDS(dsPtr,rel,ref);
558     if (LogTermSatTolerance(term) != DBL_MAX) {
559     Asc_DStringAppend(dsPtr,",",1);
560     sprintf(SBL255,"%g",LogTermSatTolerance(term));
561     Asc_DStringAppend(dsPtr,SBL255,-1);
562     }
563     Asc_DStringAppend(dsPtr,")",1);
564     }
565     else{
566     Asc_DStringAppend(dsPtr,")",1);
567     }
568     break;
569     case e_and:
570     case e_or:
571     switch(first){
572     case 1:
573     PushLogRel(pos,2);
574     lhs = LogRelLeftHandSide(lr,pos,side);
575     term = LogRelTerm(lr,lhs,side);
576     if (LogExprNeedParentheses(t,LogRelTermType(term),0))
577     Asc_DStringAppend(dsPtr,"(",1);
578     PushLogRel(lhs,1);
579     break;
580     case 2:
581     term = LogRelTerm(lr,LogRelLeftHandSide(lr,pos,side),side);
582     if (LogExprNeedParentheses(t,LogRelTermType(term),0)) {
583     Asc_DStringAppend(dsPtr,")",1);
584     }
585     Asc_DStringAppend(dsPtr," ",1);
586     WriteLogOpDS(dsPtr,t);
587     Asc_DStringAppend(dsPtr," ",1);
588     PushLogRel(pos,0);
589     term = LogRelTerm(lr,pos-1,side);
590     if (LogExprNeedParentheses(t,LogRelTermType(term),1)) {
591     Asc_DStringAppend(dsPtr,"(",1);
592     }
593     PushLogRel(pos-1,1);
594     break;
595     case 0:
596     term = LogRelTerm(lr,pos-1,side);
597     if (LogExprNeedParentheses(t,LogRelTermType(term),1))
598     Asc_DStringAppend(dsPtr,")",1);
599     break;
600     }
601     break;
602     case e_not:
603     if (first){
604     Asc_DStringAppend(dsPtr,"NOT",3);
605     PushLogRel(pos,0);
606     Asc_DStringAppend(dsPtr,"(",1);
607     PushLogRel(pos-1,1);
608     }
609     else{
610     Asc_DStringAppend(dsPtr,")",1);
611     }
612     break;
613     default:
614     Asc_Panic(2, NULL,
615     "Don't know this type of logical relation type.\n"
616     "function WriteLogSide\n");
617     }
618     }
619     }
620    
621     static
622     void WriteLogicalRelation(FILE *f,
623     CONST struct logrelation *lr,
624     CONST struct Instance *ref)
625     {
626     switch(LogRelRelop(lr)){
627     case e_boolean_eq:
628     case e_boolean_neq:
629     WriteLogSide(f,lr,1,ref);
630     PUTC(' ',f);
631     WriteLogOp(f,LogRelRelop(lr));
632     PUTC(' ',f);
633     WriteLogSide(f,lr,0,ref);
634     break;
635     default:
636     FPRINTF(ASCERR,"Unexpected Relop in WriteLogicalRelation\n");
637     break;
638     }
639     }
640    
641     static
642     void WriteLogRelDS(Asc_DString *dsPtr,
643     CONST struct logrelation *lr,
644     CONST struct Instance *ref)
645     {
646     switch(LogRelRelop(lr)){
647     case e_boolean_eq:
648     case e_boolean_neq:
649     WriteLogSideDS(dsPtr,lr,1,ref);
650     Asc_DStringAppend(dsPtr," ",1);
651     WriteLogOpDS(dsPtr,LogRelRelop(lr));
652     Asc_DStringAppend(dsPtr," ",1);
653     WriteLogSideDS(dsPtr,lr,0,ref);
654     break;
655     default:
656     FPRINTF(ASCERR,"Unexpected Relop in WriteLogRelDS\n");
657     Asc_DStringAppend(dsPtr,"BADRELOPR ",9);
658     break;
659     }
660     }
661    
662     static
663     void WriteLogSideInfix(FILE *f,
664     CONST struct logrelation *lr,
665     struct logrel_term *term,
666     CONST struct Instance *ref)
667     {
668     enum Expr_enum t;
669     struct Instance *cur_var;
670     struct Instance *rel;
671     int bvalue;
672     int parens;
673    
674     switch(t = LogRelTermType(term)) {
675     case e_var:
676     cur_var = LogRelBoolVar(lr,LogTermBoolVarNumber(term));
677     WriteInstanceName(f,cur_var,ref);
678     break;
679     case e_int:
680     FPRINTF(f,"%d",LogTermInteger(term));
681     break;
682     case e_boolean:
683     bvalue = LogTermBoolean(term);
684     if (bvalue){
685     FPRINTF(f,"TRUE");
686     }
687     else {
688     FPRINTF(f,"FALSE");
689     }
690     break;
691     case e_satisfied:
692     FPRINTF(f,"SATISFIED(");
693     rel = LogRelRelation(lr,LogTermSatRelNumber(term));
694     WriteInstanceName(f,rel,ref);
695     if (LogTermSatTolerance(term) != DBL_MAX) {
696     FPRINTF(f,",");
697     FPRINTF(f,"%g",LogTermSatTolerance(term));
698     }
699     FPRINTF(f,")");
700     break;
701     case e_not:
702     FPRINTF(f,"NOT(");
703     WriteLogSideInfix(f,lr,LogTermUniLeft(term),ref);
704     FPRINTF(f,")");
705     break;
706     case e_and:
707     case e_or:
708     parens = LogExprNeedParentheses(LogRelTermType(term),
709     LogRelTermType(LogTermBinLeft(term)),0);
710     if (parens) PUTC('(',f);
711     WriteLogSideInfix(f,lr,LogTermBinLeft(term),ref);
712     if (parens) PUTC(')',f);
713     PUTC(' ',f);
714     WriteLogOp(f,t);
715     PUTC(' ',f);
716     parens = LogExprNeedParentheses(LogRelTermType(term),
717     LogRelTermType(LogTermBinRight(term)),1);
718     if (parens) PUTC('(',f);
719     WriteLogSideInfix(f,lr,LogTermBinRight(term),ref);
720     if (parens) PUTC('(',f);
721     break;
722     default:
723     FPRINTF(f,"***");
724     break;
725     }
726     }
727    
728     void WriteLogRelInfix(FILE *f,
729     CONST struct Instance *lrelinst,
730     CONST struct Instance *ref)
731     {
732     CONST struct logrelation *lr;
733    
734     lr = GetInstanceLogRel(lrelinst);
735     switch(LogRelRelop(lr)){
736     case e_boolean_eq:
737     case e_boolean_neq:
738     WriteLogSideInfix(f,lr,Infix_Log_LhsSide(lr),ref);
739     PUTC(' ',f);
740     WriteLogOp(f,LogRelRelop(lr));
741     PUTC(' ',f);
742     WriteLogSideInfix(f,lr,Infix_Log_RhsSide(lr),ref);
743     break;
744     default:
745     FPRINTF(ASCERR,"Unexpected Relop in WriteLogRelInfix\n");
746     }
747     }
748    
749    
750    
751     void WriteLogRel(FILE *f, CONST struct Instance *lrelinst,
752     CONST struct Instance *ref)
753     {
754     CONST struct logrelation *lreln;
755    
756     lreln = GetInstanceLogRel(lrelinst);
757     if (!lreln) {
758     FPRINTF(f,"NULL logical relation\n");
759     return;
760     }
761     WriteLogicalRelation(f,lreln,ref);
762     return;
763     }
764    
765     char *WriteLogRelToString(CONST struct Instance *lrelinst,
766     CONST struct Instance *ref)
767     {
768     CONST struct logrelation *lreln;
769     static Asc_DString ds;
770     Asc_DString *dsPtr;
771     char *result;
772    
773     lreln = GetInstanceLogRel(lrelinst);
774     if (!lreln) {
775 johnpye 708 result = ASC_NEW_ARRAY(char,15);
776 aw0a 1 if (result == NULL) return result;
777     sprintf(result,"NULL logical relation\n");
778     return result;
779     }
780    
781     dsPtr = &ds;
782     Asc_DStringInit(dsPtr);
783     WriteLogRelDS(dsPtr,lreln,ref);
784     result = Asc_DStringResult(dsPtr);
785     Asc_DStringFree(dsPtr);
786     return result;
787     }
788    
789    
790     /*
791     * some io to help in debugging logical relation manipulators.
792     */
793     static FILE *g_logwritfp = NULL;
794     static void WriteIfLogRel(struct Instance *i)
795     {
796     struct Instance *p;
797     if (!i) {
798     FPRINTF(ASCERR,"null child pointer in WriteIfLogRel\n");
799     return;
800     }
801     if (InstanceKind(i)==LREL_INST) {
802     FPRINTF(g_logwritfp,"\n");
803     WriteInstanceName(g_logwritfp,i,NULL);
804     FPRINTF(g_logwritfp,"\n");
805     p = InstanceParent(i,1);
806     while (InstanceKind(p)!= MODEL_INST && InstanceKind(p) != SIM_INST) {
807     p = InstanceParent(p,1);
808     }
809     WriteLogRel(g_logwritfp,i,p);
810     FPRINTF(g_logwritfp,"\n");
811     FPRINTF(g_logwritfp,"\n");
812     WriteLogRelPostfix(g_logwritfp,i,p);
813     FPRINTF(g_logwritfp,"\n");
814     }
815     return;
816     }
817    
818     void WriteLogRelationsInTree(FILE *fp,struct Instance *i)
819     {
820     if (i==NULL || fp==NULL) return;
821     g_logwritfp = fp;
822     SlowVisitInstanceTree(i,WriteIfLogRel,0,0);
823     }
824    
825    
826     /*
827     *********************************************************************
828     * Save Logical Relation Code
829     *
830     * The below code is concerned with saving relations in a persistent
831     * format. It writes out the code in a condensed format to allow
832     * restoration to the original representation.
833     *
834     * The grammar will follow later once it has stabilized.
835     * In the mean time, the following keywords are used.
836     * $LRELOP INTEGER - the relational operator - e_boolean_eq etc.
837     * $LOPCODES INTEGER ':' (INTEGER *)
838     * $LCOUNT INTEGER - the number of variables.
839     * $BVARIABLES ':' (INTEGER)* - global varindex
840     * $BCONSTANTS ':' (BOOLEAN)*
841     *********************************************************************
842     */
843    
844     #undef LogLHS
845     #undef LogRHS
846     #define LogLHS 0
847     #define LogRHS 1
848     #define LBREAKLINES 65
849     #define SATID 23
850     static
851     void SaveLogRelSide(FILE *fp,CONST struct logrelation *lr,
852     int side, struct gl_list_t *constants)
853     {
854     CONST struct logrel_term *term;
855     struct Instance *rel;
856     enum Expr_enum t;
857     unsigned c,len;
858     int count;
859    
860     len = LogRelLength(lr,side);
861     if (!len) return;
862    
863     count = 16;
864     FPRINTF(fp,"\t$LOPCODES %d : ",side);
865     for (c=1;c<=len;c++) {
866     term = LogRelTerm(lr,c,side);
867     t = LogRelTermType(term);
868     count += FPRINTF(fp," %d ",(int)t);
869     switch (t) {
870     case e_var:
871     count += FPRINTF(fp,"%lu",LogTermBoolVarNumber(term));
872     break;
873     case e_satisfied:
874     count += FPRINTF(fp,"%d",SATID);
875     rel = LogRelRelation(lr,LogTermSatRelNumber(term));
876     count += FPRINTF(fp," %lu ",GetTmpNum(rel));
877     if (LogTermSatTolerance(term) != DBL_MAX) {
878     count += FPRINTF(fp,"%12.8e",LogTermSatTolerance(term));
879     }
880     break;
881     case e_int:
882     case e_boolean:
883     gl_append_ptr(constants,(VOIDPTR)term);
884     count += FPRINTF(fp,"%lu",gl_length(constants));
885     break;
886     case e_not:
887     case e_and:
888     case e_or:
889     break;
890     default:
891     count += FPRINTF(fp,"%d",(int)e_nop);
892     break;
893     }
894     if (count >= LBREAKLINES) {
895     PUTC('\n',fp); PUTC('\t',fp);
896     count = 8;
897     }
898     }
899     FPRINTF(fp,";\n");
900     }
901    
902    
903     static
904     void SaveTokenLogConstants(FILE *fp, struct gl_list_t *constants)
905     {
906     CONST struct logrel_term *term;
907     unsigned long len,c;
908    
909     len = gl_length(constants);
910     if (!len) return;
911    
912     FPRINTF(fp,"\t$BCONSTANTS : ");
913     for (c=1;c<=len;c++) {
914     term = (CONST struct logrel_term *)gl_fetch(constants,c);
915     switch (LogRelTermType(term)) {
916     case e_boolean:
917     FPRINTF(fp,"%d",LogTermBoolean(term));
918     break;
919     case e_int:
920     FPRINTF(fp,"%d",LogTermInteger(term));
921     break;
922     default:
923     Asc_Panic(2, NULL, "Illegal term in SaveTokenLogConstants\n");
924     }
925     PUTC(' ',fp);
926     }
927     FPRINTF(fp,";\n");
928     }
929    
930     /*
931     *********************************************************************
932     * Save Logical Relation Boolean Variables
933     *********************************************************************
934     */
935     void SaveLogRelBoolVars(FILE *fp, CONST struct logrelation *lr)
936     {
937     struct Instance *bvar;
938     unsigned long len,c;
939     int count;
940     len = NumberBoolVars(lr);
941     if (!len) return;
942    
943     count = 16;
944     FPRINTF(fp,"\t$BVARIABLES : ");
945     for (c=1;c<=len;c++) {
946     bvar = LogRelBoolVar(lr,c);
947     count += FPRINTF(fp," %lu ",GetTmpNum(bvar));
948     if (count >= LBREAKLINES) {
949     PUTC('\n',fp); PUTC('\t',fp);
950     count = 8;
951     }
952     }
953     FPRINTF(fp,";\n");
954     }
955    
956     /*
957     *********************************************************************
958     * SaveLogRel
959     * Save a logical relation in condensed opcode format.
960     *********************************************************************
961     */
962     void SaveLogRel(FILE *fp, CONST struct Instance *lrelinst)
963     {
964     CONST struct logrelation *lreln;
965     struct gl_list_t *constants = NULL;
966    
967     lreln = GetInstanceLogRel(lrelinst);
968     constants = gl_create(50L);
969    
970     FPRINTF(fp,"$LOGRELATION %lu {\n",GetTmpNum(lrelinst));
971     FPRINTF(fp,"\t$COUNT %lu;\n",NumberBoolVars(lreln));
972    
973     SaveLogRelSide(fp,lreln,LogLHS,constants);
974     SaveLogRelSide(fp,lreln,LogRHS,constants);
975     SaveTokenLogConstants(fp,constants);
976     SaveLogRelBoolVars(fp,lreln);
977     FPRINTF(fp,"}\n\n");
978    
979     gl_destroy(constants);
980     }
981    
982    

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