CVC3

LFSCObject.cpp

Go to the documentation of this file.
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 }