smt::SmtScope scope(smtEngine);
Node request = Node::fromExpr(options::expandDefinitions() ? smtEngine->expandDefinitions(*i) : *i);
Node value = Node::fromExpr(smtEngine->getValue(*i));
+ if(value.getType().isInteger() && request.getType() == nm->realType()) {
+ // Need to wrap in special marker so that output printers know this
+ // is an integer-looking constant that really should be output as
+ // a rational. Necessary for SMT-LIB standards compliance, but ugly.
+ value = nm->mkNode(kind::APPLY_TYPE_ASCRIPTION,
+ nm->mkConst(AscriptionType(em->realType())), value);
+ }
result.push_back(nm->mkNode(kind::SEXPR, request, value).toExpr());
}
d_result = em->mkExpr(kind::SEXPR, result);
bool stillNeedToPrintParams = true;
bool forceBinary = false; // force N-ary to binary when outputing children
// operator
- if(n.getNumChildren() != 0 && n.getKind()!=kind::INST_PATTERN_LIST) out << '(';
+ if(n.getNumChildren() != 0 &&
+ n.getKind() != kind::INST_PATTERN_LIST &&
+ n.getKind() != kind::APPLY_TYPE_ASCRIPTION) {
+ out << '(';
+ }
switch(Kind k = n.getKind()) {
// builtin theory
case kind::APPLY: break;
case kind::STORE:
case kind::ARRAY_TYPE: out << smtKindString(k) << " "; break;
- // string theory
+ // string theory
case kind::STRING_CONCAT:
if(d_variant == z3str_variant) {
out << "Concat ";
// datatypes
case kind::APPLY_TYPE_ASCRIPTION: {
- out << "as ";
- toStream(out, n[0], toDepth < 0 ? toDepth : toDepth - 1, types);
- out << ' ';
TypeNode t = TypeNode::fromType(n.getOperator().getConst<AscriptionType>().getType());
- out << (t.isFunctionLike() ? t.getRangeType() : t);
- out << ')';
+ if(t.getKind() == kind::TYPE_CONSTANT &&
+ t.getConst<TypeConstant>() == REAL_TYPE &&
+ n[0].getType().isInteger()) {
+ // Special case, in model output integer constants that should be
+ // Real-sorted are wrapped in a type ascription. Handle that here.
+ toStream(out, n[0], -1, false);
+ out << ".0";
+ return;
+ }
+ out << "(as ";
+ toStream(out, n[0], toDepth < 0 ? toDepth : toDepth - 1, types);
+ out << ' ' << (t.isFunctionLike() ? t.getRangeType() : t) << ')';
return;
}
break;
} else if(dynamic_cast<const DeclareFunctionCommand*>(c) != NULL) {
const DeclareFunctionCommand* dfc = (const DeclareFunctionCommand*)c;
Node n = Node::fromExpr( dfc->getFunction() );
- if(dfc->getPrintInModelSetByUser()){
- if(!dfc->getPrintInModel()){
+ if(dfc->getPrintInModelSetByUser()) {
+ if(!dfc->getPrintInModel()) {
return;
}
- }else if(n.getKind() == kind::SKOLEM) {
+ } else if(n.getKind() == kind::SKOLEM) {
// don't print out internal stuff
return;
}
}
}
out << "(define-fun " << n << " () "
- << n.getType() << " " << val << ")" << endl;
+ << n.getType() << " ";
+ if(val.getType().isInteger() && n.getType().isReal() && !n.getType().isInteger()) {
+ out << val << ".0";
+ } else {
+ out << val;
+ }
+ out << ")" << endl;
}
/*
//for table format (work in progress)
}
}
*/
- }else{
+ } else {
out << c << endl;
}
}