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