CVC3
|
00001 #include "LFSCObject.h" 00002 00003 LFSCPrinter* LFSCObj::printer; 00004 int LFSCObj::formula_i = 1; 00005 int LFSCObj::term_i = 1; 00006 int LFSCObj::trusted_i = 1; 00007 int LFSCObj::tnorm_i = 1; 00008 bool LFSCObj::debug_conv; 00009 bool LFSCObj::debug_var; 00010 bool LFSCObj::cvc3_mimic; 00011 bool LFSCObj::cvc3_mimic_input; 00012 int LFSCObj::lfsc_mode; 00013 Rational LFSCObj::nullRat; 00014 ExprMap< int > LFSCObj::nnode_map; 00015 ExprMap< Expr > LFSCObj::cas_map; 00016 ExprMap< Expr > LFSCObj::skolem_vars; 00017 ExprMap< bool > LFSCObj::temp_visited; 00018 ExprMap<int> LFSCObj::d_formulas; 00019 ExprMap<int> LFSCObj::d_trusted; 00020 ExprMap<int> LFSCObj::d_pn; 00021 ExprMap<int> LFSCObj::d_pn_form; 00022 ExprMap< int > LFSCObj::d_terms; 00023 ExprMap<bool> LFSCObj::input_vars; 00024 ExprMap<bool> LFSCObj::input_preds; 00025 std::map< int, bool > LFSCObj::pntNeeded; 00026 ExprMap<bool> LFSCObj::d_formulas_printed; 00027 Expr LFSCObj::d_pf_expr; 00028 ExprMap<bool> LFSCObj::d_assump_map; 00029 //differentiate between variables and rules 00030 ExprMap<bool> LFSCObj::d_rules; 00031 //boolean resultion rules 00032 Expr LFSCObj::d_bool_res_str; 00033 Expr LFSCObj::d_assump_str; 00034 Expr LFSCObj::d_iff_mp_str; 00035 Expr LFSCObj::d_impl_mp_str; 00036 Expr LFSCObj::d_iff_trans_str; 00037 Expr LFSCObj::d_real_shadow_str; 00038 Expr LFSCObj::d_cycle_conflict_str; 00039 Expr LFSCObj::d_real_shadow_eq_str; 00040 Expr LFSCObj::d_basic_subst_op_str; 00041 Expr LFSCObj::d_mult_ineqn_str; 00042 Expr LFSCObj::d_right_minus_left_str; 00043 Expr LFSCObj::d_eq_trans_str; 00044 Expr LFSCObj::d_eq_symm_str; 00045 Expr LFSCObj::d_canon_plus_str; 00046 Expr LFSCObj::d_refl_str; 00047 Expr LFSCObj::d_cnf_convert_str; 00048 Expr LFSCObj::d_learned_clause_str; 00049 Expr LFSCObj::d_minus_to_plus_str; 00050 Expr LFSCObj::d_plus_predicate_str; 00051 Expr LFSCObj::d_negated_inequality_str; 00052 Expr LFSCObj::d_flip_inequality_str; 00053 Expr LFSCObj::d_optimized_subst_op_str; 00054 Expr LFSCObj::d_iff_true_elim_str; 00055 Expr LFSCObj::d_basic_subst_op1_str; 00056 Expr LFSCObj::d_basic_subst_op0_str; 00057 Expr LFSCObj::d_canon_mult_str; 00058 Expr LFSCObj::d_canon_invert_divide_str; 00059 Expr LFSCObj::d_iff_true_str; 00060 Expr LFSCObj::d_mult_eqn_str; 00061 Expr LFSCObj::d_rewrite_eq_symm_str; 00062 Expr LFSCObj::d_implyWeakerInequality_str; 00063 Expr LFSCObj::d_implyWeakerInequalityDiffLogic_str; 00064 Expr LFSCObj::d_imp_mp_str; 00065 Expr LFSCObj::d_rewrite_implies_str; 00066 Expr LFSCObj::d_rewrite_or_str; 00067 Expr LFSCObj::d_rewrite_and_str; 00068 Expr LFSCObj::d_rewrite_iff_symm_str; 00069 Expr LFSCObj::d_iff_not_false_str; 00070 Expr LFSCObj::d_iff_false_str; 00071 Expr LFSCObj::d_iff_false_elim_str; 00072 Expr LFSCObj::d_not_to_iff_str; 00073 Expr LFSCObj::d_not_not_elim_str; 00074 Expr LFSCObj::d_const_predicate_str; 00075 Expr LFSCObj::d_rewrite_not_not_str; 00076 Expr LFSCObj::d_rewrite_not_true_str; 00077 Expr LFSCObj::d_rewrite_not_false_str; 00078 Expr LFSCObj::d_if_lift_rule_str; 00079 Expr LFSCObj::d_CNFITE_str; 00080 Expr LFSCObj::d_var_intro_str; 00081 Expr LFSCObj::d_int_const_eq_str; 00082 Expr LFSCObj::d_rewrite_eq_refl_str; 00083 Expr LFSCObj::d_iff_symm_str; 00084 Expr LFSCObj::d_rewrite_iff_str; 00085 Expr LFSCObj::d_implyNegatedInequality_str; 00086 Expr LFSCObj::d_uminus_to_mult_str; 00087 Expr LFSCObj::d_lessThan_To_LE_rhs_rwr_str; 00088 Expr LFSCObj::d_rewrite_ite_same_str; 00089 Expr LFSCObj::d_andE_str; 00090 Expr LFSCObj::d_implyEqualities_str; 00091 Expr LFSCObj::d_CNF_str; 00092 Expr LFSCObj::d_cnf_add_unit_str; 00093 Expr LFSCObj::d_minisat_proof_str; 00094 Expr LFSCObj::d_or_final_s; 00095 Expr LFSCObj::d_and_final_s; 00096 Expr LFSCObj::d_ite_s; 00097 Expr LFSCObj::d_iff_s; 00098 Expr LFSCObj::d_imp_s; 00099 Expr LFSCObj::d_or_mid_s; 00100 Expr LFSCObj::d_and_mid_s; 00101 Expr LFSCObj::d_addInequalities_str; 00102 00103 00104 void LFSCObj::initialize( const Expr& pf_expr, int lfscm ) 00105 { 00106 lfsc_mode = lfscm; 00107 cvc3_mimic = lfsc_mode==2 || lfsc_mode==7 || (lfsc_mode>=20 && lfsc_mode <= 29 ); 00108 cvc3_mimic_input = cvc3_mimic; 00109 debug_conv = lfsc_mode%10 == 0; 00110 debug_var = lfsc_mode>10 && ( lfsc_mode%10 == 1 ); 00111 00112 d_pf_expr = pf_expr; 00113 // initialize rules 00114 d_bool_res_str = pf_expr.getEM()->newVarExpr("bool_resolution"); 00115 d_assump_str = pf_expr.getEM()->newVarExpr("assumptions"); 00116 d_iff_mp_str = pf_expr.getEM()->newVarExpr("iff_mp"); 00117 d_impl_mp_str = pf_expr.getEM()->newVarExpr("impl_mp"); 00118 d_iff_trans_str = pf_expr.getEM()->newVarExpr("iff_trans"); 00119 d_real_shadow_str = pf_expr.getEM()->newVarExpr("real_shadow"); 00120 d_cycle_conflict_str = pf_expr.getEM()->newVarExpr("cycleConflict"); 00121 d_real_shadow_eq_str = pf_expr.getEM()->newVarExpr("real_shadow_eq"); 00122 d_basic_subst_op_str = pf_expr.getEM()->newVarExpr("basic_subst_op"); 00123 d_mult_ineqn_str = pf_expr.getEM()->newVarExpr("mult_ineqn"); 00124 d_flip_inequality_str = pf_expr.getEM()->newVarExpr("flip_inequality"); 00125 d_right_minus_left_str = pf_expr.getEM()->newVarExpr("right_minus_left"); 00126 d_eq_trans_str = pf_expr.getEM()->newVarExpr("eq_trans"); 00127 d_eq_symm_str = pf_expr.getEM()->newVarExpr("eq_symm"); 00128 d_canon_plus_str = pf_expr.getEM()->newVarExpr("canon_plus"); 00129 d_refl_str = pf_expr.getEM()->newVarExpr("refl"); 00130 d_cnf_convert_str = pf_expr.getEM()->newVarExpr("cnf_convert"); 00131 d_learned_clause_str = pf_expr.getEM()->newVarExpr("learned_clause"); 00132 d_minus_to_plus_str = pf_expr.getEM()->newVarExpr("minus_to_plus"); 00133 d_plus_predicate_str = pf_expr.getEM()->newVarExpr("plus_predicate"); 00134 d_flip_inequality_str = pf_expr.getEM()->newVarExpr("flip_inequality"); 00135 d_negated_inequality_str = pf_expr.getEM()->newVarExpr("negated_inequality"); 00136 00137 d_iff_true_elim_str = pf_expr.getEM()->newVarExpr("iff_true_elim"); 00138 d_basic_subst_op1_str= pf_expr.getEM()->newVarExpr("basic_subst_op1"); 00139 d_basic_subst_op0_str= pf_expr.getEM()->newVarExpr("basic_subst_op0"); 00140 d_canon_mult_str= pf_expr.getEM()->newVarExpr("canon_mult"); 00141 d_canon_invert_divide_str= pf_expr.getEM()->newVarExpr("canon_invert_divide"); 00142 d_iff_true_str= pf_expr.getEM()->newVarExpr("iff_true"); 00143 d_mult_eqn_str= pf_expr.getEM()->newVarExpr("mult_eqn"); 00144 d_rewrite_eq_symm_str= pf_expr.getEM()->newVarExpr("rewrite_eq_symm"); 00145 d_optimized_subst_op_str= pf_expr.getEM()->newVarExpr("optimized_subst_op"); 00146 d_implyWeakerInequality_str= pf_expr.getEM()->newVarExpr("implyWeakerInequality"); 00147 d_implyWeakerInequalityDiffLogic_str = pf_expr.getEM()->newVarExpr("implyWeakerInequalityDiffLogic"); 00148 d_imp_mp_str= pf_expr.getEM()->newVarExpr("impl_mp"); 00149 d_rewrite_implies_str = pf_expr.getEM()->newVarExpr("rewrite_implies"); 00150 d_rewrite_or_str = pf_expr.getEM()->newVarExpr("rewrite_or"); 00151 d_rewrite_and_str = pf_expr.getEM()->newVarExpr("rewrite_and"); 00152 d_rewrite_iff_symm_str = pf_expr.getEM()->newVarExpr("rewrite_iff_symm"); 00153 d_iff_not_false_str = pf_expr.getEM()->newVarExpr("iff_not_false"); 00154 d_iff_false_str = pf_expr.getEM()->newVarExpr("iff_false"); 00155 d_iff_false_elim_str = pf_expr.getEM()->newVarExpr("iff_false_elim"); 00156 d_not_to_iff_str = pf_expr.getEM()->newVarExpr("not_to_iff"); 00157 d_not_not_elim_str = pf_expr.getEM()->newVarExpr("not_not_elim"); 00158 d_const_predicate_str = pf_expr.getEM()->newVarExpr("const_predicate"); 00159 d_rewrite_not_not_str = pf_expr.getEM()->newVarExpr("rewrite_not_not"); 00160 d_rewrite_not_true_str = pf_expr.getEM()->newVarExpr("rewrite_not_true"); 00161 d_rewrite_not_false_str = pf_expr.getEM()->newVarExpr("rewrite_not_false"); 00162 00163 d_if_lift_rule_str = pf_expr.getEM()->newVarExpr("if_lift_rule"); 00164 d_CNFITE_str = pf_expr.getEM()->newVarExpr("CNFITE"); 00165 d_var_intro_str = pf_expr.getEM()->newVarExpr("var_intro"); 00166 d_int_const_eq_str = pf_expr.getEM()->newVarExpr("int_const_eq"); 00167 d_rewrite_eq_refl_str = pf_expr.getEM()->newVarExpr("rewrite_eq_refl"); 00168 d_iff_symm_str = pf_expr.getEM()->newVarExpr("iff_symm"); 00169 d_rewrite_iff_str = pf_expr.getEM()->newVarExpr("rewrite_iff"); 00170 d_implyNegatedInequality_str = pf_expr.getEM()->newVarExpr("implyNegatedInequality"); 00171 d_uminus_to_mult_str = pf_expr.getEM()->newVarExpr("uminus_to_mult"); 00172 d_lessThan_To_LE_rhs_rwr_str = pf_expr.getEM()->newVarExpr("lessThan_To_LE_rhs_rwr"); 00173 00174 d_CNF_str = pf_expr.getEM()->newVarExpr("CNF"); 00175 d_cnf_add_unit_str = pf_expr.getEM()->newVarExpr("cnf_add_unit"); 00176 d_minisat_proof_str = pf_expr.getEM()->newVarExpr("minisat_proof"); 00177 d_rewrite_ite_same_str = pf_expr.getEM()->newVarExpr("rewrite_ite_same"); 00178 d_andE_str = pf_expr.getEM()->newVarExpr("andE"); 00179 d_implyEqualities_str = pf_expr.getEM()->newVarExpr("implyEqualities"); 00180 d_addInequalities_str = pf_expr.getEM()->newVarExpr("addInequalities"); 00181 00182 //reasons for CNF 00183 d_or_final_s = pf_expr.getEM()->newStringExpr("or_final"); 00184 d_and_final_s = pf_expr.getEM()->newStringExpr("and_final"); 00185 d_ite_s = pf_expr.getEM()->newStringExpr("ite"); 00186 d_iff_s = pf_expr.getEM()->newStringExpr("iff"); 00187 d_imp_s = pf_expr.getEM()->newStringExpr("imp"); 00188 d_or_mid_s = pf_expr.getEM()->newStringExpr("or_mid"); 00189 d_and_mid_s = pf_expr.getEM()->newStringExpr("and_mid"); 00190 00191 // add them to d_rules 00192 d_rules[d_iff_mp_str]=true; 00193 d_rules[d_impl_mp_str]=true; 00194 d_rules[d_iff_trans_str]=true; 00195 d_rules[d_real_shadow_str]=true; 00196 d_rules[d_cycle_conflict_str]=true; 00197 d_rules[d_real_shadow_eq_str]=true; 00198 d_rules[d_basic_subst_op_str]=true; 00199 d_rules[d_mult_ineqn_str]=true; 00200 d_rules[d_flip_inequality_str]=true; 00201 d_rules[d_right_minus_left_str]=true; 00202 d_rules[d_eq_trans_str]=true; 00203 d_rules[d_eq_symm_str]=true; 00204 d_rules[d_canon_plus_str]=true; 00205 d_rules[d_refl_str]=true; 00206 d_rules[d_cnf_convert_str]=true; 00207 d_rules[d_learned_clause_str]=true; 00208 d_rules[d_bool_res_str] = true; 00209 d_rules[d_assump_str] = true; 00210 d_rules[d_minus_to_plus_str] = true; 00211 d_rules[d_minus_to_plus_str] = true; 00212 d_rules[d_plus_predicate_str] = true; 00213 d_rules[d_flip_inequality_str] = true; 00214 d_rules[d_negated_inequality_str] = true; 00215 d_rules[d_iff_true_elim_str] = true; 00216 d_rules[d_basic_subst_op1_str] = true; 00217 d_rules[d_basic_subst_op0_str] = true; 00218 d_rules[d_canon_mult_str] = true; 00219 d_rules[d_canon_invert_divide_str] = true; 00220 d_rules[d_iff_true_str] = true; 00221 d_rules[d_mult_eqn_str] = true; 00222 d_rules[d_rewrite_eq_symm_str] = true; 00223 d_rules[d_optimized_subst_op_str] = true; 00224 d_rules[d_implyWeakerInequality_str] = true; 00225 d_rules[d_implyWeakerInequalityDiffLogic_str] = true; 00226 d_rules[d_imp_mp_str] = true; 00227 d_rules[d_addInequalities_str] = true; 00228 d_rules[d_rewrite_implies_str] = true; 00229 d_rules[d_rewrite_or_str] = true; 00230 d_rules[d_rewrite_and_str] = true; 00231 d_rules[d_rewrite_iff_symm_str] = true; 00232 d_rules[d_iff_not_false_str] = true; 00233 d_rules[d_iff_false_str] = true; 00234 d_rules[d_iff_false_elim_str] = true; 00235 d_rules[d_not_to_iff_str] = true; 00236 d_rules[d_not_not_elim_str] = true; 00237 d_rules[d_const_predicate_str] = true; 00238 d_rules[d_rewrite_not_not_str] = true; 00239 d_rules[d_rewrite_not_true_str] = true; 00240 d_rules[d_rewrite_not_false_str] = true; 00241 00242 d_rules[d_if_lift_rule_str] = true; 00243 d_rules[d_CNFITE_str] = true; 00244 d_rules[d_var_intro_str] = true; 00245 d_rules[d_int_const_eq_str] = true; 00246 d_rules[d_rewrite_eq_refl_str] = true; 00247 d_rules[d_iff_symm_str] = true; 00248 d_rules[d_rewrite_iff_str] = true; 00249 d_rules[d_implyNegatedInequality_str] = true; 00250 d_rules[d_uminus_to_mult_str] = true; 00251 d_rules[d_lessThan_To_LE_rhs_rwr_str] = true; 00252 00253 d_rules[d_CNF_str] = true; 00254 d_rules[d_cnf_add_unit_str] = true; 00255 d_rules[d_minisat_proof_str] = true; 00256 00257 d_rules[d_andE_str] = true; 00258 d_rules[d_implyEqualities_str] = true; 00259 d_rules[d_rewrite_ite_same_str] = true; 00260 } 00261 00262 00263 int LFSCObj::getNumNodes( const Expr& pf, bool recount ){ 00264 if( pf.arity()>0 && d_rules[pf[0]] ){ 00265 if( nnode_map.find( pf )==nnode_map.end() ){ 00266 int sum=0; 00267 for( int a=1; a<pf.arity(); a++ ){ 00268 sum += getNumNodes( pf[a], recount ); 00269 } 00270 nnode_map[pf] = sum + 1; 00271 return sum + 1; 00272 }else if( recount ){ 00273 return nnode_map[pf]; 00274 }else{ 00275 return 1; 00276 } 00277 } 00278 return 0; 00279 } 00280 00281 Expr LFSCObj::cascade_expr( const Expr& e ) 00282 { 00283 if( cas_map.find( e ) != cas_map.end() ){ 00284 return cas_map[e]; 00285 }else{ 00286 Expr ce; 00287 if( e.getKind()==SKOLEM_VAR ){ 00288 ce = skolem_vars[e]; 00289 }else if( e.getKind()==ITE ){ 00290 ce = Expr( ITE, cascade_expr( e[0] ), 00291 cascade_expr( e[1] ), 00292 cascade_expr( e[2] ) ); 00293 }else if( e.arity()==1 ){ 00294 ce = Expr( e.getKind(), cascade_expr( e[0] ) ); 00295 }else if( e.arity()>0 ){ 00296 ce = cascade_expr( e[e.arity()-1] ); 00297 for( int a=e.arity()-2; a>=0; a-- ){ 00298 ce = Expr( e.getKind(), cascade_expr( e[a] ), ce ); 00299 } 00300 }else{ 00301 return e; 00302 } 00303 cas_map[e] = ce; 00304 return ce; 00305 } 00306 } 00307 00308 void LFSCObj::define_skolem_vars( const Expr& e ) 00309 { 00310 if( e.arity()>0 && d_rules[ e[0] ] && !temp_visited[e] ) 00311 { 00312 temp_visited[e] = true; 00313 if( e[0] == d_assump_str ) 00314 { 00315 if( e[1].isIff() && e[1][1].isEq() && e[1][1][1].getKind()==SKOLEM_VAR ){ 00316 Expr ce = cascade_expr( e[1][1][0] ); 00317 skolem_vars[ e[1][1][1] ] = ce; 00318 //store it in the tmap 00319 queryT( ce ); 00320 }else{ 00321 Expr ce = cascade_expr( e[1] ); 00322 if( !d_assump_map[ ce ] ){ 00323 ostringstream ose; 00324 ose << "Unexpected non-discharged assumption " << ce; 00325 print_error( ose.str().c_str(), cout ); 00326 } 00327 } 00328 } 00329 if( e[0]!=d_learned_clause_str ){ 00330 for( int a=1; a<e.arity(); a++ ){ 00331 define_skolem_vars( e[a] ); 00332 } 00333 } 00334 } 00335 } 00336 00337 bool LFSCObj::isVar( const Expr& e ) 00338 { 00339 return (e.getKind()==UCONST && d_rules[e]==false); 00340 } 00341 00342 void LFSCObj::collect_vars(const Expr& e,bool readPred){ 00343 if(isVar(e)){ 00344 if( readPred ) 00345 input_preds[e] = true; 00346 else 00347 input_vars[e]=true; 00348 }else{ 00349 readPred = !is_eq_kind( e.getKind() ) && readPred; 00350 for(int a=0; a<e.arity(); a++ ){ 00351 collect_vars( e[a], ( readPred || (e.getKind()==ITE && a==0 ) ) ); 00352 } 00353 } 00354 } 00355 00356 Expr LFSCObj::queryElimNotNot(const Expr& expr) 00357 { 00358 Expr e = expr; 00359 while( e.isNot() && e[0].isNot() ) 00360 e = e[0][0]; 00361 return e; 00362 } 00363 00364 00365 Expr LFSCObj::queryAtomic(const Expr& expr, bool getBase) 00366 { 00367 Expr e = cascade_expr( queryElimNotNot( expr ) ); 00368 if( e.isNot() ){ 00369 if( getBase ){ 00370 return e[0]; 00371 }else{ 00372 if( e[0].isTrue() ){ 00373 e = d_pf_expr.getEM()->falseExpr(); 00374 return e; 00375 }else if( e[0].isFalse() ){ 00376 e = d_pf_expr.getEM()->trueExpr(); 00377 return e; 00378 }else if( is_eq_kind( e[0].getKind() ) ){ 00379 return Expr( get_not( e[0].getKind() ), e[0][1], e[0][0] ); 00380 } 00381 } 00382 } 00383 return e; 00384 } 00385 00386 int LFSCObj::queryM(const Expr& expr, bool add, bool trusted) 00387 { 00388 //cout << "query : " << expr << endl; 00389 bool neg = false; 00390 Expr e = cascade_expr( queryElimNotNot( expr ) ); 00391 if( !trusted ){ 00392 if( e.isNot() ){ 00393 neg = true; 00394 e = e[0]; 00395 } 00396 int val = d_formulas[e]; 00397 if( val==0 && add ) 00398 { 00399 if( !e.isInitialized() ){ 00400 print_error( "WARNING: uninitialized e in query", cout ); 00401 } 00402 d_formulas[e] = formula_i; 00403 val = formula_i; 00404 formula_i++; 00405 } 00406 return val*(neg ? -1 : 1 ); 00407 }else{ 00408 int val = d_trusted[e]; 00409 if( val==0 && add ){ 00410 d_trusted[e] = trusted_i; 00411 val = trusted_i; 00412 trusted_i++; 00413 } 00414 return val; 00415 } 00416 } 00417 00418 int LFSCObj::queryMt(const Expr& expr) 00419 { 00420 Expr ce = cascade_expr( expr ); 00421 if( !can_pnorm( ce ) ){ 00422 ostringstream os; 00423 os << "ERROR: cannot make polynomial normalization for " << ce << std::endl; 00424 print_error( os.str().c_str(), cout ); 00425 } 00426 int val = d_pn[ce]; 00427 if( val==0 ) 00428 { 00429 d_pn[ce] = tnorm_i; 00430 val = tnorm_i; 00431 tnorm_i++; 00432 } 00433 return val; 00434 } 00435 00436 int LFSCObj::queryT( const Expr& e ) 00437 { 00438 Expr ce = cascade_expr( e ); 00439 int val = d_terms[ce]; 00440 if( val==0 ){ 00441 d_terms[ce] = term_i; 00442 val = term_i; 00443 term_i++; 00444 } 00445 return val; 00446 } 00447 00448 bool LFSCObj::getY( const Expr& e, Expr& pe, bool doIff, bool doLogic ) 00449 { 00450 //cout << "getY = " << e << std::endl; 00451 Expr ea = queryAtomic( e ); 00452 if( is_eq_kind( ea.getKind() ) ){ 00453 //must be able to pnorm it 00454 if( can_pnorm( ea[0] ) && can_pnorm( ea[1] ) ){ 00455 if( is_opposite( ea.getKind() ) ){ 00456 pe = Expr( get_normalized( ea.getKind() ), ea[1], ea[0] ); 00457 }else{ 00458 pe = ea; 00459 } 00460 return true; 00461 }else{ 00462 ostringstream ose; 00463 ose << "Can't pnorm " << ea[0] << " " << ea[1] << std::endl; 00464 print_error( ose.str().c_str(), cout ); 00465 } 00466 } 00467 if( doIff ){ 00468 if( e.arity()==2 ) 00469 { 00470 Expr pe1; 00471 Expr pe2; 00472 if ( e.isIff() ){ 00473 if( getY( e[1], pe2, false ) ){ 00474 if( getY( e[0], pe1, false, pe2.getKind()==TRUE_EXPR || pe2.getKind()==FALSE_EXPR ) ){ 00475 if( pe2.getKind()==TRUE_EXPR ){ 00476 pe = pe1; 00477 return true; 00478 }else if( pe1.getKind()==FALSE_EXPR ){ 00479 pe = d_pf_expr.getEM()->trueExpr(); 00480 return true; 00481 } 00482 if( pe1.getKind()==pe2.getKind() ){ 00483 pe = Expr( EQ, Expr( MINUS, pe1[0], pe2[0] ), Expr( MINUS, pe1[1], pe2[1] ) ); 00484 } 00485 return true; 00486 } 00487 } 00488 } 00489 else if( e.isImpl() ){ 00490 if( getY( e[1], pe2, false, false ) ){ 00491 if( getY( e[0], pe1, false, false ) ){ 00492 if( is_comparison( pe1.getKind() ) && is_comparison( pe2.getKind() ) ){ 00493 pe = Expr( pe1.getKind()==GT && pe2.getKind()==GT ? GT : GE, 00494 Expr( MINUS, pe1[0], pe2[0] ), Expr( MINUS, pe1[1], pe2[1] ) ); 00495 } 00496 return true; 00497 } 00498 } 00499 } 00500 } 00501 } 00502 if( doLogic ){ 00503 if( ea.isFalse() ){ 00504 pe = d_pf_expr.getEM()->trueExpr(); 00505 return true; 00506 }else if( ea.isTrue() ){ 00507 pe = ea; 00508 return true; 00509 } 00510 } 00511 return false; 00512 } 00513 00514 bool LFSCObj::isFormula( const Expr& e ) 00515 { 00516 return ( is_eq_kind( e.getKind() ) || e.isAnd() || e.isOr() || e.isImpl() || e.isIff() || e.isFalse() || e.isTrue() || e.isNot() || 00517 ( e.getKind()==ITE && isFormula( e[1] ) ) || ( input_preds.find( e )!=input_preds.end() ) ); 00518 } 00519 00520 bool LFSCObj::can_pnorm( const Expr& e ) 00521 { 00522 if( is_eq_kind( e.getKind() ) ){ 00523 return can_pnorm( e[0] ) && can_pnorm( e[1] ); 00524 }else if( e.getKind()==PLUS || e.getKind()==MINUS || e.getKind()==MULT || e.getKind()==DIVIDE ){ 00525 return can_pnorm( e[0] ) && can_pnorm( e[1] ); 00526 }else if( e.getKind()==UMINUS ){ 00527 return can_pnorm( e[0] ); 00528 }else if( e.isRational() ){ 00529 return true; 00530 }else if( e.getKind()==ITE ){ 00531 queryT( e ); 00532 return true; 00533 }else if( e.isVar() && input_preds.find( e )==input_preds.end() ){ 00534 return true; 00535 } 00536 return false; 00537 } 00538 00539 bool LFSCObj::what_is_proven( const Expr& pf, Expr& pe ) 00540 { 00541 if(pf.arity()>0 ){ 00542 if(d_rules[pf[0]]&&pf[0].getKind()==UCONST){ 00543 if( pf[0] == d_assump_str || pf[0] == d_cnf_add_unit_str || 00544 pf[0]== d_cnf_convert_str || pf[0] == d_iff_true_elim_str ){ 00545 pe = pf[1]; 00546 return true; 00547 } 00548 else if( pf[0] == d_canon_plus_str || pf[0]==d_canon_mult_str ){ 00549 pe = Expr( EQ, pf[1], pf[2] ); 00550 return true; 00551 } 00552 else if( pf[0] == d_canon_invert_divide_str ) 00553 { 00554 Rational r1 = Rational( 1 ); 00555 Expr er1 = d_pf_expr.getEM()->newRatExpr( pf[1][0].getRational() ); 00556 Expr er2 = d_pf_expr.getEM()->newRatExpr( r1/pf[1][1].getRational() ); 00557 pe = Expr( EQ, pf[1], Expr( MULT, er1, er2 ) ); 00558 return true; 00559 } 00560 else if( pf[0] == d_iff_trans_str ) 00561 { 00562 pe = Expr( IFF, pf[1], pf[3] ); 00563 return true; 00564 } 00565 else if( pf[0] == d_iff_mp_str || pf[0] == d_impl_mp_str) 00566 { 00567 pe = pf[2]; 00568 return true; 00569 } 00570 else if( pf[0] == d_eq_trans_str ) 00571 { 00572 pe = Expr( EQ, pf[2], pf[4] ); 00573 return true; 00574 } 00575 else if( pf[0] == d_eq_symm_str ) 00576 { 00577 pe = Expr( EQ, pf[3], pf[2] ); 00578 return true; 00579 } 00580 else if( pf[0] == d_basic_subst_op_str || pf[0] == d_rewrite_and_str || 00581 pf[0] == d_rewrite_or_str || pf[0] == d_lessThan_To_LE_rhs_rwr_str || 00582 pf[0] == d_mult_ineqn_str || pf[0] == d_plus_predicate_str || 00583 pf[0] == d_flip_inequality_str || pf[0] == d_int_const_eq_str || 00584 pf[0] == d_const_predicate_str ) 00585 { 00586 pe = Expr( IFF, pf[1], pf[2] ); 00587 return true; 00588 } 00589 else if (pf[0] == d_iff_symm_str){ 00590 pe = pf[2].iffExpr(pf[1]); 00591 return true; 00592 } 00593 else if( pf[0] == d_basic_subst_op0_str ) 00594 { 00595 if( pf[1].getKind()==UMINUS ){ 00596 pe = Expr( EQ, pf[1], pf[2] ); 00597 return true; 00598 }else if( pf[1].getKind()==NOT ){ 00599 pe = Expr( IFF, pf[1], pf[2] ); 00600 return true; 00601 } 00602 } 00603 else if( pf[0] == d_mult_eqn_str ) 00604 { 00605 pe = Expr( IFF, Expr( EQ, pf[1], pf[2] ), 00606 Expr( EQ, Expr( MULT, pf[1], pf[3] ), Expr( MULT, pf[2], pf[3] ) ) ); 00607 return true; 00608 } 00609 else if( pf[0] == d_real_shadow_str ) 00610 { 00611 pe = Expr( ( pf[1].getKind()==LE && pf[2].getKind()==LE ) ? LE : LT, pf[1][0], pf[2][1] ); 00612 return true; 00613 } 00614 else if(pf[0] == d_real_shadow_eq_str){ 00615 pe = Expr(EQ, pf[2][0], pf[2][1]); 00616 return true; 00617 } 00618 else if( pf[0] == d_optimized_subst_op_str || pf[0] == d_basic_subst_op1_str ) 00619 { 00620 if( pf[1].getKind()==AND || pf[1].getKind()==OR || pf[1].getKind()==IFF || is_eq_kind( pf[1].getKind() ) || 00621 ( pf[1].getKind()==ITE && isFormula( pf[1] ) ) ){ 00622 pe = Expr( IFF, pf[1], pf[2] ); 00623 return true; 00624 }else if( pf[1].getKind()==ITE || pf[1].getKind()==PLUS || pf[1].getKind()==MINUS || pf[1].getKind()==MULT ){ 00625 pe = Expr( EQ, pf[1], pf[2] ); 00626 return true; 00627 } 00628 } 00629 else if( pf[0] == d_andE_str ) 00630 { 00631 pe = pf[2][ pf[1].getRational().getNumerator().getInt() ]; 00632 return true; 00633 } 00634 else if( pf[0] == d_rewrite_implies_str ) 00635 { 00636 Expr e1 = Expr( IMPLIES, pf[1], pf[2] ); 00637 Expr e2 = Expr( NOT, pf[1] ); 00638 Expr e3 = Expr( OR, e2, pf[2] ); 00639 pe = Expr( IFF, e1, e3 ); 00640 return true; 00641 } 00642 else if( pf[0] == d_rewrite_eq_symm_str ) 00643 { 00644 Expr e1 = Expr( EQ, pf[2], pf[3] ); 00645 Expr e2 = Expr( EQ, pf[3], pf[2] ); 00646 pe = Expr( IFF, e1, e2 ); 00647 return true; 00648 } 00649 else if( pf[0] == d_rewrite_iff_symm_str ) 00650 { 00651 Expr e1 = Expr( IFF, pf[1], pf[2] ); 00652 Expr e2 = Expr( IFF, pf[2], pf[1] ); 00653 pe = Expr( IFF, e1, e2 ); 00654 return true; 00655 } 00656 else if( pf[0] == d_rewrite_ite_same_str ) 00657 { 00658 pe = Expr( EQ, Expr( ITE, pf[2], pf[3], pf[3] ), pf[3] ); 00659 return true; 00660 } 00661 else if( pf[0] == d_rewrite_eq_refl_str ) 00662 { 00663 pe = Expr( IFF, Expr( EQ, pf[2], pf[2] ), d_pf_expr.getEM()->trueExpr() ); 00664 return true; 00665 } 00666 else if( pf[0] == d_refl_str ) 00667 { 00668 if( isFormula( pf[1] ) ) 00669 pe = Expr( IFF, pf[1], pf[1] ); 00670 else 00671 pe = Expr( EQ, pf[1], pf[1] ); 00672 return true; 00673 } 00674 else if( pf[0] == d_rewrite_not_not_str ) 00675 { 00676 Expr e1 = Expr( NOT, pf[1] ); 00677 pe = Expr( NOT, e1 ); 00678 return true; 00679 } 00680 else if( pf[0] == d_not_to_iff_str ) 00681 { 00682 pe = Expr( IFF, Expr( NOT, pf[1] ), d_pf_expr.getEM()->falseExpr() ); 00683 return true; 00684 } 00685 else if( pf[0] == d_minus_to_plus_str ) 00686 { 00687 Expr er1 = d_pf_expr.getEM()->newRatExpr( Rational( -1 ) ); 00688 pe = Expr( EQ, Expr( MINUS, pf[1], pf[2] ), Expr( PLUS, pf[1], Expr( MULT, er1, pf[2] ) ) ); 00689 return true; 00690 } 00691 else if( pf[0] == d_right_minus_left_str ) 00692 { 00693 Expr er1 = d_pf_expr.getEM()->newRatExpr( Rational( 0 ) ); 00694 Expr e1 = Expr( pf[1].getKind(), er1, Expr( MINUS, pf[1][1], pf[1][0] ) ); 00695 pe = Expr(IFF, pf[1], e1); 00696 return true; 00697 } 00698 else if( pf[0] == d_negated_inequality_str ) 00699 { 00700 pe = Expr( IFF, pf[1], Expr( get_not( pf[1][0].getKind() ), pf[1][0][0], pf[1][0][1] ) ); 00701 return true; 00702 } 00703 else if( pf[0] == d_iff_false_elim_str ) 00704 { 00705 pe = queryElimNotNot( Expr( NOT, pf[1] ) ); 00706 return true; 00707 } 00708 else if( pf[0] == d_iff_true_str ) 00709 { 00710 pe = Expr( IFF, pf[1], d_pf_expr.getEM()->trueExpr() ); 00711 return true; 00712 } 00713 else if( pf[0] == d_iff_not_false_str ) 00714 { 00715 pe = Expr( IFF, queryElimNotNot( Expr( NOT, pf[1] ) ), d_pf_expr.getEM()->falseExpr() ); 00716 return true; 00717 } 00718 else if( pf[0] == d_uminus_to_mult_str ) 00719 { 00720 Expr er1 = d_pf_expr.getEM()->newRatExpr( Rational( -1 ) ); 00721 pe = Expr( EQ, Expr( UMINUS, pf[1] ), Expr( MULT, er1, pf[1] ) ); 00722 return true; 00723 } 00724 else if( pf[0] == d_rewrite_not_true_str ) 00725 { 00726 pe = Expr( IFF, Expr( NOT, d_pf_expr.getEM()->trueExpr() ), 00727 d_pf_expr.getEM()->falseExpr() ); 00728 return true; 00729 } 00730 else if( pf[0] == d_rewrite_not_false_str ) 00731 { 00732 pe = Expr( IFF, Expr( NOT, d_pf_expr.getEM()->falseExpr() ), 00733 d_pf_expr.getEM()->trueExpr() ); 00734 return true; 00735 } 00736 else if( pf[0] == d_cycle_conflict_str ) 00737 { 00738 pe = d_pf_expr.getEM()->falseExpr(); 00739 return true; 00740 } 00741 else if(pf[0] == d_implyNegatedInequality_str) 00742 { 00743 pe = pf[1].impExpr(pf[3]); 00744 return true; 00745 } 00746 else if(pf[0] == d_implyWeakerInequality_str){ 00747 pe = pf[1].impExpr(pf[2]); 00748 return true; 00749 } 00750 else if( pf[0] == d_rewrite_iff_symm_str ) 00751 { 00752 Expr e1 = Expr( IFF, pf[1], pf[2] ); 00753 Expr e2 = Expr( IFF, pf[2], pf[1] ); 00754 pe = Expr( IFF, e1, e2 ); 00755 return true; 00756 } 00757 else if( pf[0] == d_rewrite_iff_str){ 00758 Expr e = Expr( IFF, pf[1], pf[2]); 00759 Expr e_true = d_pf_expr.getEM()->trueExpr(); 00760 Expr e_false = d_pf_expr.getEM()->falseExpr(); 00761 00762 if(pf[1] == pf[2]){ 00763 pe = e.iffExpr(d_pf_expr.getEM()->trueExpr()); 00764 return true; 00765 } 00766 00767 if(pf[1] == e_true){ 00768 pe = e.iffExpr(e_true); 00769 return true; 00770 } 00771 if(pf[1] == e_false){ 00772 pe = e.iffExpr(e_false); 00773 return true; 00774 } 00775 00776 if(pf[1].isNot() && pf[1][0] == pf[2]){ 00777 pe = e.iffExpr(pf[2].negate()); 00778 return true; 00779 } 00780 00781 if(pf[2] == e_true){ 00782 pe = e.iffExpr(e_true); 00783 return true; 00784 } 00785 00786 if(pf[2] == e_false){ 00787 pe = e.iffExpr(e_false); 00788 return true; 00789 } 00790 00791 if(pf[2].isNot() && pf[2][0] == pf[1]){ 00792 pe = e.iffExpr(pf[1].negate()); 00793 return true; 00794 } 00795 00796 if(pf[1] < pf[2]){ 00797 Expr e_sym = Expr(IFF, pf[2], pf[1]); 00798 pe = e.iffExpr(e_sym); 00799 return true; 00800 } 00801 pe = e.iffExpr(e); 00802 return true; 00803 } 00804 else if(pf[0] == d_implyEqualities_str){ 00805 pe = Expr(AND, pf[1][0]); 00806 return true; 00807 } 00808 } 00809 } 00810 ostringstream ose; 00811 ose << "What_is_proven, unknown: (" << d_rules[pf[0]] << "): " << pf[0]; 00812 print_error( ose.str().c_str(), cout ); 00813 return false; 00814 }