vc_api.cpp

Go to the documentation of this file.
00001 
00002 
00003 #define GetValue(id) ((id) < 0 ? (d_vars[-(id)].value == -1 ? \
00004                                    -1 : (1 - d_vars[-(id)].value)) : \
00005                                  (id < 2) ? id : d_vars[id].value)
00006 #define ABS(x) ((x) < 0 ? -(x) : (x))
00007 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
00008 
00009 
00010 using namespace std;
00011 
00012 
00013 bool SVC_API_impl::AddConditions(long lVar)
00014 {
00015   // Collect vector of nonassertable facts and transform to vector
00016   // (conjunction) of atomified formulas
00017   vector<Expr> vecAtomify, vecDynamic, vecStatic;
00018   if (_verbosity > 1) {
00019     cout << "AddConditions" << endl;
00020   }
00021   // TODO: this becomes a callback
00022   while (!_nonassertable_facts->Done()) {
00023     vecAtomify.push_back(_nonassertable_facts->Get());
00024     if (_verbosity > 2) {
00025       _pem->Print(cout, vecAtomify.back());
00026       cout << endl;
00027     }
00028   }
00029   _patomifier->TransformVec(vecAtomify, vecDynamic, vecStatic);
00030   DebugAssert(vecAtomify.size() == vecDynamic.size(),"");
00031 
00032   // Convert atomified formulas to CNF
00033   _cnfFormula->Reset();
00034   int i;
00035   for (i = 0; i < (int)vecAtomify.size(); i++) {
00036     _conditions.push_back(vecAtomify[i]);
00037     _conditionVars.push_back(_cnfConverter->ConvertFormula(vecDynamic[i]));
00038     DebugAssert(_cnfFormula->_vecFormula.back()->_vecClause.size() == 1,
00039                 "Expected unit clause");
00040     _cnfFormula->AddLiteral(lVar);
00041     _cnfFormula->_vecFormula.back()->SetDynamic();
00042   }
00043   for (i = 0; i < (int)vecStatic.size(); i++) {
00044     _cnfConverter->ConvertFormula(vecStatic[i]);
00045     _cnfFormula->RegisterUnit();
00046   }
00047   _cnfFormula->Simplify();
00048   if (_verbosity > 2) {
00049     _cnfFormula->Print();
00050   }
00051   _cnfConverter->Connect();
00052 
00053   // Update SAT formula
00054   return _psatapi->AddClauses(*_cnfFormula, _vecMap.size());
00055 }
00056 
00057 
00058 // Description: Update value in d_vars array                                  //
00059 void SVC_API_impl::UpdateValue(long v, int value)
00060 {
00061   v++;
00062   DebugAssert(v < (int)d_vars.size(), "id out of bounds");
00063   d_vars[v].value = value;
00064 }
00065 
00066 
00067 // Description: Recursively traverse the DAG looking for a splitter.  Return //
00068 //              true if a splitter is found, false otherwise.  Visted nodes  //
00069 //              are marked by setting their "next" fields to the current     //
00070 //              value of _splitterCacheTag.                                  //
00071 bool SVC_API_impl::FindSplitterRec(long v, int value, long *pv)
00072 {
00073   int i;
00074   long tmp;
00075   bool ret;
00076   
00077   if (v == 0 || v == 1) return false;
00078   DebugAssert(v > 1 && (d_vars[v].value == value || d_vars[v].value == -1),
00079               "invariant violated");
00080   
00081   if (d_vars[v].next == _splitterCacheTag) return false;
00082 
00083   if (d_vars[v].fanins.size() == 0) {
00084     if (d_vars[v].value != -1) {
00085       d_vars[v].next = _splitterCacheTag;
00086       return false;
00087     }
00088     else {
00089       *pv = v;
00090       return true;
00091     }
00092   }
00093   // TODO:
00094   else if (d_vars[v].kind == Prop_Var_Manager::PROP_VAR_KIND) {
00095     // This propositional variable depends on static ITE's introduced by the
00096     // atomifier.  We handle these ITE's specially in order to catch the
00097     // corner case when a variable is its own fanin.
00098     for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00099       tmp = d_vars[v].fanins[i];
00100       DebugAssert(tmp > 0,"Invariant violated");
00101       DebugAssert(d_vars[tmp].isITE(),"Expected ITE");
00102       DebugAssert(d_vars[tmp].value == 1,"Expected value 1");
00103       if (GetValue(d_vars[tmp].fanins[0]) == -1) {
00104         if (GetValue(d_vars[tmp].fanins[2]) == value) {
00105           ret = FindSplitterRec(ABS(d_vars[tmp].fanins[0]),
00106                                 d_vars[tmp].fanins[0] < 0 ? 1 : 0, pv);
00107         }
00108         else {
00109           ret = FindSplitterRec(ABS(d_vars[tmp].fanins[0]),
00110                                 d_vars[tmp].fanins[0] < 0 ? 0 : 1, pv);
00111         }
00112         if (!ret) {
00113           cout << _vecMap[ABS(d_vars[tmp].fanins[0])-2] << endl;
00114           DebugAssert(false,"No controlling input found (1)");
00115         }         
00116         return true;
00117       }
00118       else if (GetValue(d_vars[tmp].fanins[0])) {
00119         if (FindSplitterRec(ABS(d_vars[tmp].fanins[0]),
00120                             d_vars[tmp].fanins[0] < 0 ? 0 : 1, pv)) {
00121             return true;
00122         }
00123         if (ABS(d_vars[tmp].fanins[1]) != v &&
00124             FindSplitterRec(ABS(d_vars[tmp].fanins[1]),
00125                             d_vars[tmp].fanins[1] < 0 ? 0 : 1, pv)) {
00126           return true;
00127         }
00128       }
00129       else {
00130         if (FindSplitterRec(ABS(d_vars[tmp].fanins[0]),
00131                             d_vars[tmp].fanins[0] < 0 ? 1 : 0, pv)) {
00132           return true;
00133         }
00134         if (ABS(d_vars[tmp].fanins[2]) != v &&
00135             FindSplitterRec(ABS(d_vars[tmp].fanins[2]),
00136                             d_vars[tmp].fanins[1] < 0 ? 0 : 1, pv)) {
00137           return true;
00138         }
00139       }
00140       d_vars[tmp].next = _splitterCacheTag;
00141     }
00142     if (d_vars[v].value != -1) {
00143       d_vars[v].next = _splitterCacheTag;
00144       return false;
00145     }
00146     else {
00147       *pv = v;
00148       return true;
00149     }
00150   }
00151 
00152   switch (d_vars[v].kind) {
00153     case AND:
00154       if (value) {
00155         for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00156           if (FindSplitterRec(ABS(d_vars[v].fanins[i]),
00157                             d_vars[v].fanins[i] < 0 ? 0 : 1, pv)) {
00158             return true;
00159           }
00160         }
00161         DebugAssert(d_vars[v].value == 1,"Output should be justified");
00162         d_vars[v].next = _splitterCacheTag;
00163         return false;
00164       }
00165       else {
00166         for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00167           if (GetValue(d_vars[v].fanins[i]) != 1) {
00168             if (FindSplitterRec(ABS(d_vars[v].fanins[i]),
00169                                 d_vars[v].fanins[i] < 0 ? 1 : 0, pv)) {
00170               return true;
00171             }
00172             DebugAssert(d_vars[v].value == 0,"Output should be justified");
00173             d_vars[v].next = _splitterCacheTag;
00174             return false;
00175           }
00176         }
00177         DebugAssert(i < (int)d_vars[v].fanins.size(),
00178                     "No controlling input found (2)");
00179       }
00180       break;
00181     case OR:
00182       if (!value) {
00183         for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00184           if (FindSplitterRec(ABS(d_vars[v].fanins[i]),
00185                             d_vars[v].fanins[i] < 0 ? 1 : 0, pv)) {
00186             return true;
00187           }
00188         }
00189         DebugAssert(d_vars[v].value == 0,"Output should be justified");
00190         d_vars[v].next = _splitterCacheTag;
00191         return false;
00192       }
00193       else {
00194         for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00195           if (GetValue(d_vars[v].fanins[i]) != 0) {
00196             if (FindSplitterRec(ABS(d_vars[v].fanins[i]),
00197                                 d_vars[v].fanins[i] < 0 ? 0 : 1, pv)) {
00198               return true;
00199             }
00200             DebugAssert(d_vars[v].value == 1,"Output should be justified");
00201             d_vars[v].next = _splitterCacheTag;
00202             return false;
00203           }
00204         }
00205         DebugAssert(i < (int)d_vars[v].fanins.size(),
00206                     "No controlling input found (3)");
00207       }
00208       break;
00209     case ITE:
00210       if (GetValue(d_vars[v].fanins[0]) == -1) {
00211         if (GetValue(d_vars[v].fanins[2]) == value) {
00212           ret = FindSplitterRec(ABS(d_vars[v].fanins[0]),
00213                                 d_vars[v].fanins[0] < 0 ? 1 : 0, pv);
00214         }
00215         else {
00216           ret = FindSplitterRec(ABS(d_vars[v].fanins[0]),
00217                                 d_vars[v].fanins[0] < 0 ? 0 : 1, pv);
00218         }
00219         if (!ret) {
00220           _pem->Print(cout, _vecMap[v-2]);
00221           DebugAssert(false,"No controlling input found (4)");
00222         }         
00223         return true;
00224       }
00225       else if (GetValue(d_vars[v].fanins[0])) {
00226         if (FindSplitterRec(ABS(d_vars[v].fanins[0]),
00227                             d_vars[v].fanins[0] < 0 ? 0 : 1, pv)) {
00228             return true;
00229         }
00230         if (FindSplitterRec(ABS(d_vars[v].fanins[1]),
00231                             d_vars[v].fanins[1] < 0 ? 1-value : value, pv)) {
00232           return true;
00233         }
00234       }
00235       else {
00236         if (FindSplitterRec(ABS(d_vars[v].fanins[0]),
00237                             d_vars[v].fanins[0] < 0 ? 1 : 0, pv)) {
00238           return true;
00239         }
00240         if (FindSplitterRec(ABS(d_vars[v].fanins[2]),
00241                             d_vars[v].fanins[2] < 0 ? 1-value : value, pv)) {
00242           return true;
00243         }
00244       }
00245       DebugAssert(d_vars[v].value == value,"Output should be justified");
00246       d_vars[v].next = _splitterCacheTag;
00247       return false;
00248     case IFF:
00249     case EQ:
00250       tmp = GetValue(d_vars[v].fanins[0]);
00251       if (tmp != -1) {
00252         if (FindSplitterRec(ABS(d_vars[v].fanins[0]),
00253                             d_vars[v].fanins[0] < 0 ? 1-tmp : tmp, pv)) {
00254           return true;
00255         }
00256         if (!value) tmp = 1 - tmp;
00257         if (FindSplitterRec(ABS(d_vars[v].fanins[1]),
00258                             d_vars[v].fanins[1] < 0 ? 1-tmp : tmp, pv)) {
00259           return true;
00260         }
00261         DebugAssert(d_vars[v].value == value,"Output should be justified");
00262         d_vars[v].next = _splitterCacheTag;
00263         return false;
00264       }
00265       else {
00266         tmp = GetValue(d_vars[v].fanins[1]);
00267         if (tmp == -1) tmp = 0;
00268         if (!value) tmp = 1 - tmp;
00269         if (FindSplitterRec(ABS(d_vars[v].fanins[0]),
00270                             d_vars[v].fanins[0] < 0 ? 1-tmp : tmp, pv)) {
00271           return true;
00272         }
00273         DebugAssert(false,"Unable to find controlling input");
00274       }
00275       break;
00276     case IMPLIES:
00277     default:
00278       FatalAssert(false,"Not implemented yet");    
00279   }
00280   *pv = 0;
00281   return true;
00282 }
00283 
00284 
00285 // Description: Traverse tree recursively looking for nodes that reduce to   //
00286 //              true or false.  Visited nodes with no splitters are marked   //
00287 //              as in FindSplitterRec.  Visited nodes with splitters are     //
00288 //              marked by setting the "prev" field to the current value of   //
00289 //              _splitterCacheTag2.                                          //
00290 bool SVC_API_impl::GetImplicationsRec(long v, long *pv, int *pvalue)
00291 {
00292   int i;
00293   long tmp;
00294   bool ret;
00295   Expr e;
00296 
00297   if (v == 0 || v == 1) return false;
00298   DebugAssert(v > 1,"invariant violated");
00299 
00300   if (d_vars[v].next == _splitterCacheTag) return false;
00301   if (d_vars[v].prev == _splitterCacheTag2) return true;
00302   d_vars[v].prev = _splitterCacheTag2;
00303 
00304   if (d_vars[v].fanins.size() == 0) {
00305     if (d_vars[v].value != -1) {
00306       d_vars[v].next = _splitterCacheTag;
00307       return false;
00308     }
00309     else if (HasSVCExpr(v-1)) {
00310       e = d_core->simplify(_vecMap[v-2]);
00311       if (e.isFalse()) == 0) {
00312         *pv = v;
00313         *pvalue = 0;
00314       }
00315       else if (e.isTrue()) {
00316         *pv = v;
00317         *pvalue = 1;
00318       }
00319     }
00320     return true;
00321   }
00322 
00323   ret = false;
00324 // TODO
00325   if (d_vars[v].kind == Prop_Var_Manager::PROP_VAR_KIND) {
00326     bool retTmp;
00327     for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00328       retTmp = false;
00329       tmp = d_vars[v].fanins[i];
00330       DebugAssert(tmp > 0,"Invariant violated");
00331       DebugAssert(d_vars[tmp].isITE(),"Expected ITE");
00332       DebugAssert(d_vars[tmp].value == 1,"Expected value 1");
00333       if (d_vars[tmp].next == _splitterCacheTag) continue;
00334       if (d_vars[tmp].prev == _splitterCacheTag2) {
00335         ret = true;
00336         continue;
00337       }
00338       d_vars[tmp].prev = _splitterCacheTag2;
00339       if (GetValue(d_vars[tmp].fanins[0]) == -1) {
00340         bool retval = GetImplicationsRec(ABS(d_vars[tmp].fanins[0]),pv,pvalue);
00341         if (*pv != 0) return true;
00342         DebugAssert(retval,"Expected unjustified");
00343         retTmp = true;
00344       }
00345       else if (GetValue(d_vars[tmp].fanins[0])) {
00346         if (GetImplicationsRec(ABS(d_vars[tmp].fanins[0]),pv,pvalue)) {
00347           retTmp = true;
00348         }
00349         if (*pv != 0) return true;
00350         if (ABS(d_vars[tmp].fanins[1]) != v &&
00351             GetImplicationsRec(ABS(d_vars[tmp].fanins[1]),pv,pvalue)) {
00352           retTmp = true;
00353         }
00354         if (*pv != 0) return true;
00355       }
00356       else {
00357         if (GetImplicationsRec(ABS(d_vars[tmp].fanins[0]),pv,pvalue)) {
00358           retTmp = true;
00359         }
00360         if (*pv != 0) return true;
00361         if (ABS(d_vars[tmp].fanins[2]) != v &&
00362             GetImplicationsRec(ABS(d_vars[tmp].fanins[2]),pv,pvalue)) {
00363           retTmp = true;
00364         }
00365         if (*pv != 0) return true;
00366       }
00367       if (!retTmp) {
00368         d_vars[tmp].next = _splitterCacheTag;
00369       }
00370       ret = ret || retTmp;
00371     }
00372     if (d_vars[v].value != -1) {
00373       if (!ret) {
00374         d_vars[v].next = _splitterCacheTag;
00375         return false;
00376       }
00377     }
00378     else if (HasSVCExpr(v-1)) {
00379       e = d_core->simplify(_vecMap[v-2]);
00380       if (e.isFalse()) {
00381         *pv = v;
00382         *pvalue = 0;
00383       }
00384       else if (e.isTrue()) {
00385         *pv = v;
00386         *pvalue = 1;
00387       }
00388     }
00389     return true;
00390   }
00391 
00392   switch (d_vars[v].kind) {
00393     case AND:
00394     case OR:
00395     case IFF:
00396     case EQ:
00397       for (i=0; i < (int)d_vars[v].fanins.size(); i++) {
00398         if (GetImplicationsRec(ABS(d_vars[v].fanins[i]),pv,pvalue)) {
00399           ret = true;
00400         }
00401         if (*pv != 0) return true;
00402       }
00403       if (d_vars[v].value != -1) {
00404         if (!ret) {
00405           d_vars[v].next = _splitterCacheTag;
00406           return false;
00407         }
00408       }
00409       else if (HasSVCExpr(v-1)) {
00410         e = d_core->simplify(_vecMap[v-2]);
00411         if (e.isFalse()) {
00412           *pv = v;
00413           *pvalue = 0;
00414         }
00415         else if (e.isTrue()) {
00416           *pv = v;
00417           *pvalue = 1;
00418         }
00419       }
00420       return true;
00421     case ITE:
00422       if (GetValue(d_vars[v].fanins[0]) == -1) {
00423         bool retval = GetImplicationsRec(ABS(d_vars[v].fanins[0]),pv,pvalue);
00424         if (*pv != 0) return true;
00425         DebugAssert(retval,"Expected unjustified");
00426         ret = true;
00427       }
00428       else if (GetValue(d_vars[v].fanins[0])) {
00429         if (GetImplicationsRec(ABS(d_vars[v].fanins[0]),pv,pvalue)) {
00430           ret = true;
00431         }
00432         if (*pv != 0) return true;
00433         if (GetImplicationsRec(ABS(d_vars[v].fanins[1]),pv,pvalue)) {
00434           ret = true;
00435         }
00436         if (*pv != 0) return true;
00437       }
00438       else {
00439         if (GetImplicationsRec(ABS(d_vars[v].fanins[0]),pv,pvalue)) {
00440           ret = true;
00441         }
00442         if (*pv != 0) return true;
00443         if (GetImplicationsRec(ABS(d_vars[v].fanins[2]),pv,pvalue)) {
00444           ret = true;
00445         }
00446         if (*pv != 0) return true;
00447       }
00448       if (d_vars[v].value != -1) {
00449         if (!ret) {
00450           d_vars[v].next = _splitterCacheTag;
00451           return false;
00452         }
00453       }
00454       else if (HasSVCExpr(v-1)) {
00455         e = d_core->simplify(_vecMap[v-2]);
00456         if (e.isFalse()) {
00457           *pv = v;
00458           *pvalue = 0;
00459         }
00460         else if (e.isTrue()) {
00461           *pv = v;
00462           *pvalue = 1;
00463         }
00464       }
00465       return true;
00466     case IMPLIES:
00467     default:
00468       FatalAssert(false,"Not implemented yet");    
00469   }
00470   return true;
00471 }
00472 
00473 
00474 ///////////////////////////////////////////////////////////////////////////////
00475 // Begin public methods                                                      //
00476 ///////////////////////////////////////////////////////////////////////////////
00477 
00478 
00479 // Description: Constructor                                                  //
00480 SVC_API_impl::SVC_API_impl(TheoryCore* core)
00481   : d_core(core), _vecMap(), _connectQueue(), _conditions(), _conditionVars(),
00482     _conditionIndex(), d_vars(100), _splitterCacheTag(1), _splitterCacheTag2(1)
00483 {
00484   // TODO:
00485   // Set up propositional variable manager
00486   _ppvm = new Prop_Var_Manager(type_sys, *_pem);
00487   _ppvm->Init("Prop_Var_Manager", "_p_");
00488   _pem->DeclareKind(Prop_Var_Manager::PROP_VAR_KIND, *_ppvm, true);
00489 
00490   _pfanout_table = new hash_map<int, vector<Expr>* >;
00491   _verbosity = 0;
00492 
00493   // Initialize Sat_SVC components
00494 // TODO:
00495   C_Nucleus::Source<E::Expr_Handle> *psourceOfFreshVars =
00496     (C_Nucleus::Source<E::Expr_Handle>*)
00497     basic_sys.GetCR(SVC2::SOURCE_OF_FRESHD_VARS);
00498   _pisAtomic = (C_Nucleus::Predicate<E::Expr_Handle>*)
00499     fdrsning_sys.Get(FDRsning::ATOMIC);
00500   _patomifier = new Atomifier(*_pem, *_prec_tb, *pvar_rec_tb,
00501                               *psourceOfFreshVars, *freshVarDefs, *_pisAtomic,
00502                               *pisBool, _vecMap, _pfanout_table, _connectQueue);
00503   _patomifier->ClearTransformCache();
00504   _cnfFormula = new CNF_Formula_For_Exprs(*_pem);
00505   _cnfConverter = new CNF_Converter(*_pem, *_cnfFormula, _vecMap, this,
00506                                     _pfanout_table, _connectQueue);
00507   _psatapi = new SAT_API(*this, *_fm_trace, flags);
00508 
00509   Reset();
00510 }
00511 
00512 
00513 // Description: Destructor                                                   //
00514 SVC_API_impl::~SVC_API_impl()
00515 {
00516   delete _psatapi;
00517   delete _cnfConverter;
00518   delete _cnfFormula;
00519   delete _patomifier;
00520   hash_map<int, vector<Expr>* >::iterator i, iend;
00521   for (i = _pfanout_table->begin(), iend = _pfanout_table->end(); i != iend; ++i) {
00522     if ((*i).second) delete (*i).second;
00523   }
00524   delete _pfanout_table;
00525 }
00526 
00527 
00528 // Description: Main SAT checking procedure                             //
00529 bool SVC_API_impl::CheckSat(const Expr& e)
00530 {
00531   // If the formula is TRUE or FALSE, return
00532   // without entering the heart of the SAT code.
00533   if (e.isBoolConst()) return e.isFalse();
00534 
00535   // Transform vector (conjunction) of formulas to vector (conjunction) of
00536   // atomified formulas
00537   vector<Expr> vecAtomify, vecDynamic, vecStatic;
00538   if (_verbosity) {
00539     cout << "SAT_SVC: Atomifying" << endl;
00540   }
00541   vecAtomify.push_back(e);
00542   _patomifier->TransformVec(vecAtomify, vecDynamic, vecStatic);
00543   DebugAssert(vecDynamic.size() == 1,"");
00544 
00545   // Convert atomified formulas to CNF
00546   vector<Expr>::const_iterator i;
00547   if (_verbosity) {
00548     cout << "SAT_SVC: Converting to CNF" << endl;
00549   }
00550   _cnfFormula->Reset();
00551   _conditions.push_back(e);
00552   _conditionVars.push_back(_cnfConverter->ConvertFormula(vecDynamic[0]));
00553   for (i = vecStatic.begin(); i != vecStatic.end(); ++i) {
00554     _cnfConverter->ConvertFormula(*i);
00555     _cnfFormula->RegisterUnit();
00556   }
00557   _cnfFormula->Simplify();
00558   if (_verbosity > 2) {
00559     _cnfFormula->Print();
00560   }
00561   _cnfConverter->Connect();
00562 
00563   // Run SAT
00564   if (_verbosity) {
00565     cout << "SAT_SVC: Starting SAT" << endl;
00566   }
00567   bool result = _psatapi->RunSAT(*_cnfFormula, _vecMap.size(), _verbosity) == SAT_API::UNSAT;
00568   if (result) {
00569     Reset();
00570   }
00571   else {
00572     _ready = false;
00573   }
00574   return result;
00575 }
00576 
00577 
00578 // Description: Push scope                                                   //
00579 void SVC_API_impl::Push()
00580 {
00581   if (_verbosity > 2) {
00582     cout << "SVC_API: Push" << endl;
00583   }
00584   d_core->getCM()->push();
00585   _conditionIndex.push_back(_conditionVars.size());
00586   DebugAssert(_conditionVars.size() == _conditions.size(),
00587               "condition size mismatch");
00588 }
00589 
00590 
00591 ///////////////////////////////////////////////////////////////////////////////
00592 //                                                                           //
00593 // Function: SVC_API_impl::Pop                                               //
00594 // Author: Clark Barrett                                                     //
00595 // Created: Wed Sep 26 19:43:16 2001                                         //
00596 // Description: Pop scope                                                    //
00597 //                                                                           //
00598 ///////////////////////////////////////////////////////////////////////////////
00599 void SVC_API_impl::Pop()
00600 {
00601   if (_verbosity > 2) {
00602     cout << "SVC_API: Pop" << endl;
00603   }
00604   d_core->getCM()->pop();
00605 
00606   // Reset context-dependent state
00607   _splitterCacheTag++;
00608   while ((int)_conditionVars.size() != _conditionIndex.back()) {
00609     _conditionVars.pop_back();
00610     _conditions.pop_back();
00611   }
00612   _conditionIndex.pop_back();
00613 }
00614 
00615 
00616 // Description: Asserts the SVC expr associated with lVar (if any).          //
00617 //              Returns true unless conditions added are inconsistent.       //
00618 bool SVC_API_impl::SVCAssert(long lVar)
00619 {
00620   DebugAssert(lVar > 0,"SVC_API::Assert 1");
00621   if (_verbosity > 2) {
00622     cout << "SVC_API: Assert " << lVar << endl;
00623   }
00624   UpdateValue(lVar,1);
00625   DebugAssert((unsigned)lVar <= _vecMap.size(),"SVC_API::Assert 2");
00626   Expr e = _vecMap[lVar-1];
00627   if (e.isNull()) return true;
00628 
00629   if (_verbosity > 2) {
00630     cout << " A " << e << endl;
00631   }
00632   d_core->addFact(d_core->assumpRule(e));
00633 
00634   if (!IsStable()) {
00635     if (_verbosity > 1) {
00636       cout << "Condition added" << endl;
00637     }
00638     return AddConditions(-lVar);
00639   }
00640   return true;
00641 }
00642 
00643 
00644 // Description: Denies the SVC expr associated with lVar (if any).           //
00645 //              Returns true unless conditions added are inconsistent.       //
00646 bool SVC_API_impl::SVCDeny(long lVar)
00647 {
00648   DebugAssert(lVar > 0,"SVC_API::Deny 1");
00649   if (_verbosity > 2) {
00650     cout << "SVC_API: Deny " << lVar << endl;
00651   }
00652   UpdateValue(lVar,0);
00653   DebugAssert((unsigned)lVar <= _vecMap.size(),"SVC_API::Deny 2");
00654   Expr e = _vecMap[lVar-1];
00655   if (e.IsNull()) return true;
00656 
00657   if (_verbosity > 2) {
00658     cout << " D " << e << endl;
00659   }
00660 
00661   d_core->addFact(d_core->assumpRule(!e));
00662 
00663   if (!IsStable()) {
00664     if (_verbosity > 1) {
00665       cout << "Condition added" << endl;
00666     }
00667     return AddConditions(lVar);
00668   }
00669   return true;
00670 }
00671 
00672 
00673 // Description: Get a vector of the assumptions used in the last proof step. //
00674 //              This is used to produce conflict clauses.                    //
00675 bool SVC_API_impl::GetConfClause(vector<int>* literals)
00676 {
00677   DebugAssert(literals->size() == 0, "Expected size = 0");
00678   vector<Expr> assumptions, expr_literals, dummy;
00679   Expr e;
00680 
00681   // TODO: Get the assumptions
00682 
00683   int numvars = _vecMap.size();
00684   _patomifier->TransformVec(assumptions, expr_literals, dummy);
00685   DebugAssert(numvars == (int)_vecMap.size(),
00686               "New vars created in conflict clause");
00687   bool invert;
00688   int var;
00689   while (!expr_literals.empty()) {
00690     e = expr_literals.back();
00691     expr_literals.pop_back();
00692     invert = false;
00693     if (e.isNot()) {
00694       e = e[0];
00695       invert = true;
00696     }
00697     DebugAssert(e.isVar(), "expected prop var");
00698     //TODO: figure out this
00699     var = (int)_pem->GetKindSpecificData(e);
00700     if (invert) var = -var;
00701     literals->push_back(var);
00702 
00703   }
00704   return true;
00705 }
00706 
00707 
00708 // Description: Check whether the context is consistent.                     //
00709 bool SVC_API_impl::IsConsistent()
00710 {
00711   bool inconsistent = !d_core->inconsistent();
00712   if (_verbosity > 2) {
00713     if (inconsistent) {
00714       cout << "Inconsistent" << endl;
00715     }
00716   }
00717   return !inconsistent;
00718 }
00719 
00720 
00721 // Description: Returns whether the variable has an associated SVC expr.     //
00722 bool SVC_API_impl::HasSVCExpr(long lVar)
00723 {
00724   DebugAssert(lVar > 0 && (unsigned)lVar <= _vecMap.size(),"");
00725   return !(_vecMap[lVar-1].IsNull());
00726 }
00727 
00728 
00729 bool SVC_API_impl::OKToSplit(long lVar)
00730 {
00731   return (HasSVCExpr(lVar) && d_vars[lVar+1].prev == _splitterCacheTag2);
00732 }
00733 
00734 
00735 // Description: Reset variable v                                             //
00736 void SVC_API_impl::ResetVariable(long v)
00737 {
00738   d_vars[++v].value = -1;
00739   d_vars[v].next = 0;
00740   d_vars[v].prev = 0;
00741 }
00742 
00743 
00744 // Description: Record each child of a propositional expression e as a fanin //
00745 //              in the d_vars vector.                                         //
00746 void SVC_API_impl::Connect(const Expr& e, long v)
00747 {
00748   int i;
00749   Expr eChild;
00750   int kind;
00751   long childID;
00752   v++;
00753   if ((int)d_vars.size() <= v) d_vars.resize(v+1);
00754   d_vars[v].kind = e.getKind();
00755   for (i=0; i < e.arity(); ++i) {
00756     eChild = e[i];
00757     kind = eChild.getKind();
00758     switch (kind) {
00759       case FALSE:
00760         childID = 0;
00761         break;
00762       case TRUE:
00763         childID = 1;
00764         break;
00765       case NOT:
00766         eChild = eChild[0];
00767         kind = eChild.getKind();
00768         //TODO:
00769         FatalAssert(kind == PROP_VAR_KIND,"Prop Var expected");
00770         childID = -((long)_pem->GetKindSpecificData(eChild, &kind))-1;
00771         break;
00772       default:
00773         Assert(kind == Prop_Var_Manager::PROP_VAR_KIND,"Prop Var expected");
00774         childID = (long)_pem->GetKindSpecificData(eChild, &kind)+1;
00775         break;
00776     }
00777     d_vars[v].fanins.push_back(childID);
00778     if (childID < 0) childID = -childID;
00779     d_vars[childID].fanouts.push_back(v);
00780   }
00781 }
00782 
00783 
00784 // Description: Connect the variable associated with eFrom to the variable   //
00785 //              associated with eTo.                                         //
00786 void SVC_API_impl::Connect1(const Expr& eFrom,
00787                             const Expr& eTo)
00788 {
00789   int kind;
00790   long idFrom, idTo;
00791   //TODO:
00792   idFrom = (long)_pem->GetKindSpecificData(eFrom, &kind)+1;
00793   idTo = (long)_pem->GetKindSpecificData(eTo, &kind)+1;
00794   if ((int)d_vars.size() <= MAX(idFrom,idTo)) d_vars.resize(MAX(idFrom,idTo)+1);
00795   d_vars[idFrom].fanouts.push_back(idTo);
00796   d_vars[idTo].fanins.push_back(idFrom);
00797   d_vars[idTo].kind = Prop_Var_Manager::PROP_VAR_KIND;
00798 }
00799 
00800 
00801 // Description: Find a splitter by calling FindSplitterRec.                  //
00802 bool SVC_API_impl::FindSplitter(long *v)
00803 {
00804   long var;
00805   int i;
00806   for (i=0; i < (int)_conditions.size(); i++) {
00807     var = _conditionVars[i]+1;
00808     if (FindSplitterRec(var, d_vars[var].value, v)) {
00809       break;
00810     }
00811   }
00812   if (i == (int)_conditions.size()) return false;
00813   (*v)--;
00814   return true;
00815 }
00816 
00817 
00818 // Description: Look for nodes in the DAG which reduce to true or false.  If //
00819 //              one is found, return it in pv with pvalue set to 1 if it     //
00820 //              reduces to true, 0 if it reduces to false.                   //
00821 void SVC_API_impl::GetImplications(long *pv, int *pvalue)
00822 {
00823   long var;
00824   int i;
00825   _splitterCacheTag2++;
00826   *pv = 0;
00827   for (i=0; i < (int)_conditions.size(); i++) {
00828     var = _conditionVars[0]+1;
00829     GetImplicationsRec(var,pv,pvalue);
00830     if (*pv != 0) {
00831       (*pv)--;
00832       return;
00833     }
00834   }
00835 }
00836 
00837 
00838 // Description: Print variable associated with lVar                          //
00839 void SVC_API_impl::PrintVar(long lVar)
00840 {
00841   Expr e = _vecMap[lVar-1];
00842   if (!e.isNull()) {
00843     cout << e;
00844   }
00845 }
00846 
00847 
00848 // Description: Print expr e with its type.                                  //
00849 void SVC_API_impl::PrintWithType(const Expr& e)
00850 {
00851   cout << e << " : " << e.getType().getExpr() << ";" << endl;
00852 }
00853 
00854 
00855 // Description: Reset and prepare to check another formula.                  //
00856 void SVC_API_impl::Reset(void)
00857 {
00858   _psatapi->Reset();
00859   _pfanout_table->clear();
00860   _vecMap.clear(); 
00861   _connectQueue.clear();
00862   _conditions.clear();
00863   _conditionVars.clear();
00864   _conditionIndex.clear();
00865   _conditionIndex.push_back(0);
00866   _patomifier->ClearTransformCache();
00867   _cnfConverter->Reset();
00868 
00869   // Reset Propositional Variable Manager and create dummy var with id 0
00870   // TODO:
00871   _ppvm->Reset();
00872   _pem->CreateExpr(Prop_Var_Manager::PROP_VAR_KIND);
00873   _ready = true;
00874 }
00875 
00876 
00877 ///////////////////////////////////////////////////////////////////////////////
00878 //                                                                           //
00879 // Function: SVC_API_impl::Ready                                             //
00880 // Author: Clark Barrett                                                     //
00881 // Created: Mon Feb 11 17:29:45 2002                                         //
00882 // Description: Return true iff ready to check another formula.              //
00883 //                                                                           //
00884 ///////////////////////////////////////////////////////////////////////////////
00885 bool SVC_API_impl::Ready(void)
00886 {
00887   return _ready;
00888 }
00889 
00890 
00891 }

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