From ce0e796ad92f040fb75435bd7880bc28a60b0374 Mon Sep 17 00:00:00 2001 From: Morgan Deters Date: Fri, 19 Feb 2010 20:29:58 +0000 Subject: * Attribute infrastructure -- static design. Documentation is coming. See test/unit/expr/node_white.h for use examples, including how to define new attribute kinds. Also: * fixes to test infrastructure * minor changes to code formatting throughout * attribute tests in test/unit/expr/node_white.h * fixes to NodeManagerScope ordering * use NodeValue::getKind() to properly deal with UNDEFINED_KIND (removing compiler warning) * ExprManager: add proper NodeManagerScope to public-facing member functions * store variable names and types in attributes * SoftNode is a placeholder, not a real implementation --- src/expr/attribute.h | 573 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 573 insertions(+) create mode 100644 src/expr/attribute.h (limited to 'src/expr/attribute.h') diff --git a/src/expr/attribute.h b/src/expr/attribute.h new file mode 100644 index 000000000..b8cddacbf --- /dev/null +++ b/src/expr/attribute.h @@ -0,0 +1,573 @@ +/********************* -*- C++ -*- */ +/** attribute.h + ** Original author: mdeters + ** Major contributors: dejan + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information. + ** + ** Node attributes. + ** + ** Attribute structures: + ** + ** An attribute structure looks like the following: + ** + ** struct VarName_attr { + ** + ** // the value type for this attribute + ** typedef std::string value_type; + ** + ** // an extra hash value (to avoid same-value-type collisions) + ** enum { hash_value = 1 }; + ** + ** // whether inclusion in the table keeps the (key) Node live or not + ** static const bool hard_key = false; + ** + ** // cleanup routine when the Node goes away + ** static inline void cleanup(const std::string&) { + ** } + ** } + **/ + +/* There are strong constraints on ordering of declarations of + * attributes and nodes due to template use */ +#include "expr/node.h" + +#ifndef __CVC4__EXPR__ATTRIBUTE_H +#define __CVC4__EXPR__ATTRIBUTE_H + +#include + +#include +#include + +#include "config.h" +#include "context/context.h" +#include "expr/soft_node.h" +#include "expr/type.h" + +#include "util/output.h" + +namespace CVC4 { +namespace expr { + +struct AttrHashFcn { + enum { LARGE_PRIME = 1 }; + std::size_t operator()(const std::pair& p) const { + return p.first * LARGE_PRIME + p.second.hash(); + } +}; + +struct AttrHashBoolFcn { + std::size_t operator()(const SoftNode& n) const { + return n.hash(); + } +}; + +/* +template +class AttrTable; + +template <> +class AttrTable { +public: + class BitAccessor { + + uint64_t& d_word; + + unsigned d_bit; + + public: + + BitAccessor(uint64_t& word, unsigned bit) : + d_word(word), + d_bit(bit) { + } + + BitAccessor& operator=(bool b) { + if(b) { + // set the bit + d_word |= (1 << d_bit); + } else { + // clear the bit + d_word &= ~(1 << d_bit); + } + + return *this; + } + }; + + // bool specialization + //static AttrHash* s_hash; + + //typedef AttrHash::iterator iterator; + //typedef AttrHash::const_iterator const_iterator; + + template + BitAccessor& find(Node e, const Attr&); + + template + bool find(Node e, const Attr&) const; +}; + +template <> +class AttrTable { +public: + // int(egral) specialization + //static AttrHash* s_hash; + typedef AttrHash::iterator iterator; + typedef AttrHash::const_iterator const_iterator; + uint64_t& find(TNode); +}; + +template +class AttrTable { +public: + // pointer specialization + //static AttrHash* s_hash; + typedef AttrHash::iterator iterator; + typedef AttrHash::const_iterator const_iterator; +}; + +template <> +class AttrTable { +public: + // Node specialization + //static AttrHash* s_hash; + typedef AttrHash::iterator iterator; + typedef AttrHash::const_iterator const_iterator; + Node find(TNode); +}; + +template <> +class AttrTable { +public: + // string specialization + //static AttrHash* s_hash; + typedef AttrHash::iterator iterator; + typedef AttrHash::const_iterator const_iterator; + Node find(TNode); +}; + +*/ + +/* +template +AttrHash* AttrTable::s_hash = &g_hash_ptr; +*/ + +template +struct KindValueToTableValueMapping { + typedef T table_value_type; + inline static T convert(const T& t) { return t; } + inline static T convertBack(const T& t) { return t; } +}; + +template <> +struct KindValueToTableValueMapping { + typedef uint64_t table_value_type; + inline static uint64_t convert(const bool& t) { return t; } + inline static bool convertBack(const uint64_t& t) { return t; } +}; + +template +struct KindValueToTableValueMapping { + typedef void* table_value_type; + inline static void* convert(const T*& t) { + return reinterpret_cast(t); + } + inline static T* convertBack(void*& t) { + return reinterpret_cast(t); + } +}; + +template +struct KindValueToTableValueMapping { + typedef void* table_value_type; + inline static void* convert(const T* const& t) { + return reinterpret_cast(const_cast(t)); + } + inline static const T* convertBack(const void*& t) { + return reinterpret_cast(t); + } +}; + +template +struct OwnTable; + +template +struct KindValueToTableValueMapping > { + typedef typename KindValueToTableValueMapping::table_value_type table_value_type; +}; + +template +struct KindTableMapping { + typedef typename AttrKind::value_type table_identifier; +}; + +// use a TAG to indicate which table it should be in +template +struct AttrHash : public __gnu_cxx::hash_map, value_type, AttrHashFcn> {}; + +/* +template <> +class AttrHash : protected __gnu_cxx::hash_map { + + typedef __gnu_cxx::hash_map super; + + class BitAccessor { + + uint64_t& d_word; + + unsigned d_bit; + + public: + + BitAccessor(uint64_t& word, unsigned bit) : + d_word(word), + d_bit(bit) { + } + + BitAccessor& operator=(bool b) { + if(b) { + // set the bit + d_word |= (1 << d_bit); + } else { + // clear the bit + d_word &= ~(1 << d_bit); + } + + return *this; + } + }; + + class BitIterator { + + std::pair& d_word; + + int d_bit; + + public: + + BitIterator() : + d_word((uint64_t&) d_bit), + d_bit(-1) { + } + + BitIterator(std::pair& entry, unsigned bit) : + d_entry(entry), + d_bit(bit) { + } + + BitAccessor operator*() { + return BitAccessor(d_word, d_bit); + } + }; + + class ConstBitIterator { + + uint64_t& d_word; + + unsigned d_bit; + + public: + + ConstBitIterator(uint64_t& word, unsigned bit) : + d_word(word), + d_bit(bit) { + } + + bool operator*() { + return (d_word & (1 << d_bit)) ? true : false; + } + }; + +public: + + typedef std::pair key_type; + typedef bool data_type; + typedef std::pair value_type; + + typedef BitIterator iterator; + typedef ConstBitIterator const_iterator; + + BitIterator find(const std::pair& k) { + super::iterator i = super::find(k.second); + if(i == super::end()) { + return BitIterator(); + } + return BitIterator(*i, k.first); + } + + ConstBitIterator find(const std::pair& k) const { + super::const_iterator i = super::find(k.second); + return ConstBitIterator(*i, k.first); + } + + BitAccessor operator[](const std::pair& k) { + uint64_t& word = super::operator[](k.second); + return BitAccessor(word, k.first); + } +}; +*/ + +/** + * An "attribute type" structure. + */ +template +struct Attribute { + + /** the value type for this attribute */ + typedef value_t value_type; + + /** cleanup routine when the Node goes away */ + static inline void cleanup(const value_t&) {} + + static inline unsigned getId() { return s_id; } + static inline unsigned getHashValue() { return s_hashValue; } + +private: + + /** an id */ + static unsigned s_id; + + /** an extra hash value (to avoid same-value-type collisions) */ + static unsigned s_hashValue; +}; + +/** + * An "attribute type" structure for boolean flags (special). + */ +template +struct Attribute { + + /** the value type for this attribute */ + typedef bool value_type; + + /** cleanup routine when the Node goes away */ + static inline void cleanup(const bool&) {} + + static inline unsigned getId() { return s_id; } + static inline unsigned getBit() { return s_bit; } + static inline unsigned getHashValue() { return s_hashValue; } + +private: + + /** an id */ + static unsigned s_id; + + /** a bit assignment */ + static unsigned s_bit; + + /** an extra hash value (to avoid same-value-type collisions) */ + static unsigned s_hashValue; +}; + +namespace attr { + struct VarName {}; + struct Type {}; + + template + struct LastAttributeId { + static unsigned s_id; + }; + + template + unsigned LastAttributeId::s_id = 0; + + struct BitAssignment { + static unsigned s_bit; + }; +}/* CVC4::expr::attr namespace */ + +typedef Attribute VarNameAttr; +typedef Attribute TypeAttr; + +/* +template +class AttributeTable { + typedef typename Attr::value_type value_type; + + AttrTable& d_table; + +}; +*/ + +/* +template +struct AttrTables { + +}; +*/ + +template +unsigned Attribute::s_id = + attr::LastAttributeId::table_value_type>::s_id++; +template +unsigned Attribute::s_hashValue = Attribute::s_id; + +template +unsigned Attribute::s_id = + attr::LastAttributeId::s_id++; +template +unsigned Attribute::s_bit = + attr::BitAssignment::s_bit++; +template +unsigned Attribute::s_hashValue = Attribute::s_id; + +class AttributeManager; + +template +struct getTable { + //inline AttrHash >& get(AttributeManager& am); +}; + +class AttributeManager { + NodeManager* d_nm; + + AttrHash d_bools; + AttrHash d_ints; + AttrHash d_exprs; + AttrHash d_strings; + AttrHash d_ptrs; + + template + friend struct getTable; + +public: + AttributeManager(NodeManager* nm) : d_nm(nm) {} + + template + typename AttrKind::value_type getAttribute(const Node& n, + const AttrKind&); + + template + bool hasAttribute(const Node& n, + const AttrKind&, + typename AttrKind::value_type* = NULL); + + template + void setAttribute(const Node& n, + const AttrKind&, + const typename AttrKind::value_type& value); +}; + +template <> +struct getTable { + typedef AttrHash table_type; + static inline table_type& get(AttributeManager& am) { + return am.d_bools; + } +}; + +template <> +struct getTable { + typedef AttrHash table_type; + static inline table_type& get(AttributeManager& am) { + return am.d_ints; + } +}; + +template <> +struct getTable { + typedef AttrHash table_type; + static inline table_type& get(AttributeManager& am) { + return am.d_exprs; + } +}; + +template <> +struct getTable { + typedef AttrHash table_type; + static inline table_type& get(AttributeManager& am) { + return am.d_strings; + } +}; + +template +struct getTable { + typedef AttrHash table_type; + static inline table_type& get(AttributeManager& am) { + return am.d_ptrs; + } +}; + +template +typename AttrKind::value_type AttributeManager::getAttribute(const Node& n, + const AttrKind& marker) { + + typedef typename AttrKind::value_type value_type; + typedef KindValueToTableValueMapping mapping; + typedef typename getTable::table_type table_type; + + table_type& ah = getTable::get(*this); + typename table_type::iterator i = ah.find(std::make_pair(AttrKind::getId(), n)); + + if(i == ah.end()) { + return typename AttrKind::value_type(); + } + + return mapping::convertBack(i->second); +} + +template +bool AttributeManager::hasAttribute(const Node& n, + const AttrKind&, + typename AttrKind::value_type* ret) { + + typedef typename AttrKind::value_type value_type; + typedef KindValueToTableValueMapping mapping; + typedef typename getTable::table_type table_type; + + table_type& ah = getTable::get(*this); + typename table_type::iterator i = ah.find(std::make_pair(AttrKind::getId(), n)); + + if(i == ah.end()) { + return false; + } + + if(ret != NULL) { + *ret = mapping::convertBack(i->second); + } + + return true; +} + +template +inline void AttributeManager::setAttribute(const Node& n, + const AttrKind&, + const typename AttrKind::value_type& value) { + + typedef typename AttrKind::value_type value_type; + typedef KindValueToTableValueMapping mapping; + typedef typename getTable::table_type table_type; + + table_type& ah = getTable::get(*this); + ah[std::make_pair(AttrKind::getId(), n)] = mapping::convert(value); +} + +/* + +template +struct last_attribute_id { + static unsigned value; +}; + +template +unsigned last_attribute_id::value = 0; + +template +unsigned register_attribute_kind() { + return last_attribute_id::value++; +} + +*/ + +}/* CVC4::expr namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__EXPR__ATTRIBUTE_H */ -- cgit v1.2.3