return cvc5::Term();
}
+Term Tptp::makeApplyUf(std::vector<Term>& args)
+{
+ std::vector<Sort> argSorts = args[0].getSort().getFunctionDomainSorts();
+ if (argSorts.size() + 1 != args.size())
+ {
+ // arity mismatch
+ parseError("Applying function to wrong number of arguments");
+ }
+ for (size_t i = 0, nargs = argSorts.size(); i < nargs; i++)
+ {
+ if (argSorts[i].isReal() && args[i + 1].getSort().isInteger())
+ {
+ args[i + 1] = d_solver->mkTerm(TO_REAL, {args[i + 1]});
+ }
+ }
+ return d_solver->mkTerm(APPLY_UF, args);
+}
+
cvc5::Term Tptp::applyParseOp(ParseOp& p, std::vector<cvc5::Term>& args)
{
if (TraceIsOn("parser"))
// this happens with some arithmetic kinds, which are wrapped around
// lambdas.
args.insert(args.begin(), p.d_expr);
- return d_solver->mkTerm(cvc5::APPLY_UF, args);
+ return makeApplyUf(args);
}
bool isBuiltinKind = false;
// the builtin kind of the overall return expression
// must curry the partial application
return d_solver->mkTerm(cvc5::HO_APPLY, args);
}
+ else if (kind == APPLY_UF)
+ {
+ // ensure subtyping is not used
+ return makeApplyUf(args);
+ }
}
}
return d_solver->mkTerm(kind, args);
// Add the inverse in order to show that over the elements that
// appear in the problem there is a bijection between unsorted and
// rational
- cvc5::Term ret = d_solver->mkTerm(cvc5::APPLY_UF, {d_rtu_op, expr});
+ std::vector<Term> args = {d_rtu_op, expr};
+ Term ret = makeApplyUf(args);
if (d_r_converted.find(expr) == d_r_converted.end()) {
d_r_converted.insert(expr);
if (expr.getSort().isInteger())
void addArithmeticOperators();
/** is the name declared, if so, return the term for that name */
cvc5::Term isTptpDeclared(const std::string& name);
+ /**
+ * Make APPLY_UF from arguments, which ensures that subyping is not used.
+ */
+ Term makeApplyUf(std::vector<Term>& args);
// In CNF variable are implicitly binded
// d_freevar collect them