bool isConst() const;
/**
- * Returns true if this node represents a constant
- * @return true if const
+ * Returns true if this node represents a variable
*/
inline bool isVar() const {
assertTNodeNotExpired();
return getMetaKind() == kind::metakind::VARIABLE;
}
-
+
+ /**
+ * Returns true if this node represents a nullary operator
+ */
+ inline bool isNullaryOp() const {
+ assertTNodeNotExpired();
+ return getMetaKind() == kind::metakind::NULLARY_OPERATOR;
+ }
+
inline bool isClosure() const {
assertTNodeNotExpired();
return getKind() == kind::LAMBDA ||
bool hasType = getAttribute(n, TypeAttr(), typeNode);
bool needsCheck = check && !getAttribute(n, TypeCheckedAttr());
- Debug("getType") << "getting type for " << n << endl;
+ Debug("getType") << this << " getting type for " << &n << " " << n << ", check=" << check << ", needsCheck = " << needsCheck << ", hasType = " << hasType << endl;
+
if(needsCheck && !(*d_options)[options::earlyTypeChecking]) {
/* Iterate and compute the children bottom up. This avoids stack
overflows in computeType() when the Node graph is really deep,
}
if( readyToCompute ) {
+ Assert( check || m.getMetaKind()!=kind::metakind::NULLARY_OPERATOR );
/* All the children have types, time to compute */
typeNode = TypeChecker::computeType(this, m, check);
worklist.pop();
} else if( !hasType || needsCheck ) {
/* We can compute the type top-down, without worrying about
deep recursion. */
+ Assert( check || n.getMetaKind()!=kind::metakind::NULLARY_OPERATOR );
typeNode = TypeChecker::computeType(this, n, check);
}
}
Node NodeManager::mkNullaryOperator(const TypeNode& type, Kind k) {
+ //FIXME : this is not correct for multitheading
std::map< TypeNode, Node >::iterator it = d_unique_vars[k].find( type );
if( it==d_unique_vars[k].end() ){
- Node n = NodeBuilder<0>(this, k);
- n.setAttribute(TypeAttr(), type);
- //should type check it
- //n.setAttribute(TypeCheckedAttr(), true);
+ Node n = NodeBuilder<0>(this, k).constructNode();
+ setAttribute(n, TypeAttr(), type);
+ //setAttribute(n, TypeCheckedAttr(), true);
d_unique_vars[k][type] = n;
Assert( n.getMetaKind() == kind::metakind::NULLARY_OPERATOR );
+ Trace("ajr-temp") << this << "...made nullary operator " << n << std::endl;
return n;
}else{
+ Trace("ajr-temp") << this << "...reuse nullary operator " << it->second << std::endl;
return it->second;
}
}
string s;
if(n.getAttribute(expr::VarNameAttr(), s)) {
out << s;
- }else if( n.getKind() == kind::UNIVERSE_SET ){
- out << "UNIVERSE :: " << n.getType();
} else {
if(n.getKind() == kind::VARIABLE) {
out << "var_";
}
return;
}
+ if(n.isNullaryOp()) {
+ if( n.getKind() == kind::UNIVERSE_SET ){
+ out << "UNIVERSE :: " << n.getType();
+ }else{
+ //unknown printer
+ out << n.getKind();
+ }
+ return;
+ }
// constants
if(n.getMetaKind() == kind::metakind::CONSTANT) {
// variable
if(n.isVar()) {
- if( n.getKind() == kind::SEP_NIL ){
- out << "(as sep.nil " << n.getType() << ")";
- return;
- }else if( n.getKind() == kind::UNIVERSE_SET ){
- out << "(as univset " << n.getType() << ")";
- return;
- }else{
- string s;
- if(n.getAttribute(expr::VarNameAttr(), s)) {
- out << maybeQuoteSymbol(s);
+ string s;
+ if(n.getAttribute(expr::VarNameAttr(), s)) {
+ out << maybeQuoteSymbol(s);
+ } else {
+ if(n.getKind() == kind::VARIABLE) {
+ out << "var_";
} else {
- if(n.getKind() == kind::VARIABLE) {
- out << "var_";
- } else {
- out << n.getKind() << '_';
- }
- out << n.getId();
- }
- if(types) {
- // print the whole type, but not *its* type
- out << ":";
- n.getType().toStream(out, language::output::LANG_SMTLIB_V2_5);
+ out << n.getKind() << '_';
}
+ out << n.getId();
+ }
+ if(types) {
+ // print the whole type, but not *its* type
+ out << ":";
+ n.getType().toStream(out, language::output::LANG_SMTLIB_V2_5);
}
return;
case kind::SET_TYPE:
case kind::SINGLETON:
case kind::COMPLEMENT:out << smtKindString(k) << " "; break;
-
+ case kind::UNIVERSE_SET:out << "(as univset " << n.getType() << ")";break;
+
// fp theory
case kind::FLOATINGPOINT_FP:
case kind::FLOATINGPOINT_EQ:
case kind::PARAMETRIC_DATATYPE:
break;
- //separation
+ //separation logic
case kind::SEP_EMP:
case kind::SEP_PTO:
case kind::SEP_STAR:
case kind::SEP_WAND:out << smtKindString(k) << " "; break;
+ case kind::SEP_NIL:out << "(as sep.nil " << n.getType() << ")";break;
+
// quantifiers
case kind::FORALL:
case kind::EXISTS:
throw (TypeCheckingExceptionPrivate, AssertionException) {
Assert(n.getKind() == kind::SEP_NIL);
Assert(check);
- TypeNode type = n.getType(false);
+ TypeNode type = n.getType();
return type;
}
};/* struct SepLabelTypeRule */
Assert(n.getKind() == kind::UNIVERSE_SET);
// for nullary operators, we only computeType for check=true, since they are given TypeAttr() on creation
Assert(check);
- TypeNode setType = n.getType(false);
+ TypeNode setType = n.getType();
if(!setType.isSet()) {
throw TypeCheckingExceptionPrivate(n, "COMPLEMENT operates on a set, non-set object found");
}