summaryrefslogtreecommitdiff
path: root/src/theory/quantifiers/sygus/cegis_unif.cpp
diff options
context:
space:
mode:
authorHaniel Barbosa <hanielbbarbosa@gmail.com>2018-05-03 07:54:27 -0500
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>2018-05-03 07:54:27 -0500
commit53e1523de04c8643186244d9fc3c329ff158a057 (patch)
tree122b85b66cba8b45a892f02147229121adf58630 /src/theory/quantifiers/sygus/cegis_unif.cpp
parentf45c0f10a01023b7653c8c36ffe37f70e4e56baa (diff)
Make CegisUnif default to Cegis when no unif used (#1836)
Diffstat (limited to 'src/theory/quantifiers/sygus/cegis_unif.cpp')
-rw-r--r--src/theory/quantifiers/sygus/cegis_unif.cpp173
1 files changed, 48 insertions, 125 deletions
diff --git a/src/theory/quantifiers/sygus/cegis_unif.cpp b/src/theory/quantifiers/sygus/cegis_unif.cpp
index cbd9358e0..14a5bedf5 100644
--- a/src/theory/quantifiers/sygus/cegis_unif.cpp
+++ b/src/theory/quantifiers/sygus/cegis_unif.cpp
@@ -14,6 +14,7 @@
#include "theory/quantifiers/sygus/cegis_unif.h"
+#include "options/quantifiers_options.h"
#include "theory/quantifiers/sygus/ce_guided_conjecture.h"
#include "theory/quantifiers/sygus/sygus_unif_rl.h"
#include "theory/quantifiers/sygus/term_database_sygus.h"
@@ -25,7 +26,7 @@ namespace theory {
namespace quantifiers {
CegisUnif::CegisUnif(QuantifiersEngine* qe, CegConjecture* p)
- : SygusModule(qe, p)
+ : Cegis(qe, p), d_sygus_unif(p)
{
d_tds = d_qe->getTermDatabaseSygus();
}
@@ -36,43 +37,43 @@ bool CegisUnif::initialize(Node n,
std::vector<Node>& lemmas)
{
Trace("cegis-unif") << "Initialize CegisUnif : " << n << std::endl;
- Assert(candidates.size() > 0);
- if (candidates.size() > 1)
+ /* Init UNIF util */
+ d_sygus_unif.initialize(d_qe, candidates, d_cond_enums, lemmas);
+ /* TODO initialize unif enumerators */
+ Trace("cegis-unif") << "Initializing enums for pure Cegis case\n";
+ /* Initialize enumerators for non-unif functions-to-synhesize */
+ for (const Node& c : candidates)
{
- return false;
- }
- d_candidate = candidates[0];
- Trace("cegis-unif") << "Initialize unif utility for " << d_candidate
- << "...\n";
- d_sygus_unif.initialize(d_qe, candidates, d_enums, lemmas);
- Assert(!d_enums.empty());
- Trace("cegis-unif") << "Initialize " << d_enums.size() << " enumerators for "
- << d_candidate << "...\n";
- /* initialize the enumerators */
- for (const Node& e : d_enums)
- {
- d_tds->registerEnumerator(e, d_candidate, d_parent, true);
- Node g = d_tds->getActiveGuardForEnumerator(e);
- d_enum_to_active_guard[e] = g;
+ if (!d_sygus_unif.usingUnif(c))
+ {
+ d_tds->registerEnumerator(c, c, d_parent);
+ }
}
return true;
}
void CegisUnif::getTermList(const std::vector<Node>& candidates,
- std::vector<Node>& terms)
+ std::vector<Node>& enums)
{
- Assert(candidates.size() == 1);
- Valuation& valuation = d_qe->getValuation();
- for (const Node& e : d_enums)
+ for (const Node& c : candidates)
{
- Assert(d_enum_to_active_guard.find(e) != d_enum_to_active_guard.end());
- Node g = d_enum_to_active_guard[e];
- /* Get whether the active guard for this enumerator is if so, then there may
- exist more values for it, and hence we add it to terms. */
- Node gstatus = valuation.getSatValue(g);
- if (!gstatus.isNull() && gstatus.getConst<bool>())
+ if (!d_sygus_unif.usingUnif(c))
+ {
+ enums.push_back(c);
+ continue;
+ }
+ Valuation& valuation = d_qe->getValuation();
+ for (const Node& e : d_cond_enums)
{
- terms.push_back(e);
+ Assert(d_enum_to_active_guard.find(e) != d_enum_to_active_guard.end());
+ Node g = d_enum_to_active_guard[e];
+ /* Get whether the active guard for this enumerator is set. If so, then
+ there may exist more values for it, and hence we add it to enums. */
+ Node gstatus = valuation.getSatValue(g);
+ if (!gstatus.isNull() && gstatus.getConst<bool>())
+ {
+ enums.push_back(e);
+ }
}
}
}
@@ -83,16 +84,23 @@ bool CegisUnif::constructCandidates(const std::vector<Node>& enums,
std::vector<Node>& candidate_values,
std::vector<Node>& lems)
{
- Assert(enums.size() == enum_values.size());
- if (enums.empty())
+ if (addEvalLemmas(enums, enum_values))
{
+ Trace("cegis-unif-lemma") << "Added eval lemmas\n";
return false;
}
unsigned min_term_size = 0;
std::vector<unsigned> enum_consider;
+ NodeManager* nm = NodeManager::currentNM();
Trace("cegis-unif-enum") << "Register new enumerated values :\n";
for (unsigned i = 0, size = enums.size(); i < size; ++i)
{
+ /* Only conditional enumerators will be notified to unif utility */
+ if (std::find(d_cond_enums.begin(), d_cond_enums.end(), enums[i])
+ == d_cond_enums.end())
+ {
+ continue;
+ }
Trace("cegis-unif-enum") << " " << enums[i] << " -> " << enum_values[i]
<< std::endl;
unsigned sz = d_tds->getSygusTermSize(enum_values[i]);
@@ -110,12 +118,10 @@ bool CegisUnif::constructCandidates(const std::vector<Node>& enums,
/* only consider the enumerators that are at minimum size (for fairness) */
Trace("cegis-unif-enum") << "...register " << enum_consider.size() << " / "
<< enums.size() << std::endl;
- NodeManager* nm = NodeManager::currentNM();
for (unsigned i = 0, ecsize = enum_consider.size(); i < ecsize; ++i)
{
unsigned j = enum_consider[i];
- Node e = enums[j];
- Node v = enum_values[j];
+ Node e = enums[j], v = enum_values[j];
std::vector<Node> enum_lems;
d_sygus_unif.notifyEnumeration(e, v, enum_lems);
/* the lemmas must be guarded by the active guard of the enumerator */
@@ -127,112 +133,29 @@ bool CegisUnif::constructCandidates(const std::vector<Node>& enums,
}
lems.insert(lems.end(), enum_lems.begin(), enum_lems.end());
}
- /* build candidate solution */
- Assert(candidates.size() == 1);
- if (d_sygus_unif.constructSolution(candidate_values))
+ /* divide-and-conquer solution bulding for candidates using unif util */
+ std::vector<Node> sols;
+ if (d_sygus_unif.constructSolution(sols))
{
- Node vc = candidate_values[0];
- Trace("cegis-unif-enum") << "... candidate solution :" << vc << "\n";
+ candidate_values.insert(candidate_values.end(), sols.begin(), sols.end());
return true;
}
return false;
}
-Node CegisUnif::purifyLemma(Node n,
- bool ensureConst,
- std::vector<Node>& model_guards,
- BoolNodePairMap& cache)
-{
- Trace("cegis-unif-purify") << "PurifyLemma : " << n << "\n";
- BoolNodePairMap::const_iterator it = cache.find(BoolNodePair(ensureConst, n));
- if (it != cache.end())
- {
- Trace("cegis-unif-purify") << "... already visited " << n << "\n";
- return it->second;
- }
- /* Recurse */
- unsigned size = n.getNumChildren();
- Kind k = n.getKind();
- bool fapp = k == APPLY_UF && size > 0 && n[0] == d_candidate;
- bool childChanged = false;
- std::vector<Node> children;
- for (unsigned i = 0; i < size; ++i)
- {
- if (i == 0 && fapp)
- {
- children.push_back(n[0]);
- continue;
- }
- Node child = purifyLemma(n[i], ensureConst || fapp, model_guards, cache);
- children.push_back(child);
- childChanged = childChanged || child != n[i];
- }
- Node nb;
- if (childChanged)
- {
- if (n.hasOperator())
- {
- children.insert(children.begin(), n.getOperator());
- }
- nb = NodeManager::currentNM()->mkNode(k, children);
- Trace("cegis-unif-purify") << "PurifyLemma : transformed " << n << " into "
- << nb << "\n";
- }
- else
- {
- nb = n;
- }
- /* get model value of non-top level applications of d_candidate */
- if (ensureConst && fapp)
- {
- Node nv = d_parent->getModelValue(nb);
- Trace("cegis-unif-purify") << "PurifyLemma : model value for " << nb
- << " is " << nv << "\n";
- /* test if different, then update model_guards */
- if (nv != nb)
- {
- Trace("cegis-unif-purify") << "PurifyLemma : adding model eq\n";
- model_guards.push_back(
- NodeManager::currentNM()->mkNode(EQUAL, nv, nb).negate());
- nb = nv;
- }
- }
- nb = Rewriter::rewrite(nb);
- /* every non-top level application of function-to-synthesize must be reduced
- to a concrete constant */
- Assert(!ensureConst || nb.isConst());
- Trace("cegis-unif-purify") << "... caching [" << n << "] = " << nb << "\n";
- cache[BoolNodePair(ensureConst, n)] = nb;
- return nb;
-}
-
void CegisUnif::registerRefinementLemma(const std::vector<Node>& vars,
Node lem,
std::vector<Node>& lems)
{
- Node plem;
- std::vector<Node> model_guards;
- BoolNodePairMap cache;
- Trace("cegis-unif") << "Registering lemma at CegisUnif : " << lem << "\n";
- /* Make the purified lemma which will guide the unification utility. */
- plem = purifyLemma(lem, false, model_guards, cache);
- if (!model_guards.empty())
- {
- model_guards.push_back(plem);
- plem = NodeManager::currentNM()->mkNode(OR, model_guards);
- }
- plem = Rewriter::rewrite(plem);
- Trace("cegis-unif") << "Purified lemma : " << plem << "\n";
+ /* Notify lemma to unification utility and get its purified form */
+ Node plem = d_sygus_unif.addRefLemma(lem);
d_refinement_lemmas.push_back(plem);
- /* Notify lemma to unification utility */
- d_sygus_unif.addRefLemma(plem);
/* 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. */
- /* Store lemma for external modules */
- lems.push_back(
- NodeManager::currentNM()->mkNode(OR, d_parent->getGuard().negate(), lem));
+ lems.push_back(NodeManager::currentNM()->mkNode(
+ OR, d_parent->getGuard().negate(), plem));
}
CegisUnifEnumManager::CegisUnifEnumManager(QuantifiersEngine* qe,
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback