d_cbqi_set_quant_inactive(false),
d_incomplete_check(false),
d_added_cbqi_lemma(userContext()),
- d_vtsCache(new VtsTermCache(env, qim)),
d_bv_invert(nullptr),
d_small_const_multiplier(NodeManager::currentNM()->mkConstReal(
Rational(1) / Rational(1000000))),
- d_small_const(d_small_const_multiplier)
+ d_small_const(d_small_const_multiplier),
+ d_freeDeltaLb(false, userContext())
{
d_check_vts_lemma_lc = false;
if (options().quantifiers.cegqiBv)
// do virtual term substitution
inst = rewrite(inst);
Trace("quant-vts-debug") << "Rewrite vts symbols in " << inst << std::endl;
- inst = d_vtsCache->rewriteVtsSymbols(inst);
+ VtsTermCache* vtc = d_treg.getVtsTermCache();
+ inst = vtc->rewriteVtsSymbols(inst);
Trace("quant-vts-debug") << "...got " << inst << std::endl;
}
if (prevInst != inst)
// don't need to process this, since it has been reduced
return;
}
+ // run the check
if( e==0 ){
CegInstantiator * cinst = getInstantiator( q );
Trace("inst-alg") << "-> Run cegqi for " << q << std::endl;
d_curr_quant = q;
if( !cinst->check() ){
d_incomplete_check = true;
- d_check_vts_lemma_lc = true;
}
d_curr_quant = Node::null();
- }else if( e==1 ){
- NodeManager* nm = NodeManager::currentNM();
+ }
+
+ // now, process the bounding lemmas for virtual terms
+ NodeManager* nm = NodeManager::currentNM();
+ VtsTermCache* vtc = d_treg.getVtsTermCache();
+ if (e == 0)
+ {
+ // if the check was incomplete, process bounds at next effort level
+ d_check_vts_lemma_lc = d_incomplete_check;
+ // process the lower bound for free delta immediately
+ Node delta = vtc->getVtsDelta(true, false);
+ if (!delta.isNull())
+ {
+ if (!d_freeDeltaLb.get())
+ {
+ d_freeDeltaLb = true;
+ Node zero = nm->mkConstReal(Rational(0));
+ Node delta_lem = nm->mkNode(GT, delta, zero);
+ d_qim.lemma(delta_lem, InferenceId::QUANTIFIERS_CEGQI_VTS_LB_DELTA);
+ }
+ }
+ }
+ else if (e == 1)
+ {
//minimize the free delta heuristically on demand
if( d_check_vts_lemma_lc ){
Trace("inst-alg") << "-> Minimize delta heuristic, for " << q << std::endl;
d_check_vts_lemma_lc = false;
- d_small_const = NodeManager::currentNM()->mkNode(
- MULT, d_small_const, d_small_const_multiplier);
+ d_small_const = nm->mkNode(MULT, d_small_const, d_small_const_multiplier);
d_small_const = rewrite(d_small_const);
//heuristic for now, until we know how to do nested quantification
- Node delta = d_vtsCache->getVtsDelta(true, false);
+ Node delta = vtc->getVtsDelta(true, false);
if( !delta.isNull() ){
Trace("quant-vts-debug") << "Delta lemma for " << d_small_const << std::endl;
- Node delta_lem_ub = NodeManager::currentNM()->mkNode( LT, delta, d_small_const );
+ Node delta_lem_ub = nm->mkNode(LT, delta, d_small_const);
d_qim.lemma(delta_lem_ub, InferenceId::QUANTIFIERS_CEGQI_VTS_UB_DELTA);
}
std::vector< Node > inf;
- d_vtsCache->getVtsTerms(inf, true, false, false);
- for( unsigned i=0; i<inf.size(); i++ ){
- Trace("quant-vts-debug") << "Infinity lemma for " << inf[i] << " " << d_small_const << std::endl;
+ vtc->getVtsTerms(inf, true, false, false);
+ for (const Node& i : inf)
+ {
+ Trace("quant-vts-debug")
+ << "Infinity lemma for " << i << " " << d_small_const << std::endl;
Node inf_lem_lb = nm->mkNode(
GT,
- inf[i],
+ i,
nm->mkConstReal(Rational(1) / d_small_const.getConst<Rational>()));
d_qim.lemma(inf_lem_lb, InferenceId::QUANTIFIERS_CEGQI_VTS_LB_INF);
}
bool InstStrategyCegqi::doAddInstantiation( std::vector< Node >& subs ) {
Assert(!d_curr_quant.isNull());
// check if we need virtual term substitution (if used delta or infinity)
- bool usedVts = d_vtsCache->containsVtsTerm(subs, false);
+ VtsTermCache* vtc = d_treg.getVtsTermCache();
+ bool usedVts = vtc->containsVtsTerm(subs, false);
Instantiate* inst = d_qim.getInstantiate();
//if doing partial quantifier elimination, record the instantiation and set the incomplete flag instead of sending instantiation lemma
if (d_qreg.getQuantAttributes().isQuantElimPartial(d_curr_quant))
VtsTermCache* InstStrategyCegqi::getVtsTermCache() const
{
- return d_vtsCache.get();
+ return d_treg.getVtsTermCache();
}
BvInverter* InstStrategyCegqi::getBvInverter() const
#include "theory/quantifiers/bv_inverter.h"
#include "theory/quantifiers/cegqi/ceg_instantiator.h"
#include "theory/quantifiers/cegqi/nested_qe.h"
-#include "theory/quantifiers/cegqi/vts_term_cache.h"
#include "theory/quantifiers/instantiate.h"
#include "theory/quantifiers/quant_module.h"
#include "util/statistics_stats.h"
* This object is responsible for finding instantiatons for q.
*/
std::map<Node, std::unique_ptr<CegInstantiator>> d_cinst;
- /** virtual term substitution term cache for arithmetic instantiation */
- std::unique_ptr<VtsTermCache> d_vtsCache;
/** inversion utility for BV instantiation */
std::unique_ptr<BvInverter> d_bv_invert;
/**
const Node d_small_const_multiplier;
/** a small constant, used as a coefficient above */
Node d_small_const;
+ /** whether we have initialized the lower bound on the free delta */
+ context::CDO<bool> d_freeDeltaLb;
//---------------------- end for vts delta minimization
/** register ce lemma */
bool registerCbqiLemma( Node q );
namespace theory {
namespace quantifiers {
-VtsTermCache::VtsTermCache(Env& env, QuantifiersInferenceManager& qim)
- : EnvObj(env), d_qim(qim)
-{
-}
+VtsTermCache::VtsTermCache(Env& env) : EnvObj(env), d_hasAllocated(false) {}
+
+bool VtsTermCache::hasAllocated() const { return d_hasAllocated; }
void VtsTermCache::getVtsTerms(std::vector<Node>& t,
bool isFree,
SkolemManager* sm = nm->getSkolemManager();
if (d_vts_delta_free.isNull())
{
+ d_hasAllocated = true;
d_vts_delta_free =
sm->mkDummySkolem("delta_free",
nm->realType(),
"free delta for virtual term substitution");
- Node zero = nm->mkConstReal(Rational(0));
- Node delta_lem = nm->mkNode(GT, d_vts_delta_free, zero);
- d_qim.lemma(delta_lem, InferenceId::QUANTIFIERS_CEGQI_VTS_LB_DELTA);
}
if (d_vts_delta.isNull())
{
+ d_hasAllocated = true;
d_vts_delta = sm->mkDummySkolem(
"delta", nm->realType(), "delta for virtual term substitution");
// mark as a virtual term
SkolemManager* sm = nm->getSkolemManager();
if (d_vts_inf_free[tn].isNull())
{
+ d_hasAllocated = true;
d_vts_inf_free[tn] = sm->mkDummySkolem(
"inf_free", tn, "free infinity for virtual term substitution");
}
if (d_vts_inf[tn].isNull())
{
+ d_hasAllocated = true;
d_vts_inf[tn] = sm->mkDummySkolem(
"inf", tn, "infinity for virtual term substitution");
// mark as a virtual term
#include "context/cdhashset.h"
#include "smt/env_obj.h"
+#include "theory/quantifiers/cegqi/vts_term_cache.h"
#include "theory/quantifiers/entailment_check.h"
#include "theory/quantifiers/sygus/term_database_sygus.h"
#include "theory/quantifiers/term_database.h"
TermEnumeration* getTermEnumeration() const;
/** get the term pools utility */
TermPools* getTermPools() const;
+ /** get the virtual term substitution term cache utility */
+ VtsTermCache* getVtsTermCache() const;
/** get the model utility */
FirstOrderModel* getModel() const;
std::unique_ptr<TermDbSygus> d_sygusTdb;
/** oracle checker */
std::unique_ptr<OracleChecker> d_ochecker;
+ /** virtual term substitution term cache for arithmetic instantiation */
+ std::unique_ptr<VtsTermCache> d_vtsCache;
/** extended model object */
FirstOrderModel* d_qmodel;
};