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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 669 - (show annotations) (download) (as text)
Wed Jun 21 07:00:45 2006 UTC (18 years, 10 months ago) by johnpye
File MIME type: text/x-csrc
File size: 24121 byte(s)
Merged changes from DAE branch (revisions 702 to 819) back into trunk.
This adds the Integration API to the ASCEND solver (in base/generic).
Also provides pre-alpha support for 'IDA' from the SUNDIALS suite, a DAE solver.
Many other minor code clean-ups, including adoption of new 'ASC_NEW' and friends (to replace 'ascmalloc')
Added some very sketchy stuff providing 'DIFF(...)' syntax, although it is anticipated that this will be removed.
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 <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 #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(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 result = (char *) ascmalloc(15);
776 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