From 9c00db91190ce2956efee1c721e6a1f8707a57b1 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Tue, 4 Feb 2014 09:00:28 -0600 Subject: [PATCH] Add variable ordering for QCF to accelerate matching procedure. Preparing for QCF_MC mode. --- src/theory/quantifiers/modes.h | 2 + src/theory/quantifiers/options_handlers.h | 9 +- .../quantifiers/quant_conflict_find.cpp | 110 +++++++++++++++++- src/theory/quantifiers/quant_conflict_find.h | 20 ++-- 4 files changed, 124 insertions(+), 17 deletions(-) diff --git a/src/theory/quantifiers/modes.h b/src/theory/quantifiers/modes.h index c36a565ea..75b9eba3e 100644 --- a/src/theory/quantifiers/modes.h +++ b/src/theory/quantifiers/modes.h @@ -86,6 +86,8 @@ typedef enum { QCF_CONFLICT_ONLY, /** use qcf for conflicts and propagations */ QCF_PROP_EQ, + /** use qcf for model checking */ + QCF_MC, } QcfMode; typedef enum { diff --git a/src/theory/quantifiers/options_handlers.h b/src/theory/quantifiers/options_handlers.h index 37362982c..15d52cc96 100644 --- a/src/theory/quantifiers/options_handlers.h +++ b/src/theory/quantifiers/options_handlers.h @@ -122,7 +122,10 @@ conflict \n\ + Default, apply conflict finding for finding conflicts only.\n\ \n\ prop-eq \n\ -+ Apply conflict finding to propagate equalities as well. \n\ ++ Apply QCF to propagate equalities as well. \n\ +\n\ +mc \n\ ++ Apply QCF in a complete way, so that a model is ensured when it fails. \n\ \n\ "; static const std::string userPatModeHelp = "\ @@ -247,8 +250,10 @@ inline QcfWhenMode stringToQcfWhenMode(std::string option, std::string optarg, S inline QcfMode stringToQcfMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { if(optarg == "default" || optarg == "conflict") { return QCF_CONFLICT_ONLY; - } else if(optarg == "prop-eq") { + } else if(optarg == "prop-eq") { return QCF_PROP_EQ; + } else if(optarg == "mc" ) { + return QCF_MC; } else if(optarg == "help") { puts(qcfModeHelp.c_str()); exit(1); diff --git a/src/theory/quantifiers/quant_conflict_find.cpp b/src/theory/quantifiers/quant_conflict_find.cpp index 91c9b6653..95744a651 100755 --- a/src/theory/quantifiers/quant_conflict_find.cpp +++ b/src/theory/quantifiers/quant_conflict_find.cpp @@ -86,18 +86,24 @@ void QuantInfo::initialize( Node q, Node qn ) { Trace("qcf-qregister") << "- Make match gen structure..." << std::endl; - d_mg = new MatchGen( this, qn, true ); + d_mg = new MatchGen( this, qn ); if( d_mg->isValid() ){ for( unsigned j=q[0].getNumChildren(); jisValid() ){ d_mg->setInvalid(); break; } } } + + if( d_mg->isValid() ){ + std::vector< int > bvars; + d_mg->determineVariableOrder( this, bvars ); + } + //must also contain all variables? /* if( d_mg->isValid() ){ @@ -562,8 +568,8 @@ struct MatchGenSort { }; */ -MatchGen::MatchGen( QuantInfo * qi, Node n, bool isTop, bool isVar ){ - Trace("qcf-qregister-debug") << "Make match gen for " << n << ", top/var = " << isTop << " " << isVar << std::endl; +MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){ + Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl; std::vector< Node > qni_apps; d_qni_size = 0; if( isVar ){ @@ -674,6 +680,93 @@ MatchGen::MatchGen( QuantInfo * qi, Node n, bool isTop, bool isVar ){ //Assert( d_children.size()==d_children_order.size() ); } +void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) { + int v = qi->getVarNum( n ); + if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){ + cbvars.push_back( v ); + } + for( unsigned i=0; i& bvars ) { + Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl; + bool isCom = d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF; + std::map< int, std::vector< int > > c_to_vars; + std::map< int, std::vector< int > > vars_to_c; + std::map< int, int > vb_count; + std::map< int, int > vu_count; + std::vector< bool > assigned; + Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl; + for( unsigned i=0; id_mg->isValid() ){ + Trace("qcf-check-debug") << "Reset round..." << std::endl; qi->reset_round( this ); //try to make a matches making the body false + Trace("qcf-check-debug") << "Reset..." << std::endl; qi->d_mg->reset( this, false, qi ); + Trace("qcf-check-debug") << "Get next match..." << std::endl; while( qi->d_mg->getNextMatch( this, qi ) ){ Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl; diff --git a/src/theory/quantifiers/quant_conflict_find.h b/src/theory/quantifiers/quant_conflict_find.h index 010a8e194..2663ff0b9 100755 --- a/src/theory/quantifiers/quant_conflict_find.h +++ b/src/theory/quantifiers/quant_conflict_find.h @@ -42,14 +42,15 @@ class QuantInfo; //match generator class MatchGen { + friend class QuantInfo; private: //current children information int d_child_counter; //children of this object - //std::vector< int > d_children_order; + std::vector< int > d_children_order; unsigned getNumChildren() { return d_children.size(); } - //MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; } - MatchGen * getChild( int i ) { return &d_children[i]; } + MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; } + //MatchGen * getChild( int i ) { return &d_children[i]; } //current matching information std::vector< QcfNodeIndex * > d_qn; std::vector< std::map< TNode, QcfNodeIndex >::iterator > d_qni; @@ -63,9 +64,13 @@ private: std::map< int, TNode > d_qni_bound_cons; std::map< int, int > d_qni_bound_cons_var; std::map< int, int >::iterator d_binding_it; + //std::vector< int > d_independent; bool d_binding; //int getVarBindingVar(); std::map< int, Node > d_ground_eval; + //determine variable order + void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ); + void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ); public: //type of the match generator enum { @@ -80,7 +85,7 @@ public: void debugPrintType( const char * c, short typ, bool isTrace = false ); public: MatchGen() : d_type( typ_invalid ){} - MatchGen( QuantInfo * qi, Node n, bool isTop = false, bool isVar = false ); + MatchGen( QuantInfo * qi, Node n, bool isVar = false ); bool d_tgt; Node d_n; std::vector< MatchGen > d_children; @@ -108,7 +113,6 @@ public: QuantInfo() : d_mg( NULL ) {} std::vector< TNode > d_vars; std::map< TNode, int > d_var_num; - //std::map< EqRegistry *, bool > d_rel_eqr; std::map< int, std::vector< Node > > d_var_constraint[2]; int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; } bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); } @@ -199,7 +203,7 @@ public: enum { effort_conflict, effort_prop_eq, - effort_prop_deq, + effort_mc, }; short d_effort; //for effort_prop @@ -210,12 +214,8 @@ public: bool areMatchDisequal( TNode n1, TNode n2 ); public: QuantConflictFind( QuantifiersEngine * qe, context::Context* c ); - - /** register assertions */ - //void registerAssertions( std::vector< Node >& assertions ); /** register quantifier */ void registerQuantifier( Node q ); - public: /** assert quantifier */ void assertNode( Node q ); -- 2.30.2