From: Aina Niemetz Date: Thu, 26 Jul 2018 16:00:18 +0000 (-0700) Subject: New C++ API: Second batch of commands (SMT-LIB). (#2201) X-Git-Tag: cvc5-1.0.0~4864 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c7be9ef42f06a721ba87ad2b0f0e4e3b66d45e06;p=cvc5.git New C++ API: Second batch of commands (SMT-LIB). (#2201) --- diff --git a/src/api/cvc4cpp.cpp b/src/api/cvc4cpp.cpp index dbaac4f8c..eefa8f7e1 100644 --- a/src/api/cvc4cpp.cpp +++ b/src/api/cvc4cpp.cpp @@ -2353,5 +2353,228 @@ Sort Solver::declareDatatype( return mkDatatypeSort(dtdecl); } +/** + * ( declare-fun () ) + */ +Term Solver::declareFun(const std::string& symbol, Sort sort) const +{ + // CHECK: sort exists + // CHECK: + // sort.isFirstClass() + // else "can not create function type for range type that is not first class" + // CHECK: + // !sort.isFunction() + // else "must flatten function types" + Type type = *sort.d_type; + // CHECK: + // !t.isFunction() || THEORY_UF not enabled + // else "Functions (of non-zero arity) cannot be declared in logic" + return d_exprMgr->mkVar(symbol, type); +} + +/** + * ( declare-fun ( * ) ) + */ +Term Solver::declareFun(const std::string& symbol, + const std::vector& sorts, + Sort sort) const +{ + // CHECK: for all s in sorts, s exists + // CHECK: sort exists + // CHECK: + // for (unsigned i = 0; i < sorts.size(); ++ i) + // sorts[i].isFirstClass() + // else "can not create function type for argument type that is not + // first class" + // CHECK: + // sort.isFirstClass() + // else "can not create function type for range type that is not first class" + // CHECK: + // !sort.isFunction() + // else "must flatten function types" + Type type = *sort.d_type; + if (!sorts.empty()) + { + std::vector types = sortVectorToTypes(sorts); + type = d_exprMgr->mkFunctionType(types, type); + } + // CHECK: + // !t.isFunction() || THEORY_UF not enabled + // else "Functions (of non-zero arity) cannot be declared in logic" + return d_exprMgr->mkVar(symbol, type); +} + +/** + * ( declare-sort ) + */ +Sort Solver::declareSort(const std::string& symbol, uint32_t arity) const +{ + // CHECK: + // - logic set? + // - !THEORY_UF && !THEORY_ARRAYS && !THEORY_DATATYPES && !THEORY_SETS + // else "Free sort symbols not allowed in logic" + if (arity == 0) return d_exprMgr->mkSort(symbol); + return d_exprMgr->mkSortConstructor(symbol, arity); +} + +/** + * ( define-fun ) + */ +Term Solver::defineFun(const std::string& symbol, + const std::vector& bound_vars, + Sort sort, + Term term) const +{ + // CHECK: + // for bv in bound_vars: + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(bv.getExprManager()) + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(expr.getExprManager()) + // CHECK: sort exists + // CHECK: not recursive + // CHECK: + // sort.isFirstClass() + // else "can not create function type for range type that is not first class" + // !sort.isFunction() + // else "must flatten function types" + // CHECK: + // for v in bound_vars: is bound var + std::vector types; + for (const Term& v : bound_vars) + { + types.push_back(v.d_expr->getType()); + } + // CHECK: + // for (unsigned i = 0; i < types.size(); ++ i) + // sorts[i].isFirstClass() + // else "can not create function type for argument type that is not + // first class" + Type type = *sort.d_type; + if (!types.empty()) + { + type = d_exprMgr->mkFunctionType(types, type); + } + Expr fun = d_exprMgr->mkVar(symbol, type); + std::vector ebound_vars = termVectorToExprs(bound_vars); + d_smtEngine->defineFunction(fun, ebound_vars, *term.d_expr); + return fun; +} + +Term Solver::defineFun(Term fun, + const std::vector& bound_vars, + Term term) const +{ + // CHECK: + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(bv.getExprManager()) + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(expr.getExprManager()) + // CHECK: + // - bound_vars matches sort of fun + // - expr matches sort of fun + // CHECK: not recursive + // CHECK: + // for v in bound_vars: is bound var + std::vector ebound_vars = termVectorToExprs(bound_vars); + d_smtEngine->defineFunction(*fun.d_expr, ebound_vars, *term.d_expr); + return fun; +} + +/** + * ( define-fun-rec ) + */ +Term Solver::defineFunRec(const std::string& symbol, + const std::vector& bound_vars, + Sort sort, + Term term) const +{ + // CHECK: + // for bv in bound_vars: + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(bv.getExprManager()) + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(expr.getExprManager()) + // CHECK: sort exists + // CHECK: + // sort.isFirstClass() + // else "can not create function type for range type that is not first class" + // !sort.isFunction() + // else "must flatten function types" + // CHECK: + // for v in bound_vars: is bound var + std::vector types; + for (const Term& v : bound_vars) + { + types.push_back(v.d_expr->getType()); + } + // CHECK: + // for (unsigned i = 0; i < types.size(); ++ i) + // sorts[i].isFirstClass() + // else "can not create function type for argument type that is not + // first class" + Type type = *sort.d_type; + if (!types.empty()) + { + type = d_exprMgr->mkFunctionType(types, type); + } + Expr fun = d_exprMgr->mkVar(symbol, type); + std::vector ebound_vars = termVectorToExprs(bound_vars); + d_smtEngine->defineFunctionRec(fun, ebound_vars, *term.d_expr); + return fun; +} + +Term Solver::defineFunRec(Term fun, + const std::vector& bound_vars, + Term term) const +{ + // CHECK: + // for bv in bound_vars: + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(bv.getExprManager()) + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(expr.getExprManager()) + // CHECK: + // - bound_vars matches sort of fun + // - expr matches sort of fun + // CHECK: + // for v in bound_vars: is bound var + std::vector ebound_vars = termVectorToExprs(bound_vars); + d_smtEngine->defineFunctionRec(*fun.d_expr, ebound_vars, *term.d_expr); + return fun; +} + +/** + * ( define-funs-rec ( ^{n+1} ) ( ^{n+1} ) ) + */ +void Solver::defineFunsRec(const std::vector& funs, + const std::vector>& bound_vars, + const std::vector& terms) const +{ + // CHECK: + // for f in funs: + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(f.getExprManager()) + // for bv in bound_vars: + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(bv.getExprManager()) + // NodeManager::fromExprManager(d_exprMgr) + // == NodeManager::fromExprManager(expr.getExprManager()) + // CHECK: + // - bound_vars matches sort of funs + // - exprs matches sort of funs + // CHECK: + // CHECK: + // for bv in bound_vars (for v in bv): is bound var + std::vector efuns = termVectorToExprs(funs); + std::vector> ebound_vars; + for (const auto& v : bound_vars) + { + ebound_vars.push_back(termVectorToExprs(v)); + } + std::vector exprs = termVectorToExprs(terms); + d_smtEngine->defineFunctionsRec(efuns, ebound_vars, exprs); +} + } // namespace api } // namespace CVC4