cnf_manager.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  *\file cnf_manager.h
00004  *\brief Manager for conversion to and traversal of CNF formulas
00005  *
00006  * Author: Clark Barrett
00007  *
00008  * Created: Thu Dec 15 13:53:16 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 #ifndef _cvcl__include__cnf_manager_h_
00030 #define _cvcl__include__cnf_manager_h_
00031 
00032 #include "cnf.h"
00033 #include "expr.h"
00034 #include "expr_map.h"
00035 #include "cdmap.h"
00036 
00037 namespace CVCL {
00038 
00039 class CommonProofRules;
00040 class CNF_Rules;
00041 
00042 }
00043 
00044 namespace SAT {
00045 
00046 class CNF_Manager {
00047 
00048   //! Common proof rules
00049   CVCL::CommonProofRules* d_commonRules;
00050 
00051   //! Rules for manipulating CNF
00052   CVCL::CNF_Rules* d_rules;
00053 
00054   //! Information kept for each CNF variable
00055   struct Varinfo {
00056     CVCL::Expr expr;
00057     std::vector<Lit> fanins;
00058     std::vector<Var> fanouts;
00059   };
00060 
00061   //! vector that maps a variable index to information for that variable
00062   std::vector<Varinfo> d_varInfo;
00063 
00064   //! Map from Exprs to Vars representing those Exprs
00065   CVCL::ExprMap<Var> d_cnfVars;
00066 
00067   //! Cached translation of term-ite-containing expressions
00068   CVCL::ExprMap<CVCL::Theorem> d_iteMap;
00069 
00070   //! Maps a clause id to the theorem justifying that clause
00071   /*! Note that clauses created by simple CNF translation are not given id's.
00072    *  This is because theorems for these clauses can be created lazily later. */
00073   CVCL::CDMap<int, CVCL::Theorem> d_theorems;
00074 
00075   //! Next clause id
00076   int d_clauseIdNext;
00077 
00078   //! Whether expr has already been translated
00079   //  CVCL::CDMap<CVCL::Expr, bool> d_translated;
00080 
00081   //! Bottom scope in which translation is valid
00082   int d_bottomScope;
00083 
00084   //! Queue of theorems to translate
00085   std::deque<CVCL::Theorem> d_translateQueueThms;
00086 
00087   //! Queue of fanouts corresponding to thms to translate
00088   std::deque<Var> d_translateQueueVars;
00089 
00090   //! Whether thm to translate is "translate only"
00091   std::deque<bool> d_translateQueueFlags;
00092 
00093 private:
00094 
00095   CVCL::CNF_Rules* createProofRules(CVCL::TheoremManager* tm);
00096 
00097   //! Recursively translate e into cnf
00098   /*! A non-context dependent cache, d_cnfVars is used to remember translations
00099    * of expressions.  A context-dependent attribute, isTranslated, is used to
00100    * remember whether an expression has been translated in the current context */
00101   Lit translateExprRec(const CVCL::Expr& e, CNF_Formula& cnf);
00102 
00103   //! Recursively traverse an expression with an embedded term ITE
00104   /*! Term ITE's are handled by introducing a skolem variable for the ITE term
00105    * and then adding new constraints describing the ITE in terms of the new variable.
00106    */
00107   CVCL::Theorem replaceITErec(const CVCL::Expr& e, Var v, bool translateOnly);
00108 
00109   //! Recursively translate e into cnf
00110   /*! Call translateExprRec.  If additional expressions are queued up,
00111    * translate them too, until none are left. */
00112   Lit translateExpr(const CVCL::Expr& e, CNF_Formula& cnf);
00113 
00114 //   bool isTranslated(const CVCL::Expr& e)
00115 //     { CVCL::CDMap<CVCL::Expr, bool>::iterator i = d_translated.find(e);
00116 //       return i != d_translated.end() && (*i).second; }
00117 //   void setTranslated(const CVCL::Expr& e)
00118 //     { DebugAssert(!isTranslated(e),"already set");
00119 //       d_translated.insert(e, true, d_bottomScope); }
00120 //   void clearTranslated(const CVCL::Expr& e)
00121 //     { d_translated.insert(e, false, d_bottomScope); }
00122 
00123 public:
00124   CNF_Manager(CVCL::TheoremManager* tm);
00125   ~CNF_Manager();
00126 
00127   //! Set scope for translation
00128   void setBottomScope(int scope) { d_bottomScope = scope; }
00129 
00130   //! Return the number of variables being managed
00131   unsigned numVars() { return d_varInfo.size(); }
00132 
00133   //! Return number of fanins for CNF node c
00134   /*! A CNF node x is a fanin of CNF node y if the expr for x is a child of the
00135    *  expr for y or if y is an ITE leaf and x is a new CNF node obtained by
00136    *  translating the ITE leaf y.
00137    *  \sa isITELeaf()
00138    */
00139   unsigned numFanins(Lit c) {
00140     if (!c.isVar()) return 0;
00141     int index = c.getVar();
00142     if ((unsigned)index >= d_varInfo.size()) return 0;
00143     return d_varInfo[index].fanins.size();
00144   }
00145 
00146   //! Returns the ith fanin of c.
00147   Lit getFanin(Lit c, unsigned i) {
00148     DebugAssert(i < numFanins(c), "attempt to access unknown fanin");
00149     return d_varInfo[c.getVar()].fanins[i];
00150   }
00151 
00152   //! Return number of fanins for c
00153   /*! x is a fanout of y if y is a fanin of x
00154    *  \sa numFanins
00155    */
00156   unsigned numFanouts(Lit c) {
00157     if (!c.isVar()) return 0;
00158     int index = c.getVar();
00159     if ((unsigned)index >= d_varInfo.size()) return 0;
00160     return d_varInfo[index].fanouts.size();
00161   }
00162 
00163   //! Returns the ith fanout of c.
00164   Lit getFanout(Lit c, unsigned i) {
00165     DebugAssert(i < numFanouts(c), "attempt to access unknown fanin");
00166     return d_varInfo[c.getVar()].fanouts[i];
00167   }
00168 
00169   //! Convert a CNF literal to an Expr literal
00170   /*! Returns a NULL Expr if there is no corresponding Expr for l
00171    */
00172   CVCL::Expr concreteLit(Lit l) {
00173     if (l.isNull()) return CVCL::Expr();
00174     bool inverted = !l.isPositive();
00175     int index = l.getVar();
00176     if ((unsigned)index >= d_varInfo.size() ||
00177         !d_varInfo[index].expr.isTranslated()) return CVCL::Expr();
00178     return inverted ? !d_varInfo[index].expr : d_varInfo[index].expr;
00179   }
00180 
00181   //! Look up the CNF literal for an Expr
00182   /*! Returns a NULL Lit if there is no corresponding CNF literal for e
00183    */
00184   Lit getCNFLit(const CVCL::Expr& e) {
00185     if (e.isFalse()) return Lit::getFalse();
00186     if (e.isTrue()) return Lit::getTrue();
00187     if (e.isNot()) return !getCNFLit(e[0]);
00188     CVCL::ExprMap<Var>::iterator i = d_cnfVars.find(e);
00189     if (!e.isTranslated() || i == d_cnfVars.end()) return Lit();
00190     return Lit((*i).second);
00191   }
00192 
00193   //! Convert thm A |- B (A is a set of literals) into a clause ~A \/ B
00194   /*! c should be an empty clause that will be filled with the result */
00195   void convertLemma(const CVCL::Theorem& thm, Clause& c);
00196 
00197   //! Given thm of form A |- B, convert B to CNF and add it to cnf
00198   /*! Returns Lit corresponding to the root of the expression that was
00199    * translated. */
00200   Lit addAssumption(const CVCL::Theorem& thm, CNF_Formula& cnf);
00201 
00202   //! Convert thm to CNF and add it to the current formula
00203   /*! \param thm should be of form A |- B where A is a set of literals
00204    * The new clauses are added to cnf.
00205    * Returns Lit corresponding to the root of the expression that was
00206    * translated. */
00207   Lit addLemma(const CVCL::Theorem& thm, CNF_Formula& cnf);
00208 
00209 };
00210 
00211 }
00212 
00213 #endif

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