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