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

Contents of /trunk/ascend/compiler/logrel_io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2362 - (show annotations) (download) (as text)
Thu Jan 20 08:12:51 2011 UTC (11 years, 5 months ago) by jpye
File MIME type: text/x-csrc
File size: 23986 byte(s)
Fix minor error in output of parentheses.
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 #include <ascend/general/platform.h>
30 #include <ascend/general/ascMalloc.h>
31 #include <ascend/general/panic.h>
32 #include <ascend/general/list.h>
33 #include <ascend/general/dstring.h>
34
35
36
37 #include "functype.h"
38 #include "expr_types.h"
39 #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
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("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("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 = ASC_NEW(struct logrel_stack);
307 g_logrel_stack->next = next;
308 g_logrel_stack->pos = pos;
309 g_logrel_stack->first = first;
310 }
311
312 static
313 int LogRelNotEmptyStack(void)
314 {
315 return g_logrel_stack!=NULL;
316 }
317
318 static
319 int LogrelFirstTop(void)
320 {
321 assert(g_logrel_stack!=NULL);
322 return g_logrel_stack->first;
323 }
324
325 static
326 unsigned long PopLogRel(void)
327 {
328 struct logrel_stack *next;
329 unsigned long result;
330 assert(g_logrel_stack!=NULL);
331 next = g_logrel_stack->next;
332 result = g_logrel_stack->pos;
333 ascfree((char *)g_logrel_stack);
334 g_logrel_stack = next;
335 return result;
336 }
337
338 static
339 unsigned long LogRelLeftHandSide(CONST struct logrelation *lr,
340 unsigned long int pos,
341 int side)
342 {
343 unsigned long depth=1;
344 CONST struct logrel_term *term;
345 pos--;
346 while(depth){
347 term = LogRelTerm(lr,pos,side);
348 switch(LogRelTermType(term)){
349 case e_int:
350 case e_boolean:
351 case e_satisfied:
352 case e_var:
353 depth--;
354 break;
355 case e_not:
356 break;
357 case e_and:
358 case e_or:
359 depth++;
360 break;
361 default:
362 Asc_Panic(2, NULL,
363 "Don't know this type of logical relation type.\n"
364 "(%d) in function LogRelLeftHandSide\n",
365 LogRelTermType(term));
366 }
367 pos--;
368 }
369 return pos;
370 }
371
372 /* a little function to tell us about precedence */
373 static
374 unsigned LogPriority(enum Expr_enum t)
375 {
376 switch(t){
377 case e_var:
378 case e_int:
379 case e_satisfied:
380 return 0;
381
382 case e_and:
383 return 1;
384
385 case e_or:
386 return 2;
387
388 case e_not:
389 return 3;
390
391 default:
392 return 0; /* 0=good idea? */
393 }
394 /*NOTREACHED*/
395 }
396
397 int LogExprNeedParentheses(enum Expr_enum parent_op, enum Expr_enum child_op, int rhs)
398 {
399 unsigned parent_p,child_p;
400 switch(child_op){
401 case e_var:
402 case e_int:
403 case e_boolean:
404 case e_satisfied:
405 return 0;
406 default:
407 parent_p = LogPriority(parent_op);
408 child_p = LogPriority(child_op);
409 if (parent_p > child_p) return 1;
410 if (parent_p < child_p) return 0;
411 if ((parent_op == e_not)&&rhs) return 1;
412 return 0;
413 }
414 }
415
416 static
417 void WriteLogSide(FILE *f,
418 CONST struct logrelation *lr,
419 int side,
420 CONST struct Instance *ref)
421 {
422 unsigned long pos,lhs;
423 int first;
424 enum Expr_enum t;
425 CONST struct logrel_term *term;
426 struct Instance *cur_var;
427 struct Instance *rel;
428 int bvalue;
429 ClearLogRelStack();
430 PushLogRel(LogRelLength(lr,side),1);
431 while(LogRelNotEmptyStack()){
432 first = LogrelFirstTop(); /* check if this is the first visit */
433 pos = PopLogRel(); /* check the top */
434 term = LogRelTerm(lr,pos,side);
435 switch(t = LogRelTermType(term)){
436 case e_var:
437 cur_var = LogRelBoolVar(lr,LogTermBoolVarNumber(term));
438 WriteInstanceName(f,cur_var,ref);
439 break;
440 case e_int:
441 FPRINTF(f,"%d",LogTermInteger(term));
442 break;
443 case e_boolean:
444 bvalue = LogTermBoolean(term);
445 if (bvalue){
446 FPRINTF(f,"TRUE");
447 }
448 else {
449 FPRINTF(f,"FALSE");
450 }
451 break;
452 case e_satisfied:
453 if(first) {
454 FPRINTF(f,"SATISFIED(");
455 rel = LogRelRelation(lr,LogTermSatRelNumber(term));
456 WriteInstanceName(f,rel,ref);
457 if (LogTermSatTolerance(term) != DBL_MAX) {
458 FPRINTF(f,",");
459 FPRINTF(f,"%g",LogTermSatTolerance(term));
460 }
461 FPRINTF(f,")");
462 }
463 else{
464 PUTC(')',f);
465 }
466 break;
467 case e_and:
468 case e_or:
469 switch(first){
470 case 1:
471 PushLogRel(pos,2);
472 lhs = LogRelLeftHandSide(lr,pos,side);
473 term = LogRelTerm(lr,lhs,side);
474 if (LogExprNeedParentheses(t,LogRelTermType(term),0))
475 PUTC('(',f);
476 PushLogRel(lhs,1);
477 break;
478 case 2:
479 term = LogRelTerm(lr,LogRelLeftHandSide(lr,pos,side),side);
480 if (LogExprNeedParentheses(t,LogRelTermType(term),0))
481 PUTC(')',f);
482 PUTC(' ',f);
483 WriteLogOp(f,t);
484 PUTC(' ',f);
485 PushLogRel(pos,0);
486 term = LogRelTerm(lr,pos-1,side);
487 if (LogExprNeedParentheses(t,LogRelTermType(term),1))
488 PUTC('(',f);
489 PushLogRel(pos-1,1);
490 break;
491 case 0:
492 term = LogRelTerm(lr,pos-1,side);
493 if (LogExprNeedParentheses(t,LogRelTermType(term),1))
494 PUTC(')',f);
495 break;
496 }
497 break;
498 case e_not:
499 if (first){
500 FPRINTF(f,"NOT");
501 PushLogRel(pos,0);
502 PUTC('(',f);
503 PushLogRel(pos-1,1);
504 }
505 else{
506 PUTC(')',f);
507 }
508 break;
509 default:
510 Asc_Panic(2, NULL,
511 "Don't know this type of logical relation type.\n"
512 "function WriteLogSide\n");;
513 }
514 }
515 }
516
517 static
518 void WriteLogSideDS(Asc_DString *dsPtr, CONST struct logrelation *lr, int side,
519 CONST struct Instance *ref)
520 {
521 unsigned long pos,lhs;
522 int first;
523 enum Expr_enum t;
524 CONST struct logrel_term *term;
525 struct Instance *cur_var;
526 struct Instance *rel;
527 int bvalue;
528 ClearLogRelStack();
529 PushLogRel(LogRelLength(lr,side),1);
530 while(LogRelNotEmptyStack()){
531 first = LogrelFirstTop(); /* check if this is the first visit */
532 pos = PopLogRel(); /* check the top */
533 term = LogRelTerm(lr,pos,side);
534 switch(t = LogRelTermType(term)){
535 case e_var:
536 cur_var = LogRelBoolVar(lr,LogTermBoolVarNumber(term));
537 WriteInstanceNameDS(dsPtr,cur_var,ref);
538 break;
539 case e_int:
540 sprintf(SBL255,"%d",LogTermInteger(term));
541 Asc_DStringAppend(dsPtr,SBL255,-1);
542 break;
543 case e_boolean:
544 bvalue = LogTermBoolean(term);
545 if (bvalue){
546 Asc_DStringAppend(dsPtr,"TRUE",4);
547 }
548 else {
549 Asc_DStringAppend(dsPtr,"FALSE",5);
550 }
551 break;
552 case e_satisfied:
553 if(first) {
554 Asc_DStringAppend(dsPtr,"SATISFIED(",10);
555 rel = LogRelRelation(lr,LogTermSatRelNumber(term));
556 WriteInstanceNameDS(dsPtr,rel,ref);
557 if (LogTermSatTolerance(term) != DBL_MAX) {
558 Asc_DStringAppend(dsPtr,",",1);
559 sprintf(SBL255,"%g",LogTermSatTolerance(term));
560 Asc_DStringAppend(dsPtr,SBL255,-1);
561 }
562 Asc_DStringAppend(dsPtr,")",1);
563 }
564 else{
565 Asc_DStringAppend(dsPtr,")",1);
566 }
567 break;
568 case e_and:
569 case e_or:
570 switch(first){
571 case 1:
572 PushLogRel(pos,2);
573 lhs = LogRelLeftHandSide(lr,pos,side);
574 term = LogRelTerm(lr,lhs,side);
575 if (LogExprNeedParentheses(t,LogRelTermType(term),0))
576 Asc_DStringAppend(dsPtr,"(",1);
577 PushLogRel(lhs,1);
578 break;
579 case 2:
580 term = LogRelTerm(lr,LogRelLeftHandSide(lr,pos,side),side);
581 if (LogExprNeedParentheses(t,LogRelTermType(term),0)) {
582 Asc_DStringAppend(dsPtr,")",1);
583 }
584 Asc_DStringAppend(dsPtr," ",1);
585 WriteLogOpDS(dsPtr,t);
586 Asc_DStringAppend(dsPtr," ",1);
587 PushLogRel(pos,0);
588 term = LogRelTerm(lr,pos-1,side);
589 if (LogExprNeedParentheses(t,LogRelTermType(term),1)) {
590 Asc_DStringAppend(dsPtr,"(",1);
591 }
592 PushLogRel(pos-1,1);
593 break;
594 case 0:
595 term = LogRelTerm(lr,pos-1,side);
596 if (LogExprNeedParentheses(t,LogRelTermType(term),1))
597 Asc_DStringAppend(dsPtr,")",1);
598 break;
599 }
600 break;
601 case e_not:
602 if (first){
603 Asc_DStringAppend(dsPtr,"NOT",3);
604 PushLogRel(pos,0);
605 Asc_DStringAppend(dsPtr,"(",1);
606 PushLogRel(pos-1,1);
607 }
608 else{
609 Asc_DStringAppend(dsPtr,")",1);
610 }
611 break;
612 default:
613 Asc_Panic(2, NULL,
614 "Don't know this type of logical relation type.\n"
615 "function WriteLogSide\n");
616 }
617 }
618 }
619
620 static
621 void WriteLogicalRelation(FILE *f,
622 CONST struct logrelation *lr,
623 CONST struct Instance *ref)
624 {
625 switch(LogRelRelop(lr)){
626 case e_boolean_eq:
627 case e_boolean_neq:
628 WriteLogSide(f,lr,1,ref);
629 PUTC(' ',f);
630 WriteLogOp(f,LogRelRelop(lr));
631 PUTC(' ',f);
632 WriteLogSide(f,lr,0,ref);
633 break;
634 default:
635 FPRINTF(ASCERR,"Unexpected Relop in WriteLogicalRelation\n");
636 break;
637 }
638 }
639
640 static
641 void WriteLogRelDS(Asc_DString *dsPtr,
642 CONST struct logrelation *lr,
643 CONST struct Instance *ref)
644 {
645 switch(LogRelRelop(lr)){
646 case e_boolean_eq:
647 case e_boolean_neq:
648 WriteLogSideDS(dsPtr,lr,1,ref);
649 Asc_DStringAppend(dsPtr," ",1);
650 WriteLogOpDS(dsPtr,LogRelRelop(lr));
651 Asc_DStringAppend(dsPtr," ",1);
652 WriteLogSideDS(dsPtr,lr,0,ref);
653 break;
654 default:
655 FPRINTF(ASCERR,"Unexpected Relop in WriteLogRelDS\n");
656 Asc_DStringAppend(dsPtr,"BADRELOPR ",9);
657 break;
658 }
659 }
660
661 static
662 void WriteLogSideInfix(FILE *f,
663 CONST struct logrelation *lr,
664 struct logrel_term *term,
665 CONST struct Instance *ref)
666 {
667 enum Expr_enum t;
668 struct Instance *cur_var;
669 struct Instance *rel;
670 int bvalue;
671 int parens;
672
673 switch(t = LogRelTermType(term)) {
674 case e_var:
675 cur_var = LogRelBoolVar(lr,LogTermBoolVarNumber(term));
676 WriteInstanceName(f,cur_var,ref);
677 break;
678 case e_int:
679 FPRINTF(f,"%d",LogTermInteger(term));
680 break;
681 case e_boolean:
682 bvalue = LogTermBoolean(term);
683 if (bvalue){
684 FPRINTF(f,"TRUE");
685 }
686 else {
687 FPRINTF(f,"FALSE");
688 }
689 break;
690 case e_satisfied:
691 FPRINTF(f,"SATISFIED(");
692 rel = LogRelRelation(lr,LogTermSatRelNumber(term));
693 WriteInstanceName(f,rel,ref);
694 if (LogTermSatTolerance(term) != DBL_MAX) {
695 FPRINTF(f,",");
696 FPRINTF(f,"%g",LogTermSatTolerance(term));
697 }
698 FPRINTF(f,")");
699 break;
700 case e_not:
701 FPRINTF(f,"NOT(");
702 WriteLogSideInfix(f,lr,LogTermUniLeft(term),ref);
703 FPRINTF(f,")");
704 break;
705 case e_and:
706 case e_or:
707 parens = LogExprNeedParentheses(LogRelTermType(term),
708 LogRelTermType(LogTermBinLeft(term)),0);
709 if (parens) PUTC('(',f);
710 WriteLogSideInfix(f,lr,LogTermBinLeft(term),ref);
711 if (parens) PUTC(')',f);
712 PUTC(' ',f);
713 WriteLogOp(f,t);
714 PUTC(' ',f);
715 parens = LogExprNeedParentheses(LogRelTermType(term),
716 LogRelTermType(LogTermBinRight(term)),1);
717 if (parens) PUTC('(',f);
718 WriteLogSideInfix(f,lr,LogTermBinRight(term),ref);
719 if (parens) PUTC(')',f);
720 break;
721 default:
722 FPRINTF(f,"***");
723 break;
724 }
725 }
726
727 void WriteLogRelInfix(FILE *f,
728 CONST struct Instance *lrelinst,
729 CONST struct Instance *ref)
730 {
731 CONST struct logrelation *lr;
732
733 lr = GetInstanceLogRel(lrelinst);
734 switch(LogRelRelop(lr)){
735 case e_boolean_eq:
736 case e_boolean_neq:
737 WriteLogSideInfix(f,lr,Infix_Log_LhsSide(lr),ref);
738 PUTC(' ',f);
739 WriteLogOp(f,LogRelRelop(lr));
740 PUTC(' ',f);
741 WriteLogSideInfix(f,lr,Infix_Log_RhsSide(lr),ref);
742 break;
743 default:
744 FPRINTF(ASCERR,"Unexpected Relop in WriteLogRelInfix\n");
745 }
746 }
747
748
749
750 void WriteLogRel(FILE *f, CONST struct Instance *lrelinst,
751 CONST struct Instance *ref)
752 {
753 CONST struct logrelation *lreln;
754
755 lreln = GetInstanceLogRel(lrelinst);
756 if (!lreln) {
757 FPRINTF(f,"NULL logical relation\n");
758 return;
759 }
760 WriteLogicalRelation(f,lreln,ref);
761 return;
762 }
763
764 char *WriteLogRelToString(CONST struct Instance *lrelinst,
765 CONST struct Instance *ref)
766 {
767 CONST struct logrelation *lreln;
768 static Asc_DString ds;
769 Asc_DString *dsPtr;
770 char *result;
771
772 lreln = GetInstanceLogRel(lrelinst);
773 if (!lreln) {
774 result = ASC_NEW_ARRAY(char,15);
775 if (result == NULL) return result;
776 sprintf(result,"NULL logical relation\n");
777 return result;
778 }
779
780 dsPtr = &ds;
781 Asc_DStringInit(dsPtr);
782 WriteLogRelDS(dsPtr,lreln,ref);
783 result = Asc_DStringResult(dsPtr);
784 Asc_DStringFree(dsPtr);
785 return result;
786 }
787
788
789 /*
790 * some io to help in debugging logical relation manipulators.
791 */
792 static FILE *g_logwritfp = NULL;
793 static void WriteIfLogRel(struct Instance *i)
794 {
795 struct Instance *p;
796 if (!i) {
797 FPRINTF(ASCERR,"null child pointer in WriteIfLogRel\n");
798 return;
799 }
800 if (InstanceKind(i)==LREL_INST) {
801 FPRINTF(g_logwritfp,"\n");
802 WriteInstanceName(g_logwritfp,i,NULL);
803 FPRINTF(g_logwritfp,"\n");
804 p = InstanceParent(i,1);
805 while (InstanceKind(p)!= MODEL_INST && InstanceKind(p) != SIM_INST) {
806 p = InstanceParent(p,1);
807 }
808 WriteLogRel(g_logwritfp,i,p);
809 FPRINTF(g_logwritfp,"\n");
810 FPRINTF(g_logwritfp,"\n");
811 WriteLogRelPostfix(g_logwritfp,i,p);
812 FPRINTF(g_logwritfp,"\n");
813 }
814 return;
815 }
816
817 void WriteLogRelationsInTree(FILE *fp,struct Instance *i)
818 {
819 if (i==NULL || fp==NULL) return;
820 g_logwritfp = fp;
821 SlowVisitInstanceTree(i,WriteIfLogRel,0,0);
822 }
823
824
825 /*
826 *********************************************************************
827 * Save Logical Relation Code
828 *
829 * The below code is concerned with saving relations in a persistent
830 * format. It writes out the code in a condensed format to allow
831 * restoration to the original representation.
832 *
833 * The grammar will follow later once it has stabilized.
834 * In the mean time, the following keywords are used.
835 * $LRELOP INTEGER - the relational operator - e_boolean_eq etc.
836 * $LOPCODES INTEGER ':' (INTEGER *)
837 * $LCOUNT INTEGER - the number of variables.
838 * $BVARIABLES ':' (INTEGER)* - global varindex
839 * $BCONSTANTS ':' (BOOLEAN)*
840 *********************************************************************
841 */
842
843 #undef LogLHS
844 #undef LogRHS
845 #define LogLHS 0
846 #define LogRHS 1
847 #define LBREAKLINES 65
848 #define SATID 23
849 static
850 void SaveLogRelSide(FILE *fp,CONST struct logrelation *lr,
851 int side, struct gl_list_t *constants)
852 {
853 CONST struct logrel_term *term;
854 struct Instance *rel;
855 enum Expr_enum t;
856 unsigned c,len;
857 int count;
858
859 len = LogRelLength(lr,side);
860 if (!len) return;
861
862 count = 16;
863 FPRINTF(fp,"\t$LOPCODES %d : ",side);
864 for (c=1;c<=len;c++) {
865 term = LogRelTerm(lr,c,side);
866 t = LogRelTermType(term);
867 count += FPRINTF(fp," %d ",(int)t);
868 switch (t) {
869 case e_var:
870 count += FPRINTF(fp,"%lu",LogTermBoolVarNumber(term));
871 break;
872 case e_satisfied:
873 count += FPRINTF(fp,"%d",SATID);
874 rel = LogRelRelation(lr,LogTermSatRelNumber(term));
875 count += FPRINTF(fp," %lu ",GetTmpNum(rel));
876 if (LogTermSatTolerance(term) != DBL_MAX) {
877 count += FPRINTF(fp,"%12.8e",LogTermSatTolerance(term));
878 }
879 break;
880 case e_int:
881 case e_boolean:
882 gl_append_ptr(constants,(VOIDPTR)term);
883 count += FPRINTF(fp,"%lu",gl_length(constants));
884 break;
885 case e_not:
886 case e_and:
887 case e_or:
888 break;
889 default:
890 count += FPRINTF(fp,"%d",(int)e_nop);
891 break;
892 }
893 if (count >= LBREAKLINES) {
894 PUTC('\n',fp); PUTC('\t',fp);
895 count = 8;
896 }
897 }
898 FPRINTF(fp,";\n");
899 }
900
901
902 static
903 void SaveTokenLogConstants(FILE *fp, struct gl_list_t *constants)
904 {
905 CONST struct logrel_term *term;
906 unsigned long len,c;
907
908 len = gl_length(constants);
909 if (!len) return;
910
911 FPRINTF(fp,"\t$BCONSTANTS : ");
912 for (c=1;c<=len;c++) {
913 term = (CONST struct logrel_term *)gl_fetch(constants,c);
914 switch (LogRelTermType(term)) {
915 case e_boolean:
916 FPRINTF(fp,"%d",LogTermBoolean(term));
917 break;
918 case e_int:
919 FPRINTF(fp,"%d",LogTermInteger(term));
920 break;
921 default:
922 ASC_PANIC("Illegal term in SaveTokenLogConstants\n");
923 }
924 PUTC(' ',fp);
925 }
926 FPRINTF(fp,";\n");
927 }
928
929 /*
930 *********************************************************************
931 * Save Logical Relation Boolean Variables
932 *********************************************************************
933 */
934 void SaveLogRelBoolVars(FILE *fp, CONST struct logrelation *lr)
935 {
936 struct Instance *bvar;
937 unsigned long len,c;
938 int count;
939 len = NumberBoolVars(lr);
940 if (!len) return;
941
942 count = 16;
943 FPRINTF(fp,"\t$BVARIABLES : ");
944 for (c=1;c<=len;c++) {
945 bvar = LogRelBoolVar(lr,c);
946 count += FPRINTF(fp," %lu ",GetTmpNum(bvar));
947 if (count >= LBREAKLINES) {
948 PUTC('\n',fp); PUTC('\t',fp);
949 count = 8;
950 }
951 }
952 FPRINTF(fp,";\n");
953 }
954
955 /*
956 *********************************************************************
957 * SaveLogRel
958 * Save a logical relation in condensed opcode format.
959 *********************************************************************
960 */
961 void SaveLogRel(FILE *fp, CONST struct Instance *lrelinst)
962 {
963 CONST struct logrelation *lreln;
964 struct gl_list_t *constants = NULL;
965
966 lreln = GetInstanceLogRel(lrelinst);
967 constants = gl_create(50L);
968
969 FPRINTF(fp,"$LOGRELATION %lu {\n",GetTmpNum(lrelinst));
970 FPRINTF(fp,"\t$COUNT %lu;\n",NumberBoolVars(lreln));
971
972 SaveLogRelSide(fp,lreln,LogLHS,constants);
973 SaveLogRelSide(fp,lreln,LogRHS,constants);
974 SaveTokenLogConstants(fp,constants);
975 SaveLogRelBoolVars(fp,lreln);
976 FPRINTF(fp,"}\n\n");
977
978 gl_destroy(constants);
979 }
980
981

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