summaryrefslogtreecommitdiff
path: root/src/theory/quantifiers/candidate_rewrite_database.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/quantifiers/candidate_rewrite_database.cpp')
-rw-r--r--src/theory/quantifiers/candidate_rewrite_database.cpp197
1 files changed, 154 insertions, 43 deletions
diff --git a/src/theory/quantifiers/candidate_rewrite_database.cpp b/src/theory/quantifiers/candidate_rewrite_database.cpp
index 03c39f718..9bbb88699 100644
--- a/src/theory/quantifiers/candidate_rewrite_database.cpp
+++ b/src/theory/quantifiers/candidate_rewrite_database.cpp
@@ -32,37 +32,93 @@ namespace CVC4 {
namespace theory {
namespace quantifiers {
-CandidateRewriteDatabase::CandidateRewriteDatabase() : d_qe(nullptr) {}
-void CandidateRewriteDatabase::initialize(QuantifiersEngine* qe,
- Node f,
+// the number of d_drewrite objects we have allocated (to avoid name conflicts)
+static unsigned drewrite_counter = 0;
+
+CandidateRewriteDatabase::CandidateRewriteDatabase()
+ : d_qe(nullptr),
+ d_tds(nullptr),
+ d_ext_rewrite(nullptr),
+ d_using_sygus(false)
+{
+ if (options::sygusRewSynthFilterCong())
+ {
+ // initialize the dynamic rewriter
+ std::stringstream ss;
+ ss << "_dyn_rewriter_" << drewrite_counter;
+ drewrite_counter++;
+ d_drewrite = std::unique_ptr<DynamicRewriter>(
+ new DynamicRewriter(ss.str(), &d_fake_context));
+ d_sampler.setDynamicRewriter(d_drewrite.get());
+ }
+}
+void CandidateRewriteDatabase::initialize(ExtendedRewriter* er,
+ TypeNode tn,
+ std::vector<Node>& vars,
unsigned nsamples,
- bool useSygusType)
+ bool unique_type_ids)
+{
+ d_candidate = Node::null();
+ d_type = tn;
+ d_using_sygus = false;
+ d_qe = nullptr;
+ d_tds = nullptr;
+ d_ext_rewrite = er;
+ d_sampler.initialize(tn, vars, nsamples, unique_type_ids);
+}
+
+void CandidateRewriteDatabase::initializeSygus(QuantifiersEngine* qe,
+ Node f,
+ unsigned nsamples,
+ bool useSygusType)
{
- d_qe = qe;
d_candidate = f;
- d_sampler.initializeSygusExt(d_qe, f, nsamples, useSygusType);
+ d_type = f.getType();
+ Assert(d_type.isDatatype());
+ Assert(static_cast<DatatypeType>(d_type.toType()).getDatatype().isSygus());
+ d_using_sygus = true;
+ d_qe = qe;
+ d_tds = d_qe->getTermDatabaseSygus();
+ d_ext_rewrite = d_tds->getExtRewriter();
+ d_sampler.initializeSygus(d_tds, f, nsamples, useSygusType);
}
-bool CandidateRewriteDatabase::addTerm(Node sol, std::ostream& out)
+bool CandidateRewriteDatabase::addTerm(Node sol,
+ std::ostream& out,
+ bool& rew_print)
{
bool is_unique_term = true;
- TermDbSygus* sygusDb = d_qe->getTermDatabaseSygus();
Node eq_sol = d_sampler.registerTerm(sol);
// eq_sol is a candidate solution that is equivalent to sol
if (eq_sol != sol)
{
- CegInstantiation* cei = d_qe->getCegInstantiation();
is_unique_term = false;
// if eq_sol is null, then we have an uninteresting candidate rewrite,
// e.g. one that is alpha-equivalent to another.
- bool success = true;
if (!eq_sol.isNull())
{
- ExtendedRewriter* er = sygusDb->getExtRewriter();
- Node solb = sygusDb->sygusToBuiltin(sol);
- Node solbr = er->extendedRewrite(solb);
- Node eq_solb = sygusDb->sygusToBuiltin(eq_sol);
- Node eq_solr = er->extendedRewrite(eq_solb);
+ // get the actual term
+ Node solb = sol;
+ Node eq_solb = eq_sol;
+ if (d_using_sygus)
+ {
+ Assert(d_tds != nullptr);
+ solb = d_tds->sygusToBuiltin(sol);
+ eq_solb = d_tds->sygusToBuiltin(eq_sol);
+ }
+ // get the rewritten form
+ Node solbr;
+ Node eq_solr;
+ if (d_ext_rewrite != nullptr)
+ {
+ solbr = d_ext_rewrite->extendedRewrite(solb);
+ eq_solr = d_ext_rewrite->extendedRewrite(eq_solb);
+ }
+ else
+ {
+ solbr = Rewriter::rewrite(solb);
+ eq_solr = Rewriter::rewrite(eq_solb);
+ }
bool verified = false;
Trace("rr-check") << "Check candidate rewrite..." << std::endl;
// verify it if applicable
@@ -108,27 +164,36 @@ bool CandidateRewriteDatabase::addTerm(Node sol, std::ostream& out)
if (r.asSatisfiabilityResult().isSat() == Result::SAT)
{
Trace("rr-check") << "...rewrite does not hold for: " << std::endl;
- success = false;
is_unique_term = true;
std::vector<Node> vars;
d_sampler.getVariables(vars);
std::vector<Node> pt;
for (const Node& v : vars)
{
- std::map<Node, unsigned>::iterator itf = fv_index.find(v);
Node val;
- if (itf == fv_index.end())
+ Node refv = v;
+ // if a bound variable, map to the skolem we introduce before
+ // looking up the model value
+ if (v.getKind() == BOUND_VARIABLE)
{
- // not in conjecture, can use arbitrary value
- val = v.getType().mkGroundTerm();
+ std::map<Node, unsigned>::iterator itf = fv_index.find(v);
+ if (itf == fv_index.end())
+ {
+ // not in conjecture, can use arbitrary value
+ val = v.getType().mkGroundTerm();
+ }
+ else
+ {
+ // get the model value of its skolem
+ refv = sks[itf->second];
+ }
}
- else
+ if (val.isNull())
{
- // get the model value of its skolem
- Node sk = sks[itf->second];
- val = Node::fromExpr(rrChecker.getValue(sk.toExpr()));
- Trace("rr-check") << " " << v << " -> " << val << std::endl;
+ Assert(!refv.isNull() && refv.getKind() != BOUND_VARIABLE);
+ val = Node::fromExpr(rrChecker.getValue(refv.toExpr()));
}
+ Trace("rr-check") << " " << v << " -> " << val << std::endl;
pt.push_back(val);
}
d_sampler.addSamplePoint(pt);
@@ -145,22 +210,29 @@ bool CandidateRewriteDatabase::addTerm(Node sol, std::ostream& out)
else
{
// just insist that constants are not relevant pairs
- success = !solb.isConst() || !eq_solb.isConst();
+ is_unique_term = solb.isConst() && eq_solb.isConst();
}
- if (success)
+ if (!is_unique_term)
{
// register this as a relevant pair (helps filtering)
d_sampler.registerRelevantPair(sol, eq_sol);
// The analog of terms sol and eq_sol are equivalent under
// sample points but do not rewrite to the same term. Hence,
// this indicates a candidate rewrite.
- Printer* p = Printer::getPrinter(options::outputLanguage());
out << "(" << (verified ? "" : "candidate-") << "rewrite ";
- p->toStreamSygus(out, sol);
- out << " ";
- p->toStreamSygus(out, eq_sol);
+ if (d_using_sygus)
+ {
+ Printer* p = Printer::getPrinter(options::outputLanguage());
+ p->toStreamSygus(out, sol);
+ out << " ";
+ p->toStreamSygus(out, eq_sol);
+ }
+ else
+ {
+ out << sol << " " << eq_sol;
+ }
out << ")" << std::endl;
- ++(cei->d_statistics.d_candidate_rewrites_print);
+ rew_print = true;
// debugging information
if (Trace.isOn("sygus-rr-debug"))
{
@@ -169,32 +241,33 @@ bool CandidateRewriteDatabase::addTerm(Node sol, std::ostream& out)
Trace("sygus-rr-debug")
<< "; candidate #2 ext-rewrites to: " << eq_solr << std::endl;
}
- if (options::sygusRewSynthAccel())
+ if (options::sygusRewSynthAccel() && d_using_sygus)
{
+ Assert(d_tds != nullptr);
// Add a symmetry breaking clause that excludes the larger
// of sol and eq_sol. This effectively states that we no longer
// wish to enumerate any term that contains sol (resp. eq_sol)
// as a subterm.
Node exc_sol = sol;
- unsigned sz = sygusDb->getSygusTermSize(sol);
- unsigned eqsz = sygusDb->getSygusTermSize(eq_sol);
+ unsigned sz = d_tds->getSygusTermSize(sol);
+ unsigned eqsz = d_tds->getSygusTermSize(eq_sol);
if (eqsz > sz)
{
sz = eqsz;
exc_sol = eq_sol;
}
TypeNode ptn = d_candidate.getType();
- Node x = sygusDb->getFreeVar(ptn, 0);
- Node lem =
- sygusDb->getExplain()->getExplanationForEquality(x, exc_sol);
+ Node x = d_tds->getFreeVar(ptn, 0);
+ Node lem = d_tds->getExplain()->getExplanationForEquality(x, exc_sol);
lem = lem.negate();
Trace("sygus-rr-sb") << "Symmetry breaking lemma : " << lem
<< std::endl;
- sygusDb->registerSymBreakLemma(d_candidate, lem, ptn, sz);
+ d_tds->registerSymBreakLemma(d_candidate, lem, ptn, sz);
}
}
}
// We count this as a rewrite if we did not explicitly rule it out.
+ // The value of is_unique_term is false iff this call resulted in a rewrite.
// Notice that when --sygus-rr-synth-check is enabled,
// statistics on number of candidate rewrite rules is
// an accurate count of (#enumerated_terms-#unique_terms) only if
@@ -203,14 +276,52 @@ bool CandidateRewriteDatabase::addTerm(Node sol, std::ostream& out)
// rule is not useful since its variables are unordered, whereby
// it discards it as a redundant candidate rewrite rule before
// checking its correctness.
- if (success)
- {
- ++(cei->d_statistics.d_candidate_rewrites);
- }
}
return is_unique_term;
}
+bool CandidateRewriteDatabase::addTerm(Node sol, std::ostream& out)
+{
+ bool rew_print = false;
+ return addTerm(sol, out, rew_print);
+}
+
+CandidateRewriteDatabaseGen::CandidateRewriteDatabaseGen(
+ std::vector<Node>& vars, unsigned nsamples)
+ : d_vars(vars.begin(), vars.end()), d_nsamples(nsamples)
+{
+}
+
+bool CandidateRewriteDatabaseGen::addTerm(Node n, std::ostream& out)
+{
+ ExtendedRewriter* er = nullptr;
+ if (options::synthRrPrepExtRew())
+ {
+ er = &d_ext_rewrite;
+ }
+ Node nr;
+ if (er == nullptr)
+ {
+ nr = Rewriter::rewrite(n);
+ }
+ else
+ {
+ nr = er->extendedRewrite(n);
+ }
+ TypeNode tn = nr.getType();
+ std::map<TypeNode, CandidateRewriteDatabase>::iterator itc = d_cdbs.find(tn);
+ if (itc == d_cdbs.end())
+ {
+ Trace("synth-rr-dbg") << "Initialize database for " << tn << std::endl;
+ // initialize with the extended rewriter owned by this class
+ d_cdbs[tn].initialize(er, tn, d_vars, d_nsamples, true);
+ itc = d_cdbs.find(tn);
+ Trace("synth-rr-dbg") << "...finish." << std::endl;
+ }
+ Trace("synth-rr-dbg") << "Add term " << nr << " for " << tn << std::endl;
+ return itc->second.addTerm(nr, out);
+}
+
} /* CVC4::theory::quantifiers namespace */
} /* CVC4::theory namespace */
} /* CVC4 namespace */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback