1 /********************* */
4 ** Original author: dejan
5 ** Major contributors: none
6 ** Minor contributors (to current version): taking
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
14 ** \brief Reference-counted encapsulation of a pointer to node information.
16 ** Reference-counted encapsulation of a pointer to node information.
19 #include "cvc4_private.h"
21 // circular dependency
22 #include "expr/node_value.h"
24 #ifndef __CVC4__TYPE_NODE_H
25 #define __CVC4__TYPE_NODE_H
32 #include "expr/kind.h"
33 #include "expr/metakind.h"
34 #include "util/Assert.h"
35 #include "util/output.h"
43 }/* CVC4::expr namespace */
46 * Encapsulation of an NodeValue pointer for Types. The reference count is
47 * maintained in the NodeValue.
52 * The NodeValue has access to the private constructors, so that the
53 * iterators can can create new types.
55 friend class expr::NodeValue
;
57 /** A convenient null-valued encapsulated pointer */
58 static TypeNode s_null
;
60 /** The referenced NodeValue */
61 expr::NodeValue
* d_nv
;
64 * This constructor is reserved for use by the TypeNode package.
66 explicit TypeNode(const expr::NodeValue
*);
68 friend class NodeManager
;
70 template <unsigned nchild_thresh
>
71 friend class NodeBuilder
;
74 * Assigns the expression value and does reference counting. No assumptions
75 * are made on the expression, and should only be used if we know what we
78 * @param ev the expression value to assign
80 void assignNodeValue(expr::NodeValue
* ev
);
84 /** Default constructor, makes a null expression. */
85 TypeNode() : d_nv(&expr::NodeValue::s_null
) { }
87 /** Copy constructor */
88 TypeNode(const TypeNode
& node
);
91 * Assignment operator for nodes, copies the relevant information from node
93 * @param node the node to copy
94 * @return reference to this node
96 TypeNode
& operator=(const TypeNode
& typeNode
);
99 * Destructor. If ref_count is true it will decrement the reference count
100 * and, if zero, collect the NodeValue.
102 ~TypeNode() throw(AssertionException
);
105 * Return the null node.
106 * @return the null node
108 static TypeNode
null() {
113 * Structural comparison operator for expressions.
114 * @param typeNode the type node to compare to
115 * @return true if expressions are equal, false otherwise
117 bool operator==(const TypeNode
& typeNode
) const {
118 return d_nv
== typeNode
.d_nv
|| (typeNode
.isReal() && this->isReal());
122 * Structural comparison operator for expressions.
123 * @param typeNode the type node to compare to
124 * @return true if expressions are equal, false otherwise
126 bool operator!=(const TypeNode
& typeNode
) const {
127 return !(*this == typeNode
);
131 * We compare by expression ids so, keeping things deterministic and having
132 * that subexpressions have to be smaller than the enclosing expressions.
133 * @param node the node to compare to
134 * @return true if this expression is smaller
136 inline bool operator<(const TypeNode
& typeNode
) const {
137 return d_nv
->d_id
< typeNode
.d_nv
->d_id
;
141 * Returns the i-th child of this node.
142 * @param i the index of the child
143 * @return the node representing the i-th child
145 TypeNode
operator[](int i
) const {
146 return TypeNode(d_nv
->getChild(i
));
150 * Returns the unique id of this node
153 unsigned getId() const {
154 return d_nv
->getId();
158 * Returns the kind of this type node.
161 inline Kind
getKind() const {
162 return Kind(d_nv
->d_kind
);
166 * Returns the metakind of this type node.
167 * @return the metakind
169 inline kind::MetaKind
getMetaKind() const {
170 return kind::metaKindOf(getKind());
174 * Returns the number of children this node has.
175 * @return the number of children
177 inline size_t getNumChildren() const;
180 * If this is a CONST_* TypeNode, extract the constant from it.
183 inline const T
& getConst() const;
186 * Returns the value of the given attribute that this has been attached.
187 * @param attKind the kind of the attribute
188 * @return the value of the attribute
190 template <class AttrKind
>
191 inline typename
AttrKind::value_type
getAttribute(const AttrKind
& attKind
) const;
193 // Note that there are two, distinct hasAttribute() declarations for
194 // a reason (rather than using a pointer-valued argument with a
195 // default value): they permit more optimized code in the underlying
196 // hasAttribute() implementations.
199 * Returns true if this node has been associated an attribute of given kind.
200 * Additionaly, if a pointer to the value_kind is give, and the attribute
201 * value has been set for this node, it will be returned.
202 * @param attKind the kind of the attribute
203 * @return true if this node has the requested attribute
205 template <class AttrKind
>
206 inline bool hasAttribute(const AttrKind
& attKind
) const;
209 * Returns true if this node has been associated an attribute of given kind.
210 * Additionaly, if a pointer to the value_kind is give, and the attribute
211 * value has been set for this node, it will be returned.
212 * @param attKind the kind of the attribute
213 * @param value where to store the value if it exists
214 * @return true if this node has the requested attribute
216 template <class AttrKind
>
217 inline bool getAttribute(const AttrKind
& attKind
,
218 typename
AttrKind::value_type
& value
) const;
221 * Sets the given attribute of this node to the given value.
222 * @param attKind the kind of the atribute
223 * @param value the value to set the attribute to
225 template <class AttrKind
>
226 inline void setAttribute(const AttrKind
& attKind
,
227 const typename
AttrKind::value_type
& value
);
229 /** Iterator allowing for scanning through the children. */
230 typedef expr::NodeValue::iterator
<TypeNode
> iterator
;
231 /** Constant iterator allowing for scanning through the children. */
232 typedef expr::NodeValue::iterator
<TypeNode
> const_iterator
;
235 * Returns the iterator pointing to the first child.
236 * @return the iterator
238 inline iterator
begin() {
239 return d_nv
->begin
<TypeNode
>();
243 * Returns the iterator pointing to the end of the children (one beyond the
245 * @return the end of the children iterator.
247 inline iterator
end() {
248 return d_nv
->end
<TypeNode
>();
252 * Returns the const_iterator pointing to the first child.
253 * @return the const_iterator
255 inline const_iterator
begin() const {
256 return d_nv
->begin
<TypeNode
>();
260 * Returns the const_iterator pointing to the end of the children (one
261 * beyond the last one.
262 * @return the end of the children const_iterator.
264 inline const_iterator
end() const {
265 return d_nv
->end
<TypeNode
>();
269 * Converts this node into a string representation.
270 * @return the string representation of this node.
272 inline std::string
toString() const {
273 return d_nv
->toString();
277 * Converst this node into a string representation and sends it to the
279 * @param out the sream to serialise this node to
281 inline void toStream(std::ostream
& out
, int toDepth
= -1) const {
282 d_nv
->toStream(out
, toDepth
);
286 * Very basic pretty printer for Node.
287 * @param o output stream to print to.
288 * @param indent number of spaces to indent the formula by.
290 void printAst(std::ostream
& o
, int indent
= 0) const;
293 * Returns true if this type is a null type.
294 * @return true if null
296 bool isNull() const {
297 return d_nv
== &expr::NodeValue::s_null
;
300 /** Is this the Boolean type? */
301 bool isBoolean() const;
303 /** Is this the Integer type? */
304 bool isInteger() const;
306 /** Is this the Real type? */
309 /** Is this a function type? */
310 bool isFunction() const;
312 /** Get the argument types */
313 std::vector
<TypeNode
> getArgTypes() const;
315 /** Get the range type (i.e., the type of the result). */
316 TypeNode
getRangeType() const;
318 /** Is this a predicate type? NOTE: all predicate types are also
320 bool isPredicate() const;
322 /** Is this a bit-vector type */
323 bool isBitVector() const;
325 /** Is this a bit-vector type of size <code>size</code> */
326 bool isBitVector(unsigned size
) const;
328 /** Get the size of this bit-vector type */
329 unsigned getBitVectorSize() const;
331 /** Is this a sort kind */
334 /** Is this a kind type (i.e., the type of a type)? */
340 * Indents the given stream a given amount of spaces.
341 * @param out the stream to indent
342 * @param indent the numer of spaces
344 static void indent(std::ostream
& out
, int indent
) {
345 for(int i
= 0; i
< indent
; i
++) {
350 };/* class TypeNode */
353 * Serializes a given node to the given stream.
354 * @param out the output stream to use
355 * @param node the node to output to the stream
356 * @return the changed stream.
358 inline std::ostream
& operator<<(std::ostream
& out
, const TypeNode
& n
) {
359 n
.toStream(out
, Node::setdepth::getDepth(out
));
363 }/* CVC4 namespace */
365 #include <ext/hash_map>
367 #include "expr/node_manager.h"
371 // for hash_maps, hash_sets..
372 struct TypeNodeHashFunction
{
373 size_t operator()(const CVC4::TypeNode
& node
) const {
374 return (size_t) node
.getId();
378 inline size_t TypeNode::getNumChildren() const {
379 return d_nv
->getNumChildren();
383 inline const T
& TypeNode::getConst() const {
384 return d_nv
->getConst
<T
>();
387 inline TypeNode::TypeNode(const expr::NodeValue
* ev
) :
388 d_nv(const_cast<expr::NodeValue
*> (ev
)) {
389 Assert(d_nv
!= NULL
, "Expecting a non-NULL expression value!");
393 inline TypeNode::TypeNode(const TypeNode
& typeNode
) {
394 Assert(typeNode
.d_nv
!= NULL
, "Expecting a non-NULL expression value!");
395 d_nv
= typeNode
.d_nv
;
399 inline TypeNode::~TypeNode() throw(AssertionException
) {
400 Assert(d_nv
!= NULL
, "Expecting a non-NULL expression value!");
404 inline void TypeNode::assignNodeValue(expr::NodeValue
* ev
) {
409 inline TypeNode
& TypeNode::operator=(const TypeNode
& typeNode
) {
410 Assert(d_nv
!= NULL
, "Expecting a non-NULL expression value!");
411 Assert(typeNode
.d_nv
!= NULL
, "Expecting a non-NULL expression value on RHS!");
412 if(EXPECT_TRUE( d_nv
!= typeNode
.d_nv
)) {
414 d_nv
= typeNode
.d_nv
;
420 template <class AttrKind
>
421 inline typename
AttrKind::value_type
TypeNode::
422 getAttribute(const AttrKind
&) const {
423 Assert( NodeManager::currentNM() != NULL
,
424 "There is no current CVC4::NodeManager associated to this thread.\n"
425 "Perhaps a public-facing function is missing a NodeManagerScope ?" );
426 return NodeManager::currentNM()->getAttribute(d_nv
, AttrKind());
429 template <class AttrKind
>
430 inline bool TypeNode::
431 hasAttribute(const AttrKind
&) const {
432 Assert( NodeManager::currentNM() != NULL
,
433 "There is no current CVC4::NodeManager associated to this thread.\n"
434 "Perhaps a public-facing function is missing a NodeManagerScope ?" );
435 return NodeManager::currentNM()->hasAttribute(d_nv
, AttrKind());
438 template <class AttrKind
>
439 inline bool TypeNode::getAttribute(const AttrKind
&, typename
AttrKind::value_type
& ret
) const {
440 Assert( NodeManager::currentNM() != NULL
,
441 "There is no current CVC4::NodeManager associated to this thread.\n"
442 "Perhaps a public-facing function is missing a NodeManagerScope ?" );
443 return NodeManager::currentNM()->getAttribute(d_nv
, AttrKind(), ret
);
446 template <class AttrKind
>
447 inline void TypeNode::
448 setAttribute(const AttrKind
&, const typename
AttrKind::value_type
& value
) {
449 Assert( NodeManager::currentNM() != NULL
,
450 "There is no current CVC4::NodeManager associated to this thread.\n"
451 "Perhaps a public-facing function is missing a NodeManagerScope ?" );
452 NodeManager::currentNM()->setAttribute(d_nv
, AttrKind(), value
);
455 }/* CVC4 namespace */
457 #endif /* __CVC4__NODE_H */