CVC3
|
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 * 00012 * License to use, copy, modify, sell and/or distribute this software 00013 * and its documentation for any purpose is hereby granted without 00014 * royalty, subject to the terms and conditions defined in the \ref 00015 * LICENSE file provided with this distribution. 00016 * 00017 * <hr> 00018 * 00019 */ 00020 /*****************************************************************************/ 00021 00022 00023 #include <algorithm> 00024 #include "assumptions.h" 00025 00026 00027 using namespace std; 00028 using namespace CVC3; 00029 00030 00031 Assumptions Assumptions::s_empty; 00032 00033 00034 const Theorem& Assumptions::findTheorem(const Expr& e) const { 00035 static Theorem null; 00036 00037 // TRACE_MSG("assumptions", "findTheorem"); 00038 00039 const Theorem& t = find(e); 00040 if (!t.isNull()) return t; 00041 // recurse 00042 const vector<Theorem>::const_iterator aend = d_vector.end(); 00043 for (vector<Theorem>::const_iterator iter2 = d_vector.begin(); 00044 iter2 != aend; ++iter2) { 00045 if (iter2->isRefl() || !iter2->isFlagged()) { 00046 if (compare(*iter2, e) == 0) return *iter2; 00047 if (!iter2->isAssump()) { 00048 const Theorem& t = iter2->getAssumptionsRef().findTheorem(e); 00049 if (!t.isNull()) return t; 00050 } 00051 if (!iter2->isRefl()) iter2->setFlag(); 00052 } 00053 } 00054 return null; // not found 00055 } 00056 00057 00058 bool Assumptions::findExpr(const Assumptions& a, 00059 const Expr& e, vector<Theorem>& gamma) { 00060 bool found = false; 00061 const Assumptions::iterator aend = a.end(); 00062 Assumptions::iterator iter = a.begin(); 00063 for (; iter != aend; ++iter) { 00064 if (iter->isRefl()) continue; 00065 if (iter->isFlagged()) { 00066 if (iter->getCachedValue()) found = true; 00067 } 00068 else { 00069 if ((iter->getExpr() == e) || 00070 (!iter->isAssump() && 00071 findExpr(iter->getAssumptionsRef(), e, gamma))) { 00072 found = true; 00073 iter->setCachedValue(true); 00074 } 00075 else iter->setCachedValue(false); 00076 00077 iter->setFlag(); 00078 } 00079 } 00080 00081 if (found) { 00082 for (iter = a.begin(); iter != aend; ++iter) { 00083 if (iter->isRefl()) continue; 00084 if (!iter->getCachedValue()) gamma.push_back(*iter); 00085 } 00086 } 00087 00088 return found; 00089 } 00090 00091 00092 bool Assumptions::findExprs(const Assumptions& a, const vector<Expr>& es, 00093 vector<Theorem>& gamma) { 00094 bool found = false; 00095 const vector<Expr>::const_iterator esbegin = es.begin(); 00096 const vector<Expr>::const_iterator esend = es.end(); 00097 const Assumptions::iterator aend = a.end(); 00098 Assumptions::iterator iter = a.begin(); 00099 for (; iter != aend; ++iter) { 00100 if (iter->isRefl()) continue; 00101 else if (iter->isFlagged()) { 00102 if (iter->getCachedValue()) found = true; 00103 } 00104 else { 00105 // switch to binary search below? (sort es first) 00106 if ((::find(esbegin, esend, iter->getExpr()) != esend) || 00107 (!iter->isAssump() && 00108 findExprs(iter->getAssumptionsRef(), es, gamma))) { 00109 found = true; 00110 iter->setCachedValue(true); 00111 } 00112 else iter->setCachedValue(false); 00113 00114 iter->setFlag(); 00115 } 00116 } 00117 if (found) { 00118 for (iter = a.begin(); iter != aend; ++iter) { 00119 if (iter->isRefl()) continue; 00120 if (!iter->getCachedValue()) gamma.push_back(*iter); 00121 } 00122 } 00123 return found; 00124 } 00125 00126 00127 Assumptions::Assumptions(const vector<Theorem>& v) { 00128 if (v.empty()) return; 00129 d_vector.reserve(v.size()); 00130 00131 const vector<Theorem>::const_iterator iend = v.end(); 00132 vector<Theorem>::const_iterator i = v.begin(); 00133 00134 for (;i != iend; ++i) { 00135 if ((!i->getAssumptionsRef().empty())) { 00136 d_vector.push_back(*i); 00137 } 00138 } 00139 00140 if (d_vector.size() <= 1) return; 00141 sort(d_vector.begin(), d_vector.end()); 00142 vector<Theorem>::iterator newend = 00143 unique(d_vector.begin(), d_vector.end(), Theorem::TheoremEq); 00144 00145 d_vector.resize(newend - d_vector.begin()); 00146 } 00147 00148 00149 Assumptions::Assumptions(const Theorem& t1, const Theorem& t2) 00150 { 00151 00152 if (!t1.getAssumptionsRef().empty()) { 00153 if (!t2.getAssumptionsRef().empty()) { 00154 switch(compare(t1, t2)) { 00155 case -1: // t1 < t2: 00156 d_vector.push_back(t1); 00157 d_vector.push_back(t2); 00158 break; 00159 case 0: // t1 == t2: 00160 d_vector.push_back(t1); 00161 break; 00162 case 1: // t1 > t2: 00163 d_vector.push_back(t2); 00164 d_vector.push_back(t1); 00165 break; 00166 } 00167 } else d_vector.push_back(t1); 00168 } else if (!t2.getAssumptionsRef().empty()) { 00169 d_vector.push_back(t2); 00170 } 00171 00172 /* 00173 switch(compare(t1, t2)) { 00174 case -1: // t1 < t2: 00175 d_vector.push_back(t1); 00176 d_vector.push_back(t2); 00177 break; 00178 case 0: // t1 == t2: 00179 d_vector.push_back(t1); 00180 break; 00181 case 1: // t1 > t2: 00182 d_vector.push_back(t2); 00183 d_vector.push_back(t1); 00184 break; 00185 } 00186 */ 00187 } 00188 00189 00190 void Assumptions::add(const Theorem& t) 00191 { 00192 if (t.getAssumptionsRef().empty()) return; 00193 vector<Theorem>::iterator iter, iend = d_vector.end(); 00194 iter = lower_bound(d_vector.begin(), iend, t); 00195 if (iter != iend && compare(t, *iter) == 0) return; 00196 d_vector.insert(iter, t); 00197 } 00198 00199 00200 void Assumptions::add(const std::vector<Theorem>& thms) 00201 { 00202 if (thms.size() == 0) return; 00203 00204 IF_DEBUG( 00205 vector<Theorem>::const_iterator iend = thms.end(); 00206 for (vector<Theorem>::const_iterator i = thms.begin(); 00207 i != iend; ++i) { 00208 if (i+1 == iend) break; 00209 DebugAssert(compare(*i, *(i+1)) == -1, "Expected sorted"); 00210 } 00211 ) 00212 vector<Theorem> v; 00213 v.reserve(d_vector.size()+thms.size()); 00214 00215 vector<Theorem>::const_iterator i = d_vector.begin(); 00216 vector<Theorem>::const_iterator j = thms.begin(); 00217 const vector<Theorem>::const_iterator v1end = d_vector.end(); 00218 const vector<Theorem>::const_iterator v2end = thms.end(); 00219 00220 // merge 00221 while (i != v1end && j != v2end) { 00222 if (j->getAssumptionsRef().empty()) { 00223 ++j; 00224 continue; 00225 } 00226 switch(compare(*i, *j)) { 00227 case 0: 00228 // copy only 1, drop down to next case 00229 ++j; 00230 case -1: // < 00231 v.push_back(*i); 00232 ++i; 00233 break; 00234 default: // > 00235 v.push_back(*j); 00236 ++j; 00237 }; 00238 } 00239 // Push in the remaining elements 00240 for(; i != v1end; ++i) v.push_back(*i); 00241 for(; j != v2end; ++j) { 00242 if (!j->getAssumptionsRef().empty()) 00243 v.push_back(*j); 00244 } 00245 00246 d_vector.swap(v); 00247 } 00248 00249 00250 string Assumptions::toString() const { 00251 ostringstream ss; 00252 ss << (*this); 00253 return ss.str(); 00254 } 00255 00256 00257 void Assumptions::print() const 00258 { 00259 cout << toString() << endl; 00260 } 00261 00262 00263 const Theorem& Assumptions::operator[](const Expr& e) const { 00264 if (!d_vector.empty()) { 00265 d_vector.front().clearAllFlags(); 00266 } 00267 return findTheorem(e); 00268 } 00269 00270 00271 const Theorem& Assumptions::find(const Expr& e) const { 00272 static Theorem null; 00273 // binary search 00274 int lo = 0; 00275 int hi = d_vector.size() - 1; 00276 int loc; 00277 while (lo <= hi) { 00278 loc = (lo + hi) / 2; 00279 00280 switch (compare(d_vector[loc], e)) { 00281 case 0: return d_vector[loc]; 00282 case -1: // t < e 00283 lo = loc + 1; 00284 break; 00285 default: // t > e 00286 hi = loc - 1; 00287 }; 00288 } 00289 return null; 00290 } 00291 00292 00293 //////////////////////////////////////////////////////////////////// 00294 // Assumptions friend methods 00295 //////////////////////////////////////////////////////////////////// 00296 00297 00298 namespace CVC3 { 00299 00300 00301 Assumptions operator-(const Assumptions& a, const Expr& e) { 00302 if (a.begin() != a.end()) { 00303 a.begin()->clearAllFlags(); 00304 vector<Theorem> gamma; 00305 if (Assumptions::findExpr(a, e, gamma)) return Assumptions(gamma); 00306 } 00307 return a; 00308 } 00309 00310 00311 Assumptions operator-(const Assumptions& a, const vector<Expr>& es) { 00312 if (!es.empty() && a.begin() != a.end()) { 00313 a.begin()->clearAllFlags(); 00314 vector<Theorem> gamma; 00315 if (Assumptions::findExprs(a, es, gamma)) return Assumptions(gamma); 00316 } 00317 return a; 00318 } 00319 00320 00321 ostream& operator<<(ostream& os, const Assumptions &assump) { 00322 vector<Theorem>::const_iterator i = assump.d_vector.begin(); 00323 const vector<Theorem>::const_iterator iend = assump.d_vector.end(); 00324 if(i != iend) { os << i->getExpr(); i++; } 00325 for(; i != iend; i++) os << ",\n " << i->getExpr(); 00326 return os; 00327 } 00328 00329 00330 } // end of namespace CVC3