00001 // Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6), 00002 // département Systèmes Répartis Coopératifs (SRC), Université Pierre 00003 // et Marie Curie. 00004 // 00005 // This file is part of Spot, a model checking library. 00006 // 00007 // Spot is free software; you can redistribute it and/or modify it 00008 // under the terms of the GNU General Public License as published by 00009 // the Free Software Foundation; either version 2 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // Spot is distributed in the hope that it will be useful, but WITHOUT 00013 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00014 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 00015 // License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with Spot; see the file COPYING. If not, write to the Free 00019 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00020 // 02111-1307, USA. 00021 00022 #ifndef SPOT_TGBAALGOS_EMPTINESS_STATS_HH 00023 # define SPOT_TGBAALGOS_EMPTINESS_STATS_HH 00024 00025 #include <cassert> 00026 #include <map> 00027 #include "misc/ltstr.hh" 00028 00029 namespace spot 00030 { 00031 00034 00035 struct unsigned_statistics 00036 { 00037 virtual 00038 ~unsigned_statistics() 00039 { 00040 } 00041 00042 unsigned 00043 get(const char* str) const 00044 { 00045 stats_map::const_iterator i = stats.find(str); 00046 assert(i != stats.end()); 00047 return (this->*i->second)(); 00048 } 00049 00050 typedef unsigned (unsigned_statistics::*unsigned_fun)() const; 00051 typedef std::map<const char*, unsigned_fun, char_ptr_less_than> stats_map; 00052 stats_map stats; 00053 }; 00054 00060 class unsigned_statistics_copy 00061 { 00062 public: 00063 unsigned_statistics_copy() 00064 : set(false) 00065 { 00066 } 00067 00068 unsigned_statistics_copy(const unsigned_statistics& o) 00069 : set(false) 00070 { 00071 seteq(o); 00072 } 00073 00074 bool 00075 seteq(const unsigned_statistics& o) 00076 { 00077 if (!set) 00078 { 00079 unsigned_statistics::stats_map::const_iterator i; 00080 for (i = o.stats.begin(); i != o.stats.end(); ++i) 00081 stats[i->first] = (o.*i->second)(); 00082 set = true; 00083 return true; 00084 } 00085 if (*this == o) 00086 return true; 00087 return false; 00088 } 00089 00090 typedef std::map<const char*, unsigned, char_ptr_less_than> stats_map; 00091 stats_map stats; 00092 00093 00094 bool 00095 operator==(const unsigned_statistics_copy& o) const 00096 { 00097 stats_map::const_iterator i; 00098 for (i = stats.begin(); i != stats.end(); ++i) 00099 { 00100 stats_map::const_iterator i2 = o.stats.find(i->first); 00101 if (i2 == o.stats.end()) 00102 return false; 00103 if (i->second != i2->second) 00104 return false; 00105 } 00106 return true; 00107 } 00108 00109 bool 00110 operator!=(const unsigned_statistics_copy& o) const 00111 { 00112 return !(*this == o); 00113 } 00114 00115 bool set; 00116 }; 00117 00123 class ec_statistics: public unsigned_statistics 00124 { 00125 public : 00126 ec_statistics() 00127 : states_(0), transitions_(0), depth_(0), max_depth_(0) 00128 { 00129 stats["states"] = 00130 static_cast<unsigned_statistics::unsigned_fun>(&ec_statistics::states); 00131 stats["transitions"] = 00132 static_cast<unsigned_statistics::unsigned_fun> 00133 (&ec_statistics::transitions); 00134 stats["max. depth"] = 00135 static_cast<unsigned_statistics::unsigned_fun> 00136 (&ec_statistics::max_depth); 00137 } 00138 00139 void 00140 set_states(unsigned n) 00141 { 00142 states_ = n; 00143 } 00144 00145 void 00146 inc_states() 00147 { 00148 ++states_; 00149 } 00150 00151 void 00152 inc_transitions() 00153 { 00154 ++transitions_; 00155 } 00156 00157 void 00158 inc_depth(unsigned n = 1) 00159 { 00160 depth_ += n; 00161 if (depth_ > max_depth_) 00162 max_depth_ = depth_; 00163 } 00164 00165 void 00166 dec_depth(unsigned n = 1) 00167 { 00168 assert(depth_ >= n); 00169 depth_ -= n; 00170 } 00171 00172 unsigned 00173 states() const 00174 { 00175 return states_; 00176 } 00177 00178 unsigned 00179 transitions() const 00180 { 00181 return transitions_; 00182 } 00183 00184 unsigned 00185 max_depth() const 00186 { 00187 return max_depth_; 00188 } 00189 00190 unsigned 00191 depth() const 00192 { 00193 return depth_; 00194 } 00195 00196 private : 00197 unsigned states_; 00198 unsigned transitions_; 00199 unsigned depth_; 00200 unsigned max_depth_; 00201 }; 00202 00208 class ars_statistics: public unsigned_statistics 00209 { 00210 public: 00211 ars_statistics() 00212 : prefix_states_(0), cycle_states_(0) 00213 { 00214 stats["(non unique) states for prefix"] = 00215 static_cast<unsigned_statistics::unsigned_fun> 00216 (&ars_statistics::ars_prefix_states); 00217 stats["(non unique) states for cycle"] = 00218 static_cast<unsigned_statistics::unsigned_fun> 00219 (&ars_statistics::ars_cycle_states); 00220 } 00221 00222 void 00223 inc_ars_prefix_states() 00224 { 00225 ++prefix_states_; 00226 } 00227 00228 unsigned 00229 ars_prefix_states() const 00230 { 00231 return prefix_states_; 00232 } 00233 00234 void 00235 inc_ars_cycle_states() 00236 { 00237 ++cycle_states_; 00238 } 00239 00240 unsigned 00241 ars_cycle_states() const 00242 { 00243 return cycle_states_; 00244 } 00245 00246 private: 00247 unsigned prefix_states_; 00248 unsigned cycle_states_; 00249 }; 00250 00256 class acss_statistics: public ars_statistics 00257 { 00258 public: 00259 acss_statistics() 00260 { 00261 stats["search space states"] = 00262 static_cast<unsigned_statistics::unsigned_fun> 00263 (&acss_statistics::acss_states); 00264 } 00265 00266 virtual 00267 ~acss_statistics() 00268 { 00269 } 00270 00272 virtual unsigned acss_states() const = 0; 00273 }; 00274 00275 00277 } 00278 00279 #endif // SPOT_TGBAALGOS_EMPTINESS_STATS_HH