1 /********************* -*- C++ -*- */
3 ** Original author: mdeters
4 ** Major contributors: dejan
5 ** Minor contributors (to current version): none
6 ** This file is part of the CVC4 prototype.
7 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
8 ** Courant Institute of Mathematical Sciences
10 ** See the file COPYING in the top-level source directory for licensing
15 ** Attribute structures:
17 ** An attribute structure looks like the following:
19 ** struct VarNameAttr {
21 ** // the value type for this attribute
22 ** typedef std::string value_type;
24 ** // an extra hash value (to avoid same-value-type collisions)
25 ** enum { hash_value = 1 };
27 ** // cleanup routine when the Node goes away
28 ** static inline void cleanup(const std::string&) {
33 /* There are strong constraints on ordering of declarations of
34 * attributes and nodes due to template use */
35 #include "expr/node.h"
37 #ifndef __CVC4__EXPR__ATTRIBUTE_H
38 #define __CVC4__EXPR__ATTRIBUTE_H
43 #include <ext/hash_map>
46 #include "context/context.h"
47 #include "expr/soft_node.h"
48 #include "expr/type.h"
50 #include "util/output.h"
55 // ATTRIBUTE HASH FUNCTIONS ====================================================
58 enum { LARGE_PRIME
= 1 };
59 std::size_t operator()(const std::pair
<unsigned, SoftNode
>& p
) const {
60 return p
.first
* LARGE_PRIME
+ p
.second
.hash();
64 struct AttrHashBoolFcn
{
65 std::size_t operator()(const SoftNode
& n
) const {
70 // ATTRIBUTE TYPE MAPPINGS =====================================================
73 struct KindValueToTableValueMapping
{
74 typedef T table_value_type
;
75 inline static T
convert(const T
& t
) { return t
; }
76 inline static T
convertBack(const T
& t
) { return t
; }
80 struct KindValueToTableValueMapping
<bool> {
81 typedef uint64_t table_value_type
;
82 inline static uint64_t convert(const bool& t
) { return t
; }
83 inline static bool convertBack(const uint64_t& t
) { return t
; }
87 struct KindValueToTableValueMapping
<T
*> {
88 typedef void* table_value_type
;
89 inline static void* convert(const T
*& t
) {
90 return reinterpret_cast<void*>(t
);
92 inline static T
* convertBack(void*& t
) {
93 return reinterpret_cast<T
*>(t
);
98 struct KindValueToTableValueMapping
<const T
*> {
99 typedef void* table_value_type
;
100 inline static void* convert(const T
* const& t
) {
101 return reinterpret_cast<void*>(const_cast<T
*>(t
));
103 inline static const T
* convertBack(const void*& t
) {
104 return reinterpret_cast<const T
*>(t
);
108 template <class AttrKind
, class T
>
111 template <class AttrKind
, class T
>
112 struct KindValueToTableValueMapping
<OwnTable
<AttrKind
, T
> > {
113 typedef typename KindValueToTableValueMapping
<T
>::table_value_type table_value_type
;
116 template <class AttrKind
>
117 struct KindTableMapping
{
118 typedef typename
AttrKind::value_type table_identifier
;
121 // ATTRIBUTE HASH TABLES =======================================================
123 // use a TAG to indicate which table it should be in
124 template <class value_type
>
125 struct AttrHash
: public __gnu_cxx::hash_map
<std::pair
<unsigned, SoftNode
>, value_type
, AttrHashFcn
> {};
128 class AttrHash
<bool> : protected __gnu_cxx::hash_map
<SoftNode
, uint64_t, AttrHashBoolFcn
> {
130 typedef __gnu_cxx::hash_map
<SoftNode
, uint64_t, AttrHashBoolFcn
> super
;
140 BitAccessor(uint64_t& word
, unsigned bit
) :
145 BitAccessor
& operator=(bool b
) {
148 d_word
|= (1 << d_bit
);
151 d_word
&= ~(1 << d_bit
);
157 operator bool() const {
158 return (d_word
& (1 << d_bit
)) ? true : false;
164 std::pair
<const SoftNode
, uint64_t>* d_entry
;
175 BitIterator(std::pair
<const SoftNode
, uint64_t>& entry
, unsigned bit
) :
180 std::pair
<const SoftNode
, BitAccessor
> operator*() {
181 return std::make_pair(d_entry
->first
, BitAccessor(d_entry
->second
, d_bit
));
184 bool operator==(const BitIterator
& b
) {
185 return d_entry
== b
.d_entry
&& d_bit
== b
.d_bit
;
189 class ConstBitIterator
{
191 const std::pair
<const SoftNode
, uint64_t>* d_entry
;
202 ConstBitIterator(const std::pair
<const SoftNode
, uint64_t>& entry
, unsigned bit
) :
207 std::pair
<const SoftNode
, bool> operator*() {
208 return std::make_pair(d_entry
->first
, (d_entry
->second
& (1 << d_bit
)) ? true : false);
211 bool operator==(const ConstBitIterator
& b
) {
212 return d_entry
== b
.d_entry
&& d_bit
== b
.d_bit
;
218 typedef std::pair
<unsigned, SoftNode
> key_type
;
219 typedef bool data_type
;
220 typedef std::pair
<const key_type
, data_type
> value_type
;
222 typedef BitIterator iterator
;
223 typedef ConstBitIterator const_iterator
;
225 BitIterator
find(const std::pair
<unsigned, SoftNode
>& k
) {
226 super::iterator i
= super::find(k
.second
);
227 if(i
== super::end()) {
228 return BitIterator();
230 Debug
.printf("boolattr", "underlying word at 0x%p looks like 0x%016llx, bit is %u\n", &(*i
).second
, (*i
).second
, k
.first
);
231 return BitIterator(*i
, k
.first
);
235 return BitIterator();
238 ConstBitIterator
find(const std::pair
<unsigned, SoftNode
>& k
) const {
239 super::const_iterator i
= super::find(k
.second
);
240 if(i
== super::end()) {
241 return ConstBitIterator();
243 Debug
.printf("boolattr", "underlying word at 0x%p looks like 0x%016llx, bit is %u\n", &(*i
).second
, (*i
).second
, k
.first
);
244 return ConstBitIterator(*i
, k
.first
);
247 ConstBitIterator
end() const {
248 return ConstBitIterator();
251 BitAccessor
operator[](const std::pair
<unsigned, SoftNode
>& k
) {
252 uint64_t& word
= super::operator[](k
.second
);
253 return BitAccessor(word
, k
.first
);
255 };/* class AttrHash<bool> */
257 // ATTRIBUTE PATTERN ===========================================================
260 * An "attribute type" structure.
262 template <class T
, class value_t
>
265 /** the value type for this attribute */
266 typedef value_t value_type
;
268 /** cleanup routine when the Node goes away */
269 static inline void cleanup(const value_t
&) {}
271 static inline unsigned getId() { return s_id
; }
272 static inline unsigned getHashValue() { return s_hashValue
; }
274 static const bool has_default_value
= false;
279 static const unsigned s_id
;
281 /** an extra hash value (to avoid same-value-type collisions) */
282 static const unsigned s_hashValue
;
286 * An "attribute type" structure for boolean flags (special).
289 struct Attribute
<T
, bool> {
291 /** the value type for this attribute */
292 typedef bool value_type
;
294 /** cleanup routine when the Node goes away */
295 static inline void cleanup(const bool&) {}
297 static inline unsigned getId() { return s_id
; }
298 static inline unsigned getHashValue() { return s_hashValue
; }
300 static const bool has_default_value
= true;
301 static const bool default_value
= false;
303 static inline unsigned checkID(unsigned id
) {
304 AlwaysAssert(id
<= 63,
305 "Too many boolean node attributes registered during initialization !");
311 /** a bit assignment */
312 static const unsigned s_id
;
314 /** an extra hash value (to avoid same-value-type collisions) */
315 static const unsigned s_hashValue
;
318 // SPECIFIC, GLOBAL ATTRIBUTE DEFINITIONS ======================================
325 struct LastAttributeId
{
326 static unsigned s_id
;
330 unsigned LastAttributeId
<T
>::s_id
= 0;
331 }/* CVC4::expr::attr namespace */
333 typedef Attribute
<attr::VarName
, std::string
> VarNameAttr
;
334 typedef Attribute
<attr::Type
, const CVC4::Type
*> TypeAttr
;
336 // ATTRIBUTE IDENTIFIER ASSIGNMENT =============================================
338 template <class T
, class value_t
>
339 const unsigned Attribute
<T
, value_t
>::s_id
=
340 attr::LastAttributeId
<typename KindValueToTableValueMapping
<value_t
>::table_value_type
>::s_id
++;
341 template <class T
, class value_t
>
342 const unsigned Attribute
<T
, value_t
>::s_hashValue
= Attribute
<T
, value_t
>::s_id
;
345 const unsigned Attribute
<T
, bool>::s_id
=
346 Attribute
<T
, bool>::checkID(attr::LastAttributeId
<bool>::s_id
++);
348 const unsigned Attribute
<T
, bool>::s_hashValue
= Attribute
<T
, bool>::s_id
;
350 class AttributeManager
;
354 //inline AttrHash<KindTableValueMapping<T> >& get(AttributeManager& am);
357 // ATTRIBUTE MANAGER ===========================================================
359 class AttributeManager
{
362 AttrHash
<bool> d_bools
;
363 AttrHash
<uint64_t> d_ints
;
364 AttrHash
<SoftNode
> d_exprs
;
365 AttrHash
<std::string
> d_strings
;
366 AttrHash
<void*> d_ptrs
;
369 friend struct getTable
;
372 AttributeManager(NodeManager
* nm
) : d_nm(nm
) {}
374 template <class AttrKind
>
375 typename
AttrKind::value_type
getAttribute(const Node
& n
,
378 template <class AttrKind
>
379 bool hasAttribute(const Node
& n
,
382 template <class AttrKind
>
383 bool hasAttribute(const Node
& n
,
385 typename
AttrKind::value_type
*);
387 template <class AttrKind
>
388 void setAttribute(const Node
& n
,
390 const typename
AttrKind::value_type
& value
);
393 // MAPPING OF ATTRIBUTE KINDS TO TABLES IN THE ATTRIBUTE MANAGER ===============
396 struct getTable
<bool> {
397 typedef AttrHash
<bool> table_type
;
398 static inline table_type
& get(AttributeManager
& am
) {
404 struct getTable
<uint64_t> {
405 typedef AttrHash
<uint64_t> table_type
;
406 static inline table_type
& get(AttributeManager
& am
) {
412 struct getTable
<Node
> {
413 typedef AttrHash
<SoftNode
> table_type
;
414 static inline table_type
& get(AttributeManager
& am
) {
420 struct getTable
<std::string
> {
421 typedef AttrHash
<std::string
> table_type
;
422 static inline table_type
& get(AttributeManager
& am
) {
428 struct getTable
<T
*> {
429 typedef AttrHash
<void*> table_type
;
430 static inline table_type
& get(AttributeManager
& am
) {
435 // ATTRIBUTE MANAGER IMPLEMENTATIONS ===========================================
437 template <class AttrKind
>
438 typename
AttrKind::value_type
AttributeManager::getAttribute(const Node
& n
,
441 typedef typename
AttrKind::value_type value_type
;
442 typedef KindValueToTableValueMapping
<value_type
> mapping
;
443 typedef typename getTable
<value_type
>::table_type table_type
;
445 table_type
& ah
= getTable
<value_type
>::get(*this);
446 typename
table_type::iterator i
= ah
.find(std::make_pair(AttrKind::getId(), n
));
449 return typename
AttrKind::value_type();
452 return mapping::convertBack((*i
).second
);
455 /* helper template class for hasAttribute(), specialized based on
456 * whether AttrKind has a "default value" that all Nodes implicitly
458 template <bool has_default
, class AttrKind
>
461 template <class AttrKind
>
462 struct HasAttribute
<true, AttrKind
> {
463 static inline bool hasAttribute(AttributeManager
* am
,
468 static inline bool hasAttribute(AttributeManager
* am
,
470 typename
AttrKind::value_type
* ret
) {
472 typedef typename
AttrKind::value_type value_type
;
473 typedef KindValueToTableValueMapping
<value_type
> mapping
;
474 typedef typename getTable
<value_type
>::table_type table_type
;
476 table_type
& ah
= getTable
<value_type
>::get(*am
);
477 typename
table_type::iterator i
= ah
.find(std::make_pair(AttrKind::getId(), n
));
480 *ret
= AttrKind::default_value
;
482 *ret
= mapping::convertBack((*i
).second
);
490 template <class AttrKind
>
491 struct HasAttribute
<false, AttrKind
> {
492 static inline bool hasAttribute(AttributeManager
* am
,
494 typedef typename
AttrKind::value_type value_type
;
495 typedef KindValueToTableValueMapping
<value_type
> mapping
;
496 typedef typename getTable
<value_type
>::table_type table_type
;
498 table_type
& ah
= getTable
<value_type
>::get(*am
);
499 typename
table_type::iterator i
= ah
.find(std::make_pair(AttrKind::getId(), n
));
508 static inline bool hasAttribute(AttributeManager
* am
,
510 typename
AttrKind::value_type
* ret
) {
511 typedef typename
AttrKind::value_type value_type
;
512 typedef KindValueToTableValueMapping
<value_type
> mapping
;
513 typedef typename getTable
<value_type
>::table_type table_type
;
515 table_type
& ah
= getTable
<value_type
>::get(*am
);
516 typename
table_type::iterator i
= ah
.find(std::make_pair(AttrKind::getId(), n
));
523 *ret
= mapping::convertBack((*i
).second
);
530 template <class AttrKind
>
531 bool AttributeManager::hasAttribute(const Node
& n
,
533 return HasAttribute
<AttrKind::has_default_value
, AttrKind
>::hasAttribute(this, n
);
536 template <class AttrKind
>
537 bool AttributeManager::hasAttribute(const Node
& n
,
539 typename
AttrKind::value_type
* ret
) {
540 return HasAttribute
<AttrKind::has_default_value
, AttrKind
>::hasAttribute(this, n
, ret
);
543 template <class AttrKind
>
544 inline void AttributeManager::setAttribute(const Node
& n
,
546 const typename
AttrKind::value_type
& value
) {
548 typedef typename
AttrKind::value_type value_type
;
549 typedef KindValueToTableValueMapping
<value_type
> mapping
;
550 typedef typename getTable
<value_type
>::table_type table_type
;
552 table_type
& ah
= getTable
<value_type
>::get(*this);
553 ah
[std::make_pair(AttrKind::getId(), n
)] = mapping::convert(value
);
556 }/* CVC4::expr namespace */
557 }/* CVC4 namespace */
559 #endif /* __CVC4__EXPR__ATTRIBUTE_H */