expr_template.h
Go to the documentation of this file.
/********************* */
#include "cvc4_public.h"
// putting the constant-payload #includes up here allows circularity
// (some of them may require a completely-defined Expr type). This
// way, those #includes can forward-declare some stuff to get Expr's
// getConst<> template instantiations correct, and then #include
// "expr.h" safely, then go on to completely declare their own stuff.
${includes}
#ifndef __CVC4__EXPR_H
#define __CVC4__EXPR_H
#include <string>
#include <iostream>
#include <iterator>
#include <stdint.h>
#include "util/exception.h"
#include "util/language.h"
#include "util/hash.h"
#include "expr/options.h"
// This is a hack, but an important one: if there's an error, the
// compiler directs the user to the template file instead of the
// generated one. We don't want the user to modify the generated one,
// since it'll get overwritten on a later build.
#line 44 "${template}"
namespace CVC4 {
// The internal expression representation
template <bool ref_count>
class NodeTemplate;
class NodeManager;
class Expr;
class ExprManager;
class SmtEngine;
class Type;
class TypeCheckingException;
class TypeCheckingExceptionPrivate;
namespace expr {
namespace pickle {
class Pickler;
}/* CVC4::expr::pickle namespace */
}/* CVC4::expr namespace */
namespace prop {
class TheoryProxy;
}/* CVC4::prop namespace */
struct ExprManagerMapCollection;
struct ExprHashFunction;
namespace smt {
class SmtEnginePrivate;
}/* CVC4::smt namespace */
namespace expr {
class CVC4_PUBLIC ExprSetDepth;
class CVC4_PUBLIC ExprPrintTypes;
class CVC4_PUBLIC ExprDag;
class CVC4_PUBLIC ExprSetLanguage;
class ExportPrivate;
}/* CVC4::expr namespace */
class CVC4_PUBLIC TypeCheckingException : public Exception {
friend class SmtEngine;
friend class smt::SmtEnginePrivate;
private:
Expr* d_expr;
protected:
TypeCheckingException() throw() : Exception() {}
TypeCheckingException(ExprManager* em,
const TypeCheckingExceptionPrivate* exc) throw();
public:
TypeCheckingException(const Expr& expr, std::string message) throw();
TypeCheckingException(const TypeCheckingException& t) throw();
~TypeCheckingException() throw();
Expr getExpression() const throw();
void toStream(std::ostream& out) const throw();
friend class ExprManager;
};/* class TypeCheckingException */
class CVC4_PUBLIC ExportUnsupportedException : public Exception {
public:
ExportUnsupportedException() throw():
Exception("export unsupported") {
}
ExportUnsupportedException(const char* msg) throw():
Exception(msg) {
}
};/* class DatatypeExportUnsupportedException */
std::ostream& operator<<(std::ostream& out,
const TypeCheckingException& e) CVC4_PUBLIC;
std::ostream& operator<<(std::ostream& out, const Expr& e) CVC4_PUBLIC;
// for hash_maps, hash_sets..
struct ExprHashFunction {
size_t operator()(CVC4::Expr e) const;
};/* struct ExprHashFunction */
class CVC4_PUBLIC Expr {
NodeTemplate<true>* d_node;
ExprManager* d_exprManager;
Expr(ExprManager* em, NodeTemplate<true>* node);
public:
Expr();
Expr(const Expr& e);
~Expr();
Expr& operator=(const Expr& e);
bool operator==(const Expr& e) const;
bool operator!=(const Expr& e) const;
bool operator<(const Expr& e) const;
bool operator>(const Expr& e) const;
bool operator<=(const Expr& e) const { return !(*this > e); }
bool operator>=(const Expr& e) const { return !(*this < e); }
unsigned long getId() const;
Kind getKind() const;
size_t getNumChildren() const;
Expr operator[](unsigned i) const;
std::vector<Expr> getChildren() const {
return std::vector<Expr>(begin(), end());
}
Expr notExpr() const;
Expr andExpr(const Expr& e) const;
Expr orExpr(const Expr& e) const;
Expr xorExpr(const Expr& e) const;
Expr iffExpr(const Expr& e) const;
Expr impExpr(const Expr& e) const;
Expr iteExpr(const Expr& then_e, const Expr& else_e) const;
class const_iterator : public std::iterator<std::input_iterator_tag, Expr> {
ExprManager* d_exprManager;
void* d_iterator;
explicit const_iterator(ExprManager*, void*);
friend class Expr;// to access void* constructor
public:
const_iterator();
const_iterator(const const_iterator& it);
const_iterator& operator=(const const_iterator& it);
~const_iterator();
bool operator==(const const_iterator& it) const;
bool operator!=(const const_iterator& it) const {
return !(*this == it);
}
const_iterator& operator++();
const_iterator operator++(int);
Expr operator*() const;
};/* class Expr::const_iterator */
const_iterator begin() const;
const_iterator end() const;
bool hasOperator() const;
Expr getOperator() const;
Type getType(bool check = false) const throw (TypeCheckingException);
Expr substitute(Expr e, Expr replacement) const;
Expr substitute(const std::vector<Expr> exes,
const std::vector<Expr>& replacements) const;
Expr substitute(const std::hash_map<Expr, Expr, ExprHashFunction> map) const;
std::string toString() const;
void toStream(std::ostream& out, int toDepth = -1, bool types = false, size_t dag = 1,
OutputLanguage language = language::output::LANG_AUTO) const;
bool isNull() const;
bool isVariable() const;
bool isConst() const;
/* A note on isAtomic() and isAtomicFormula() (in CVC3 parlance)..
*
* It has been decided for now to hold off on implementations of
* these functions, as they may only be needed in CNF conversion,
* where it's pointless to do a lazy isAtomic determination by
* searching through the DAG, and storing it, since the result will
* only be used once. For more details see the 4/27/2010 CVC4
* developer's meeting notes at:
*
* http://goedel.cims.nyu.edu/wiki/Meeting_Minutes_-_April_27,_2010#isAtomic.28.29_and_isAtomicFormula.28.29
*/
// bool containsDecision(); // is "atomic"
// bool properlyContainsDecision(); // maybe not atomic but all children are
template <class T>
const T& getConst() const;
ExprManager* getExprManager() const;
Expr exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap, uint32_t flags = 0) const;
typedef expr::ExprSetDepth setdepth;
typedef expr::ExprPrintTypes printtypes;
typedef expr::ExprDag dag;
typedef expr::ExprSetLanguage setlanguage;
void printAst(std::ostream& out, int indent = 0) const;
private:
void debugPrint();
NodeTemplate<true> getNode() const throw();
NodeTemplate<false> getTNode() const throw();
// Friend to access the actual internal expr information and private methods
friend class SmtEngine;
friend class smt::SmtEnginePrivate;
friend class ExprManager;
friend class NodeManager;
friend class TypeCheckingException;
friend class expr::pickle::Pickler;
friend class prop::TheoryProxy;
friend class expr::ExportPrivate;
friend std::ostream& CVC4::operator<<(std::ostream& out, const Expr& e);
template <bool ref_count> friend class NodeTemplate;
};/* class Expr */
namespace expr {
class CVC4_PUBLIC ExprSetDepth {
static const int s_iosIndex;
static const int s_defaultPrintDepth = -1;
long d_depth;
public:
ExprSetDepth(long depth) : d_depth(depth) {}
inline void applyDepth(std::ostream& out) {
out.iword(s_iosIndex) = d_depth;
}
static inline long getDepth(std::ostream& out) {
long& l = out.iword(s_iosIndex);
if(l == 0) {
// set the default print depth on this ostream
if(&Options::current() != NULL) {
l = options::defaultExprDepth();
}
if(l == 0) {
// if called from outside the library, we may not have options
// available to us at this point (or perhaps the output language
// is not set in Options). Default to something reasonable, but
// don't set "l" since that would make it "sticky" for this
// stream.
return s_defaultPrintDepth;
}
}
return l;
}
static inline void setDepth(std::ostream& out, long depth) {
out.iword(s_iosIndex) = depth;
}
class Scope {
std::ostream& d_out;
long d_oldDepth;
public:
inline Scope(std::ostream& out, long depth) :
d_out(out),
d_oldDepth(ExprSetDepth::getDepth(out)) {
ExprSetDepth::setDepth(out, depth);
}
inline ~Scope() {
ExprSetDepth::setDepth(d_out, d_oldDepth);
}
};/* class ExprSetDepth::Scope */
};/* class ExprSetDepth */
class CVC4_PUBLIC ExprPrintTypes {
static const int s_iosIndex;
bool d_printTypes;
public:
ExprPrintTypes(bool printTypes) : d_printTypes(printTypes) {}
inline void applyPrintTypes(std::ostream& out) {
out.iword(s_iosIndex) = d_printTypes;
}
static inline bool getPrintTypes(std::ostream& out) {
return out.iword(s_iosIndex);
}
static inline void setPrintTypes(std::ostream& out, bool printTypes) {
out.iword(s_iosIndex) = printTypes;
}
class Scope {
std::ostream& d_out;
bool d_oldPrintTypes;
public:
inline Scope(std::ostream& out, bool printTypes) :
d_out(out),
d_oldPrintTypes(ExprPrintTypes::getPrintTypes(out)) {
ExprPrintTypes::setPrintTypes(out, printTypes);
}
inline ~Scope() {
ExprPrintTypes::setPrintTypes(d_out, d_oldPrintTypes);
}
};/* class ExprPrintTypes::Scope */
};/* class ExprPrintTypes */
class CVC4_PUBLIC ExprDag {
static const int s_iosIndex;
static const size_t s_defaultDag = 1;
size_t d_dag;
public:
explicit ExprDag(bool dag) : d_dag(dag ? 1 : 0) {}
explicit ExprDag(int dag) : d_dag(dag < 0 ? 0 : dag) {}
inline void applyDag(std::ostream& out) {
// (offset by one to detect whether default has been set yet)
out.iword(s_iosIndex) = static_cast<long>(d_dag) + 1;
}
static inline size_t getDag(std::ostream& out) {
long& l = out.iword(s_iosIndex);
if(l == 0) {
// set the default dag setting on this ostream
// (offset by one to detect whether default has been set yet)
if(&Options::current() != NULL) {
l = options::defaultDagThresh() + 1;
}
if(l == 0) {
// if called from outside the library, we may not have options
// available to us at this point (or perhaps the output language
// is not set in Options). Default to something reasonable, but
// don't set "l" since that would make it "sticky" for this
// stream.
return s_defaultDag + 1;
}
}
return static_cast<size_t>(l - 1);
}
static inline void setDag(std::ostream& out, size_t dag) {
// (offset by one to detect whether default has been set yet)
out.iword(s_iosIndex) = static_cast<long>(dag) + 1;
}
class Scope {
std::ostream& d_out;
size_t d_oldDag;
public:
inline Scope(std::ostream& out, size_t dag) :
d_out(out),
d_oldDag(ExprDag::getDag(out)) {
ExprDag::setDag(out, dag);
}
inline ~Scope() {
ExprDag::setDag(d_out, d_oldDag);
}
};/* class ExprDag::Scope */
};/* class ExprDag */
class CVC4_PUBLIC ExprSetLanguage {
static const int s_iosIndex;
static const int s_defaultOutputLanguage = language::output::LANG_AUTO;
OutputLanguage d_language;
public:
ExprSetLanguage(OutputLanguage l) : d_language(l) {}
inline void applyLanguage(std::ostream& out) {
// (offset by one to detect whether default has been set yet)
out.iword(s_iosIndex) = int(d_language) + 1;
}
static inline OutputLanguage getLanguage(std::ostream& out) {
long& l = out.iword(s_iosIndex);
if(l == 0) {
// set the default language on this ostream
// (offset by one to detect whether default has been set yet)
if(&Options::current() != NULL) {
l = options::outputLanguage() + 1;
}
if(l <= 0 || l > language::output::LANG_MAX) {
// if called from outside the library, we may not have options
// available to us at this point (or perhaps the output language
// is not set in Options). Default to something reasonable, but
// don't set "l" since that would make it "sticky" for this
// stream.
return OutputLanguage(s_defaultOutputLanguage);
}
}
return OutputLanguage(l - 1);
}
static inline void setLanguage(std::ostream& out, OutputLanguage l) {
// (offset by one to detect whether default has been set yet)
out.iword(s_iosIndex) = int(l) + 1;
}
class Scope {
std::ostream& d_out;
OutputLanguage d_oldLanguage;
public:
inline Scope(std::ostream& out, OutputLanguage language) :
d_out(out),
d_oldLanguage(ExprSetLanguage::getLanguage(out)) {
ExprSetLanguage::setLanguage(out, language);
}
inline ~Scope() {
ExprSetLanguage::setLanguage(d_out, d_oldLanguage);
}
};/* class ExprSetLanguage::Scope */
};/* class ExprSetLanguage */
}/* CVC4::expr namespace */
${getConst_instantiations}
#line 938 "${template}"
namespace expr {
inline std::ostream& operator<<(std::ostream& out, ExprSetDepth sd) {
sd.applyDepth(out);
return out;
}
inline std::ostream& operator<<(std::ostream& out, ExprPrintTypes pt) {
pt.applyPrintTypes(out);
return out;
}
inline std::ostream& operator<<(std::ostream& out, ExprDag d) {
d.applyDag(out);
return out;
}
inline std::ostream& operator<<(std::ostream& out, ExprSetLanguage l) {
l.applyLanguage(out);
return out;
}
}/* CVC4::expr namespace */
inline size_t ExprHashFunction::operator()(CVC4::Expr e) const {
return (size_t) e.getId();
}
}/* CVC4 namespace */
#endif /* __CVC4__EXPR_H */
Expr
void * Expr
Definition c_interface_defs.h:46
Type
void * Type
Definition c_interface_defs.h:48
ExprManager
void * ExprManager
Definition c_interface_defs.h:43
CVC4::Expr
Class encapsulating CVC4 expressions and methods for constructing new expressions.
Definition expr.h:227
CVC4::Expr::getId
unsigned long getId() const
Get the ID of this expression (used for the comparison operators).
cvc4_public.h
Macros that should be defined everywhere during the building of the libraries and driver binary,...
CVC4_PUBLIC
#define CVC4_PUBLIC
Definition cvc4_public.h:30
exception.h
CVC4's exception base class and some associated utilities.
options.h
hash.h
[[ Add one-line brief description here ]]
language.h
Definition of input and output languages.
CVC3::operator!=
bool operator!=(const Cardinality &c, CVC3CardinalityKind d)
CVC3::operator==
bool operator==(const Cardinality &c, CVC3CardinalityKind d)
CVC4::kind::$
@ $
marks the upper-bound of this enumeration
Definition kind_template.h:33
CVC4::options::out
struct CVC4::options::out__option_t out
CVC4::theory::operator++
TheoryId & operator++(TheoryId &id)
Definition kind.h:610
CVC4
Definition expr.h:106
CVC4::Kind
::CVC4::kind::Kind_t Kind
Definition kind.h:279
CVC4::OutputLanguage
language::output::Language OutputLanguage
Definition language.h:166
CVC4::operator<<
std::ostream & operator<<(std::ostream &out, const TypeCheckingException &e)
std
STL namespace.