records_theorem_producer.cpp

Go to the documentation of this file.
00001 
00002 /*****************************************************************************/
00003 /*!
00004  * \file records_theorem_producer.cpp
00005  * 
00006  * Author: Daniel Wichs
00007  * 
00008  * Created: Jul 22 22:59:07 GMT 2003
00009  *
00010  * <hr>
00011  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 #define _CVCL_TRUSTED_
00030 
00031 #include "records_theorem_producer.h"
00032 #include "theory_records.h"
00033 #include "theory_core.h"
00034 
00035 
00036 using namespace std;
00037 using namespace CVCL;
00038 
00039 
00040 RecordsProofRules* TheoryRecords::createProofRules() {
00041   return new RecordsTheoremProducer(theoryCore()->getTM(), this);
00042 }
00043   
00044 
00045 #define CLASS_NAME "CVCL::RecordsTheoremProducer"
00046 
00047 //! ==> (SELECT (LITERAL  v1 ... vi ...) fi) = vi
00048 Theorem RecordsTheoremProducer::rewriteLitSelect(const Expr &e){
00049   
00050   Assumptions a;
00051   Proof pf;
00052   if(withProof())
00053     pf = newPf("rewrite_record_literal_select", e);
00054 
00055   int index=0;
00056   switch(e.getOpKind())
00057     {
00058     case RECORD_SELECT: {
00059       if(CHECK_PROOFS) {
00060         CHECK_SOUND(e[0].getOpKind()==RECORD,
00061                     "expected RECORD child:\n"
00062                     +e.toString());
00063       } 
00064       index = getFieldIndex(e[0], getField(e));
00065       break;
00066     }
00067     case TUPLE_SELECT: {
00068       if(CHECK_PROOFS) {
00069         CHECK_SOUND(e[0].getOpKind()==TUPLE,
00070                     "expected TUPLE childs:\n"
00071                     +e.toString());
00072       } 
00073       index = getIndex(e);
00074       break;
00075     }
00076     default: {
00077       if(CHECK_PROOFS)
00078         CHECK_SOUND(false, "expected TUPLE_SELECT or RECORD_SELECT kind" 
00079                     + e.toString());
00080     }
00081     } 
00082   if(CHECK_PROOFS) {
00083     CHECK_SOUND(index!=-1 && index<e[0].arity(), 
00084                 "selected field did not appear in literal" + e.toString());
00085   }
00086   return newRWTheorem(e, e[0][index], a, pf);
00087 }
00088 //! ==> (RECORD_SELECT (RECORD_UPDATE r fi vi) fj) = vi
00089 //iff j=i, r.fj otherwise  (and same for tuples)
00090 Theorem RecordsTheoremProducer::rewriteUpdateSelect(const Expr& e) {
00091   Assumptions a;
00092   Proof pf;
00093   switch(e.getOpKind()) {
00094   case RECORD_SELECT: {
00095     if(CHECK_PROOFS)
00096       CHECK_SOUND(e[0].getOpKind() == RECORD_UPDATE,
00097                   "expected RECORD_UPDATE child" + e.toString());
00098     if(withProof())
00099       pf = newPf("rewrite_record_update_and_select", e);
00100     if(getField(e) == getField(e[0]))
00101       return newRWTheorem(e, e[0][1], a, pf);
00102     else
00103       return newRWTheorem(e, recordSelect(e[0][0], getField(e)), a, pf);
00104     break;
00105   }
00106   case TUPLE_SELECT: {
00107     if(CHECK_PROOFS)
00108       CHECK_SOUND(e[0].getOpKind() == TUPLE_UPDATE,
00109                   "expected TUPLE_UPDATE child" + e.toString());
00110     if(withProof())
00111       pf = newPf("rewrite_record_update_and_select", e);
00112     if(getIndex(e) == getIndex(e[0]))
00113       return newRWTheorem(e, e[0][1], a, pf);
00114     else
00115       return newRWTheorem(e, tupleSelect(e[0][0], getIndex(e)), a, pf);
00116     break;
00117   }
00118   default:
00119     if(CHECK_PROOFS)
00120       CHECK_SOUND(false, "expected RECORD_SELECT or TUPLE_SELECT kind"
00121                   + e.toString());
00122     //to avoid warnings
00123     return newRWTheorem(e, e, a, pf);
00124   }
00125   
00126 }
00127 
00128 
00129 //! ==> (RECORD_UPDATE (RECORD (f1 v1) ... (fi vi) ...) fi v') =(RECORD (f1 v1) ... (fi v') ...) and same for tuples.
00130 Theorem RecordsTheoremProducer::rewriteLitUpdate(const Expr& e) {
00131   int index =0;
00132   switch(e.getOpKind()) {
00133   case RECORD_UPDATE: {
00134     if(CHECK_PROOFS)
00135       CHECK_SOUND(e[0].getOpKind() == RECORD,
00136                   "expected a RECORD: e = "+e.toString());
00137     index = getFieldIndex(e[0], getField(e));
00138     break;
00139   }
00140   case TUPLE_UPDATE: {
00141     if(CHECK_PROOFS)
00142       CHECK_SOUND(e[0].getOpKind() == TUPLE,
00143                   "expected a TUPLE: e = "+ e.toString());
00144     index = getIndex(e);
00145     break;
00146   }
00147   default:
00148     if(CHECK_PROOFS)
00149       CHECK_SOUND(false, "expected RECORD_UPDATE or TUPLE_UPDATE kind"
00150                   + e.toString());
00151   }
00152 
00153   vector<Expr> fieldVals= e[0].getKids();
00154   if(CHECK_PROOFS)
00155     CHECK_SOUND(index!=-1 && index<e[0].arity(),
00156                 "update field does not appear in literal"
00157                 + e.toString());
00158   fieldVals[index] = e[1];
00159   Assumptions a;
00160   Proof pf;
00161   if(withProof())
00162     pf= newPf("rewrite record_literal_update", e);
00163   if(e.getOpKind() == RECORD_UPDATE)
00164     return newRWTheorem(e, recordExpr(getFields(e[0]), fieldVals), a, pf);
00165   else
00166     return newRWTheorem(e, tupleExpr(fieldVals), a, pf);
00167 }
00168 
00169 Theorem RecordsTheoremProducer::expandNeq(const Theorem& neqThrm)
00170 {
00171   Expr e = neqThrm.getExpr();
00172   if(CHECK_PROOFS)
00173     CHECK_SOUND(e.getKind() == NOT, "expected not expression" + e.toString());
00174   e=e[0];
00175   Expr e0 = e[0].getType().getExpr() , e1 = e[1].getType().getExpr();
00176   if(CHECK_PROOFS)
00177     {
00178     CHECK_SOUND(e.getKind() == EQ, 
00179                 "equation expression expected \n" + e.toString());
00180     CHECK_SOUND(e0.arity()==e1.arity() && e0.getOpKind() == e1.getOpKind(),
00181                 "equation types mismatch \n" + e.toString());
00182     CHECK_SOUND(e0.getOpKind() == RECORD_TYPE || e0.getOpKind() == TUPLE_TYPE,
00183                 "expected TUPLES or RECORDS \n" + e.toString());
00184     }
00185   std::vector<Expr> orChildren;
00186   for(int i=0; i<e0.arity();i++)
00187   {
00188     Expr lhs, rhs;
00189     switch(e0.getOpKind()) {
00190     case RECORD_TYPE: {
00191       const string& field(getField(e0, i));
00192       DebugAssert(field == getField(e1, i),     
00193                   "equation types mismatch \n" + neqThrm.getExpr().toString());
00194       lhs = recordSelect(e[0], field);
00195       rhs = recordSelect(e[1], field);
00196       break;
00197     }
00198     case TUPLE_TYPE: {
00199       lhs = tupleSelect(e[0], i);
00200       rhs = tupleSelect(e[1], i);
00201       break;
00202       }
00203     default:
00204       DebugAssert(false, "RecordsTheoremProducer::expandNeq: "
00205                   "Type must be TUPLE or RECORD: "+e0.toString());
00206     }
00207     Expr eq = lhs.getType().isBool()? lhs.iffExpr(rhs) : lhs.eqExpr(rhs);
00208     orChildren.push_back(!eq);
00209   }
00210   Assumptions a;
00211   if(withAssumptions())
00212     a=neqThrm.getAssumptions();
00213   Proof pf;
00214   if(withProof())
00215     pf= newPf("rewrite_record_literal_update", e, neqThrm.getProof());
00216   return newTheorem(orExpr(orChildren), a , pf);
00217 }
00218 
00219 Theorem RecordsTheoremProducer::expandEq(const Theorem& eqThrm)
00220 {
00221   Expr lhs(eqThrm.getLHS()), e0 = lhs.getType().getExpr();
00222   Expr rhs(eqThrm.getRHS()), e1 = rhs.getType().getExpr();
00223   if(CHECK_PROOFS)
00224     {
00225     CHECK_SOUND(eqThrm.isRewrite(), 
00226                 "equation expression expected \n"
00227                 + eqThrm.getExpr().toString());
00228     CHECK_SOUND(e0.arity() == e1.arity() && e0.getOpKind() == e1.getOpKind(),
00229                 "equation types mismatch \n" + eqThrm.getExpr().toString());
00230     CHECK_SOUND(e0.getOpKind() == RECORD_TYPE || e0.getOpKind() == TUPLE_TYPE,
00231                 "expected TUPLES or RECORDS \n" + eqThrm.getExpr().toString());
00232     }
00233   std::vector<Expr> andChildren;
00234   for(int i=0; i<e0.arity();i++)
00235   {
00236     Expr lhs1, rhs1;
00237     switch(e0.getOpKind()) {
00238     case RECORD_TYPE: {
00239       const vector<Expr>& fields(getFields(e0));
00240       DebugAssert(fields[i].getString() == getField(e1, i),
00241                   "equation types mismatch \n" + eqThrm.getExpr().toString());
00242       lhs1 = recordSelect(lhs, fields[i].getString());
00243       rhs1 = recordSelect(rhs, fields[i].getString());
00244       break;
00245     }
00246     case TUPLE_TYPE: {
00247       lhs1 = tupleSelect(lhs, i);
00248       rhs1 = tupleSelect(rhs, i);
00249       break;
00250       }
00251     default:
00252       DebugAssert(false, "RecordsTheoremProducer::expandEq(): "
00253                   "Type must be TUPLE or RECORD: "+e0.toString());
00254     }
00255     Expr eq = lhs1.getType().isBool()? lhs1.iffExpr(rhs1) : lhs1.eqExpr(rhs1);
00256     andChildren.push_back(eq);
00257   }
00258   Assumptions a;
00259   if(withAssumptions())
00260     a=eqThrm.getAssumptions();
00261   Proof pf;
00262   if(withProof())
00263     pf= newPf("rewrite record_literal_update",
00264               eqThrm.getExpr(), eqThrm.getProof());
00265   return newTheorem(andExpr(andChildren), a , pf);  
00266 }
00267 
00268 
00269 Theorem RecordsTheoremProducer::expandRecord(const Expr& e) {
00270   Type tp(d_theoryRecords->getBaseType(e));
00271   if(CHECK_PROOFS) {
00272     CHECK_SOUND(isRecordType(tp),
00273                 "expandRecord("+e.toString()+"): not a record type");
00274   }
00275   const vector<Expr>& fields = getFields(tp.getExpr());
00276   vector<Expr> kids;
00277   for(vector<Expr>::const_iterator i=fields.begin(), iend=fields.end();
00278       i!=iend; ++i)
00279     kids.push_back(recordSelect(e, (*i).getString()));
00280   Assumptions a;
00281   Proof pf;
00282   if(withProof()) pf = newPf("expand_record", e);
00283   return newRWTheorem(e, recordExpr(fields, kids), a, pf);
00284 }
00285 
00286 
00287 Theorem RecordsTheoremProducer::expandTuple(const Expr& e) {
00288   Type tp(d_theoryRecords->getBaseType(e));
00289   if(CHECK_PROOFS) {
00290     CHECK_SOUND(tp.getExpr().getOpKind() == TUPLE_TYPE,
00291                 "expandTuple("+e.toString()+"): not a tuple type");
00292   }
00293   int size(tp.arity());
00294   vector<Expr> kids;
00295   for(int i=0; i<size; ++i)
00296     kids.push_back(tupleSelect(e, i));
00297   Assumptions a;
00298   Proof pf;
00299   if(withProof()) pf = newPf("expand_tuple", e);
00300   return newRWTheorem(e, tupleExpr(kids), a, pf);
00301 }

Generated on Thu Apr 13 16:57:32 2006 for CVC Lite by  doxygen 1.4.4