summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorMorgan Deters <mdeters@gmail.com>2011-11-16 03:47:25 +0000
committerMorgan Deters <mdeters@gmail.com>2011-11-16 03:47:25 +0000
commitf55dfd4df98fbecbd0ef0f86da79d537457109d6 (patch)
tree8979e0e92e4d228d285c847f4af4913d4d8a7638 /src/util
parentb9118b75a8ee24a94a693cd3f850c63eb5085ef1 (diff)
Addressed many of the concerns raised in the public interface review of CVC4 Datatypes (bug #283) by Chris Conway. Thanks, Chris!
Diffstat (limited to 'src/util')
-rw-r--r--src/util/datatype.cpp106
-rw-r--r--src/util/datatype.h593
-rw-r--r--src/util/datatype.i247
3 files changed, 383 insertions, 563 deletions
diff --git a/src/util/datatype.cpp b/src/util/datatype.cpp
index 19415769e..f009bbbbe 100644
--- a/src/util/datatype.cpp
+++ b/src/util/datatype.cpp
@@ -95,6 +95,8 @@ void Datatype::resolve(ExprManager* em,
"Datatype::resolve(): resolutions doesn't contain me!");
AssertArgument(placeholders.size() == replacements.size(), placeholders,
"placeholders and replacements must be the same size");
+ AssertArgument(paramTypes.size() == paramReplacements.size(), paramTypes,
+ "paramTypes and paramReplacements must be the same size");
CheckArgument(getNumConstructors() > 0, *this, "cannot resolve a Datatype that has no constructors");
DatatypeType self = (*resolutions.find(d_name)).second;
AssertArgument(&self.getDatatype() == this, "Datatype::resolve(): resolutions doesn't contain me!");
@@ -110,7 +112,7 @@ void Datatype::resolve(ExprManager* em,
Assert(index == getNumConstructors());
}
-void Datatype::addConstructor(const Constructor& c) {
+void Datatype::addConstructor(const DatatypeConstructor& c) {
CheckArgument(!d_resolved, this,
"cannot add a constructor to a finalized Datatype");
d_constructors.push_back(c);
@@ -233,7 +235,7 @@ Expr Datatype::mkGroundTerm( Type t ) const throw(AssertionException) {
i != i_end;
++i) {
if( groundTerm.isNull() ){
- Constructor::const_iterator j = (*i).begin(), j_end = (*i).end();
+ DatatypeConstructor::const_iterator j = (*i).begin(), j_end = (*i).end();
for(; j != j_end; ++j) {
SelectorType stype((*j).getSelector().getType());
if(stype.getDomain() == stype.getRangeType()) {
@@ -245,7 +247,7 @@ Expr Datatype::mkGroundTerm( Type t ) const throw(AssertionException) {
if(j == j_end && (*i).isWellFounded()) {
groundTerm = (*i).mkGroundTerm( t );
- // Constructor::mkGroundTerm() doesn't ever return null when
+ // DatatypeConstructor::mkGroundTerm() doesn't ever return null when
// called from the outside. But in recursive invocations, it
// can: say you have dt = a(one:dt) | b(two:INT), and you ask
// the "a" constructor for a ground term. It asks "dt" for a
@@ -253,7 +255,7 @@ Expr Datatype::mkGroundTerm( Type t ) const throw(AssertionException) {
// ground term! Thus, even though "a" is a well-founded
// constructor, it cannot construct a ground-term by itself. We
// have to skip past it, and we do that with a
- // RecursionBreaker<> in Constructor::mkGroundTerm(). In the
+ // RecursionBreaker<> in DatatypeConstructor::mkGroundTerm(). In the
// case of recursion, it returns null.
if(!groundTerm.isNull()) {
// we found a ground-term-constructing constructor!
@@ -323,7 +325,7 @@ bool Datatype::operator==(const Datatype& other) const throw() {
if(!(*i).d_tester.isNull() && (*i).d_tester != (*j).d_tester) {
return false;
}
- for(Constructor::const_iterator k = (*i).begin(), l = (*j).begin(); k != (*i).end(); ++k, ++l) {
+ for(DatatypeConstructor::const_iterator k = (*i).begin(), l = (*j).begin(); k != (*i).end(); ++k, ++l) {
Assert(l != (*j).end());
if((*k).getName() != (*l).getName()) {
return false;
@@ -359,12 +361,12 @@ bool Datatype::operator==(const Datatype& other) const throw() {
return true;
}
-const Datatype::Constructor& Datatype::operator[](size_t index) const {
+const DatatypeConstructor& Datatype::operator[](size_t index) const {
CheckArgument(index < getNumConstructors(), index, "index out of bounds");
return d_constructors[index];
}
-const Datatype::Constructor& Datatype::operator[](std::string name) const {
+const DatatypeConstructor& Datatype::operator[](std::string name) const {
for(const_iterator i = begin(); i != end(); ++i) {
if((*i).getName() == name) {
return *i;
@@ -377,12 +379,12 @@ Expr Datatype::getConstructor(std::string name) const {
return (*this)[name].getConstructor();
}
-void Datatype::Constructor::resolve(ExprManager* em, DatatypeType self,
- const std::map<std::string, DatatypeType>& resolutions,
- const std::vector<Type>& placeholders,
- const std::vector<Type>& replacements,
- const std::vector< SortConstructorType >& paramTypes,
- const std::vector< DatatypeType >& paramReplacements)
+void DatatypeConstructor::resolve(ExprManager* em, DatatypeType self,
+ const std::map<std::string, DatatypeType>& resolutions,
+ const std::vector<Type>& placeholders,
+ const std::vector<Type>& replacements,
+ const std::vector< SortConstructorType >& paramTypes,
+ const std::vector< DatatypeType >& paramReplacements)
throw(AssertionException, DatatypeResolutionException) {
AssertArgument(em != NULL, "cannot resolve a Datatype with a NULL expression manager");
@@ -428,7 +430,7 @@ void Datatype::Constructor::resolve(ExprManager* em, DatatypeType self,
Assert(index == getNumArgs());
- // Set constructor/tester last, since Constructor::isResolved()
+ // Set constructor/tester last, since DatatypeConstructor::isResolved()
// returns true when d_tester is not the null Expr. If something
// fails above, we want Constuctor::isResolved() to remain "false".
// Further, mkConstructorType() iterates over the selectors, so
@@ -442,7 +444,7 @@ void Datatype::Constructor::resolve(ExprManager* em, DatatypeType self,
}
}
-Type Datatype::Constructor::doParametricSubstitution( Type range,
+Type DatatypeConstructor::doParametricSubstitution( Type range,
const std::vector< SortConstructorType >& paramTypes,
const std::vector< DatatypeType >& paramReplacements ) {
TypeNode typn = TypeNode::fromType( range );
@@ -455,23 +457,23 @@ Type Datatype::Constructor::doParametricSubstitution( Type range,
origChildren.push_back( (*i).toType() );
children.push_back( doParametricSubstitution( (*i).toType(), paramTypes, paramReplacements ) );
}
- for( int i=0; i<(int)paramTypes.size(); i++ ) {
- if( paramTypes[i].getArity()==origChildren.size() ) {
+ for( unsigned i = 0; i < paramTypes.size(); ++i ) {
+ if( paramTypes[i].getArity() == origChildren.size() ) {
Type tn = paramTypes[i].instantiate( origChildren );
- if( range==tn ) {
+ if( range == tn ) {
return paramReplacements[i].instantiate( children );
}
}
}
NodeBuilder<> nb(typn.getKind());
- for( int i=0; i<(int)children.size(); i++ ) {
+ for( unsigned i = 0; i < children.size(); ++i ) {
nb << TypeNode::fromType( children[i] );
}
return nb.constructTypeNode().toType();
}
}
-Datatype::Constructor::Constructor(std::string name) :
+DatatypeConstructor::DatatypeConstructor(std::string name) :
// We don't want to introduce a new data member, because eventually
// we're going to be a constant stuffed inside a node. So we stow
// the tester name away inside the constructor name until
@@ -482,7 +484,7 @@ Datatype::Constructor::Constructor(std::string name) :
CheckArgument(name != "", name, "cannot construct a datatype constructor without a name");
}
-Datatype::Constructor::Constructor(std::string name, std::string tester) :
+DatatypeConstructor::DatatypeConstructor(std::string name, std::string tester) :
// We don't want to introduce a new data member, because eventually
// we're going to be a constant stuffed inside a node. So we stow
// the tester name away inside the constructor name until
@@ -494,7 +496,7 @@ Datatype::Constructor::Constructor(std::string name, std::string tester) :
CheckArgument(!tester.empty(), tester, "cannot construct a datatype constructor without a tester");
}
-void Datatype::Constructor::addArg(std::string selectorName, Type selectorType) {
+void DatatypeConstructor::addArg(std::string selectorName, Type selectorType) {
// We don't want to introduce a new data member, because eventually
// we're going to be a constant stuffed inside a node. So we stow
// the selector type away inside a var until resolution (when we can
@@ -503,30 +505,30 @@ void Datatype::Constructor::addArg(std::string selectorName, Type selectorType)
CheckArgument(!selectorType.isNull(), selectorType, "cannot add a null selector type");
Expr type = selectorType.getExprManager()->mkVar(selectorType);
Debug("datatypes") << type << endl;
- d_args.push_back(Arg(selectorName, type));
+ d_args.push_back(DatatypeConstructorArg(selectorName, type));
}
-void Datatype::Constructor::addArg(std::string selectorName, Datatype::UnresolvedType selectorType) {
+void DatatypeConstructor::addArg(std::string selectorName, DatatypeUnresolvedType selectorType) {
// We don't want to introduce a new data member, because eventually
// we're going to be a constant stuffed inside a node. So we stow
// the selector type away after a NUL in the name string until
// resolution (when we can create the proper selector type)
CheckArgument(!isResolved(), this, "cannot modify a finalized Datatype constructor");
CheckArgument(selectorType.getName() != "", selectorType, "cannot add a null selector type");
- d_args.push_back(Arg(selectorName + '\0' + selectorType.getName(), Expr()));
+ d_args.push_back(DatatypeConstructorArg(selectorName + '\0' + selectorType.getName(), Expr()));
}
-void Datatype::Constructor::addArg(std::string selectorName, Datatype::SelfType) {
+void DatatypeConstructor::addArg(std::string selectorName, DatatypeSelfType) {
// We don't want to introduce a new data member, because eventually
// we're going to be a constant stuffed inside a node. So we mark
// the name string with a NUL to indicate that we have a
// self-selecting selector until resolution (when we can create the
// proper selector type)
CheckArgument(!isResolved(), this, "cannot modify a finalized Datatype constructor");
- d_args.push_back(Arg(selectorName + '\0', Expr()));
+ d_args.push_back(DatatypeConstructorArg(selectorName + '\0', Expr()));
}
-std::string Datatype::Constructor::getName() const throw() {
+std::string DatatypeConstructor::getName() const throw() {
string name = d_name;
if(!isResolved()) {
name.resize(name.find('\0'));
@@ -534,16 +536,16 @@ std::string Datatype::Constructor::getName() const throw() {
return name;
}
-Expr Datatype::Constructor::getConstructor() const {
+Expr DatatypeConstructor::getConstructor() const {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
return d_constructor;
}
-Type Datatype::Constructor::getSpecializedConstructorType(Type returnType) const {
+Type DatatypeConstructor::getSpecializedConstructorType(Type returnType) const {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
const Datatype& dt = Datatype::datatypeOf(d_constructor);
CheckArgument(dt.isParametric(), this, "this datatype constructor is not yet resolved");
- DatatypeType dtt = DatatypeType(dt.d_self);
+ DatatypeType dtt = dt.getDatatypeType();
Matcher m(dtt);
m.doMatching( TypeNode::fromType(dtt), TypeNode::fromType(returnType) );
vector<Type> subst;
@@ -552,12 +554,12 @@ Type Datatype::Constructor::getSpecializedConstructorType(Type returnType) const
return d_constructor.getType().substitute(params, subst);
}
-Expr Datatype::Constructor::getTester() const {
+Expr DatatypeConstructor::getTester() const {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
return d_tester;
}
-Cardinality Datatype::Constructor::getCardinality() const throw(AssertionException) {
+Cardinality DatatypeConstructor::getCardinality() const throw(AssertionException) {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
Cardinality c = 1;
@@ -569,7 +571,7 @@ Cardinality Datatype::Constructor::getCardinality() const throw(AssertionExcepti
return c;
}
-bool Datatype::Constructor::isFinite() const throw(AssertionException) {
+bool DatatypeConstructor::isFinite() const throw(AssertionException) {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
// we're using some internals, so we have to set up this library context
@@ -595,7 +597,7 @@ bool Datatype::Constructor::isFinite() const throw(AssertionException) {
return true;
}
-bool Datatype::Constructor::isWellFounded() const throw(AssertionException) {
+bool DatatypeConstructor::isWellFounded() const throw(AssertionException) {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
// we're using some internals, so we have to set up this library context
@@ -608,7 +610,7 @@ bool Datatype::Constructor::isWellFounded() const throw(AssertionException) {
return self.getAttribute(DatatypeWellFoundedAttr());
}
- RecursionBreaker<const Datatype::Constructor*, DatatypeHashFunction> breaker(__PRETTY_FUNCTION__, this);
+ RecursionBreaker<const DatatypeConstructor*, DatatypeHashFunction> breaker(__PRETTY_FUNCTION__, this);
if(breaker.isRecursion()) {
// This *path* is cyclic, sso may not be well-founded. The
// constructor itself might still be well-founded, though (we'll
@@ -639,7 +641,7 @@ bool Datatype::Constructor::isWellFounded() const throw(AssertionException) {
return true;
}
-Expr Datatype::Constructor::mkGroundTerm( Type t ) const throw(AssertionException) {
+Expr DatatypeConstructor::mkGroundTerm( Type t ) const throw(AssertionException) {
CheckArgument(isResolved(), this, "this datatype constructor is not yet resolved");
// we're using some internals, so we have to set up this library context
@@ -653,7 +655,7 @@ Expr Datatype::Constructor::mkGroundTerm( Type t ) const throw(AssertionExceptio
return groundTerm;
}
- RecursionBreaker<const Datatype::Constructor*, DatatypeHashFunction> breaker(__PRETTY_FUNCTION__, this);
+ RecursionBreaker<const DatatypeConstructor*, DatatypeHashFunction> breaker(__PRETTY_FUNCTION__, this);
if(breaker.isRecursion()) {
// Recursive path, we should skip and go to the next constructor;
// see lengthy comments in Datatype::mkGroundTerm().
@@ -693,12 +695,12 @@ Expr Datatype::Constructor::mkGroundTerm( Type t ) const throw(AssertionExceptio
return groundTerm;
}
-const Datatype::Constructor::Arg& Datatype::Constructor::operator[](size_t index) const {
+const DatatypeConstructorArg& DatatypeConstructor::operator[](size_t index) const {
CheckArgument(index < getNumArgs(), index, "index out of bounds");
return d_args[index];
}
-const Datatype::Constructor::Arg& Datatype::Constructor::operator[](std::string name) const {
+const DatatypeConstructorArg& DatatypeConstructor::operator[](std::string name) const {
for(const_iterator i = begin(); i != end(); ++i) {
if((*i).getName() == name) {
return *i;
@@ -707,18 +709,18 @@ const Datatype::Constructor::Arg& Datatype::Constructor::operator[](std::string
CheckArgument(false, name, "No such arg `%s' of constructor `%s'", name.c_str(), d_name.c_str());
}
-Expr Datatype::Constructor::getSelector(std::string name) const {
+Expr DatatypeConstructor::getSelector(std::string name) const {
return (*this)[name].getSelector();
}
-Datatype::Constructor::Arg::Arg(std::string name, Expr selector) :
+DatatypeConstructorArg::DatatypeConstructorArg(std::string name, Expr selector) :
d_name(name),
d_selector(selector),
d_resolved(false) {
CheckArgument(name != "", name, "cannot construct a datatype constructor arg without a name");
}
-std::string Datatype::Constructor::Arg::getName() const throw() {
+std::string DatatypeConstructorArg::getName() const throw() {
string name = d_name;
const size_t nul = name.find('\0');
if(nul != string::npos) {
@@ -727,28 +729,28 @@ std::string Datatype::Constructor::Arg::getName() const throw() {
return name;
}
-Expr Datatype::Constructor::Arg::getSelector() const {
+Expr DatatypeConstructorArg::getSelector() const {
CheckArgument(isResolved(), this, "cannot get a selector for an unresolved datatype constructor");
return d_selector;
}
-Expr Datatype::Constructor::Arg::getConstructor() const {
+Expr DatatypeConstructorArg::getConstructor() const {
CheckArgument(isResolved(), this,
"cannot get a associated constructor for argument of an unresolved datatype constructor");
return d_constructor;
}
-Type Datatype::Constructor::Arg::getSelectorType() const {
+Type DatatypeConstructorArg::getType() const {
return getSelector().getType();
}
-bool Datatype::Constructor::Arg::isUnresolvedSelf() const throw() {
+bool DatatypeConstructorArg::isUnresolvedSelf() const throw() {
return d_selector.isNull() && d_name.size() == d_name.find('\0') + 1;
}
static const int s_printDatatypeNamesOnly = std::ios_base::xalloc();
-std::string Datatype::Constructor::Arg::getSelectorTypeName() const {
+std::string DatatypeConstructorArg::getTypeName() const {
Type t;
if(isResolved()) {
t = SelectorType(d_selector.getType()).getRangeType();
@@ -809,13 +811,13 @@ std::ostream& operator<<(std::ostream& os, const Datatype& dt) {
return os;
}
-std::ostream& operator<<(std::ostream& os, const Datatype::Constructor& ctor) {
+std::ostream& operator<<(std::ostream& os, const DatatypeConstructor& ctor) {
// can only output datatypes in the CVC4 native language
Expr::setlanguage::Scope ls(os, language::output::LANG_CVC4);
os << ctor.getName();
- Datatype::Constructor::const_iterator i = ctor.begin(), i_end = ctor.end();
+ DatatypeConstructor::const_iterator i = ctor.begin(), i_end = ctor.end();
if(i != i_end) {
os << "(";
do {
@@ -830,11 +832,11 @@ std::ostream& operator<<(std::ostream& os, const Datatype::Constructor& ctor) {
return os;
}
-std::ostream& operator<<(std::ostream& os, const Datatype::Constructor::Arg& arg) {
+std::ostream& operator<<(std::ostream& os, const DatatypeConstructorArg& arg) {
// can only output datatypes in the CVC4 native language
Expr::setlanguage::Scope ls(os, language::output::LANG_CVC4);
- os << arg.getName() << ": " << arg.getSelectorTypeName();
+ os << arg.getName() << ": " << arg.getTypeName();
return os;
}
diff --git a/src/util/datatype.h b/src/util/datatype.h
index 24a625bd1..5a1d9b931 100644
--- a/src/util/datatype.h
+++ b/src/util/datatype.h
@@ -53,6 +53,259 @@ public:
};/* class DatatypeResolutionException */
/**
+ * A holder type (used in calls to DatatypeConstructor::addArg())
+ * to allow a Datatype to refer to itself. Self-typed fields of
+ * Datatypes will be properly typed when a Type is created for the
+ * Datatype by the ExprManager (which calls Datatype::resolve()).
+ */
+class CVC4_PUBLIC DatatypeSelfType {
+};/* class DatatypeSelfType */
+
+/**
+ * An unresolved type (used in calls to
+ * DatatypeConstructor::addArg()) to allow a Datatype to refer to
+ * itself or to other mutually-recursive Datatypes. Unresolved-type
+ * fields of Datatypes will be properly typed when a Type is created
+ * for the Datatype by the ExprManager (which calls
+ * Datatype::resolve()).
+ */
+class CVC4_PUBLIC DatatypeUnresolvedType {
+ std::string d_name;
+public:
+ inline DatatypeUnresolvedType(std::string name);
+ inline std::string getName() const throw();
+};/* class DatatypeUnresolvedType */
+
+/**
+ * A Datatype constructor argument (i.e., a Datatype field).
+ */
+class CVC4_PUBLIC DatatypeConstructorArg {
+
+ std::string d_name;
+ Expr d_selector;
+ /** the constructor associated with this selector */
+ Expr d_constructor;
+ bool d_resolved;
+
+ DatatypeConstructorArg(std::string name, Expr selector);
+ friend class DatatypeConstructor;
+ friend class Datatype;
+
+ bool isUnresolvedSelf() const throw();
+
+public:
+
+ /** Get the name of this constructor argument. */
+ std::string getName() const throw();
+
+ /**
+ * Get the selector for this constructor argument; this call is
+ * only permitted after resolution.
+ */
+ Expr getSelector() const;
+
+ /**
+ * Get the associated constructor for this constructor argument;
+ * this call is only permitted after resolution.
+ */
+ Expr getConstructor() const;
+
+ /**
+ * Get the type of the selector for this constructor argument;
+ * this call is only permitted after resolution.
+ */
+ Type getType() const;
+
+ /**
+ * Get the name of the type of this constructor argument
+ * (Datatype field). Can be used for not-yet-resolved Datatypes
+ * (in which case the name of the unresolved type, or "[self]"
+ * for a self-referential type is returned).
+ */
+ std::string getTypeName() const;
+
+ /**
+ * Returns true iff this constructor argument has been resolved.
+ */
+ bool isResolved() const throw();
+
+};/* class DatatypeConstructorArg */
+
+/**
+ * A constructor for a Datatype.
+ */
+class CVC4_PUBLIC DatatypeConstructor {
+public:
+
+ /** The type for iterators over constructor arguments. */
+ typedef std::vector<DatatypeConstructorArg>::iterator iterator;
+ /** The (const) type for iterators over constructor arguments. */
+ typedef std::vector<DatatypeConstructorArg>::const_iterator const_iterator;
+
+private:
+
+ std::string d_name;
+ Expr d_constructor;
+ Expr d_tester;
+ std::vector<DatatypeConstructorArg> d_args;
+
+ void resolve(ExprManager* em, DatatypeType self,
+ const std::map<std::string, DatatypeType>& resolutions,
+ const std::vector<Type>& placeholders,
+ const std::vector<Type>& replacements,
+ const std::vector< SortConstructorType >& paramTypes,
+ const std::vector< DatatypeType >& paramReplacements)
+ throw(AssertionException, DatatypeResolutionException);
+ friend class Datatype;
+
+ /** @FIXME document this! */
+ Type doParametricSubstitution(Type range,
+ const std::vector< SortConstructorType >& paramTypes,
+ const std::vector< DatatypeType >& paramReplacements);
+public:
+ /**
+ * Create a new Datatype constructor with the given name for the
+ * constructor and the same name (prefixed with "is_") for the
+ * tester. The actual constructor and tester (meaning, the Exprs
+ * representing operators for these entities) aren't created until
+ * resolution time.
+ */
+ explicit DatatypeConstructor(std::string name);
+
+ /**
+ * Create a new Datatype constructor with the given name for the
+ * constructor and the given name for the tester. The actual
+ * constructor and tester aren't created until resolution time.
+ */
+ DatatypeConstructor(std::string name, std::string tester);
+
+ /**
+ * Add an argument (i.e., a data field) of the given name and type
+ * to this Datatype constructor. Selector names need not be unique;
+ * they are for convenience and pretty-printing only.
+ */
+ void addArg(std::string selectorName, Type selectorType);
+
+ /**
+ * Add an argument (i.e., a data field) of the given name to this
+ * Datatype constructor that refers to an as-yet-unresolved
+ * Datatype (which may be mutually-recursive). Selector names need
+ * not be unique; they are for convenience and pretty-printing only.
+ */
+ void addArg(std::string selectorName, DatatypeUnresolvedType selectorType);
+
+ /**
+ * Add a self-referential (i.e., a data field) of the given name
+ * to this Datatype constructor that refers to the enclosing
+ * Datatype. For example, using the familiar "nat" Datatype, to
+ * create the "pred" field for "succ" constructor, one uses
+ * succ::addArg("pred", DatatypeSelfType())---the actual Type
+ * cannot be passed because the Datatype is still under
+ * construction. Selector names need not be unique; they are for
+ * convenience and pretty-printing only.
+ *
+ * This is a special case of
+ * DatatypeConstructor::addArg(std::string, DatatypeUnresolvedType).
+ */
+ void addArg(std::string selectorName, DatatypeSelfType);
+
+ /** Get the name of this Datatype constructor. */
+ std::string getName() const throw();
+
+ /**
+ * Get the constructor operator of this Datatype constructor. The
+ * Datatype must be resolved.
+ */
+ Expr getConstructor() const;
+
+ /**
+ * Get the tester operator of this Datatype constructor. The
+ * Datatype must be resolved.
+ */
+ Expr getTester() const;
+
+ /**
+ * Get the number of arguments (so far) of this Datatype constructor.
+ */
+ inline size_t getNumArgs() const throw();
+
+ /**
+ * Get the specialized constructor type for a parametric
+ * constructor; this call is only permitted after resolution.
+ * Given a (concrete) returnType, the constructor's concrete
+ * type in this parametric datatype is returned.
+ *
+ * For instance, if the datatype is list[T], with constructor
+ * "cons[T]" of type "T -> list[T] -> list[T]", then calling
+ * this function with "list[int]" will return the concrete
+ * "cons" constructor type for lists of int---namely,
+ * "int -> list[int] -> list[int]".
+ */
+ Type getSpecializedConstructorType(Type returnType) const;
+
+ /**
+ * Return the cardinality of this constructor (the product of the
+ * cardinalities of its arguments).
+ */
+ Cardinality getCardinality() const throw(AssertionException);
+
+ /**
+ * Return true iff this constructor is finite (it is nullary or
+ * each of its argument types are finite). This function can
+ * only be called for resolved constructors.
+ */
+ bool isFinite() const throw(AssertionException);
+
+ /**
+ * Return true iff this constructor is well-founded (there exist
+ * ground terms). The constructor must be resolved or an
+ * exception is thrown.
+ */
+ bool isWellFounded() const throw(AssertionException);
+
+ /**
+ * Construct and return a ground term of this constructor. The
+ * constructor must be both resolved and well-founded, or else an
+ * exception is thrown.
+ */
+ Expr mkGroundTerm( Type t ) const throw(AssertionException);
+
+ /**
+ * Returns true iff this Datatype constructor has already been
+ * resolved.
+ */
+ inline bool isResolved() const throw();
+
+ /** Get the beginning iterator over DatatypeConstructor args. */
+ inline iterator begin() throw();
+ /** Get the ending iterator over DatatypeConstructor args. */
+ inline iterator end() throw();
+ /** Get the beginning const_iterator over DatatypeConstructor args. */
+ inline const_iterator begin() const throw();
+ /** Get the ending const_iterator over DatatypeConstructor args. */
+ inline const_iterator end() const throw();
+
+ /** Get the ith DatatypeConstructor arg. */
+ const DatatypeConstructorArg& operator[](size_t index) const;
+
+ /**
+ * Get the DatatypeConstructor arg named. This is a linear search
+ * through the arguments, so in the case of multiple,
+ * similarly-named arguments, the first is returned.
+ */
+ const DatatypeConstructorArg& operator[](std::string name) const;
+
+ /**
+ * Get the selector named. This is a linear search
+ * through the arguments, so in the case of multiple,
+ * similarly-named arguments, the selector for the first
+ * is returned.
+ */
+ Expr getSelector(std::string name) const;
+
+};/* class DatatypeConstructor */
+
+/**
* The representation of an inductive datatype.
*
* This is far more complicated than it first seems. Consider this
@@ -66,7 +319,7 @@ public:
* You cannot define "nat" until you have a Type for it, but you
* cannot have a Type for it until you fill in the type of the "pred"
* selector, which needs the Type. So we have a chicken-and-egg
- * problem. It's even more complicated when we have mutual recusion
+ * problem. It's even more complicated when we have mutual recursion
* between datatypes, since the CVC presentation language does not
* require forward-declarations. Here, we define trees of lists that
* contain trees of lists (etc):
@@ -94,8 +347,9 @@ public:
* on the task of generating its own selectors and testers, for
* instance. That means that, after reifying the Datatype with the
* ExprManager, the parser needs to go through the (now-resolved)
- * Datatype and request ; see src/parser/parser.cpp for how this is
- * done. For API usage ideas, see test/unit/util/datatype_black.h.
+ * Datatype and request the constructor, selector, and tester terms.
+ * See src/parser/parser.cpp for how this is done. For API usage
+ * ideas, see test/unit/util/datatype_black.h.
*/
class CVC4_PUBLIC Datatype {
public:
@@ -111,255 +365,15 @@ public:
*/
static size_t indexOf(Expr item) CVC4_PUBLIC;
- /**
- * A holder type (used in calls to Datatype::Constructor::addArg())
- * to allow a Datatype to refer to itself. Self-typed fields of
- * Datatypes will be properly typed when a Type is created for the
- * Datatype by the ExprManager (which calls Datatype::resolve()).
- */
- class CVC4_PUBLIC SelfType {
- };/* class Datatype::SelfType */
-
- /**
- * An unresolved type (used in calls to
- * Datatype::Constructor::addArg()) to allow a Datatype to refer to
- * itself or to other mutually-recursive Datatypes. Unresolved-type
- * fields of Datatypes will be properly typed when a Type is created
- * for the Datatype by the ExprManager (which calls
- * Datatype::resolve()).
- */
- class CVC4_PUBLIC UnresolvedType {
- std::string d_name;
- public:
- inline UnresolvedType(std::string name);
- inline std::string getName() const throw();
- };/* class Datatype::UnresolvedType */
-
- /**
- * A constructor for a Datatype.
- */
- class CVC4_PUBLIC Constructor {
- public:
- /**
- * A Datatype constructor argument (i.e., a Datatype field).
- */
- class CVC4_PUBLIC Arg {
-
- std::string d_name;
- Expr d_selector;
- /** the constructor associated with this selector */
- Expr d_constructor;
- bool d_resolved;
-
- explicit Arg(std::string name, Expr selector);
- friend class Constructor;
- friend class Datatype;
-
- bool isUnresolvedSelf() const throw();
-
- public:
-
- /** Get the name of this constructor argument. */
- std::string getName() const throw();
-
- /**
- * Get the selector for this constructor argument; this call is
- * only permitted after resolution.
- */
- Expr getSelector() const;
-
- /**
- * Get the associated constructor for this constructor argument;
- * this call is only permitted after resolution.
- */
- Expr getConstructor() const;
-
- /**
- * Get the selector for this constructor argument; this call is
- * only permitted after resolution.
- */
- Type getSelectorType() const;
-
- /**
- * Get the name of the type of this constructor argument
- * (Datatype field). Can be used for not-yet-resolved Datatypes
- * (in which case the name of the unresolved type, or "[self]"
- * for a self-referential type is returned).
- */
- std::string getSelectorTypeName() const;
-
- /**
- * Returns true iff this constructor argument has been resolved.
- */
- bool isResolved() const throw();
-
- };/* class Datatype::Constructor::Arg */
-
- /** The type for iterators over constructor arguments. */
- typedef std::vector<Arg>::iterator iterator;
- /** The (const) type for iterators over constructor arguments. */
- typedef std::vector<Arg>::const_iterator const_iterator;
-
- private:
-
- std::string d_name;
- Expr d_constructor;
- Expr d_tester;
- std::vector<Arg> d_args;
-
- void resolve(ExprManager* em, DatatypeType self,
- const std::map<std::string, DatatypeType>& resolutions,
- const std::vector<Type>& placeholders,
- const std::vector<Type>& replacements,
- const std::vector< SortConstructorType >& paramTypes,
- const std::vector< DatatypeType >& paramReplacements)
- throw(AssertionException, DatatypeResolutionException);
- friend class Datatype;
-
- /** @FIXME document this! */
- Type doParametricSubstitution(Type range,
- const std::vector< SortConstructorType >& paramTypes,
- const std::vector< DatatypeType >& paramReplacements);
- public:
- /**
- * Create a new Datatype constructor with the given name for the
- * constructor and the same name (prefixed with "is_") for the
- * tester. The actual constructor and tester aren't created until
- * resolution time.
- */
- explicit Constructor(std::string name);
-
- /**
- * Create a new Datatype constructor with the given name for the
- * constructor and the given name for the tester. The actual
- * constructor and tester aren't created until resolution time.
- */
- explicit Constructor(std::string name, std::string tester);
-
- /**
- * Add an argument (i.e., a data field) of the given name and type
- * to this Datatype constructor.
- */
- void addArg(std::string selectorName, Type selectorType);
-
- /**
- * Add an argument (i.e., a data field) of the given name to this
- * Datatype constructor that refers to an as-yet-unresolved
- * Datatype (which may be mutually-recursive).
- */
- void addArg(std::string selectorName, Datatype::UnresolvedType selectorType);
-
- /**
- * Add a self-referential (i.e., a data field) of the given name
- * to this Datatype constructor that refers to the enclosing
- * Datatype. For example, using the familiar "nat" Datatype, to
- * create the "pred" field for "succ" constructor, one uses
- * succ::addArg("pred", Datatype::SelfType())---the actual Type
- * cannot be passed because the Datatype is still under
- * construction.
- *
- * This is a special case of
- * Constructor::addArg(std::string, Datatype::UnresolvedType).
- */
- void addArg(std::string selectorName, Datatype::SelfType);
-
- /** Get the name of this Datatype constructor. */
- std::string getName() const throw();
-
- /**
- * Get the constructor operator of this Datatype constructor. The
- * Datatype must be resolved.
- */
- Expr getConstructor() const;
-
- /**
- * Get the tester operator of this Datatype constructor. The
- * Datatype must be resolved.
- */
- Expr getTester() const;
-
- /**
- * Get the number of arguments (so far) of this Datatype constructor.
- */
- inline size_t getNumArgs() const throw();
-
- /**
- * Get the specialized constructor type for a parametric
- * constructor; this call is only permitted after resolution.
- */
- Type getSpecializedConstructorType(Type returnType) const;
-
- /**
- * Return the cardinality of this constructor (the product of the
- * cardinalities of its arguments).
- */
- Cardinality getCardinality() const throw(AssertionException);
-
- /**
- * Return true iff this constructor is finite (it is nullary or
- * each of its argument types are finite). This function can
- * only be called for resolved constructors.
- */
- bool isFinite() const throw(AssertionException);
-
- /**
- * Return true iff this constructor is well-founded (there exist
- * ground terms). The constructor must be resolved or an
- * exception is thrown.
- */
- bool isWellFounded() const throw(AssertionException);
-
- /**
- * Construct and return a ground term of this constructor. The
- * constructor must be both resolved and well-founded, or else an
- * exception is thrown.
- */
- Expr mkGroundTerm( Type t ) const throw(AssertionException);
-
- /**
- * Returns true iff this Datatype constructor has already been
- * resolved.
- */
- inline bool isResolved() const throw();
-
- /** Get the beginning iterator over Constructor args. */
- inline iterator begin() throw();
- /** Get the ending iterator over Constructor args. */
- inline iterator end() throw();
- /** Get the beginning const_iterator over Constructor args. */
- inline const_iterator begin() const throw();
- /** Get the ending const_iterator over Constructor args. */
- inline const_iterator end() const throw();
-
- /** Get the ith Constructor arg. */
- const Arg& operator[](size_t index) const;
-
- /**
- * Get the Constructor arg named. This is a linear search
- * through the arguments, so in the case of multiple,
- * similarly-named arguments, the first is returned.
- */
- const Arg& operator[](std::string name) const;
-
- /**
- * Get the selector named. This is a linear search
- * through the arguments, so in the case of multiple,
- * similarly-named arguments, the selector for the first
- * is returned.
- */
- Expr getSelector(std::string name) const;
-
- };/* class Datatype::Constructor */
-
/** The type for iterators over constructors. */
- typedef std::vector<Constructor>::iterator iterator;
+ typedef std::vector<DatatypeConstructor>::iterator iterator;
/** The (const) type for iterators over constructors. */
- typedef std::vector<Constructor>::const_iterator const_iterator;
+ typedef std::vector<DatatypeConstructor>::const_iterator const_iterator;
private:
std::string d_name;
std::vector<Type> d_params;
- std::vector<Constructor> d_constructors;
+ std::vector<DatatypeConstructor> d_constructors;
bool d_resolved;
Type d_self;
@@ -368,9 +382,26 @@ private:
* chicken-and-egg problem. The DatatypeType around the Datatype
* cannot exist until the Datatype is finalized, and the Datatype
* cannot refer to the DatatypeType representing itself until it
- * exists. resolve() is called by the ExprManager when a Type. Has
- * the effect of freezing the object, too; that is, addConstructor()
- * will fail after a call to resolve().
+ * exists. resolve() is called by the ExprManager when a Type is
+ * ultimately requested of the Datatype specification (that is, when
+ * ExprManager::mkDatatypeType() or ExprManager::mkMutualDatatypeTypes()
+ * is called). Has the effect of freezing the object, too; that is,
+ * addConstructor() will fail after a call to resolve().
+ *
+ * The basic goal of resolution is to assign constructors, selectors,
+ * and testers. To do this, any UnresolvedType/SelfType references
+ * must be cleared up. This is the purpose of the "resolutions" map;
+ * it includes any mutually-recursive datatypes that are currently
+ * under resolution. The four vectors come in two pairs (so, really
+ * they are two maps). placeholders->replacements give type variables
+ * that should be resolved in the case of parametric datatypes.
+ *
+ * @param em the ExprManager at play
+ * @param resolutions a map of strings to DatatypeTypes currently under resolution
+ * @param placeholders the types in these Datatypes under resolution that must be replaced
+ * @param replacements the corresponding replacements
+ * @param paramTypes the sort constructors in these Datatypes under resolution that must be replaced
+ * @param paramReplacements the corresponding (parametric) DatatypeTypes
*/
void resolve(ExprManager* em,
const std::map<std::string, DatatypeType>& resolutions,
@@ -390,10 +421,13 @@ public:
* Create a new Datatype of the given name, with the given
* parameterization.
*/
- inline explicit Datatype(std::string name, std::vector<Type>& params);
+ inline Datatype(std::string name, std::vector<Type>& params);
- /** Add a constructor to this Datatype. */
- void addConstructor(const Constructor& c);
+ /**
+ * Add a constructor to this Datatype. Constructor names need not
+ * be unique; they are for convenience and pretty-printing only.
+ */
+ void addConstructor(const DatatypeConstructor& c);
/** Get the name of this Datatype. */
inline std::string getName() const throw();
@@ -473,34 +507,37 @@ public:
/** Return true iff this Datatype has already been resolved. */
inline bool isResolved() const throw();
- /** Get the beginning iterator over Constructors. */
- inline std::vector<Constructor>::iterator begin() throw();
- /** Get the ending iterator over Constructors. */
- inline std::vector<Constructor>::iterator end() throw();
- /** Get the beginning const_iterator over Constructors. */
- inline std::vector<Constructor>::const_iterator begin() const throw();
- /** Get the ending const_iterator over Constructors. */
- inline std::vector<Constructor>::const_iterator end() const throw();
+ /** Get the beginning iterator over DatatypeConstructors. */
+ inline std::vector<DatatypeConstructor>::iterator begin() throw();
+ /** Get the ending iterator over DatatypeConstructors. */
+ inline std::vector<DatatypeConstructor>::iterator end() throw();
+ /** Get the beginning const_iterator over DatatypeConstructors. */
+ inline std::vector<DatatypeConstructor>::const_iterator begin() const throw();
+ /** Get the ending const_iterator over DatatypeConstructors. */
+ inline std::vector<DatatypeConstructor>::const_iterator end() const throw();
- /** Get the ith Constructor. */
- const Constructor& operator[](size_t index) const;
+ /** Get the ith DatatypeConstructor. */
+ const DatatypeConstructor& operator[](size_t index) const;
/**
- * Get the Constructor named. This is a linear search
+ * Get the DatatypeConstructor named. This is a linear search
* through the constructors, so in the case of multiple,
* similarly-named constructors, the first is returned.
*/
- const Constructor& operator[](std::string name) const;
+ const DatatypeConstructor& operator[](std::string name) const;
/**
* Get the constructor operator for the named constructor.
+ * This is a linear search through the constructors, so in
+ * the case of multiple, similarly-named constructors, the
+ * first is returned.
+ *
* This Datatype must be resolved.
*/
Expr getConstructor(std::string name) const;
};/* class Datatype */
-
/**
* A hash strategy for Datatypes. Needed because Datatypes are used
* as the constant payload in CONSTANT-kinded TypeNodes (for
@@ -523,10 +560,10 @@ struct CVC4_PUBLIC DatatypeHashFunction {
inline size_t operator()(const Datatype* dt) const {
return StringHashFunction()(dt->getName());
}
- inline size_t operator()(const Datatype::Constructor& dtc) const {
+ inline size_t operator()(const DatatypeConstructor& dtc) const {
return StringHashFunction()(dtc.getName());
}
- inline size_t operator()(const Datatype::Constructor* dtc) const {
+ inline size_t operator()(const DatatypeConstructor* dtc) const {
return StringHashFunction()(dtc->getName());
}
};/* struct DatatypeHashFunction */
@@ -534,8 +571,8 @@ struct CVC4_PUBLIC DatatypeHashFunction {
// FUNCTION DECLARATIONS FOR OUTPUT STREAMS
std::ostream& operator<<(std::ostream& os, const Datatype& dt) CVC4_PUBLIC;
-std::ostream& operator<<(std::ostream& os, const Datatype::Constructor& ctor) CVC4_PUBLIC;
-std::ostream& operator<<(std::ostream& os, const Datatype::Constructor::Arg& arg) CVC4_PUBLIC;
+std::ostream& operator<<(std::ostream& os, const DatatypeConstructor& ctor) CVC4_PUBLIC;
+std::ostream& operator<<(std::ostream& os, const DatatypeConstructorArg& arg) CVC4_PUBLIC;
// INLINE FUNCTIONS
@@ -543,11 +580,11 @@ inline DatatypeResolutionException::DatatypeResolutionException(std::string msg)
Exception(msg) {
}
-inline Datatype::UnresolvedType::UnresolvedType(std::string name) :
+inline DatatypeUnresolvedType::DatatypeUnresolvedType(std::string name) :
d_name(name) {
}
-inline std::string Datatype::UnresolvedType::getName() const throw() {
+inline std::string DatatypeUnresolvedType::getName() const throw() {
return d_name;
}
@@ -618,15 +655,15 @@ inline Datatype::const_iterator Datatype::end() const throw() {
return d_constructors.end();
}
-inline bool Datatype::Constructor::isResolved() const throw() {
+inline bool DatatypeConstructor::isResolved() const throw() {
return !d_tester.isNull();
}
-inline size_t Datatype::Constructor::getNumArgs() const throw() {
+inline size_t DatatypeConstructor::getNumArgs() const throw() {
return d_args.size();
}
-inline bool Datatype::Constructor::Arg::isResolved() const throw() {
+inline bool DatatypeConstructorArg::isResolved() const throw() {
// We could just write:
//
// return !d_selector.isNull() && d_selector.getType().isSelector();
@@ -643,19 +680,19 @@ inline bool Datatype::Constructor::Arg::isResolved() const throw() {
return d_resolved;
}
-inline Datatype::Constructor::iterator Datatype::Constructor::begin() throw() {
+inline DatatypeConstructor::iterator DatatypeConstructor::begin() throw() {
return d_args.begin();
}
-inline Datatype::Constructor::iterator Datatype::Constructor::end() throw() {
+inline DatatypeConstructor::iterator DatatypeConstructor::end() throw() {
return d_args.end();
}
-inline Datatype::Constructor::const_iterator Datatype::Constructor::begin() const throw() {
+inline DatatypeConstructor::const_iterator DatatypeConstructor::begin() const throw() {
return d_args.begin();
}
-inline Datatype::Constructor::const_iterator Datatype::Constructor::end() const throw() {
+inline DatatypeConstructor::const_iterator DatatypeConstructor::end() const throw() {
return d_args.end();
}
diff --git a/src/util/datatype.i b/src/util/datatype.i
index 34e890214..056c15004 100644
--- a/src/util/datatype.i
+++ b/src/util/datatype.i
@@ -2,15 +2,10 @@
#include "util/datatype.h"
%}
-namespace CVC4 {
-%rename(DatatypeConstructor) CVC4::Datatype::Constructor;
-%rename(DatatypeConstructor) CVC4::Constructor;
-}
-
%extend std::vector< CVC4::Datatype > {
/* These member functions have slightly different signatures in
* different swig language packages. The underlying issue is that
- * Datatype::Constructor doesn't have a default constructor */
+ * DatatypeConstructor doesn't have a default constructor */
%ignore vector(unsigned int size = 0);// ocaml
%ignore set( int i, const CVC4::Datatype &x );// ocaml
%ignore to_array();// ocaml
@@ -19,17 +14,17 @@ namespace CVC4 {
};
%template(vectorDatatype) std::vector< CVC4::Datatype >;
-%extend std::vector< CVC4::Datatype::Constructor > {
+%extend std::vector< CVC4::DatatypeConstructor > {
/* These member functions have slightly different signatures in
* different swig language packages. The underlying issue is that
- * Datatype::Constructor doesn't have a default constructor */
+ * DatatypeConstructor doesn't have a default constructor */
%ignore vector(unsigned int size = 0);// ocaml
- %ignore set( int i, const CVC4::Datatype::Constructor &x );// ocaml
+ %ignore set( int i, const CVC4::DatatypeConstructor &x );// ocaml
%ignore to_array();// ocaml
%ignore vector(size_type);// java/python
%ignore resize(size_type);// java/python
};
-%template(vectorDatatypeConstructor) std::vector< CVC4::Datatype::Constructor >;
+%template(vectorDatatypeConstructor) std::vector< CVC4::DatatypeConstructor >;
%rename(equals) CVC4::Datatype::operator==(const Datatype&) const;
%ignore CVC4::Datatype::operator!=(const Datatype&) const;
@@ -41,234 +36,20 @@ namespace CVC4 {
%rename(apply) CVC4::DatatypeHashFunction::operator()(const Datatype&) const;
%ignore CVC4::DatatypeHashFunction::operator()(const Datatype*) const;
-%rename(apply) CVC4::DatatypeHashFunction::operator()(const Datatype::Constructor&) const;
-%ignore CVC4::DatatypeHashFunction::operator()(const Datatype::Constructor*) const;
+%rename(apply) CVC4::DatatypeHashFunction::operator()(const DatatypeConstructor&) const;
+%ignore CVC4::DatatypeHashFunction::operator()(const DatatypeConstructor*) const;
-%rename(beginConst) CVC4::Constructor::begin() const;
-%rename(endConst) CVC4::Constructor::end() const;
+%rename(beginConst) CVC4::DatatypeConstructor::begin() const;
+%rename(endConst) CVC4::DatatypeConstructor::end() const;
-%rename(getArg) CVC4::Constructor::operator[](size_t) const;
+%rename(getArg) CVC4::DatatypeConstructor::operator[](size_t) const;
%ignore CVC4::operator<<(std::ostream&, const Datatype&);
-%ignore CVC4::operator<<(std::ostream&, const Datatype::Constructor&);
-%ignore CVC4::operator<<(std::ostream&, const Datatype::Constructor::Arg&);
+%ignore CVC4::operator<<(std::ostream&, const DatatypeConstructor&);
+%ignore CVC4::operator<<(std::ostream&, const DatatypeConstructorArg&);
-%feature("valuewrapper") CVC4::Datatype::UnresolvedType;
-%feature("valuewrapper") CVC4::Datatype::Constructor;
+%feature("valuewrapper") CVC4::DatatypeUnresolvedType;
+%feature("valuewrapper") CVC4::DatatypeConstructor;
%include "util/datatype.h"
-namespace CVC4 {
- class CVC4_PUBLIC Arg {
-
- std::string d_name;
- Expr d_selector;
- /** the constructor associated with this selector */
- Expr d_constructor;
- bool d_resolved;
-
- explicit Arg(std::string name, Expr selector);
- friend class Constructor;
- friend class Datatype;
-
- bool isUnresolvedSelf() const throw();
-
- public:
-
- /** Get the name of this constructor argument. */
- std::string getName() const throw();
-
- /**
- * Get the selector for this constructor argument; this call is
- * only permitted after resolution.
- */
- Expr getSelector() const;
-
- /**
- * Get the associated constructor for this constructor argument;
- * this call is only permitted after resolution.
- */
- Expr getConstructor() const;
-
- /**
- * Get the selector for this constructor argument; this call is
- * only permitted after resolution.
- */
- Type getSelectorType() const;
-
- /**
- * Get the name of the type of this constructor argument
- * (Datatype field). Can be used for not-yet-resolved Datatypes
- * (in which case the name of the unresolved type, or "[self]"
- * for a self-referential type is returned).
- */
- std::string getSelectorTypeName() const;
-
- /**
- * Returns true iff this constructor argument has been resolved.
- */
- bool isResolved() const throw();
-
- };/* class Datatype::Constructor::Arg */
-
- class Constructor {
- public:
-
- /** The type for iterators over constructor arguments. */
- typedef std::vector<Arg>::iterator iterator;
- /** The (const) type for iterators over constructor arguments. */
- typedef std::vector<Arg>::const_iterator const_iterator;
-
- private:
-
- std::string d_name;
- Expr d_constructor;
- Expr d_tester;
- std::vector<Arg> d_args;
-
- void resolve(ExprManager* em, DatatypeType self,
- const std::map<std::string, DatatypeType>& resolutions,
- const std::vector<Type>& placeholders,
- const std::vector<Type>& replacements,
- const std::vector< SortConstructorType >& paramTypes,
- const std::vector< DatatypeType >& paramReplacements)
- throw(AssertionException, DatatypeResolutionException);
- friend class Datatype;
-
- /** @FIXME document this! */
- Type doParametricSubstitution(Type range,
- const std::vector< SortConstructorType >& paramTypes,
- const std::vector< DatatypeType >& paramReplacements);
- public:
- /**
- * Create a new Datatype constructor with the given name for the
- * constructor and the given name for the tester. The actual
- * constructor and tester aren't created until resolution time.
- */
- explicit Constructor(std::string name, std::string tester);
-
- /**
- * Add an argument (i.e., a data field) of the given name and type
- * to this Datatype constructor.
- */
- void addArg(std::string selectorName, Type selectorType);
-
- /**
- * Add an argument (i.e., a data field) of the given name to this
- * Datatype constructor that refers to an as-yet-unresolved
- * Datatype (which may be mutually-recursive).
- */
- void addArg(std::string selectorName, Datatype::UnresolvedType selectorType);
-
- /**
- * Add a self-referential (i.e., a data field) of the given name
- * to this Datatype constructor that refers to the enclosing
- * Datatype. For example, using the familiar "nat" Datatype, to
- * create the "pred" field for "succ" constructor, one uses
- * succ::addArg("pred", Datatype::SelfType())---the actual Type
- * cannot be passed because the Datatype is still under
- * construction.
- *
- * This is a special case of
- * Constructor::addArg(std::string, Datatype::UnresolvedType).
- */
- void addArg(std::string selectorName, Datatype::SelfType);
-
- /** Get the name of this Datatype constructor. */
- std::string getName() const throw();
- /**
- * Get the constructor operator of this Datatype constructor. The
- * Datatype must be resolved.
- */
- Expr getConstructor() const;
- /**
- * Get the tester operator of this Datatype constructor. The
- * Datatype must be resolved.
- */
- Expr getTester() const;
- /**
- * Get the number of arguments (so far) of this Datatype constructor.
- */
- inline size_t getNumArgs() const throw();
-
- /**
- * Get the specialized constructor type for a parametric
- * constructor; this call is only permitted after resolution.
- */
- Type getSpecializedConstructorType(Type returnType) const;
-
- /**
- * Return the cardinality of this constructor (the product of the
- * cardinalities of its arguments).
- */
- Cardinality getCardinality() const throw(AssertionException);
-
- /**
- * Return true iff this constructor is finite (it is nullary or
- * each of its argument types are finite). This function can
- * only be called for resolved constructors.
- */
- bool isFinite() const throw(AssertionException);
-
- /**
- * Return true iff this constructor is well-founded (there exist
- * ground terms). The constructor must be resolved or an
- * exception is thrown.
- */
- bool isWellFounded() const throw(AssertionException);
-
- /**
- * Construct and return a ground term of this constructor. The
- * constructor must be both resolved and well-founded, or else an
- * exception is thrown.
- */
- Expr mkGroundTerm( Type t ) const throw(AssertionException);
-
- /**
- * Returns true iff this Datatype constructor has already been
- * resolved.
- */
- inline bool isResolved() const throw();
-
- /** Get the beginning iterator over Constructor args. */
- inline iterator begin() throw();
- /** Get the ending iterator over Constructor args. */
- inline iterator end() throw();
- /** Get the beginning const_iterator over Constructor args. */
- inline const_iterator begin() const throw();
- /** Get the ending const_iterator over Constructor args. */
- inline const_iterator end() const throw();
-
- /** Get the ith Constructor arg. */
- const Arg& operator[](size_t index) const;
-
- };/* class Datatype::Constructor */
-
- class SelfType {
- };/* class Datatype::SelfType */
-
- /**
- * An unresolved type (used in calls to
- * Datatype::Constructor::addArg()) to allow a Datatype to refer to
- * itself or to other mutually-recursive Datatypes. Unresolved-type
- * fields of Datatypes will be properly typed when a Type is created
- * for the Datatype by the ExprManager (which calls
- * Datatype::resolve()).
- */
- class UnresolvedType {
- std::string d_name;
- public:
- inline UnresolvedType(std::string name);
- inline std::string getName() const throw();
- };/* class Datatype::UnresolvedType */
-}
-
-%{
-namespace CVC4 {
-typedef Datatype::Constructor Constructor;
-typedef Datatype::Constructor::Arg Arg;
-typedef Datatype::SelfType SelfType;
-typedef Datatype::UnresolvedType UnresolvedType;
-}
-%}
-
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback