CVC3
|
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 }