#include "theory/quantifiers/macros.h"
#include "theory/quantifiers/fun_def_process.h"
#include "theory/quantifiers/quantifiers_rewriter.h"
+#include "theory/quantifiers/ce_guided_instantiation.h"
#include "theory/quantifiers/options.h"
#include "theory/datatypes/options.h"
#include "theory/strings/theory_strings_preprocess.h"
Debug("smt") << " d_assertions : " << d_assertions.size() << endl;
+ if( options::ceGuidedInst() ){
+ //register sygus conjecture pre-rewrite (motivated by solution reconstruction)
+ for (unsigned i = 0; i < d_assertions.size(); ++ i) {
+ d_smt.d_theoryEngine->getQuantifiersEngine()->getCegInstantiation()->preregisterAssertion( d_assertions[i] );
+ }
+ }
+
if (options::bitblastMode() == theory::bv::BITBLAST_MODE_EAGER &&
!d_smt.d_logic.isPure(THEORY_BV)) {
throw ModalException("Eager bit-blasting does not currently support theory combination. "
return d_active && !d_infeasible && ( !isSingleInvocation() || d_ceg_si->needsCheck() );
}
+void CegConjecture::preregisterConjecture( Node q ) {
+ d_ceg_si->preregisterConjecture( q );
+}
+
CegInstantiation::CegInstantiation( QuantifiersEngine * qe, context::Context* c ) : QuantifiersModule( qe ){
d_conj = new CegConjecture( qe, qe->getSatContext() );
d_last_inst_si = false;
}
}
+void CegInstantiation::preregisterAssertion( Node n ) {
+ //check if it sygus conjecture
+ if( n.getKind()==FORALL ){
+ if( n.getNumChildren()==3 ){
+ for( unsigned i=0; i<n[2].getNumChildren(); i++ ){
+ if( n[2][i].getKind()==INST_ATTRIBUTE ){
+ Node avar = n[2][i][0];
+ if( avar.getAttribute(SygusAttribute()) ){
+ //this is a sygus conjecture
+ Trace("cegqi") << "Preregister sygus conjecture : " << n << std::endl;
+ d_conj->preregisterConjecture( n );
+ }
+ }
+ }
+ }
+ }
+}
+
CegInstantiation::Statistics::Statistics():
d_cegqi_lemmas_ce("CegInstantiation::cegqi_lemmas_ce", 0),
d_cegqi_lemmas_refine("CegInstantiation::cegqi_lemmas_refine", 0),
bool isSingleInvocation();
/** needs check */
bool needsCheck();
+ /** preregister conjecture */
+ void preregisterConjecture( Node q );
};
void printSynthSolution( std::ostream& out );
/** collect disjuncts */
static void collectDisjuncts( Node n, std::vector< Node >& ex );
+ /** preregister assertion (before rewrite) */
+ void preregisterAssertion( Node n );
public:
class Statistics {
public:
//reconstruct the solution into sygus if necessary
reconstructed = 0;
if( options::cegqiSingleInvReconstruct() && !dt.getSygusAllowAll() && !stn.isNull() ){
+ d_sol->preregisterConjecture( d_orig_conjecture );
d_sygus_solution = d_sol->reconstructSolution( s, stn, reconstructed );
if( reconstructed==1 ){
Trace("csi-sol") << "Solution (post-reconstruction into Sygus): " << d_sygus_solution << std::endl;
return true;
}
+void CegConjectureSingleInv::preregisterConjecture( Node q ) {
+ d_orig_conjecture = q;
+}
}
\ No newline at end of file
//lemmas produced
inst::InstMatchTrie d_inst_match_trie;
inst::CDInstMatchTrie * d_c_inst_match_trie;
+ //original conjecture
+ Node d_orig_conjecture;
// solution
std::vector< Node > d_varList;
Node d_orig_solution;
bool isSingleInvocation() { return !d_single_inv.isNull(); }
//needs check
bool needsCheck();
+ /** preregister conjecture */
+ void preregisterConjecture( Node q );
};
}
}
-
-
-
+void CegConjectureSingleInvSol::preregisterConjecture( Node q ) {
+ Trace("csi-sol") << "Preregister conjecture : " << q << std::endl;
+ Node n = q;
+ if( n.getKind()==FORALL ){
+ n = n[1];
+ }
+ if( n.getKind()==EXISTS ){
+ if( n[0].getNumChildren()==d_varList.size() ){
+ std::vector< Node > evars;
+ for( unsigned i=0; i<n[0].getNumChildren(); i++ ){
+ evars.push_back( n[0][i] );
+ }
+ n = n[1].substitute( evars.begin(), evars.end(), d_varList.begin(), d_varList.end() );
+ }else{
+ Trace("csi-sol") << "Not the same number of variables, return." << std::endl;
+ return;
+ }
+ }
+ Trace("csi-sol") << "Preregister node for solution reconstruction : " << n << std::endl;
+ registerEquivalentTerms( n );
+}
Node CegConjectureSingleInvSol::reconstructSolution( Node sol, TypeNode stn, int& reconstructed ) {
Trace("csi-rcons") << "Solution (pre-reconstruction) is : " << sol << std::endl;
nn = Rewriter::rewrite( nn );
equiv.push_back( NodeManager::currentNM()->mkNode( MINUS, NodeManager::currentNM()->mkConst( Rational(0) ), nn ) );
}
- }
-}
+ }
+ //based on eqt cache
+ std::map< Node, Node >::iterator itet = d_eqt_rep.find( n );
+ if( itet!=d_eqt_rep.end() ){
+ Node rn = itet->second;
+ for( unsigned i=0; i<d_eqt_eqc[rn].size(); i++ ){
+ if( d_eqt_eqc[rn][i]!=n ){
+ if( std::find( equiv.begin(), equiv.end(), d_eqt_eqc[rn][i] )==equiv.end() ){
+ equiv.push_back( d_eqt_eqc[rn][i] );
+ }
+ }
+ }
+ }
+}
+
+void CegConjectureSingleInvSol::registerEquivalentTerms( Node n ) {
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ registerEquivalentTerms( n[i] );
+ }
+ Node rn = Rewriter::rewrite( n );
+ if( rn!=n ){
+ Trace("csi-equiv") << " eq terms : " << n << " " << rn << std::endl;
+ d_eqt_rep[n] = rn;
+ d_eqt_rep[rn] = rn;
+ if( std::find( d_eqt_eqc[rn].begin(), d_eqt_eqc[rn].end(), rn )==d_eqt_eqc[rn].end() ){
+ d_eqt_eqc[rn].push_back( rn );
+ }
+ if( std::find( d_eqt_eqc[rn].begin(), d_eqt_eqc[rn].end(), n )==d_eqt_eqc[rn].end() ){
+ d_eqt_eqc[rn].push_back( n );
+ }
+ }
+}
+
}
std::map< int, std::vector< int > > d_eqc;
std::map< int, int > d_rep;
+
+ //equivalent terms
+ std::map< Node, Node > d_eqt_rep;
+ std::map< Node, std::vector< Node > > d_eqt_eqc;
//cache when reconstructing solutions
std::vector< int > d_tmp_fail;
void setReconstructed( int id, Node n );
//get equivalent terms to n with top symbol k
void getEquivalentTerms( Kind k, Node n, std::vector< Node >& equiv );
+ //register equivalent terms
+ void registerEquivalentTerms( Node n );
public:
Node reconstructSolution( Node sol, TypeNode stn, int& reconstructed );
+ void preregisterConjecture( Node q );
public:
CegConjectureSingleInvSol( QuantifiersEngine * qe );
};
option sygusNormalFormGlobalContent --sygus-nf-sym-content bool :default true
generalize based on content in global search space narrowing
-option sygusInvTemplMode --sygus-inv-templ=MODE CVC4::theory::quantifiers::SygusInvTemplMode :default CVC4::theory::quantifiers::SYGUS_INV_TEMPL_MODE_NONE :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToSygusInvTemplMode :handler-include "theory/quantifiers/options_handlers.h"
+option sygusInvTemplMode --sygus-inv-templ=MODE CVC4::theory::quantifiers::SygusInvTemplMode :default CVC4::theory::quantifiers::SYGUS_INV_TEMPL_MODE_POST :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToSygusInvTemplMode :handler-include "theory/quantifiers/options_handlers.h"
template mode for sygus invariant synthesis
# approach applied to general quantified formulas