search_sat.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  *\file search_sat.h
00004  *\brief Search engine that uses an external SAT engine
00005  *
00006  * Author: Clark Barrett
00007  *
00008  * Created: Mon Dec  5 17:52:05 2005
00009  *
00010  * <hr>
00011  * Copyright (C) 2005 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 #ifndef _cvcl__include__search_sat_h_
00031 #define _cvcl__include__search_sat_h_
00032 
00033 #include <vector>
00034 #include "search.h"
00035 #include "smartcdo.h"
00036 #include "cdlist.h"
00037 #include "cnf_manager.h"
00038 #include "expr.h"
00039 #include "dpllt.h"
00040 #include "theory_core.h"
00041 
00042 namespace CVCL {
00043 
00044 //! Search engine that connects to a generic SAT reasoning module
00045 /*! \ingroup SE */
00046 class SearchSat :public SearchEngine {
00047 
00048   //! Name of search engine
00049   std::string d_name;
00050 
00051   //! Bottom scope for current query
00052   CDO<int> d_bottomScope;
00053 
00054   //! Last expr checked for validity
00055   CDO<Expr> d_lastCheck;
00056 
00057   /*! @brief Theorem from the last successful checkValid call.  It is
00058     used by getProof and getAssumptions. */
00059   CDO<Theorem> d_lastValid;
00060 
00061   //! List of all user assumptions
00062   CDList<Theorem> d_userAssumptions;
00063 
00064   //! List of all internal assumptions
00065   CDList<Theorem> d_intAssumptions;
00066 
00067   //! Index to where unprocessed assumptions start
00068   CDO<unsigned> d_idxUserAssump;
00069 
00070   TheoryCore::CoreSatAPI* d_coreSatAPI;
00071 
00072   //! Pointer to DPLLT implementation
00073   SAT::DPLLT* d_dpllt;
00074 
00075   //! Implementation of TheoryAPI for DPLLT
00076   SAT::DPLLT::TheoryAPI* d_theoryAPI;
00077 
00078   //! Implementation of Decider for DPLLT
00079   SAT::DPLLT::Decider* d_decider;
00080 
00081   //! Store of theorems for expressions sent to DPLLT
00082   CDMap<Expr, Theorem> d_theorems;
00083 
00084   //! Manages CNF formula and its relationship to original Exprs and Theorems
00085   SAT::CNF_Manager *d_cnfManager;
00086 
00087   //! Cached values of variables
00088   std::vector<SmartCDO<SAT::Var::Val> > d_vars;
00089 
00090   //! Whether we are currently in a call to dpllt->checkSat
00091   bool d_inCheckSat;
00092 
00093   //! CNF Formula used for theory lemmas
00094   SAT::CD_CNF_Formula d_lemmas;
00095 
00096   //! Current position in d_lemmas
00097   CDO<unsigned> d_lemmasNext;
00098 
00099   //! Vector of CNF literals which represent Exprs with no fanouts
00100   CDList<SAT::Lit> d_rootLits;
00101 
00102   //! Last Var registered with core theory
00103   CDO<unsigned> d_lastRegisteredVar;
00104 
00105   //! Whether it's OK to call DPLLT solver from the current scope
00106   CDO<bool> d_dplltReady;
00107 
00108   CDO<unsigned> d_nextImpliedLiteral;
00109 
00110   //! Helper class for resetting DPLLT engine
00111   /*! We need to be notified when the scope goes below the scope from
00112    *  which the last invalid call to checkValid originated.  This helper class
00113    *  ensures that this happens.
00114    */
00115   friend class Restorer;
00116   class Restorer :public ContextNotifyObj {
00117     SearchSat* d_ss;
00118     public:
00119       Restorer(Context* context, SearchSat* ss)
00120         : ContextNotifyObj(context), d_ss(ss) {}
00121     void notifyPre()
00122     { if (!d_ss->d_inCheckSat && d_context->level() == d_ss->getBottomScope())
00123       d_ss->restoreDPLLT(); }
00124   };
00125   //! Instance of Restorer class
00126   Restorer d_restorer;
00127 
00128 private:
00129 
00130   //! Tell DPLLT object to go back to state before last satisfiable check
00131   void restoreDPLLT() { d_dpllt->returnFromSat(); }
00132 
00133   friend class SearchSatCoreSatAPI;
00134   //! Core theory callback which adds a new lemma from the core theory
00135   void addLemma(const Theorem& thm);
00136   //! Core theory callback which asks for the bottom scope for current query
00137   int getBottomScope() { return d_bottomScope; }
00138   //! Core theory callback which suggests a splitter
00139   void addSplitter(const Expr& e, int priority);
00140 
00141   friend class SearchSatTheoryAPI;
00142   //! DPLLT callback to inform theory that a literal has been assigned
00143   void assertLit(SAT::Lit l);
00144   //! DPLLT callback to ask if theory has detected inconsistency.
00145   SAT::DPLLT::ConsistentResult checkConsistent(SAT::Clause& c,bool fullEffort);
00146   //! DPLLT callback to get theory propagations.
00147   SAT::Lit getImplication();
00148   //! DPLLT callback to explain a theory propagation.
00149   void getExplanation(SAT::Lit l, SAT::Clause& c);
00150   //! DPLLT callback to get more general theory clauses.
00151   bool getNewClauses(SAT::CNF_Formula& cnf);
00152 
00153   friend class SearchSatDecider;
00154   //! DPLLT callback to decide which literal to split on next
00155   SAT::Lit makeDecision();
00156 
00157   //! Recursively traverse DAG looking for a splitter
00158   /*! Returns true if a splitter is found, false otherwise.  The splitter is
00159    * returned in lit (lit should be set to true).  Nodes whose current value is
00160    * fully justified are marked by calling setFlag to avoid searching them in
00161    * the future.
00162    */
00163   bool findSplitterRec(SAT::Lit lit, SAT::Var::Val value,
00164                        SAT::Lit* litDecision);
00165 
00166   //! Get the value of a CNF Literal
00167   SAT::Var::Val getValue(SAT::Lit c) {
00168     DebugAssert(!c.isVar() || unsigned(c.getVar()) < d_vars.size(),
00169                 "Lit out of bounds in getValue");
00170     return c.isFalse() ? SAT::Var::FALSE : c.isTrue() ? SAT::Var::TRUE :
00171       c.isInverted() ? SAT::Var::invertValue(d_vars[c.getVar()]) :
00172       d_vars[c.getVar()]; }
00173 
00174   //! Set the value of a variable
00175   void setValue(SAT::Var v, SAT::Var::Val val) {
00176     DebugAssert(!v.isNull(), "expected non-null Var");
00177     DebugAssert(unsigned(v) < d_vars.size(), "Var out of bounds in getValue");
00178     d_vars[v] = val; }
00179 
00180   //! Check whether this variable's value is justified
00181   bool checkJustified(SAT::Var v)
00182     { return d_cnfManager->concreteLit(v).isJustified(); }
00183 
00184   //! Mark this variable as justified
00185   void setJustified(SAT::Var v)
00186     { d_cnfManager->concreteLit(v).setJustified(); }
00187 
00188   //! Main checking procedure shared by checkValid and restart
00189   Theorem check(const Expr& e, bool isRestart = false);
00190 
00191 public:
00192 
00193   //! Constructor
00194   SearchSat(TheoryCore* core);
00195 
00196   //! Destructor
00197   virtual ~SearchSat();
00198 
00199   // Implementation of virtual SearchEngine methods
00200   virtual const std::string& getName() { return d_name; }
00201   virtual void registerAtom(const Expr& e);
00202   virtual Theorem getImpliedLiteral();
00203   virtual Theorem checkValid(const Expr& e) { return check(e); }
00204   virtual Theorem restart(const Expr& e) { return check(e, true); }
00205   virtual void returnFromCheck();
00206   virtual Theorem lastThm() { return d_lastValid; }
00207   virtual Theorem newUserAssumption(const Expr& e, int scope = -1);
00208   virtual void getUserAssumptions(std::vector<Expr>& assumptions);
00209   virtual void getInternalAssumptions(std::vector<Expr>& assumptions);
00210   virtual void getAssumptions(std::vector<Expr>& assumptions);
00211   virtual bool isAssumption(const Expr& e);
00212   virtual void getCounterExample(std::vector<Expr>& assertions,
00213                                  bool inOrder = true);
00214   virtual Proof getProof();
00215 
00216 };
00217 
00218 }
00219 
00220 #endif

Generated on Thu Apr 13 16:57:33 2006 for CVC Lite by  doxygen 1.4.4