From eba03c5af0112aea04d83977333ae37e8a13137d Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Mon, 12 Aug 2019 15:40:26 -0500 Subject: [PATCH] Clean smt2 parsing of named attributes (#3172) --- src/parser/smt2/Smt2.g | 59 +--------------------------------------- src/parser/smt2/smt2.cpp | 24 ++++++++++++++++ src/parser/smt2/smt2.h | 11 ++++++++ 3 files changed, 36 insertions(+), 58 deletions(-) diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g index c672d8ff5..a5109361b 100644 --- a/src/parser/smt2/Smt2.g +++ b/src/parser/smt2/Smt2.g @@ -150,41 +150,6 @@ using namespace CVC4::parser; #define SOLVER PARSER_STATE->getSolver() #define UNSUPPORTED PARSER_STATE->unimplementedFeature -static bool isClosed(const Expr& e, std::set& free, std::unordered_set& 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& free) { - std::unordered_set cache; - return isClosed(e, free, cache); -} - }/* parser::postinclude */ /** @@ -2842,30 +2807,8 @@ attribute[CVC4::Expr& expr, CVC4::Expr& retExpr, std::string& attr] | 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 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::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); diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp index be0306a9e..d1fb3fe32 100644 --- a/src/parser/smt2/smt2.cpp +++ b/src/parser/smt2/smt2.cpp @@ -1566,5 +1566,29 @@ InputLanguage Smt2::getLanguage() const 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 */ diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h index 3afbcd61a..669104954 100644 --- a/src/parser/smt2/smt2.h +++ b/src/parser/smt2/smt2.h @@ -425,6 +425,17 @@ class Smt2 : public Parser } } } + /** 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) -- 2.30.2