PPL  0.12.1
Ask_Tell.inlines.hh
Go to the documentation of this file.
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)