inline bool
NodeTemplate<ref_count>::isConst() const {
assertTNodeNotExpired();
+ Debug("isConst") << "Node::isConst() for " << getKind() << " with " << getNumChildren() << " children" << std::endl;
if(isNull()) {
return false;
}
switch(getMetaKind()) {
case kind::metakind::CONSTANT:
+ Debug("isConst") << "Node::isConst() returning true, it's a CONSTANT" << std::endl;
return true;
case kind::metakind::VARIABLE:
+ Debug("isConst") << "Node::isConst() returning false, it's a VARIABLE" << std::endl;
return false;
default:
if(getAttribute(IsConstComputedAttr())) {
- return getAttribute(IsConstAttr());
+ bool bval = getAttribute(IsConstAttr());
+ Debug("isConst") << "Node::isConst() returning cached value " << bval << std::endl;
+ return bval;
} else {
bool bval = expr::TypeChecker::computeIsConst(NodeManager::currentNM(), *this);
+ Debug("isConst") << "Node::isConst() computed value " << bval << std::endl;
const_cast< NodeTemplate<ref_count>* >(this)->setAttribute(IsConstAttr(), bval);
const_cast< NodeTemplate<ref_count>* >(this)->setAttribute(IsConstComputedAttr(), true);
return bval;
typerule APPLY_TESTER ::CVC4::theory::datatypes::DatatypeTesterTypeRule
typerule APPLY_TYPE_ASCRIPTION ::CVC4::theory::datatypes::DatatypeAscriptionTypeRule
+# constructor applications are constant if they are applied only to constants
+construle APPLY_CONSTRUCTOR ::CVC4::theory::datatypes::DatatypeConstructorTypeRule
+
endtheory
struct DatatypeConstructorTypeRule {
inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
- throw(TypeCheckingExceptionPrivate) {
+ throw(TypeCheckingExceptionPrivate, AssertionException) {
Assert(n.getKind() == kind::APPLY_CONSTRUCTOR);
TypeNode consType = n.getOperator().getType(check);
Type t = consType.getConstructorRangeType().toType();
Debug("typecheck-idt") << "typecheck cons arg: " << childType << " " << (*tchild_it) << std::endl;
TypeNode argumentType = *tchild_it;
if(!childType.isSubtypeOf(argumentType)) {
- throw TypeCheckingExceptionPrivate(n, "bad type for constructor argument");
+ std::stringstream ss;
+ ss << "bad type for constructor argument:\nexpected: " << argumentType << "\ngot : " << childType;
+ throw TypeCheckingExceptionPrivate(n, ss.str());
}
}
}
return consType.getConstructorRangeType();
}
}
+
+ inline static bool computeIsConst(NodeManager* nodeManager, TNode n)
+ throw(AssertionException) {
+ Assert(n.getKind() == kind::APPLY_CONSTRUCTOR);
+ NodeManagerScope nms(nodeManager);
+ for(TNode::const_iterator i = n.begin(); i != n.end(); ++i) {
+ if( ! (*i).isConst() ) {
+ return false;
+ }
+ }
+ return true;
+ }
};/* struct DatatypeConstructorTypeRule */
struct DatatypeSelectorTypeRule {
void testIsConst() {
/* bool isConst() const; */
+ Debug.on("isConst");
+
TS_ASSERT(!a_bool->isConst());
TS_ASSERT(!b_bool->isConst());
TS_ASSERT(!c_bool_and->isConst());
TS_ASSERT(plus_op->isConst());
TS_ASSERT(!d_apply_fun_bool->isConst());
TS_ASSERT(!null->isConst());
+
+ // more complicated "constants" exist in datatypes and arrays theories
+ Datatype list("list");
+ DatatypeConstructor consC("cons");
+ consC.addArg("car", d_em->integerType());
+ consC.addArg("cdr", DatatypeSelfType());
+ list.addConstructor(consC);
+ list.addConstructor(DatatypeConstructor("nil"));
+ DatatypeType listType = d_em->mkDatatypeType(list);
+ Expr cons = listType.getDatatype().getConstructor("cons");
+ Expr nil = listType.getDatatype().getConstructor("nil");
+ Expr x = d_em->mkVar("x", d_em->integerType());
+ Expr cons_x_nil = d_em->mkExpr(APPLY_CONSTRUCTOR, cons, x, d_em->mkExpr(APPLY_CONSTRUCTOR, nil));
+ Expr cons_1_nil = d_em->mkExpr(APPLY_CONSTRUCTOR, cons, d_em->mkConst(Rational(1)), d_em->mkExpr(APPLY_CONSTRUCTOR, nil));
+ Expr cons_1_cons_2_nil = d_em->mkExpr(APPLY_CONSTRUCTOR, cons, d_em->mkConst(Rational(1)), d_em->mkExpr(APPLY_CONSTRUCTOR, cons, d_em->mkConst(Rational(2)), d_em->mkExpr(APPLY_CONSTRUCTOR, nil)));
+ TS_ASSERT(d_em->mkExpr(APPLY_CONSTRUCTOR, nil).isConst());
+ TS_ASSERT(!cons_x_nil.isConst());
+ TS_ASSERT(cons_1_nil.isConst());
+ TS_ASSERT(cons_1_cons_2_nil.isConst());
}
void testGetConst() {