summaryrefslogtreecommitdiff
path: root/src/expr/node.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr/node.h')
-rw-r--r--src/expr/node.h1067
1 files changed, 543 insertions, 524 deletions
diff --git a/src/expr/node.h b/src/expr/node.h
index 5655d7e3a..e4e57fc62 100644
--- a/src/expr/node.h
+++ b/src/expr/node.h
@@ -36,8 +36,9 @@ namespace CVC4 {
class Type;
class NodeManager;
-template<bool ref_count>
- class NodeTemplate;
+
+template<bool ref_count> class NodeTemplate;
+
/**
* The Node class encapsulates the NodeValue with reference counting.
*/
@@ -49,14 +50,14 @@ typedef NodeTemplate<true> Node;
typedef NodeTemplate<false> TNode;
namespace expr {
- class NodeValue;
+
+class NodeValue;
namespace attr {
class AttributeManager;
}/* CVC4::expr::attr namespace */
-}/* CVC4::expr namespace */
-using CVC4::expr::NodeValue;
+}/* CVC4::expr namespace */
/**
* Encapsulation of an NodeValue pointer. The reference count is
@@ -64,390 +65,335 @@ using CVC4::expr::NodeValue;
* @param ref_count if true reference are counted in the NodeValue
*/
template<bool ref_count>
- class NodeTemplate {
-
- /**
- * The NodeValue has access to the private constructors, so that the
- * iterators can can create new nodes.
- */
- friend class NodeValue;
-
- /** A convenient null-valued encapsulated pointer */
- static NodeTemplate s_null;
-
- /** The referenced NodeValue */
- NodeValue* d_nv;
-
- /**
- * This constructor is reserved for use by the NodeTemplate package; one
- * must construct an NodeTemplate using one of the build mechanisms of the
- * NodeTemplate package.
- *
- * FIXME: there's a type-system escape here to cast away the const,
- * since the refcount needs to be updated. But conceptually Nodes
- * don't change their arguments, and it's nice to have
- * const_iterators over them.
- *
- * This really does needs to be explicit to avoid hard to track errors with
- * Nodes implicitly wrapping NodeValues
- */
- explicit NodeTemplate(const NodeValue*);
-
- friend class NodeTemplate<true> ;
- friend class NodeTemplate<false> ;
- friend class NodeManager;
- template<unsigned>
- friend class NodeBuilder;
- friend class ::CVC4::expr::attr::AttributeManager;
-
- /**
- * Assigns the expression value and does reference counting. No assumptions
- * are made on the expression, and should only be used if we know what we
- * are doing.
- *
- * @param ev the expression value to assign
- */
- void assignNodeValue(NodeValue* ev);
-
- public:
-
- /** Default constructor, makes a null expression. */
- NodeTemplate() : d_nv(&NodeValue::s_null) { }
-
- /**
- * Conversion between nodes that are reference-counted and those that are
- * not.
- * @param node the node to make copy of
- */
- NodeTemplate(const NodeTemplate<!ref_count>& node);
-
- /**
- * Copy constructor. Note that GCC does NOT recognize an instantiation of
- * the above template as a copy constructor and problems ensue. So we
- * provide an explicit one here.
- * @param node the node to make copy of
- */
- NodeTemplate(const NodeTemplate& node);
-
- /**
- * Assignment operator for nodes, copies the relevant information from node
- * to this node.
- * @param node the node to copy
- * @return reference to this node
- */
- NodeTemplate& operator=(const NodeTemplate& node);
-
- /**
- * Assignment operator for nodes, copies the relevant information from node
- * to this node.
- * @param node the node to copy
- * @return reference to this node
- */
- NodeTemplate& operator=(const NodeTemplate<!ref_count>& node);
-
- /**
- * Destructor. If ref_count is true it will decrement the reference count
- * and, if zero, collect the NodeValue.
- */
- ~NodeTemplate();
-
- /**
- * Return the null node.
- * @return the null node
- */
- static NodeTemplate null() {
- return s_null;
- }
-
- /**
- * Returns true if this expression is a null expression.
- * @return true if null
- */
- bool isNull() const {
- return d_nv == &NodeValue::s_null;
- }
-
- /**
- * Structural comparison operator for expressions.
- * @param node the node to compare to
- * @return true if expressions are equal, false otherwise
- */
- template <bool ref_count_1>
- bool operator==(const NodeTemplate<ref_count_1>& node) const {
- return d_nv == node.d_nv;
- }
-
- /**
- * Structural comparison operator for expressions.
- * @param node the node to compare to
- * @return false if expressions are equal, true otherwise
- */
- template <bool ref_count_1>
- bool operator!=(const NodeTemplate<ref_count_1>& node) const {
- return d_nv != node.d_nv;
- }
+class NodeTemplate {
+
+ /**
+ * The NodeValue has access to the private constructors, so that the
+ * iterators can can create new nodes.
+ */
+ friend class expr::NodeValue;
+
+ /** A convenient null-valued encapsulated pointer */
+ static NodeTemplate s_null;
+
+ /** The referenced NodeValue */
+ expr::NodeValue* d_nv;
+
+ /**
+ * This constructor is reserved for use by the NodeTemplate package; one
+ * must construct an NodeTemplate using one of the build mechanisms of the
+ * NodeTemplate package.
+ *
+ * FIXME: there's a type-system escape here to cast away the const,
+ * since the refcount needs to be updated. But conceptually Nodes
+ * don't change their arguments, and it's nice to have
+ * const_iterators over them.
+ *
+ * This really does needs to be explicit to avoid hard to track errors with
+ * Nodes implicitly wrapping NodeValues
+ */
+ explicit NodeTemplate(const expr::NodeValue*);
+
+ friend class NodeTemplate<true> ;
+ friend class NodeTemplate<false> ;
+ friend class NodeManager;
+
+ template<unsigned>
+ friend class NodeBuilder;
+
+ friend class ::CVC4::expr::attr::AttributeManager;
+
+ /**
+ * Assigns the expression value and does reference counting. No assumptions
+ * are made on the expression, and should only be used if we know what we
+ * are doing.
+ *
+ * @param ev the expression value to assign
+ */
+ void assignNodeValue(expr::NodeValue* ev);
+
+public:
+
+ /** Default constructor, makes a null expression. */
+ NodeTemplate() : d_nv(&expr::NodeValue::s_null) { }
+
+ /**
+ * Conversion between nodes that are reference-counted and those that are
+ * not.
+ * @param node the node to make copy of
+ */
+ NodeTemplate(const NodeTemplate<!ref_count>& node);
+
+ /**
+ * Copy constructor. Note that GCC does NOT recognize an instantiation of
+ * the above template as a copy constructor and problems ensue. So we
+ * provide an explicit one here.
+ * @param node the node to make copy of
+ */
+ NodeTemplate(const NodeTemplate& node);
+
+ /**
+ * Assignment operator for nodes, copies the relevant information from node
+ * to this node.
+ * @param node the node to copy
+ * @return reference to this node
+ */
+ NodeTemplate& operator=(const NodeTemplate& node);
+
+ /**
+ * Assignment operator for nodes, copies the relevant information from node
+ * to this node.
+ * @param node the node to copy
+ * @return reference to this node
+ */
+ NodeTemplate& operator=(const NodeTemplate<!ref_count>& node);
+
+ /**
+ * Destructor. If ref_count is true it will decrement the reference count
+ * and, if zero, collect the NodeValue.
+ */
+ ~NodeTemplate() throw();
+
+ /**
+ * Return the null node.
+ * @return the null node
+ */
+ static NodeTemplate null() {
+ return s_null;
+ }
- /**
- * We compare by expression ids so, keeping things deterministic and having
- * that subexpressions have to be smaller than the enclosing expressions.
- * @param node the node to compare to
- * @return true if this expression is smaller
- */
- template <bool ref_count_1>
- inline bool operator<(const NodeTemplate<ref_count_1>& node) const {
- return d_nv->d_id < node.d_nv->d_id;
- }
+ /**
+ * Returns true if this expression is a null expression.
+ * @return true if null
+ */
+ bool isNull() const {
+ return d_nv == &expr::NodeValue::s_null;
+ }
- /**
- * Returns the i-th child of this node.
- * @param i the index of the child
- * @return the node representing the i-th child
- */
- NodeTemplate operator[](int i) const {
- Assert(i >= 0 && unsigned(i) < d_nv->d_nchildren);
- return NodeTemplate(d_nv->d_children[i]);
- }
+ /**
+ * Structural comparison operator for expressions.
+ * @param node the node to compare to
+ * @return true if expressions are equal, false otherwise
+ */
+ template <bool ref_count_1>
+ bool operator==(const NodeTemplate<ref_count_1>& node) const {
+ return d_nv == node.d_nv;
+ }
- /**
- * Returns true if this node is atomic (has no more Boolean structure)
- * @return true if atomic
- */
- bool isAtomic() const;
-
- /**
- * Returns the hash value of this node.
- * @return the hash value
- */
- size_t hash() const {
- return d_nv->getId();
- }
+ /**
+ * Structural comparison operator for expressions.
+ * @param node the node to compare to
+ * @return false if expressions are equal, true otherwise
+ */
+ template <bool ref_count_1>
+ bool operator!=(const NodeTemplate<ref_count_1>& node) const {
+ return d_nv != node.d_nv;
+ }
- /**
- * Returns the unique id of this node
- * @return the ud
- */
- uint64_t getId() const {
- return d_nv->getId();
- }
+ /**
+ * We compare by expression ids so, keeping things deterministic and having
+ * that subexpressions have to be smaller than the enclosing expressions.
+ * @param node the node to compare to
+ * @return true if this expression is smaller
+ */
+ template <bool ref_count_1>
+ inline bool operator<(const NodeTemplate<ref_count_1>& node) const {
+ return d_nv->d_id < node.d_nv->d_id;
+ }
- /**
- * Returns a node representing the operator of this expression.
- * If this is an APPLY, then the operator will be a functional term.
- * Otherwise, it will be a node with kind BUILTIN
- */
- inline NodeTemplate<true> getOperator() const {
- switch(getKind()) {
- case kind::APPLY:
- /* The operator is the first child. */
- return NodeTemplate<true> (d_nv->d_children[0]);
-
- case kind::EQUAL:
- case kind::ITE:
- case kind::TUPLE:
- case kind::NOT:
- case kind::AND:
- case kind::IFF:
- case kind::IMPLIES:
- case kind::OR:
- case kind::XOR:
- case kind::PLUS:
- /* Should return a BUILTIN node. */
- Unimplemented("getOperator() on non-APPLY kind: " + getKind());
- break;
-
- case kind::FALSE:
- case kind::TRUE:
- case kind::SKOLEM:
- case kind::VARIABLE:
- IllegalArgument(*this,"getOperator() called on kind with no operator");
- break;
-
- default:
- Unhandled(getKind());
- }
-
- NodeTemplate<true> n; // NULL Node for default return
- return n;
- }
+ /**
+ * Returns the i-th child of this node.
+ * @param i the index of the child
+ * @return the node representing the i-th child
+ */
+ NodeTemplate operator[](int i) const {
+ Assert(i >= 0 && unsigned(i) < d_nv->d_nchildren);
+ return NodeTemplate(d_nv->d_children[i]);
+ }
- /** Returns true if the node has an operator (i.e., it's not a variable or a constant). */
- inline bool hasOperator() const {
- switch(getKind()) {
- case kind::APPLY:
- case kind::EQUAL:
- case kind::ITE:
- case kind::TUPLE:
- case kind::FALSE:
- case kind::TRUE:
- case kind::NOT:
- case kind::AND:
- case kind::IFF:
- case kind::IMPLIES:
- case kind::OR:
- case kind::XOR:
- case kind::PLUS:
- return true;
-
- case kind::SKOLEM:
- case kind::VARIABLE:
- return false;
-
- default:
- Unhandled(getKind());
- }
+ /**
+ * Returns true if this node is atomic (has no more Boolean structure)
+ * @return true if atomic
+ */
+ bool isAtomic() const;
+
+ /**
+ * Returns the hash value of this node.
+ * @return the hash value
+ */
+ size_t hash() const {
+ return d_nv->getId();
+ }
- }
+ /**
+ * Returns the unique id of this node
+ * @return the ud
+ */
+ uint64_t getId() const {
+ return d_nv->getId();
+ }
- /**
- * Returns the type of this node.
- * @return the type
- */
- const Type* getType() const;
-
- /**
- * Returns the kind of this node.
- * @return the kind
- */
- inline Kind getKind() const {
- return Kind(d_nv->d_kind);
- }
+ /**
+ * Returns a node representing the operator of this expression.
+ * If this is an APPLY, then the operator will be a functional term.
+ * Otherwise, it will be a node with kind BUILTIN
+ */
+ NodeTemplate<true> getOperator() const;
+
+ /** Returns true if the node has an operator (i.e., it's not a variable or a constant). */
+ bool hasOperator() const;
+
+ /**
+ * Returns the type of this node.
+ * @return the type
+ */
+ const Type* getType() const;
+
+ /**
+ * Returns the kind of this node.
+ * @return the kind
+ */
+ inline Kind getKind() const {
+ return Kind(d_nv->d_kind);
+ }
- /**
- * Returns the number of children this node has.
- * @return the number of children
- */
- inline size_t getNumChildren() const;
-
- /**
- * Returns the value of the given attribute that this has been attached.
- * @param attKind the kind of the attribute
- * @return the value of the attribute
- */
- template <class AttrKind>
- inline typename AttrKind::value_type getAttribute(const AttrKind& attKind) const;
-
- // Note that there are two, distinct hasAttribute() declarations for
- // a reason (rather than using a pointer-valued argument with a
- // default value): they permit more optimized code in the underlying
- // hasAttribute() implementations.
-
- /**
- * Returns true if this node has been associated an attribute of given kind.
- * Additionaly, if a pointer to the value_kind is give, and the attribute
- * value has been set for this node, it will be returned.
- * @param attKind the kind of the attribute
- * @return true if this node has the requested attribute
- */
- template <class AttrKind>
- inline bool hasAttribute(const AttrKind& attKind) const;
-
- /**
- * Returns true if this node has been associated an attribute of given kind.
- * Additionaly, if a pointer to the value_kind is give, and the attribute
- * value has been set for this node, it will be returned.
- * @param attKind the kind of the attribute
- * @param value where to store the value if it exists
- * @return true if this node has the requested attribute
- */
- template <class AttrKind>
- inline bool hasAttribute(const AttrKind& attKind, typename AttrKind::value_type& value) const;
-
- /**
- * Sets the given attribute of this node to the given value.
- * @param attKind the kind of the atribute
- * @param value the value to set the attribute to
- */
- template <class AttrKind>
- inline void setAttribute(const AttrKind& attKind,
- const typename AttrKind::value_type& value);
-
- /** Iterator allowing for scanning through the children. */
- typedef typename NodeValue::iterator<ref_count> iterator;
- /** Constant iterator allowing for scanning through the children. */
- typedef typename NodeValue::iterator<ref_count> const_iterator;
-
- /**
- * Returns the iterator pointing to the first child.
- * @return the iterator
- */
- inline iterator begin() {
- return d_nv->begin<ref_count>();
- }
+ /**
+ * Returns the number of children this node has.
+ * @return the number of children
+ */
+ inline size_t getNumChildren() const;
+
+ /**
+ * Returns the value of the given attribute that this has been attached.
+ * @param attKind the kind of the attribute
+ * @return the value of the attribute
+ */
+ template <class AttrKind>
+ inline typename AttrKind::value_type getAttribute(const AttrKind& attKind) const;
+
+ // Note that there are two, distinct hasAttribute() declarations for
+ // a reason (rather than using a pointer-valued argument with a
+ // default value): they permit more optimized code in the underlying
+ // hasAttribute() implementations.
+
+ /**
+ * Returns true if this node has been associated an attribute of given kind.
+ * Additionaly, if a pointer to the value_kind is give, and the attribute
+ * value has been set for this node, it will be returned.
+ * @param attKind the kind of the attribute
+ * @return true if this node has the requested attribute
+ */
+ template <class AttrKind>
+ inline bool hasAttribute(const AttrKind& attKind) const;
+
+ /**
+ * Returns true if this node has been associated an attribute of given kind.
+ * Additionaly, if a pointer to the value_kind is give, and the attribute
+ * value has been set for this node, it will be returned.
+ * @param attKind the kind of the attribute
+ * @param value where to store the value if it exists
+ * @return true if this node has the requested attribute
+ */
+ template <class AttrKind>
+ inline bool hasAttribute(const AttrKind& attKind,
+ typename AttrKind::value_type& value) const;
+
+ /**
+ * Sets the given attribute of this node to the given value.
+ * @param attKind the kind of the atribute
+ * @param value the value to set the attribute to
+ */
+ template <class AttrKind>
+ inline void setAttribute(const AttrKind& attKind,
+ const typename AttrKind::value_type& value);
+
+ /** Iterator allowing for scanning through the children. */
+ typedef typename expr::NodeValue::iterator<ref_count> iterator;
+ /** Constant iterator allowing for scanning through the children. */
+ typedef typename expr::NodeValue::iterator<ref_count> const_iterator;
+
+ /**
+ * Returns the iterator pointing to the first child.
+ * @return the iterator
+ */
+ inline iterator begin() {
+ return d_nv->begin<ref_count>();
+ }
- /**
- * Returns the iterator pointing to the end of the children (one beyond the
- * last one.
- * @return the end of the children iterator.
- */
- inline iterator end() {
- return d_nv->end<ref_count>();
- }
+ /**
+ * Returns the iterator pointing to the end of the children (one beyond the
+ * last one.
+ * @return the end of the children iterator.
+ */
+ inline iterator end() {
+ return d_nv->end<ref_count>();
+ }
- /**
- * Returns the const_iterator pointing to the first child.
- * @return the const_iterator
- */
- inline const_iterator begin() const {
- return d_nv->begin<ref_count>();
- }
+ /**
+ * Returns the const_iterator pointing to the first child.
+ * @return the const_iterator
+ */
+ inline const_iterator begin() const {
+ return d_nv->begin<ref_count>();
+ }
- /**
- * Returns the const_iterator pointing to the end of the children (one
- * beyond the last one.
- * @return the end of the children const_iterator.
- */
- inline const_iterator end() const {
- return d_nv->end<ref_count>();
- }
+ /**
+ * Returns the const_iterator pointing to the end of the children (one
+ * beyond the last one.
+ * @return the end of the children const_iterator.
+ */
+ inline const_iterator end() const {
+ return d_nv->end<ref_count>();
+ }
- /**
- * Converts this node into a string representation.
- * @return the string representation of this node.
- */
- inline std::string toString() const {
- return d_nv->toString();
- }
+ /**
+ * Converts this node into a string representation.
+ * @return the string representation of this node.
+ */
+ inline std::string toString() const {
+ return d_nv->toString();
+ }
- /**
- * Converst this node into a string representation and sends it to the
- * given stream
- * @param out the sream to serialise this node to
- */
- inline void toStream(std::ostream& out) const {
- d_nv->toStream(out);
- }
+ /**
+ * Converst this node into a string representation and sends it to the
+ * given stream
+ * @param out the sream to serialise this node to
+ */
+ inline void toStream(std::ostream& out) const {
+ d_nv->toStream(out);
+ }
- /**
- * Very basic pretty printer for Node.
- * @param o output stream to print to.
- * @param indent number of spaces to indent the formula by.
- */
- void printAst(std::ostream & o, int indent = 0) const;
-
- NodeTemplate<true> eqNode(const NodeTemplate& right) const;
-
- NodeTemplate<true> notNode() const;
- NodeTemplate<true> andNode(const NodeTemplate& right) const;
- NodeTemplate<true> orNode(const NodeTemplate& right) const;
- NodeTemplate<true> iteNode(const NodeTemplate& thenpart,
- const NodeTemplate& elsepart) const;
- NodeTemplate<true> iffNode(const NodeTemplate& right) const;
- NodeTemplate<true> impNode(const NodeTemplate& right) const;
- NodeTemplate<true> xorNode(const NodeTemplate& right) const;
-
- private:
-
- /**
- * Indents the given stream a given amount of spaces.
- * @param out the stream to indent
- * @param indent the numer of spaces
- */
- static void indent(std::ostream& out, int indent) {
- for(int i = 0; i < indent; i++)
- out << ' ';
- }
+ /**
+ * Very basic pretty printer for Node.
+ * @param o output stream to print to.
+ * @param indent number of spaces to indent the formula by.
+ */
+ void printAst(std::ostream & o, int indent = 0) const;
+
+ NodeTemplate<true> eqNode(const NodeTemplate& right) const;
+
+ NodeTemplate<true> notNode() const;
+ NodeTemplate<true> andNode(const NodeTemplate& right) const;
+ NodeTemplate<true> orNode(const NodeTemplate& right) const;
+ NodeTemplate<true> iteNode(const NodeTemplate& thenpart,
+ const NodeTemplate& elsepart) const;
+ NodeTemplate<true> iffNode(const NodeTemplate& right) const;
+ NodeTemplate<true> impNode(const NodeTemplate& right) const;
+ NodeTemplate<true> xorNode(const NodeTemplate& right) const;
+
+private:
+
+ /**
+ * Indents the given stream a given amount of spaces.
+ * @param out the stream to indent
+ * @param indent the numer of spaces
+ */
+ static void indent(std::ostream& out, int indent) {
+ for(int i = 0; i < indent; i++)
+ out << ' ';
+ }
- };/* class NodeTemplate */
+};/* class NodeTemplate */
/**
* Serializes a given node to the given stream.
@@ -464,239 +410,313 @@ inline std::ostream& operator<<(std::ostream& out, const Node& node) {
#include <ext/hash_map>
-// for hashtables
-namespace __gnu_cxx {
-template<>
- struct hash<CVC4::Node> {
- size_t operator()(const CVC4::Node& node) const {
- return (size_t) node.hash();
- }
- };
-}/* __gnu_cxx namespace */
-
#include "expr/attribute.h"
#include "expr/node_manager.h"
namespace CVC4 {
-template<bool ref_count>
- inline size_t NodeTemplate<ref_count>::getNumChildren() const {
- return d_nv->d_nchildren;
+// for hash_maps, hash_sets..
+struct NodeHashFcn {
+ size_t operator()(const CVC4::Node& node) const {
+ return (size_t) node.hash();
}
+};
template<bool ref_count>
- template<class AttrKind>
- inline typename AttrKind::value_type NodeTemplate<ref_count>::
- getAttribute(const AttrKind&) const {
- Assert( NodeManager::currentNM() != NULL,
+inline size_t NodeTemplate<ref_count>::getNumChildren() const {
+ return d_nv->d_nchildren;
+}
+
+template<bool ref_count>
+template<class AttrKind>
+inline typename AttrKind::value_type NodeTemplate<ref_count>::
+getAttribute(const AttrKind&) const {
+ Assert( NodeManager::currentNM() != NULL,
"There is no current CVC4::NodeManager associated to this thread.\n"
"Perhaps a public-facing function is missing a NodeManagerScope ?" );
- return NodeManager::currentNM()->getAttribute(*this, AttrKind());
- }
+ return NodeManager::currentNM()->getAttribute(*this, AttrKind());
+}
template<bool ref_count>
- template<class AttrKind>
- inline bool NodeTemplate<ref_count>::
- hasAttribute(const AttrKind&) const {
- Assert( NodeManager::currentNM() != NULL,
+template<class AttrKind>
+inline bool NodeTemplate<ref_count>::
+hasAttribute(const AttrKind&) const {
+ Assert( NodeManager::currentNM() != NULL,
"There is no current CVC4::NodeManager associated to this thread.\n"
"Perhaps a public-facing function is missing a NodeManagerScope ?" );
- return NodeManager::currentNM()->hasAttribute(*this, AttrKind());
- }
+ return NodeManager::currentNM()->hasAttribute(*this, AttrKind());
+}
template<bool ref_count>
- template<class AttrKind>
- inline bool NodeTemplate<ref_count>::
- hasAttribute(const AttrKind&, typename AttrKind::value_type& ret) const {
- Assert( NodeManager::currentNM() != NULL,
+template<class AttrKind>
+inline bool NodeTemplate<ref_count>::
+hasAttribute(const AttrKind&, typename AttrKind::value_type& ret) const {
+ Assert( NodeManager::currentNM() != NULL,
"There is no current CVC4::NodeManager associated to this thread.\n"
"Perhaps a public-facing function is missing a NodeManagerScope ?" );
- return NodeManager::currentNM()->hasAttribute(*this, AttrKind(), ret);
- }
+ return NodeManager::currentNM()->hasAttribute(*this, AttrKind(), ret);
+}
template<bool ref_count>
- template<class AttrKind>
- inline void NodeTemplate<ref_count>::
- setAttribute(const AttrKind&, const typename AttrKind::value_type& value) {
- Assert( NodeManager::currentNM() != NULL,
+template<class AttrKind>
+inline void NodeTemplate<ref_count>::
+setAttribute(const AttrKind&, const typename AttrKind::value_type& value) {
+ Assert( NodeManager::currentNM() != NULL,
"There is no current CVC4::NodeManager associated to this thread.\n"
"Perhaps a public-facing function is missing a NodeManagerScope ?" );
- NodeManager::currentNM()->setAttribute(*this, AttrKind(), value);
- }
+ NodeManager::currentNM()->setAttribute(*this, AttrKind(), value);
+}
template<bool ref_count>
- NodeTemplate<ref_count> NodeTemplate<ref_count>::s_null(&NodeValue::s_null);
+NodeTemplate<ref_count> NodeTemplate<ref_count>::s_null(&expr::NodeValue::s_null);
////FIXME: This function is a major hack! Should be changed ASAP
////TODO: Should use positive definition, i.e. what kinds are atomic.
template<bool ref_count>
- bool NodeTemplate<ref_count>::isAtomic() const {
- using namespace kind;
- switch(getKind()) {
- case NOT:
- case XOR:
- case ITE:
- case IFF:
- case IMPLIES:
- case OR:
- case AND:
- return false;
- default:
- return true;
- }
+bool NodeTemplate<ref_count>::isAtomic() const {
+ using namespace kind;
+ switch(getKind()) {
+ case NOT:
+ case XOR:
+ case ITE:
+ case IFF:
+ case IMPLIES:
+ case OR:
+ case AND:
+ return false;
+ default:
+ return true;
}
+}
// FIXME: escape from type system convenient but is there a better
// way? Nodes conceptually don't change their expr values but of
// course they do modify the refcount. But it's nice to be able to
// support node_iterators over const NodeValue*. So.... hm.
template<bool ref_count>
- NodeTemplate<ref_count>::NodeTemplate(const NodeValue* ev) :
- d_nv(const_cast<NodeValue*> (ev)) {
- Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
- if(ref_count)
- d_nv->inc();
+NodeTemplate<ref_count>::NodeTemplate(const expr::NodeValue* ev) :
+ d_nv(const_cast<expr::NodeValue*> (ev)) {
+ Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
+ if(ref_count) {
+ d_nv->inc();
}
+}
// the code for these two "conversion/copy constructors" is identical, but
// apparently we need both. see comment in the class.
template<bool ref_count>
- NodeTemplate<ref_count>::NodeTemplate(const NodeTemplate<!ref_count>& e) {
- Assert(e.d_nv != NULL, "Expecting a non-NULL expression value!");
- d_nv = e.d_nv;
- if(ref_count)
- d_nv->inc();
+NodeTemplate<ref_count>::NodeTemplate(const NodeTemplate<!ref_count>& e) {
+ Assert(e.d_nv != NULL, "Expecting a non-NULL expression value!");
+ d_nv = e.d_nv;
+ if(ref_count) {
+ d_nv->inc();
}
+}
template<bool ref_count>
- NodeTemplate<ref_count>::NodeTemplate(const NodeTemplate& e) {
- Assert(e.d_nv != NULL, "Expecting a non-NULL expression value!");
- d_nv = e.d_nv;
- if(ref_count)
- d_nv->inc();
+NodeTemplate<ref_count>::NodeTemplate(const NodeTemplate& e) {
+ Assert(e.d_nv != NULL, "Expecting a non-NULL expression value!");
+ d_nv = e.d_nv;
+ if(ref_count) {
+ d_nv->inc();
}
+}
template<bool ref_count>
- NodeTemplate<ref_count>::~NodeTemplate() {
- Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
- if(ref_count)
- d_nv->dec();
- Assert(ref_count || d_nv->d_rc > 0,
- "Temporary node pointing to an expired node");
+NodeTemplate<ref_count>::~NodeTemplate() throw() {
+ DtorAssert(d_nv != NULL, "Expecting a non-NULL expression value!");
+ if(ref_count) {
+ d_nv->dec();
}
+ DtorAssert(ref_count || d_nv->d_rc > 0,
+ "Temporary node pointing to an expired node");
+}
template<bool ref_count>
- void NodeTemplate<ref_count>::assignNodeValue(NodeValue* ev) {
- d_nv = ev;
- if(ref_count)
- d_nv->inc();
+void NodeTemplate<ref_count>::assignNodeValue(expr::NodeValue* ev) {
+ d_nv = ev;
+ if(ref_count) {
+ d_nv->inc();
}
+}
template<bool ref_count>
- NodeTemplate<ref_count>& NodeTemplate<ref_count>::
- operator=(const NodeTemplate& e) {
- Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
- Assert(e.d_nv != NULL, "Expecting a non-NULL expression value on RHS!");
- if(EXPECT_TRUE( d_nv != e.d_nv )) {
- if(ref_count)
- d_nv->dec();
- d_nv = e.d_nv;
- if(ref_count)
- d_nv->inc();
+NodeTemplate<ref_count>& NodeTemplate<ref_count>::
+operator=(const NodeTemplate& e) {
+ Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
+ Assert(e.d_nv != NULL, "Expecting a non-NULL expression value on RHS!");
+ if(EXPECT_TRUE( d_nv != e.d_nv )) {
+ if(ref_count) {
+ d_nv->dec();
+ }
+ d_nv = e.d_nv;
+ if(ref_count) {
+ d_nv->inc();
}
- return *this;
}
+ return *this;
+}
template<bool ref_count>
- NodeTemplate<ref_count>& NodeTemplate<ref_count>::
- operator=(const NodeTemplate<!ref_count>& e) {
- Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
- Assert(e.d_nv != NULL, "Expecting a non-NULL expression value on RHS!");
- if(EXPECT_TRUE( d_nv != e.d_nv )) {
- if(ref_count)
- d_nv->dec();
- d_nv = e.d_nv;
- if(ref_count)
- d_nv->inc();
+NodeTemplate<ref_count>& NodeTemplate<ref_count>::
+operator=(const NodeTemplate<!ref_count>& e) {
+ Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
+ Assert(e.d_nv != NULL, "Expecting a non-NULL expression value on RHS!");
+ if(EXPECT_TRUE( d_nv != e.d_nv )) {
+ if(ref_count) {
+ d_nv->dec();
+ }
+ d_nv = e.d_nv;
+ if(ref_count) {
+ d_nv->inc();
}
- return *this;
}
+ return *this;
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::eqNode(const NodeTemplate<
- ref_count>& right) const {
- return NodeManager::currentNM()->mkNode(kind::EQUAL, *this, right);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::eqNode(const NodeTemplate<
+ ref_count>& right) const {
+ return NodeManager::currentNM()->mkNode(kind::EQUAL, *this, right);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::notNode() const {
- return NodeManager::currentNM()->mkNode(kind::NOT, *this);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::notNode() const {
+ return NodeManager::currentNM()->mkNode(kind::NOT, *this);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::andNode(const NodeTemplate<
- ref_count>& right) const {
- return NodeManager::currentNM()->mkNode(kind::AND, *this, right);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::andNode(const NodeTemplate<
+ ref_count>& right) const {
+ return NodeManager::currentNM()->mkNode(kind::AND, *this, right);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::orNode(const NodeTemplate<
- ref_count>& right) const {
- return NodeManager::currentNM()->mkNode(kind::OR, *this, right);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::orNode(const NodeTemplate<
+ ref_count>& right) const {
+ return NodeManager::currentNM()->mkNode(kind::OR, *this, right);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::iteNode(const NodeTemplate<
- ref_count>& thenpart, const NodeTemplate<ref_count>& elsepart) const {
- return NodeManager::currentNM()->mkNode(kind::ITE, *this, thenpart, elsepart);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::iteNode(const NodeTemplate<
+ ref_count>& thenpart, const NodeTemplate<ref_count>& elsepart) const {
+ return NodeManager::currentNM()->mkNode(kind::ITE, *this, thenpart, elsepart);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::iffNode(const NodeTemplate<
- ref_count>& right) const {
- return NodeManager::currentNM()->mkNode(kind::IFF, *this, right);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::iffNode(const NodeTemplate<
+ ref_count>& right) const {
+ return NodeManager::currentNM()->mkNode(kind::IFF, *this, right);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::impNode(const NodeTemplate<
- ref_count>& right) const {
- return NodeManager::currentNM()->mkNode(kind::IMPLIES, *this, right);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::impNode(const NodeTemplate<
+ ref_count>& right) const {
+ return NodeManager::currentNM()->mkNode(kind::IMPLIES, *this, right);
+}
template<bool ref_count>
- NodeTemplate<true> NodeTemplate<ref_count>::xorNode(const NodeTemplate<
- ref_count>& right) const {
- return NodeManager::currentNM()->mkNode(kind::XOR, *this, right);
- }
+NodeTemplate<true> NodeTemplate<ref_count>::xorNode(const NodeTemplate<
+ ref_count>& right) const {
+ return NodeManager::currentNM()->mkNode(kind::XOR, *this, right);
+}
template<bool ref_count>
- void NodeTemplate<ref_count>::printAst(std::ostream& out, int ind) const {
- indent(out, ind);
- out << '(';
- out << getKind();
- if(getKind() == kind::VARIABLE) {
- out << ' ' << getId();
-
- } else if(getNumChildren() >= 1) {
- for(const_iterator child = begin(); child != end(); ++child) {
- out << std::endl;
- NodeTemplate((*child)).printAst(out, ind + 1);
- }
+void NodeTemplate<ref_count>::printAst(std::ostream& out, int ind) const {
+ indent(out, ind);
+ out << '(';
+ out << getKind();
+ if(getKind() == kind::VARIABLE) {
+ out << ' ' << getId();
+
+ } else if(getNumChildren() >= 1) {
+ for(const_iterator child = begin(); child != end(); ++child) {
out << std::endl;
- indent(out, ind);
+ NodeTemplate((*child)).printAst(out, ind + 1);
}
- out << ')';
+ out << std::endl;
+ indent(out, ind);
}
+ out << ')';
+}
-template<bool ref_count>
- const Type* NodeTemplate<ref_count>::getType() const {
- Assert( NodeManager::currentNM() != NULL,
- "There is no current CVC4::NodeManager associated to this thread.\n"
- "Perhaps a public-facing function is missing a NodeManagerScope ?" );
- return NodeManager::currentNM()->getType(*this);
+/**
+ * Returns a node representing the operator of this expression.
+ * If this is an APPLY, then the operator will be a functional term.
+ * Otherwise, it will be a node with kind BUILTIN
+ */
+template <bool ref_count>
+NodeTemplate<true> NodeTemplate<ref_count>::getOperator() const {
+ switch(Kind k = getKind()) {
+ case kind::APPLY:
+ /* The operator is the first child. */
+ return NodeTemplate<true>(d_nv->d_children[0]);
+
+ case kind::EQUAL:
+ case kind::ITE:
+ case kind::TUPLE:
+ case kind::NOT:
+ case kind::AND:
+ case kind::IFF:
+ case kind::IMPLIES:
+ case kind::OR:
+ case kind::XOR:
+ case kind::PLUS: {
+ /* Returns a BUILTIN node. */
+ /* TODO: construct a singleton at load-time? */
+ /* TODO: maybe keep a table like the TheoryOfTable ? */
+ NodeTemplate<true> n = NodeManager::currentNM()->mkNode(k);
+ return NodeManager::currentNM()->mkNode(kind::BUILTIN, n);
}
+ case kind::FALSE:
+ case kind::TRUE:
+ case kind::SKOLEM:
+ case kind::VARIABLE:
+ IllegalArgument(*this, "getOperator() called on kind with no operator");
+
+ default:
+ Unhandled(getKind());
+ }
+}
+
+/**
+ * Returns true if the node has an operator (i.e., it's not a variable or a constant).
+ */
+template <bool ref_count>
+bool NodeTemplate<ref_count>::hasOperator() const {
+ switch(getKind()) {
+ case kind::APPLY:
+ case kind::EQUAL:
+ case kind::ITE:
+ case kind::TUPLE:
+ case kind::FALSE:
+ case kind::TRUE:
+ case kind::NOT:
+ case kind::AND:
+ case kind::IFF:
+ case kind::IMPLIES:
+ case kind::OR:
+ case kind::XOR:
+ case kind::PLUS:
+ return true;
+
+ case kind::SKOLEM:
+ case kind::VARIABLE:
+ return false;
+
+ default:
+ Unhandled(getKind());
+ }
+}
+template<bool ref_count>
+const Type* NodeTemplate<ref_count>::getType() const {
+ Assert( NodeManager::currentNM() != NULL,
+ "There is no current CVC4::NodeManager associated to this thread.\n"
+ "Perhaps a public-facing function is missing a NodeManagerScope ?" );
+ return NodeManager::currentNM()->getType(*this);
+}
/**
* Pretty printer for use within gdb. This is not intended to be used
@@ -721,7 +741,6 @@ static void __attribute__((used)) debugPrintTNode(const NodeTemplate<false>& n)
Warning().flush();
}
-
}/* CVC4 namespace */
#endif /* __CVC4__NODE_H */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback