theory_quant.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theory_quant.h
00004  * 
00005  * Author: Sergey Berezin, Yeting Ge
00006  * 
00007  * Created: Jun 24 21:13:59 GMT 2003
00008  *
00009  * <hr>
00010  *
00011  * License to use, copy, modify, sell and/or distribute this software
00012  * and its documentation for any purpose is hereby granted without
00013  * royalty, subject to the terms and conditions defined in the \ref
00014  * LICENSE file provided with this distribution.
00015  * 
00016  * <hr>
00017  * 
00018  * ! Author: Daniel Wichs
00019  * ! Created: Wednesday July 2, 2003
00020  *
00021  * 
00022  */
00023 /*****************************************************************************/
00024 #ifndef _cvc3__include__theory_quant_h_
00025 #define _cvc3__include__theory_quant_h_
00026 
00027 #include "theory.h"
00028 #include "cdmap.h"
00029 #include "statistics.h"
00030 #include<queue>
00031 
00032 namespace CVC3 {
00033 
00034 class QuantProofRules;
00035 
00036 /*****************************************************************************/
00037 /*!
00038  *\class TheoryQuant
00039  *\ingroup Theories
00040  *\brief This theory handles quantifiers.
00041  *
00042  * Author: Daniel Wichs
00043  *
00044  * Created: Wednesday July 2,  2003
00045  */
00046 /*****************************************************************************/
00047 
00048  typedef enum{ Ukn, Pos, Neg, PosNeg} Polarity;
00049 
00050  class Trigger {
00051  public: 
00052    Expr trig;
00053    Polarity polarity;
00054    
00055    std::vector<Expr> bvs;
00056    Expr head;
00057    bool hasRWOp;
00058    bool hasTrans;
00059    bool hasT2; //if has trans of 2,
00060    bool isSimple; //if of the form g(x,a);
00061    bool isSuperSimple; //if of the form g(x,y);
00062    bool isMulti;
00063    size_t multiIndex; 
00064    size_t multiId;
00065 
00066    Trigger(TheoryCore* core, Expr e, Polarity pol, std::set<Expr>);
00067    bool  isPos();
00068    bool  isNeg();
00069    Expr  getEx();
00070    std::vector<Expr> getBVs(); 
00071    void  setHead(Expr h);
00072    Expr  getHead();
00073    void  setRWOp(bool b);
00074    bool  hasRW(); 
00075    void  setTrans(bool b);
00076    bool  hasTr(); 
00077    void  setTrans2(bool b);
00078    bool  hasTr2(); 
00079    void  setSimp();
00080    bool  isSimp(); 
00081    void  setSuperSimp();
00082    bool  isSuperSimp(); 
00083    void  setMultiTrig();
00084    bool  isMultiTrig(); 
00085 
00086    
00087  };
00088 
00089  typedef struct dynTrig{
00090    Trigger trig;
00091    size_t univ_id;
00092    ExprMap<Expr> binds;
00093    dynTrig(Trigger t, ExprMap<Expr> b, size_t id);
00094  } dynTrig;
00095  
00096  
00097 class TheoryQuant :public Theory {
00098   
00099   class  TypeComp { //!< needed for typeMap
00100   public:
00101     bool operator() (const Type t1, const Type t2) const
00102       {return (t1.getExpr() < t2.getExpr()); }
00103   };
00104 
00105   //! used to facilitate instantiation of universal quantifiers
00106   typedef std::map<Type, std::vector<size_t>, TypeComp > typeMap; 
00107 
00108   //! database of universally quantified theorems
00109   CDList<Theorem> d_univs; 
00110 
00111   CDList<Theorem> d_rawUnivs; 
00112 
00113   CDList<dynTrig> d_arrayTrigs; 
00114   CDO<size_t> d_lastArrayPos;
00115 
00116   //! universally quantified formulas to be instantiated, the var bindings is in d_bingQueue and the ground term matched with the trigger is in d_gtermQueue 
00117   std::queue<Theorem> d_univsQueue;
00118 
00119   std::queue<Theorem> d_simplifiedThmQueue;
00120 
00121   ExprMap<std::set<std::vector<Expr> > >  d_tempBinds;
00122 
00123   //!tracks the possition of preds 
00124   CDO<size_t> d_lastPredsPos;
00125   //!tracks the possition of terms 
00126   CDO<size_t> d_lastTermsPos;
00127 
00128   //!tracks the positions of preds for partial instantiation
00129   CDO<size_t> d_lastPartPredsPos;
00130   //!tracks the possition of terms for partial instantiation
00131   CDO<size_t> d_lastPartTermsPos;
00132   //!tracks a possition in the database of universals for partial instantiation
00133   CDO<size_t> d_univsPartSavedPos;
00134   
00135   //! the last decision level on which partial instantion is called
00136   CDO<size_t> d_lastPartLevel;
00137   
00138   //!useful gterms for matching
00139   CDList<Expr> d_usefulGterms; 
00140 
00141   //!tracks the position in d_usefulGterms
00142   CDO<size_t> d_lastUsefulGtermsPos;
00143   
00144   //!tracks a possition in the savedTerms map
00145   CDO<size_t> d_savedTermsPos;
00146   //!tracks a possition in the database of universals
00147   CDO<size_t> d_univsSavedPos;
00148   CDO<size_t> d_rawUnivsSavedPos;
00149   //!tracks a possition in the database of universals
00150   CDO<size_t> d_univsPosFull;
00151   //!tracks a possition in the database of universals if fulleffort mode, the d_univsSavedPos now uesed when fulleffort=0 only.
00152 
00153   CDO<size_t> d_univsContextPos;
00154   
00155   
00156   CDO<int> d_instCount; //!< number of instantiations made in given context
00157 
00158   //! set if the fullEffort = 1
00159   int d_inEnd; 
00160 
00161   int d_allout; 
00162 
00163   //! a map of types to posisitions in the d_contextTerms list
00164   std::map<Type, CDList<size_t>* ,TypeComp> d_contextMap;
00165   //! a list of all the terms appearing in the current context
00166   CDList<Expr> d_contextTerms;
00167   //!< chache of expressions
00168   CDMap<Expr, bool> d_contextCache;
00169   
00170   //! a map of types to positions in the d_savedTerms vector
00171   typeMap d_savedMap;
00172   ExprMap<bool> d_savedCache; //!< cache of expressions
00173   //! a vector of all of the terms that have produced conflicts.
00174   std::vector<Expr> d_savedTerms; 
00175 
00176   //! a map of instantiated universals to a vector of their instantiations
00177   ExprMap<std::vector<Expr> >  d_insts;
00178 
00179   //! quantifier theorem production rules
00180   QuantProofRules* d_rules;
00181   
00182   const int* d_maxQuantInst; //!< Command line option
00183 
00184 
00185   /*! \brief categorizes all the terms contained in an expressions by
00186    *type.
00187    *
00188    * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
00189    * returns true if the expression does not contain bound variables, false
00190    * otherwise.
00191    */
00192   bool recursiveMap(const Expr& term);
00193 
00194   /*! \brief categorizes all the terms contained in a vector of  expressions by
00195    * type.
00196    *
00197    * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
00198    */
00199   void mapTermsByType(const CDList<Expr>& terms);
00200   
00201   /*! \brief Queues up all possible instantiations of bound
00202    * variables.
00203    *
00204    * The savedMap boolean indicates whether to use savedMap or
00205    * d_contextMap the all boolean indicates weather to use all
00206    * instantiation or only new ones and newIndex is the index where
00207    * new instantiations begin.
00208    */
00209   void instantiate(Theorem univ, bool all, bool savedMap, 
00210        size_t newIndex);
00211   //! does most of the work of the instantiate function.
00212   void recInstantiate(Theorem& univ , bool all, bool savedMap,size_t newIndex, 
00213            std::vector<Expr>& varReplacements);
00214 
00215   /*! \brief A recursive function used to find instantiated universals
00216    * in the hierarchy of assumptions.
00217    */
00218   void findInstAssumptions(const Theorem& thm);
00219 
00220   //  CDO<bool> usedup;
00221   const bool* d_useNew;//!use new way of instantiation
00222   const bool* d_useLazyInst;//!use lazy instantiation
00223   const bool* d_useSemMatch;//!use semantic matching
00224   const bool* d_useAtomSem;
00225   const bool* d_translate;//!translate only
00226 
00227   const bool* d_useTrigNew;//!use new trig class, to be deleted
00228   const bool* d_usePart;//!use partial instantiaion
00229   const bool* d_useMult;//use 
00230   const bool* d_useInstEnd;
00231   const bool* d_useInstLCache;
00232   const bool* d_useInstGCache;
00233   const bool* d_useInstTrue;
00234   const bool* d_usePullVar;
00235   const bool* d_useExprScore;
00236   const int* d_useTrigLoop;
00237   const int* d_maxInst;
00238   //  const int* d_maxUserScore;
00239   const bool* d_useTrans;
00240   const bool* d_useTrans2;
00241   const bool* d_useInstAll;
00242   const bool* d_usePolarity;
00243   const bool* d_useEqu;
00244   const int* d_maxNaiveCall;
00245 
00246   CDO<int> d_curMaxExprScore;
00247 
00248   bool d_useFullTrig;
00249   bool d_usePartTrig;
00250   bool d_useMultTrig;
00251 
00252   //ExprMap<std::vector<Expr> > d_arrayIndic; //map array name to a list of indics
00253   CDMap<Expr, std::vector<Expr> > d_arrayIndic; //map array name to a list of indics
00254   void arrayIndexName(const Expr& e);
00255 
00256   std::vector<Expr> d_allInsts; //! all instantiations
00257 
00258   int d_initMaxScore;
00259   int d_offset_multi_trig ;
00260   
00261   int d_instThisRound;
00262   int d_callThisRound;
00263 
00264   int partial_called;
00265 
00266   //  ExprMap<std::vector<Expr> > d_fullTriggers;
00267   //for multi-triggers, now we only have one set of multi-triggers.
00268 
00269 
00270   ExprMap<std::vector<Expr> > d_multTriggers;
00271   ExprMap<std::vector<Expr> > d_partTriggers;
00272 
00273   ExprMap<std::vector<Trigger> > d_fullTrigs;
00274   //for multi-triggers, now we only have one set of multi-triggers.
00275   ExprMap<std::vector<Trigger> > d_multTrigs;
00276   ExprMap<std::vector<Trigger> > d_partTrigs;
00277 
00278  
00279   CDO<size_t> d_exprLastUpdatedPos ;//the position of the last expr updated in d_exprUpdate 
00280 
00281   std::map<ExprIndex, int> d_indexScore;
00282 
00283   std::map<ExprIndex, Expr> d_indexExpr;
00284 
00285   int getExprScore(const Expr& e);
00286 
00287   //!the score for a full trigger
00288   
00289   ExprMap<bool> d_hasTriggers;
00290   ExprMap<bool> d_hasMoreBVs;
00291 
00292   int d_trans_num;
00293   int d_trans2_num;
00294 
00295   typedef struct{
00296     std::vector<std::vector<size_t> > common_pos;
00297     std::vector<std::vector<size_t> > var_pos; 
00298     
00299     std::vector<CDMap<Expr, bool>* > var_binds_found;
00300 
00301     std::vector<ExprMap<CDList<Expr>* >* > uncomm_list; //
00302   } multTrigsInfo ;
00303   
00304   ExprMap<multTrigsInfo> d_multitrigs_maps;
00305   std::vector<multTrigsInfo> d_all_multTrigsInfo;
00306   
00307   ExprMap<CDList<Expr>* > d_trans_back;
00308   ExprMap<CDList<Expr>* > d_trans_forw;
00309   CDMap<Expr,bool > d_trans_found;
00310   CDMap<Expr,bool > d_trans2_found;
00311 
00312 
00313   inline  bool transFound(const Expr& comb);
00314   
00315   inline   void setTransFound(const Expr& comb);
00316 
00317   inline  bool trans2Found(const Expr& comb);
00318 
00319   inline  void setTrans2Found(const Expr& comb);
00320 
00321  
00322   inline  CDList<Expr> & backList(const Expr& ex);
00323   
00324   inline  CDList<Expr> & forwList(const Expr& ex);
00325 
00326   CDList<Expr> null_cdlist;
00327 
00328 
00329   inline  void  pushBackList(const Expr& node, Expr ex);
00330   inline  void  pushForwList(const Expr& node, Expr ex);
00331   
00332   
00333   ExprMap<CDList<std::vector<Expr> >* > d_mtrigs_inst; //map expr to bindings
00334   
00335   ExprMap<CDList<Expr>* > d_same_head_expr; //map an expr to a list of expres shard the same head
00336   ExprMap<CDList<Expr>* > d_eq_list; //the equalities list
00337   
00338   CDList<Expr > d_eqs; //the equalities list
00339   CDO<size_t > d_eqs_pos; //the equalities list
00340 
00341   ExprMap<CDO<size_t>* > d_eq_pos;
00342 
00343   ExprMap<CDList<Expr>* > d_parent_list; 
00344   void  collectChangedTerms(CDList<Expr>& changed_terms);
00345   ExprMap<std::vector<Expr> > d_mtrigs_bvorder;
00346 
00347   int loc_gterm(const std::vector<Expr>& border,
00348     const Expr& gterm, 
00349     int pos);
00350 
00351   void  recSearchCover(const std::vector<Expr>& border,
00352            const std::vector<Expr>& mtrigs, 
00353            int cur_depth, 
00354            std::vector<std::vector<Expr> >& instSet,
00355            std::vector<Expr>& cur_inst
00356            );
00357 
00358   void  searchCover(const Expr& thm, 
00359         const std::vector<Expr>& border,
00360         std::vector<std::vector<Expr> >& instSet
00361         );
00362 
00363 
00364   std::map<Type, std::vector<Expr>,TypeComp > d_typeExprMap;
00365   std::set<std::string> cacheHead;
00366 
00367   StatCounter d_allInstCount ;
00368 
00369   CDO<bool> d_partCalled;;
00370 
00371   std::vector<Theorem> d_cacheTheorem;
00372   size_t d_cacheThmPos;
00373 
00374   void addNotify(const Expr& e);
00375 
00376   int sendInstNew();
00377 
00378   CDMap<Expr, std::set<std::vector<Expr> > > d_instHistory;//the history of instantiations
00379   //map univ to the trig, gterm and result
00380   
00381   ExprMap<CDMap<Expr, bool>* > d_bindHistory; //the history of instantiations
00382 
00383   ExprMap<std::set<std::vector<Expr> > > d_instHistoryGlobal;//the history of instantiations
00384 
00385   
00386   ExprMap<std::vector<Expr> > d_subTermsMap;
00387   //std::map<Expr, std::vector<Expr> > d_subTermsMap;
00388   const std::vector<Expr>& getSubTerms(const Expr& e);
00389 
00390   //ExprMap<int > d_thmTimes; 
00391   void enqueueInst(const Theorem, const Theorem); 
00392   void enqueueInst(const Theorem& univ, const std::vector<Expr>& bind, const Expr& gterm);
00393   void enqueueInst(size_t univ_id , const std::vector<Expr>& bind, const Expr& gterm);
00394   void enqueueInst(const Theorem& univ, 
00395        Trigger& trig,
00396        const std::vector<Expr>& binds,  
00397        const Expr& gterm
00398        );
00399     
00400   void synCheckSat(ExprMap<ExprMap<std::vector<dynTrig>* >* >& , bool);
00401   void synCheckSat(bool);
00402   void semCheckSat(bool);
00403   void naiveCheckSat(bool);
00404 
00405   bool insted(const Theorem & univ, const std::vector<Expr>& binds);
00406   void synInst(const Theorem & univ,  const CDList<Expr>& allterms, size_t tBegin);
00407 
00408   void synFullInst(const Theorem & univ,  const CDList<Expr>& allterms, size_t tBegin);
00409 
00410   void arrayHeuristic(const Trigger& trig, size_t univid);
00411   
00412 
00413   void synNewInst(size_t univ_id, const std::vector<Expr>& binds, const Expr& gterm, const Trigger& trig );
00414   void synMultInst(const Theorem & univ,  const CDList<Expr>& allterms,  size_t tBegin);
00415 
00416   void synPartInst(const Theorem & univ,  const CDList<Expr>& allterms,  size_t tBegin);
00417 
00418   void semInst(const Theorem & univ, size_t tBegin);
00419 
00420 
00421   void goodSynMatch(const Expr& e,
00422         const std::vector<Expr> & boundVars,
00423         std::vector<std::vector<Expr> >& instBindsTerm,
00424         std::vector<Expr>& instGterm,
00425         const CDList<Expr>& allterms,          
00426         size_t tBegin);
00427   void goodSynMatchNewTrig(const Trigger& trig,
00428          const std::vector<Expr> & boundVars,
00429          std::vector<std::vector<Expr> >& instBinds,
00430          std::vector<Expr>& instGterms,
00431          const CDList<Expr>& allterms,           
00432          size_t tBegin);
00433 
00434   bool goodSynMatchNewTrig(const Trigger& trig,
00435          const std::vector<Expr> & boundVars,
00436          std::vector<std::vector<Expr> >& instBinds,
00437          std::vector<Expr>& instGterms,
00438          const Expr& gterm);
00439 
00440   void matchListOld(const CDList<Expr>& list, size_t gbegin, size_t gend);
00441     //  void matchListOld(const Expr& gterm);
00442   void matchListNew(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs,
00443         const CDList<Expr>& list,
00444         size_t gbegin,
00445         size_t gend);
00446   
00447   void delNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs);
00448   void combineOldNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs);
00449 
00450   void newTopMatch(const Expr& gterm, 
00451        const Expr& vterm, 
00452        std::vector<ExprMap<Expr> >& binds, 
00453        const Trigger& trig);
00454     
00455 
00456   bool synMatchTopPred(const Expr& gterm, const Trigger trig, ExprMap<Expr>& env);
00457 
00458   inline bool matchChild(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env);
00459   inline void matchChild(const Expr& gterm, const Expr& vterm, std::vector<ExprMap<Expr> >& env);
00460   inline void add_parent(const Expr& parent);
00461 
00462   bool recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env);
00463 
00464   bool hasGoodSynInstNewTrigOld(Trigger& trig, 
00465         std::vector<Expr> & boundVars, 
00466         std::vector<std::vector<Expr> >& instBinds, 
00467         std::vector<Expr>& instGterms, 
00468         const CDList<Expr>& allterms,          
00469         size_t tBegin); 
00470   
00471   bool hasGoodSynInstNewTrig(Trigger& trig, 
00472            const std::vector<Expr> & boundVars, 
00473              std::vector<std::vector<Expr> >& instBinds, 
00474            std::vector<Expr>& instGterms, 
00475            const CDList<Expr>& allterms,           
00476            size_t tBegin); 
00477 
00478 
00479   bool hasGoodSynMultiInst(const Expr& e,
00480          std::vector<Expr>& bVars,
00481          std::vector<std::vector<Expr> >& instSet,
00482          const CDList<Expr>& allterms,           
00483          size_t tBegin);
00484   
00485   void recGoodSemMatch(const Expr& e,
00486            const std::vector<Expr>& bVars,
00487            std::vector<Expr>& newInst,
00488            std::set<std::vector<Expr> >& instSet);
00489   
00490   bool hasGoodSemInst(const Expr& e,
00491        std::vector<Expr>& bVars,
00492        std::set<std::vector<Expr> >& instSet,
00493        size_t tBegin);
00494 
00495   bool isTransLike (const std::vector<Expr>& cur_trig);
00496   bool isTrans2Like (const std::vector<Expr>& all_terms, const Expr& tr2);
00497   
00498 
00499   static const size_t MAX_TRIG_BVS=15;
00500   Expr d_mybvs[MAX_TRIG_BVS];
00501  
00502   Expr recGeneralTrig(const Expr& trig, ExprMap<Expr>& bvs, size_t& mybvs_count);
00503   Expr generalTrig(const Expr& trig, ExprMap<Expr>& bvs);
00504 
00505   ExprMap<CDMap<Expr, CDList<dynTrig>* >* > d_allmap_trigs;
00506   
00507   CDList<Trigger> d_alltrig_list;
00508 
00509   void registerTrig(ExprMap<ExprMap<std::vector<dynTrig>* >* >& cur_trig_map,
00510        Trigger trig, 
00511        const std::vector<Expr> thmBVs, 
00512        size_t univ_id);
00513     
00514   void registerTrigReal(Trigger trig, const std::vector<Expr>, size_t univ_id);
00515 
00516   bool canMatch(const Expr& t1, const Expr& t2, ExprMap<Expr>& env);
00517   void setGround(const Expr& gterm, const Expr& trig, const Theorem& univ, const std::vector<Expr>& subTerms) ;    
00518 
00519   //  std::string getHead(const Expr& e) ;
00520   void setupTriggers(const Theorem& thm, size_t univ_id);
00521   void setupTriggers(ExprMap<ExprMap<std::vector<dynTrig>* >*>& trig_maps,
00522          const Theorem& thm, 
00523          size_t univs_id);
00524 
00525   void saveContext();
00526 
00527 
00528   /*! \brief categorizes all the terms contained in an expressions by
00529    *type.
00530    *
00531    * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
00532    * returns true if the expression does not contain bound variables, false
00533    * otherwise.
00534    */
00535 
00536   
00537  public:
00538   TheoryQuant(TheoryCore* core); //!< Constructor
00539   ~TheoryQuant(); //! Destructor
00540 
00541   QuantProofRules* createProofRules();
00542   
00543 
00544  
00545   void addSharedTerm(const Expr& e) {} //!< Theory interface
00546   
00547   /*! \brief Theory interface function to assert quantified formulas
00548    *
00549    * pushes in negations and converts to either universally or existentially 
00550    * quantified theorems. Universals are stored in a database while 
00551    * existentials are enqueued to be handled by the search engine.
00552    */
00553   void assertFact(const Theorem& e); 
00554   
00555 
00556   /* \brief Checks the satisfiability of the universal theorems stored in a 
00557    * databse by instantiating them.
00558    *
00559    * There are two algorithms that the checkSat function uses to find 
00560    * instnatiations. The first algortihm looks for instanitations in a saved 
00561    * database of previous instantiations that worked in proving an earlier
00562    * theorem unsatifiable. All of the class variables with the word saved in
00563    * them  are for the use of this algorithm. The other algorithm uses terms 
00564    * found in the assertions that exist in the particular context when 
00565    * checkSat is called. All of the class variables with the word context in
00566    * them are used for the second algorithm.
00567    */
00568   void checkSat(bool fullEffort);
00569   void setup(const Expr& e); 
00570   void update(const Theorem& e, const Expr& d);
00571   /*!\brief Used to notify the quantifier algorithm of possible 
00572    * instantiations that were used in proving a context inconsistent.
00573    */
00574   void notifyInconsistent(const Theorem& thm); 
00575   //! computes the type of a quantified term. Always a  boolean.
00576   void computeType(const Expr& e); 
00577   Expr computeTCC(const Expr& e);
00578   
00579   virtual Expr parseExprOp(const Expr& e);
00580 
00581   ExprStream& print(ExprStream& os, const Expr& e);
00582 };
00583  
00584 }
00585 
00586 #endif

Generated on Tue Jul 3 14:33:41 2007 for CVC3 by  doxygen 1.5.1