Skip to content

Commit

Permalink
Do not allow implicit arguments in definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
ajreynol committed Jan 30, 2024
1 parent 685b750 commit 50ade27
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/cmd_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,27 @@ bool CmdParser::parseNextCommand()
case Token::DEFINE:
{
d_state.pushScope();
//d_state.checkThatLogicIsSet();
std::string name = d_eparser.parseSymbol();
//d_state.checkUserSymbol(name);
std::vector<Expr> impls;
std::vector<Expr> vars =
d_eparser.parseAndBindSortedVarList();
d_eparser.parseAndBindSortedVarList(impls);
if (!impls.empty())
{
// If there were implicit variables, we go back and refine what is
// bound in the body to only include the explicit arguments. This
// ensures that `T` is not parsable in the body of a definition like:
// (define test ((T Type :implicit) (x T)) T)
// It should not be parsable since it is not bound when test is applied,
// which prevents users from generating definitions that lead to
// unexpected unbound arguments.
d_state.popScope();
d_state.pushScope();
for (const Expr& e : vars)
{
d_state.bind(e.getSymbol(), e);
}
}
Expr ret;
if (tok == Token::DEFINE_FUN)
{
Expand Down
8 changes: 8 additions & 0 deletions src/expr_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,13 @@ std::vector<Expr> ExprParser::parseExprPairList()
}

std::vector<Expr> ExprParser::parseAndBindSortedVarList(bool isLookup)
{
std::vector<Expr> impls;
return parseAndBindSortedVarList(impls, isLookup);
}

std::vector<Expr> ExprParser::parseAndBindSortedVarList(
std::vector<Expr>& impls, bool isLookup)
{
std::vector<Expr> varList;
d_lex.eatToken(Token::LPAREN);
Expand Down Expand Up @@ -700,6 +707,7 @@ std::vector<Expr> ExprParser::parseAndBindSortedVarList(bool isLookup)
{
attrs.erase(Attr::IMPLICIT);
isImplicit = true;
impls.push_back(v);
}
if (processAttributeMap(attrs, ck, cons))
{
Expand Down
7 changes: 7 additions & 0 deletions src/expr_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ class ExprParser
* variables and throw an error if a variable does not match.
*/
std::vector<Expr> parseAndBindSortedVarList(bool isLookup=false);
/**
* Same as above, but tracks implicit variables. All variables marked
* :implicit that were parsed and not added to the return value of this
* method are added to impls.
*/
std::vector<Expr> parseAndBindSortedVarList(std::vector<Expr>& impls,
bool isLookup=false);
/**
* Parse symbol, which returns the string of the parsed symbol if the next
* token is a valid smt2 symbol.
Expand Down

0 comments on commit 50ade27

Please sign in to comment.