summaryrefslogtreecommitdiff
path: root/src/theory/quantifiers/sygus
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/quantifiers/sygus')
-rw-r--r--src/theory/quantifiers/sygus/cegis.cpp28
-rw-r--r--src/theory/quantifiers/sygus/cegis.h7
-rw-r--r--src/theory/quantifiers/sygus/cegis_core_connective.cpp74
-rw-r--r--src/theory/quantifiers/sygus/cegis_core_connective.h42
-rw-r--r--src/theory/quantifiers/sygus/sygus_grammar_cons.cpp3
5 files changed, 35 insertions, 119 deletions
diff --git a/src/theory/quantifiers/sygus/cegis.cpp b/src/theory/quantifiers/sygus/cegis.cpp
index c8e14e4bd..fdc0b28e0 100644
--- a/src/theory/quantifiers/sygus/cegis.cpp
+++ b/src/theory/quantifiers/sygus/cegis.cpp
@@ -39,6 +39,7 @@ Cegis::Cegis(Env& env,
SynthConjecture* p)
: SygusModule(env, qs, qim, tds, p),
d_eval_unfold(tds->getEvalUnfold()),
+ d_cexClosedEnum(false),
d_cegis_sampler(env),
d_usingSymCons(false)
{
@@ -47,11 +48,18 @@ Cegis::Cegis(Env& env,
bool Cegis::initialize(Node conj, Node n, const std::vector<Node>& candidates)
{
d_base_body = n;
+ d_cexClosedEnum = true;
if (d_base_body.getKind() == NOT && d_base_body[0].getKind() == FORALL)
{
for (const Node& v : d_base_body[0][0])
{
d_base_vars.push_back(v);
+ if (!v.getType().isClosedEnumerable())
+ {
+ // not closed enumerable, refinement lemmas cannot be sent to the
+ // quantifier-free datatype solver
+ d_cexClosedEnum = false;
+ }
}
d_base_body = d_base_body[0][1];
}
@@ -467,14 +475,18 @@ void Cegis::addRefinementLemmaConjunct(unsigned wcounter,
void Cegis::registerRefinementLemma(const std::vector<Node>& vars, Node lem)
{
addRefinementLemma(lem);
- // Make the refinement lemma and add it to lems.
- // This lemma is guarded by the parent's guard, which has the semantics
- // "this conjecture has a solution", hence this lemma states:
- // if the parent conjecture has a solution, it satisfies the specification
- // for the given concrete point.
- Node rlem =
- NodeManager::currentNM()->mkNode(OR, d_parent->getGuard().negate(), lem);
- d_qim.addPendingLemma(rlem, InferenceId::QUANTIFIERS_SYGUS_CEGIS_REFINE);
+ // must be closed enumerable
+ if (d_cexClosedEnum && options().quantifiers.sygusEvalUnfold)
+ {
+ // Make the refinement lemma and add it to lems.
+ // This lemma is guarded by the parent's guard, which has the semantics
+ // "this conjecture has a solution", hence this lemma states:
+ // if the parent conjecture has a solution, it satisfies the specification
+ // for the given concrete point.
+ Node rlem = NodeManager::currentNM()->mkNode(
+ OR, d_parent->getGuard().negate(), lem);
+ d_qim.addPendingLemma(rlem, InferenceId::QUANTIFIERS_SYGUS_CEGIS_REFINE);
+ }
}
bool Cegis::usingRepairConst() { return true; }
diff --git a/src/theory/quantifiers/sygus/cegis.h b/src/theory/quantifiers/sygus/cegis.h
index 8e0fffdd1..8d1f0a1b2 100644
--- a/src/theory/quantifiers/sygus/cegis.h
+++ b/src/theory/quantifiers/sygus/cegis.h
@@ -119,6 +119,13 @@ class Cegis : public SygusModule
std::vector<Node> d_rl_vals;
/** all variables appearing in refinement lemmas */
std::unordered_set<Node> d_refinement_lemma_vars;
+ /**
+ * Are the counterexamples we are handling in this class of only closed
+ * enumerable types (see TypeNode::isClosedEnumerable). If this is false,
+ * then CEGIS refinement lemmas can contain terms that are unhandled by
+ * theory solvers, e.g. uninterpreted constants.
+ */
+ bool d_cexClosedEnum;
/** adds lem as a refinement lemma */
void addRefinementLemma(Node lem);
diff --git a/src/theory/quantifiers/sygus/cegis_core_connective.cpp b/src/theory/quantifiers/sygus/cegis_core_connective.cpp
index 936310e4e..5a0cf8724 100644
--- a/src/theory/quantifiers/sygus/cegis_core_connective.cpp
+++ b/src/theory/quantifiers/sygus/cegis_core_connective.cpp
@@ -33,41 +33,6 @@ namespace cvc5 {
namespace theory {
namespace quantifiers {
-bool VariadicTrie::add(Node n, const std::vector<Node>& i)
-{
- VariadicTrie* curr = this;
- for (const Node& ic : i)
- {
- curr = &(curr->d_children[ic]);
- }
- if (curr->d_data.isNull())
- {
- curr->d_data = n;
- return true;
- }
- return false;
-}
-
-bool VariadicTrie::hasSubset(const std::vector<Node>& is) const
-{
- if (!d_data.isNull())
- {
- return true;
- }
- for (const std::pair<const Node, VariadicTrie>& p : d_children)
- {
- Node n = p.first;
- if (std::find(is.begin(), is.end(), n) != is.end())
- {
- if (p.second.hasSubset(is))
- {
- return true;
- }
- }
- }
- return false;
-}
-
CegisCoreConnective::CegisCoreConnective(Env& env,
QuantifiersState& qs,
QuantifiersInferenceManager& qim,
@@ -595,38 +560,6 @@ bool CegisCoreConnective::Component::addToAsserts(CegisCoreConnective* p,
return true;
}
-void CegisCoreConnective::getModel(SolverEngine& smt,
- std::vector<Node>& vals) const
-{
- for (const Node& v : d_vars)
- {
- Node mv = smt.getValue(v);
- Trace("sygus-ccore-model") << v << " -> " << mv << " ";
- vals.push_back(mv);
- }
-}
-
-bool CegisCoreConnective::getUnsatCore(
- SolverEngine& smt,
- const std::unordered_set<Node>& queryAsserts,
- std::vector<Node>& uasserts) const
-{
- UnsatCore uc = smt.getUnsatCore();
- bool hasQuery = false;
- for (UnsatCore::const_iterator i = uc.begin(); i != uc.end(); ++i)
- {
- Node uassert = *i;
- Trace("sygus-ccore-debug") << " uc " << uassert << std::endl;
- if (queryAsserts.find(uassert) != queryAsserts.end())
- {
- hasQuery = true;
- continue;
- }
- uasserts.push_back(uassert);
- }
- return hasQuery;
-}
-
Result CegisCoreConnective::checkSat(Node n, std::vector<Node>& mvs) const
{
Trace("sygus-ccore-debug") << "...check-sat " << n << "..." << std::endl;
@@ -758,7 +691,8 @@ Node CegisCoreConnective::constructSolutionFromPool(Component& ccheck,
std::unordered_set<Node> queryAsserts;
queryAsserts.insert(ccheck.getFormula());
queryAsserts.insert(d_sc);
- bool hasQuery = getUnsatCore(*checkSol, queryAsserts, uasserts);
+ bool hasQuery =
+ getUnsatCoreFromSubsolver(*checkSol, queryAsserts, uasserts);
// now, check the side condition
bool falseCore = false;
if (!d_sc.isNull())
@@ -794,7 +728,7 @@ Node CegisCoreConnective::constructSolutionFromPool(Component& ccheck,
uasserts.clear();
std::unordered_set<Node> queryAsserts2;
queryAsserts2.insert(d_sc);
- getUnsatCore(*checkSc, queryAsserts2, uasserts);
+ getUnsatCoreFromSubsolver(*checkSc, queryAsserts2, uasserts);
falseCore = true;
}
}
@@ -838,7 +772,7 @@ Node CegisCoreConnective::constructSolutionFromPool(Component& ccheck,
// it does not entail the postcondition, add an assertion that blocks
// the current point
mvs.clear();
- getModel(*checkSol, mvs);
+ getModelFromSubsolver(*checkSol, d_vars, mvs);
// should evaluate to true
Node ean = evaluatePt(an, Node::null(), mvs);
Assert(ean.isConst() && ean.getConst<bool>());
diff --git a/src/theory/quantifiers/sygus/cegis_core_connective.h b/src/theory/quantifiers/sygus/cegis_core_connective.h
index 3ee631dea..26784f939 100644
--- a/src/theory/quantifiers/sygus/cegis_core_connective.h
+++ b/src/theory/quantifiers/sygus/cegis_core_connective.h
@@ -22,6 +22,7 @@
#include "expr/node.h"
#include "expr/node_trie.h"
+#include "expr/variadic_trie.h"
#include "smt/env_obj.h"
#include "theory/quantifiers/sygus/cegis.h"
#include "util/result.h"
@@ -33,30 +34,6 @@ class SolverEngine;
namespace theory {
namespace quantifiers {
-/**
- * A trie that stores data at undetermined depth. Storing data at
- * undetermined depth is in contrast to the NodeTrie (expr/node_trie.h), which
- * assumes all data is stored at a fixed depth.
- *
- * Since data can be stored at any depth, we require both a d_children field
- * and a d_data field.
- */
-class VariadicTrie
-{
- public:
- /** the children of this node */
- std::map<Node, VariadicTrie> d_children;
- /** the data at this node */
- Node d_data;
- /**
- * Add data with identifier n indexed by i, return true if data is not already
- * stored at the node indexed by i.
- */
- bool add(Node n, const std::vector<Node>& i);
- /** Is there any data in this trie that is indexed by any subset of is? */
- bool hasSubset(const std::vector<Node>& is) const;
-};
-
/** CegisCoreConnective
*
* A sygus module that is specialized in handling conjectures of the form:
@@ -336,23 +313,6 @@ class CegisCoreConnective : public Cegis
Node d_sc;
//-----------------------------------for SMT engine calls
/**
- * Assuming smt has just been called to check-sat and returned "SAT", this
- * method adds the model for d_vars to mvs.
- */
- void getModel(SolverEngine& smt, std::vector<Node>& mvs) const;
- /**
- * Assuming smt has just been called to check-sat and returned "UNSAT", this
- * method get the unsat core and adds it to uasserts.
- *
- * The assertions in the argument queryAsserts (which we are not interested
- * in tracking in the unsat core) are excluded from uasserts.
- * If one of the formulas in queryAsserts was in the unsat core, then this
- * method returns true. Otherwise, this method returns false.
- */
- bool getUnsatCore(SolverEngine& smt,
- const std::unordered_set<Node>& queryAsserts,
- std::vector<Node>& uasserts) const;
- /**
* Return the result of checking satisfiability of formula n.
* If n was satisfiable, then we store the model for d_vars in mvs.
*/
diff --git a/src/theory/quantifiers/sygus/sygus_grammar_cons.cpp b/src/theory/quantifiers/sygus/sygus_grammar_cons.cpp
index 43c958ff9..9b4cfb9e1 100644
--- a/src/theory/quantifiers/sygus/sygus_grammar_cons.cpp
+++ b/src/theory/quantifiers/sygus/sygus_grammar_cons.cpp
@@ -20,6 +20,7 @@
#include "expr/ascription_type.h"
#include "expr/dtype_cons.h"
+#include "expr/node_algorithm.h"
#include "options/quantifiers_options.h"
#include "theory/bv/theory_bv_utils.h"
#include "theory/datatypes/sygus_datatype_utils.h"
@@ -420,6 +421,8 @@ void CegGrammarConstructor::mkSygusConstantsForType(TypeNode type,
{
// generate constant array over the first element of the constituent type
Node c = type.mkGroundTerm();
+ // note that c should never contain an uninterpreted constant
+ Assert(!expr::hasSubtermKind(UNINTERPRETED_CONSTANT, c));
ops.push_back(c);
}
else if (type.isRoundingMode())
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback