getArgTypes() == t.getArgTypes() &&
getRangeType().isSubtypeOf(t.getRangeType());
}
+ if(isParametricDatatype() && t.isParametricDatatype()) {
+ Assert(getKind() == kind::PARAMETRIC_DATATYPE);
+ Assert(t.getKind() == kind::PARAMETRIC_DATATYPE);
+ if((*this)[0] != t[0] || getNumChildren() != t.getNumChildren()) {
+ return false;
+ }
+ for(size_t i = 1; i < getNumChildren(); ++i) {
+ if(!((*this)[i].isSubtypeOf(t[i]))) {
+ return false;
+ }
+ }
+ return true;
+ }
if(isPredicateSubtype()) {
return getSubtypeParentType().isSubtypeOf(t);
}
} else if(isDatatype() && (t.isTuple() || t.isRecord())) {
Assert(!isTuple() && !isRecord());// should have been handled above
return *this == NodeManager::currentNM()->getDatatypeForTupleRecord(t);
+ } else if(isParametricDatatype() && t.isParametricDatatype()) {
+ Assert(getKind() == kind::PARAMETRIC_DATATYPE);
+ Assert(t.getKind() == kind::PARAMETRIC_DATATYPE);
+ if((*this)[0] != t[0] || getNumChildren() != t.getNumChildren()) {
+ return false;
+ }
+ for(size_t i = 1; i < getNumChildren(); ++i) {
+ if(!((*this)[i].isComparableTo(t[i]))) {
+ return false;
+ }
+ }
+ return true;
}
+
if(isPredicateSubtype()) {
return t.isComparableTo(getSubtypeParentType());
}
return NodeManager::currentNM()->getDatatypeForTupleRecord(*this);
} else if (isPredicateSubtype()) {
return getSubtypeParentType().getBaseType();
+ } else if (isParametricDatatype()) {
+ vector<Type> v;
+ for(size_t i = 1; i < getNumChildren(); ++i) {
+ v.push_back((*this)[i].getBaseType().toType());
+ }
+ TypeNode tn = TypeNode::fromType((*this)[0].getDatatype().getDatatypeType(v));
+ return tn;
}
return *this;
}
case kind::ARRAY_TYPE:
case kind::BITVECTOR_TYPE:
case kind::SORT_TYPE:
- case kind::PARAMETRIC_DATATYPE:
case kind::CONSTRUCTOR_TYPE:
case kind::SELECTOR_TYPE:
case kind::TESTER_TYPE:
}
// otherwise no common ancestor
return TypeNode();
+ case kind::PARAMETRIC_DATATYPE: {
+ if(!t1.isParametricDatatype()) {
+ return TypeNode();
+ }
+ while(t1.getKind() != kind::PARAMETRIC_DATATYPE) {
+ t1 = t1.getSubtypeParentType();
+ }
+ if(t0[0] != t1[0] || t0.getNumChildren() != t1.getNumChildren()) {
+ return TypeNode();
+ }
+ vector<Type> v;
+ for(size_t i = 1; i < t0.getNumChildren(); ++i) {
+ v.push_back(leastCommonTypeNode(t0[i], t1[i]).toType());
+ }
+ return TypeNode::fromType(t0[0].getDatatype().getDatatypeType(v));
+ }
default:
Unimplemented("don't have a leastCommonType for types `%s' and `%s'", t0.toString().c_str(), t1.toString().c_str());
return TypeNode();
#include "expr/expr.h"
#include "expr/expr_manager.h"
+#include "expr/expr_manager_scope.h"
+#include "expr/type_node.h"
using namespace CVC4;
using namespace std;
class DatatypeBlack : public CxxTest::TestSuite {
ExprManager* d_em;
+ ExprManagerScope* d_scope;
public:
void setUp() {
d_em = new ExprManager();
+ d_scope = new ExprManagerScope(*d_em);
Debug.on("datatypes");
Debug.on("groundterms");
}
void tearDown() {
+ delete d_scope;
delete d_em;
}
TS_ASSERT_THROWS(colorsDT["blue"].getSelector("foo"), IllegalArgumentException);
TS_ASSERT_THROWS(colorsDT["blue"]["foo"], IllegalArgumentException);
+ TS_ASSERT(! colorsType.getDatatype().isParametric());
TS_ASSERT(colorsType.getDatatype().isFinite());
TS_ASSERT(colorsType.getDatatype().getCardinality().compare(4) == Cardinality::EQUAL);
TS_ASSERT(ctor.getType().getCardinality().compare(1) == Cardinality::EQUAL);
Expr apply = d_em->mkExpr(kind::APPLY_CONSTRUCTOR, ctor);
Debug("datatypes") << apply << std::endl;
+ TS_ASSERT(! natType.getDatatype().isParametric());
TS_ASSERT(! natType.getDatatype().isFinite());
TS_ASSERT(natType.getDatatype().getCardinality().compare(Cardinality::INTEGERS) == Cardinality::EQUAL);
TS_ASSERT(natType.getDatatype().isWellFounded());
TS_ASSERT(treeType.getConstructor("leaf") == ctor);
TS_ASSERT_THROWS(treeType.getConstructor("leff"), IllegalArgumentException);
+ TS_ASSERT(! treeType.getDatatype().isParametric());
TS_ASSERT(! treeType.getDatatype().isFinite());
TS_ASSERT(treeType.getDatatype().getCardinality().compare(Cardinality::INTEGERS) == Cardinality::EQUAL);
TS_ASSERT(treeType.getDatatype().isWellFounded());
DatatypeType listType = d_em->mkDatatypeType(list);
Debug("datatypes") << listType << std::endl;
+ TS_ASSERT(! listType.getDatatype().isParametric());
TS_ASSERT(! listType.getDatatype().isFinite());
TS_ASSERT(listType.getDatatype().getCardinality().compare(Cardinality::INTEGERS) == Cardinality::EQUAL);
TS_ASSERT(listType.getDatatype().isWellFounded());
DatatypeType listType = d_em->mkDatatypeType(list);
Debug("datatypes") << listType << std::endl;
+ TS_ASSERT(! listType.getDatatype().isParametric());
TS_ASSERT(! listType.getDatatype().isFinite());
TS_ASSERT(listType.getDatatype().getCardinality().compare(Cardinality::REALS) == Cardinality::EQUAL);
TS_ASSERT(listType.getDatatype().isWellFounded());
TS_ASSERT((*i).mkGroundTerm( dtts2[0] ).getType() == dtts2[0]);
}
+ TS_ASSERT(! dtts2[1].getDatatype().isParametric());
TS_ASSERT(! dtts2[1].getDatatype().isFinite());
TS_ASSERT(dtts2[1].getDatatype().getCardinality().compare(Cardinality::INTEGERS) == Cardinality::EQUAL);
TS_ASSERT(dtts2[1].getDatatype().isWellFounded());
DatatypeType treeType = d_em->mkDatatypeType(tree);
Debug("datatypes") << treeType << std::endl;
+ TS_ASSERT(! treeType.getDatatype().isParametric());
TS_ASSERT(! treeType.getDatatype().isFinite());
TS_ASSERT(treeType.getDatatype().getCardinality().compare(Cardinality::INTEGERS) == Cardinality::EQUAL);
TS_ASSERT(! treeType.getDatatype().isWellFounded());
}
}
+ void testParametricDatatype() {
+ vector<Type> v;
+ Type t1, t2;
+ v.push_back(t1 = d_em->mkSort("T1"));
+ v.push_back(t2 = d_em->mkSort("T2"));
+ Datatype pair("pair", v);
+
+ DatatypeConstructor mkpair("mk-pair");
+ mkpair.addArg("first", t1);
+ mkpair.addArg("second", t2);
+ pair.addConstructor(mkpair);
+ DatatypeType pairType = d_em->mkDatatypeType(pair);
+
+ TS_ASSERT(pairType.getDatatype().isParametric());
+ v.clear();
+ v.push_back(d_em->integerType());
+ v.push_back(d_em->integerType());
+ DatatypeType pairIntInt = pairType.getDatatype().getDatatypeType(v);
+ v.clear();
+ v.push_back(d_em->realType());
+ v.push_back(d_em->realType());
+ DatatypeType pairRealReal = pairType.getDatatype().getDatatypeType(v);
+ v.clear();
+ v.push_back(d_em->realType());
+ v.push_back(d_em->integerType());
+ DatatypeType pairRealInt = pairType.getDatatype().getDatatypeType(v);
+ v.clear();
+ v.push_back(d_em->integerType());
+ v.push_back(d_em->realType());
+ DatatypeType pairIntReal = pairType.getDatatype().getDatatypeType(v);
+
+ TS_ASSERT_DIFFERS(pairIntInt, pairRealReal);
+ TS_ASSERT_DIFFERS(pairIntReal, pairRealReal);
+ TS_ASSERT_DIFFERS(pairRealInt, pairRealReal);
+ TS_ASSERT_DIFFERS(pairIntInt, pairIntReal);
+ TS_ASSERT_DIFFERS(pairIntInt, pairRealInt);
+ TS_ASSERT_DIFFERS(pairIntReal, pairRealInt);
+
+ TS_ASSERT_EQUALS(pairRealReal.getBaseType(), pairRealReal);
+ TS_ASSERT_EQUALS(pairRealInt.getBaseType(), pairRealReal);
+ TS_ASSERT_EQUALS(pairIntReal.getBaseType(), pairRealReal);
+ TS_ASSERT_EQUALS(pairIntInt.getBaseType(), pairRealReal);
+
+ TS_ASSERT(pairRealReal.isComparableTo(pairRealReal));
+ TS_ASSERT(pairIntReal.isComparableTo(pairRealReal));
+ TS_ASSERT(pairRealInt.isComparableTo(pairRealReal));
+ TS_ASSERT(pairIntInt.isComparableTo(pairRealReal));
+ TS_ASSERT(pairRealReal.isComparableTo(pairRealInt));
+ TS_ASSERT(pairIntReal.isComparableTo(pairRealInt));
+ TS_ASSERT(pairRealInt.isComparableTo(pairRealInt));
+ TS_ASSERT(pairIntInt.isComparableTo(pairRealInt));
+ TS_ASSERT(pairRealReal.isComparableTo(pairIntReal));
+ TS_ASSERT(pairIntReal.isComparableTo(pairIntReal));
+ TS_ASSERT(pairRealInt.isComparableTo(pairIntReal));
+ TS_ASSERT(pairIntInt.isComparableTo(pairIntReal));
+ TS_ASSERT(pairRealReal.isComparableTo(pairIntInt));
+ TS_ASSERT(pairIntReal.isComparableTo(pairIntInt));
+ TS_ASSERT(pairRealInt.isComparableTo(pairIntInt));
+ TS_ASSERT(pairIntInt.isComparableTo(pairIntInt));
+
+ TS_ASSERT(pairRealReal.isSubtypeOf(pairRealReal));
+ TS_ASSERT(pairIntReal.isSubtypeOf(pairRealReal));
+ TS_ASSERT(pairRealInt.isSubtypeOf(pairRealReal));
+ TS_ASSERT(pairIntInt.isSubtypeOf(pairRealReal));
+ TS_ASSERT(!pairRealReal.isSubtypeOf(pairRealInt));
+ TS_ASSERT(!pairIntReal.isSubtypeOf(pairRealInt));
+ TS_ASSERT(pairRealInt.isSubtypeOf(pairRealInt));
+ TS_ASSERT(pairIntInt.isSubtypeOf(pairRealInt));
+ TS_ASSERT(!pairRealReal.isSubtypeOf(pairIntReal));
+ TS_ASSERT(pairIntReal.isSubtypeOf(pairIntReal));
+ TS_ASSERT(!pairRealInt.isSubtypeOf(pairIntReal));
+ TS_ASSERT(pairIntInt.isSubtypeOf(pairIntReal));
+ TS_ASSERT(!pairRealReal.isSubtypeOf(pairIntInt));
+ TS_ASSERT(!pairIntReal.isSubtypeOf(pairIntInt));
+ TS_ASSERT(!pairRealInt.isSubtypeOf(pairIntInt));
+ TS_ASSERT(pairIntInt.isSubtypeOf(pairIntInt));
+
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealReal), TypeNode::fromType(pairRealReal)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntReal), TypeNode::fromType(pairRealReal)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealInt), TypeNode::fromType(pairRealReal)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntInt), TypeNode::fromType(pairRealReal)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealReal), TypeNode::fromType(pairRealInt)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntReal), TypeNode::fromType(pairRealInt)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealInt), TypeNode::fromType(pairRealInt)).toType(), pairRealInt);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntInt), TypeNode::fromType(pairRealInt)).toType(), pairRealInt);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealReal), TypeNode::fromType(pairIntReal)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntReal), TypeNode::fromType(pairIntReal)).toType(), pairIntReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealInt), TypeNode::fromType(pairIntReal)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntInt), TypeNode::fromType(pairIntReal)).toType(), pairIntReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealReal), TypeNode::fromType(pairIntInt)).toType(), pairRealReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntReal), TypeNode::fromType(pairIntInt)).toType(), pairIntReal);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairRealInt), TypeNode::fromType(pairIntInt)).toType(), pairRealInt);
+ TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntInt), TypeNode::fromType(pairIntInt)).toType(), pairIntInt);
+ }
+
};/* class DatatypeBlack */