assumptions.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  *\file assumptions.cpp
00004  *\brief Implementation of class Assumptions
00005  *
00006  * Author: Clark Barrett
00007  *
00008  * Created: Thu Jan  5 06:25:52 2006
00009  *
00010  * <hr>
00011  * Copyright (C) 2006 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 
00031 #include <algorithm>
00032 #include "assumptions_value.h"
00033 
00034 
00035 using namespace std;
00036 using namespace CVCL;
00037 
00038 
00039 Assumptions::Assumptions(AssumptionsValue *v)
00040   : d_val(v) { d_val->d_refcount++; }
00041 
00042 
00043 const Theorem& Assumptions::findTheorem(const Expr& e) const {
00044   static Theorem null;
00045 
00046   TRACE_MSG("assumptions", "findTheorem");
00047   if (d_val == NULL) return null;
00048 
00049   const Theorem& t = find(e);
00050   if (!t.isNull()) return t;
00051   // recurse
00052   const vector<Theorem>::iterator aend = d_val->d_vector.end();
00053   for (vector<Theorem>::iterator iter2 = d_val->d_vector.begin(); 
00054        iter2 != aend; ++iter2) {
00055     if (!iter2->isFlagged()) {
00056       if (compare(*iter2, e) == 0) return *iter2;
00057       if (!iter2->isAssump()) {
00058         const Theorem& t = iter2->getAssumptions().findTheorem(e);
00059         if (!t.isNull()) return t;
00060       }
00061       iter2->setFlag();
00062     }
00063   }
00064   return null; // not found
00065 }
00066 
00067 
00068 bool Assumptions::findExpr(const Assumptions& a,
00069                            const Expr& e, vector<Theorem>& gamma) {
00070   bool found = false;
00071   const Assumptions::iterator aend = a.end();
00072   Assumptions::iterator iter = a.begin();
00073   for (; iter != aend; ++iter) { 
00074     if (iter->isFlagged()) {
00075       if (iter->getCachedValue()) found = true;
00076     }
00077     else {
00078       if ((iter->getExpr() == e) || 
00079           (!iter->isAssump() && 
00080            findExpr(iter->getAssumptions(), e, gamma))) {
00081         found = true;
00082         iter->setCachedValue(true);
00083       }
00084       else iter->setCachedValue(false);
00085 
00086       iter->setFlag();
00087     } 
00088   }
00089 
00090   if (found) {
00091     for (iter = a.begin(); iter != aend; ++iter) {     
00092       if (!iter->getCachedValue()) gamma.push_back(*iter);
00093     }
00094   }
00095 
00096   return found;
00097 }
00098 
00099 
00100 bool Assumptions::findExprs(const Assumptions& a, const vector<Expr>& es, 
00101                             vector<Theorem>& gamma) {
00102   bool found = false;
00103   const vector<Expr>::const_iterator esbegin = es.begin();
00104   const vector<Expr>::const_iterator esend = es.end();
00105   const Assumptions::iterator aend = a.end();
00106   Assumptions::iterator iter = a.begin();
00107   for (; iter != aend; ++iter) {
00108     if (iter->isFlagged()) {
00109       if (iter->getCachedValue()) found = true;
00110     }
00111     else {
00112       // switch to binary search below? (sort es first)
00113       if ((::find(esbegin, esend, iter->getExpr()) != esend) ||
00114           (!iter->isAssump() && 
00115            findExprs(iter->getAssumptions(), es, gamma))) {
00116         found = true;
00117         iter->setCachedValue(true);
00118       }
00119       else iter->setCachedValue(false);
00120 
00121       iter->setFlag();
00122     }
00123   }
00124   if (found) {
00125     for (iter = a.begin(); iter != aend; ++iter) {     
00126       if (!iter->getCachedValue()) gamma.push_back(*iter);
00127     }
00128   }
00129   return found;
00130 }
00131 
00132 
00133 Assumptions::Assumptions(const vector<Theorem>& v) {
00134   if (v.empty()) {
00135     d_val = NULL;
00136     return;
00137   }
00138   d_val = new AssumptionsValue(v);
00139   d_val->d_refcount++;
00140 }
00141 
00142 
00143 Assumptions::Assumptions(const Theorem& t) {
00144   vector<Theorem> v(1);
00145   v[0] = t;
00146   d_val = new AssumptionsValue(v);
00147   d_val->d_refcount++;
00148 }
00149 
00150 
00151 Assumptions::Assumptions(const Theorem& t1, const Theorem& t2) {
00152   d_val = new AssumptionsValue(t1, t2);
00153   d_val->d_refcount++;
00154 }
00155 
00156 
00157 Assumptions::~Assumptions() {
00158   DebugAssert(d_val == NULL || d_val->d_refcount > 0,
00159               "~Assumptions(): refcount = "
00160               + int2string(d_val->d_refcount));
00161   if(d_val != NULL && --(d_val->d_refcount) == 0)
00162     delete d_val;
00163 }
00164 
00165 
00166 Assumptions::Assumptions(const Assumptions &assump): d_val(assump.d_val)
00167 {
00168   DebugAssert(d_val == NULL || d_val->d_refcount > 0,
00169               "Assumptions(const Assumptions&): refcount = "
00170               + int2string(d_val->d_refcount));
00171   if(d_val != NULL) d_val->d_refcount++;
00172 }
00173 
00174 
00175 Assumptions& Assumptions::operator=(const Assumptions &assump) {
00176   // Handle self-assignment
00177   if(this == &assump) return *this;
00178   if(d_val != NULL) {
00179     DebugAssert(d_val->d_refcount > 0,
00180                 "Assumptions::operator=: OLD refcount = "
00181                 + int2string(d_val->d_refcount));                   
00182     if(--(d_val->d_refcount) == 0) delete d_val;
00183   }
00184   d_val = assump.d_val;
00185   if(d_val != NULL) {
00186     DebugAssert(d_val->d_refcount > 0,
00187                 "Assumptions::operator=: NEW refcount = "
00188                 + int2string(d_val->d_refcount));                   
00189     d_val->d_refcount++;
00190   }
00191   return *this;
00192 }
00193       
00194 
00195 void Assumptions::init() {
00196   if(isNull()) {
00197     d_val = new AssumptionsValue;
00198     d_val->d_refcount++;
00199   }
00200 }
00201 
00202 
00203 Assumptions Assumptions::copy() const {
00204   if(isNull()) return Assumptions();
00205   // Create a clean copy of the value 
00206   AssumptionsValue *v = new AssumptionsValue(*d_val);
00207   return Assumptions(v);
00208 }
00209 
00210 
00211 void Assumptions::add(const Theorem& t) {
00212   init();
00213   d_val->add(t);
00214 }
00215 
00216 
00217 void Assumptions::add(const Assumptions& a) {
00218   init();
00219   d_val->add(*a.d_val);
00220 }
00221 
00222 
00223 void Assumptions::clear() {
00224   DebugAssert(!d_val->d_const, "Can't call clear on const assumptions");
00225   d_val->d_vector.clear();
00226 }
00227 
00228 
00229 int Assumptions::size() const {
00230   if (isNull())
00231     return 0;
00232   else
00233     return d_val->d_vector.size();
00234 }
00235 
00236 
00237 bool Assumptions::empty() const
00238 {
00239   return (d_val)? d_val->d_vector.empty() : true;
00240 }
00241 
00242 
00243 bool Assumptions::isConst() const
00244 {
00245   return (d_val)? false : d_val->d_const;
00246 }
00247 
00248 
00249 void Assumptions::setConst() {
00250   static AssumptionsValue nullConst(1);
00251   if(isNull()) {
00252     d_val = &nullConst;
00253     d_val->d_refcount++;
00254   }
00255   d_val->d_const = true;
00256 }
00257 
00258 
00259 string Assumptions::toString() const {
00260   if(isNull()) return "Null";
00261   return d_val->toString();
00262 }
00263 
00264 
00265 void Assumptions::print() const
00266 {
00267   cout << toString() << endl;
00268 }
00269       
00270 
00271 const Theorem& Assumptions::operator[](const Expr& e) const {
00272   if (!isNull() && !(d_val->d_vector.empty())) {
00273     d_val->d_vector.front().clearAllFlags();
00274   }
00275   return findTheorem(e);
00276 }
00277 
00278 
00279 const Theorem& Assumptions::find(const Expr& e) const {
00280   static Theorem null;
00281   if (d_val == NULL) return null;
00282   return d_val->find(e);
00283 }
00284 
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 // Assumptions::iterator methods
00288 ////////////////////////////////////////////////////////////////////
00289 
00290 
00291 Assumptions::iterator& 
00292 Assumptions::iterator::operator++() { ++d_it; return *this; }
00293 
00294 
00295 Assumptions::iterator::Proxy
00296 Assumptions::iterator::operator++(int) { return Proxy(*(d_it++)); }
00297 
00298 
00299 Assumptions::iterator Assumptions::begin() const {
00300   DebugAssert(d_val != NULL,
00301               "Thm::Assumptions::begin(): we are Null!");
00302   return iterator(d_val->d_vector.begin());
00303 }
00304   
00305 
00306 Assumptions::iterator Assumptions::end() const {
00307   DebugAssert(d_val != NULL,
00308               "Thm::Assumptions::end(): we are Null!");
00309   return iterator(d_val->d_vector.end()); 
00310 }
00311 
00312 
00313 ////////////////////////////////////////////////////////////////////
00314 // Assumptions friend methods
00315 ////////////////////////////////////////////////////////////////////
00316 
00317 
00318 namespace CVCL {
00319 
00320 
00321 Assumptions operator-(const Assumptions& a, const Expr& e) {
00322   if (a.isNull()) return Assumptions();
00323   if (a.begin() != a.end()) {
00324     a.begin()->clearAllFlags();
00325     vector<Theorem> gamma;
00326     if (Assumptions::findExpr(a, e, gamma)) return Assumptions(gamma);
00327   } 
00328   return a.copy();
00329 }
00330 
00331 
00332 Assumptions operator-(const Assumptions& a, const vector<Expr>& es) {
00333   if (a.isNull()) return Assumptions();
00334   if (!es.empty() && a.begin() != a.end()) {
00335     a.begin()->clearAllFlags();
00336     vector<Theorem> gamma;
00337     if (Assumptions::findExprs(a, es, gamma)) return Assumptions(gamma);
00338   }
00339   return a.copy();
00340 }
00341 
00342 
00343 ostream& operator<<(ostream& os, const Assumptions &assump) {
00344   if(assump.isNull()) return os << "Null";
00345   else return os << *assump.d_val;
00346 }
00347 
00348 
00349 // comparison operators
00350 bool operator==(const Assumptions& a1, const Assumptions& a2) {
00351   if (a1.d_val == a2.d_val) return true;
00352   if (a1.d_val == NULL || a2.d_val == NULL) return false;
00353   return (*a1.d_val == *a2.d_val);
00354 }
00355 
00356 
00357 bool operator!=(const Assumptions& a1, const Assumptions& a2) { 
00358   if (a1.d_val == a2.d_val) return false;
00359   if (a1.d_val == NULL || a2.d_val == NULL) return true;
00360   return (*a1.d_val != *a2.d_val);
00361 }
00362 
00363 
00364 } // end of namespace CVCL

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