CVC3
|
00001 #include "Util.h" 00002 00003 bool Obj::errsInit = false; 00004 ofstream Obj::errs; 00005 bool Obj::indentFlag = false; 00006 00007 // helper utility functions 00008 void ajr_debug_print( const Expr& pf ) 00009 { 00010 for( int a=0; a<pf.arity(); a++ ) 00011 { 00012 cout << a << ": "; 00013 pf[a].print(); 00014 } 00015 } 00016 00017 string kind_to_str(int knd ){ 00018 00019 string knd_str; 00020 switch(knd){ 00021 case EQ: knd_str = "="; break; 00022 case LE: knd_str = "<="; break; 00023 case LT: knd_str = "<"; break; 00024 case GE: knd_str = ">="; break; 00025 case GT: knd_str = ">"; break; 00026 case DISTINCT: knd_str = "distinct"; break; 00027 case PLUS: knd_str = "+"; break; 00028 case MINUS: knd_str = "-"; break; 00029 case MULT: knd_str = "*"; break; 00030 case AND: knd_str = "and"; break; 00031 case OR: knd_str = "or";break; 00032 case NOT: knd_str = "not";break; 00033 case ITE: knd_str = "ite";break; 00034 case IFF: knd_str = "iff";break; 00035 case UMINUS: knd_str = "u-";break; 00036 default: 00037 { 00038 knd_str="Unknown"; 00039 ostringstream ose; 00040 ose << "WARNING: Unknown operator "<<knd; 00041 Obj::print_error( ose.str().c_str(), cout ); 00042 } 00043 } 00044 return knd_str; 00045 } 00046 00047 bool is_eq_kind( int knd ) 00048 { 00049 switch(knd){ 00050 case EQ: 00051 case LE: 00052 case LT: 00053 case GE: 00054 case GT: 00055 case DISTINCT:return true;break; 00056 } 00057 return false; 00058 } 00059 00060 bool is_smt_kind( int knd ) 00061 { 00062 return knd==EQ || knd==DISTINCT; 00063 } 00064 00065 //equation types ( a ~ b ) that are normalized to (b-a) ~' 0 00066 bool is_opposite( int knd ) 00067 { 00068 return ( knd==LE || knd==LT || knd==DISTINCT ); 00069 } 00070 bool is_comparison( int knd ) 00071 { 00072 return ( knd==LE || knd==LT || knd==GE || knd==GT ); 00073 } 00074 00075 int get_not( int knd ) 00076 { 00077 switch(knd){ 00078 case EQ: return DISTINCT; break; 00079 case LE: return GT; break; 00080 case LT: return GE; break; 00081 case GE: return LT; break; 00082 case GT: return LE; break; 00083 case DISTINCT: return EQ; break; 00084 } 00085 return knd; 00086 } 00087 00088 //order in LFSC signature for rules when order does not matter (such as lra_add) 00089 int get_knd_order( int knd ) 00090 { 00091 switch(knd){ 00092 case EQ: return 0; break; 00093 case GT: return 1; break; 00094 case GE: return 2; break; 00095 case DISTINCT: return 3; break; 00096 } 00097 return 4; 00098 } 00099 00100 int get_normalized( int knd, bool isnot ) 00101 { 00102 if( isnot ) return get_normalized( get_not( knd ) ); 00103 switch(knd){ 00104 case LE: return GE; break; 00105 case LT: return GT; break; 00106 } 00107 return knd; 00108 } 00109 00110 //should only be called on normalized ops 00111 int get_knd_result( int knd1, int knd2 ) 00112 { 00113 if( knd1==EQ ) 00114 return knd2; 00115 if( knd2==EQ ) 00116 return knd1; 00117 if( knd1!=DISTINCT && knd2!=DISTINCT ){ 00118 return ( knd1==GT || knd2==GT ) ? GT : GE; 00119 } 00120 ostringstream ose; 00121 ose << "Unknown get_op_result. " << kind_to_str( knd1 ) << " " << kind_to_str( knd2 ) << std::endl; 00122 Obj::print_error( ose.str().c_str(), cout ); 00123 return -1; 00124 } 00125 00126 // print helpers 00127 void print_mpq(int num, int den, std::ostream& s ) 00128 { 00129 if( num<0 ) 00130 s << "(~ "; 00131 s << abs( num ) << "/" << den; 00132 if( num<0 ) 00133 s << ")"; 00134 } 00135 00136 void print_rational( const Rational& r, std::ostream& s ) 00137 { 00138 //print_mpq( r.getNumerator().getInt(), r.getDenominator().getInt(), s ); 00139 if( r<0 ) 00140 s << "(~ " << -r; 00141 else 00142 s << r; 00143 if( r.isInteger() ) 00144 s << "/1"; 00145 if( r<0 ) 00146 s << ")"; 00147 } 00148 00149 void print_rational_divide( const Rational& n, const Rational& d, std::ostream& s ) 00150 { 00151 //print_mpq( n.getNumerator().getInt(), d.getNumerator().getInt(), s ); 00152 if( n<0 ) 00153 s << "(~ " << -n << "/" << d << ")"; 00154 else 00155 s << n << "/" << d; 00156 } 00157 00158 bool getRat( const Expr& e, Rational& r ){ 00159 if( e.isRational() ){ 00160 r = e.getRational(); 00161 return true; 00162 }else if( e.getKind()==DIVIDE && e[0].isRational() && e[1].isRational() ){ 00163 r = e[0].getRational()/e[1].getRational(); 00164 return true; 00165 }else if( e.getKind()==UMINUS ){ 00166 getRat( e[0], r ); 00167 r = -r; 00168 return true; 00169 } 00170 return false; 00171 } 00172 00173 bool isFlat( const Expr& e ){ 00174 for( int a=0; a<e.arity(); a++ ){ 00175 if( e.getKind()==e[a].getKind() ){ 00176 if( e.arity()>=10 ) 00177 return false; 00178 else if( !isFlat( e[a] ) ) 00179 return false; 00180 } 00181 } 00182 return true; 00183 } 00184 00185 void make_flatten_expr_h( const Expr& e, Expr& pe, const Expr& pec, bool pecDef, int knd ){ 00186 //cout << "Trav " << e << std::endl; 00187 if( e.getKind()==knd ){ 00188 make_flatten_expr_h( e[1], pe, pec, pecDef, knd ); 00189 if( e[0].getKind()==knd ){ 00190 make_flatten_expr_h( e[0], pe, pe, true, knd ); 00191 }else{ 00192 pe = Expr( knd, e[0], pe ); 00193 } 00194 }else{ 00195 if( pecDef ){ 00196 pe = Expr( knd, e, pec ); 00197 }else{ 00198 pe = e; 00199 } 00200 } 00201 } 00202 00203 void make_flatten_expr( const Expr& e, Expr& pe, int knd ){ 00204 Expr pec; 00205 make_flatten_expr_h( e, pe, pec, false, knd ); 00206 }