From 3df24b6e0480799e8f400d15778ed5d3fb2ba7ae Mon Sep 17 00:00:00 2001 From: ajreynol Date: Tue, 3 Feb 2015 11:39:03 +0100 Subject: [PATCH] Simple variable elimination for single inv properties. Relax conditions for partial inst variables for LTE. --- .../quantifiers/ce_guided_instantiation.cpp | 28 ++-- .../quantifiers/ce_guided_single_inv.cpp | 129 +++++++++++++++--- src/theory/quantifiers/ce_guided_single_inv.h | 6 + src/theory/quantifiers/local_theory_ext.cpp | 8 +- 4 files changed, 139 insertions(+), 32 deletions(-) diff --git a/src/theory/quantifiers/ce_guided_instantiation.cpp b/src/theory/quantifiers/ce_guided_instantiation.cpp index addcd5337..2015501d9 100644 --- a/src/theory/quantifiers/ce_guided_instantiation.cpp +++ b/src/theory/quantifiers/ce_guided_instantiation.cpp @@ -483,25 +483,35 @@ void CegInstantiation::printSynthSolution( std::ostream& out ) { ss << d_conj->d_quant[0][i]; std::string f(ss.str()); f.erase(f.begin()); - out << "(define-fun f "; TypeNode tn = d_conj->d_quant[0][i].getType(); Assert( datatypes::DatatypesRewriter::isTypeDatatype( tn ) ); const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype(); Assert( dt.isSygus() ); - out << dt.getSygusVarList() << " "; - out << dt.getSygusType() << " "; + //get the solution + Node sol; if( d_last_inst_si ){ Assert( d_conj->d_ceg_si ); - Node sol = d_conj->d_ceg_si->getSolution( i, Node::fromExpr( dt.getSygusVarList() ) ); - out << sol; + sol = d_conj->d_ceg_si->getSolution( i, Node::fromExpr( dt.getSygusVarList() ) ); }else{ - if( d_conj->d_candidate_inst[i].empty() ){ - out << "?"; + if( !d_conj->d_candidate_inst[i].empty() ){ + sol = d_conj->d_candidate_inst[i].back(); + } + } + if( !Trace.isOn("cegqi-stats") ){ + out << "(define-fun " << f << " "; + out << dt.getSygusVarList() << " "; + out << dt.getSygusType() << " "; + if( d_last_inst_si ){ + out << sol; }else{ - printSygusTerm( out, d_conj->d_candidate_inst[i].back() ); + if( sol.isNull() ){ + out << "?"; + }else{ + printSygusTerm( out, sol ); + } } + out << ")" << std::endl; } - out << ")" << std::endl; } } } diff --git a/src/theory/quantifiers/ce_guided_single_inv.cpp b/src/theory/quantifiers/ce_guided_single_inv.cpp index c3ca5cfe6..0b160e631 100644 --- a/src/theory/quantifiers/ce_guided_single_inv.cpp +++ b/src/theory/quantifiers/ce_guided_single_inv.cpp @@ -162,7 +162,7 @@ void CegConjectureSingleInv::initialize() { for( std::map< Node, std::vector< Node > >::iterator it = children.begin(); it != children.end(); ++it ){ //should hold since we prevent miniscoping Assert( d_single_inv.isNull() ); - std::vector< Node > tmp; + std::vector< Node > conjuncts; for( unsigned i=0; isecond.size(); i++ ){ Node c = it->second[i]; std::vector< Node > disj; @@ -197,16 +197,15 @@ void CegConjectureSingleInv::initialize() { } Node curr = disj.size()==1 ? disj[0] : NodeManager::currentNM()->mkNode( OR, disj ); Trace("cegqi-si") << " " << curr; - tmp.push_back( curr.negate() ); + conjuncts.push_back( curr.negate() ); if( !it->first.isNull() ){ Trace("cegqi-si-debug") << " under " << it->first; } Trace("cegqi-si") << std::endl; } - Assert( !tmp.empty() ); - Node bd = tmp.size()==1 ? tmp[0] : NodeManager::currentNM()->mkNode( OR, tmp ); + Assert( !conjuncts.empty() ); + //make the skolems for the existential if( !it->first.isNull() ){ - // apply substitution for skolem variables std::vector< Node > vars; std::vector< Node > sks; for( unsigned j=0; jfirst.getNumChildren(); j++ ){ @@ -216,15 +215,18 @@ void CegConjectureSingleInv::initialize() { vars.push_back( it->first[j] ); sks.push_back( v ); } - bd = bd.substitute( vars.begin(), vars.end(), sks.begin(), sks.end() ); + //substitute conjunctions + for( unsigned i=0; i::iterator itam = d_single_inv_app_map.begin(); itam != d_single_inv_app_map.end(); ++itam ){ Node n = itam->second; d_single_inv_app_map[itam->first] = n.substitute( vars.begin(), vars.end(), sks.begin(), sks.end() ); } - - Trace("cegqi-si-debug") << " -> " << bd << std::endl; } + //ensure that this is a ground property for( std::map< Node, Node >::iterator itam = d_single_inv_app_map.begin(); itam != d_single_inv_app_map.end(); ++itam ){ Node n = itam->second; //check if all variables are arguments of this @@ -232,22 +234,31 @@ void CegConjectureSingleInv::initialize() { for( unsigned i=1; imkNode( OR, conjuncts ); d_single_inv = NodeManager::currentNM()->mkNode( FORALL, pbvl, bd ); Trace("cegqi-si-debug") << "...formula is : " << d_single_inv << std::endl; /* //equality resolution - for( unsigned j=0; j > case_vals; bool exh = processSingleInvLiteral( conj, false, case_vals ); Trace("cegqi-si-er") << "Conjunct " << conj << " gives equality restrictions, exh = " << exh << " : " << std::endl; @@ -272,6 +283,63 @@ void CegConjectureSingleInv::initialize() { } } +bool CegConjectureSingleInv::doVariableElimination( Node v, std::vector< Node >& conjuncts ) { + //all conjuncts containing v must contain a literal v != s for some s + // if so, do DER on all such conjuncts + TNode s; + for( unsigned i=0; i >& case_vals ) { if( lit.getKind()==NOT ){ return processSingleInvLiteral( lit[0], !pol, case_vals ); @@ -525,7 +593,9 @@ Node CegConjectureSingleInv::applyProgVarSubstitution( Node n, std::map< Node, i subs_from_model.erase( vars[i] ); } } - return n.substitute( vars.begin(), vars.end(), ssubs.begin(), ssubs.end() ); + n = n.substitute( vars.begin(), vars.end(), ssubs.begin(), ssubs.end() ); + n = Rewriter::rewrite( n ); + return n; }else{ return n; } @@ -604,17 +674,28 @@ Node CegConjectureSingleInv::getSolution( unsigned i, Node varList ){ vars.push_back( prog_app[i] ); subs.push_back( varList[i-1] ); } - s = s.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() ); + d_orig_solution = s.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() ); + d_solution = Rewriter::rewrite( d_orig_solution ); if( Trace.isOn("cegqi-si-warn") ){ //debug solution - if( !debugSolution( s ) ){ - Trace("cegqi-si-warn") << "WARNING : solution " << s << " contains free constants." << std::endl; + if( !debugSolution( d_solution ) ){ + Trace("cegqi-si-warn") << "WARNING : solution " << d_solution << " contains free constants." << std::endl; //exit( 47 ); }else{ //exit( 49 ); } } - return s; + if( Trace.isOn("cegqi-stats") ){ + int t_size = 0; + int num_ite = 0; + debugTermSize( d_orig_solution, t_size, num_ite ); + Trace("cegqi-stats") << "size " << t_size << " #ite " << num_ite << std::endl; + t_size = 0; + num_ite = 0; + debugTermSize( d_solution, t_size, num_ite ); + Trace("cegqi-stats") << "simplified size " << t_size << " #ite " << num_ite << std::endl; + } + return d_solution; } bool CegConjectureSingleInv::debugSolution( Node sol ) { @@ -631,4 +712,14 @@ bool CegConjectureSingleInv::debugSolution( Node sol ) { } +void CegConjectureSingleInv::debugTermSize( Node sol, int& t_size, int& num_ite ) { + t_size++; + if( sol.getKind()==ITE ){ + num_ite++; + } + for( unsigned i=0; i& progs, std::map< Node, std::map< Node, bool > >& contains, bool pol ); bool analyzeSygusTerm( Node n, std::map< Node, std::vector< Node > >& prog_invoke, std::map< Node, bool >& contains ); bool processSingleInvLiteral( Node lit, bool pol, std::map< Node, std::vector< Node > >& case_vals ); + bool doVariableElimination( Node v, std::vector< Node >& conjuncts ); + bool getVariableEliminationTerm( bool pol, bool active, Node v, Node n, TNode& s, int& status ); Node constructSolution( unsigned i, unsigned index ); int classifyTerm( Node n, std::map< Node, int >& subs_from_model ); @@ -43,6 +45,7 @@ private: Node applyProgVarSubstitution( Node n, std::map< Node, int >& subs_from_model, std::vector< Node >& subs ); bool debugSolution( Node sol ); + void debugTermSize( Node sol, int& t_size, int& num_ite ); public: CegConjectureSingleInv( Node q, CegConjecture * p ); // original conjecture @@ -64,6 +67,9 @@ public: //lemmas produced std::vector< Node > d_lemmas_produced; std::vector< std::vector< Node > > d_inst; + // solution + Node d_orig_solution; + Node d_solution; public: //get the single invocation lemma Node getSingleInvLemma( Node guard ); diff --git a/src/theory/quantifiers/local_theory_ext.cpp b/src/theory/quantifiers/local_theory_ext.cpp index d62fa02c2..794032c87 100644 --- a/src/theory/quantifiers/local_theory_ext.cpp +++ b/src/theory/quantifiers/local_theory_ext.cpp @@ -45,11 +45,11 @@ bool LtePartialInst::addQuantifier( Node q ) { //check if this quantified formula is eligible for partial instantiation std::map< Node, bool > vars; for( unsigned i=0; i var_order; bool doInst = true; for( unsigned i=0; i& pat_v } void LtePartialInst::getEligibleInstVars( Node n, std::map< Node, bool >& vars ) { - if( n.getKind()!=APPLY_UF || n.getType().isBoolean() ){ + if( n.getKind()==APPLY_UF && !n.getType().isBoolean() ){ for( unsigned i=0; i