summaryrefslogtreecommitdiff
path: root/src/expr/node_manager.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr/node_manager.h')
-rw-r--r--src/expr/node_manager.h243
1 files changed, 148 insertions, 95 deletions
diff --git a/src/expr/node_manager.h b/src/expr/node_manager.h
index c3f5238d6..3a6b6e15a 100644
--- a/src/expr/node_manager.h
+++ b/src/expr/node_manager.h
@@ -30,7 +30,6 @@
#include "expr/kind.h"
#include "expr/metakind.h"
-#include "expr/expr.h"
#include "expr/node_value.h"
#include "context/context.h"
#include "expr/type.h"
@@ -86,7 +85,12 @@ class NodeManager {
* NodeValues, but these shouldn't trigger a (recursive) call to
* reclaimZombies().
*/
- bool d_reclaiming;
+ bool d_dontGC;
+
+ /**
+ * Marks that we are in the Destructor currently.
+ */
+ bool d_inDestruction;
/**
* The set of zombie nodes. We may want to revisit this design, as
@@ -164,11 +168,11 @@ class NodeManager {
// reclaimZombies(), because it's already running.
Debug("gc") << "zombifying node value " << nv
<< " [" << nv->d_id << "]: " << *nv
- << (d_reclaiming ? " [CURRENTLY-RECLAIMING]" : "")
+ << (d_dontGC ? " [CURRENTLY-RECLAIMING]" : "")
<< std::endl;
d_zombies.insert(nv);// FIXME multithreading
- if(!d_reclaiming) {// FIXME multithreading
+ if(!d_dontGC) {// FIXME multithreading
// for now, collect eagerly. can add heuristic here later..
reclaimZombies();
}
@@ -202,9 +206,7 @@ class NodeManager {
// NodeManager's attributes. These aren't exposed outside of this
// class; use the getters.
- typedef expr::ManagedAttribute<TypeTag,
- CVC4::Type*,
- expr::attr::TypeCleanupStrategy> TypeAttr;
+ typedef expr::Attribute<TypeTag, Node> TypeAttr;
typedef expr::Attribute<AtomicTag, bool> AtomicAttr;
/**
@@ -239,6 +241,11 @@ public:
NodeManager(context::Context* ctxt);
~NodeManager();
+ /**
+ * Return true if we are in destruction.
+ */
+ bool inDestruction() const { return d_inDestruction; }
+
/** The node manager in the current context. */
static NodeManager* currentNM() { return s_current; }
@@ -246,37 +253,49 @@ public:
/** Create a node with no children. */
Node mkNode(Kind kind);
+ Node* mkNodePtr(Kind kind);
/** Create a node with one child. */
Node mkNode(Kind kind, TNode child1);
+ Node* mkNodePtr(Kind kind, TNode child1);
/** Create a node with two children. */
Node mkNode(Kind kind, TNode child1, TNode child2);
+ Node* mkNodePtr(Kind kind, TNode child1, TNode child2);
/** Create a node with three children. */
Node mkNode(Kind kind, TNode child1, TNode child2, TNode child3);
+ Node* mkNodePtr(Kind kind, TNode child1, TNode child2, TNode child3);
/** Create a node with four children. */
Node mkNode(Kind kind, TNode child1, TNode child2, TNode child3,
TNode child4);
+ Node* mkNodePtr(Kind kind, TNode child1, TNode child2, TNode child3,
+ TNode child4);
/** Create a node with five children. */
Node mkNode(Kind kind, TNode child1, TNode child2, TNode child3,
TNode child4, TNode child5);
+ Node* mkNodePtr(Kind kind, TNode child1, TNode child2, TNode child3,
+ TNode child4, TNode child5);
/** Create a node with an arbitrary number of children. */
template <bool ref_count>
Node mkNode(Kind kind, const std::vector<NodeTemplate<ref_count> >& children);
+ template <bool ref_count>
+ Node* mkNodePtr(Kind kind, const std::vector<NodeTemplate<ref_count> >& children);
/**
* Create a variable with the given name and type. NOTE that no
* lookup is done on the name. If you mkVar("a", type) and then
* mkVar("a", type) again, you have two variables.
*/
- Node mkVar(const std::string& name, Type* type);
+ Node mkVar(const std::string& name, const Type& type);
+ Node* mkVarPtr(const std::string& name, const Type& type);
/** Create a variable with the given type. */
- Node mkVar(Type* type);
+ Node mkVar(const Type& type);
+ Node* mkVarPtr(const Type& type);
/**
* Create a constant of type T. It will have the appropriate
@@ -414,14 +433,10 @@ public:
const typename AttrKind::value_type& value);
/** Get the (singleton) type for booleans. */
- inline BooleanType* booleanType() const {
- return BooleanType::getInstance();
- }
+ inline BooleanType booleanType();
/** Get the (singleton) type for sorts. */
- inline KindType* kindType() const {
- return KindType::getInstance();
- }
+ inline KindType kindType();
/**
* Make a function type from domain to range.
@@ -430,7 +445,7 @@ public:
* @param range the range type
* @returns the functional type domain -> range
*/
- inline FunctionType* mkFunctionType(Type* domain, Type* range) const;
+ inline Type mkFunctionType(const Type& domain, const Type& range);
/**
* Make a function type with input types from
@@ -440,8 +455,7 @@ public:
* @param range the range type
* @returns the functional type (argTypes[0], ..., argTypes[n]) -> range
*/
- inline FunctionType* mkFunctionType(const std::vector<Type*>& argTypes,
- Type* range) const;
+ inline Type mkFunctionType(const std::vector<Type>& argTypes, const Type& range);
/**
* Make a function type with input types from
@@ -449,7 +463,7 @@ public:
* <code>sorts[sorts.size()-1]</code>. <code>sorts</code> must have
* at least 2 elements.
*/
- inline FunctionType* mkFunctionType(const std::vector<Type*>& sorts) const;
+ inline Type mkFunctionType(const std::vector<Type>& sorts);
/**
* Make a predicate type with input types from
@@ -457,16 +471,15 @@ public:
* <code>BOOLEAN</code>. <code>sorts</code> must have at least one
* element.
*/
- inline FunctionType* mkPredicateType(const std::vector<Type*>& sorts) const;
+ inline Type mkPredicateType(const std::vector<Type>& sorts);
/** Make a new sort with the given name. */
- inline Type* mkSort(const std::string& name) const;
+ inline Type mkSort(const std::string& name);
- /** Get the type for the given node.
- *
- * TODO: Does this call compute the type if it's not already available?
+ /**
+ * Get the type for the given node.
*/
- inline Type* getType(TNode n) const;
+ inline Type getType(TNode n);
/**
* Returns true if this node is atomic (has no more Boolean structure)
@@ -518,38 +531,6 @@ public:
}
};
-/**
- * Creates a <code>NodeManagerScope</code> with the underlying
- * <code>NodeManager</code> of a given <code>Expr</code> or
- * <code>ExprManager</code>. The <code>NodeManagerScope</code> is
- * destroyed when the <code>ExprManagerScope</code> is destroyed. See
- * <code>NodeManagerScope</code> for more information.
- */
-// NOTE: Here, it seems ExprManagerScope is redundant, since we have
-// NodeManagerScope already. However, without this class, we'd need
-// Expr to be a friend of ExprManager, because in the implementation
-// of Expr functions, it needs to set the current NodeManager
-// correctly (and to do that it needs access to
-// ExprManager::getNodeManager()). So, we make ExprManagerScope a
-// friend of ExprManager's, since its implementation is simple to
-// read and understand (and verify that it doesn't do any mischief).
-//
-// ExprManager::getNodeManager() can't just be made public, since
-// ExprManager is exposed to clients of the library and NodeManager is
-// not. Similarly, ExprManagerScope shouldn't go in expr_manager.h,
-// since that's a public header.
-class ExprManagerScope {
- NodeManagerScope d_nms;
-public:
- inline ExprManagerScope(const Expr& e) :
- d_nms(e.getExprManager() == NULL
- ? NodeManager::currentNM()
- : e.getExprManager()->getNodeManager()) {
- }
- inline ExprManagerScope(const ExprManager& exprManager) :
- d_nms(exprManager.getNodeManager()) {
- }
-};
template <class AttrKind>
inline typename AttrKind::value_type
@@ -603,45 +584,61 @@ NodeManager::setAttribute(TNode n, const AttrKind&,
d_attrManager.setAttribute(n.d_nv, AttrKind(), value);
}
+
+/** Get the (singleton) type for booleans. */
+inline BooleanType NodeManager::booleanType() {
+ return Type(this, new Node(mkConst<TypeConstant>(BOOLEAN_TYPE)));
+}
+
+/** Get the (singleton) type for sorts. */
+inline KindType NodeManager::kindType() {
+ return Type(this, new Node(mkConst<TypeConstant>(KIND_TYPE)));
+}
+
/** Make a function type from domain to range.
* TODO: Function types should be unique for this manager. */
-inline FunctionType* NodeManager::mkFunctionType(Type* domain,
- Type* range) const {
- std::vector<Type*> argTypes;
- argTypes.push_back(domain);
- return new FunctionType(argTypes, range);
+inline Type NodeManager::mkFunctionType(const Type& domain, const Type& range) {
+ return Type(this, mkNodePtr(kind::FUNCTION_TYPE, *domain.d_typeNode, *range.d_typeNode));
}
-/** Make a function type with input types from argTypes.
- * TODO: Function types should be unique for this manager. */
-inline FunctionType*
-NodeManager::mkFunctionType(const std::vector<Type*>& argTypes,
- Type* range) const {
- Assert( argTypes.size() > 0 );
- return new FunctionType(argTypes, range);
+inline Type NodeManager::mkFunctionType(const std::vector<Type>& argTypes, const Type& range) {
+ Assert(argTypes.size() >= 1);
+ std::vector<Type> sorts(argTypes);
+ sorts.push_back(range);
+ return mkFunctionType(sorts);
}
-inline FunctionType*
-NodeManager::mkFunctionType(const std::vector<Type*>& sorts) const {
- Assert( sorts.size() >= 2 );
- std::vector<Type*> argTypes(sorts);
- Type* rangeType = argTypes.back();
- argTypes.pop_back();
- return mkFunctionType(argTypes,rangeType);
+
+inline Type
+NodeManager::mkFunctionType(const std::vector<Type>& sorts) {
+ Assert(sorts.size() >= 2);
+ std::vector<Node> sortNodes;
+ for (unsigned i = 0; i < sorts.size(); ++ i) {
+ sortNodes.push_back(*(sorts[i].d_typeNode));
+ }
+ return Type(this, mkNodePtr(kind::FUNCTION_TYPE, sortNodes));
}
-inline FunctionType*
-NodeManager::mkPredicateType(const std::vector<Type*>& sorts) const {
- Assert( sorts.size() >= 1 );
- return mkFunctionType(sorts,booleanType());
+inline Type
+NodeManager::mkPredicateType(const std::vector<Type>& sorts) {
+ Assert(sorts.size() >= 1);
+ std::vector<Node> sortNodes;
+ for (unsigned i = 0; i < sorts.size(); ++ i) {
+ sortNodes.push_back(*(sorts[i].d_typeNode));
+ }
+ sortNodes.push_back(*(booleanType().d_typeNode));
+ return Type(this, mkNodePtr(kind::FUNCTION_TYPE, sortNodes));
}
-inline Type* NodeManager::mkSort(const std::string& name) const {
- return new SortType(name);
+inline Type NodeManager::mkSort(const std::string& name) {
+ return Type(this, mkVarPtr(name, kindType()));
}
-inline Type* NodeManager::getType(TNode n) const {
- return getAttribute(n, TypeAttr());
+inline Type NodeManager::getType(TNode n) {
+ Node* typeNode = new Node;
+ getAttribute(n, TypeAttr(), *typeNode);
+ // TODO: Type computation
+ return Type(this, typeNode);
}
inline expr::NodeValue* NodeManager::poolLookup(expr::NodeValue* nv) const {
@@ -731,33 +728,71 @@ inline bool NodeManager::hasOperator(Kind k) {
}
inline Node NodeManager::mkNode(Kind kind) {
- return NodeBuilder<>(this, kind);
+ return NodeBuilder<0>(this, kind);
+}
+
+inline Node* NodeManager::mkNodePtr(Kind kind) {
+ NodeBuilder<0> nb(this, kind);
+ return nb.constructNodePtr();
}
inline Node NodeManager::mkNode(Kind kind, TNode child1) {
- return NodeBuilder<>(this, kind) << child1;
+ return NodeBuilder<1>(this, kind) << child1;
+}
+
+inline Node* NodeManager::mkNodePtr(Kind kind, TNode child1) {
+ NodeBuilder<1> nb(this, kind);
+ nb << child1;
+ return nb.constructNodePtr();
}
inline Node NodeManager::mkNode(Kind kind, TNode child1, TNode child2) {
- return NodeBuilder<>(this, kind) << child1 << child2;
+ return NodeBuilder<2>(this, kind) << child1 << child2;
+}
+
+inline Node* NodeManager::mkNodePtr(Kind kind, TNode child1, TNode child2) {
+ NodeBuilder<2> nb(this, kind);
+ nb << child1 << child2;
+ return nb.constructNodePtr();
}
inline Node NodeManager::mkNode(Kind kind, TNode child1, TNode child2,
TNode child3) {
- return NodeBuilder<>(this, kind) << child1 << child2 << child3;
+ return NodeBuilder<3>(this, kind) << child1 << child2 << child3;
+}
+
+inline Node* NodeManager::mkNodePtr(Kind kind, TNode child1, TNode child2,
+ TNode child3) {
+ NodeBuilder<3> nb(this, kind);
+ nb << child1 << child2 << child3;
+ return nb.constructNodePtr();
}
inline Node NodeManager::mkNode(Kind kind, TNode child1, TNode child2,
TNode child3, TNode child4) {
- return NodeBuilder<>(this, kind) << child1 << child2 << child3 << child4;
+ return NodeBuilder<4>(this, kind) << child1 << child2 << child3 << child4;
+}
+
+inline Node* NodeManager::mkNodePtr(Kind kind, TNode child1, TNode child2,
+ TNode child3, TNode child4) {
+ NodeBuilder<4> nb(this, kind);
+ nb << child1 << child2 << child3 << child4;
+ return nb.constructNodePtr();
}
inline Node NodeManager::mkNode(Kind kind, TNode child1, TNode child2,
TNode child3, TNode child4, TNode child5) {
- return NodeBuilder<>(this, kind) << child1 << child2 << child3 << child4
+ return NodeBuilder<5>(this, kind) << child1 << child2 << child3 << child4
<< child5;
}
+inline Node* NodeManager::mkNodePtr(Kind kind, TNode child1, TNode child2,
+ TNode child3, TNode child4, TNode child5) {
+ NodeBuilder<5> nb(this, kind);
+ nb << child1 << child2 << child3 << child4 << child5;
+ return nb.constructNodePtr();
+}
+
// N-ary version
template <bool ref_count>
inline Node NodeManager::mkNode(Kind kind,
@@ -766,16 +801,34 @@ inline Node NodeManager::mkNode(Kind kind,
return NodeBuilder<>(this, kind).append(children);
}
-inline Node NodeManager::mkVar(const std::string& name, Type* type) {
+template <bool ref_count>
+inline Node* NodeManager::mkNodePtr(Kind kind,
+ const std::vector<NodeTemplate<ref_count> >&
+ children) {
+ return NodeBuilder<>(this, kind).append(children).constructNodePtr();
+}
+
+inline Node NodeManager::mkVar(const std::string& name, const Type& type) {
Node n = mkVar(type);
n.setAttribute(expr::VarNameAttr(), name);
return n;
}
-inline Node NodeManager::mkVar(Type* type) {
- Node n = Node(NodeBuilder<>(this, kind::VARIABLE));
- type->inc();// reference-count the type
- n.setAttribute(TypeAttr(), type);
+inline Node* NodeManager::mkVarPtr(const std::string& name, const Type& type) {
+ Node* n = mkVarPtr(type);
+ n->setAttribute(expr::VarNameAttr(), name);
+ return n;
+}
+
+inline Node NodeManager::mkVar(const Type& type) {
+ Node n = NodeBuilder<0>(this, kind::VARIABLE);
+ n.setAttribute(TypeAttr(), *type.d_typeNode);
+ return n;
+}
+
+inline Node* NodeManager::mkVarPtr(const Type& type) {
+ Node* n = NodeBuilder<0>(this, kind::VARIABLE).constructNodePtr();
+ n->setAttribute(TypeAttr(), *type.d_typeNode);
return n;
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback