/********************* */ /*! \file attribute.h ** \verbatim ** Original author: mdeters ** Major contributors: dejan ** Minor contributors (to current version): cconway, taking ** This file is part of the CVC4 prototype. ** Copyright (c) 2009-2012 New York University and The University of Iowa ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** ** \brief Node attributes. ** ** Node attributes. **/ #include "cvc4_private.h" /* There are strong constraints on ordering of declarations of * attributes and nodes due to template use */ #include "expr/node.h" #include "expr/type_node.h" #ifndef __CVC4__EXPR__ATTRIBUTE_H #define __CVC4__EXPR__ATTRIBUTE_H #include #include // include supporting templates #define CVC4_ATTRIBUTE_H__INCLUDING__ATTRIBUTE_INTERNALS_H #include "expr/attribute_internals.h" #undef CVC4_ATTRIBUTE_H__INCLUDING__ATTRIBUTE_INTERNALS_H namespace CVC4 { namespace expr { namespace attr { // ATTRIBUTE MANAGER =========================================================== /** * A container for the main attribute tables of the system. There's a * one-to-one NodeManager : AttributeManager correspondence. */ class AttributeManager { // IF YOU ADD ANY TABLES, don't forget to add them also to the // implementation of deleteAllAttributes(). /** Underlying hash table for boolean-valued attributes */ AttrHash d_bools; /** Underlying hash table for integral-valued attributes */ AttrHash d_ints; /** Underlying hash table for node-valued attributes */ AttrHash d_tnodes; /** Underlying hash table for node-valued attributes */ AttrHash d_nodes; /** Underlying hash table for types attributes */ AttrHash d_types; /** Underlying hash table for string-valued attributes */ AttrHash d_strings; /** Underlying hash table for pointer-valued attributes */ AttrHash d_ptrs; // IF YOU ADD ANY TABLES, don't forget to add them also to the // implementation of deleteAllAttributes(). /** Underlying hash table for context-dependent boolean-valued attributes */ CDAttrHash d_cdbools; /** Underlying hash table for context-dependent integral-valued attributes */ CDAttrHash d_cdints; /** Underlying hash table for context-dependent node-valued attributes */ CDAttrHash d_cdtnodes; /** Underlying hash table for context-dependent node-valued attributes */ CDAttrHash d_cdnodes; /** Underlying hash table for context-dependent string-valued attributes */ CDAttrHash d_cdstrings; /** Underlying hash table for context-dependent pointer-valued attributes */ CDAttrHash d_cdptrs; template void deleteFromTable(AttrHash& table, NodeValue* nv); template void deleteFromTable(CDAttrHash& table, NodeValue* nv); template void deleteAllFromTable(AttrHash& table); /** * getTable<> is a helper template that gets the right table from an * AttributeManager given its type. */ template friend struct getTable; public: /** Construct an attribute manager. */ AttributeManager(context::Context* ctxt) : d_cdbools(ctxt), d_cdints(ctxt), d_cdtnodes(ctxt), d_cdnodes(ctxt), d_cdstrings(ctxt), d_cdptrs(ctxt) { } /** * Get a particular attribute on a particular node. * * @param nv the node about which to inquire * @param attr the attribute kind to get * @return the attribute value, if set, or a default-constructed * AttrKind::value_type if not. */ template typename AttrKind::value_type getAttribute(NodeValue* nv, const AttrKind& attr) const; /** * Determine if a particular attribute exists for a particular node. * * @param nv the node about which to inquire * @param attr the attribute kind to inquire about * @return true if the given node has the given attribute */ template bool hasAttribute(NodeValue* nv, const AttrKind& attr) const; /** * Determine if a particular attribute exists for a particular node, * and get it if it does. * * @param nv the node about which to inquire * @param attr the attribute kind to inquire about * @param ret a pointer to a return value, set in case the node has * the attribute * @return true if the given node has the given attribute */ template bool getAttribute(NodeValue* nv, const AttrKind& attr, typename AttrKind::value_type& ret) const; /** * Set a particular attribute on a particular node. * * @param nv the node for which to set the attribute * @param attr the attribute kind to set * @param value a pointer to a return value, set in case the node has * the attribute * @return true if the given node has the given attribute */ template void setAttribute(NodeValue* nv, const AttrKind& attr, const typename AttrKind::value_type& value); /** * Remove all attributes associated to the given node. * * @param nv the node from which to delete attributes */ void deleteAllAttributes(NodeValue* nv); /** * Remove all attributes from the tables. */ void deleteAllAttributes(); }; }/* CVC4::expr::attr namespace */ // MAPPING OF ATTRIBUTE KINDS TO TABLES IN THE ATTRIBUTE MANAGER =============== namespace attr { /** * The getTable<> template provides (static) access to the * AttributeManager field holding the table. */ template struct getTable; /** Access the "d_bools" member of AttributeManager. */ template <> struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_bools; } static inline const table_type& get(const AttributeManager& am) { return am.d_bools; } }; /** Access the "d_ints" member of AttributeManager. */ template <> struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_ints; } static inline const table_type& get(const AttributeManager& am) { return am.d_ints; } }; /** Access the "d_tnodes" member of AttributeManager. */ template <> struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_tnodes; } static inline const table_type& get(const AttributeManager& am) { return am.d_tnodes; } }; /** Access the "d_nodes" member of AttributeManager. */ template <> struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_nodes; } static inline const table_type& get(const AttributeManager& am) { return am.d_nodes; } }; /** Access the "d_types" member of AttributeManager. */ template <> struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_types; } static inline const table_type& get(const AttributeManager& am) { return am.d_types; } }; /** Access the "d_strings" member of AttributeManager. */ template <> struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_strings; } static inline const table_type& get(const AttributeManager& am) { return am.d_strings; } }; /** Access the "d_ptrs" member of AttributeManager. */ template struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_ptrs; } static inline const table_type& get(const AttributeManager& am) { return am.d_ptrs; } }; /** Access the "d_ptrs" member of AttributeManager. */ template struct getTable { typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_ptrs; } static inline const table_type& get(const AttributeManager& am) { return am.d_ptrs; } }; /** Access the "d_cdbools" member of AttributeManager. */ template <> struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdbools; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdbools; } }; /** Access the "d_cdints" member of AttributeManager. */ template <> struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdints; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdints; } }; /** Access the "d_tnodes" member of AttributeManager. */ template <> struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdtnodes; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdtnodes; } }; /** Access the "d_cdnodes" member of AttributeManager. */ template <> struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdnodes; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdnodes; } }; /** Access the "d_cdstrings" member of AttributeManager. */ template <> struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdstrings; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdstrings; } }; /** Access the "d_cdptrs" member of AttributeManager. */ template struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdptrs; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdptrs; } }; /** Access the "d_cdptrs" member of AttributeManager. */ template struct getTable { typedef CDAttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_cdptrs; } static inline const table_type& get(const AttributeManager& am) { return am.d_cdptrs; } }; }/* CVC4::expr::attr namespace */ // ATTRIBUTE MANAGER IMPLEMENTATIONS =========================================== namespace attr { // implementation for AttributeManager::getAttribute() template typename AttrKind::value_type AttributeManager::getAttribute(NodeValue* nv, const AttrKind&) const { typedef typename AttrKind::value_type value_type; typedef KindValueToTableValueMapping mapping; typedef typename getTable:: table_type table_type; const table_type& ah = getTable::get(*this); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); if(i == ah.end()) { return typename AttrKind::value_type(); } return mapping::convertBack((*i).second); } /* Helper template class for hasAttribute(), specialized based on * whether AttrKind has a "default value" that all Nodes implicitly * have or not. */ template struct HasAttribute; /** * Specialization of HasAttribute<> helper template for AttrKinds * with a default value. */ template struct HasAttribute { /** This implementation is simple; it's always true. */ static inline bool hasAttribute(const AttributeManager* am, NodeValue* nv) { return true; } /** * This implementation returns the AttrKind's default value if the * Node doesn't have the given attribute. */ static inline bool getAttribute(const AttributeManager* am, NodeValue* nv, typename AttrKind::value_type& ret) { typedef typename AttrKind::value_type value_type; typedef KindValueToTableValueMapping mapping; typedef typename getTable::table_type table_type; const table_type& ah = getTable::get(*am); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); if(i == ah.end()) { ret = AttrKind::default_value; } else { ret = mapping::convertBack((*i).second); } return true; } }; /** * Specialization of HasAttribute<> helper template for AttrKinds * without a default value. */ template struct HasAttribute { static inline bool hasAttribute(const AttributeManager* am, NodeValue* nv) { typedef typename AttrKind::value_type value_type; typedef KindValueToTableValueMapping mapping; typedef typename getTable:: table_type table_type; const table_type& ah = getTable::get(*am); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); if(i == ah.end()) { return false; } return true; } static inline bool getAttribute(const AttributeManager* am, NodeValue* nv, typename AttrKind::value_type& ret) { typedef typename AttrKind::value_type value_type; typedef KindValueToTableValueMapping mapping; typedef typename getTable:: table_type table_type; const table_type& ah = getTable::get(*am); typename table_type::const_iterator i = ah.find(std::make_pair(AttrKind::getId(), nv)); if(i == ah.end()) { return false; } ret = mapping::convertBack((*i).second); return true; } }; template bool AttributeManager::hasAttribute(NodeValue* nv, const AttrKind&) const { return HasAttribute:: hasAttribute(this, nv); } template bool AttributeManager::getAttribute(NodeValue* nv, const AttrKind&, typename AttrKind::value_type& ret) const { return HasAttribute:: getAttribute(this, nv, ret); } template inline void AttributeManager::setAttribute(NodeValue* nv, 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(), nv)] = mapping::convert(value); } /** * Search for the NodeValue in all attribute tables and remove it, * calling the cleanup function if one is defined. */ template inline void AttributeManager::deleteFromTable(AttrHash& table, NodeValue* nv) { for(uint64_t id = 0; id < attr::LastAttributeId::s_id; ++id) { typedef AttributeTraits traits_t; typedef AttrHash hash_t; std::pair pr = std::make_pair(id, nv); if(traits_t::cleanup[id] != NULL) { typename hash_t::iterator i = table.find(pr); if(i != table.end()) { traits_t::cleanup[id]((*i).second); table.erase(pr); } } else { table.erase(pr); } } } /** * Obliterate a NodeValue from a (context-dependent) attribute table. */ template inline void AttributeManager::deleteFromTable(CDAttrHash& table, NodeValue* nv) { for(unsigned id = 0; id < attr::LastAttributeId::s_id; ++id) { table.obliterate(std::make_pair(id, nv)); } } /** * Remove all attributes from the table calling the cleanup function * if one is defined. */ template inline void AttributeManager::deleteAllFromTable(AttrHash& table) { bool anyRequireClearing = false; typedef AttributeTraits traits_t; typedef AttrHash hash_t; for(uint64_t id = 0; id < attr::LastAttributeId::s_id; ++id) { if(traits_t::cleanup[id] != NULL) { anyRequireClearing = true; } } if(anyRequireClearing) { typename hash_t::iterator it = table.begin(); typename hash_t::iterator it_end = table.end(); while (it != it_end){ uint64_t id = (*it).first.first; Debug("attrgc") << "id " << id << " node_value: " << ((*it).first.second) << std::endl; if(traits_t::cleanup[id] != NULL) { traits_t::cleanup[id]((*it).second); } ++it; } } table.clear(); } }/* CVC4::expr::attr namespace */ }/* CVC4::expr namespace */ }/* CVC4 namespace */ #endif /* __CVC4__EXPR__ATTRIBUTE_H */