~Implementation() { d_context.pop(); }
/** set expression name */
- bool setExpressionName(api::Term t,
- const std::string& name,
- bool isAssertion = false);
+ NamingResult setExpressionName(api::Term t,
+ const std::string& name,
+ bool isAssertion = false);
/** get expression name */
bool getExpressionName(api::Term t,
std::string& name,
CDO<bool> d_hasPushedScope;
};
-bool SymbolManager::Implementation::setExpressionName(api::Term t,
- const std::string& name,
- bool isAssertion)
+NamingResult SymbolManager::Implementation::setExpressionName(
+ api::Term t, const std::string& name, bool isAssertion)
{
Trace("sym-manager") << "SymbolManager: set expression name: " << t << " -> "
<< name << ", isAssertion=" << isAssertion << std::endl;
- // cannot name subexpressions under quantifiers
- PrettyCheckArgument(
- !d_hasPushedScope.get(), name, "cannot name function in a scope");
+ if (d_hasPushedScope.get())
+ {
+ // cannot name subexpressions under binders
+ return NamingResult::ERROR_IN_BINDER;
+ }
+
if (isAssertion)
{
d_namedAsserts.insert(t);
if (d_names.find(t) != d_names.end())
{
// already named assertion
- return false;
+ return NamingResult::ERROR_ALREADY_NAMED;
}
d_names[t] = name;
- return true;
+ return NamingResult::SUCCESS;
}
bool SymbolManager::Implementation::getExpressionName(api::Term t,
SymbolTable* SymbolManager::getSymbolTable() { return &d_symtabAllocated; }
-bool SymbolManager::setExpressionName(api::Term t,
- const std::string& name,
- bool isAssertion)
+NamingResult SymbolManager::setExpressionName(api::Term t,
+ const std::string& name,
+ bool isAssertion)
{
return d_implementation->setExpressionName(t, name, isAssertion);
}
namespace cvc5 {
+/** Represents the result of a call to `setExpressionName()`. */
+enum class NamingResult
+{
+ /** The expression name was set successfully. */
+ SUCCESS,
+ /** The expression already has a name. */
+ ERROR_ALREADY_NAMED,
+ /** The expression is in a binder. */
+ ERROR_IN_BINDER
+};
+
/**
* Symbol manager, which manages:
* (1) The symbol table used by the parser,
* @return true if the name was set. This method may return false if t
* already has a name.
*/
- bool setExpressionName(api::Term t,
- const std::string& name,
- bool isAssertion = false);
+ NamingResult setExpressionName(api::Term t,
+ const std::string& name,
+ bool isAssertion = false);
/** Get name for term t
*
* @param t The term
}
t = PARSER_STATE->mkFlatFunctionType(sorts, t, flattenVars);
- PARSER_STATE->pushScope();
+ if (sortedVarNames.size() > 0)
+ {
+ PARSER_STATE->pushScope();
+ }
terms = PARSER_STATE->bindBoundVars(sortedVarNames);
}
term[expr, expr2]
expr = PARSER_STATE->mkHoApply(expr, flattenVars);
terms.insert(terms.end(), flattenVars.begin(), flattenVars.end());
}
- PARSER_STATE->popScope();
+ if (sortedVarNames.size() > 0)
+ {
+ PARSER_STATE->popScope();
+ }
// declare the name down here (while parsing term, signature
// must not be extended with the name itself; no recursion
// permitted)
symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
{ PARSER_STATE->checkUserSymbol(name); }
sortSymbol[t,CHECK_DECLARED]
- { /* add variables to parser state before parsing term */
- Debug("parser") << "define const: '" << name << "'" << std::endl;
- PARSER_STATE->pushScope();
- terms = PARSER_STATE->bindBoundVars(sortedVarNames);
- }
term[e, e2]
{
- PARSER_STATE->popScope();
// declare the name down here (while parsing term, signature
// must not be extended with the name itself; no recursion
// permitted)
{
checkUserSymbol(name);
// remember the expression name in the symbol manager
- getSymbolManager()->setExpressionName(expr, name, false);
+ if (getSymbolManager()->setExpressionName(expr, name, false)
+ == NamingResult::ERROR_IN_BINDER)
+ {
+ parseError(
+ "Cannot name a term in a binder (e.g., quantifiers, definitions)");
+ }
// define the variable
defineVar(name, expr);
// set the last named term, which ensures that we catch when assertions are
regress0/parser/linear_arithmetic_err1.smt2
regress0/parser/linear_arithmetic_err2.smt2
regress0/parser/linear_arithmetic_err3.smt2
+ regress0/parser/named-attr-error.smt2
+ regress0/parser/named-attr.smt2
regress0/parser/shadow_fun_symbol_all.smt2
regress0/parser/shadow_fun_symbol_nirat.smt2
regress0/parser/strings20.smt2
--- /dev/null
+; REQUIRES: no-competition
+; SCRUBBER: grep -o "Cannot name a term in a binder"
+; EXPECT: Cannot name a term in a binder
+; EXIT: 1
+(set-logic QF_UF)
+(define-fun f ((x Bool)) Bool (! x :named foo))
--- /dev/null
+(set-logic QF_UF)
+(declare-const x Bool)
+(declare-const y Bool)
+(define-fun f () Bool (! x :named foo))
+(define-const g Bool (! y :named bar))
+(assert (and foo bar))
+(set-info :status sat)
+(check-sat)