|
PPL
0.12.1
|
00001 /* Ask_Tell class implementation: inline functions. 00002 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 00003 Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com) 00004 00005 This file is part of the Parma Polyhedra Library (PPL). 00006 00007 The PPL is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 The PPL is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00020 00021 For the most up-to-date information see the Parma Polyhedra Library 00022 site: http://bugseng.com/products/ppl/ . */ 00023 00024 #ifndef PPL_Ask_Tell_inlines_hh 00025 #define PPL_Ask_Tell_inlines_hh 1 00026 00027 #include <algorithm> 00028 #include "assert.hh" 00029 00030 // Temporary!!! 00031 #include <iostream> 00032 00033 namespace Parma_Polyhedra_Library { 00034 00035 template <typename D> 00036 Ask_Tell_Pair<D>::Ask_Tell_Pair(const D& ask, const D& tell) 00037 : a(ask), t(tell) { 00038 } 00039 00040 template <typename D> 00041 const D& 00042 Ask_Tell_Pair<D>::ask() const { 00043 return a; 00044 } 00045 00046 template <typename D> 00047 D& 00048 Ask_Tell_Pair<D>::ask() { 00049 return a; 00050 } 00051 00052 template <typename D> 00053 const D& 00054 Ask_Tell_Pair<D>::tell() const { 00055 return t; 00056 } 00057 00058 template <typename D> 00059 D& 00060 Ask_Tell_Pair<D>::tell() { 00061 return t; 00062 } 00063 00064 template <typename D> 00065 bool 00066 Ask_Tell_Pair<D>::definitely_entails(const Ask_Tell_Pair& y) const { 00067 const Ask_Tell_Pair<D>& x = *this; 00068 const D& x_ask = x.ask(); 00069 const D& x_tell = x.tell(); 00070 const D& y_ask = y.ask(); 00071 const D& y_tell = y.tell(); 00072 if (!y_ask.definitely_entails(x_ask)) 00073 return false; 00074 else if (x_tell.definitely_entails(y_tell)) 00075 return true; 00076 // The following test can be omitted. 00077 else if (x_tell.definitely_entails(y_ask)) 00078 return false; 00079 else { 00080 D x_tell_y_ask = x_tell; 00081 x_tell_y_ask.meet_assign(y_ask); 00082 return x_tell_y_ask.definitely_entails(y_tell); 00083 } 00084 } 00085 00086 template <typename D> 00087 Ask_Tell<D>::Ask_Tell() 00088 : sequence(), normalized(true) { 00089 } 00090 00091 template <typename D> 00092 Ask_Tell<D>::Ask_Tell(const Ask_Tell& y) 00093 : sequence(y.sequence), normalized(y.normalized) { 00094 } 00095 00096 template <typename D> 00097 Ask_Tell<D>::Ask_Tell(const D& ask, const D& tell) 00098 : sequence(), normalized(true) { 00099 if (!tell.is_top()) 00100 pair_insert(ask, tell); 00101 } 00102 00103 template <typename D> 00104 inline 00105 Ask_Tell<D>::~Ask_Tell() { 00106 } 00107 00108 template <typename D> 00109 Ask_Tell<D>& 00110 Ask_Tell<D>::operator=(const Ask_Tell& y) { 00111 sequence = y.sequence; 00112 normalized = y.normalized; 00113 return *this; 00114 } 00115 00116 template <typename D> 00117 inline void 00118 Ask_Tell<D>::m_swap(Ask_Tell& y) { 00119 swap(sequence, y.sequence); 00120 swap(normalized, y.normalized); 00121 } 00122 00123 template <typename D> 00124 typename Ask_Tell<D>::iterator 00125 Ask_Tell<D>::begin() { 00126 return sequence.begin(); 00127 } 00128 00129 template <typename D> 00130 typename Ask_Tell<D>::const_iterator 00131 Ask_Tell<D>::begin() const { 00132 return sequence.begin(); 00133 } 00134 00135 template <typename D> 00136 typename Ask_Tell<D>::iterator 00137 Ask_Tell<D>::end() { 00138 return sequence.end(); 00139 } 00140 00141 template <typename D> 00142 typename Ask_Tell<D>::const_iterator 00143 Ask_Tell<D>::end() const { 00144 return sequence.end(); 00145 } 00146 00147 template <typename D> 00148 typename Ask_Tell<D>::reverse_iterator 00149 Ask_Tell<D>::rbegin() { 00150 return sequence.rbegin(); 00151 } 00152 00153 template <typename D> 00154 typename Ask_Tell<D>::const_reverse_iterator 00155 Ask_Tell<D>::rbegin() const { 00156 return sequence.rbegin(); 00157 } 00158 00159 template <typename D> 00160 typename Ask_Tell<D>::reverse_iterator 00161 Ask_Tell<D>::rend() { 00162 return sequence.rend(); 00163 } 00164 00165 template <typename D> 00166 typename Ask_Tell<D>::const_reverse_iterator 00167 Ask_Tell<D>::rend() const { 00168 return sequence.rend(); 00169 } 00170 00171 template <typename D> 00172 typename Ask_Tell<D>::size_type 00173 Ask_Tell<D>::size() const { 00174 return sequence.size(); 00175 } 00176 00177 template <typename D> 00178 void 00179 Ask_Tell<D>::pair_insert_good(const D& ask, const D& tell) { 00180 PPL_ASSERT_HEAVY(!ask.definitely_entails(tell)); 00181 sequence.push_back(Ask_Tell_Pair<D>(ask, tell)); 00182 normalized = false; 00183 } 00184 00185 template <typename D> 00186 void 00187 Ask_Tell<D>::pair_insert(const D& ask, const D& tell) { 00188 if (tell.definitely_entails(ask)) 00189 pair_insert_good(ask, tell); 00190 else { 00191 D new_tell = tell; 00192 new_tell.meet_assign(ask); 00193 pair_insert_good(ask, new_tell); 00194 } 00195 } 00196 00197 template <typename D> 00198 void 00199 Ask_Tell<D>::normalize() const { 00200 if (normalized) 00201 return; 00202 00203 Ask_Tell& x = const_cast<Ask_Tell&>(*this); 00204 x.reduce(); 00205 x.deduce(); 00206 x.absorb(); 00207 normalized = true; 00208 00209 PPL_ASSERT_HEAVY(OK()); 00210 } 00211 00212 template <typename D> 00213 bool 00214 Ask_Tell<D>::is_normalized() const { 00215 if (!normalized && check_normalized()) 00216 normalized = true; 00217 return normalized; 00218 } 00219 00220 template <typename D> 00221 bool 00222 Ask_Tell<D>::definitely_entails(const Ask_Tell& y) const { 00223 const Ask_Tell<D>& x = *this; 00224 x.normalize(); 00225 y.normalize(); 00226 bool found = true; 00227 for (const_iterator x_begin = x.begin(), x_end = x.end(), y_end = y.end(), 00228 yi = y.begin(); found && yi != y_end; ++yi) { 00229 found = false; 00230 for (const_iterator xi = x_begin; !found && xi != x_end; ++xi) 00231 found = xi->definitely_entails(*yi); 00232 } 00233 return found; 00234 } 00235 00236 template <typename D> 00237 Ask_Tell<D>& 00238 Ask_Tell<D>::add_pair(const D& ask, const D& tell) { 00239 if (!ask.definitely_entails(tell)) 00240 pair_insert(ask, tell); 00241 PPL_ASSERT_HEAVY(OK()); 00242 return *this; 00243 } 00244 00246 template <typename D> 00247 inline 00248 bool operator==(const Ask_Tell<D>& x, const Ask_Tell<D>& y) { 00249 return x.definitely_entails(y) && y.definitely_entails(x); 00250 } 00251 00253 template <typename D> 00254 inline 00255 bool operator!=(const Ask_Tell<D>& x, const Ask_Tell<D>& y) { 00256 return !(x == y); 00257 } 00258 00259 template <typename D> 00260 bool 00261 Ask_Tell<D>::is_top() const { 00262 return sequence.empty(); 00263 } 00264 00265 template <typename D> 00266 bool 00267 Ask_Tell<D>::is_bottom() const { 00268 // Must normalize for correctness. 00269 const_iterator xi = begin(); 00270 const_iterator x_end = end(); 00271 return xi != x_end 00272 && xi->ask().is_top() && xi->tell().is_bottom() 00273 && ++xi == x_end; 00274 } 00275 00276 template <typename D> 00277 bool 00278 Ask_Tell<D>::empty() const { 00279 return sequence.empty(); 00280 } 00281 00282 template <typename D> 00283 void 00284 Ask_Tell<D>::meet_assign(const Ask_Tell& y) { 00285 if (!y.empty()) { 00286 std::copy(y.begin(), y.end(), back_inserter(sequence)); 00287 normalized = false; 00288 } 00289 PPL_ASSERT_HEAVY(OK()); 00290 } 00291 00292 // Hiding 00293 00294 template <typename D> 00295 bool 00296 Ask_Tell<D>::probe(const D& tell, const D& ask) const { 00297 const_iterator yi; 00298 bool tell_changed; 00299 00300 D xtell(tell); 00301 tell_changed = true; 00302 while (tell_changed) { 00303 tell_changed = false; 00304 for (yi = begin(); yi != end(); ++yi) { 00305 if (xtell.definitely_entails(yi->ask()) 00306 && !xtell.definitely_entails(yi->tell())) { 00307 xtell.meet_assign(yi->tell()); 00308 if (xtell.definitely_entails(ask)) 00309 return true; 00310 tell_changed = true; 00311 } 00312 } 00313 } 00314 return false; 00315 } 00316 00318 template <typename D> 00319 inline void 00320 swap(Ask_Tell<D>& x, Ask_Tell<D>& y) { 00321 x.m_swap(y); 00322 } 00323 00324 } // namespace Parma_Polyhedra_Library 00325 00326 #endif // !defined(PPL_Ask_Tell_inlines_hh)