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