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