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 #include "theory_simulate.h"
00031 #include "simulate_proof_rules.h"
00032 #include "typecheck_exception.h"
00033 #include "parser_exception.h"
00034 #include "smtlib_exception.h"
00035
00036 #include "theory_arith.h"
00037
00038
00039 using namespace std;
00040 using namespace CVCL;
00041
00042
00043 TheorySimulate::TheorySimulate(TheoryCore* core)
00044 : Theory(core, "Simulate") {
00045
00046 d_rules = createProofRules();
00047
00048 vector<int> kinds;
00049 kinds.push_back(SIMULATE);
00050
00051 registerTheory(this, kinds, false );
00052 }
00053
00054
00055 TheorySimulate::~TheorySimulate() {
00056 delete d_rules;
00057 }
00058
00059
00060 Theorem
00061 TheorySimulate::rewrite(const Expr& e) {
00062 switch (e.getKind()) {
00063 case SIMULATE:
00064 return d_rules->expandSimulate(e);
00065 break;
00066 default:
00067 return reflexivityRule(e);
00068 }
00069 }
00070
00071
00072 void
00073 TheorySimulate::computeType(const Expr& e) {
00074 switch (e.getKind()) {
00075 case SIMULATE: {
00076 const int arity = e.arity();
00077 if (!e[arity - 1].isRational() ||
00078 !e[arity - 1].getRational().isInteger()) {
00079 throw TypecheckException
00080 ("Number of cycles in SIMULATE (last arg) "
00081 "must be an integer constant:\n\n " + e[arity -1].toString()
00082 +"\n\nIn the following expression:\n\n "
00083 +e.toString());
00084 }
00085
00086 const Expr& fn(e[0]);
00087 Type fnType(getBaseType(fn));
00088
00089
00090 if(fnType.arity() != e.arity()-1)
00091 throw TypecheckException
00092 ("Wrong number of arguments in SIMULATE:\n\n"
00093 +e.toString()
00094 +"\n\nExpected "+int2string(fnType.arity()+1)
00095 +" arguments, but received "+int2string(e.arity())+".");
00096
00097 vector<Type> argTp;
00098
00099 Type resType(getBaseType(e[1]));
00100 argTp.push_back(resType);
00101 for(int i=2, iend=e.arity()-1; i<iend; ++i) {
00102 Type iTp(e[i].getType());
00103 Type iTpBase(getBaseType(e[i]));
00104 if(!iTp.isFunction() || iTp.arity() != 2 || !isReal(iTpBase[0]))
00105 throw TypecheckException
00106 ("Type mismatch in SIMULATE:\n\n "
00107 +e.toString()
00108 +"\n\nThe input #"+int2string(i-1)
00109 +" is expected to be of type:\n\n REAL -> <something>"
00110 "\n\nBut the actual type is:\n\n "
00111 +iTp.toString());
00112 argTp.push_back(iTpBase[1]);
00113 }
00114 Type expectedFnType(Type::funType(argTp, resType));
00115 if(fnType != expectedFnType)
00116 throw TypecheckException
00117 ("Type mismatch in SIMULATE:\n\n "
00118 +e.toString()
00119 +"\n\nThe transition function is expected to be of type:\n\n "
00120 +expectedFnType.toString()
00121 +"\n\nBut the actual type is:\n\n "
00122 +fnType.toString());
00123
00124 e.setType(resType);
00125 break;
00126 }
00127 default:
00128 DebugAssert(false,"TheorySimulate::computeType: Unexpected expression: "
00129 +e.toString());
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138 Expr
00139 TheorySimulate::parseExprOp(const Expr& e) {
00140 TRACE("parser", "TheorySimulate::parseExprOp(", e, ")");
00141
00142
00143 if(RAW_LIST != e.getKind()) return e;
00144
00145 DebugAssert(e.arity() > 0,
00146 "TheorySimulate::parseExprOp:\n e = "+e.toString());
00147
00148
00149 const Expr& c1 = e[0][0];
00150 int kind = getEM()->getKind(c1.getString());
00151 switch(kind) {
00152 case SIMULATE: {
00153 vector<Expr> k;
00154 Expr::iterator i = e.begin(), iend=e.end();
00155
00156
00157 ++i;
00158
00159 for(; i!=iend; ++i)
00160 k.push_back(parseExpr(*i));
00161 return Expr(SIMULATE, k, e.getEM());
00162 break;
00163 }
00164 default:
00165 DebugAssert(false, "TheorySimulate::parseExprOp: Unexpected operator: "
00166 +e.toString());
00167 }
00168 return e;
00169 }
00170
00171 Expr
00172 TheorySimulate::computeTCC(const Expr& e) {
00173 switch (e.getKind()) {
00174 case SIMULATE: {
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 vector<Expr> tccs;
00187 Type fnType(e[0].getType());
00188 DebugAssert(fnType.arity() == e.arity()-1,
00189 "TheorySimulate::computeTCC: SIMULATE() doesn't typecheck: "
00190 +e.toString());
00191 Type resType(fnType[fnType.arity()-1]);
00192
00193 if(fnType[0] != resType)
00194 return getEM()->falseExpr();
00195
00196 tccs.push_back(getTypePred(fnType[0], e[1]));
00197
00198 const Rational& N = e[e.arity()-1].getRational();
00199
00200 for(int i=2, iend=e.arity()-1; i<iend; ++i) {
00201 Type iTp(e[i].getType());
00202 DebugAssert(iTp.isFunction() && iTp.arity()==2,
00203 "TheorySimulate::computeTCC: SIMULATE() doesn't typecheck: "
00204 +e.toString());
00205
00206 if(iTp[1] != fnType[i-1])
00207 return getEM()->falseExpr();
00208
00209 for(Rational j=0; j<N; j = j+1)
00210 tccs.push_back(getTypePred(iTp[0], getEM()->newRatExpr(j)));
00211 }
00212 return rewriteAnd(andExpr(tccs)).getRHS();
00213 }
00214 default:
00215 DebugAssert(false, "TheorySimulate::computeTCC("+e.toString()
00216 +")\n\nUnknown expression.");
00217 return getEM()->trueExpr();
00218 }
00219 }
00220
00221
00222 ExprStream&
00223 TheorySimulate::print(ExprStream& os, const Expr& e) {
00224 switch(os.lang()) {
00225 case PRESENTATION_LANG:
00226 switch(e.getKind()) {
00227 case SIMULATE:{
00228 os << "SIMULATE" << "(" << push;
00229 bool first(true);
00230 for (int i = 0; i < e.arity(); i++) {
00231 if (first) first = false;
00232 else os << push << "," << pop << space;
00233 os << e[i];
00234 }
00235 os << push << ")";
00236 break;
00237 }
00238 default:
00239
00240
00241 e.printAST(os);
00242
00243 break;
00244 }
00245 break;
00246 case SMTLIB_LANG:
00247 d_theoryUsed = true;
00248 throw SmtlibException("TheorySimulate::print: SMTLIB not supported");
00249 switch(e.getKind()) {
00250 case SIMULATE:{
00251 os << "(" << push << "SIMULATE" << space;
00252 for (int i = 0; i < e.arity(); i++) {
00253 os << space << e[i];
00254 }
00255 os << push << ")";
00256 break;
00257 }
00258 default:
00259
00260
00261 e.printAST(os);
00262
00263 break;
00264 }
00265 break;
00266 case LISP_LANG:
00267 switch(e.getKind()) {
00268 case SIMULATE:{
00269 os << "(" << push << "SIMULATE" << space;
00270 for (int i = 0; i < e.arity(); i++) {
00271 os << space << e[i];
00272 }
00273 os << push << ")";
00274 break;
00275 }
00276 default:
00277
00278
00279 e.printAST(os);
00280
00281 break;
00282 }
00283 break;
00284 default:
00285 e.printAST(os);
00286 break;
00287 }
00288 return os;
00289 }