#define SOLVER PARSER_STATE->getSolver()
#define UNSUPPORTED PARSER_STATE->unimplementedFeature
-static bool isClosed(const Expr& e, std::set<Expr>& free, std::unordered_set<Expr, ExprHashFunction>& closedCache) {
- if(closedCache.find(e) != closedCache.end()) {
- return true;
- }
-
- if(e.getKind() == kind::FORALL || e.getKind() == kind::EXISTS || e.getKind() == kind::LAMBDA) {
- isClosed(e[1], free, closedCache);
- for(Expr::const_iterator i = e[0].begin(); i != e[0].end(); ++i) {
- free.erase(*i);
- }
- } else if(e.getKind() == kind::BOUND_VARIABLE) {
- free.insert(e);
- return false;
- } else {
- if(e.hasOperator()) {
- isClosed(e.getOperator(), free, closedCache);
- }
- for(Expr::const_iterator i = e.begin(); i != e.end(); ++i) {
- isClosed(*i, free, closedCache);
- }
- }
-
- if(free.empty()) {
- closedCache.insert(e);
- return true;
- } else {
- return false;
- }
-}
-
-static inline bool isClosed(const Expr& e, std::set<Expr>& free) {
- std::unordered_set<Expr, ExprHashFunction> cache;
- return isClosed(e, free, cache);
-}
-
}/* parser::postinclude */
/**
| ATTRIBUTE_NAMED_TOK symbolicExpr[sexpr]
{
attr = std::string(":named");
- if(!sexpr.isKeyword()) {
- PARSER_STATE->parseError("improperly formed :named annotation");
- }
+ Expr func = PARSER_STATE->setNamedAttribute(expr, sexpr);
std::string name = sexpr.getValue();
- PARSER_STATE->checkUserSymbol(name);
- // ensure expr is a closed subterm
- std::set<Expr> freeVars;
- if(!isClosed(expr, freeVars)) {
- assert(!freeVars.empty());
- std::stringstream ss;
- ss << ":named annotations can only name terms that are closed; this "
- << "one contains free variables:";
- for(std::set<Expr>::const_iterator i = freeVars.begin();
- i != freeVars.end(); ++i) {
- ss << " " << *i;
- }
- PARSER_STATE->parseError(ss.str());
- }
- // check that sexpr is a fresh function symbol, and reserve it
- PARSER_STATE->reserveSymbolAtAssertionLevel(name);
- // define it
- Expr func = PARSER_STATE->mkVar(name, expr.getType());
- // remember the last term to have been given a :named attribute
- PARSER_STATE->setLastNamedTerm(expr, name);
// bind name to expr with define-fun
Command* c =
new DefineNamedFunctionCommand(name, func, std::vector<Expr>(), expr);
return em->getOptions().getInputLanguage();
}
+Expr Smt2::setNamedAttribute(Expr& expr, const SExpr& sexpr)
+{
+ if (!sexpr.isKeyword())
+ {
+ parseError("improperly formed :named annotation");
+ }
+ std::string name = sexpr.getValue();
+ checkUserSymbol(name);
+ // ensure expr is a closed subterm
+ if (expr.hasFreeVariable())
+ {
+ std::stringstream ss;
+ ss << ":named annotations can only name terms that are closed";
+ parseError(ss.str());
+ }
+ // check that sexpr is a fresh function symbol, and reserve it
+ reserveSymbolAtAssertionLevel(name);
+ // define it
+ Expr func = mkVar(name, expr.getType());
+ // remember the last term to have been given a :named attribute
+ setLastNamedTerm(expr, name);
+ return func;
+}
+
} // namespace parser
}/* CVC4 namespace */
}
}
}
+ /** Set named attribute
+ *
+ * This is called when expression expr is annotated with a name, i.e.
+ * (! expr :named sexpr). It sets up the necessary information to process
+ * this naming, including marking that expr is the last named term.
+ *
+ * We construct an expression symbol whose name is the name of s-expression
+ * which is used later for tracking assertions in unsat cores. This
+ * symbol is returned by this method.
+ */
+ Expr setNamedAttribute(Expr& expr, const SExpr& sexpr);
// Throw a ParserException with msg appended with the current logic.
inline void parseErrorLogic(const std::string& msg)