CVC3

Util.cpp

Go to the documentation of this file.
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 }