CVC3

LFSCPrinter.cpp

Go to the documentation of this file.
00001 #include "LFSCPrinter.h"
00002 
00003 
00004 LFSCPrinter::LFSCPrinter( Expr pf_expr, Expr qExpr, std::vector<Expr> assumps,
00005                           int lfscm, CommonProofRules* commonRules ):
00006                             d_user_assumptions(assumps),
00007                             d_common_pf_rules(commonRules){
00008 
00009   printer = this;
00010 
00011   if( !qExpr.isFalse() ){
00012     d_user_assumptions.push_back( cascade_expr( Expr( NOT, qExpr ) ) );
00013   }
00014 
00015   Obj::initialize();
00016 
00017   let_i = 1;
00018   LFSCObj::initialize( pf_expr, lfscm );
00019   converter = new LFSCConvert( lfscm );
00020 }
00021 
00022 ///////////////////////////////////////
00023 // main print method
00024 ///////////////////////////////////////
00025 
00026 void LFSCPrinter::print_LFSC( const Expr& pf )
00027 {
00028   ostringstream cparen;
00029 
00030   //(AJR-1) Print the input formula and (: bottom ascription
00031 
00032   cout << "(check " << endl;
00033   cparen << ")";
00034 
00035   // collecting variables from assumptions
00036   std::vector<Expr>::iterator a = d_user_assumptions.begin(), aend = d_user_assumptions.end();
00037   while(a!=aend){
00038     Expr ce = cascade_expr( *a );
00039     queryM( ce );
00040     d_assump_map[ ce ] = true;
00041     collect_vars(*a);
00042     a++;
00043   }
00044 
00045   //////scan for the assumptions
00046   //std::vector< Expr > assumps;
00047   //collect_assumptions( pf, assumps );
00048   ////we must record skolemizations
00049   //for( int a=1; a<(int)assumps.size(); a++ ){
00050   //  if( !d_assump_map[ assumps[a] ] ){
00051   //    ostringstream ose;
00052   //    ose << "Unexpected non-discharged assumption " << assumps[a];
00053   //    print_error( ose.str().c_str(), cout );
00054   //  }
00055   //}
00056 
00057   //printing variables
00058   ExprMap<bool>::iterator v = input_vars.begin(), vend = input_vars.end();
00059   while(v!= vend){
00060     cout<<"(% "<<(*v).first<<" var_real"<<endl;
00061     v++;
00062     cparen<<")";
00063   }
00064   v = input_preds.begin(), vend = input_preds.end();
00065   while(v!= vend){
00066     cout<<"(% "<<(*v).first<<" formula"<<endl;
00067     v++;
00068     cparen<<")";
00069   }
00070   //cout << "here1" << std::endl;
00071   //(AJR-2) Run T0( pf )
00072   define_skolem_vars( pf );
00073   //cout << "here2" << std::endl;
00074   //convert the proof
00075   converter->convert( pf );
00076 
00077   //make the let map for input formulas
00078   a = d_user_assumptions.begin();
00079   while(a!=aend){
00080     make_let_map( cascade_expr( *a ) );
00081     a++;
00082   }
00083   //make the let map for trusted formulas
00084   ExprMap<int>::iterator j = d_trusted.begin(), jend = d_trusted.end();
00085   while( j != jend){
00086     make_let_map( cascade_expr( (*j).first ) );
00087     j++;
00088   }
00089   //make the let map for output atomic formulas and terms
00090   ExprMap<bool>::iterator j2 = d_formulas_printed.begin(), j2end = d_formulas_printed.end();
00091   while( j2 != j2end){
00092     if( (*j2).second ){
00093       make_let_map( cascade_expr( (*j2).first ) );
00094     }
00095     j2++;
00096   }
00097   //j = d_terms.begin(), jend = d_terms.end();
00098   //while( j != jend){
00099   //  make_let_map((*j).first);
00100   //  j++;
00101   //}
00102 
00103   ////output skolem vars
00104   //j = skolem_vars.begin(), jend = skolem_vars.end();
00105   //while( j != jend ){
00106   //  if( (*j).second!=0 ){
00107   //    cout<<"(% "<<(*j).first<<" var_real"<<endl;
00108   //    cparen << ")";
00109   //  }
00110   //  j++;
00111   //}
00112 
00113   //output let definitions
00114   j2 = d_print_visited_map.begin(), j2end = d_print_visited_map.end();
00115   while( j2 != j2end ){
00116     int val = d_print_map[(*j2).first];
00117     if( val!=0 ){
00118       cout << "(@ ";
00119       d_print_map[(*j2).first] = 0;
00120       if( isFormula( (*j2).first ) ){
00121         cout << "@f" << val << " ";
00122         print_formula( (*j2).first, cout );
00123       }else{
00124         cout << "@x" << val << " ";
00125         print_terms( (*j2).first, cout );
00126       }
00127       d_print_map[(*j2).first] = val;
00128       cout << endl;
00129       cparen << ")";
00130     }
00131     j2++;
00132   }
00133   if( !d_print_map.empty() )
00134     cout << endl;
00135 
00136   // printing user assumptions
00137   a = d_user_assumptions.begin();
00138   int m = 1;
00139   while(a!=aend){
00140     cout<<"(% @F"<<m<<" (th_holds ";
00141     print_formula(*a, cout);
00142     cout<<")"<<endl;
00143     a++;
00144     m++;
00145     cparen << ")";
00146   }
00147 
00148   //print trusted formulas
00149   j = d_trusted.begin(), jend = d_trusted.end();
00150   while( j != jend){
00151     cout <<"(% @T" << (*j).second <<" (th_holds ";
00152     print_formula((*j).first, cout);
00153     cout<<")"<<endl;
00154     cparen << ")";
00155     j++;
00156   }
00157 
00158   cout << "(: bottom" << endl;
00159   cparen << ")";
00160 
00161 
00162   //outer lambda abstractions
00163   //cout << "number of outer lam abstractions = " << LFSCProof::lambdaCounter << std::endl;
00164   RefPtr< LFSCProof > lambda_pf = converter->getLFSCProof();
00165 
00166 
00167   ////debug----
00168   //j = d_formulas.begin(), jend = d_formulas.end();
00169   //while( j != jend){
00170   //  ExprMap< int >::iterator jPrev = j;
00171   //  j++;
00172   //  while( j != jend ){
00173   //    Expr e1 = cascade_expr( (*j).first );
00174   //    Expr e2 = cascade_expr( (*jPrev).first );
00175   //    if( e1==e2 ){
00176   //      ostringstream ose;
00177   //      ose << "Warning: Atomizing identical formulas " << (*j).second << " " << (*jPrev).second << std::endl;
00178   //      print_error( ose.str().c_str(), cout );
00179   //    }
00180   //    j++;
00181   //  }
00182   //  j = jPrev;
00183   //  j++;
00184   //}
00185   ////debug----
00186 
00187   //(AJR-3) Print the atoms used in the proof, these are contained in M.
00188   j = d_formulas.begin(), jend = d_formulas.end();
00189   while( j != jend){
00190     cout <<"(decl_atom ";
00191     //if( d_formulas_printed[(*j).first] ){     //HACK to ignore this
00192       print_formula( (*j).first, cout );
00193     //}else{
00194     //  cout << "_";
00195     //}
00196     cout<< " (\\ @b"<<(*j).second<<" (\\ @a"<<(*j).second<<endl;
00197     cparen << ")))";
00198     j++;
00199   }
00200   //need to print out atomized terms too
00201   j = d_terms.begin(), jend = d_terms.end();
00202   while( j != jend){
00203     cout <<"(decl_term_atom ";
00204     print_terms( (*j).first, cout );
00205     cout<< " (\\ @bt"<<(*j).second<<" (\\ @at"<<(*j).second<<endl;
00206     cparen << ")))";
00207     j++;
00208   }
00209 
00210   //(AJR-4) Print all polynomial normalization proofs.  These are stored in M_t.
00211   //print out the term normalizations
00212   j = d_pn_form.begin(), jend = d_pn_form.end();
00213   while(j !=jend ){
00214     pntNeeded[ (*j).second ] = true;
00215     j++;
00216   }
00217   j = d_pn.begin(), jend = d_pn.end();
00218   while(j !=jend){
00219     if( cvc3_mimic || pntNeeded[ (*j).second ] ){
00220       cout << "(pn_let _ _ ";
00221       Expr ce = cascade_expr( (*j).first );
00222       print_poly_norm( ce, cout);
00223       cout << "(\\ @pnt" << (*j).second << endl;
00224       cparen << "))";
00225     }
00226     j++;
00227   }
00228 
00229   //print out the equation normalizations
00230   j = d_pn_form.begin(), jend = d_pn_form.end();
00231   while(j !=jend){
00232     cout << "(poly_norm_" << kind_to_str( (*j).first.getKind() ) << " _ _ _ @pnt";
00233     //mapped to the polynomial norm proof
00234     cout << (*j).second << " ";
00235     //print out the same number as the equation in M
00236     cout << "(\\ @pn" << abs( queryM( (*j).first ) ) << endl;
00237     cparen << "))";
00238     j++;
00239   }
00240 
00241   //(AJR-5) print the proof and closing parentheses.
00242   if( lfsc_mode%10==7 ){
00243     LFSCProof::indentFlag = true;
00244     lambda_pf->print_structure( cout );
00245   }else
00246     lambda_pf->print( cout );
00247   cout << endl;
00248 
00249 
00250   //print closing parentheses
00251   cout << cparen.str() << endl;
00252 }
00253 
00254 
00255 void LFSCPrinter::print_poly_norm(const Expr& expr, std::ostream& s, bool pnRat, bool ratNeg ){
00256   // if +, -, etc.
00257   if(expr.arity()==2 ){
00258     if( expr.getKind()==MULT ){
00259       ostringstream cparen;
00260       int nrIndex = -1;    //the non-rational child
00261       for( int a=0; a<2; a++ ){
00262         if( nrIndex==-1 )
00263         {
00264           Expr ec = expr[a];
00265           bool rNeg = ratNeg;
00266           while( ec.getKind()==UMINUS ){
00267             ec = ec[0];
00268             if( !cvc3_mimic )
00269               rNeg = !rNeg;
00270           }
00271           if( ec.isRational() || ec.getKind()==DIVIDE )
00272           {
00273             s<<"(pn_mul_";
00274             if( cvc3_mimic && expr[a].getKind()==UMINUS ){
00275               s << "u-_";
00276             }
00277             s<< "c_" << ( a==0 ? "L" : "R" );
00278             s<<" _ _ _ ";
00279             print_poly_norm( ec, s, false, rNeg );
00280             s << " ";
00281             nrIndex = (1-a);
00282             cparen << ")";
00283           }
00284         }
00285       }
00286       if( nrIndex==-1 )
00287       {
00288         ostringstream ose;
00289         ose << "ERROR: Multiplying by non-constant " << expr;
00290         print_error( ose.str().c_str(), s );
00291       }
00292       else
00293       {
00294         print_poly_norm(expr[nrIndex],s);
00295       }
00296       s << cparen.str();
00297     }
00298     else if( expr.getKind()==DIVIDE )
00299     {
00300       //this should be 2 constants
00301       if( expr[0].isRational() && expr[1].isRational() )
00302       {
00303         if( pnRat )
00304           s<<"(pn_const ";
00305         Rational r = expr[0].getRational();
00306         print_rational_divide( ratNeg ? -r : r, expr[1].getRational(), s );
00307         if( pnRat )
00308           s << ")";
00309       }
00310       else
00311       {
00312         print_error("ERROR: Pn Dividing by non-constant", s );
00313       }
00314     }
00315     else
00316     {
00317       //TODO: checks for appropriate op
00318       //cout<<"e0 and e1"<<expr[0]<<" "<<expr[1]<<endl;
00319       s<<"(pn_"<<kind_to_str(expr.getKind())<<" _ _ _ _ _ ";
00320       print_poly_norm(expr[0],s);
00321       s<<" ";
00322       print_poly_norm(expr[1],s);
00323       s<<")";
00324     }
00325   }else if(expr.getKind()==UMINUS ){
00326     if( !cvc3_mimic )
00327       print_poly_norm( expr[0], s, pnRat, !ratNeg );
00328     else{
00329       s << "(pn_u- _ _ _ ";
00330       print_poly_norm( expr[0], s, pnRat, ratNeg );
00331       s << ")";
00332     }
00333   }else if(expr.isRational()){
00334     if( pnRat )
00335       s<<"(pn_const ";
00336     Rational r = expr.getRational();
00337     print_rational( ratNeg ? -r : r, s );
00338     if( pnRat )
00339       s << ")";
00340   }
00341   else if( expr.getKind()==SKOLEM_VAR )
00342   {
00343     bool success = false;
00344     if( skolem_vars.find( expr )!=skolem_vars.end() )
00345     {
00346       int val = d_terms[skolem_vars[expr]];
00347       if( val!=0 ){
00348         success = true;
00349         s << "(pn_var_atom _ _ @at" << val << ")";
00350       }
00351     }
00352     if( !success ){
00353       ostringstream ose;
00354       ose << "Trying to pn_var_atom a non-atomized skolem var " << expr;
00355       print_error( ose.str().c_str(), cout );
00356     }
00357   }
00358   else if( expr.getKind()==ITE ){
00359     int val = d_terms[expr];
00360     if( val!=0 ){
00361       s << "(pn_var_atom _ _ @at" << val << ")";
00362     }else{
00363       ostringstream ose;
00364       ose << "Trying to pn_var_atom a non-atomized ITE " << expr;
00365       print_error( ose.str().c_str(), cout );
00366     }
00367   }else if(expr.isVar()){
00368     s<<"(pn_var "<<expr<<")";
00369   }
00370   else{
00371     ostringstream ose;
00372     ose<<"ERROR printing polynomial norm for "<<expr;
00373     print_error( ose.str().c_str(), s );
00374   }
00375 }
00376 
00377 // recursively prints arithm terms
00378 void LFSCPrinter::print_terms_h( const Expr& expr,std::ostream& s ){
00379   int val = d_print_map[expr];
00380   if( val!=0 ){
00381     s << "@x" << val;
00382   }else if(expr.isRational()){
00383     s<<"(a_real ";
00384     print_rational( expr.getRational(), s );
00385     s<<")";
00386   }else if(expr.isVar()){
00387     s<<"(a_var_real "<<expr<<")";
00388   }else if(expr.arity()==2 ){
00389     if( expr.getKind()==DIVIDE ){
00390       if( expr[0].isRational() && expr[1].isRational() ){
00391         s<<"(a_real ";
00392         print_rational_divide( expr[0].getRational(), expr[1].getRational(), s );
00393         s<<")";
00394       }else{
00395         print_error( "ERROR: Dividing by non constant", s );
00396       }
00397     }else{
00398       //TODO: checks for appropriate op
00399       s<<"("<<kind_to_str(expr.getKind())<<"_Real ";
00400       print_terms_h(expr[0],s);
00401       s<< " ";
00402       print_terms_h(expr[1],s);
00403       s<<")";
00404     }
00405   }else if( expr.getKind()==ITE ){
00406     s << "(ite Real ";
00407     print_formula_h( expr[0], s );
00408     s << " ";
00409     print_terms_h( expr[1], s );
00410     s << " ";
00411     print_terms_h( expr[2], s );
00412     s << ")";
00413   }else if( expr.getKind()==UMINUS ){
00414     if( !cvc3_mimic ){ 
00415       s<<"(a_real ";
00416       if( expr[0].isRational() ){
00417         Rational r = expr[0].getRational();
00418         r = -r;
00419         print_rational( r, s );
00420       }else if( expr[0].getKind()==DIVIDE && expr[0][0].isRational() && expr[0][1].isRational() ){
00421         print_rational_divide( -expr[0][0].getRational(), expr[0][1].getRational(), s );
00422       }else{
00423         cout << "cannot determine rational " << expr << endl;
00424       }
00425       s<<")";
00426     }else{
00427       s<<"(u-_Real ";
00428       print_terms_h( expr[0], s );
00429       s<<")";
00430     }
00431   }else if(expr.arity()>2){
00432     //cout<<"term debug"<<expr<<" "<<expr.arity()<<endl;
00433     vector<Expr> kids = expr.getKids();
00434     vector<Expr>::iterator i = kids.begin(), iend= kids.end();
00435     while(i+1!=iend){
00436       s<<"("<<kind_to_str(expr.getKind())<<"_Real ";
00437       print_terms_h(*i,s);
00438       i++;
00439       s << " ";
00440     }
00441     print_terms_h(*i,s);
00442     for(int j=0; j<expr.arity();j++){
00443       s<<")";
00444 
00445     }
00446   }else{
00447     ostringstream os;
00448     os << "ERROR printing term "<<expr<<" "<<expr.arity();
00449     print_error( os.str().c_str(), s );
00450   }
00451 }
00452 
00453 void LFSCPrinter::print_formula_h(const Expr& clause, std::ostream& s){
00454   int val = d_print_map[clause];
00455   if( val!=0 ){
00456     s << "@f" << val;
00457   }else if(clause.isNot()){
00458     s<<"(not ";
00459     print_formula_h(clause[0],s);
00460     s<<")";
00461   }else if(clause.isOr()){
00462     s<<"(or ";
00463     print_formula_h(clause[0],s);
00464     s << " ";
00465     print_formula_h(clause[1],s);
00466     s<<")";
00467   }else if(clause.isAnd()){
00468     s<<"(and ";
00469     print_formula_h(clause[0],s);
00470     s << " ";
00471     print_formula_h(clause[1],s);
00472     s<<")";
00473   }else if(clause.isImpl()){
00474     s<<"(impl ";
00475     print_formula_h(clause[0],s);
00476     s << " ";
00477     print_formula_h(clause[1],s);
00478     s<<")";
00479   }else if(clause.isIff()){
00480     s<<"(iff ";
00481     print_formula_h(clause[0],s);
00482     s << " ";
00483     print_formula_h(clause[1],s);
00484     s<<")";
00485   }else if(clause.getKind()==ITE){
00486     s<<"(ifte ";
00487     print_formula_h( clause[0], s );
00488     s << " ";
00489     print_formula_h( clause[1], s );
00490     s << " ";
00491     print_formula_h( clause[2], s );
00492     s << ")";
00493   }else if( is_eq_kind( clause.getKind() ) ){
00494     int k = clause.getKind();
00495     s<<"("<<kind_to_str(k);
00496     s<<(is_smt_kind( k ) ? " " : "_" );
00497     s<<"Real ";
00498     print_terms_h(clause[0],s);
00499     s << " ";
00500     print_terms_h(clause[1],s);
00501     s<<")";
00502   }else if( clause.isFalse() ){
00503     s << "false";
00504   }else if( clause.isTrue() ){
00505     s << "true";
00506   }else{
00507     s << clause;
00508   }
00509 }
00510 
00511 void LFSCPrinter::make_let_map( const Expr& e ){
00512   if( e.arity()<=1 || d_print_visited_map.find( e )==d_print_visited_map.end() ){
00513     for( int a=0; a<(int)e.arity(); a++ ){
00514       make_let_map( e[a] );
00515     }
00516     if( e.arity()>1 ){
00517       if( d_print_map[e]==0 ){
00518         d_print_map[e] = let_i;
00519         let_i++;
00520       }
00521       d_print_visited_map[e] = true;
00522     }
00523   }
00524 }