#include "expr/declaration_scope.h"
#include "expr/expr.h"
#include "expr/type.h"
+#include "expr/expr_manager_scope.h"
#include "context/cdmap.h"
#include "context/cdset.h"
#include "context/context.h"
delete d_context;
}
-void DeclarationScope::bind(const std::string& name, Expr obj) throw() {
+void DeclarationScope::bind(const std::string& name, Expr obj) throw(AssertionException) {
+ CheckArgument(!obj.isNull(), obj, "cannot bind to a null Expr");
+ ExprManagerScope ems(obj);
d_exprMap->insert(name, obj);
}
-void DeclarationScope::bindDefinedFunction(const std::string& name, Expr obj) throw() {
+void DeclarationScope::bindDefinedFunction(const std::string& name, Expr obj) throw(AssertionException) {
+ CheckArgument(!obj.isNull(), obj, "cannot bind to a null Expr");
+ ExprManagerScope ems(obj);
d_exprMap->insert(name, obj);
d_functions->insert(obj);
}
* @param name an identifier
* @param obj the expression to bind to <code>name</code>
*/
- void bind(const std::string& name, Expr obj) throw();
+ void bind(const std::string& name, Expr obj) throw(AssertionException);
/**
* Bind a function body to a name in the current scope. If
* @param name an identifier
* @param obj the expression to bind to <code>name</code>
*/
- void bindDefinedFunction(const std::string& name, Expr obj) throw();
+ void bindDefinedFunction(const std::string& name, Expr obj) throw(AssertionException);
/**
* Bind a type to a name in the current scope. If <code>name</code>
** \todo document this file
**/
+#include "cvc4_private.h"
+
#ifndef __CVC4__EXPR_MANAGER_SCOPE_H
#define __CVC4__EXPR_MANAGER_SCOPE_H
}
ExprManager::~ExprManager() {
- delete d_nodeManager;
- delete d_ctxt;
#ifdef CVC4_STATISTICS_ON
+ NodeManagerScope nms(d_nodeManager);
for (unsigned i = 0; i < kind::LAST_KIND; ++ i) {
if (d_exprStatistics[i] != NULL) {
StatisticsRegistry::unregisterStat(d_exprStatistics[i]);
}
}
#endif
+ delete d_nodeManager;
+ delete d_ctxt;
}
BooleanType ExprManager::booleanType() const {
expr::NodeValue* constructNV();
expr::NodeValue* constructNV() const;
- inline void maybeCheckType(const TNode n) const {
- /* force an immediate type check, if early type checking is
- enabled and the current node isn't a variable or constant */
- if( d_nm->d_earlyTypeChecking ) {
- kind::MetaKind mk = n.getMetaKind();
- if( mk != kind::metakind::VARIABLE
- && mk != kind::metakind::CONSTANT ) {
- d_nm->getType(n, true);
- }
- }
- }
+#ifdef CVC4_DEBUG
+ void maybeCheckType(const TNode n) const
+ throw(TypeCheckingExceptionPrivate, AssertionException);
+#else /* CVC4_DEBUG */
+ inline void maybeCheckType(const TNode n) const throw() { }
+#endif /* CVC4_DEBUG */
public:
#include "expr/node.h"
#include "expr/node_manager.h"
+#include "util/options.h"
namespace CVC4 {
}
}
+#ifdef CVC4_DEBUG
+template <unsigned nchild_thresh>
+inline void NodeBuilder<nchild_thresh>::maybeCheckType(const TNode n) const
+ throw(TypeCheckingExceptionPrivate, AssertionException) {
+ /* force an immediate type check, if early type checking is
+ enabled and the current node isn't a variable or constant */
+ if( d_nm->getOptions()->earlyTypeChecking ) {
+ kind::MetaKind mk = n.getMetaKind();
+ if( mk != kind::metakind::VARIABLE
+ && mk != kind::metakind::CONSTANT ) {
+ d_nm->getType(n, true);
+ }
+ }
+}
+#endif /* CVC4_DEBUG */
+
}/* CVC4 namespace */
#endif /* __CVC4__NODE_BUILDER_H */
#include "util/Assert.h"
#include "util/options.h"
+#include "util/stats.h"
#include "util/tls.h"
#include <algorithm>
};
NodeManager::NodeManager(context::Context* ctxt) :
- d_attrManager(ctxt) {
- Options options;
- init(options);
+ d_optionsAllocated(new Options()),
+ d_options(d_optionsAllocated),
+ d_statisticsRegistry(new StatisticsRegistry()),
+ d_attrManager(ctxt),
+ d_nodeUnderDeletion(NULL),
+ d_inReclaimZombies(false) {
+ init();
}
NodeManager::NodeManager(context::Context* ctxt,
const Options& options) :
- d_attrManager(ctxt) {
- init(options);
+ d_optionsAllocated(NULL),
+ d_options(&options),
+ d_statisticsRegistry(new StatisticsRegistry()),
+ d_attrManager(ctxt),
+ d_nodeUnderDeletion(NULL),
+ d_inReclaimZombies(false) {
+ init();
}
-inline void NodeManager::init(const Options& options) {
- d_nodeUnderDeletion = NULL;
- d_inReclaimZombies = false;
- d_earlyTypeChecking = options.earlyTypeChecking;
+inline void NodeManager::init() {
poolInsert( &expr::NodeValue::s_null );
for(unsigned i = 0; i < unsigned(kind::LAST_KIND); ++i) {
}
Debug("gc:leaks") << ":end:" << std::endl;
}
+
+ delete d_statisticsRegistry;
+ delete d_optionsAllocated;
}
void NodeManager::reclaimZombies() {
Debug("getType") << "getting type for " << n << std::endl;
- if(needsCheck && !d_earlyTypeChecking) {
+ if(needsCheck && !d_options->earlyTypeChecking) {
/* Iterate and compute the children bottom up. This avoids stack
overflows in computeType() when the Node graph is really deep,
which should only affect us when we're type checking lazily. */
#include "context/context.h"
#include "util/configuration_private.h"
#include "util/tls.h"
+#include "util/options.h"
namespace CVC4 {
-struct Options;
+class StatisticsRegistry;
namespace expr {
static CVC4_THREADLOCAL(NodeManager*) s_current;
+ const Options* d_optionsAllocated;
+ const Options* d_options;
+ StatisticsRegistry* d_statisticsRegistry;
+
NodeValuePool d_nodeValuePool;
expr::attr::AttributeManager d_attrManager;
*/
Node d_operators[kind::LAST_KIND];
- /**
- * Whether to do early type checking (only effective in debug
- * builds; other builds never do early type checking).
- */
- bool d_earlyTypeChecking;
-
/**
* Look up a NodeValue in the pool associated to this NodeManager.
* The NodeValue argument need not be a "completely-constructed"
TypeNode computeType(TNode n, bool check = false)
throw (TypeCheckingExceptionPrivate, AssertionException);
- void init(const Options& options);
+ void init();
public:
explicit NodeManager(context::Context* ctxt, const Options& options);
~NodeManager();
- /** The node manager in the current context. */
+ /** The node manager in the current public-facing CVC4 library context */
static NodeManager* currentNM() { return s_current; }
+ /** Get this node manager's options */
+ const Options* getOptions() const {
+ return d_options;
+ }
+
+ /** Get this node manager's statistics registry */
+ StatisticsRegistry* getStatisticsRegistry() const {
+ return d_statisticsRegistry;
+ }
+
// general expression-builders
/** Create a node with one child. */
NodeManagerScope(NodeManager* nm) :
d_oldNodeManager(NodeManager::s_current) {
+ // There are corner cases where nm can be NULL and it's ok.
+ // For example, if you write { Expr e; }, then when the null
+ // Expr is destructed, there's no active node manager.
+ //Assert(nm != NULL);
NodeManager::s_current = nm;
+ Options::s_current = nm ? nm->d_options : NULL;
Debug("current") << "node manager scope: "
<< NodeManager::s_current << "\n";
}
~NodeManagerScope() {
NodeManager::s_current = d_oldNodeManager;
+ Options::s_current = d_oldNodeManager ? d_oldNodeManager->d_options : NULL;
Debug("current") << "node manager scope: "
<< "returning to " << NodeManager::s_current << "\n";
}
}
Type& Type::operator=(const Type& t) {
- NodeManagerScope nms(d_nodeManager);
+ NodeManagerScope nms(t.d_nodeManager);
if(this != &t) {
*d_typeNode = *t.d_typeNode;
d_nodeManager = t.d_nodeManager;
void printUsage();
namespace CVC4 {
- namespace main {/* Global options variable */
+ namespace main {
+ /** Global options variable */
Options options;
/** Full argv[0] */
/** Just the basename component of argv[0] */
const char *progName;
+
+ /** A pointer to the StatisticsRegistry (the signal handlers need it) */
+ CVC4::StatisticsRegistry* pStatistics;
}
}
*options.out << "unknown" << endl;
#endif
*options.err << "CVC4 Error:" << endl << e << endl;
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(*options.err);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(*options.err);
}
exit(1);
} catch(bad_alloc) {
*options.out << "unknown" << endl;
#endif
*options.err << "CVC4 ran out of memory." << endl;
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(*options.err);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(*options.err);
}
exit(1);
} catch(...) {
options.interactive = inputFromStdin && isatty(fileno(stdin));
}
+ // Determine which messages to show based on smtcomp_mode and verbosity
+ if(Configuration::isMuzzledBuild()) {
+ Debug.setStream(CVC4::null_os);
+ Trace.setStream(CVC4::null_os);
+ Notice.setStream(CVC4::null_os);
+ Chat.setStream(CVC4::null_os);
+ Message.setStream(CVC4::null_os);
+ Warning.setStream(CVC4::null_os);
+ } else {
+ if(options.verbosity < 2) {
+ Chat.setStream(CVC4::null_os);
+ }
+ if(options.verbosity < 1) {
+ Notice.setStream(CVC4::null_os);
+ }
+ if(options.verbosity < 0) {
+ Message.setStream(CVC4::null_os);
+ Warning.setStream(CVC4::null_os);
+ }
+ }
+
// Create the expression manager
ExprManager exprMgr(options);
// Create the SmtEngine
- SmtEngine smt(&exprMgr, options);
+ SmtEngine smt(&exprMgr);
+
+ // signal handlers need access
+ pStatistics = smt.getStatisticsRegistry();
// Auto-detect input language by filename extension
const char* filename = inputFromStdin ? "<stdin>" : argv[firstArgIndex];
ReferenceStat< const char* > s_statFilename("filename", filename);
- RegisterStatistic statFilenameReg(&s_statFilename);
+ RegisterStatistic statFilenameReg(exprMgr, &s_statFilename);
if(options.inputLanguage == language::input::LANG_AUTO) {
if( inputFromStdin ) {
}
}
- // Determine which messages to show based on smtcomp_mode and verbosity
- if(Configuration::isMuzzledBuild()) {
- Debug.setStream(CVC4::null_os);
- Trace.setStream(CVC4::null_os);
- Notice.setStream(CVC4::null_os);
- Chat.setStream(CVC4::null_os);
- Message.setStream(CVC4::null_os);
- Warning.setStream(CVC4::null_os);
- } else {
- if(options.verbosity < 2) {
- Chat.setStream(CVC4::null_os);
- }
- if(options.verbosity < 1) {
- Notice.setStream(CVC4::null_os);
- }
- if(options.verbosity < 0) {
- Message.setStream(CVC4::null_os);
- Warning.setStream(CVC4::null_os);
- }
-
+ if(!Configuration::isMuzzledBuild()) {
OutputLanguage language = language::toOutputLanguage(options.inputLanguage);
Debug.getStream() << Expr::setlanguage(language);
Trace.getStream() << Expr::setlanguage(language);
Warning.getStream() << Expr::setlanguage(language);
}
-
// Parse and execute commands until we are done
Command* cmd;
if( options.interactive ) {
#endif
ReferenceStat< Result > s_statSatResult("sat/unsat", result);
- RegisterStatistic statSatResultReg(&s_statSatResult);
+ RegisterStatistic statSatResultReg(exprMgr, &s_statSatResult);
if(options.statistics) {
- StatisticsRegistry::flushStatistics(*options.err);
+ smt.getStatisticsRegistry()->flushStatistics(*options.err);
}
return returnValue;
#include "util/options.h"
#include "util/exception.h"
+#include "util/stats.h"
#include "cvc4autoconfig.h"
#ifndef __CVC4__MAIN__MAIN_H
namespace main {
/** Full argv[0] */
-extern const char *progPath;
+extern const char* progPath;
/** Just the basename component of argv[0] */
-extern const char *progName;
+extern const char* progName;
+
+/** A reference to the StatisticsRegistry for use by the signal handlers */
+extern CVC4::StatisticsRegistry* pStatistics;
/**
* If true, will not spin on segfault even when CVC4_DEBUG is on.
/** Handler for SIGXCPU, i.e., timeout. */
void timeout_handler(int sig, siginfo_t* info, void*) {
fprintf(stderr, "CVC4 interrupted by timeout.\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
abort();
}
/** Handler for SIGINT, i.e., when the user hits control C. */
void sigint_handler(int sig, siginfo_t* info, void*) {
fprintf(stderr, "CVC4 interrupted by user.\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
abort();
}
if(segvNoSpin) {
fprintf(stderr, "No-spin requested, aborting...\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
abort();
} else {
} else if(addr < 10*1024) {
cerr << "Looks like a NULL pointer was dereferenced." << endl;
}
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
abort();
#endif /* CVC4_DEBUG */
fprintf(stderr, "CVC4 executed an illegal instruction in DEBUG mode.\n");
if(segvNoSpin) {
fprintf(stderr, "No-spin requested, aborting...\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
abort();
} else {
}
#else /* CVC4_DEBUG */
fprintf(stderr, "CVC4 executed an illegal instruction.\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
abort();
#endif /* CVC4_DEBUG */
}
if(segvNoSpin) {
fprintf(stderr, "No-spin requested.\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
set_terminate(default_terminator);
} else {
}
#else /* CVC4_DEBUG */
fprintf(stderr, "CVC4 threw an \"unexpected\" exception.\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
set_terminate(default_terminator);
#endif /* CVC4_DEBUG */
"CVC4 was terminated by the C++ runtime.\n"
"Perhaps an exception was thrown during stack unwinding. "
"(Don't do that.)\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
default_terminator();
#else /* CVC4_DEBUG */
fprintf(stderr,
"CVC4 was terminated by the C++ runtime.\n"
"Perhaps an exception was thrown during stack unwinding.\n");
- if(options.statistics) {
- StatisticsRegistry::flushStatistics(cerr);
+ if(options.statistics && pStatistics != NULL) {
+ pStatistics->flushStatistics(cerr);
}
default_terminator();
#endif /* CVC4_DEBUG */
The PropEngine then uses the following
// Create the sat solver (this is the proxy, which will create minisat)
-d_satSolver = new SatSolver(this, d_theoryEngine, d_context, d_options);
+d_satSolver = new SatSolver(this, d_theoryEngine, d_context);
// Add some clauses
d_cnfStream->convertAndAssert(node);
// Check for satisfiabilty
}
};
-PropEngine::PropEngine(TheoryEngine* te,
- Context* context, const Options& opts) :
+PropEngine::PropEngine(TheoryEngine* te, Context* context) :
d_inCheckSat(false),
d_theoryEngine(te),
d_context(context) {
Debug("prop") << "Constructing the PropEngine" << endl;
- d_satSolver = new SatSolver(this, d_theoryEngine, d_context, opts);
+ d_satSolver = new SatSolver(this, d_theoryEngine, d_context);
d_cnfStream = new CVC4::prop::TseitinCnfStream(d_satSolver);
d_satSolver->setCnfStream(d_cnfStream);
}
*/
bool d_inCheckSat;
- /** The global options */
- //const Options d_options;
-
/** The theory engine we will be using */
TheoryEngine *d_theoryEngine;
/**
* Create a PropEngine with a particular decision and theory engine.
*/
- PropEngine(TheoryEngine*, context::Context*, const Options&);
+ PropEngine(TheoryEngine*, context::Context*);
/**
* Destructor.
/** Context we will be using to synchronzie the sat solver */
context::Context* d_context;
- /** Remember the options */
- // Options* d_options;
-
/* Pointer to the concrete SAT solver. Including this via the
preprocessor saves us a level of indirection vs, e.g., defining a
sub-class for each solver. */
};
SatSolver(PropEngine* propEngine,
- TheoryEngine* theoryEngine,
- context::Context* context,
- const Options& options);
+ TheoryEngine* theoryEngine,
+ context::Context* context);
~SatSolver();
#ifdef __CVC4_USE_MINISAT
inline SatSolver::SatSolver(PropEngine* propEngine, TheoryEngine* theoryEngine,
- context::Context* context, const Options& options) :
+ context::Context* context) :
d_propEngine(propEngine),
d_cnfStream(NULL),
d_theoryEngine(theoryEngine),
d_statistics()
{
// Create the solver
- d_minisat = new Minisat::SimpSolver(this, d_context, options.incrementalSolving);
+ d_minisat = new Minisat::SimpSolver(this, d_context,
+ Options::current()->incrementalSolving);
// Setup the verbosity
- d_minisat->verbosity = (options.verbosity > 0) ? 1 : -1;
+ d_minisat->verbosity = (Options::current()->verbosity > 0) ? 1 : -1;
// No random choices
- if(Debug.isOn("no_rnd_decisions")){
+ if(Debug.isOn("no_rnd_decisions")) {
d_minisat->random_var_freq = 0;
}
using namespace CVC4::smt;
-SmtEngine::SmtEngine(ExprManager* em) throw() :
- d_exprManager(em) {
- Options opts;
- init(opts);
-}
-
-SmtEngine::SmtEngine(ExprManager* em, const Options& opts) throw() :
- d_exprManager(em){
- init(opts);
-}
-
-void SmtEngine::init(const Options& opts) throw() {
- d_context = d_exprManager->getContext();
- d_userContext = new Context();
-
- d_nodeManager = d_exprManager->getNodeManager();
+SmtEngine::SmtEngine(ExprManager* em) throw(AssertionException) :
+ d_context(em->getContext()),
+ d_userContext(new Context()),
+ d_exprManager(em),
+ d_nodeManager(d_exprManager->getNodeManager()) {
NodeManagerScope nms(d_nodeManager);
// We have mutual dependancy here, so we add the prop engine to the theory
// engine later (it is non-essential there)
- d_theoryEngine = new TheoryEngine(d_context, opts);
+ d_theoryEngine = new TheoryEngine(d_context);
// Add the theories
d_theoryEngine->addTheory<theory::builtin::TheoryBuiltin>();
d_theoryEngine->addTheory<theory::arith::TheoryArith>();
d_theoryEngine->addTheory<theory::arrays::TheoryArrays>();
d_theoryEngine->addTheory<theory::bv::TheoryBV>();
- switch(opts.uf_implementation) {
+ switch(Options::current()->uf_implementation) {
case Options::TIM:
d_theoryEngine->addTheory<theory::uf::tim::TheoryUFTim>();
break;
d_theoryEngine->addTheory<theory::uf::morgan::TheoryUFMorgan>();
break;
default:
- Unhandled(opts.uf_implementation);
+ Unhandled(Options::current()->uf_implementation);
}
- d_propEngine = new PropEngine(d_theoryEngine, d_context, opts);
+ d_propEngine = new PropEngine(d_theoryEngine, d_context);
d_theoryEngine->setPropEngine(d_propEngine);
d_definedFunctions = new(true) DefinedFunctionMap(d_userContext);
d_assertionList = NULL;
- d_interactive = opts.interactive;
- if(d_interactive) {
+ if(Options::current()->interactive) {
d_assertionList = new(true) AssertionList(d_userContext);
}
d_assignments = NULL;
d_haveAdditions = false;
d_queryMade = false;
-
- d_typeChecking = opts.typeChecking;
- d_lazyDefinitionExpansion = opts.lazyDefinitionExpansion;
- d_produceModels = opts.produceModels;
- d_produceAssignments = opts.produceAssignments;
-
- d_incrementalSolving = opts.incrementalSolving;
}
void SmtEngine::shutdown() {
Expr formula) {
Debug("smt") << "SMT defineFunction(" << func << ")" << endl;
NodeManagerScope nms(d_nodeManager);
- Type formulaType = formula.getType(d_typeChecking);// type check body
+ Type formulaType = formula.getType(Options::current()->typeChecking);// type check body
Type funcType = func.getType();
Type rangeType = funcType.isFunction() ?
FunctionType(funcType).getRangeType() : funcType;
throw(NoSuchFunctionException, AssertionException) {
Node n;
- if(!smt.d_lazyDefinitionExpansion) {
+ if(!Options::current()->lazyDefinitionExpansion) {
Debug("expand") << "have: " << n << endl;
n = expandDefinitions(smt, in);
Debug("expand") << "made: " << n << endl;
}
void SmtEngine::ensureBoolean(const BoolExpr& e) {
- Type type = e.getType(d_typeChecking);
+ Type type = e.getType(Options::current()->typeChecking);
Type boolType = d_exprManager->booleanType();
if(type != boolType) {
stringstream ss;
Assert(e.getExprManager() == d_exprManager);
NodeManagerScope nms(d_nodeManager);
Debug("smt") << "SMT checkSat(" << e << ")" << endl;
- if(d_queryMade && !d_incrementalSolving) {
+ if(d_queryMade && !Options::current()->incrementalSolving) {
throw ModalException("Cannot make multiple queries unless "
"incremental solving is enabled "
"(try --incremental)");
Assert(e.getExprManager() == d_exprManager);
NodeManagerScope nms(d_nodeManager);
Debug("smt") << "SMT query(" << e << ")" << endl;
- if(d_queryMade && !d_incrementalSolving) {
+ if(d_queryMade && !Options::current()->incrementalSolving) {
throw ModalException("Cannot make multiple queries unless "
"incremental solving is enabled "
"(try --incremental)");
Expr SmtEngine::simplify(const Expr& e) {
Assert(e.getExprManager() == d_exprManager);
NodeManagerScope nms(d_nodeManager);
- if( d_typeChecking ) {
+ if( Options::current()->typeChecking ) {
e.getType(true);// ensure expr is type-checked at this point
}
Debug("smt") << "SMT simplify(" << e << ")" << endl;
Expr SmtEngine::getValue(const Expr& e)
throw(ModalException, AssertionException) {
Assert(e.getExprManager() == d_exprManager);
- Type type = e.getType(d_typeChecking);// ensure expr is type-checked at this point
+ Type type = e.getType(Options::current()->typeChecking);// ensure expr is type-checked at this point
Debug("smt") << "SMT getValue(" << e << ")" << endl;
- if(!d_produceModels) {
+ if(!Options::current()->produceModels) {
const char* msg =
"Cannot get value when produce-models options is off.";
throw ModalException(msg);
bool SmtEngine::addToAssignment(const Expr& e) throw(AssertionException) {
NodeManagerScope nms(d_nodeManager);
- Type type = e.getType(d_typeChecking);
+ Type type = e.getType(Options::current()->typeChecking);
// must be Boolean
CheckArgument( type.isBoolean(), e,
"expected Boolean-typed variable or function application "
n.getMetaKind() == kind::metakind::VARIABLE ), e,
"expected variable or defined-function application "
"in addToAssignment(),\ngot %s", e.toString().c_str() );
- if(!d_produceAssignments) {
+ if(!Options::current()->produceAssignments) {
return false;
}
if(d_assignments == NULL) {
SExpr SmtEngine::getAssignment() throw(ModalException, AssertionException) {
Debug("smt") << "SMT getAssignment()" << endl;
- if(!d_produceAssignments) {
+ if(!Options::current()->produceAssignments) {
const char* msg =
"Cannot get the current assignment when "
"produce-assignments option is off.";
vector<Expr> SmtEngine::getAssertions()
throw(ModalException, AssertionException) {
Debug("smt") << "SMT getAssertions()" << endl;
- if(!d_interactive) {
+ if(!Options::current()->interactive) {
const char* msg =
"Cannot query the current assertion list when not in interactive mode.";
throw ModalException(msg);
void SmtEngine::push() {
NodeManagerScope nms(d_nodeManager);
Debug("smt") << "SMT push()" << endl;
- if(!d_incrementalSolving) {
+ if(!Options::current()->incrementalSolving) {
throw ModalException("Cannot push when not solving incrementally (use --incremental)");
}
d_userLevels.push_back(d_userContext->getLevel());
void SmtEngine::pop() {
NodeManagerScope nms(d_nodeManager);
Debug("smt") << "SMT pop()" << endl;
- if(!d_incrementalSolving) {
+ if(!Options::current()->incrementalSolving) {
throw ModalException("Cannot pop when not solving incrementally (use --incremental)");
}
AlwaysAssert(d_userLevels.size() > 0 && d_userLevels.back() < d_userContext->getLevel());
d_propEngine->push();
}
+StatisticsRegistry* SmtEngine::getStatisticsRegistry() const {
+ return d_exprManager->d_nodeManager->getStatisticsRegistry();
+}
+
}/* CVC4 namespace */
class TheoryEngine;
+class StatisticsRegistry;
+
namespace context {
class Context;
}/* CVC4::context namespace */
*/
bool d_queryMade;
- /**
- * Whether or not to type check input expressions.
- */
- bool d_typeChecking;
-
- /**
- * Whether we're being used in an interactive setting.
- */
- bool d_interactive;
-
- /**
- * Whether we expand function definitions lazily.
- */
- bool d_lazyDefinitionExpansion;
-
- /**
- * Whether getValue() is enabled.
- */
- bool d_produceModels;
-
- /**
- * Whether getAssignment() is enabled.
- */
- bool d_produceAssignments;
-
- /**
- * Whether multiple queries can be made, and also push/pop is enabled.
- */
- bool d_incrementalSolving;
-
/**
* Most recent result of last checkSat/query or (set-info :status).
*/
Result d_status;
- /** Called by the constructors to setup fields. */
- void init(const Options& opts) throw();
-
/**
* This is called by the destructor, just before destroying the
* PropEngine, TheoryEngine, and DecisionEngine (in that order). It
/**
* Construct an SmtEngine with the given expression manager.
*/
- SmtEngine(ExprManager* em) throw();
-
- /**
- * Construct an SmtEngine with the given expression manager and user options.
- */
- SmtEngine(ExprManager* em, const Options& opts) throw();
+ SmtEngine(ExprManager* em) throw(AssertionException);
/**
* Destruct the SMT engine.
*/
void pop();
- /** Enable type checking. Forces a type check on any Expr parameter
- to an SmtEngine method. */
- void enableTypeChecking() { d_typeChecking = true; }
-
- /** Disable type checking. */
- void disableTypeChecking() { d_typeChecking = false; }
+ /**
+ * Permit access to the underlying StatisticsRegistry.
+ */
+ StatisticsRegistry* getStatisticsRegistry() const;
};/* class SmtEngine */
Assert(d_varOrderQueue.empty());
Assert(d_diffQueue.empty());
}
+
+std::ostream& CVC4::theory::arith::operator<<(std::ostream& out, ArithPriorityQueue::PivotRule rule) {
+ switch(rule) {
+ case ArithPriorityQueue::MINIMUM:
+ out << "MINIMUM";
+ break;
+ case ArithPriorityQueue::BREAK_TIES:
+ out << "BREAK_TIES";
+ break;
+ case ArithPriorityQueue::MAXIMUM:
+ out << "MAXIMUM";
+ break;
+ default:
+ out << "PivotRule!UNKNOWN";
+ }
+
+ return out;
+}
Statistics d_statistics;
};
+std::ostream& operator<<(std::ostream& out, ArithPriorityQueue::PivotRule rule);
}/* CVC4::theory::arith namespace */
}/* CVC4::theory namespace */
}else if(reduction.getKind() == kind::LT){
Node geq = currNM->mkNode(kind::GEQ, reduction[0], reduction[1]);
reduction = currNM->mkNode(kind::NOT, geq);
- }else if( Options::rewriteArithEqualities && reduction.getKind() == kind::EQUAL){
+ }else if( Options::current()->rewriteArithEqualities && reduction.getKind() == kind::EQUAL){
Node geq = currNM->mkNode(kind::GEQ, reduction[0], reduction[1]);
Node leq = currNM->mkNode(kind::LEQ, reduction[0], reduction[1]);
reduction = currNM->mkNode(kind::AND, geq, leq);
d_numVariables(0),
d_delayedLemmas(),
d_ZERO(0)
- {}
+ {
+ switch(Options::ArithPivotRule rule = Options::current()->pivotRule) {
+ case Options::MINIMUM:
+ d_queue.setPivotRule(ArithPriorityQueue::MINIMUM);
+ break;
+ case Options::BREAK_TIES:
+ d_queue.setPivotRule(ArithPriorityQueue::BREAK_TIES);
+ break;
+ case Options::MAXIMUM:
+ d_queue.setPivotRule(ArithPriorityQueue::MAXIMUM);
+ break;
+ default:
+ Unhandled(rule);
+ }
+ }
/**
* Assert*(n, orig) takes an bound n that is implied by orig.
Node generateConflictAbove(ArithVar conflictVar);
Node generateConflictBelow(ArithVar conflictVar);
-public:
- void notifyOptions(const Options& opt){
- switch(opt.pivotRule){
- case Options::MINIMUM:
- d_queue.setPivotRule(ArithPriorityQueue::MINIMUM);
- break;
- case Options::BREAK_TIES:
- d_queue.setPivotRule(ArithPriorityQueue::BREAK_TIES);
- break;
- case Options::MAXIMUM:
- d_queue.setPivotRule(ArithPriorityQueue::MAXIMUM);
- break;
- default:
- Unhandled(opt.pivotRule);
- }
- }
-
-
public:
/**
* Checks to make sure the assignment is consistent with the tableau.
std::string identify() const { return std::string("TheoryArith"); }
- void notifyOptions(const Options& opt) {
- d_simplex.notifyOptions(opt);
- }
private:
/** The constant zero. */
DeltaRational d_DELTA_ZERO;
*/
virtual std::string identify() const = 0;
- /**
- * Notify the theory of the current set of options.
- */
- virtual void notifyOptions(const Options& opt) { }
-
};/* class Theory */
std::ostream& operator<<(std::ostream& os, Theory::Effort level);
d_engine->getSharedTermManager()->addEq(fact);
}
- if(d_engine->d_theoryRegistration && !fact.getAttribute(RegisteredAttr())) {
+ if(Options::current()->theoryRegistration && !fact.getAttribute(RegisteredAttr())) {
list<TNode> toReg;
toReg.push_back(fact);
d_engine->theoryOf(n)->registerTerm(n);
}
}
- }/* d_engine->d_theoryRegistration && !fact.getAttribute(RegisteredAttr()) */
+ }/* Options::current()->theoryRegistration && !fact.getAttribute(RegisteredAttr()) */
}
-TheoryEngine::TheoryEngine(context::Context* ctxt, const Options& opts) :
+TheoryEngine::TheoryEngine(context::Context* ctxt) :
d_propEngine(NULL),
d_context(ctxt),
d_theoryOut(this, ctxt),
- d_theoryRegistration(opts.theoryRegistration),
d_hasShutDown(false),
d_incomplete(ctxt, false),
- d_opts(opts),
d_statistics() {
Rewriter::init();
*/
Node removeITEs(TNode t);
- const Options& d_opts;
-
public:
/**
* Construct a theory engine.
*/
- TheoryEngine(context::Context* ctxt, const Options& opts);
+ TheoryEngine(context::Context* ctxt);
/**
* Destroy a theory engine.
TheoryClass* theory = new TheoryClass(d_context, d_theoryOut, theory::Valuation(this));
d_theoryTable[theory->getId()] = theory;
d_sharedTermManager->registerTheory(static_cast<TheoryClass*>(theory));
-
- theory->notifyOptions(d_opts);
}
SharedTermManager* getSharedTermManager() {
namespace CVC4 {
+CVC4_THREADLOCAL(const Options*) Options::s_current = NULL;
+
#ifdef CVC4_DEBUG
# define USE_EARLY_TYPE_CHECKING_BY_DEFAULT true
#else /* CVC4_DEBUG */
typeChecking(DO_SEMANTIC_CHECKS_BY_DEFAULT),
earlyTypeChecking(USE_EARLY_TYPE_CHECKING_BY_DEFAULT),
incrementalSolving(false),
+ rewriteArithEqualities(false),
pivotRule(MINIMUM)
{
}
--show-config show CVC4 static configuration\n\
--segv-nospin don't spin on segfault waiting for gdb\n\
--lazy-type-checking type check expressions only when necessary (default)\n\
- --eager-type-checking type check expressions immediately on creation\n\
+ --eager-type-checking type check expressions immediately on creation (debug builds only)\n\
--no-type-checking never type check expressions\n\
- --no-checking disable ALL semantic checks, including type checks \n\
+ --no-checking disable ALL semantic checks, including type checks\n\
--no-theory-registration disable theory reg (not safe for some theories)\n\
--strict-parsing fail on non-conformant inputs (SMT2 only)\n\
--verbose | -v increase verbosity (repeatable)\n\
--produce-models support the get-value command\n\
--produce-assignments support the get-assignment command\n\
--lazy-definition-expansion expand define-fun lazily\n\
- --rewrite-arithmetic-equalities rewrite (= x y) to (and (<= x y) (>= x y)) in arithmetic \n\
+ --pivot-rule=RULE change the pivot rule (see --pivot-rule help)\n\
+ --rewrite-arithmetic-equalities rewrite (= x y) to (and (<= x y) (>= x y)) in arithmetic\n\
--incremental enable incremental solving\n";
static const string languageDescription = "\
{ "lazy-definition-expansion", no_argument, NULL, LAZY_DEFINITION_EXPANSION },
{ "interactive", no_argument , NULL, INTERACTIVE },
{ "no-interactive", no_argument , NULL, NO_INTERACTIVE },
- { "produce-models", no_argument , NULL, PRODUCE_MODELS},
- { "produce-assignments", no_argument, NULL, PRODUCE_ASSIGNMENTS},
- { "no-type-checking", no_argument, NULL, NO_TYPE_CHECKING},
- { "lazy-type-checking", no_argument, NULL, LAZY_TYPE_CHECKING},
- { "eager-type-checking", no_argument, NULL, EAGER_TYPE_CHECKING},
- { "incremental", no_argument, NULL, INCREMENTAL},
+ { "produce-models", no_argument , NULL, PRODUCE_MODELS },
+ { "produce-assignments", no_argument, NULL, PRODUCE_ASSIGNMENTS },
+ { "no-type-checking", no_argument, NULL, NO_TYPE_CHECKING },
+ { "lazy-type-checking", no_argument, NULL, LAZY_TYPE_CHECKING },
+ { "eager-type-checking", no_argument, NULL, EAGER_TYPE_CHECKING },
+ { "incremental", no_argument, NULL, INCREMENTAL },
{ "pivot-rule" , required_argument, NULL, PIVOT_RULE },
- { "rewrite-arithmetic-equalities" , no_argument, NULL, REWRITE_ARITHMETIC_EQUALITIES},
+ { "rewrite-arithmetic-equalities", no_argument, NULL, REWRITE_ARITHMETIC_EQUALITIES },
{ NULL , no_argument , NULL, '\0' }
};/* if you add things to the above, please remember to update usage.h! */
return optind;
}
-bool Options::rewriteArithEqualities = false;
+std::ostream& operator<<(std::ostream& out, Options::ArithPivotRule rule) {
+ switch(rule) {
+ case Options::MINIMUM:
+ out << "MINIMUM";
+ break;
+ case Options::BREAK_TIES:
+ out << "BREAK_TIES";
+ break;
+ case Options::MAXIMUM:
+ out << "MAXIMUM";
+ break;
+ default:
+ out << "ArithPivotRule!UNKNOWN";
+ }
+ return out;
+}
#undef USE_EARLY_TYPE_CHECKING_BY_DEFAULT
#undef DO_SEMANTIC_CHECKS_BY_DEFAULT
#include "util/exception.h"
#include "util/language.h"
+#include "util/tls.h"
namespace CVC4 {
struct CVC4_PUBLIC Options {
+ /** The current Options in effect */
+ static CVC4_THREADLOCAL(const Options*) s_current;
+
+ /** Get the current Options in effect */
+ static inline const Options* current() {
+ return s_current;
+ }
+
+ /** The name of the binary (e.g. "cvc4") */
std::string binary_name;
+ /** Whether to collect statistics during this run */
bool statistics;
- std::istream* in;
- std::ostream* out;
- std::ostream* err;
+ std::istream* in; /*< The input stream to use */
+ std::ostream* out; /*< The output stream to use */
+ std::ostream* err; /*< The error stream to use */
/* -1 means no output */
/* 0 is normal (and default) -- warnings only */
/** Whether incemental solving (push/pop) */
bool incrementalSolving;
- static bool rewriteArithEqualities;
+ /** Whether to rewrite equalities in arithmetic theory */
+ bool rewriteArithEqualities;
+ /** The pivot rule for arithmetic */
typedef enum { MINIMUM, BREAK_TIES, MAXIMUM } ArithPivotRule;
ArithPivotRule pivotRule;
* suitable as an argument to printf. */
std::string getDescription() const;
+ /**
+ * Print overall command-line option usage message, prefixed by
+ * "msg"---which could be an error message causing the usage
+ * output in the first place, e.g. "no such option --foo"
+ */
static void printUsage(const std::string msg, std::ostream& out);
+
+ /** Print help for the --lang command line option */
static void printLanguageHelp(std::ostream& out);
/**
return out;
}
+std::ostream& operator<<(std::ostream& out, Options::ArithPivotRule rule);
+
}/* CVC4 namespace */
#endif /* __CVC4__OPTIONS_H */
**/
#include "util/stats.h"
+#include "expr/node_manager.h"
+#include "expr/expr_manager_scope.h"
using namespace CVC4;
-StatisticsRegistry::StatSet StatisticsRegistry::d_registeredStats;
-
std::string Stat::s_delim(",");
+StatisticsRegistry* StatisticsRegistry::current() {
+ return NodeManager::currentNM()->getStatisticsRegistry();
+}
+
+void StatisticsRegistry::registerStat(Stat* s) throw(AssertionException) {
+#ifdef CVC4_STATISTICS_ON
+ StatSet& registeredStats = NodeManager::currentNM()->getStatisticsRegistry()->d_registeredStats;
+ AlwaysAssert(registeredStats.find(s) == registeredStats.end());
+ registeredStats.insert(s);
+#endif /* CVC4_STATISTICS_ON */
+}/* StatisticsRegistry::registerStat() */
+
+void StatisticsRegistry::unregisterStat(Stat* s) throw(AssertionException) {
+#ifdef CVC4_STATISTICS_ON
+ StatSet& registeredStats = NodeManager::currentNM()->getStatisticsRegistry()->d_registeredStats;
+ AlwaysAssert(registeredStats.find(s) != registeredStats.end());
+ registeredStats.erase(s);
+#endif /* CVC4_STATISTICS_ON */
+}/* StatisticsRegistry::unregisterStat() */
+
void StatisticsRegistry::flushStatistics(std::ostream& out) {
#ifdef CVC4_STATISTICS_ON
for(StatSet::iterator i = d_registeredStats.begin();
s->flushStat(out);
out << std::endl;
}
-#endif
+#endif /* CVC4_STATISTICS_ON */
}/* StatisticsRegistry::flushStatistics() */
+
+StatisticsRegistry::const_iterator StatisticsRegistry::begin() {
+ return NodeManager::currentNM()->getStatisticsRegistry()->d_registeredStats.begin();
+}/* StatisticsRegistry::begin() */
+
+StatisticsRegistry::const_iterator StatisticsRegistry::end() {
+ return NodeManager::currentNM()->getStatisticsRegistry()->d_registeredStats.end();
+}/* StatisticsRegistry::end() */
+
+RegisterStatistic::RegisterStatistic(ExprManager& em, Stat* stat) :
+ d_em(&em), d_stat(stat) {
+ ExprManagerScope ems(*d_em);
+ StatisticsRegistry::registerStat(d_stat);
+}/* RegisterStatistic::RegisterStatistic(ExprManager&, Stat*) */
+
+RegisterStatistic::~RegisterStatistic() {
+ if(d_em != NULL) {
+ ExprManagerScope ems(*d_em);
+ StatisticsRegistry::unregisterStat(d_stat);
+ } else {
+ StatisticsRegistry::unregisterStat(d_stat);
+ }
+}/* RegisterStatistic::~RegisterStatistic() */
# define __CVC4_USE_STATISTICS false
#endif
+class ExprManager;
+
class CVC4_PUBLIC Stat;
inline std::ostream& operator<<(std::ostream& os, const ::timespec& t);
/**
* The main statistics registry. This registry maintains the list of
* currently active statistics and is able to "flush" them all.
- *
- * The statistics registry is only used statically; one does not
- * construct a statistics registry.
*/
class CVC4_PUBLIC StatisticsRegistry {
private:
typedef std::set< Stat*, StatCmp > StatSet;
/** The set of currently active statistics */
- static StatSet d_registeredStats;
+ StatSet d_registeredStats;
- /** Private default constructor undefined (no construction permitted). */
- StatisticsRegistry() CVC4_UNDEFINED;
/** Private copy constructor undefined (no copy permitted). */
StatisticsRegistry(const StatisticsRegistry&) CVC4_UNDEFINED;
public:
+ /** Construct a statistics registry */
+ StatisticsRegistry() { }
+
/** An iterator type over a set of statistics */
typedef StatSet::const_iterator const_iterator;
+ /** Get a pointer to the current statistics registry */
+ static StatisticsRegistry* current();
+
/** Flush all statistics to the given output stream. */
- static void flushStatistics(std::ostream& out);
+ void flushStatistics(std::ostream& out);
/** Register a new statistic, making it active. */
- static inline void registerStat(Stat* s) throw(AssertionException);
+ static void registerStat(Stat* s) throw(AssertionException);
/** Unregister an active statistic, making it inactive. */
- static inline void unregisterStat(Stat* s) throw(AssertionException);
+ static void unregisterStat(Stat* s) throw(AssertionException);
/**
* Get an iterator to the beginning of the range of the set of active
* (registered) statistics.
*/
- static inline const_iterator begin() {
- return d_registeredStats.begin();
- }
+ static const_iterator begin();
/**
* Get an iterator to the end of the range of the set of active
* (registered) statistics.
*/
- static inline const_iterator end() {
- return d_registeredStats.end();
- }
+ static const_iterator end();
};/* class StatisticsRegistry */
return s1->getName() < s2->getName();
}
-inline void StatisticsRegistry::registerStat(Stat* s)
- throw(AssertionException) {
- if(__CVC4_USE_STATISTICS) {
- AlwaysAssert(d_registeredStats.find(s) == d_registeredStats.end());
- d_registeredStats.insert(s);
- }
-}/* StatisticsRegistry::registerStat() */
-
-
-inline void StatisticsRegistry::unregisterStat(Stat* s)
- throw(AssertionException) {
- if(__CVC4_USE_STATISTICS) {
- AlwaysAssert(d_registeredStats.find(s) != d_registeredStats.end());
- d_registeredStats.erase(s);
- }
-}/* StatisticsRegistry::unregisterStat() */
-
-
/**
* A class to represent a "read-only" data statistic of type T. Adds to
* the Stat base class the pure virtual function getData(), which returns
* registration and unregistration.
*/
class RegisterStatistic {
+ ExprManager* d_em;
Stat* d_stat;
public:
RegisterStatistic(Stat* stat) : d_stat(stat) {
+ Assert(StatisticsRegistry::current() != NULL,
+ "You need to specify an expression manager "
+ "on which to set the statistic");
StatisticsRegistry::registerStat(d_stat);
}
- ~RegisterStatistic() {
- StatisticsRegistry::unregisterStat(d_stat);
- }
+
+ RegisterStatistic(ExprManager& em, Stat* stat);
+
+ ~RegisterStatistic();
+
};/* class RegisterStatistic */
#undef __CVC4_USE_STATISTICS
int main() {
ExprManager em;
Options opts;
- SmtEngine smt(&em, opts);
+ SmtEngine smt(&em);
Result r = smt.query(em.mkConst(true));
return r == Result::VALID ? 0 : 1;
d_nm = new NodeManager(d_ctxt);
d_scope = new NodeManagerScope(d_nm);
- Options options;
- d_theoryEngine = new TheoryEngine(d_ctxt, options);
+ d_theoryEngine = new TheoryEngine(d_ctxt);
}
void tearDown() {
d_nullChannel = new FakeOutputChannel;
// create the TheoryEngine
- Options options;
- d_theoryEngine = new TheoryEngine(d_ctxt, options);
+ d_theoryEngine = new TheoryEngine(d_ctxt);
d_theoryEngine->addTheory< FakeTheory<THEORY_BUILTIN> >();
d_theoryEngine->addTheory< FakeTheory<THEORY_BOOL> >();