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