00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
00089
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
00123 return newRWTheorem(e, e, a, pf);
00124 }
00125
00126 }
00127
00128
00129
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 }