Fixes cvc5/cvc5-projects#381.
<< "Cannot get specialized constructor type for non-datatype type "
<< retSort;
//////// all checks before this line
-
- NodeManager* nm = d_solver->getNodeManager();
- Node ret =
- nm->mkNode(kind::APPLY_TYPE_ASCRIPTION,
- nm->mkConst(AscriptionType(
- d_ctor->getSpecializedConstructorType(*retSort.d_type))),
- d_ctor->getConstructor());
+ Node ret = d_ctor->getInstantiatedConstructor(*retSort.d_type);
(void)ret.getType(true); /* kick off type checking */
// apply type ascription to the operator
Term sctor = api::Term(d_solver, ret);
return d_constructor;
}
+Node DTypeConstructor::getInstantiatedConstructor(TypeNode returnType) const
+{
+ Assert(isResolved());
+ NodeManager* nm = NodeManager::currentNM();
+ return nm->mkNode(
+ kind::APPLY_TYPE_ASCRIPTION,
+ nm->mkConst(AscriptionType(getInstantiatedConstructorType(returnType))),
+ d_constructor);
+}
+
Node DTypeConstructor::getTester() const
{
Assert(isResolved());
size_t DTypeConstructor::getNumArgs() const { return d_args.size(); }
-TypeNode DTypeConstructor::getSpecializedConstructorType(
+TypeNode DTypeConstructor::getInstantiatedConstructorType(
TypeNode returnType) const
{
Assert(isResolved());
Assert(returnType.isDatatype())
- << "DTypeConstructor::getSpecializedConstructorType: expected datatype, "
+ << "DTypeConstructor::getInstantiatedConstructorType: expected datatype, "
"got "
<< returnType;
TypeNode ctn = d_constructor.getType();
<< ", ascribe to " << t << std::endl;
groundTerms[0] = nm->mkNode(
APPLY_TYPE_ASCRIPTION,
- nm->mkConst(AscriptionType(getSpecializedConstructorType(t))),
+ nm->mkConst(AscriptionType(getInstantiatedConstructorType(t))),
groundTerms[0]);
groundTerm = nm->mkNode(APPLY_CONSTRUCTOR, groundTerms);
}
TypeNode ctype;
if (domainType.isParametricDatatype())
{
- ctype = getSpecializedConstructorType(domainType);
+ ctype = getInstantiatedConstructorType(domainType);
}
else
{
* DType must be resolved.
*/
Node getConstructor() const;
+ /**
+ * Get the specialized constructor term of this constructor, which is
+ * the constructor wrapped in a APPLY_TYPE_ASCRIPTION. This is required
+ * for constructing applications of constructors for parametric datatypes.
+ */
+ Node getInstantiatedConstructor(TypeNode returnType) const;
/**
* Get the tester operator of this constructor. The
* "cons" constructor type for lists of int---namely,
* "int -> list[int] -> list[int]".
*/
- TypeNode getSpecializedConstructorType(TypeNode returnType) const;
+ TypeNode getInstantiatedConstructorType(TypeNode returnType) const;
/**
* Return the cardinality of this constructor (the product of the
// get the constructor object
const DTypeConstructor& dtc = utils::datatypeOf(op)[utils::indexOf(op)];
// create ascribed constructor type
- Node tc = NodeManager::currentNM()->mkConst(
- AscriptionType(dtc.getSpecializedConstructorType(tn)));
- Node op_new = NodeManager::currentNM()->mkNode(
- kind::APPLY_TYPE_ASCRIPTION, tc, op);
+ Node op_new = dtc.getInstantiatedConstructor(tn);
// make new node
std::vector<Node> children;
children.push_back(op_new);
size_t cindex = utils::cindexOf(op);
const DTypeConstructor& dc = dt[cindex];
NodeBuilder b(APPLY_CONSTRUCTOR);
- b << dc.getConstructor();
+ if (tn.isParametricDatatype())
+ {
+ b << dc.getInstantiatedConstructor(n[0].getType());
+ }
+ else
+ {
+ b << dc.getConstructor();
+ }
Trace("dt-expand") << "Expand updater " << n << std::endl;
Trace("dt-expand") << "expr is " << n << std::endl;
Trace("dt-expand") << "updateIndex is " << updateIndex << std::endl;
for( unsigned i=0; i<pcons.size(); i++ ){
// must try the infinite ones first
bool cfinite =
- d_env.isFiniteType(dt[i].getSpecializedConstructorType(tt));
+ d_env.isFiniteType(dt[i].getInstantiatedConstructorType(tt));
if( pcons[i] && (r==1)==cfinite ){
neqc = utils::getInstCons(eqc, dt, i);
break;
// add type ascription for ambiguous constructor types
Debug("datatypes-parametric")
<< "Constructor is " << dt[index] << std::endl;
- TypeNode tspec = dt[index].getSpecializedConstructorType(tn);
- Debug("datatypes-parametric")
- << "Type specification is " << tspec << std::endl;
- cchildren[0] = nm->mkNode(APPLY_TYPE_ASCRIPTION,
- nm->mkConst(AscriptionType(tspec)),
- cchildren[0]);
+ cchildren[0] = dt[index].getInstantiatedConstructor(tn);
}
return nm->mkNode(APPLY_CONSTRUCTOR, cchildren);
}
NodeBuilder b(kind::APPLY_CONSTRUCTOR);
if (d_datatype.isParametric())
{
- NodeManager* nm = NodeManager::currentNM();
- TypeNode typ = ctor.getSpecializedConstructorType(d_type);
- b << nm->mkNode(kind::APPLY_TYPE_ASCRIPTION,
- nm->mkConst(AscriptionType(typ)),
- ctor.getConstructor());
+ b << ctor.getInstantiatedConstructor(d_type);
}
else
{
TypeNode typ;
if (d_datatype.isParametric())
{
- typ = ctor.getSpecializedConstructorType(d_type);
+ typ = ctor.getInstantiatedConstructorType(d_type);
}
for (unsigned a = 0; a < ctor.getNumArgs(); ++a)
{
if (dt.isParametric())
{
// if parametric, must instantiate the argument types
- consType = dt[i].getSpecializedConstructorType(tn);
+ consType = dt[i].getInstantiatedConstructorType(tn);
}
else
{
for (unsigned j = 0, ncons = dt.getNumConstructors(); j < ncons; j++)
{
std::vector<Node> vars;
- TypeNode dtjtn = dt[j].getSpecializedConstructorType(tn);
+ TypeNode dtjtn = dt[j].getInstantiatedConstructorType(tn);
Assert(dtjtn.getNumChildren() == dt[j].getNumArgs() + 1);
for (unsigned k = 0, nargs = dt[j].getNumArgs(); k < nargs; k++)
{
// take into account if parametric
if (dt.isParametric())
{
- tspec = c.getSpecializedConstructorType(lit[0].getType());
- cons = nm->mkNode(
- APPLY_TYPE_ASCRIPTION, nm->mkConst(AscriptionType(tspec)), cons);
+ TypeNode ltn = lit[0].getType();
+ tspec = c.getInstantiatedConstructorType(ltn);
+ cons = c.getInstantiatedConstructor(ltn);
}
else
{
TypeNode tspec;
if (dt.isParametric())
{
- tspec = dc.getSpecializedConstructorType(n.getType());
- Trace("sk-ind-debug") << "Specialized constructor type : " << tspec
+ tspec = dc.getInstantiatedConstructorType(n.getType());
+ Trace("sk-ind-debug") << "Instantiated constructor type : " << tspec
<< std::endl;
Assert(tspec.getNumChildren() == dc.getNumArgs());
}
{
// get the specialized constructor type, which accounts for
// parametric datatypes
- TypeNode ctn = dt[i].getSpecializedConstructorType(range);
+ TypeNode ctn = dt[i].getInstantiatedConstructorType(range);
std::vector<TypeNode> argTypes = ctn.getArgTypes();
for (size_t j = 0, nargs = argTypes.size(); j < nargs; ++j)
{
{
Trace("sygus-grammar-def") << "...for " << dt[l].getName() << std::endl;
Node cop = dt[l].getConstructor();
- TypeNode tspec = dt[l].getSpecializedConstructorType(types[i]);
+ TypeNode tspec = dt[l].getInstantiatedConstructorType(types[i]);
// must specialize if a parametric datatype
if (dt.isParametric())
{
- cop = nm->mkNode(
- APPLY_TYPE_ASCRIPTION, nm->mkConst(AscriptionType(tspec)), cop);
+ cop = dt[l].getInstantiatedConstructor(types[i]);
}
if (dt[l].getNumArgs() == 0)
{
ASSERT_EQ(s3.getDatatypeArity(), 0);
}
+TEST_F(TestApiBlackSolver, proj_issue381)
+{
+ Sort s1 = d_solver.getBooleanSort();
+
+ Sort psort = d_solver.mkParamSort("_x9");
+ DatatypeDecl dtdecl = d_solver.mkDatatypeDecl("_x8", psort);
+ DatatypeConstructorDecl ctor = d_solver.mkDatatypeConstructorDecl("_x22");
+ ctor.addSelector("_x19", s1);
+ dtdecl.addConstructor(ctor);
+ Sort s3 = d_solver.mkDatatypeSort(dtdecl);
+ Sort s6 = s3.instantiate({s1});
+ Term t26 = d_solver.mkConst(s6, "_x63");
+ Term t5 = d_solver.mkTrue();
+ Term t187 = d_solver.mkTerm(APPLY_UPDATER,
+ t26.getSort()
+ .getDatatype()
+ .getConstructor("_x22")
+ .getSelector("_x19")
+ .getUpdaterTerm(),
+ t26,
+ t5);
+ ASSERT_NO_THROW(d_solver.simplify(t187));
+}
+
} // namespace test
} // namespace cvc5