* don't change their arguments, and it's nice to have
* const_iterators over them. See notes in .cpp file for
* details. */
+ // this really does needs to be explicit to avoid hard to track
+ // errors with Nodes implicitly wrapping NodeValues
explicit Node(const NodeValue*);
template <unsigned> friend class NodeBuilder;
friend class NodeManager;
- /** Access to the encapsulated expression.
- * @return the encapsulated expression. */
- NodeValue const* operator->() const;
-
/**
* 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
*/
void assignNodeValue(NodeValue* ev);
- typedef NodeValue::iterator ev_iterator;
- typedef NodeValue::const_iterator const_ev_iterator;
+ typedef NodeValue::ev_iterator ev_iterator;
+ typedef NodeValue::const_ev_iterator const_ev_iterator;
inline ev_iterator ev_begin();
inline ev_iterator ev_end();
return d_ev->d_id < e.d_ev->d_id;
}
-inline std::ostream& operator<<(std::ostream& out, const Node& e) {
+inline std::ostream&
+
+operator<<(std::ostream& out, const Node& e) {
e.toStream(out);
return out;
}
#include "expr/kind.h"
#include "util/Assert.h"
#include "expr/node_value.h"
+#include "util/output.h"
namespace CVC4 {
}
}
+ void crop() {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
+ if(EXPECT_FALSE( evIsAllocated() ) && EXPECT_TRUE( d_size > d_ev->d_nchildren )) {
+ d_ev = (NodeValue*)
+ std::realloc(d_ev, sizeof(NodeValue) +
+ ( sizeof(NodeValue*) * (d_size = d_ev->d_nchildren) ));
+ }
+ }
+
public:
inline NodeBuilder();
typedef NodeValue::ev_iterator iterator;
typedef NodeValue::const_ev_iterator const_iterator;
- iterator begin() { return d_ev->ev_begin(); }
- iterator end() { return d_ev->ev_end(); }
- const_iterator begin() const { return d_ev->ev_begin(); }
- const_iterator end() const { return d_ev->ev_end(); }
+ iterator begin() {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
+ return d_ev->ev_begin();
+ }
+ iterator end() {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
+ return d_ev->ev_end();
+ }
+ const_iterator begin() const {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
+ return d_ev->ev_begin();
+ }
+ const_iterator end() const {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
+ return d_ev->ev_end();
+ }
// Compound expression constructors
/*
// "Stream" expression constructor syntax
NodeBuilder& operator<<(const Kind& k) {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
Assert(d_ev->d_kind == UNDEFINED_KIND);
d_ev->d_kind = k;
return *this;
}
NodeBuilder& operator<<(const Node& n) {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
return append(n);
}
// For pushing sequences of children
NodeBuilder& append(const std::vector<Node>& children) {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
return append(children.begin(), children.end());
}
NodeBuilder& append(const Node& n) {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
allocateEvIfNecessaryForAppend();
NodeValue* ev = n.d_ev;
d_hash = NodeValue::computeHash(d_hash, ev);
template <class Iterator>
NodeBuilder& append(const Iterator& begin, const Iterator& end) {
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
for(Iterator i = begin; i != end; ++i) {
append(*i);
}
return *this;
}
- void crop() {
- if(EXPECT_FALSE( evIsAllocated() ) && d_size > d_ev->d_nchildren) {
- d_ev = (NodeValue*)
- std::realloc(d_ev, sizeof(NodeValue) +
- ( sizeof(NodeValue*) * (d_size = d_ev->d_nchildren) ));
- }
- }
-
// not const
operator Node();
d_inlineEv(0),
d_childrenStorage(0) {
+ Message() << "kind " << k << std::endl;
d_inlineEv.d_kind = k;
}
d_inlineEv(0),
d_childrenStorage() {
+ Message() << "kind " << k << std::endl;
d_inlineEv.d_kind = k;
}
template <unsigned nchild_thresh>
inline NodeBuilder<nchild_thresh>::~NodeBuilder() {
- for(iterator i = begin();
- i != end();
+ Assert(d_used, "NodeBuilder unused at destruction");
+
+ return;
+ /*
+ for(iterator i = d_ev->ev_begin();
+ i != d_ev->ev_end();
++i) {
(*i)->dec();
}
if(evIsAllocated()) {
free(d_ev);
}
+ */
}
template <unsigned nchild_thresh>
template <unsigned nchild_thresh>
NodeBuilder<nchild_thresh>::operator Node() {// not const
+ Assert(!d_used, "NodeBuilder is one-shot only; tried to access it after conversion");
Assert(d_ev->d_kind != UNDEFINED_KIND,
"Can't make an expression of an undefined kind!");
- Assert(! d_used, "This NodeBuilder has already been used!");
// implementation differs depending on whether the expression value
// was malloc'ed or not
if(EXPECT_FALSE( evIsAllocated() )) {
NodeValue *ev = d_nm->lookupNoInsert(d_hash, d_ev);
- if(ev != d_ev) {
+ if(ev != NULL) {
// expression already exists in node manager
+ d_used = true;
return Node(ev);
}
// otherwise create the canonical expression value for this node
crop();
- d_used = true;
ev = d_ev;
d_ev = NULL;
// this inserts into the NodeManager;
// return the result of lookup() in case another thread beat us to it
+ d_used = true;
return d_nm->lookup(d_hash, ev);
}
NodeValue *ev = d_nm->lookupNoInsert(d_hash, &d_inlineEv);
- if(ev != &d_inlineEv) {
+ if(ev != NULL) {
// expression already exists in node manager
+ d_used = true;
return Node(ev);
}
#include "node_builder.h"
#include "node_manager.h"
#include "expr/node.h"
+#include "util/output.h"
namespace CVC4 {
continue;
}
- NodeValue::const_iterator c1 = ev->ev_begin();
- NodeValue::iterator c2 = j->d_ev->ev_begin();
+ NodeValue::const_ev_iterator c1 = ev->ev_begin();
+ NodeValue::ev_iterator c2 = j->d_ev->ev_begin();
for(; c1 != ev->ev_end() && c2 != j->d_ev->ev_end(); ++c1, ++c2) {
- if((*c1).d_ev != (*c2).d_ev) {
+ if(*c1 != *c2) {
break;
}
}
- if(c1 != ev->ev_end() || c2 != j->end()) {
+ if(c1 != ev->ev_end() || c2 != j->d_ev->ev_end()) {
continue;
}
continue;
}
- NodeValue::const_iterator c1 = ev->ev_begin();
- NodeValue::iterator c2 = j->d_ev->ev_begin();
+ NodeValue::const_ev_iterator c1 = ev->ev_begin();
+ NodeValue::ev_iterator c2 = j->d_ev->ev_begin();
for(; c1 != ev->ev_end() && c2 != j->d_ev->ev_end(); ++c1, ++c2) {
- if((*c1).d_ev != (*c2).d_ev) {
+ Debug("expr") << "comparing " << c1 << " and " << c2 << std::endl;
+ if(*c1 != *c2) {
break;
}
}
- if(c1 != ev->ev_end() || c2 != j->end()) {
+ if(c1 != ev->ev_end() || c2 != j->d_ev->ev_end()) {
continue;
}
return j->d_ev;
}
- // didn't find it
+ // didn't find it, don't insert
return 0;
}
}
* @return the hash value
*/
template<typename const_iterator_type>
- static uint64_t computeHash(uint64_t hash, const_iterator_type begin, const_iterator_type end) {
+ static uint64_t computeHash(uint64_t hash, const_iterator_type begin,
+ const_iterator_type end) {
for(const_iterator_type i = begin; i != end; ++i) {
hash = computeHash(hash, *i);
}
}
static uint64_t computeHash(uint64_t hash, const NodeValue* ev) {
- return ( (hash << 3) | ((hash & 0xE000000000000000ull) >> 61) ) ^ ev->getId();
+ return
+ ( (hash << 3) | ((hash & 0xE000000000000000ull) >> 61) ) ^ ev->getId();
}
typedef NodeValue** ev_iterator;
class node_iterator {
const_ev_iterator d_i;
public:
- node_iterator(const_ev_iterator i) : d_i(i) {}
+ explicit node_iterator(const_ev_iterator i) : d_i(i) {}
inline Node operator*();
return d_i != i.d_i;
}
- node_iterator& operator++() {
+ node_iterator operator++() {
++d_i;
return *this;
}
namespace expr {
inline Node NodeValue::node_iterator::operator*() {
- return Node(*d_i);
+ return Node((NodeValue*) d_i);
}
}/* CVC4::expr namespace */