summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2021-08-19 17:40:05 -0500
committerGitHub <noreply@github.com>2021-08-19 22:40:05 +0000
commit09719301db1532093117bc60546e01dca77b59b8 (patch)
tree230245ce4224b5c69df3e8fd19db86298ac76cb6
parent4cf91341622270e4aaefe926d4be7fe148c6fa74 (diff)
Catch cases where recursive functions reference functions-to-synthesize (#6993)
We previously incorrectly allowed this, leading to problems that were unsolvable but where we would not warn the user this combination is not supported. FYI @polgreen
-rw-r--r--src/smt/assertions.cpp25
-rw-r--r--src/theory/theory_engine.cpp11
2 files changed, 27 insertions, 9 deletions
diff --git a/src/smt/assertions.cpp b/src/smt/assertions.cpp
index b7688d833..6292b5982 100644
--- a/src/smt/assertions.cpp
+++ b/src/smt/assertions.cpp
@@ -178,12 +178,19 @@ void Assertions::addFormula(TNode n,
if (expr::hasFreeVar(n))
{
std::stringstream se;
- se << "Cannot process assertion with free variable.";
- if (language::isInputLangSygus(options::inputLanguage()))
+ if (isFunDef)
{
- // Common misuse of SyGuS is to use top-level assert instead of
- // constraint when defining the synthesis conjecture.
- se << " Perhaps you meant `constraint` instead of `assert`?";
+ se << "Cannot process function definition with free variable.";
+ }
+ else
+ {
+ se << "Cannot process assertion with free variable.";
+ if (language::isInputLangSygus(options::inputLanguage()))
+ {
+ // Common misuse of SyGuS is to use top-level assert instead of
+ // constraint when defining the synthesis conjecture.
+ se << " Perhaps you meant `constraint` instead of `assert`?";
+ }
}
throw ModalException(se.str().c_str());
}
@@ -205,9 +212,11 @@ void Assertions::addDefineFunDefinition(Node n, bool global)
}
else
{
- // we don't check for free variables here, since even if we are sygus,
- // we could contain functions-to-synthesize within definitions.
- addFormula(n, true, false, true, false);
+ // We don't permit functions-to-synthesize within recursive function
+ // definitions currently. Thus, we should check for free variables if the
+ // input language is SyGuS.
+ bool maybeHasFv = language::isInputLangSygus(options::inputLanguage());
+ addFormula(n, true, false, true, maybeHasFv);
}
}
diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp
index 21c22586b..12d3fccfe 100644
--- a/src/theory/theory_engine.cpp
+++ b/src/theory/theory_engine.cpp
@@ -303,7 +303,16 @@ void TheoryEngine::preRegister(TNode preprocessed) {
// the atom should not have free variables
Debug("theory") << "TheoryEngine::preRegister: " << preprocessed
<< std::endl;
- Assert(!expr::hasFreeVar(preprocessed));
+ if (Configuration::isAssertionBuild())
+ {
+ std::unordered_set<Node> fvs;
+ expr::getFreeVariables(preprocessed, fvs);
+ if (!fvs.empty())
+ {
+ Unhandled() << "Preregistered term with free variable: "
+ << preprocessed << ", fv=" << *fvs.begin();
+ }
+ }
// should not have witness
Assert(!expr::hasSubtermKind(kind::WITNESS, preprocessed));
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback