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
00030
00031
00032 #define _CVCL_TRUSTED_
00033
00034
00035 #include "array_theorem_producer.h"
00036 #include "theory_array.h"
00037 #include "theory_core.h"
00038
00039
00040 using namespace std;
00041 using namespace CVCL;
00042
00043
00044
00045
00046
00047
00048
00049 ArrayProofRules* TheoryArray::createProofRules() {
00050 return new ArrayTheoremProducer(theoryCore()->getTM());
00051 }
00052
00053
00054
00055
00056
00057
00058
00059 #define CLASS_NAME "CVCL::ArrayTheoremProducer"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 Theorem
00072 ArrayTheoremProducer::rewriteSameStore(const Expr& e, int n)
00073 {
00074 IF_DEBUG(
00075 DebugAssert(e.isEq(), "EQ expected");
00076 Expr e1 = e[0];
00077 int N = 0;
00078 while (isWrite(e1)) { N++; e1 = e1[0]; }
00079 DebugAssert(N == n && n > 0, "Counting error");
00080 DebugAssert(e1 == e[1], "Stores do not match");
00081 )
00082
00083 Assumptions a;
00084 Proof pf;
00085 Expr write_i, write_j, index_i, index_j, hyp, conc, result;
00086 int i, j;
00087
00088 write_i = e[0];
00089 for (i = n-1; i >= 0; --i) {
00090 index_i = write_i[1];
00091
00092
00093
00094 write_j = e[0];
00095 for (j = n - 1; j > i; --j) {
00096 index_j = write_j[1];
00097 Expr hyp2(!((index_i.getType().isBool())?
00098 index_i.iffExpr(index_j) : index_i.eqExpr(index_j)));
00099 if (hyp.isNull()) hyp = hyp2;
00100 else hyp = hyp && hyp2;
00101 write_j = write_j[0];
00102 }
00103 Expr r1(Expr(READ, e[1], index_i));
00104 conc = (r1.getType().isBool())?
00105 r1.iffExpr(write_i[2]) : r1.eqExpr(write_i[2]);
00106 if (!hyp.isNull()) conc = hyp.impExpr(conc);
00107
00108
00109 if (result.isNull()) result = conc;
00110 else result = result && conc;
00111
00112
00113 write_i = write_i[0];
00114 hyp = Expr();
00115 }
00116 if (withProof()) pf = newPf("rewriteSameStore", e);
00117 return newRWTheorem(e, result, a, pf);
00118 }
00119
00120
00121
00122
00123
00124 Theorem
00125 ArrayTheoremProducer::rewriteWriteWrite(const Expr& e)
00126 {
00127 IF_DEBUG(
00128 DebugAssert(e.isEq(), "EQ expected");
00129 DebugAssert(isWrite(e[0]) && isWrite(e[1]),
00130 "Expected WRITE = WRITE");
00131 )
00132 Assumptions a;
00133 Proof pf;
00134 const Expr& left = e[0];
00135 const Expr& right = e[1];
00136 const Expr& store = left[0];
00137 const Expr& index = left[1];
00138 const Expr& value = left[2];
00139 Expr e1 = (store.getType().isBool())?
00140 store.iffExpr(Expr(WRITE, right, index, Expr(READ, store, index)))
00141 : store.eqExpr(Expr(WRITE, right, index, Expr(READ, store, index)));
00142 Expr e2 = (value.getType().isBool()) ?
00143 value.iffExpr(Expr(READ, right, index)) :
00144 value.eqExpr(Expr(READ, right, index));
00145 if (withProof()) pf = newPf("rewriteWriteWrite", e);
00146 return newRWTheorem(e, e1.andExpr(e2), a, pf);
00147 }
00148
00149
00150
00151
00152 Theorem
00153 ArrayTheoremProducer::rewriteReadWrite(const Expr& e)
00154 {
00155 IF_DEBUG(
00156 DebugAssert(isRead(e), "Read expected");
00157 DebugAssert(isWrite(e[0]), "Expected Read(Write)");
00158 )
00159 Assumptions a;
00160 Proof pf;
00161 const Expr& store = e[0][0];
00162 const Expr& index1 = e[0][1];
00163 const Expr& value = e[0][2];
00164 const Expr& index2 = e[1];
00165 Expr indexCond = (index1.getType().isBool())?
00166 index1.iffExpr(index2) : index1.eqExpr(index2);
00167 if (withProof()) pf = newPf("rewriteReadWrite", e);
00168 return newRWTheorem(e, indexCond.iteExpr(value,
00169 Expr(READ, store, index2)), a, pf);
00170 }
00171
00172
00173
00174
00175 Theorem
00176 ArrayTheoremProducer::rewriteRedundantWrite1(const Theorem& v_eq_r,
00177 const Expr& write)
00178 {
00179 DebugAssert(v_eq_r.isRewrite(), "Expected equation");
00180 DebugAssert(isRead(v_eq_r.getRHS()), "Expected Read");
00181 DebugAssert(isWrite(write) && v_eq_r.getRHS()[0] == write[0] &&
00182 v_eq_r.getRHS()[1] == write[1] && v_eq_r.getLHS() == write[2],
00183 "Error in parameters to rewriteRedundantWrite1");
00184 Assumptions a;
00185 Proof pf;
00186 if (withAssumptions()) a = v_eq_r.getAssumptions().copy();
00187 if(withProof()) {
00188 pf = newPf("rewriteRedundantWrite1", write, v_eq_r.getProof());
00189 }
00190 return newRWTheorem(write, write[0], a, pf);
00191 }
00192
00193
00194
00195
00196 Theorem
00197 ArrayTheoremProducer::rewriteRedundantWrite2(const Expr& e)
00198 {
00199 DebugAssert(isWrite(e) && isWrite(e[0]) &&
00200 e[0][1] == e[1],
00201 "Error in parameters to rewriteRedundantWrite2");
00202
00203 Assumptions a;
00204 Proof pf;
00205
00206 if(withProof()) {
00207 pf = newPf("rewriteRedundantWrite2", e);
00208 }
00209
00210 return newRWTheorem(e, Expr(WRITE, e[0][0], e[1], e[2]), a, pf);
00211 }
00212
00213
00214
00215
00216
00217 Theorem
00218 ArrayTheoremProducer::interchangeIndices(const Expr& e)
00219 {
00220 DebugAssert(isWrite(e) && isWrite(e[0]),
00221 "Error in parameters to interchangeIndices");
00222
00223 Assumptions a;
00224 Proof pf;
00225
00226 if(withProof()) {
00227 pf = newPf("interchangeIndices", e);
00228 }
00229
00230 Expr w0 = Expr(WRITE, e[0][0], e[1], e[2]);
00231 Expr indexCond = (e[0][1].getType().isBool())?
00232 e[0][1].iffExpr(e[1]) : e[0][1].eqExpr(e[1]);
00233 Expr w2 = Expr(WRITE, w0, e[0][1], indexCond.iteExpr(e[2], e[0][2]));
00234
00235 return newRWTheorem(e, w2, a, pf);
00236 }
00237
00238 Theorem
00239 ArrayTheoremProducer::readArrayLiteral(const Expr& e) {
00240 if(CHECK_PROOFS) {
00241 CHECK_SOUND(e.getKind() == READ,
00242 "ArrayTheoremProducer::readArrayLiteral("+e.toString()
00243 +"):\n\n expression is not a READ");
00244 }
00245
00246 Expr arrayLit(e[0]);
00247
00248 if (CHECK_PROOFS) {
00249 CHECK_SOUND(arrayLit.isClosure() && arrayLit.getKind()==ARRAY_LITERAL,
00250 "ArrayTheoremProducer::readArrayLiteral("+e.toString()+")");
00251 }
00252
00253 Expr body(arrayLit.getBody());
00254 const vector<Expr>& vars = arrayLit.getVars();
00255
00256 if(CHECK_PROOFS) {
00257 CHECK_SOUND(vars.size() == 1,
00258 "ArrayTheoremProducer::readArrayLiteral("+e.toString()+"):\n"
00259 +"wrong number of bound variables");
00260 }
00261
00262
00263 vector<Expr> ind;
00264 ind.push_back(e[1]);
00265 body = body.substExpr(vars, ind);
00266
00267 Assumptions a;
00268 Proof pf;
00269 if(withProof())
00270 pf = newPf("read_array_literal", e);
00271 return newRWTheorem(e, body, a, pf);
00272 }