CVC3

TReturn.cpp

Go to the documentation of this file.
00001 #include "TReturn.h"
00002 
00003 #include "LFSCUtilProof.h"
00004 #include "LFSCLraProof.h"
00005 #include "LFSCBoolProof.h"
00006 #include "LFSCPrinter.h"
00007 
00008 TReturn::TReturn(LFSCProof* lfsc_pf, std::vector<int>& L, std::vector<int>& Lused, Rational r, bool hasR, int pvY):
00009                 d_lfsc_pf(lfsc_pf), d_c( r ), d_provesY(pvY){
00010   d_hasRt = hasR;
00011   for( int a=0; a<(int)L.size(); a++ )
00012     d_L.push_back( L[a] );
00013   for( int a=0; a<(int)Lused.size(); a++ )
00014     d_L_used.push_back( Lused[a] );
00015 
00016 #ifdef DEBUG_MEM_STATS
00017   static int counter = 0;
00018   counter++;
00019   cout << "make a tret " << counter << std::endl;
00020 #endif
00021   lcalced = false;
00022 }
00023 
00024 Rational TReturn::mult_rational( TReturn* lhs )
00025 {
00026   if( !hasRational() && lhs->hasRational() )
00027     return lhs->mult_rational( this );
00028   else if( hasRational() ){
00029     if( lhs->hasRational() )
00030       return d_c*lhs->d_c;
00031     else
00032       return d_c;
00033   }else
00034     return lhs->d_c;
00035 }
00036 
00037 void TReturn::getL( std::vector< int >& lget, std::vector< int >& lgetu ){
00038 #ifndef OPTIMIZE
00039   std::vector< int >::iterator i;
00040   for( int a=0; a<(int)d_L.size(); a++ ){
00041     i = std::find( lget.begin(), lget.end(), d_L[a] );
00042     if( i==lget.end() ){
00043       lget.push_back( d_L[a] );
00044     }
00045   }
00046   for( int a=0; a<(int)d_L_used.size(); a++ ){
00047     i = std::find( lgetu.begin(), lgetu.end(), d_L_used[a] );
00048     if( i==lgetu.end() ){
00049       lgetu.push_back( d_L_used[a] );
00050     }
00051   }
00052 #endif
00053 }
00054 
00055 #ifdef OPTIMIZE
00056 void TReturn::calcL( std::vector< int >& lget, std::vector< int >& lgetu ){
00057   if( !lcalced ){
00058     d_L.clear();
00059     d_L_used.clear();
00060     d_lfsc_pf->calcL( d_L, d_L_used );
00061     lcalced = true;
00062   }
00063   std::vector< int >::iterator i;
00064   for( int a=0; a<(int)d_L.size(); a++ ){
00065     i = std::find( lget.begin(), lget.end(), d_L[a] );
00066     if( i==lget.end() ){
00067       lget.push_back( d_L[a] );
00068     }
00069   }
00070   for( int a=0; a<(int)d_L_used.size(); a++ ){
00071     i = std::find( lgetu.begin(), lgetu.end(), d_L_used[a] );
00072     if( i==lgetu.end() ){
00073       lgetu.push_back( d_L_used[a] );
00074     }
00075   }
00076 }
00077 #endif
00078 
00079 
00080 // make it so that the two TReturns agree on what they are proving
00081 // t1 proves pf1, Y( pf1 ), or Y2( pf1 )
00082 // t2 proves pf2, Y( pf2 ), or Y2( pf2 )
00083 // on return, t1->d_proveY should equal t2->d_proveY
00084 int TReturn::normalize_tret( const Expr& pf1, TReturn*& t1, const Expr& pf2, TReturn*& t2, bool rev_pol )
00085 {
00086   if( t1->getProvesY()!=t2->getProvesY() )
00087   {
00088     if( t1->getProvesY()>t2->getProvesY() )
00089       return normalize_tret( pf2, t2, pf1, t1, rev_pol );
00090     else
00091     {
00092       if( debug_conv )
00093         cout << "normalizing proofs " << t1->getProvesY() << " " << t2->getProvesY() << " " << rev_pol << std::endl;
00094 
00095       if( t1->getProvesY()==0 && t2->getProvesY()==2 )
00096         normalize_tr( pf1, t1, 2, rev_pol );
00097       if( t1->getProvesY()==1 && t2->getProvesY()==2 )
00098         normalize_tr( pf1, t1, 2, rev_pol );
00099       if( t1->getProvesY()==0 && t2->getProvesY()==1 ){
00100         if( normalize_tr( pf1, t1, 1, rev_pol, false )==-1 ){     //try to go 0 to 1 (optional)
00101           if( normalize_tr( pf2, t2, 0, rev_pol, false )==-1 ){   //try to go 1 to 0 immediately (optional)
00102             normalize_tr( pf1, t1, 2, rev_pol );
00103             normalize_tr( pf2, t2, 2, rev_pol );
00104           }
00105         }
00106       }
00107       if( t2->getProvesY()==3 ){
00108         normalize_tr( pf1, t1, 3, rev_pol );
00109       }
00110 
00111       if( t1->getProvesY()!=t2->getProvesY() ){
00112         ostringstream os;
00113         os << "ERROR:normalize_tret: Could not normalize proofs " << t1->getProvesY() << " " << t2->getProvesY() << std::endl;
00114         os << pf1[0] << " " << pf2[0] << std::endl;
00115         print_error( os.str().c_str(), cout );
00116         return -1;
00117       }else{
00118         return t1->getProvesY();
00119       }
00120     }
00121   }
00122   return t1->getProvesY();
00123 }
00124  
00125 int TReturn::normalize_tr( const Expr& pf1, TReturn*& t1, int y, bool rev_pol, bool printErr )
00126 {
00127   TReturn* torig = t1;
00128 
00129   int chOp = t1->getLFSCProof()->getChOp();
00130   std::vector< int > emptyL;
00131   std::vector< int > emptyLUsed;
00132   t1->getL( emptyL, emptyLUsed );
00133 
00134   if( t1->getProvesY()!=y )
00135   {
00136     if( debug_conv ){
00137       cout << "normalizing tr " << t1->getProvesY() << " to " << y << " rev_pol = " << rev_pol << std::endl;
00138     }
00139     Expr e;
00140     if( what_is_proven( pf1, e ) )
00141     {
00142       e = queryElimNotNot( e );
00143       if( rev_pol ){
00144         if( e.isIff() ){
00145           //cout << "Warning: rev_pol called on IFF, 0 normalize to " << y << std::endl;
00146           e = Expr( IFF, e[1], e[0] );
00147         }else if( e.isImpl() ){
00148           e = Expr( IMPLIES, e[1], e[0] );
00149         }
00150       }
00151       Expr eb = queryAtomic( e, true );
00152       if( y==3 )
00153       {
00154         if( t1->getProvesY()!=2 ){
00155           if( normalize_tr( pf1, t1, 2, rev_pol )==-1 ){
00156             return -1;
00157           }
00158         }
00159         if( e.isIff() ){
00160           e = Expr( IMPLIES, e[0], e[1] );
00161         }
00162         //clausify what t1 is proving
00163         t1 = new TReturn( LFSCClausify::Make( e, t1->getLFSCProof() ), emptyL, emptyLUsed, nullRat, false, 3 );
00164       }
00165       else if( y==1 )
00166       {
00167         if( t1->getProvesY()==0 || t1->getProvesY()==2 ){
00168           if( can_pnorm( eb ) )
00169           {
00170             t1 = new TReturn( LFSCLraPoly::Make( e, t1->getLFSCProof() ), emptyL, emptyLUsed,
00171                               t1->getRational(), t1->hasRational(), 1 );
00172           }else{
00173             //cout << "nrt kind = " << kind_to_str( eb.getKind() ) << std::endl;
00174           }
00175         }
00176       }
00177       else if( y==0 )
00178       {
00179         if( is_eq_kind( eb.getKind() ) ){
00180           normalize_to_tf( e, t1, 0 );
00181         }else if( e[0]==e[1] ){
00182           ostringstream os1, os2;
00183           os1 << "(iff_refl ";
00184           RefPtr< LFSCProof > p = LFSCProofExpr::Make( e[0] );
00185           os2 << ")";
00186           t1 = new TReturn( LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() ),
00187                             emptyL, emptyLUsed, nullRat, false, 0 );
00188         }else{
00189           if( t1->getProvesY()==1 ){
00190 #ifdef PRINT_MAJOR_METHODS
00191             cout << ";[M]: Normalize 1 to 0, iff" << std::endl;
00192 #endif
00193             if( e[1].isFalse() )
00194             {
00195               Expr ea = Expr( NOT, e[0] );
00196               normalize_to_tf( ea, t1, 0 );
00197               ostringstream os1, os2;
00198               os1 << "(" << ( e[0].getKind()==NOT ? "not_to_iff" : "iff_not_false" );
00199               os1 << " _ ";
00200               os2 << ")";
00201               t1 = new TReturn( LFSCProofGeneric::Make( os1.str(), t1->getLFSCProof(), os2.str() ), 
00202                                 emptyL, emptyLUsed, nullRat, false, 0 );
00203             }
00204             else if( e[1].isTrue() )
00205             {
00206               normalize_to_tf( e[0], t1, 0 );
00207               ostringstream os1, os2;
00208               os1 << "(iff_true _ ";
00209               os2 << ")";
00210               t1 = new TReturn( LFSCProofGeneric::Make( os1.str(), t1->getLFSCProof(), os2.str() ), 
00211                                 emptyL, emptyLUsed, nullRat, false, 0 );
00212             }
00213             else if( printErr )
00214             {
00215               TReturn* torg = new TReturn( LFSCPfVar::Make( "@V", 0 ), emptyL, emptyLUsed,
00216                                           t1->getRational(), t1->hasRational(), t1->getProvesY() );
00217               TReturn *ti1, *ti2;
00218               TReturn* to = torg;
00219               if( normalize_tr( pf1, to, 2, rev_pol ) )
00220               {
00221                 ti1 = to;
00222                 to = torg;
00223                 if( normalize_tr( pf1, to, 2, !rev_pol ) )
00224                 {
00225                   ti2 = to;
00226                   ostringstream os1, os2, os3, os4;
00227                   os1 << "(impl_elim _ _ ";
00228                   os2 << "(impl_intro _ _ (\\ @V0 (iff_intro _ _ ";
00229                   os3 << " ";
00230                   os4 << "))))";
00231                   std::vector< RefPtr< LFSCProof > > pfs;
00232                   pfs.push_back( t1->getLFSCProof() );
00233                   pfs.push_back( ti1->getLFSCProof() );
00234                   pfs.push_back( ti2->getLFSCProof() );
00235                   std::vector< string > strs;
00236                   strs.push_back( os1.str() );
00237                   strs.push_back( os2.str() );
00238                   strs.push_back( os3.str() );
00239                   strs.push_back( os4.str() );
00240                   t1 = new TReturn( LFSCProofGeneric::Make( pfs, strs ), emptyL, emptyLUsed, nullRat, false, 0 );
00241                 }
00242               }
00243             }
00244           }
00245         }
00246       }
00247       else if( y==2 )
00248       {
00249         if( t1->getProvesY()==0 )
00250         {
00251           RefPtr< LFSCProof > p;
00252           if( e.isIff() ){
00253             ostringstream os1, os2;
00254             os1 << "(iff_elim_1 _ _ ";
00255             os2 << ")";
00256             p = LFSCProofGeneric::Make( os1.str(), t1->getLFSCProof(), os2.str() );
00257           }else{
00258             //cout << "actually I can just drop it " << e << std::endl;
00259             p = t1->getLFSCProof();
00260           }
00261           t1 = new TReturn( p.get(), emptyL, emptyLUsed, nullRat, false, 2 );
00262         }
00263         else if( t1->getProvesY()==1 )
00264         {
00265           if( is_eq_kind( eb.getKind() ) ){
00266             normalize_to_tf( e, t1, 2 );
00267           }else if( e.isIff() || e.isImpl() ){
00268             Expr eatom1 = queryAtomic( e[0] );
00269             Expr eatom2 = queryAtomic( e[1] );
00270             //Expr ebase1 = queryAtomic( eatom1, true );
00271             //Expr ebase2 = queryAtomic( eatom2, true );
00272             int val1 = queryM( e[0] );
00273             int val2 = queryM( e[1] );
00274             int k1 = eatom1.getKind();
00275             int k2 = eatom2.getKind();
00276 
00277             if( e[0]==e[1] ){
00278               ostringstream os;
00279               os << "(impl_refl_atom" << (val1<0 ? "_not" : "" );
00280               os << " _ _ @a" << abs( val1 ) << ")";
00281               //d_formulas_printed[queryAtomic( e[0], true )] = true;
00282               t1 = new TReturn( LFSCProofGeneric::MakeStr( os.str().c_str()),
00283                                 emptyL, emptyLUsed, nullRat, false, 2 );
00284             }else if( eatom2.isFalse() || eatom2.isTrue() ){
00285               if( eatom1.getKind()==eatom2.getKind() )
00286               {
00287 #ifdef PRINT_MAJOR_METHODS
00288                 cout << ";[M]: Normalize 1 to 2, iff/impl double logical iff" << std::endl;
00289 #endif
00290                 if( e[0]!=e[1] ){
00291                   ostringstream ose;
00292                   ose << "Warning: normalize logical atoms, not equal ";
00293                   ose << e[0] << " " << e[1] << std::endl;
00294                   print_error( ose.str().c_str(), cout );
00295                 }
00296                 ostringstream os;
00297                 os << "impl_refl_" << ( eatom2.isFalse() ? "false" : "true" );
00298                 t1 = new TReturn( LFSCProofGeneric::MakeStr(os.str().c_str()),
00299                                   emptyL, emptyLUsed, nullRat, false, 2 );
00300               }
00301               else if( eatom2.isTrue() )
00302               {
00303                 normalize_to_tf( e[0], t1, 2 );
00304                 ostringstream oss1, oss2;
00305                 oss1 << "(iff_true_impl _ ";
00306                 oss2 << ")";
00307                 t1 = new TReturn( LFSCProofGeneric::Make( oss1.str(), t1->getLFSCProof(), oss2.str() ),
00308                                   emptyL, emptyLUsed, nullRat, false, 2 );
00309               }
00310               else if( eatom2.isFalse() )
00311               {
00312 #ifdef PRINT_MAJOR_METHODS
00313                // cout << ";[M]: Normalize 1 to 2, iff/impl logical iff" << std::endl;
00314 #endif
00315                 //make proof for assumption
00316                 RefPtr< LFSCProof > p = LFSCPfVar::Make( "@v", abs( val1 ) );
00317                 p = LFSCLraPoly::Make( e[0], p.get() );
00318 
00319                 p = LFSCLraAdd::Make( p.get(), t1->getLFSCProof(),
00320                                       get_normalized( k1 ),
00321                                       get_normalized( k1, true ) );
00322                 p = LFSCLraContra::Make( p.get(), is_comparison( k1 ) ? (int)GT : (int)DISTINCT );
00323 
00324                 ostringstream oss1, oss2;
00325                 //oss1 << std::endl << "this is a normalization proof of " << e[0] << "->" << e[1] << std::endl;
00326                 //oss1 << "or a proof of " << eatom1 << " -> " << eatom2 << std::endl;
00327                 oss1 << "(impl_intro"; // << ( eatom2.isTrue() ? "_not" : "" );
00328                 oss1 << " _ _ (\\ @v" << abs( val1 ) << " ";
00329                 oss1 << "(bottom_elim ";
00330                 printer->print_formula( e[1], oss1 );
00331                 oss1 << " ";
00332 
00333                 oss2 << ")))";
00334                 p = LFSCProofGeneric::Make( oss1.str(), p.get(), oss2.str() );
00335                 //p = LFSCAssume::Make( val1, p.get(), false, 1 );
00336 
00337                 t1 = new TReturn( p.get(), emptyL, emptyLUsed, nullRat, false, 2 );
00338               }
00339             }
00340             else if( is_eq_kind( k1 ) && is_eq_kind( k2 ) )
00341             {
00342 #ifdef PRINT_MAJOR_METHODS
00343               //cout << ";[M]: Normalize 1 to 2, iff/impl" << std::endl;
00344 #endif
00345               RefPtr< LFSCProof > p;
00346               //assume1
00347               ostringstream os1, os2;
00348               //os1 << "this is a normalization proof of " << e[0] << "->" << e[1] << std::endl;
00349               //os1 << "or a proof of " << eatom1 << " -> " << eatom2 << std::endl;
00350               os1 << "(impl_intro";
00351               os1 << " _ _ (\\ ";
00352               os1 << "@v" << abs( val1 ) << " ";
00353               os2 << "))";
00354 
00355               //make proof for assumption
00356               RefPtr< LFSCProof > p1 = LFSCPfVar::Make( "@v", abs( val1 ) );
00357               RefPtr< LFSCProof > p2 = LFSCPfVar::Make( "@v", abs( val2 ) );
00358 
00359               //convert to polynomial proofs
00360               p1 = LFSCLraPoly::Make( e[0], p1.get() );
00361               Expr ea2 = Expr( NOT, e[1] );
00362               p2 = LFSCLraPoly::Make( ea2, p2.get() );
00363 
00364               if( t1->hasRational() ){
00365                 if( rev_pol )
00366                   p2 = LFSCLraMulC::Make( p2.get(), t1->getRational(), get_normalized( k2, true ) );
00367                 else
00368                   p1 = LFSCLraMulC::Make( p1.get(), t1->getRational(), get_normalized( k1 ) );
00369               }
00370 
00371               p = LFSCLraAdd::Make( p1.get(), p2.get(),
00372                                     get_normalized( k1 ),
00373                                     get_normalized( k2, true ) );
00374 
00375               p = LFSCLraSub::Make( p.get(), t1->getLFSCProof(),
00376                                     is_comparison( k1 ) ? (int)GT : (int)DISTINCT, EQ );
00377               p = LFSCLraContra::Make( p.get(),
00378                                        is_comparison( k1 ) ? (int)GT : (int)DISTINCT );
00379 
00380               p = LFSCAssume::Make( val2, p.get(), false, 1 );   
00381 
00382               p = LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() );
00383 
00384               t1 = new TReturn( p.get(), emptyL, emptyLUsed, nullRat, false, 2 );
00385             }
00386             else
00387             {
00388               ostringstream ose;
00389               ose << "NTret 12 could not handle " << eatom1 << " " << eatom2;
00390               print_error( ose.str().c_str(), cout );
00391             }
00392           }
00393         }
00394       }
00395     }
00396   }
00397   t1->getLFSCProof()->setChOp( chOp );
00398   if( t1->getProvesY()!=y )
00399   {
00400     if( printErr || debug_conv ){
00401       ostringstream ose;
00402       ose << "Failed normalize_tr " << t1->getProvesY() << " " << y << std::endl;
00403       Expr e;
00404       if( what_is_proven( pf1, e ) )
00405        ose << "proven_expr = " << e << std::endl;
00406       print_error( ose.str().c_str(), cout );
00407     }
00408     return -1;
00409   }
00410   else
00411   {
00412 #ifdef IGNORE_NORMALIZE
00413   t1 = new TReturn( torig->getLFSCProof(), emptyL, emptyLUsed,
00414                     torig->getRational(), torig->hasRational(), y );
00415   t1->getLFSCProof()->setChOp( chOp );
00416   return t1->getProvesY();
00417 #else
00418     return t1->getProvesY();
00419 #endif
00420   }
00421 }
00422 
00423 void TReturn::normalize_to_tf( const Expr& e, TReturn*& t1, int y )
00424 {
00425   int chOp = t1->getLFSCProof()->getChOp();
00426   if( t1->getProvesY()!=1 ){
00427     ostringstream ose;
00428     ose << "Bad mode for norm to tf " << t1->getProvesY() << std::endl;
00429     print_error( ose.str().c_str(), cout );
00430   }
00431   std::vector< int > emptyL;
00432   std::vector< int > emptyLUsed;
00433   t1->getL( emptyL, emptyLUsed );
00434 
00435   if( t1->getLFSCProof()->AsLFSCLraPoly() && false )
00436   {
00437 #ifdef PRINT_MAJOR_METHODS
00438     cout << ";[M]: Normalize 1 to " << y << ", simplify case" << std::endl;
00439 #endif
00440     t1 = new TReturn( t1->getLFSCProof()->getChild( 0 ), emptyL, emptyLUsed, nullRat, false, y );
00441   }
00442   else
00443   {
00444 
00445 #ifdef PRINT_MAJOR_METHODS
00446     cout << ";[M]: Normalize 1 to " << y << ", iff/impl, atom" << std::endl;
00447 #endif
00448 
00449     Expr eatom = queryAtomic( e );
00450     int val = queryM( e );
00451     int knd = eatom.getKind();
00452 
00453     //make proof for assumption
00454     RefPtr< LFSCProof > p = LFSCPfVar::Make( "@v", abs( val ) );
00455     //convert to polynomial proof
00456     Expr ea = Expr( NOT, e );
00457     p = LFSCLraPoly::Make( ea, p.get() );
00458 
00459     p = LFSCLraContra::Make(
00460           LFSCLraAdd::Make( p.get(), t1->getLFSCProof(),
00461                             get_normalized( knd, (val<0) ),
00462                             get_normalized( knd, !(val<0) ) ),
00463           is_comparison( knd ) ? (int)GT : (int)DISTINCT );
00464 
00465     p = LFSCAssume::Make( val, p.get(), false, 1 );
00466 
00467     //ostringstream os1, os2;
00468     //os1 << "This is the atomization of " << e << ":";
00469     //os2 << " ";
00470     //p = LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() );
00471 
00472     //we have concluded e
00473     t1 = new TReturn( p.get(), emptyL, emptyLUsed, nullRat, false, y );
00474   }
00475   t1->getLFSCProof()->setChOp( chOp );
00476 }