spot
0.9.1
|
00001 // -*- coding: utf-8 -*- 00002 // Copyright (C) 2008, 2009, 2010, 2011, 2012 Laboratoire de Recherche 00003 // et Développement de l'Epita (LRDE). 00004 // Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de 00005 // 00006 // This file is part of Spot, a model checking library. 00007 // 00008 // Spot is free software; you can redistribute it and/or modify it 00009 // under the terms of the GNU General Public License as published by 00010 // the Free Software Foundation; either version 2 of the License, or 00011 // (at your option) any later version. 00012 // 00013 // Spot is distributed in the hope that it will be useful, but WITHOUT 00014 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00015 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 00016 // License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with Spot; see the file COPYING. If not, write to the Free 00020 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00021 // 02111-1307, USA. 00022 00025 #ifndef SPOT_LTLAST_FORMULA_HH 00026 # define SPOT_LTLAST_FORMULA_HH 00027 00028 #include <string> 00029 #include <cassert> 00030 #include "predecl.hh" 00031 #include <list> 00032 00033 namespace spot 00034 { 00035 namespace ltl 00036 { 00040 00043 00046 00050 00053 00056 00059 00062 00065 00066 00073 class formula 00074 { 00075 public: 00077 enum opkind { Constant, 00078 AtomicProp, 00079 UnOp, 00080 BinOp, 00081 MultOp, 00082 BUnOp, 00083 AutomatOp }; 00084 00085 protected: 00086 formula(opkind k) : count_(max_count++), kind_(k) 00087 { 00088 // If the counter of formulae ever loops, we want to skip the 00089 // first three values, because they are permanently associated 00090 // to constants, and it is convenient to have constants smaller 00091 // than all other formulae. 00092 if (max_count == 0) 00093 max_count = 3; 00094 } 00095 00096 public: 00098 virtual void accept(visitor& v) const = 0; 00099 00104 const formula* clone() const; 00109 void destroy() const; 00110 00112 virtual std::string dump() const = 0; 00113 00115 opkind kind() const 00116 { 00117 return kind_; 00118 } 00119 00121 // Properties // 00123 00125 bool is_boolean() const 00126 { 00127 return is.boolean; 00128 } 00129 00131 bool is_sugar_free_boolean() const 00132 { 00133 return is.sugar_free_boolean; 00134 } 00135 00140 bool is_in_nenoform() const 00141 { 00142 return is.in_nenoform; 00143 } 00144 00146 bool is_X_free() const 00147 { 00148 return is.X_free; 00149 } 00150 00152 bool is_sugar_free_ltl() const 00153 { 00154 return is.sugar_free_ltl; 00155 } 00156 00158 bool is_ltl_formula() const 00159 { 00160 return is.ltl_formula; 00161 } 00162 00164 bool is_eltl_formula() const 00165 { 00166 return is.eltl_formula; 00167 } 00168 00170 bool is_psl_formula() const 00171 { 00172 return is.psl_formula; 00173 } 00174 00176 bool is_sere_formula() const 00177 { 00178 return is.sere_formula; 00179 } 00180 00183 bool is_finite() const 00184 { 00185 return is.finite; 00186 } 00187 00208 bool is_eventual() const 00209 { 00210 return is.eventual; 00211 } 00212 00233 bool is_universal() const 00234 { 00235 return is.universal; 00236 } 00237 00239 bool is_syntactic_safety() const 00240 { 00241 return is.syntactic_safety; 00242 } 00243 00245 bool is_syntactic_guarantee() const 00246 { 00247 return is.syntactic_guarantee; 00248 } 00249 00251 bool is_syntactic_obligation() const 00252 { 00253 return is.syntactic_obligation; 00254 } 00255 00257 bool is_syntactic_recurrence() const 00258 { 00259 return is.syntactic_recurrence; 00260 } 00261 00263 bool is_syntactic_persistence() const 00264 { 00265 return is.syntactic_persistence; 00266 } 00267 00269 bool is_marked() const 00270 { 00271 return !is.not_marked; 00272 } 00273 00275 bool accepts_eword() const 00276 { 00277 return is.accepting_eword; 00278 } 00279 00281 unsigned get_props() const 00282 { 00283 return props; 00284 } 00285 00287 size_t 00288 hash() const 00289 { 00290 return count_; 00291 } 00292 protected: 00293 virtual ~formula(); 00294 00296 virtual void ref_() const; 00299 virtual bool unref_() const; 00300 00302 size_t count_; 00303 00304 struct ltl_prop 00305 { 00306 // All properties here should be expressed in such a a way 00307 // that property(f && g) is just property(f)&property(g). 00308 // This allows us to compute all properties of a compound 00309 // formula in one operation. 00310 // 00311 // For instance we do not use a property that says "has 00312 // temporal operator", because it would require an OR between 00313 // the two arguments. Instead we have a property that 00314 // says "no temporal operator", and that one is computed 00315 // with an AND between the arguments. 00316 // 00317 // Also choose a name that makes sense when prefixed with 00318 // "the formula is". 00319 bool boolean:1; // No temporal operators. 00320 bool sugar_free_boolean:1; // Only AND, OR, and NOT operators. 00321 bool in_nenoform:1; // Negative Normal Form. 00322 bool X_free:1; // No X operators. 00323 bool sugar_free_ltl:1; // No F and G operators. 00324 bool ltl_formula:1; // Only LTL operators. 00325 bool eltl_formula:1; // Only ELTL operators. 00326 bool psl_formula:1; // Only PSL operators. 00327 bool sere_formula:1; // Only SERE operators. 00328 bool finite:1; // Finite SERE formulae, or Bool+X forms. 00329 bool eventual:1; // Purely eventual formula. 00330 bool universal:1; // Purely universal formula. 00331 bool syntactic_safety:1; // Syntactic Safety Property. 00332 bool syntactic_guarantee:1; // Syntactic Guarantee Property. 00333 bool syntactic_obligation:1; // Syntactic Obligation Property. 00334 bool syntactic_recurrence:1; // Syntactic Recurrence Property. 00335 bool syntactic_persistence:1; // Syntactic Persistence Property. 00336 bool not_marked:1; // No occurrence of EConcatMarked. 00337 bool accepting_eword:1; // Accepts the empty word. 00338 }; 00339 union 00340 { 00341 // Use an unsigned for fast computation of all properties. 00342 unsigned props; 00343 ltl_prop is; 00344 }; 00345 00346 private: 00348 static size_t max_count; 00349 opkind kind_; 00350 }; 00351 00365 struct formula_ptr_less_than: 00366 public std::binary_function<const formula*, const formula*, bool> 00367 { 00368 bool 00369 operator()(const formula* left, const formula* right) const 00370 { 00371 assert(left); 00372 assert(right); 00373 if (left == right) 00374 return false; 00375 size_t l = left->hash(); 00376 size_t r = right->hash(); 00377 if (l != r) 00378 return l < r; 00379 // Because the hash code assigned to each formula is the 00380 // number of formulae constructed so far, it is very unlikely 00381 // that we will ever reach a case were two different formulae 00382 // have the same hash. This will happen only ever with have 00383 // produced 256**sizeof(size_t) formulae (i.e. max_count has 00384 // looped back to 0 and started over). In that case we can 00385 // order two formulae by looking at their text representation. 00386 // We could be more efficient and look at their AST, but it's 00387 // not worth the burden. (Also ordering pointers is ruled out 00388 // because it breaks the determinism of the implementation.) 00389 return left->dump() < right->dump(); 00390 } 00391 }; 00392 00407 struct formula_ptr_hash: 00408 public std::unary_function<const formula*, size_t> 00409 { 00410 size_t 00411 operator()(const formula* that) const 00412 { 00413 assert(that); 00414 return that->hash(); 00415 } 00416 }; 00417 00419 std::ostream& print_formula_props(std::ostream& out, 00420 const formula* f, 00421 bool abbreviated = false); 00422 00424 std::list<std::string> list_formula_props(const formula* f); 00425 } 00426 } 00427 00428 #endif // SPOT_LTLAST_FORMULA_HH