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_datatype.h"
00031 #include "datatype_proof_rules.h"
00032 #include "typecheck_exception.h"
00033 #include "parser_exception.h"
00034 #include "smtlib_exception.h"
00035 #include "theory_core.h"
00036 #include "theory_uf.h"
00037 #include "command_line_flags.h"
00038
00039
00040 using namespace std;
00041 using namespace CVCL;
00042
00043
00044
00045
00046
00047
00048
00049 TheoryDatatype::TheoryDatatype(TheoryCore* core)
00050 : Theory(core, "Datatypes"),
00051 d_labels(core->getCM()->getCurrentContext()),
00052 d_facts(core->getCM()->getCurrentContext()),
00053 d_splitters(core->getCM()->getCurrentContext()),
00054 d_splittersIndex(core->getCM()->getCurrentContext(), 0),
00055 d_splitterAsserted(core->getCM()->getCurrentContext(), false),
00056 d_smartSplits(core->getFlags()["dt-smartsplits"].getBool())
00057 {
00058 d_rules = createProofRules();
00059
00060
00061 getEM()->newKind(DATATYPE, "DATATYPE", true);
00062 getEM()->newKind(CONSTRUCTOR, "CONSTRUCTOR");
00063 getEM()->newKind(SELECTOR, "SELECTOR");
00064 getEM()->newKind(TESTER, "TESTER");
00065
00066 vector<int> kinds;
00067 kinds.push_back(DATATYPE);
00068 kinds.push_back(TESTER);
00069 kinds.push_back(CONSTRUCTOR);
00070 kinds.push_back(SELECTOR);
00071
00072 registerTheory(this, kinds);
00073 }
00074
00075
00076 TheoryDatatype::~TheoryDatatype() {
00077 delete d_rules;
00078 }
00079
00080
00081 void TheoryDatatype::instantiate(const Expr& e, const bigunsigned& u)
00082 {
00083 DebugAssert(e.hasFind() && findExpr(e) == e,
00084 "datatype: instantiate: Expected find(e)=e");
00085 if (isConstructor(e)) return;
00086 DebugAssert(u != 0 && (u & (u-1)) == 0,
00087 "datatype: instantiate: Expected single label in u");
00088 DebugAssert(d_datatypes.find(e.getType().getExpr()) != d_datatypes.end(),
00089 "datatype: instantiate: Unexpected type: "+e.getType().toString()
00090 +"\n\n for expression: "+e.toString());
00091 ExprMap<unsigned>& c = d_datatypes[e.getType().getExpr()];
00092 ExprMap<unsigned>::iterator c_it = c.begin(), c_end = c.end();
00093 for (; c_it != c_end; ++c_it) {
00094 if (u & (1 << bigunsigned((*c_it).second))) break;
00095 }
00096 DebugAssert(c_it != c_end,
00097 "datatype: instantiate: couldn't find constructor");
00098 const Expr& cons = (*c_it).first;
00099
00100 if (!cons.isFinite() && !e.isSelected()) return;
00101
00102 Type consType = cons.getType();
00103 if (consType.arity() == 1) {
00104 enqueueFact(d_rules->dummyTheorem(d_facts, e.eqExpr(cons)));
00105 return;
00106 }
00107
00108 vector<Expr> vars;
00109 for (int i = 0; i < consType.arity()-1; ++i) {
00110 vars.push_back(getEM()->newBoundVarExpr(consType[i]));
00111 }
00112 Expr e2 = getEM()->newClosureExpr(EXISTS, vars,
00113 e.eqExpr(Expr(cons.mkOp(), vars)));
00114 enqueueFact(d_rules->dummyTheorem(d_facts, e2));
00115 }
00116
00117
00118 void TheoryDatatype::initializeLabels(const Expr& e, const Type& t)
00119 {
00120 DebugAssert(findExpr(e) == e,
00121 "datatype: initializeLabels: Expected find(e)=e");
00122 DebugAssert(d_datatypes.find(t.getExpr()) != d_datatypes.end(),
00123 "Unknown datatype: "+t.getExpr().toString());
00124 ExprMap<unsigned>& c = d_datatypes[t.getExpr()];
00125 DebugAssert(d_labels.find(e) == d_labels.end(),
00126 "datatype: initializeLabels: expected unlabeled expr");
00127 if (isConstructor(e)) {
00128 Expr cons = getConstructor(e);
00129 DebugAssert(c.find(cons) != c.end(),
00130 "datatype: initializeLabels: Couldn't find constructor "
00131 +cons.toString());
00132 bigunsigned position = c[cons];
00133 d_labels.insert(e,
00134 SmartCDO<bigunsigned>(theoryCore()->getCM()->getCurrentContext(),
00135 1 << position, 0));
00136 }
00137 else {
00138 DebugAssert(c.size() > 0, "No constructors?");
00139 bigunsigned value = (1 << bigunsigned(c.size())) - 1;
00140 d_labels.insert(e,
00141 SmartCDO<bigunsigned>(theoryCore()->getCM()->getCurrentContext(),
00142 value, 0));
00143 if (value == 1) instantiate(e, 1);
00144 else {
00145 if (!d_smartSplits || t.getExpr().isFinite()) d_splitters.push_back(e);
00146 }
00147 }
00148 }
00149
00150
00151 void TheoryDatatype::mergeLabels(const Theorem& thm,
00152 const Expr& e1, const Expr& e2)
00153 {
00154 DebugAssert(e2.hasFind() && findExpr(e2) == e2,
00155 "datatype: mergeLabels: Expected find(e2)=e2");
00156 DebugAssert(d_labels.find(e1) != d_labels.end() &&
00157 d_labels.find(e2) != d_labels.end(),
00158 "mergeLabels: expr is not labeled");
00159 DebugAssert(e1.getType() == e2.getType(), "Expected same type");
00160 bigunsigned u = d_labels[e2].get().get();
00161 bigunsigned uNew = u & d_labels[e1].get().get();
00162 if (u != uNew) {
00163 if (!thm.isNull()) d_facts.push_back(thm);
00164 d_labels[e2].get().set(uNew);
00165 if (uNew == 0)
00166 setInconsistent(d_rules->dummyTheorem(d_facts, falseExpr()));
00167 }
00168 if (uNew != 0 && ((uNew - 1) & uNew) == 0) {
00169 instantiate(e2, uNew);
00170 }
00171 }
00172
00173
00174 void TheoryDatatype::mergeLabels(const Theorem& thm, const Expr& e,
00175 unsigned position, bool positive)
00176 {
00177 DebugAssert(e.hasFind() && findExpr(e) == e,
00178 "datatype: mergeLabels2: Expected find(e)=e");
00179 DebugAssert(d_labels.find(e) != d_labels.end(),
00180 "mergeLabels2: expr is not labeled");
00181 bigunsigned u = d_labels[e].get().get();
00182 bigunsigned uNew = 1 << bigunsigned(position);
00183 if (positive) {
00184 uNew = u & uNew;
00185 if (u == uNew) return;
00186 } else if (u & uNew) uNew = u - uNew;
00187 else return;
00188 d_facts.push_back(thm);
00189 d_labels[e].get().set(uNew);
00190 if (uNew == 0)
00191 setInconsistent(d_rules->dummyTheorem(d_facts, falseExpr()));
00192 else if (((uNew - 1) & uNew) == 0) {
00193 instantiate(e, uNew);
00194 }
00195 }
00196
00197
00198 void TheoryDatatype::addSharedTerm(const Expr& e)
00199 {
00200 if (e.getType().getExpr().getKind() == DATATYPE &&
00201 d_labels.find(e) == d_labels.end()) {
00202 initializeLabels(e, e.getType());
00203 e.addToNotify(this, Expr());
00204 }
00205 }
00206
00207
00208 void TheoryDatatype::assertFact(const Theorem& e)
00209 {
00210 if (!e.isRewrite()) {
00211 const Expr& expr = e.getExpr();
00212 if (expr.getOpKind() == TESTER) {
00213 mergeLabels(e, expr[0],
00214 getConsPos(getConsForTester(expr.getOpExpr())),
00215 true);
00216 }
00217 else if (expr.isNot() && expr[0].getOpKind() == TESTER) {
00218 mergeLabels(e, expr[0][0],
00219 getConsPos(getConsForTester(expr[0].getOpExpr())),
00220 false);
00221 }
00222 }
00223 }
00224
00225
00226 void TheoryDatatype::checkSat(bool fullEffort)
00227 {
00228 bool done = false;
00229 while (!done && d_splittersIndex < d_splitters.size()) {
00230 Expr e = d_splitters[d_splittersIndex];
00231 if ((!d_smartSplits || e.getType().getExpr().isFinite()) &&
00232 findExpr(e) == e) {
00233 DebugAssert(d_labels.find(e) != d_labels.end(),
00234 "checkSat: expr is not labeled");
00235 bigunsigned u = d_labels[e].get().get();
00236 if ((u & (u-1)) != 0) {
00237 done = true;
00238 DebugAssert(!d_splitterAsserted || !fullEffort,
00239 "splitter should have been resolved");
00240 if (!d_splitterAsserted) {
00241 DebugAssert
00242 (d_datatypes.find(e.getType().getExpr()) != d_datatypes.end(),
00243 "datatype: checkSat: Unexpected type: "+e.getType().toString()
00244 +"\n\n for expression: "+e.toString());
00245 ExprMap<unsigned>& c = d_datatypes[e.getType().getExpr()];
00246 ExprMap<unsigned>::iterator c_it = c.begin(), c_end = c.end();
00247 for (; c_it != c_end; ++c_it) {
00248 if (u & (1 << bigunsigned((*c_it).second))) break;
00249 }
00250 DebugAssert(c_it != c_end,
00251 "datatype: checkSat: couldn't find constructor");
00252 addSplitter(datatypeTestExpr((*c_it).first.getName(), e));
00253 d_splitterAsserted = true;
00254 }
00255 }
00256 }
00257 if (d_smartSplits && !done && isSelector(e)) {
00258 Expr f = findExpr(e[0]);
00259 DebugAssert(d_labels.find(f) != d_labels.end(),
00260 "checkSat: expr is not labeled");
00261 bigunsigned u = d_labels[f].get().get();
00262 if ((u & (u-1)) != 0) {
00263 pair<Expr, unsigned> selectorInfo = getSelectorInfo(e.getOpExpr());
00264 bigunsigned pos = getConsPos(selectorInfo.first);
00265 if (u & (1 << pos)) {
00266 done = true;
00267 DebugAssert(!d_splitterAsserted || !fullEffort,
00268 "splitter should have been resolved");
00269 if (!d_splitterAsserted) {
00270 addSplitter(datatypeTestExpr(selectorInfo.first.getName(), f));
00271 d_splitterAsserted = true;
00272 }
00273 }
00274 }
00275 }
00276 if (!done) {
00277 d_splitterAsserted = false;
00278 d_splittersIndex = d_splittersIndex + 1;
00279 }
00280 }
00281 }
00282
00283
00284 Theorem TheoryDatatype::rewrite(const Expr& e)
00285 {
00286
00287 Theorem thm;
00288 if (isSelector(e)) {
00289 if (canCollapse(e)) {
00290 thm = d_rules->rewriteSelCons(d_facts, e);
00291 return transitivityRule(thm, simplify(thm.getRHS()));
00292 }
00293 }
00294 else if (isTester(e)) {
00295 if (isConstructor(e[0])) {
00296 return d_rules->rewriteTestCons(e);
00297 }
00298 }
00299 return reflexivityRule(e);
00300 }
00301
00302
00303 void TheoryDatatype::setup(const Expr& e)
00304 {
00305 if (e.getType().getExpr().getKind() == DATATYPE &&
00306 d_labels.find(e) == d_labels.end()) {
00307 initializeLabels(e, e.getType());
00308 e.addToNotify(this, Expr());
00309 }
00310 if (e.getKind() != APPLY) return;
00311 if (isConstructor(e) && e.arity() > 0) {
00312 enqueueFact(d_rules->noCycle(e));
00313 }
00314 if (isSelector(e)) {
00315 if (d_smartSplits) d_splitters.push_back(e);
00316 e[0].setSelected();
00317 mergeLabels(Theorem(), e[0], e[0]);
00318 }
00319 setupCC(e);
00320 }
00321
00322
00323 void TheoryDatatype::update(const Theorem& e, const Expr& d)
00324 {
00325 if (d.isNull()) {
00326 const Expr& lhs = e.getLHS();
00327 const Expr& rhs = e.getRHS();
00328 if (isConstructor(lhs) && isConstructor(rhs) &&
00329 lhs.isApply() && rhs.isApply() &&
00330 lhs.getOpExpr() == rhs.getOpExpr()) {
00331 enqueueFact(d_rules->decompose(e));
00332 }
00333 else {
00334 Theorem thm(e);
00335 if (lhs.isSelected() && !rhs.isSelected()) {
00336 d_facts.push_back(e);
00337 rhs.setSelected();
00338 thm = Theorem();
00339 }
00340 mergeLabels(thm, lhs, rhs);
00341 }
00342 }
00343 else {
00344 const Theorem& dEQdsig = d.getSig();
00345 if (!dEQdsig.isNull()) {
00346 const Expr& dsig = dEQdsig.getRHS();
00347 Theorem thm = updateHelper(d);
00348 const Expr& sigNew = thm.getRHS();
00349 if (sigNew == dsig) return;
00350 dsig.setRep(Theorem());
00351 if (isSelector(sigNew) && canCollapse(sigNew)) {
00352 d.setSig(Theorem());
00353 enqueueFact(transitivityRule(thm, d_rules->rewriteSelCons(d_facts, sigNew)));
00354 }
00355 else if (isTester(sigNew) && isConstructor(sigNew[0])) {
00356 d.setSig(Theorem());
00357 enqueueFact(transitivityRule(thm, d_rules->rewriteTestCons(sigNew)));
00358 }
00359 else {
00360 const Theorem& repEQsigNew = sigNew.getRep();
00361 if (!repEQsigNew.isNull()) {
00362 d.setSig(Theorem());
00363 enqueueFact(transitivityRule(repEQsigNew, symmetryRule(thm)));
00364 }
00365 else {
00366 int k, ar(d.arity());
00367 for (k = 0; k < ar; ++k) {
00368 if (sigNew[k] != dsig[k]) {
00369 sigNew[k].addToNotify(this, d);
00370 }
00371 }
00372 d.setSig(thm);
00373 sigNew.setRep(thm);
00374 }
00375 }
00376 }
00377 }
00378 }
00379
00380
00381 Theorem TheoryDatatype::solve(const Theorem& e)
00382 {
00383 DebugAssert(e.isRewrite() && e.getLHS().isTerm(), "Expected equality");
00384 const Expr& lhs = e.getLHS();
00385 if (isConstructor(lhs) && !isConstructor(e.getRHS())) {
00386 return symmetryRule(e);
00387 }
00388 return e;
00389 }
00390
00391
00392 void TheoryDatatype::checkType(const Expr& e)
00393 {
00394 switch (e.getKind()) {
00395 case DATATYPE: {
00396 if (e.arity() != 1 || !e[0].isString())
00397 throw Exception("Ill-formed datatype"+e.toString());
00398 if (resolveID(e[0].getString()) != e)
00399 throw Exception("Unknown datatype"+e.toString());
00400 break;
00401 }
00402 case CONSTRUCTOR:
00403 case SELECTOR:
00404 case TESTER:
00405 throw Exception("Non-type: "+e.toString());
00406 default:
00407 DebugAssert(false, "Unexpected kind in TheoryDatatype::checkType"
00408 +getEM()->getKindName(e.getKind()));
00409 }
00410 }
00411
00412
00413 void TheoryDatatype::computeType(const Expr& e)
00414 {
00415 switch (e.getOpKind()) {
00416 case CONSTRUCTOR:
00417 case SELECTOR:
00418 case TESTER: {
00419 DebugAssert(e.isApply(), "Expected application");
00420 Expr op = e.getOp().getExpr();
00421 Type t = op.lookupType();
00422 DebugAssert(!t.isNull(), "Expected operator to be well-typed");
00423 if (t.getExpr().getKind() == DATATYPE) {
00424 if (e.arity() != 0)
00425 throw TypecheckException("Expected no children: "+e.toString());
00426 e.setType(t);
00427 break;
00428 }
00429 else {
00430 DebugAssert(t.getExpr().getKind() == ARROW, "Expected function type");
00431 if (e.arity() != t.getExpr().arity()-1)
00432 throw TypecheckException("Wrong number of children:\n"+e.toString());
00433 Expr::iterator i = e.begin(), iend = e.end();
00434 Expr::iterator j = t.getExpr().begin();
00435 Expr arg;
00436 for (; i != iend; ++i, ++j) {
00437 arg = getBaseType(*i).getExpr();
00438 if (arg != getBaseType(*j)) {
00439 throw TypecheckException("Type mismatch for expression:\n\n "
00440 + (*i).toString()
00441 + "\n\nhas the following type:\n\n "
00442 + (*i).getType().getExpr().toString()
00443 + "\n\nbut the expected type is:\n\n "
00444 + (*j).toString()
00445 + "\n\nin datatype function application:\n\n "
00446 + e.toString());
00447 }
00448 }
00449 e.setType(*j);
00450 }
00451 break;
00452 }
00453 default:
00454 DebugAssert(false, "Unexpected kind in datatype::computeType: "
00455 +e.toString());
00456 }
00457 }
00458
00459
00460 void TheoryDatatype::computeModelTerm(const Expr& e, std::vector<Expr>& v) {
00461 }
00462
00463
00464
00465 Expr TheoryDatatype::computeTCC(const Expr& e)
00466 {
00467 Expr tcc(Theory::computeTCC(e));
00468 switch (e.getKind()) {
00469 case CONSTRUCTOR:
00470 DebugAssert(e.arity() == 0, "Expected leaf constructor");
00471 return trueExpr();
00472 case APPLY: {
00473 DebugAssert(e.isApply(), "Should be application");
00474 Expr op(e.getOpExpr());
00475 if (op.getKind() != SELECTOR) return tcc;
00476 DebugAssert(e.arity() == 1, "Expected single argument");
00477 const std::pair<Expr,unsigned>& p = getSelectorInfo(op);
00478 Expr tester = datatypeTestExpr(p.first.getName(), e[0]);
00479 return tcc.andExpr(tester);
00480 }
00481 default:
00482 DebugAssert(false,"Unexpected type: "+e.toString());
00483 return trueExpr();
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492 ExprStream& TheoryDatatype::print(ExprStream& os, const Expr& e) {
00493 switch (os.lang()) {
00494 case PRESENTATION_LANG:
00495 switch (e.getKind()) {
00496 case DATATYPE:
00497 if (e.arity() == 1 && e[0].isString()) {
00498 os << e[0].getString();
00499 }
00500 else e.printAST(os);
00501 break;
00502 case APPLY:
00503 os << e.getOpExpr();
00504 if(e.arity() > 0) {
00505 os << "(" << push;
00506 bool first(true);
00507 for (Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
00508 if(first) first = false;
00509 else os << "," << space;
00510 os << *i;
00511 }
00512 os << push << ")";
00513 }
00514 break;
00515 case CONSTRUCTOR:
00516 case SELECTOR:
00517 case TESTER:
00518 DebugAssert(e.isSymbol(), "Expected symbol");
00519 os << e.getName();
00520 break;
00521 default:
00522 DebugAssert(false, "TheoryDatatype::print: Unexpected kind: "
00523 +getEM()->getKindName(e.getKind()));
00524 }
00525 break;
00526 case SMTLIB_LANG:
00527 FatalAssert(false, "Not Implemented Yet");
00528 break;
00529 case LISP_LANG:
00530 FatalAssert(false, "Not Implemented Yet");
00531 break;
00532 default:
00533 e.printAST(os);
00534 break;
00535 }
00536 return os;
00537 }
00538
00539
00540
00541
00542
00543 Expr TheoryDatatype::parseExprOp(const Expr& e)
00544 {
00545
00546
00547 if(RAW_LIST != e.getKind()) return e;
00548
00549 DebugAssert(e.arity() > 0,
00550 "TheoryDatatype::parseExprOp:\n e = "+e.toString());
00551
00552 DebugAssert(e[0].getKind() == ID,
00553 "Expected ID kind for first elem in list expr");
00554
00555 const Expr& c1 = e[0][0];
00556 int kind = getEM()->getKind(c1.getString());
00557 switch(kind) {
00558 case DATATYPE: {
00559 DebugAssert(e.arity() > 1,
00560 "Empty DATATYPE expression\n"
00561 " (expected at least one datatype): "+e.toString());
00562
00563 vector<string> names;
00564 vector<vector<string> > allConstructorNames(e.arity()-1);
00565 vector<vector<vector<string> > > allSelectorNames(e.arity()-1);
00566 vector<vector<vector<Expr> > > allTypes(e.arity()-1);
00567 int i,j,k;
00568 Expr dt, constructor, selectors, selector;
00569
00570
00571 ExprMap<bool> namesMap;
00572 for (i = 0; i < e.arity()-1; ++i) {
00573 dt = e[i+1];
00574 DebugAssert(dt.getKind() == RAW_LIST && dt.arity() == 2,
00575 "Bad formed datatype expression"
00576 +dt.toString());
00577 DebugAssert(dt[0].getKind() == ID,
00578 "Expected ID kind for datatype name"
00579 +dt.toString());
00580 names.push_back(dt[0][0].getString());
00581 if (namesMap.count(dt[0][0]) != 0) {
00582 throw ParserException("Datatype name used more than once"+names.back());
00583 }
00584 namesMap.insert(dt[0][0], true);
00585 }
00586
00587
00588 for (i = 0; i < e.arity()-1; ++i) {
00589 dt = e[i+1];
00590 DebugAssert(dt[1].getKind() == RAW_LIST && dt[1].arity() > 0,
00591 "Expected non-empty list for datatype constructors"
00592 +dt.toString());
00593 dt = dt[1];
00594 vector<string>& constructorNames = allConstructorNames[i];
00595 vector<vector<string> >& selectorNames = allSelectorNames[i];
00596 selectorNames.resize(dt.arity());
00597 vector<vector<Expr> >& types = allTypes[i];
00598 types.resize(dt.arity());
00599
00600
00601 for(j = 0; j < dt.arity(); ++j) {
00602 constructor = dt[j];
00603 DebugAssert(constructor.getKind() == RAW_LIST &&
00604 (constructor.arity() == 1 || constructor.arity() == 2),
00605 "Unexpected constructor"+constructor.toString());
00606 DebugAssert(constructor[0].getKind() == ID,
00607 "Expected ID kind for constructor name"
00608 +constructor.toString());
00609 constructorNames.push_back(constructor[0][0].getString());
00610
00611 if (constructor.arity() == 2) {
00612 selectors = constructor[1];
00613 DebugAssert(selectors.getKind() == RAW_LIST && selectors.arity() > 0,
00614 "Non-empty list expected as second argument of constructor:\n"
00615 +constructor.toString());
00616
00617
00618 for (k = 0; k < selectors.arity(); ++k) {
00619 selector = selectors[k];
00620 DebugAssert(selector.getKind() == RAW_LIST && selector.arity() == 2,
00621 "Expected list of arity 2 for selector"
00622 +selector.toString());
00623 DebugAssert(selector[0].getKind() == ID,
00624 "Expected ID kind for selector name"
00625 +selector.toString());
00626 selectorNames[j].push_back(selector[0][0].getString());
00627 DebugAssert(selector[1].getKind() == ID,
00628 "Expected ID kind for selector type"
00629 +selector.toString());
00630 if (namesMap.count(selector[1][0]) > 0) {
00631 types[j].push_back(selector[1][0]);
00632 }
00633 else {
00634 types[j].push_back(parseExpr(selector[1]));
00635 }
00636 }
00637 }
00638 }
00639 }
00640
00641 vector<Type> returnTypes;
00642 dataType(names, allConstructorNames, allSelectorNames, allTypes,
00643 returnTypes);
00644 return returnTypes[0].getExpr();
00645 }
00646
00647 default: {
00648 throw ParserException("Unexpected datatype expression: "+e.toString());
00649 }
00650 }
00651 return e;
00652 }
00653
00654
00655 Type TheoryDatatype::dataType(const string& name,
00656 const vector<string>& constructors,
00657 const vector<vector<string> >& selectors,
00658 const vector<vector<Expr> >& types)
00659 {
00660 vector<string> names;
00661 vector<vector<string> > constructors2;
00662 vector<vector<vector<string> > > selectors2;
00663 vector<vector<vector<Expr> > > types2;
00664 vector<Type> returnTypes;
00665 names.push_back(name);
00666 constructors2.push_back(constructors);
00667 selectors2.push_back(selectors);
00668 types2.push_back(types);
00669 dataType(names, constructors2, selectors2, types2, returnTypes);
00670 return returnTypes[0];
00671 }
00672
00673
00674
00675
00676 void TheoryDatatype::dataType(const vector<string>& names,
00677 const vector<vector<string> >& allConstructors,
00678 const vector<vector<vector<string> > >& allSelectors,
00679 const vector<vector<vector<Expr> > >& allTypes,
00680 vector<Type>& returnTypes)
00681 {
00682
00683 bool thisWellFounded;
00684
00685 if (names.size() != allConstructors.size() ||
00686 allConstructors.size() != allSelectors.size() ||
00687 allSelectors.size() != allTypes.size()) {
00688 throw TypecheckException
00689 ("dataType: vector sizes don't match");
00690 }
00691
00692 unsigned i, j, k;
00693 Expr e;
00694
00695
00696 vector<Type> funTypeArgs;
00697 funTypeArgs.push_back(Type(getEM()->newLeafExpr(ANY_TYPE)));
00698 funTypeArgs.push_back(Type(getEM()->newLeafExpr(ANY_TYPE)));
00699 Op op = newFunction("_reach_"+names[0],
00700 Type::funType(funTypeArgs, boolType()),
00701 true );
00702 Op reach = getEM()->newSymbolExpr(op.getExpr().getName(),
00703 TRANS_CLOSURE).mkOp();
00704
00705 for (i = 0; i < names.size(); ++i) {
00706 e = resolveID(names[i]);
00707 if (!e.isNull()) {
00708 throw TypecheckException
00709 ("Attempt to define datatype "+names[i]+":\n "
00710 "This variable is already defined.");
00711 }
00712 e = Expr(DATATYPE, getEM()->newStringExpr(names[i]));
00713 installID(names[i], e);
00714 returnTypes.push_back(Type(e));
00715 d_reach[e] = reach;
00716 }
00717
00718 for (i = 0; i < names.size(); ++i) {
00719
00720 const vector<string>& constructors = allConstructors[i];
00721 const vector<vector<string> >& selectors = allSelectors[i];
00722 const vector<vector<Expr> >& types = allTypes[i];
00723
00724 if (constructors.size() == 0) {
00725 throw TypecheckException
00726 ("datatype: "+names[i]+": must have at least one constructor");
00727 }
00728 if (constructors.size() != selectors.size() ||
00729 selectors.size() != types.size()) {
00730 throw TypecheckException
00731 ("dataType: vector sizes at index "+int2string(i)+" don't match");
00732 }
00733
00734 ExprMap<unsigned>& constMap = d_datatypes[returnTypes[i].getExpr()];
00735
00736 for (j = 0; j < constructors.size(); ++j) {
00737 Expr c = resolveID(constructors[j]);
00738 if (!c.isNull()) {
00739 throw TypecheckException
00740 ("Attempt to define datatype constructor "+constructors[j]+":\n "
00741 "This variable is already defined.");
00742 }
00743 c = getEM()->newSymbolExpr(constructors[j], CONSTRUCTOR);
00744
00745 if (selectors[j].size() != types[j].size()) {
00746 throw TypecheckException
00747 ("dataType: constructor at index "+int2string(i)+", "+int2string(j)+
00748 ": number of selectors does not match number of types");
00749 }
00750 thisWellFounded = true;
00751 const vector<string>& sels = selectors[j];
00752 const vector<Expr>& tps = types[j];
00753
00754 vector<Type> selTypes;
00755 Type t;
00756 Expr s;
00757 for (k = 0; k < sels.size(); ++k) {
00758 s = resolveID(sels[k]);
00759 if (!s.isNull()) {
00760 throw TypecheckException
00761 ("Attempt to define datatype selector "+sels[k]+":\n "
00762 "This variable is already defined.");
00763 }
00764 s = getEM()->newSymbolExpr(sels[k], SELECTOR);
00765 if (tps[k].isString()) {
00766 t = Type(resolveID(tps[k].getString()));
00767 if (t.isNull()) {
00768 throw TypecheckException
00769 ("Unable to resolve type identifier: "+tps[k].getString());
00770 }
00771 } else t = Type(tps[k]);
00772 if (t.isBool()) {
00773 throw TypecheckException
00774 ("Cannot have BOOLEAN inside of datatype");
00775 }
00776 else if (t.isFunction()) {
00777 throw TypecheckException
00778 ("Cannot have function inside of datatype");
00779 }
00780
00781 selTypes.push_back(Type(t));
00782 s.setType(returnTypes[i].funType(Type(t)));
00783 if (isDatatype(Type(t)) && !t.getExpr().isWellFounded()) {
00784 thisWellFounded = false;
00785 }
00786 d_selectorMap[s] = pair<Expr,unsigned>(c,k);
00787 installID(sels[k], s);
00788 }
00789 if (thisWellFounded) c.setWellFounded();
00790 if (selTypes.size() == 0) {
00791 c.setType(returnTypes[i]);
00792 c.setFinite();
00793 }
00794 else c.setType(Type::funType(selTypes, returnTypes[i]));
00795 installID(constructors[j], c);
00796 constMap[c] = j;
00797
00798 string testerString = "is_"+constructors[j];
00799 e = resolveID(testerString);
00800 if (!e.isNull()) {
00801 throw TypecheckException
00802 ("Attempt to define datatype tester "+testerString+":\n "
00803 "This variable is already defined.");
00804 }
00805 e = getEM()->newSymbolExpr(testerString, TESTER);
00806 e.setType(returnTypes[i].funType(boolType()));
00807 d_testerMap[e] = c;
00808 installID(testerString, e);
00809 }
00810 }
00811
00812
00813
00814 bool changed, thisFinite;
00815 int firstNotWellFounded;
00816 do {
00817 changed = false;
00818 firstNotWellFounded = -1;
00819 for (i = 0; i < names.size(); ++i) {
00820 ExprMap<unsigned>& c = d_datatypes[returnTypes[i].getExpr()];
00821 ExprMap<unsigned>::iterator c_it = c.begin(), c_end = c.end();
00822 thisWellFounded = false;
00823 thisFinite = true;
00824 for (; c_it != c_end; ++c_it) {
00825 const Expr& cons = (*c_it).first;
00826 Expr funType = cons.getType().getExpr();
00827 int j;
00828 if (!cons.isFinite()) {
00829 for (j = 0; j < funType.arity()-1; ++j) {
00830 if (!isDatatype(funType[j]) || !funType[j].isFinite())
00831 break;
00832 }
00833 if (j == funType.arity()-1) {
00834 changed = true;
00835 cons.setFinite();
00836 }
00837 else thisFinite = false;
00838 }
00839 if (cons.isWellFounded()) {
00840 thisWellFounded = true;
00841 continue;
00842 }
00843 for (j = 0; j < funType.arity()-1; ++j) {
00844 if (isDatatype(funType[j]) && !funType[j].isWellFounded())
00845 break;
00846 }
00847 if (j == funType.arity()-1) {
00848 changed = true;
00849 cons.setWellFounded();
00850 thisWellFounded = true;
00851 }
00852 }
00853 if (!thisWellFounded) {
00854 if (firstNotWellFounded == -1) firstNotWellFounded = i;
00855 }
00856 else {
00857 if (!returnTypes[i].getExpr().isWellFounded()) {
00858 changed = true;
00859 returnTypes[i].getExpr().setWellFounded();
00860 }
00861 }
00862 if (thisFinite && !returnTypes[i].getExpr().isFinite()) {
00863 changed = true;
00864 returnTypes[i].getExpr().setFinite();
00865 }
00866 }
00867 } while (changed);
00868
00869 if (firstNotWellFounded >= 0) {
00870
00871 throw TypecheckException
00872 ("Datatype "+names[firstNotWellFounded]+" has no finite terms");
00873 }
00874
00875 }
00876
00877 Expr TheoryDatatype::datatypeConsExpr(const string& constructor,
00878 const vector<Expr>& args)
00879 {
00880 Expr e = resolveID(constructor);
00881 if (e.isNull())
00882 throw Exception("datatype: unknown constructor: "+constructor);
00883 if (!(e.isSymbol() && e.getKind() == CONSTRUCTOR))
00884 throw Exception("datatype: "+constructor+" resolves to: "+e.toString()+
00885 "\nwhich is not a constructor");
00886 if (args.size() == 0) return e;
00887 return Expr(e.mkOp(), args);
00888 }
00889
00890
00891 Expr TheoryDatatype::datatypeSelExpr(const string& selector, const Expr& arg)
00892 {
00893 Expr e = resolveID(selector);
00894 if (e.isNull())
00895 throw Exception("datatype: unknown selector: "+selector);
00896 if (!(e.isSymbol() && e.getKind() == SELECTOR))
00897 throw Exception("datatype: "+selector+" resolves to: "+e.toString()+
00898 "\nwhich is not a selector");
00899 return Expr(e.mkOp(), arg);
00900 }
00901
00902
00903 Expr TheoryDatatype::datatypeTestExpr(const string& constructor, const Expr& arg)
00904 {
00905 Expr e = resolveID("is_"+constructor);
00906 if (e.isNull())
00907 throw Exception("datatype: unknown tester: is_"+constructor);
00908 if (!(e.isSymbol() && e.getKind() == TESTER))
00909 throw Exception("datatype: is_"+constructor+" resolves to: "+e.toString()+
00910 "\nwhich is not a tester");
00911 return Expr(e.mkOp(), arg);
00912 }
00913
00914
00915 const pair<Expr,unsigned>& TheoryDatatype::getSelectorInfo(const Expr& e)
00916 {
00917 DebugAssert(e.getKind() == SELECTOR, "getSelectorInfo called on non-selector: "
00918 +e.toString());
00919 DebugAssert(d_selectorMap.find(e) != d_selectorMap.end(),
00920 "Unknown selector: "+e.toString());
00921 return d_selectorMap[e];
00922 }
00923
00924
00925 Expr TheoryDatatype::getConsForTester(const Expr& e)
00926 {
00927 DebugAssert(e.getKind() == TESTER,
00928 "getConsForTester called on non-tester"
00929 +e.toString());
00930 DebugAssert(d_testerMap.find(e) != d_testerMap.end(),
00931 "Unknown tester: "+e.toString());
00932 return d_testerMap[e];
00933 }
00934
00935
00936 unsigned TheoryDatatype::getConsPos(const Expr& e)
00937 {
00938 DebugAssert(e.getKind() == CONSTRUCTOR,
00939 "getConsPos called on non-constructor");
00940 Type t = e.getType();
00941 if (t.isFunction()) t = t[t.arity()-1];
00942 DebugAssert(isDatatype(t), "Expected datatype");
00943 DebugAssert(d_datatypes.find(t.getExpr()) != d_datatypes.end(),
00944 "Could not find datatype: "+t.toString());
00945 ExprMap<unsigned>& constMap = d_datatypes[t.getExpr()];
00946 DebugAssert(constMap.find(e) != constMap.end(),
00947 "Could not find constructor: "+e.toString());
00948 return constMap[e];
00949 }
00950
00951
00952 Expr TheoryDatatype::getConstant(const Type& t)
00953 {
00954
00955 if (isDatatype(t)) {
00956 DebugAssert(d_datatypes.find(t.getExpr()) != d_datatypes.end(),
00957 "Unknown datatype: "+t.getExpr().toString());
00958 ExprMap<unsigned>& c = d_datatypes[t.getExpr()];
00959 ExprMap<unsigned>::iterator i = c.begin(), iend = c.end();
00960 for (; i != iend; ++i) {
00961 const Expr& cons = (*i).first;
00962 if (!cons.getType().isFunction()) return cons;
00963 }
00964 for (i = c.begin(), iend = c.end(); i != iend; ++i) {
00965 const Expr& cons = (*i).first;
00966 if (!cons.isWellFounded()) continue;
00967 if (!cons.getType().isFunction()) return cons;
00968 Expr funType = cons.getType().getExpr();
00969 vector<Expr> args;
00970 int j = 0;
00971 for (; j < funType.arity()-1; ++j) {
00972 Type t_j = Type(funType[j]);
00973 if (t_j == t) break;
00974 args.push_back(getConstant(t_j));
00975 }
00976 if (j == funType.arity()-1) return Expr(cons.mkOp(), args);
00977 }
00978 DebugAssert(false, "Couldn't find well-founded constructor for"
00979 +t.toString());
00980 }
00981 DebugAssert(!t.isBool() && !t.isFunction(),
00982 "Expected non-bool, non-function type");
00983 string name = "datatype_"+t.getExpr().toString();
00984 Expr e = resolveID(name);
00985 if (e.isNull()) return newVar(name, t);
00986 return e;
00987 }
00988
00989
00990 const Op& TheoryDatatype::getReachablePredicate(const Type& t)
00991 {
00992 DebugAssert(isDatatype(t), "Expected datatype");
00993 DebugAssert(d_reach.find(t.getExpr()) != d_reach.end(),
00994 "Couldn't find reachable predicate");
00995 return d_reach[t.getExpr()];
00996 }
00997
00998
00999 bool TheoryDatatype::canCollapse(const Expr& e)
01000 {
01001 DebugAssert(isSelector(e), "canCollapse: Selector expression expected");
01002 DebugAssert(e.arity() == 1, "expected arity 1");
01003 if (isConstructor(e[0])) return true;
01004 if (d_labels.find(e[0]) == d_labels.end()) return false;
01005 DebugAssert(e[0].hasFind() && findExpr(e[0]) == e[0],
01006 "canCollapse: Expected find(e[0])=e[0]");
01007 bigunsigned u = d_labels[e[0]].get().get();
01008 Expr cons = getSelectorInfo(e.getOpExpr()).first;
01009 bigunsigned uCons = 1 << bigunsigned(getConsPos(cons));
01010 if ((u & uCons) == 0) return true;
01011 return false;
01012 }