CVC3

LFSCProof.cpp

Go to the documentation of this file.
00001 #include "LFSCProof.h"
00002 
00003 #include "LFSCBoolProof.h"
00004 #include "LFSCUtilProof.h"
00005 
00006 int LFSCProof::pf_counter = 0;
00007 std::map< LFSCProof*, int > LFSCProof::lambdaMap;
00008 std::map< LFSCProof*, LFSCProof* > LFSCProof::lambdaPrintMap;
00009 int LFSCProof::lambdaCounter = 1;
00010 
00011 LFSCProof::LFSCProof()
00012 {
00013   pf_counter++;
00014   printCounter = 0;
00015   strLen = -1;
00016   rplProof = NULL;
00017   chOp = -1;
00018   brComputed = false;
00019   assumeVar = -1;
00020   assumeVarUsed = -1;
00021 }
00022 
00023 void LFSCProof::print( std::ostream& s, int ind ){
00024   LFSCProof* p = rplProof ? rplProof : lambdaPrintMap[this];
00025   if( p ){
00026     p->print( s, ind );
00027   }else{
00028     if( lambdaMap.find( this )!=lambdaMap.end() && printCounter>0 ){
00029       print_warning( "Warning: printing out lambda abstracted proof more than once");
00030 #ifdef IGNORE_PRINT_MULTI_LAMBDA
00031       return;
00032 #endif
00033     }
00034     //if( printCounter>0 ){
00035     //  return;
00036     //}
00037     printCounter++;
00038     indent( s, ind );
00039     print_pf( s, ind );
00040   }
00041 }
00042 
00043 void LFSCProof::print_structure( std::ostream& s, int ind ){
00044   LFSCProof* p = rplProof ? rplProof : lambdaPrintMap[this];
00045   if( p ){
00046     p->print( s, ind );
00047   }else{
00048     indent( s, ind );
00049     if( lambdaMap.find( this )!=lambdaMap.end() && printCounter>0 ){
00050       //just a warning, print it out in ose
00051       print_warning( "ERROR: printing out lambda abstracted proof more than once" );
00052 #ifdef IGNORE_PRINT_MULTI_LAMBDA
00053       return;
00054 #endif
00055     }
00056     printCounter++;
00057     print_struct( s, ind );
00058   }
00059 }
00060 
00061 void LFSCProof::fillHoles(){
00062   //if( !is_lambda() ){
00063     for( int a=0; a<getNumChildren(); a++ ){
00064       getChild( a )->fillHoles();
00065     }
00066   //}
00067 }
00068 
00069 #ifdef OPTIMIZE
00070 void LFSCProof::calcL( std::vector< int >& lget, std::vector< int >& lgetu ){
00071   for( int a=0; a<getNumChildren(); a++ ){
00072     getChild( a )->calcL( lget, lgetu );
00073   }
00074   if( assumeVar!=-1 && std::find( lget.begin(), lget.end(), assumeVar )==lget.end() ){
00075     lget.push_back( assumeVar );
00076   }
00077   if( assumeVarUsed!=-1 && std::find( lgetu.begin(), lgetu.end(), assumeVarUsed )==lgetu.end() ){
00078     lgetu.push_back( assumeVarUsed );
00079   }
00080 }
00081 #endif
00082 
00083 int LFSCProof::checkOp() {
00084   if( chOp!=-1 )
00085     return chOp;
00086   if( getNumChildren()==1 )
00087     return getChild( 0 )->checkOp();
00088   else{
00089     int ret = -1;
00090     for( int a=0; a<getNumChildren(); a++ ){
00091       int o = getChild( a )->checkOp();
00092       if( a!=-1 ){
00093         if( ret==-1 )
00094           ret = a;
00095         else
00096           return -1;
00097       }
00098     }
00099     //cout << "fail case " << getNumChildren() << std::endl;
00100     return ret;
00101   }
00102 }
00103 
00104 LFSCProof* LFSCProof::Make_CNF( const Expr& form, const Expr& reason, int pos )
00105 {
00106   Expr ec = cascade_expr( form );
00107 #ifdef PRINT_MAJOR_METHODS
00108   cout << ";[M] CNF " << reason << " " << pos << std::endl;
00109 #endif
00110   int m = queryM( ec );
00111   if( m>0 )
00112   {
00113     ostringstream os1;
00114     ostringstream os2;
00115     RefPtr< LFSCProof > p;
00116     if( reason==d_or_final_s )
00117     {
00118 #if 0
00119       //this is the version that cascades
00120       //make the proof for the or
00121       p = LFSCPfVar::Make( "@v", abs(m) );
00122       //clausify the or statement
00123       p = LFSCClausify::Make( ec, p.get(), true );
00124       //return
00125       return LFSCAssume::Make( m, p.get(), true );
00126 #else
00127       //this is the version that does not expand the last
00128       ostringstream oss1, oss2;
00129       p = LFSCPfVar::Make( "@v", abs(m) );
00130       for( int a=(form.arity()-2); a>=0; a-- ){
00131         int m1 = queryM( form[a] );
00132         oss1 << "(or_elim_1 _ _ ";
00133         oss1 << ( m1<0 ? "(not_not_intro _ " : "" );
00134         oss1 << "@v" << abs( m1 );
00135         oss1 << ( m1<0 ? ") " : " " );
00136         oss2 << ")";
00137       }
00138       p = LFSCProofGeneric::Make( oss1.str(), p.get(), oss2.str() );
00139       //p = LFSCClausify::Make( form[form.arity()-1], p.get() );
00140       p = LFSCClausify::Make( queryM( form[form.arity()-1] ), p.get() );
00141       for( int a=0; a<(form.arity()-1); a++ ){
00142         p = LFSCAssume::Make( queryM( form[a] ), p.get(), false );
00143       }
00144       return LFSCAssume::Make( m, p.get() );
00145 #endif
00146     }
00147     else if( reason==d_and_final_s )
00148     {
00149 #if 1
00150       //this is the version that does not expand the last
00151       p = LFSCPfVar::Make( "@v", abs(m) );
00152       os1 << "(contra _ ";
00153       for( int a=0; a<form.arity(); a++ ){
00154         if( a<(form.arity()-1))
00155           os1 << "(and_intro _ _ ";
00156         os1 << "@v" << abs( queryM( form[a] ) );
00157         if( a<(form.arity()-1)){
00158           os1 << " ";
00159           os2 << ")";
00160         }
00161       }
00162       os2 << " @v" << abs(m) << ")";
00163       os1 << os2.str();
00164       p = LFSCProofGeneric::MakeStr( os1.str().c_str() );
00165       for( int a=0; a<form.arity(); a++ ){
00166         p = LFSCAssume::Make( queryM( form[a] ), p.get() );
00167       }
00168       return LFSCAssume::Make( m, p.get(), false );
00169 #else
00170       //this is the version that cascades
00171       std::vector< Expr > assumes;
00172       Expr ce = cascade_expr( form );
00173       Expr curr = ce;
00174       os1 << "(contra _ ";
00175       while( curr.getKind()==AND ){
00176         os1 << "(and_intro _ _ ";
00177         os1 << "@v" << abs( queryM( curr[0] ) ) << " ";
00178         os2 << ")";
00179         assumes.push_back( curr[0] );
00180         curr = curr[1];
00181       }
00182       os2 << " @v" << abs(m) << ")";
00183       p = LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() );
00184       for( int a=0; a<(int)assumes.size(); a++ ){
00185         p = LFSCAssume::Make( queryM( assumes[a] ), p.get() );
00186       }
00187       return LFSCAssume::Make( m, p.get(), false );
00188 #endif
00189     }
00190     else if( reason==d_imp_s )
00191     {
00192       int m1 = queryM( ec[0] );
00193       int m2 = queryM( ec[1] );
00194       switch( pos )
00195       {
00196       case 0:
00197 
00198         break;
00199       case 1:
00200 
00201         break;
00202       case 2:
00203       {
00204         //make a proof of the RHS
00205         ostringstream os;
00206         os << "(impl_elim _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")";
00207         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00208         //clausify the RHS
00209         p = LFSCClausify::Make( form[1], p.get() );     //cascadeOr?
00210         p = LFSCAssume::Make( queryM( ec[0] ), p.get() );
00211         return LFSCAssume::Make( queryM( ec ), p.get() );
00212       }
00213         break;
00214       }
00215     }
00216     else if( reason==d_ite_s )
00217     {
00218       int m1 = queryM( ec[0] );
00219       int m2 = queryM( ec[1] );
00220       switch( pos )
00221       {
00222       case 1:
00223       {
00224         ostringstream os;
00225         os << "(ite_elim_2" << (m1<0 ? "n" : "" );
00226         os << " _ _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")";
00227         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00228         p = LFSCClausify::Make( form[2], p.get() );
00229         p = LFSCAssume::Make( queryM( ec[0] ), p.get(), false );
00230         return LFSCAssume::Make( queryM( ec ), p.get() );
00231       }
00232         break;
00233       case 2:
00234       {
00235         ostringstream os;
00236         os << "(not_ite_elim_2 _ _ _ @v" << (m1<0 ? "n" : "" );
00237         os << abs( m1 ) << " @v" << abs( m ) << ")";
00238         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00239         Expr e = Expr( NOT, form[2] );
00240         p = LFSCClausify::Make( e, p.get() );
00241         p = LFSCAssume::Make( queryM( ec[0] ), p.get(), false );
00242         return LFSCAssume::Make( queryM( ec ), p.get(), false );
00243       }
00244         break;
00245       case 3:
00246       {
00247         ostringstream os;
00248         os << "(not_ite_elim_1 _ _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")";
00249         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00250         Expr e = Expr( NOT, form[1] );
00251         p = LFSCClausify::Make( e, p.get() );
00252         p = LFSCAssume::Make( queryM( ec[0] ), p.get() );
00253         return LFSCAssume::Make( queryM( ec ), p.get(), false );
00254       }
00255         break;
00256       case 4:
00257       {
00258         ostringstream os;
00259         os << "(ite_elim_1";// << (m1<0 ? "n" : "" );
00260         os << "  _ _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")";
00261         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00262         p = LFSCClausify::Make( form[1], p.get() );
00263         p = LFSCAssume::Make( queryM( ec[0] ), p.get() );
00264         return LFSCAssume::Make( queryM( ec ), p.get() );
00265       }
00266         break;
00267       case 5:
00268       {
00269         ostringstream os;
00270         os << "(not_ite_elim_3 _ _ _ @v" << abs( m2 ) << " @v" << abs( m ) << ")";
00271         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00272         Expr e = Expr( NOT, form[2] );
00273         p = LFSCClausify::Make( e, p.get() );
00274         p = LFSCAssume::Make( queryM( ec[1] ), p.get() );
00275         return LFSCAssume::Make( queryM( ec ), p.get(), false );
00276       }
00277         break;
00278       case 6:
00279       {
00280         ostringstream os;
00281         os << "(ite_elim_3";// << (m1<0 ? "n" : "" );
00282         os << "  _ _ _ @v" << abs( m2 ) << " @v" << abs( m ) << ")";
00283         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00284         p = LFSCClausify::Make( form[2], p.get() );
00285         p = LFSCAssume::Make( queryM( ec[1] ), p.get(), false );
00286         return LFSCAssume::Make( queryM( ec ), p.get() );
00287       }
00288         break;
00289       }
00290     }
00291     else if( reason==d_iff_s )
00292     {
00293       int m1 = queryM( ec[0] );
00294       int m2 = queryM( ec[1] );
00295       switch( pos )
00296       {
00297       case 0:
00298       {
00299         ostringstream os;
00300         os << "(not_iff_elim_1 _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")";
00301         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00302         p = LFSCClausify::Make( form[1], p.get() );
00303         p = LFSCAssume::Make( queryM( ec[0] ), p.get(), false );
00304         return LFSCAssume::Make( queryM( ec ), p.get(), false );
00305       }
00306         break;
00307       case 1:
00308       {
00309         ostringstream os;
00310         os << "(not_iff_elim_2 _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")";
00311         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00312         p = LFSCClausify::Make( Expr( NOT, form[1] ), p.get() );
00313         p = LFSCAssume::Make( queryM( ec[0] ), p.get() );
00314         return LFSCAssume::Make( queryM( ec ), p.get(), false );
00315       }
00316         break;
00317       case 2:
00318       {
00319         ostringstream os;
00320         os << "(impl_elim _ _ @v" << abs( m1 ) << "(iff_elim_1 _ _ @v" << abs( m ) << "))";
00321         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00322         //clausify the RHS
00323         p = LFSCClausify::Make( form[1], p.get() );     //cascadeOr?
00324         p = LFSCAssume::Make( queryM( ec[0] ), p.get() );
00325         return LFSCAssume::Make( queryM( ec ), p.get() );
00326       }
00327         break;
00328       case 3:
00329       {
00330         ostringstream os;
00331         os << "(impl_elim _ _ @v" << abs( m2 ) << "(iff_elim_2 _ _ @v" << abs( m ) << "))";
00332         p = LFSCProofGeneric::MakeStr( os.str().c_str() );
00333         //clausify the RHS
00334         p = LFSCClausify::Make( form[0], p.get() );     //cascadeOr?
00335         p = LFSCAssume::Make( queryM( ec[1] ), p.get() );
00336         return LFSCAssume::Make( m, p.get() );
00337       }
00338         break;
00339       }
00340     }
00341     else if( reason==d_or_mid_s )
00342     {
00343       ostringstream os1, os2;
00344       if( form[pos].isNot() )
00345         os1 << "(not_not_elim _ ";
00346       os1 << "(or_elim" << ( (pos==form.arity()) ? "_end" : "" );
00347       os1 << " _ _ " << pos << " ";
00348       os2 << ")";
00349       if( form[pos].isNot() )
00350         os2 << ")";
00351       p = LFSCPfVar::Make( "@v", abs( m ) );
00352       p = LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() );
00353       Expr ea = Expr( NOT, form[pos] );
00354       p = LFSCClausify::Make( ea, p.get() );
00355       return LFSCAssume::Make( m, p.get(), false );
00356     }
00357     else if( reason==d_and_mid_s )
00358     {
00359       //make a proof of the pos-th statement
00360       p = LFSCPfVar::Make( "@v", abs( m ) );
00361       p = LFSCProof::Make_and_elim( form, p.get(), pos, form[pos] );
00362       p = LFSCClausify::Make( form[pos], p.get() );
00363       return LFSCAssume::Make( m, p.get() );
00364     }
00365   }
00366   ostringstream ose;
00367   ose << "CNF, " << reason << " unknown position = " << pos << std::endl;
00368   print_error( ose.str().c_str(), cout );
00369   return NULL;
00370 }
00371 
00372 LFSCProof* LFSCProof::Make_not_not_elim( const Expr& pf, LFSCProof* p )
00373 {
00374   if( pf.isNot() && pf[0].isNot() ){
00375     p = Make_not_not_elim( pf[0][0], p );
00376     ostringstream os1, os2;
00377     os1 << "(not_not_elim _ ";
00378     os2 << ")";
00379     p = LFSCProofGeneric::Make( os1.str(), p, os2.str() );
00380   }
00381   return p;
00382 }
00383 
00384 LFSCProof* LFSCProof::Make_mimic( const Expr& pf, LFSCProof* p, int numHoles )
00385 {
00386   ostringstream os1, os2;
00387   os1 << "(";
00388   os1 << pf[0];
00389   for( int a=0; a<numHoles; a++ )
00390     os1 << " _";
00391   os1 << " ";
00392   os2 << ")";
00393   return LFSCProofGeneric::Make( os1.str(), p, os2.str() );
00394 }
00395 
00396 //input should be in non-cascaded form
00397 LFSCProof* LFSCProof::Make_and_elim( const Expr& form, LFSCProof* p, int n,  const Expr& expected )
00398 {
00399   Expr e = cascade_expr( form );
00400   for( int a=0; a<n; a++ ){
00401     if( e.arity()==2 ){
00402       e = e[1];
00403     }else{
00404       print_error( "WARNING: and elim out of range", cout );
00405     }
00406   }
00407   if( form.arity()>1 )
00408   {
00409     ostringstream os1, os2;
00410     os1 << "(and_elim";
00411     if( n==form.arity()-1 )
00412       os1 << "_end";
00413     os1 << " _ _ " << n << " ";
00414     os2 << ")";
00415     return LFSCProofGeneric::Make( os1.str(), p, os2.str() );
00416   }
00417   else
00418   {
00419     return p;
00420   }
00421 }
00422