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  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00011  * Junior University and by New York University. 
00012  *
00013  * License to use, copy, modify, sell and/or distribute this software
00014  * and its documentation for any purpose is hereby granted without
00015  * royalty, subject to the terms and conditions defined in the \ref
00016  * LICENSE file provided with this distribution.  In particular:
00017  *
00018  * - The above copyright notice and this permission notice must appear
00019  * in all copies of the software and related documentation.
00020  *
00021  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00022  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00023  * 
00024  * <hr>
00025  * 
00026  */
00027 /*****************************************************************************/
00028 
00029 #include "vc_cmd.h"
00030 #include "vc.h"
00031 #include "parser.h"
00032 #include "eval_exception.h"
00033 #include "typecheck_exception.h"
00034 #include "command_line_flags.h"
00035 #include "expr_stream.h"
00036 
00037 using namespace std;
00038 using namespace CVCL;
00039 
00040 VCCmd::VCCmd(ValidityChecker* vc, Parser* parser)
00041   : d_vc(vc), d_parser(parser), d_name_of_cur_ctxt("DEFAULT")
00042 {
00043   d_map[d_name_of_cur_ctxt.c_str()] = d_vc->getCurrentContext();
00044 }
00045 
00046 VCCmd::~VCCmd() { }
00047 
00048 void VCCmd::findAxioms(const Expr& e,  ExprMap<bool>& skolemAxioms,
00049                        ExprMap<bool>& visited) {
00050   if(visited.count(e)>0)
00051     return;
00052   else visited[e] = true;
00053   if(e.isSkolem()) {
00054     skolemAxioms.insert(e.getExistential(), true);
00055     return;
00056   }
00057   if(e.isClosure()) {
00058     findAxioms(e.getBody(), skolemAxioms, visited);
00059   }
00060   if(e.arity()>0) {
00061     Expr::iterator end = e.end();
00062     for(Expr::iterator i = e.begin(); i!=end; ++i)
00063       findAxioms(*i, skolemAxioms, visited);
00064   }
00065   
00066 }
00067 
00068 Expr VCCmd::skolemizeAx(const Expr& e)
00069 {
00070   vector<Expr>vars;
00071   const vector<Expr>boundVars = e.getVars(); 
00072   for(unsigned int i=0; i<boundVars.size(); i++) {
00073     Expr skolV(e.skolemExpr(i));
00074     vars.push_back(skolV);
00075   }
00076   Expr sub = e.getBody().substExpr(boundVars, vars);
00077   return e.iffExpr(sub);
00078 }
00079 
00080 bool VCCmd::evaluateNext() throw(Exception)
00081 {
00082 readAgain:
00083   if(d_parser->done()) return false; // No more commands
00084   Expr e;
00085   try {
00086     TRACE_MSG("commands", "** [commands] Parsing command...");
00087     e = d_parser->next();
00088     TRACE("commands verbose", "evaluateNext(", e, ")");
00089   } 
00090   catch(Exception& e) {
00091     cerr << "*** " << e << endl;
00092     IF_DEBUG(++(debugger.counter("parse errors")));
00093   }
00094   // The parser may return a Null Expr in case of parse errors or end
00095   // of file.  The right thing to do is to ignore it and repeat
00096   // reading.
00097   if(e.isNull()) {
00098     TRACE_MSG("commands", "** [commands] Null command; read again");
00099     goto readAgain;
00100   }
00101 
00102   if(d_vc->getFlags()["reorder"].getBool()
00103      || d_vc->getFlags()["pq"].getBool()){
00104     if(!e.isNull() && e.getKind()!= CONST && e.getKind()!=CONSTDEF
00105        && e.getKind()!=ASSERT && e.getKind()!=QUERY
00106        && e.getKind()!=TYPEDEF && e.getKind()!=TYPEDECL && e.getKind()!=TRANSFORM){
00107       cout << e << ";" << endl;
00108       return true;
00109     }
00110   }
00111   return evaluateCommand(e);
00112 }
00113 
00114 void VCCmd::reportResult(bool ret, bool checkingValidity)
00115 {
00116   if (d_vc->getFlags()["printResults"].getBool()) {
00117     // Vector of reasons in case of incomplete result
00118     vector<string> reasons;
00119     if (ret) cout << (checkingValidity ? "Valid." : "Unsatisfiable.") << endl;
00120     else if(d_vc->incomplete(reasons)) {
00121       cout << "Unknown.\n\n";
00122       cout << "CVC Lite was incomplete in this example due to:";
00123       for(vector<string>::iterator i=reasons.begin(), iend=reasons.end();
00124           i!=iend; ++i)
00125         cout << "\n * " << (*i);
00126       cout << endl << endl;
00127     }
00128     else cout << (checkingValidity ? "Invalid." : "Satisfiable.") << endl;
00129     cout << flush;
00130   }
00131 }
00132 
00133 
00134 bool VCCmd::evaluateCommand(const Expr& e0) throw(Exception)
00135 {
00136   TRACE("commands", "evaluateCommand(", e0, ") {");
00137   Expr e(e0);
00138   if(e.getKind() != RAW_LIST || e.arity() == 0 || e[0].getKind() != ID)
00139     throw EvalException("Invalid command: "+e.toString());
00140   const string& kindName = e[0][0].getString();
00141   int kind = d_vc->getEM()->getKind(kindName);
00142   if(kind == NULL_KIND)
00143     throw EvalException("Unknown command: "+e.toString());
00144   switch(kind) {
00145   case CONST: { // (CONST (id_1 ... id_n) type) or (CONST id type)
00146     if(e.arity() == 3) {
00147       Type t(d_vc->parseExpr(e[2]));
00148       vector<Expr> vars;
00149       if(e[1].getKind() == RAW_LIST)
00150         vars = e[1].getKids();
00151       else
00152         vars.push_back(e[1]);
00153       for(vector<Expr>::iterator i=vars.begin(), iend=vars.end(); i!=iend; ++i) {
00154         if((*i).getKind() != ID)
00155           throw EvalException("Constant name must be an identifier: "
00156                               +i->toString());
00157       }
00158       if (t.isFunction()) {
00159         for(vector<Expr>::iterator i=vars.begin(), iend=vars.end();
00160             i!=iend; ++i) {
00161           Op op = d_vc->createOp((*i)[0].getString(), t);
00162           TRACE("commands", "evaluateNext: declare new uninterpreted function: ",
00163                 op, "");
00164         }
00165       }
00166       else {
00167         for(vector<Expr>::iterator i=vars.begin(), iend=vars.end();
00168             i!=iend; ++i) {
00169           // Add to variable list
00170           Expr v = d_vc->varExpr((*i)[0].getString(), t);
00171           TRACE_MSG("commands", "** [commands] Declare new variable");
00172           TRACE("commands verbose", "evaluateNext: declare new UCONST: ",
00173                 v, "");
00174         }
00175       }
00176     } else if(e.arity() == 4) { // Constant definition (CONST id type def)
00177       TRACE_MSG("commands", "** [commands] Define new constant");
00178       // Set the type for later typechecking
00179       DebugAssert(e[1].getKind() == ID, "Expected ID kind");
00180       Type t(d_vc->parseExpr(e[2]));
00181       Expr def(d_vc->parseExpr(e[3]));
00182       
00183       if(t.isFunction()) {
00184         Op f = d_vc->createOp(e[1][0].getString(), t, def);
00185         TRACE("commands verbose", "evaluateNext: define new function: ",
00186               f, "");
00187       } else {
00188         Expr v = d_vc->varExpr(e[1][0].getString(), t, def);
00189         TRACE("commands verbose", "evaluateNext: define new variable: ",
00190               v, "");
00191       }
00192     } else 
00193       throw EvalException("Wrong number of arguments in CONST: "+e.toString());
00194     break;
00195   }
00196   case DEFUN: { // (DEFUN name ((x y z type1) ... ) resType [ body ])
00197     if(e.arity() != 5 && e.arity() != 4)
00198       throw EvalException
00199         ("DEFUN requires 3 or 4 arguments:"
00200          " (DEFUN f (args) type [ body ]):\n\n  "
00201          +e.toString());
00202     if(e[2].getKind() != RAW_LIST)
00203       throw EvalException
00204         ("2nd argument of DEFUN must be a list of arguments:\n\n  "
00205          +e.toString());
00206 
00207     // Build a CONST declaration and parse it recursively
00208 
00209     // Build the function type
00210     vector<Expr> argTps;
00211     for(Expr::iterator i=e[2].begin(), iend=e[2].end(); i!=iend; ++i) {
00212       if(i->getKind() != RAW_LIST || i->arity() < 2)
00213         throw EvalException
00214           ("DEFUN: bad argument declaration:\n\n  "+i->toString()
00215            +"\n\nIn the following statement:\n\n  "
00216            +e.toString());
00217       Expr tp((*i)[i->arity()-1]);
00218       for(int j=0, jend=i->arity()-1; j<jend; ++j)
00219         argTps.push_back(tp);
00220     }
00221     argTps.push_back(e[3]);
00222     Expr fnType = d_vc->listExpr("ARROW", argTps);
00223     Expr newDecl; // The resulting transformed declaration
00224     if(e.arity() == 5) {
00225       // Build the LAMBDA expression
00226       Expr lambda(d_vc->listExpr("LAMBDA", e[2], e[4]));
00227       // Construct the (CONST name fnType lambda) declaration
00228       newDecl = d_vc->listExpr("CONST", e[1], fnType, lambda);
00229     } else {
00230       newDecl = d_vc->listExpr("CONST", e[1], fnType);
00231     }
00232     // Parse the new declaration
00233     return evaluateCommand(newDecl);
00234     break;
00235   }
00236   case TYPEDEF: {
00237     DebugAssert(e.arity() == 3, "Bad TYPEDEF");
00238     Expr def(d_vc->parseExpr(e[2]));
00239     Type t = d_vc->createType(e[1][0].getString(), def);
00240     TRACE("commands", "evaluateNext: declare new TYPEDEF: ", t, "");
00241   }
00242     break;
00243   case TYPE: {
00244     if(e.arity() < 2)
00245       throw EvalException("Bad TYPE declaration: "+e.toString());
00246     Expr::iterator i=e.begin(), iend=e.end();
00247     ++i; // Skip "TYPE" symbol
00248     for(; i!=iend; ++i) {
00249       if(i->getKind() != ID)
00250         throw EvalException("Type name must be an identifier: "+i->toString());
00251       Type t = d_vc->createType((*i)[0].getString());
00252       TRACE("commands", "evaluateNext: declare new TYPEDECL: ", t, "");
00253     }
00254   }
00255     break;
00256   case ASSERT: {
00257     if(e.arity() != 2)
00258       throw EvalException("ASSERT requires exactly one argument, but is given "
00259                           +int2string(e.arity()-1)+":\n "+e.toString());
00260     if(d_vc->getFlags()["reorder"].getBool()
00261        || d_vc->getFlags()["pq"].getBool()){
00262       cout << "%% Print assertion variables:" << endl;
00263       d_vc->printV(d_vc->parseExpr(e[1]));
00264       cout << "ASSERT ";
00265       d_vc->printExpr(d_vc->parseExpr(e[1]));
00266       cout << ";" << endl;
00267       TRACE_MSG("commands", "evaluateCommand => true}");
00268       return true;
00269     }
00270     TRACE_MSG("commands", "** [commands] Asserting formula");
00271     d_vc->assertFormula(d_vc->parseExpr(e[1]));
00272     break;
00273   }
00274   case QUERY: {
00275     if(e.arity() != 2)
00276       throw EvalException("QUERY requires exactly one argument, but is given "
00277                           +int2string(e.arity()-1)+":\n "+e.toString());
00278     TRACE_MSG("commands", "** [commands] Query formula");
00279     bool ret = d_vc->query(d_vc->parseExpr(e[1]));
00280 
00281     reportResult(ret);
00282     break;
00283   }
00284   case CHECKSAT: {
00285     bool ret;
00286     TRACE_MSG("commands", "** [commands] CheckSat");
00287     if (e.arity() == 1) {
00288       ret = d_vc->checkUnsat(d_vc->trueExpr());
00289     }
00290     else if (e.arity() == 2) {
00291       ret = d_vc->checkUnsat(d_vc->parseExpr(e[1]));
00292     }
00293     else {
00294       throw EvalException("CHECKSAT requires no more than one argument, but is given "
00295                           +int2string(e.arity()-1)+":\n "+e.toString());
00296     }
00297     reportResult(ret, false);
00298     break;
00299   }
00300   case CONTINUE: {
00301     if (e.arity() != 1) {
00302       throw EvalException("CONTINUE takes no arguments");
00303     }
00304     TRACE_MSG("commands", "** [commands] Continue");
00305     bool ret = d_vc->checkContinue();
00306     if (d_vc->getFlags()["printResults"].getBool()) {
00307       if (!ret) cout << "Model found." << endl;
00308       else cout << "No additional models found." << endl;
00309       cout << flush;
00310     }
00311     break;
00312   }
00313   case RESTART: {
00314     if(e.arity() != 2)
00315       throw EvalException("RESTART requires exactly one argument, but is given "
00316                           +int2string(e.arity()-1)+":\n "+e.toString());
00317     TRACE_MSG("commands", "** [commands] Restart formula");
00318     bool ret = d_vc->restart(d_vc->parseExpr(e[1]));
00319     reportResult(ret);
00320     break;
00321   }
00322   case TRANSFORM: {
00323     if(e.arity() != 2)
00324       throw EvalException
00325         ("TRANSFORM requires exactly one argument, but is given "
00326          +int2string(e.arity()-1)+":\n "+e.toString());
00327     if(d_vc->getFlags()["reorder"].getBool()
00328      || d_vc->getFlags()["pq"].getBool()){
00329       cout << "TRANSFORM " << d_vc->parseExpr(e[1]);
00330       cout << ";" << endl;
00331       TRACE_MSG("commands", "evaluateCommand => true }");
00332       return true;
00333     }    
00334     TRACE_MSG("commands", "** [commands] Transforming expression");
00335     Expr ee = d_vc->parseExpr(e[1]);
00336     e = d_vc->simplify(ee);
00337     if (d_vc->getFlags()["printResults"].getBool()) d_vc->printExpr(e);
00338     break;
00339   }
00340   case PRINT:
00341     if(e.arity() != 2)
00342       throw EvalException
00343         ("PRINT requires exactly one argument, but is given "
00344          +int2string(e.arity()-1)+":\n "+e.toString());
00345     d_vc->printExpr(d_vc->parseExpr(e[1]));
00346     break;
00347   case PUSH:
00348   case POP:
00349   case PUSH_SCOPE:
00350   case POP_SCOPE: {
00351     int arg;
00352     if (e.arity() == 1) arg = 1;
00353     else {
00354       DebugAssert(e.arity() == 2 && e[1].getKind() == RATIONAL_EXPR,
00355                   "Bad argument to "+kindName);
00356       arg = e[1].getRational().getInt();
00357       if(arg <= 0)
00358         throw EvalException("Argument to PUSH or POP is <= 0");
00359     }
00360     if (kind == PUSH) {
00361       for (int i = 0; i < arg; i++) {
00362         d_vc->push();
00363       }
00364     }
00365     else if (kind == POP) {
00366       if(arg > d_vc->stackLevel())
00367         throw EvalException("Argument to POP is out of range:\n"
00368                             " current stack level = "
00369                             +int2string(d_vc->stackLevel())
00370                             +"\n argument = "
00371                             +int2string(arg));
00372       for (int i = 0; i < arg; i++) {
00373         d_vc->pop();
00374       }
00375     }
00376     else if (kind == PUSH_SCOPE) {
00377       for (int i = 0; i < arg; i++) {
00378         d_vc->pushScope();
00379       }
00380     }
00381     else if (kind == POP_SCOPE) {
00382       if(arg >= d_vc->scopeLevel())
00383         throw EvalException("Argument to POP_SCOPE is out of range:\n"
00384                             " current scope = "
00385                             +int2string(d_vc->scopeLevel())
00386                             +"\n argument = "
00387                             +int2string(arg));
00388       for (int i = 0; i < arg; i++) {
00389         d_vc->popScope();
00390       }
00391     }
00392     break;
00393   }
00394   case POPTO:
00395   case POPTO_SCOPE: {
00396     int arg;
00397     if (e.arity() == 1) arg = 0;
00398     else {
00399       DebugAssert(e.arity() == 2 && e[1].getKind() == RATIONAL_EXPR,
00400                   "Bad argument to "+kindName);
00401       arg = e[1].getRational().getInt();
00402     }
00403     if (kind == POPTO) {
00404       d_vc->popto(arg);
00405     }
00406     else {
00407       d_vc->poptoScope(arg);
00408     }
00409     break;
00410   }
00411   case WHERE:
00412   case ASSERTIONS:
00413   case ASSUMPTIONS:
00414   {
00415     vector<Expr> assertions;
00416     ExprMap<bool> skolemAxioms;
00417     ExprMap<bool> visited;
00418 
00419     d_vc->getAssumptions(assertions);
00420 
00421     if (d_vc->getFlags()["printResults"].getBool()) {
00422       cout << "Current stack level is " << d_vc->stackLevel()
00423            << " (scope " << d_vc->scopeLevel() << ")." << endl;
00424       if (assertions.size() == 0) {
00425         cout << "% No active assumptions\n";
00426       } else {
00427         cout << "% Active assumptions:\n";
00428         for (unsigned i = 0; i < assertions.size(); i++) {      
00429           cout << "ASSERT " << assertions[i] << ";" << endl;
00430           findAxioms(assertions[i], skolemAxioms, visited);
00431         }
00432         ExprMap<bool>::iterator it = skolemAxioms.begin();
00433         ExprMap<bool>::iterator end = skolemAxioms.end();
00434         if (it != end) {
00435           cout << "% Skolemization axioms" << endl;
00436           for(; it!=end; ++it)
00437             cout << "ASSERT " << skolemizeAx((*it).first) << ";" << endl;
00438         }
00439       }
00440       cout << endl;
00441     }
00442     break;
00443   }
00444   case COUNTEREXAMPLE: {
00445     vector<Expr> assertions;
00446     ExprMap<bool> skolemAxioms;
00447     ExprMap<bool> visited;
00448 
00449     d_vc->getCounterExample(assertions);
00450 
00451     if (d_vc->getFlags()["printResults"].getBool()) {
00452       cout << "Current scope level is " << d_vc->scopeLevel() << "." << endl;
00453       if (assertions.size() == 0) {
00454         cout << "% There are no assertions\n";
00455       } else {
00456 
00457         cout << "% Assertions which make the QUERY invalid:\n";
00458 
00459         for (unsigned i = 0; i < assertions.size(); i++) {
00460           cout << Expr(ASSERT, assertions[i]) << "\n";
00461           findAxioms(assertions[i], skolemAxioms, visited);
00462         }
00463         ExprMap<bool>::iterator end = skolemAxioms.end();
00464         for(ExprMap<bool>::iterator it = skolemAxioms.begin(); it!=end; it++)
00465           cout << "ASSERT " << skolemizeAx((*it).first) << ";" << endl;
00466       }
00467       cout << endl;
00468     }
00469     break;
00470   }
00471   case COUNTERMODEL: {
00472     ExprMap<Expr> m;
00473     d_vc->getConcreteModel(m);
00474 
00475     if (d_vc->getFlags()["printResults"].getBool()) {
00476       cout << "Current scope level is " << d_vc->scopeLevel() << "." << endl;
00477       ExprMap<Expr>::iterator it = m.begin(), end = m.end();
00478       if(it == end)
00479         cout << " Did not find concrete model for any vars" << endl;
00480       else {
00481         cout << "%Satisfiable  Variable Assignment: % \n";
00482         for(; it!= end; it++) {
00483           Expr eq;
00484           if(it->first.getType().isBool()) {
00485             DebugAssert((it->second).isBoolConst(),
00486                         "Bad variable assignement: e = "+(it->first).toString()
00487                         +"\n\n val = "+(it->second).toString());
00488             if((it->second).isTrue())
00489               eq = it->first;
00490             else
00491               eq = !(it->first);
00492           }
00493           else
00494             eq = (it->first).eqExpr(it->second);
00495           cout << Expr(ASSERT,  eq) << "\n";
00496         }
00497       }
00498     }
00499     break;
00500   }
00501   case TRACE: { // Set a trace flag
00502 #ifdef DEBUG
00503     if(e.arity() != 2)
00504       throw EvalException("TRACE takes exactly one string argument");
00505     if(!e[1].isString())
00506       throw EvalException("TRACE requires a string argument");
00507     debugger.traceFlag(e[1].getString()) = true;
00508 #endif
00509   }
00510     break;
00511   case UNTRACE: { // Unset a trace flag
00512 #ifdef DEBUG
00513     if(e.arity() != 2)
00514       throw EvalException("UNTRACE takes exactly one string argument");
00515     if(!e[1].isString())
00516       throw EvalException("UNTRACE requires a string argument");
00517     debugger.traceFlag(e[1].getString()) = false;
00518 #endif
00519   }
00520     break;
00521   case OPTION: {
00522     if(e.arity() != 3)
00523       throw EvalException("OPTION takes exactly two arguments "
00524                           "(name and value of a flag)");
00525     if(!e[1].isString())
00526       throw EvalException("OPTION: flag name must be a string");
00527     CLFlags& flags = d_vc->getFlags();
00528     string name(e[1].getString());
00529     vector<string> names;
00530     size_t n = flags.countFlags(name, names);
00531     if(n != 1)
00532       throw EvalException("OPTION: found "+int2string(n)
00533                           +" flags matching "+name
00534                           +".\nThe flag name must uniquely resolve.");
00535     name = names[0];
00536     const CLFlag& flag(flags[name]);
00537     // If the flag is set on the command line, ignore it
00538     if(flag.modified()) break;
00539     switch(flag.getType()) {
00540     case CLFLAG_BOOL:
00541       if(!(e[2].isRational() && e[2].getRational().isInteger()))
00542         throw EvalException("OPTION: flag "+name
00543                             +" expects a boolean value (0 or 1");
00544       flags.setFlag(name, e[2].getRational().getInt() != 0);
00545       break;
00546     case CLFLAG_INT:
00547       if(!(e[2].isRational() && e[2].getRational().isInteger()))
00548         throw EvalException("OPTION: flag "+name+" expects an integer value");
00549       flags.setFlag(name, e[2].getRational().getInt());
00550       break;
00551     case CLFLAG_STRING:
00552       if(!e[2].isString())
00553         throw EvalException("OPTION: flag "+name+" expects a string value");
00554       flags.setFlag(name, e[2].getString());
00555       break;
00556     default:
00557       throw EvalException("OPTION: the type of flag "+name
00558                           +" is not supported by the OPTION commnand");
00559       break;
00560     }
00561     d_vc->reprocessFlags();
00562   }
00563     break;
00564   case DUMP_PROOF: {
00565     Proof p = d_vc->getProof();
00566     if (d_vc->getFlags()["printResults"].getBool()) {
00567       cout << p << endl;
00568       cout << flush;
00569     }
00570     break;
00571   }
00572   case DUMP_ASSUMPTIONS: { // Assumption tracking
00573     vector<Expr> assertions;
00574     d_vc->getAssumptionsUsed(assertions);
00575 
00576     if (d_vc->getFlags()["printResults"].getBool()) {
00577       if(assertions.size() == 0) {
00578         cout << "% No relevant assumptions\n";
00579       } else {
00580         cout << "% Relevant assumptions:\n";
00581         for (unsigned i = 0; i < assertions.size(); i++) {
00582           cout << Expr(ASSERT, assertions[i]) << "\n";
00583         }
00584       }
00585       cout << endl << flush;
00586     }
00587     break;
00588   }
00589   case DUMP_TCC: {
00590     const Expr& tcc = d_vc->getTCC();
00591 
00592     if (d_vc->getFlags()["printResults"].getBool()) {
00593       if(tcc.isNull())
00594         cout << "% No TCC is avaialble" << endl;
00595       else
00596         cout << "% TCC for the last declaration, ASSERT, or QUERY:\n\n"
00597              << tcc << endl;
00598     }
00599     break;
00600   }
00601   case DUMP_TCC_ASSUMPTIONS: {
00602     vector<Expr> assertions;
00603     d_vc->getAssumptionsTCC(assertions);
00604     if (d_vc->getFlags()["printResults"].getBool()) {
00605       if(assertions.size() == 0) {
00606         cout << "% No relevant assumptions\n";
00607       } else {
00608         cout << "% Relevant assumptions for the last TCC:\n";
00609         for (unsigned i = 0; i < assertions.size(); i++) {
00610           cout << Expr(ASSERT, assertions[i]) << "\n";
00611         }
00612       }
00613       cout << endl << flush;
00614     }
00615     break;
00616   }
00617   case DUMP_TCC_PROOF: {
00618     const Proof& tcc = d_vc->getProofTCC();
00619     if (d_vc->getFlags()["printResults"].getBool()) {
00620       if(tcc.isNull())
00621         cout << "% No TCC is avaialble" << endl;
00622       else
00623         cout << "% Proof of TCC for the last declaration, ASSERT, or QUERY:\n\n"
00624              << tcc << endl;
00625     }
00626     break;
00627   }
00628   case DUMP_CLOSURE: {
00629     const Expr& cl = d_vc->getClosure();
00630     if (d_vc->getFlags()["printResults"].getBool()) {
00631       if(cl.isNull())
00632         cout << "% No closure is avaialble" << endl;
00633       else
00634         cout << "% Closure for the last QUERY:\n\n" << cl << endl;
00635     }
00636     break;
00637   }
00638   case DUMP_CLOSURE_PROOF: {
00639     const Proof& cl = d_vc->getProofClosure();
00640     if (d_vc->getFlags()["printResults"].getBool()) {
00641       if(cl.isNull())
00642         cout << "% No closure is avaialble" << endl;
00643       else
00644         cout << "% Proof of closure for the last QUERY:\n\n" << cl << endl;
00645     }
00646     break;
00647   }
00648   case ECHO:
00649     if(e.arity() != 2)
00650       throw EvalException("ECHO: wrong number of arguments: "
00651                           + e.toString());
00652     if(!e[1].isString())
00653       throw EvalException("ECHO: the argument must be a string: "
00654                           +e.toString());
00655     if (d_vc->getFlags()["printResults"].getBool()) {
00656       cout << e[1].getString();
00657       cout << endl << flush;
00658     }
00659     break;
00660   case SEQ: {
00661     Expr::iterator i=e.begin(), iend=e.end();
00662     ++i; // Skip "SEQ" symbol
00663     bool success = true;
00664     for(; i!=iend; ++i) {
00665       success = success && evaluateCommand(*i);
00666     }
00667     return success;
00668   }
00669   case HELP:
00670     cout << "Use the -help command-line option for help." << endl;
00671     break;
00672   case DUMP_SIG:
00673   case DBG:
00674   case INCLUDE:
00675   case SUBSTITUTE:
00676   case GET_CHILD:
00677   case GET_TYPE:
00678   case CHECK_TYPE:
00679     throw EvalException("Unknown command: " + e.toString());
00680   default:
00681     d_vc->parseExpr(e);
00682     break;
00683   }
00684   TRACE_MSG("commands", "evaluateCommand => true }");
00685   return true;
00686 }
00687 
00688 
00689 void VCCmd::processCommands()
00690 {
00691   bool error(false);
00692   try {
00693     bool success(true);
00694     while(success) {
00695       try {
00696         success = evaluateNext();
00697       } catch(EvalException& e) {
00698         error= true;
00699         cerr << "*** Error:\n  " << e << endl;
00700       }
00701     }
00702   }
00703   catch(Exception& e) { 
00704     cerr << "*** Fatal exception:\n" << e << endl;
00705     error= true;
00706   } catch(...) {
00707     cerr << "*** Unknown fatal exception caught" << endl;
00708     error= true;
00709   }
00710   if (error)
00711   {
00712     d_parser->printLocation(cerr);
00713     cerr << ": this is the location of the error" << endl;
00714   }    
00715 }

Generated on Thu Apr 13 16:57:36 2006 for CVC Lite by  doxygen 1.4.4