CVC3

vc_cmd.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file vc_cmd.cpp
00004  *
00005  * Author: Clark Barrett
00006  *
00007  * Created: Fri Dec 13 22:39:02 2002
00008  *
00009  * <hr>
00010  * License to use, copy, modify, sell and/or distribute this software
00011  * and its documentation for any purpose is hereby granted without
00012  * royalty, subject to the terms and conditions defined in the \ref
00013  * LICENSE file provided with this distribution.
00014  *
00015  * <hr>
00016  *
00017  */
00018 /*****************************************************************************/
00019 
00020 #include <fstream>
00021 #include "vc_cmd.h"
00022 #include "vc.h"
00023 #include "parser.h"
00024 #include "eval_exception.h"
00025 #include "typecheck_exception.h"
00026 #include "command_line_flags.h"
00027 #include "expr_stream.h"
00028 
00029 using namespace std;
00030 using namespace CVC3;
00031 
00032 VCCmd::VCCmd(ValidityChecker* vc, Parser* parser, bool calledFromParser)
00033   : d_vc(vc), d_parser(parser), d_name_of_cur_ctxt("DEFAULT"),
00034     d_calledFromParser(calledFromParser)
00035 {
00036   d_map[d_name_of_cur_ctxt.c_str()] = d_vc->getCurrentContext();
00037 }
00038 
00039 VCCmd::~VCCmd() { }
00040 
00041 void VCCmd::findAxioms(const Expr& e,  ExprMap<bool>& skolemAxioms,
00042            ExprMap<bool>& visited) {
00043   if(visited.count(e)>0)
00044     return;
00045   else visited[e] = true;
00046   if(e.isSkolem()) {
00047     skolemAxioms.insert(e.getExistential(), true);
00048     return;
00049   }
00050   if(e.isClosure()) {
00051     findAxioms(e.getBody(), skolemAxioms, visited);
00052   }
00053   if(e.arity()>0) {
00054     Expr::iterator end = e.end();
00055     for(Expr::iterator i = e.begin(); i!=end; ++i)
00056       findAxioms(*i, skolemAxioms, visited);
00057   }
00058 
00059 }
00060 
00061 Expr VCCmd::skolemizeAx(const Expr& e)
00062 {
00063   vector<Expr>vars;
00064   const vector<Expr>boundVars = e.getVars();
00065   for(unsigned int i=0; i<boundVars.size(); i++) {
00066     Expr skolV(e.skolemExpr(i));
00067     vars.push_back(skolV);
00068   }
00069   Expr sub = e.getBody().substExpr(boundVars, vars);
00070   return e.iffExpr(sub);
00071 }
00072 
00073 bool VCCmd::evaluateNext()
00074 {
00075 readAgain:
00076   if(d_parser->done()) return false; // No more commands
00077   Expr e;
00078   try {
00079     TRACE_MSG("commands", "** [commands] Parsing command...");
00080     e = d_parser->next();
00081     TRACE("commands verbose", "evaluateNext(", e, ")");
00082   }
00083   catch(Exception& e) {
00084     cerr << "*** " << e << endl;
00085     IF_DEBUG(++(debugger.counter("parse errors"));)
00086   }
00087   // The parser may return a Null Expr in case of parse errors or end
00088   // of file.  The right thing to do is to ignore it and repeat
00089   // reading.
00090   if(e.isNull()) {
00091     TRACE_MSG("commands", "** [commands] Null command; read again");
00092     goto readAgain;
00093   }
00094   if( d_vc->getFlags()["parse-only"].getBool() ) {
00095     TRACE_MSG("commands", "** [commands] parse-only; skipping evaluateCommand");
00096     goto readAgain;
00097   }
00098 
00099   return evaluateCommand(e);
00100 }
00101 
00102 void VCCmd::reportResult(QueryResult qres, bool checkingValidity)
00103 {
00104   if (d_vc->getFlags()["printResults"].getBool()) {
00105     if (d_vc->getEM()->getOutputLang() == SMTLIB_LANG
00106         || d_vc->getEM()->getOutputLang() == SMTLIB_V2_LANG) {
00107       switch (qres) {
00108         case VALID:
00109           cout << "unsat" << endl;
00110           break;
00111         case INVALID:
00112           cout << "sat" << endl;
00113           break;
00114         case ABORT:
00115         case UNKNOWN:
00116           cout << "unknown" << endl;
00117           break;
00118         default:
00119           FatalAssert(false, "Unexpected case");
00120       }
00121     }
00122     else {
00123       switch (qres) {
00124         case VALID:
00125           cout << (checkingValidity ? "Valid." : "Unsatisfiable.") << endl;
00126           break;
00127         case INVALID:
00128           cout << (checkingValidity ? "Invalid." : "Satisfiable.") << endl;
00129           break;
00130         case ABORT:
00131           cout << "Unknown: resource limit exhausted." << endl;
00132           break;
00133         case UNKNOWN: {
00134           // Vector of reasons in case of incomplete result
00135           vector<string> reasons;
00136           IF_DEBUG(bool b =) d_vc->incomplete(reasons);
00137           DebugAssert(b, "Expected incompleteness");
00138           cout << "Unknown.\n\n";
00139           cout << "CVC3 was incomplete in this example due to:";
00140           for(vector<string>::iterator i=reasons.begin(), iend=reasons.end();
00141               i!=iend; ++i)
00142             cout << "\n * " << (*i);
00143           cout << endl << endl;
00144           break;
00145         }
00146         default:
00147           FatalAssert(false, "Unexpected case");
00148       }
00149     }
00150     cout << flush;
00151   }
00152   //d_vc->printStatistics();
00153   //  exit(0);
00154 }
00155 
00156 
00157 void VCCmd::printModel()
00158 {
00159   ExprMap<Expr> m;
00160   d_vc->getConcreteModel(m);
00161 
00162   cout << "Current scope level is " << d_vc->scopeLevel() << "." << endl;
00163   ExprMap<Expr>::iterator it = m.begin(), end = m.end();
00164   if(it == end)
00165     cout << " Did not find concrete model for any vars" << endl;
00166   else {
00167     cout << "%Satisfiable  Variable Assignment: % \n";
00168     for(; it!= end; it++) {
00169       Expr eq;
00170       if(it->first.getType().isBool()) {
00171         DebugAssert((it->second).isBoolConst(),
00172                     "Bad variable assignement: e = "+(it->first).toString()
00173                     +"\n\n val = "+(it->second).toString());
00174         if((it->second).isTrue())
00175           eq = it->first;
00176         else
00177           eq = !(it->first);
00178       }
00179       else
00180         eq = (it->first).eqExpr(it->second);
00181       cout << Expr(ASSERT,  eq) << "\n";
00182     }
00183   }
00184 }
00185 
00186 
00187 // For debugging: there are missing cases: user-defined types, symbols inside of quantifiers, etc.
00188 void VCCmd::printSymbols(Expr e, ExprMap<bool>& cache)
00189 {
00190   if (cache.find(e) != cache.end()) return;
00191   switch (e.getKind()) {
00192     case SKOLEM_VAR:
00193     case UCONST: {
00194       cout << e << " : ";
00195       ExprStream os(d_vc->getEM());
00196       os.dagFlag(false);
00197       os << e.getType().getExpr();
00198       cout << ";" << endl;
00199       break;
00200     }
00201     case APPLY: {
00202       Expr op = e.getOpExpr();
00203       if ((op.getKind() == UFUNC) && (cache.find(op) == cache.end())) {
00204         cout << op << " : ";
00205         ExprStream os(d_vc->getEM());
00206         os.dagFlag(false);
00207         os << op.getType().getExpr();
00208         cout << ";" << endl;
00209         cache[op] = true;
00210       }
00211       // fall through
00212     }
00213     default: {
00214       Expr::iterator i = e.begin(), iend = e.end();
00215       for (; i != iend; ++i) {
00216         printSymbols(*i, cache);
00217       }
00218       break;
00219     }
00220   }
00221   cache[e] = true;
00222 }
00223 
00224 
00225 bool debug_skolem = false;
00226 
00227 
00228 void VCCmd::printCounterExample()
00229 {
00230   vector<Expr> assertions;
00231   ExprMap<bool> skolemAxioms;
00232   ExprMap<bool> visited;
00233 
00234   d_vc->getCounterExample(assertions);
00235 
00236   // get variable information
00237   ExprMap<bool> cache;
00238   unsigned i;
00239   for (i = 0; i < assertions.size(); i++) {
00240     printSymbols(assertions[i], cache);
00241   }
00242 
00243   cout << "% Current scope level is " << d_vc->scopeLevel() << "." << endl;
00244   if (assertions.size() == 0) {
00245     cout << "% There are no assertions\n";
00246   } else {
00247 
00248     cout << "% Assertions which make the QUERY invalid:\n";
00249 
00250     for (i = 0; i < assertions.size(); i++) {
00251       cout << Expr(ASSERT, assertions[i]) << "\n";
00252       findAxioms(assertions[i], skolemAxioms, visited);
00253     }
00254 
00255     if (debug_skolem) {
00256       cout << "% Including skolemization axioms:\n";
00257 
00258       ExprMap<bool>::iterator end = skolemAxioms.end();
00259       for(ExprMap<bool>::iterator it = skolemAxioms.begin(); it!=end; it++)
00260         cout << "ASSERT " << skolemizeAx((*it).first) << ";" << endl;
00261     }
00262   }
00263   cout << endl;
00264 }
00265 
00266 
00267 bool VCCmd::evaluateCommand(const Expr& e0)
00268 {
00269   TRACE("commands", "evaluateCommand(", e0.toString(PRESENTATION_LANG), ") {");
00270   Expr e(e0);
00271   if(e.getKind() != RAW_LIST || e.arity() == 0 || e[0].getKind() != ID)
00272     throw EvalException("Invalid command: "+e.toString());
00273   const string& kindName = e[0][0].getString();
00274   int kind = d_vc->getEM()->getKind(kindName);
00275   if(kind == NULL_KIND)
00276     throw EvalException("Unknown command: "+e.toString());
00277   switch(kind) {
00278   case CONST: { // (CONST (id_1 ... id_n) type) or (CONST id type)
00279     if(e.arity() == 3) {
00280       Type t(d_vc->parseExpr(e[2]));
00281       vector<Expr> vars;
00282       if(e[1].getKind() == RAW_LIST)
00283   vars = e[1].getKids();
00284       else
00285   vars.push_back(e[1]);
00286       for(vector<Expr>::iterator i=vars.begin(), iend=vars.end(); i!=iend; ++i) {
00287   if((*i).getKind() != ID)
00288     throw EvalException("Constant name must be an identifier: "
00289             +i->toString());
00290       }
00291       if (t.isFunction()) {
00292   for(vector<Expr>::iterator i=vars.begin(), iend=vars.end();
00293       i!=iend; ++i) {
00294     Op op = d_vc->createOp((*i)[0].getString(), t);
00295     TRACE("commands", "evaluateNext: declare new uninterpreted function: ",
00296     op, "");
00297   }
00298       }
00299       else {
00300   for(vector<Expr>::iterator i=vars.begin(), iend=vars.end();
00301       i!=iend; ++i) {
00302     // Add to variable list
00303     Expr v = d_vc->varExpr((*i)[0].getString(), t);
00304     TRACE_MSG("commands", "** [commands] Declare new variable");
00305     TRACE("commands verbose", "evaluateNext: declare new UCONST: ",
00306     v, "");
00307   }
00308       }
00309     } else if(e.arity() == 4) { // Constant definition (CONST id type def)
00310       TRACE_MSG("commands", "** [commands] Define new constant");
00311       // Set the type for later typechecking
00312       DebugAssert(e[1].getKind() == ID, "Expected ID kind");
00313       Type t(d_vc->parseExpr(e[2]));
00314       Expr def(d_vc->parseExpr(e[3]));
00315 
00316       if(t.isFunction()) {
00317   d_vc->createOp(e[1][0].getString(), t, def);
00318   TRACE("commands verbose", "evaluateNext: define new function: ",
00319         e[1][0].getString(), "");
00320       } else {
00321   d_vc->varExpr(e[1][0].getString(), t, def);
00322   TRACE("commands verbose", "evaluateNext: define new variable: ",
00323         e[1][0].getString(), "");
00324       }
00325     } else
00326       throw EvalException("Wrong number of arguments in CONST: "+e.toString());
00327     break;
00328   }
00329   case DEFUN: { // (DEFUN name ((x y z type1) ... ) resType [ body ])
00330     if(e.arity() != 5 && e.arity() != 4)
00331       throw EvalException
00332   ("DEFUN requires 3 or 4 arguments:"
00333    " (DEFUN f (args) type [ body ]):\n\n  "
00334    +e.toString());
00335     if(e[2].getKind() != RAW_LIST)
00336       throw EvalException
00337   ("2nd argument of DEFUN must be a list of arguments:\n\n  "
00338    +e.toString());
00339 
00340     // Build a CONST declaration and parse it recursively
00341 
00342     // Build the function type
00343     vector<Expr> argTps;
00344     for(Expr::iterator i=e[2].begin(), iend=e[2].end(); i!=iend; ++i) {
00345       if(i->getKind() != RAW_LIST || i->arity() < 2)
00346   throw EvalException
00347     ("DEFUN: bad argument declaration:\n\n  "+i->toString()
00348      +"\n\nIn the following statement:\n\n  "
00349      +e.toString());
00350       Expr tp((*i)[i->arity()-1]);
00351       for(int j=0, jend=i->arity()-1; j<jend; ++j)
00352   argTps.push_back(tp);
00353     }
00354     argTps.push_back(e[3]);
00355     Expr fnType = d_vc->listExpr("ARROW", argTps);
00356     Expr newDecl; // The resulting transformed declaration
00357     if(e.arity() == 5) {
00358       // Build the LAMBDA expression
00359       Expr lambda(d_vc->listExpr("LAMBDA", e[2], e[4]));
00360       // Construct the (CONST name fnType lambda) declaration
00361       newDecl = d_vc->listExpr("CONST", e[1], fnType, lambda);
00362     } else {
00363       newDecl = d_vc->listExpr("CONST", e[1], fnType);
00364     }
00365     // Parse the new declaration
00366     return evaluateCommand(newDecl);
00367     break;
00368   }
00369   case TYPEDEF: {
00370     if (e.arity() == 2) {
00371       // Datatype command
00372       DebugAssert(e.arity() == 2, "Bad TYPEDEF");
00373       Expr res = d_vc->parseExpr(e[1]);
00374       // convert res to vectors
00375 
00376       Expr eNames = res[0];
00377       Expr eCons = res[1];
00378       Expr eSel = res[2];
00379       Expr eTypes = res[3];
00380 
00381       vector<string> names;
00382       vector<vector<string> > constructors(eNames.arity());
00383       vector<vector<vector<string> > > selectors(eNames.arity());
00384       vector<vector<vector<Expr> > > types(eNames.arity());
00385 
00386       int i, j, k;
00387       for (i = 0; i < eNames.arity(); ++i) {
00388         names.push_back(eNames[i].getString());
00389         selectors[i].resize(eSel[i].arity());
00390         types[i].resize(eTypes[i].arity());
00391         for (j = 0; j < eCons[i].arity(); ++j) {
00392           constructors[i].push_back(eCons[i][j].getString());
00393           for (k = 0; k < eSel[i][j].arity(); ++k) {
00394             selectors[i][j].push_back(eSel[i][j][k].getString());
00395             types[i][j].push_back(eTypes[i][j][k]);
00396           }
00397         }
00398       }
00399 
00400       vector<Type> returnTypes;
00401       d_vc->dataType(names, constructors, selectors, types, returnTypes);
00402       break;
00403     }
00404     DebugAssert(e.arity() == 3, "Bad TYPEDEF");
00405     Expr def(d_vc->parseExpr(e[2]));
00406     Type t = d_vc->createType(e[1][0].getString(), def);
00407     TRACE("commands", "evaluateNext: declare new TYPEDEF: ", t, "");
00408   }
00409     break;
00410   case TYPE: {
00411     if(e.arity() < 2)
00412       throw EvalException("Bad TYPE declaration: "+e.toString());
00413     Expr::iterator i=e.begin(), iend=e.end();
00414     ++i; // Skip "TYPE" symbol
00415     for(; i!=iend; ++i) {
00416       if(i->getKind() != ID)
00417   throw EvalException("Type name must be an identifier: "+i->toString());
00418       Type t = d_vc->createType((*i)[0].getString());
00419       TRACE("commands", "evaluateNext: declare new TYPEDECL: ", t, "");
00420     }
00421   }
00422     break;
00423   case ASSERT: {
00424     if(e.arity() != 2)
00425       throw EvalException("ASSERT requires exactly one argument, but is given "
00426         +int2string(e.arity()-1)+":\n "+e.toString());
00427     TRACE_MSG("commands", "** [commands] Asserting formula");
00428     d_vc->assertFormula(d_vc->parseExpr(e[1]));
00429     break;
00430   }
00431   case QUERY: {
00432     if(e.arity() != 2)
00433       throw EvalException("QUERY requires exactly one argument, but is given "
00434         +int2string(e.arity()-1)+":\n "+e.toString());
00435     TRACE_MSG("commands", "** [commands] Query formula");
00436     QueryResult qres = d_vc->query(d_vc->parseExpr(e[1]));
00437     if (qres == UNKNOWN && d_vc->getFlags()["unknown-check-model"].getBool())
00438     qres = d_vc->tryModelGeneration();
00439     reportResult(qres);
00440     if (qres == INVALID) {
00441       if (d_vc->getFlags()["counterexample"].getBool()) {
00442         printCounterExample();
00443       }
00444       if (d_vc->getFlags()["model"].getBool()) {
00445         printModel();
00446       }
00447     }
00448     break;
00449   }
00450   case CHECKSAT: {
00451     QueryResult qres;
00452     TRACE_MSG("commands", "** [commands] CheckSat");
00453     if (e.arity() == 1) {
00454       qres = d_vc->checkUnsat(d_vc->trueExpr());
00455     }
00456     else if (e.arity() == 2) {
00457       qres = d_vc->checkUnsat(d_vc->parseExpr(e[1]));
00458     }
00459     else {
00460       throw EvalException("CHECKSAT requires no more than one argument, but is given "
00461         +int2string(e.arity()-1)+":\n "+e.toString());
00462     }
00463     if (qres == UNKNOWN && !d_vc->getFlags()["translate"].getBool() && d_vc->getFlags()["unknown-check-model"].getBool())
00464       qres = d_vc->tryModelGeneration();
00465     reportResult(qres, false);
00466     if (qres == SATISFIABLE) {
00467       if (d_vc->getFlags()["counterexample"].getBool()) {
00468         printCounterExample();
00469       }
00470       if (d_vc->getFlags()["model"].getBool()) {
00471         printModel();
00472       }
00473     }
00474 //     {//for debug only by yeting
00475 //       Proof p = d_vc->getProof();
00476 //       if (d_vc->getFlags()["printResults"].getBool()) {
00477 //    cout << p << endl;
00478 //    cout << flush;
00479 //       }
00480 //     }
00481 
00482 
00483     break;
00484   }
00485   case CONTINUE: {
00486     if (e.arity() != 1) {
00487       throw EvalException("CONTINUE takes no arguments");
00488     }
00489     TRACE_MSG("commands", "** [commands] Continue");
00490     QueryResult qres = d_vc->checkContinue();
00491     if (d_vc->getFlags()["printResults"].getBool()) {
00492       switch (qres) {
00493         case VALID:
00494           cout << "No more models found." << endl;
00495           break;
00496         case INVALID:
00497           cout << "Model found" << endl;
00498           break;
00499         case ABORT:
00500           cout << "Unknown: resource limit exhausted." << endl;
00501           break;
00502         case UNKNOWN: {
00503           // Vector of reasons in case of incomplete result
00504           vector<string> reasons;
00505           IF_DEBUG(bool b =) d_vc->incomplete(reasons);
00506           DebugAssert(b, "Expected incompleteness");
00507           cout << "Unknown.\n\n";
00508           cout << "CVC3 was incomplete in this example due to:";
00509           for(vector<string>::iterator i=reasons.begin(), iend=reasons.end();
00510               i!=iend; ++i)
00511             cout << "\n * " << (*i);
00512           cout << endl << endl;
00513           break;
00514         }
00515         default:
00516           FatalAssert(false, "Unexpected case");
00517       }
00518       cout << flush;
00519     }
00520     break;
00521   }
00522   case RESTART: {
00523     if(e.arity() != 2)
00524       throw EvalException("RESTART requires exactly one argument, but is given "
00525         +int2string(e.arity()-1)+":\n "+e.toString());
00526     TRACE_MSG("commands", "** [commands] Restart formula");
00527     QueryResult qres = d_vc->restart(d_vc->parseExpr(e[1]));
00528     reportResult(qres);
00529     if (qres == INVALID) {
00530       if (d_vc->getFlags()["counterexample"].getBool()) {
00531         printCounterExample();
00532       }
00533       if (d_vc->getFlags()["model"].getBool()) {
00534         printModel();
00535       }
00536     }
00537     break;
00538   }
00539   case TRANSFORM: {
00540     if(e.arity() != 2)
00541       throw EvalException
00542   ("TRANSFORM requires exactly one argument, but is given "
00543    +int2string(e.arity()-1)+":\n "+e.toString());
00544     TRACE_MSG("commands", "** [commands] Transforming expression");
00545     Expr ee = d_vc->parseExpr(e[1]);
00546     e = d_vc->simplify(ee);
00547     if (d_vc->getFlags()["printResults"].getBool()) d_vc->printExpr(e);
00548     break;
00549   }
00550   case PRINT:
00551     if(e.arity() != 2)
00552       throw EvalException
00553   ("PRINT requires exactly one argument, but is given "
00554    +int2string(e.arity()-1)+":\n "+e.toString());
00555     d_vc->printExpr(d_vc->parseExpr(e[1]));
00556     break;
00557   case PUSH:
00558   case POP:
00559   case PUSH_SCOPE:
00560   case POP_SCOPE: {
00561     int arg;
00562     if (e.arity() == 1) arg = 1;
00563     else {
00564       DebugAssert(e.arity() == 2 && e[1].getKind() == RATIONAL_EXPR,
00565                   "Bad argument to "+kindName);
00566       arg = e[1].getRational().getInt();
00567       if(arg <= 0)
00568         throw EvalException("Argument to PUSH or POP is <= 0");
00569     }
00570     if (kind == PUSH) {
00571       for (int i = 0; i < arg; i++) {
00572         d_vc->push();
00573       }
00574     }
00575     else if (kind == POP) {
00576       if(arg > d_vc->stackLevel())
00577         throw EvalException("Argument to POP is out of range:\n"
00578                             " current stack level = "
00579                             +int2string(d_vc->stackLevel())
00580                             +"\n argument = "
00581                             +int2string(arg));
00582       for (int i = 0; i < arg; i++) {
00583         d_vc->pop();
00584       }
00585     }
00586     else if (kind == PUSH_SCOPE) {
00587       for (int i = 0; i < arg; i++) {
00588         d_vc->pushScope();
00589       }
00590     }
00591     else if (kind == POP_SCOPE) {
00592       if(arg >= d_vc->scopeLevel())
00593         throw EvalException("Argument to POP_SCOPE is out of range:\n"
00594                             " current scope = "
00595                             +int2string(d_vc->scopeLevel())
00596                             +"\n argument = "
00597                             +int2string(arg));
00598       for (int i = 0; i < arg; i++) {
00599         d_vc->popScope();
00600       }
00601     }
00602     break;
00603   }
00604   case POPTO:
00605   case POPTO_SCOPE: {
00606     int arg;
00607     if (e.arity() == 1) arg = 0;
00608     else {
00609       DebugAssert(e.arity() == 2 && e[1].getKind() == RATIONAL_EXPR,
00610                   "Bad argument to "+kindName);
00611       arg = e[1].getRational().getInt();
00612     }
00613     if (kind == POPTO) {
00614       d_vc->popto(arg);
00615     }
00616     else {
00617       d_vc->poptoScope(arg);
00618     }
00619     break;
00620   }
00621   case RESET: {
00622     throw ResetException();
00623     break;
00624   }
00625   case WHERE:
00626   case ASSERTIONS:
00627   case ASSUMPTIONS:
00628   {
00629     vector<Expr> assertions;
00630     ExprMap<bool> skolemAxioms;
00631     ExprMap<bool> visited;
00632 
00633     d_vc->getAssumptions(assertions);
00634 
00635     if (d_vc->getFlags()["printResults"].getBool()) {
00636       cout << "Current stack level is " << d_vc->stackLevel()
00637            << " (scope " << d_vc->scopeLevel() << ")." << endl;
00638       if (assertions.size() == 0) {
00639         cout << "% No active assumptions\n";
00640       } else {
00641         cout << "% Active assumptions:\n";
00642         for (unsigned i = 0; i < assertions.size(); i++) {
00643           cout << "ASSERT " << assertions[i] << ";" << endl;
00644           findAxioms(assertions[i], skolemAxioms, visited);
00645         }
00646         ExprMap<bool>::iterator it = skolemAxioms.begin();
00647         ExprMap<bool>::iterator end = skolemAxioms.end();
00648         if (it != end) {
00649           cout << "% Skolemization axioms" << endl;
00650           for(; it!=end; ++it)
00651             cout << "ASSERT " << skolemizeAx((*it).first) << ";" << endl;
00652         }
00653       }
00654       cout << endl;
00655     }
00656     break;
00657   }
00658   case COUNTEREXAMPLE: {
00659     if (d_vc->getFlags()["printResults"].getBool()) {
00660       printCounterExample();
00661     }
00662     break;
00663   }
00664   case COUNTERMODEL: {
00665     if (d_vc->getFlags()["printResults"].getBool()) {
00666       try {
00667         printModel();
00668       } catch (Exception& e) {
00669         throw EvalException(e.toString());
00670       }
00671     }
00672     break;
00673   }
00674   case TRACE: { // Set a trace flag
00675 #ifdef _CVC3_DEBUG_MODE
00676     if(e.arity() != 2)
00677       throw EvalException("TRACE takes exactly one string argument");
00678     if(!e[1].isString())
00679       throw EvalException("TRACE requires a string argument");
00680     debugger.traceFlag(e[1].getString()) = true;
00681 #endif
00682   }
00683     break;
00684   case UNTRACE: { // Unset a trace flag
00685 #ifdef _CVC3_DEBUG_MODE
00686     if(e.arity() != 2)
00687       throw EvalException("UNTRACE takes exactly one string argument");
00688     if(!e[1].isString())
00689       throw EvalException("UNTRACE requires a string argument");
00690     debugger.traceFlag(e[1].getString()) = false;
00691 #endif
00692   }
00693     break;
00694   case OPTION: {
00695     if(e.arity() != 3)
00696       throw EvalException("OPTION takes exactly two arguments "
00697                           "(name and value of a flag)");
00698     if(!e[1].isString())
00699       throw EvalException("OPTION: flag name must be a string");
00700     CLFlags& flags = d_vc->getFlags();
00701     string name(e[1].getString());
00702     vector<string> names;
00703     size_t n = flags.countFlags(name, names);
00704     if(n != 1)
00705       throw EvalException("OPTION: found "+int2string(n)
00706                           +" flags matching "+name
00707                           +".\nThe flag name must uniquely resolve.");
00708     name = names[0];
00709     const CLFlag& flag(flags[name]);
00710     // If the flag is set on the command line, ignore it
00711     if(flag.modified()) break;
00712     switch(flag.getType()) {
00713     case CLFLAG_BOOL:
00714       if(!(e[2].isRational() && e[2].getRational().isInteger()))
00715         throw EvalException("OPTION: flag "+name
00716                             +" expects a boolean value (0 or 1");
00717       flags.setFlag(name, e[2].getRational().getInt() != 0);
00718       break;
00719     case CLFLAG_INT:
00720       if(!(e[2].isRational() && e[2].getRational().isInteger()))
00721         throw EvalException("OPTION: flag "+name+" expects an integer value");
00722       flags.setFlag(name, e[2].getRational().getInt());
00723       break;
00724     case CLFLAG_STRING:
00725       if(!e[2].isString())
00726         throw EvalException("OPTION: flag "+name+" expects a string value");
00727       flags.setFlag(name, e[2].getString());
00728       break;
00729     default:
00730       throw EvalException("OPTION: the type of flag "+name
00731                           +" is not supported by the OPTION commnand");
00732       break;
00733     }
00734     d_vc->reprocessFlags();
00735   }
00736     break;
00737   case GET_VALUE: {
00738     ExprMap<Expr> m;
00739     d_vc->getConcreteModel(m);
00740 
00741     if (d_vc->getFlags()["printResults"].getBool()) {
00742       cout << "(";
00743     }
00744     for(int i = 0; i < e[1].arity(); ++i) {
00745       Expr res = d_vc->getValue(d_vc->parseExpr(e[1][i]));
00746       if (d_vc->getFlags()["printResults"].getBool()) {
00747         cout << res;
00748         if(i < e[1].arity() - 1) {
00749           cout << endl;
00750         }
00751       }
00752     }
00753     if (d_vc->getFlags()["printResults"].getBool()) {
00754       cout << ")" << endl;
00755     }
00756     break;
00757   }
00758   case GET_ASSIGNMENT: {
00759     ExprMap<Expr> m;
00760     d_vc->getConcreteModel(m);
00761 
00762     Expr res = d_vc->getAssignment();
00763     if (d_vc->getFlags()["printResults"].getBool()) {
00764       cout << res << endl;
00765       cout << flush;
00766     }
00767     break;
00768   }
00769   case DUMP_PROOF: {
00770     Proof p = d_vc->getProof();
00771     if (d_vc->getFlags()["printResults"].getBool()) {
00772       cout << p << endl;
00773       cout << flush;
00774     }
00775     break;
00776   }
00777   case DUMP_ASSUMPTIONS: { // Assumption tracking
00778     vector<Expr> assertions;
00779 
00780     bool b = d_vc->inconsistent(assertions);
00781     DebugAssert(b, "not inconsistent");
00782 
00783     if (d_vc->getFlags()["printResults"].getBool()) {
00784       if(assertions.size() == 0) {
00785         cout << "% No relevant assumptions\n";
00786       } else {
00787         cout << "% Relevant assumptions:\n";
00788         for (unsigned i = 0; i < assertions.size(); i++) {
00789           cout << Expr(ASSERT, assertions[i]) << "\n";
00790         }
00791       }
00792       cout << endl << flush;
00793     }
00794     break;
00795   }
00796   case DUMP_TCC: {
00797     const Expr& tcc = d_vc->getTCC();
00798 
00799     if (d_vc->getFlags()["printResults"].getBool()) {
00800       if(tcc.isNull())
00801         cout << "% No TCC is avaialble" << endl;
00802       else
00803         cout << "% TCC for the last declaration, ASSERT, or QUERY:\n\n"
00804              << tcc << endl;
00805     }
00806     break;
00807   }
00808   case DUMP_TCC_ASSUMPTIONS: {
00809     vector<Expr> assertions;
00810     d_vc->getAssumptionsTCC(assertions);
00811     if (d_vc->getFlags()["printResults"].getBool()) {
00812       if(assertions.size() == 0) {
00813         cout << "% No relevant assumptions\n";
00814       } else {
00815         cout << "% Relevant assumptions for the last TCC:\n";
00816         for (unsigned i = 0; i < assertions.size(); i++) {
00817           cout << Expr(ASSERT, assertions[i]) << "\n";
00818         }
00819       }
00820       cout << endl << flush;
00821     }
00822     break;
00823   }
00824   case DUMP_TCC_PROOF: {
00825     const Proof& tcc = d_vc->getProofTCC();
00826     if (d_vc->getFlags()["printResults"].getBool()) {
00827       if(tcc.isNull())
00828         cout << "% No TCC is avaialble" << endl;
00829       else
00830         cout << "% Proof of TCC for the last declaration, ASSERT, or QUERY:\n\n"
00831              << tcc << endl;
00832     }
00833     break;
00834   }
00835   case DUMP_CLOSURE: {
00836     const Expr& cl = d_vc->getClosure();
00837     if (d_vc->getFlags()["printResults"].getBool()) {
00838       if(cl.isNull())
00839         cout << "% No closure is avaialble" << endl;
00840       else
00841         cout << "% Closure for the last QUERY:\n\n" << cl << endl;
00842     }
00843     break;
00844   }
00845   case DUMP_CLOSURE_PROOF: {
00846     const Proof& cl = d_vc->getProofClosure();
00847     if (d_vc->getFlags()["printResults"].getBool()) {
00848       if(cl.isNull())
00849         cout << "% No closure is avaialble" << endl;
00850       else
00851         cout << "% Proof of closure for the last QUERY:\n\n" << cl << endl;
00852     }
00853     break;
00854   }
00855   case ECHO:
00856     if(e.arity() != 2)
00857       throw EvalException("ECHO: wrong number of arguments: "
00858         + e.toString());
00859     if(!e[1].isString())
00860       throw EvalException("ECHO: the argument must be a string: "
00861         +e.toString());
00862     if (d_vc->getFlags()["printResults"].getBool()) {
00863       cout << e[1].getString();
00864       cout << endl << flush;
00865     }
00866     break;
00867   case SEQ: {
00868     Expr::iterator i=e.begin(), iend=e.end();
00869     ++i; // Skip "SEQ" symbol
00870     bool success = true;
00871     for(; i!=iend; ++i) {
00872       try {
00873         success = success && evaluateCommand(*i);
00874       } catch(ResetException& e) {
00875         if (++i == iend) throw e;
00876         throw EvalException("RESET can only be the last command in a sequence");
00877       }
00878     }
00879     return success;
00880   }
00881   case ARITH_VAR_ORDER: {
00882     if (e.arity() <= 2)
00883       throw EvalException("ARITH_VAR_ORDER takes at least two arguments");
00884     Expr smaller;
00885     Expr bigger = d_vc->parseExpr(e[1]);
00886     for (int i = 2; i < e.arity(); i ++) {
00887       smaller = bigger;
00888       bigger = d_vc->parseExpr(e[i]);
00889       if (!d_vc->addPairToArithOrder(smaller, bigger))
00890         throw EvalException("ARITH_VAR_ORDER only takes arithmetic terms");
00891     }
00892     return true;
00893   }
00894   case ANNOTATION: {
00895     for (int i = 1; i < e.arity(); ++i) {
00896       if (e[i].arity() == 1) {
00897         d_vc->logAnnotation(Expr(ANNOTATION, e[i][0]));
00898       }
00899       else {
00900         DebugAssert(e[i].arity() == 2, "Expected arity 2");
00901         d_vc->logAnnotation(Expr(ANNOTATION, e[i][0], e[i][1]));
00902       }
00903     }
00904     break;
00905   }
00906   case INCLUDE: { // read in the specified file
00907     if(e.arity() != 2)
00908       throw EvalException("INCLUDE takes exactly one string argument");
00909     if(!e[1].isString())
00910       throw EvalException("INCLUDE requires a string argument");
00911     ifstream fs;
00912     fs.open(e[1].getString().c_str(),ios::in);
00913     if(!fs.is_open()) {
00914       fs.close();
00915       throw EvalException("File "+e[1].getString()+" does not exist");
00916     }
00917     fs.close();
00918     d_vc->loadFile(e[1].getString(),
00919                    d_vc->getEM()->getInputLang(),
00920                    d_vc->getFlags()["interactive"].getBool(),
00921                    true /* nested call */);
00922     break;
00923   }
00924   case HELP:
00925     cout << "Use the -help command-line option for help." << endl;
00926     break;
00927   case DUMP_SIG:
00928   case DBG:
00929   case SUBSTITUTE:
00930   case GET_CHILD:
00931   case GET_TYPE:
00932   case CHECK_TYPE:
00933   case FORGET:
00934   case CALL:
00935   default:
00936     throw EvalException("Unknown command: " + e.toString());
00937     break;
00938   }
00939   TRACE_MSG("commands", "evaluateCommand => true }");
00940   return true;
00941 }
00942 
00943 
00944 void VCCmd::processCommands()
00945 {
00946   bool error(false);
00947   try {
00948     bool success(true);
00949     while(success) {
00950       try {
00951         success = evaluateNext();
00952       } catch (ResetException& e) {
00953         if (d_calledFromParser) {
00954           throw EvalException("RESET not supported within INCLUDEd file");
00955         }
00956         d_parser->reset();
00957         d_vc->reset();
00958         success = true;
00959       } catch (EvalException& e) {
00960         error= true;
00961         cerr << "*** Eval Error:\n  " << e << endl;
00962       }
00963     }
00964     
00965   }
00966 
00967   catch(Exception& e) {
00968     cerr << "*** Fatal exception:\n" << e << endl;
00969     error= true;
00970   } catch(...) {
00971     cerr << "*** Unknown fatal exception caught" << endl;
00972     error= true;
00973   } 
00974   
00975   if (error)
00976   {
00977     d_parser->printLocation(cerr);
00978     cerr << ": this is the location of the error" << endl;
00979   }
00980 }