spot  1.99.8
twa.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2009, 2011, 2013, 2014, 2015, 2016 Laboratoire de
3 // Recherche et Développement de l'Epita (LRDE).
4 // Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
5 // Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
6 // Université Pierre et Marie Curie.
7 //
8 // This file is part of Spot, a model checking library.
9 //
10 // Spot is free software; you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Spot is distributed in the hope that it will be useful, but WITHOUT
16 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 // License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 
23 #pragma once
24 
25 #include <spot/twa/fwd.hh>
26 #include <spot/twa/acc.hh>
27 #include <spot/twa/bdddict.hh>
28 #include <cassert>
29 #include <memory>
30 #include <unordered_map>
31 #include <functional>
32 #include <array>
33 #include <vector>
34 #include <spot/misc/casts.hh>
35 #include <spot/misc/hash.hh>
36 #include <spot/tl/formula.hh>
37 #include <spot/misc/trival.hh>
38 
39 namespace spot
40 {
43  class SPOT_API state
44  {
45  public:
56  virtual int compare(const state* other) const = 0;
57 
77  virtual size_t hash() const = 0;
78 
80  virtual state* clone() const = 0;
81 
91  virtual void destroy() const
92  {
93  delete this;
94  }
95 
96  protected:
103  virtual ~state()
104  {
105  }
106  };
107 
121  {
122  bool
123  operator()(const state* left, const state* right) const
124  {
125  assert(left);
126  return left->compare(right) < 0;
127  }
128  };
129 
144  {
145  bool
146  operator()(const state* left, const state* right) const
147  {
148  assert(left);
149  return 0 == left->compare(right);
150  }
151  };
152 
168  {
169  size_t
170  operator()(const state* that) const
171  {
172  assert(that);
173  return that->hash();
174  }
175  };
176 
182  typedef std::unordered_set<const state*,
183  state_ptr_hash, state_ptr_equal> state_set;
184 
188  template<class val>
189  using state_map = std::unordered_map<const state*, val,
190  state_ptr_hash, state_ptr_equal>;
191 
194  class SPOT_API state_unicity_table
195  {
196  state_set m;
197  public:
198 
207  const state* operator()(const state* s)
208  {
209  auto p = m.insert(s);
210  if (!p.second)
211  s->destroy();
212  return *p.first;
213  }
214 
219  const state* is_new(const state* s)
220  {
221  auto p = m.insert(s);
222  if (!p.second)
223  {
224  s->destroy();
225  return nullptr;
226  }
227  return *p.first;
228  }
229 
231  {
232  for (state_set::iterator i = m.begin(); i != m.end();)
233  {
234  // Advance the iterator before destroying its key. This
235  // avoid issues with old g++ implementations.
236  state_set::iterator old = i++;
237  (*old)->destroy();
238  }
239  }
240 
241  size_t
242  size()
243  {
244  return m.size();
245  }
246  };
247 
248 
249 
250  // Functions related to shared_ptr.
252 
253  typedef std::shared_ptr<const state> shared_state;
254 
255  inline void shared_state_deleter(state* s) { s->destroy(); }
256 
271  {
272  bool
273  operator()(shared_state left,
274  shared_state right) const
275  {
276  assert(left);
277  return left->compare(right.get()) < 0;
278  }
279  };
280 
299  {
300  bool
301  operator()(shared_state left,
302  shared_state right) const
303  {
304  assert(left);
305  return 0 == left->compare(right.get());
306  }
307  };
308 
328  {
329  size_t
330  operator()(shared_state that) const
331  {
332  assert(that);
333  return that->hash();
334  }
335  };
336 
338  typedef std::unordered_set<shared_state,
340  state_shared_ptr_equal> shared_state_set;
341 
390  class SPOT_API twa_succ_iterator
391  {
392  public:
393  virtual
395  {
396  }
397 
400 
415  virtual bool first() = 0;
416 
427  virtual bool next() = 0;
428 
444  virtual bool done() const = 0;
445 
447 
450 
460  virtual const state* dst() const = 0;
464  virtual bdd cond() const = 0;
467  virtual acc_cond::mark_t acc() const = 0;
468 
470  };
471 
472  namespace internal
473  {
479  struct SPOT_API succ_iterator
480  {
481  protected:
482  twa_succ_iterator* it_;
483  public:
484 
486  it_(it)
487  {
488  }
489 
490  bool operator==(succ_iterator o) const
491  {
492  return it_ == o.it_;
493  }
494 
495  bool operator!=(succ_iterator o) const
496  {
497  return it_ != o.it_;
498  }
499 
500  const twa_succ_iterator* operator*() const
501  {
502  return it_;
503  }
504 
505  void operator++()
506  {
507  if (!it_->next())
508  it_ = nullptr;
509  }
510  };
511  }
512 
522 
525 
577  class SPOT_API twa: public std::enable_shared_from_this<twa>
578  {
579  protected:
580  twa(const bdd_dict_ptr& d);
584  bdd_dict_ptr dict_;
585  public:
586 
587 #ifndef SWIG
588  class succ_iterable
594  {
595  protected:
596  const twa* aut_;
597  twa_succ_iterator* it_;
598  public:
599  succ_iterable(const twa* aut, twa_succ_iterator* it)
600  : aut_(aut), it_(it)
601  {
602  }
603 
605  : aut_(other.aut_), it_(other.it_)
606  {
607  other.it_ = nullptr;
608  }
609 
610  ~succ_iterable()
611  {
612  if (it_)
613  aut_->release_iter(it_);
614  }
615 
617  {
618  return it_->first() ? it_ : nullptr;
619  }
620 
622  {
623  return nullptr;
624  }
625  };
626 #endif
627 
628  virtual ~twa();
629 
635  virtual const state* get_init_state() const = 0;
636 
644  virtual twa_succ_iterator*
645  succ_iter(const state* local_state) const = 0;
646 
647 #ifndef SWIG
648  succ_iterable
672  succ(const state* s) const
673  {
674  return {this, succ_iter(s)};
675  }
676 #endif
677 
683  {
684  if (iter_cache_)
685  delete i;
686  else
687  iter_cache_ = i;
688  }
689 
706  bdd_dict_ptr get_dict() const
707  {
708  return dict_;
709  }
710 
724  {
725  int res = dict_->has_registered_proposition(ap, this);
726  if (res < 0)
727  {
728  aps_.push_back(ap);
729  res = dict_->register_proposition(ap, this);
730  bddaps_ &= bdd_ithvar(res);
731  }
732  return res;
733  }
734 
735  int register_ap(std::string ap)
736  {
737  return register_ap(formula::ap(ap));
738  }
740 
743  const std::vector<formula>& ap() const
744  {
745  return aps_;
746  }
747 
749  bdd ap_var() const
750  {
751  return bddaps_;
752  }
753 
760  virtual std::string format_state(const state* s) const = 0;
761 
775  virtual state* project_state(const state* s,
776  const const_twa_ptr& t) const;
777 
780  const acc_cond& acc() const
781  {
782  return acc_;
783  }
784 
786  {
787  return acc_;
788  }
790 
792  virtual bool is_empty() const;
793 
794  private:
795  acc_cond acc_;
796 
797  void set_num_sets_(unsigned num)
798  {
799  if (num < acc_.num_sets())
800  {
801  acc_.~acc_cond();
802  new (&acc_) acc_cond;
803  }
804  acc_.add_sets(num - acc_.num_sets());
805  }
806 
807  public:
809  unsigned num_sets() const
810  {
811  return acc_.num_sets();
812  }
813 
816  {
817  return acc_.get_acceptance();
818  }
819 
824  void set_acceptance(unsigned num, const acc_cond::acc_code& c)
825  {
826  set_num_sets_(num);
827  acc_.set_acceptance(c);
828  if (num == 0)
829  prop_state_acc(true);
830  }
831 
833  void copy_acceptance_of(const const_twa_ptr& a)
834  {
835  acc_ = a->acc();
836  unsigned num = acc_.num_sets();
837  if (num == 0)
838  prop_state_acc(true);
839  }
840 
842  void copy_ap_of(const const_twa_ptr& a)
843  {
844  for (auto f: a->ap())
845  this->register_ap(f);
846  }
847 
860  void set_generalized_buchi(unsigned num)
861  {
862  set_num_sets_(num);
863  acc_.set_generalized_buchi();
864  if (num == 0)
865  prop_state_acc(true);
866  }
867 
884  {
885  set_generalized_buchi(1);
886  return acc_.mark(0);
887  }
888 
889  private:
890  std::vector<formula> aps_;
891  bdd bddaps_;
892 
894  struct bprop
895  {
896  trival::repr_t state_based_acc:2; // State-based acceptance.
897  trival::repr_t inherently_weak:2; // Inherently Weak automaton.
898  trival::repr_t weak:2; // Weak automaton.
899  trival::repr_t terminal:2; // Terminal automaton.
900  trival::repr_t deterministic:2; // Deterministic automaton.
901  trival::repr_t unambiguous:2; // Unambiguous automaton.
902  trival::repr_t stutter_invariant:2; // Stutter invariant language.
903  };
904  union
905  {
906  unsigned props;
907  bprop is;
908  };
909 
910 #ifndef SWIG
911  // Dynamic properties, are given with a name and a destructor function.
912  std::unordered_map<std::string,
913  std::pair<void*,
914  std::function<void(void*)>>> named_prop_;
915 #endif
916  void* get_named_prop_(std::string s) const;
917 
918  public:
919 
920 #ifndef SWIG
921  void set_named_prop(std::string s,
933  void* val, std::function<void(void*)> destructor);
934 
946  template<typename T>
947  void set_named_prop(std::string s, T* val)
948  {
949  set_named_prop(s, val, [](void *p) { delete static_cast<T*>(p); });
950  }
951 
964  template<typename T>
965  T* get_named_prop(std::string s) const
966  {
967  void* p = get_named_prop_(s);
968  if (!p)
969  return nullptr;
970  return static_cast<T*>(p);
971  }
972 #endif
973 
979  {
980  // Destroy all named properties.
981  for (auto& np: named_prop_)
982  np.second.second(np.second.first);
983  named_prop_.clear();
984  }
985 
993  {
994  return is.state_based_acc;
995  }
996 
1002  {
1003  is.state_based_acc = val.val();
1004  }
1005 
1010  trival is_sba() const
1011  {
1012  return prop_state_acc() && acc().is_buchi();
1013  }
1014 
1024  {
1025  return is.inherently_weak;
1026  }
1027 
1036  {
1037  is.inherently_weak = val.val();
1038  if (!val)
1039  is.terminal = is.weak = val.val();
1040  }
1041 
1052  {
1053  return is.terminal;
1054  }
1055 
1064  {
1065  is.terminal = val.val();
1066  if (val)
1067  is.inherently_weak = is.weak = val.val();
1068  }
1069 
1078  {
1079  return is.weak;
1080  }
1081 
1090  void prop_weak(trival val)
1091  {
1092  is.weak = val.val();
1093  if (val)
1094  is.inherently_weak = val.val();
1095  if (!val)
1096  is.terminal = val.val();
1097  }
1098 
1111  {
1112  return is.deterministic;
1113  }
1114 
1122  {
1123  is.deterministic = val.val();
1124  if (val)
1125  // deterministic implies unambiguous
1126  is.unambiguous = val.val();
1127  }
1128 
1143  {
1144  return is.unambiguous;
1145  }
1146 
1154  {
1155  is.unambiguous = val.val();
1156  if (!val)
1157  is.deterministic = val.val();
1158  }
1159 
1173  {
1174  return is.stutter_invariant;
1175  }
1176 
1179  {
1180  is.stutter_invariant = val.val();
1181  }
1182 
1216  struct prop_set
1217  {
1222 
1238  static prop_set all()
1239  {
1240  return { true, true, true, true };
1241  }
1242  };
1243 
1254  void prop_copy(const const_twa_ptr& other, prop_set p)
1255  {
1256  if (p.state_based)
1257  prop_state_acc(other->prop_state_acc());
1258  if (p.inherently_weak)
1259  {
1260  prop_terminal(other->prop_terminal());
1261  prop_weak(other->prop_weak());
1262  prop_inherently_weak(other->prop_inherently_weak());
1263  }
1264  if (p.deterministic)
1265  {
1266  prop_deterministic(other->prop_deterministic());
1267  prop_unambiguous(other->prop_unambiguous());
1268  }
1269  if (p.stutter_inv)
1270  prop_stutter_invariant(other->prop_stutter_invariant());
1271  }
1272 
1279  {
1280  if (!p.state_based)
1281  prop_state_acc(trival::maybe());
1282  if (!p.inherently_weak)
1283  {
1284  prop_terminal(trival::maybe());
1285  prop_weak(trival::maybe());
1286  prop_inherently_weak(trival::maybe());
1287  }
1288  if (!p.deterministic)
1289  {
1290  prop_deterministic(trival::maybe());
1291  prop_unambiguous(trival::maybe());
1292  }
1293  if (!p.stutter_inv)
1294  prop_stutter_invariant(trival::maybe());
1295  }
1296 
1297  };
1298 
1301 
1304 
1307 
1310 
1313 
1316 
1319 
1322 }
virtual ~state()
Destructor.
Definition: twa.hh:103
Definition: graph.hh:32
bool stutter_inv
preserve stutter invariance
Definition: twa.hh:1221
Helper structure to iterate over the successor of a state using the on-the-fly interface.
Definition: twa.hh:479
bool inherently_weak
preserve inherently weak, weak, & terminal
Definition: twa.hh:1219
An Equivalence Relation for state*.
Definition: twa.hh:143
Render state pointers unique via a hash table.
Definition: twa.hh:194
void prop_weak(trival val)
Set the weak property.
Definition: twa.hh:1090
void prop_inherently_weak(trival val)
Set the "inherently weak" proeprty.
Definition: twa.hh:1035
static formula ap(const std::string &name)
Build an atomic proposition.
Definition: formula.hh:705
twa_succ_iterator * iter_cache_
Any iterator returned via release_iter.
Definition: twa.hh:582
bdd_dict_ptr dict_
BDD dictionary used by the automaton.
Definition: twa.hh:584
trival prop_inherently_weak() const
Whether the automaton is inherently weak.
Definition: twa.hh:1023
A Transition-based ω-Automaton.
Definition: twa.hh:577
LTL/PSL formula interface.
void prop_stutter_invariant(trival val)
Set the stutter-invariant property.
Definition: twa.hh:1178
bdd ap_var() const
The set of atomic propositions as a conjunction.
Definition: twa.hh:749
acc_cond & acc()
The acceptance condition of the automaton.
Definition: twa.hh:785
Abstract class for states.
Definition: twa.hh:43
Strict Weak Ordering for shared_state (shared_ptr).
Definition: twa.hh:270
trival prop_unambiguous() const
Whether the automaton is unambiguous.
Definition: twa.hh:1142
bool deterministic
preserve deterministic and unambiguous
Definition: twa.hh:1220
trival prop_state_acc() const
Whether the automaton uses state-based acceptance.
Definition: twa.hh:992
Helper class to iterate over the successor of a state using the on-the-fly interface.
Definition: twa.hh:593
Main class for temporal logic formula.
Definition: formula.hh:578
virtual bool next()=0
Jump to the next successor (if any).
succ_iterable succ(const state *s) const
Build an iterable over the successors of s.
Definition: twa.hh:672
void set_generalized_buchi(unsigned num)
Set generalized Büchi acceptance.
Definition: twa.hh:860
void copy_acceptance_of(const const_twa_ptr &a)
Copy the acceptance condition of another TωA.
Definition: twa.hh:833
static prop_set all()
An all-true prop_set.
Definition: twa.hh:1238
virtual bool first()=0
Position the iterator on the first successor (if any).
void set_named_prop(std::string s, T *val)
Declare a named property.
Definition: twa.hh:947
void set_acceptance(unsigned num, const acc_cond::acc_code &c)
Set the acceptance condition of the automaton.
Definition: twa.hh:824
void prop_state_acc(trival val)
Set the state-based-acceptance property.
Definition: twa.hh:1001
virtual void destroy() const
Release a state.
Definition: twa.hh:91
void prop_unambiguous(trival val)
Sets the unambiguous property.
Definition: twa.hh:1153
Hash Function for shared_state (shared_ptr).
Definition: twa.hh:327
Iterate over the successors of a state.
Definition: twa.hh:390
trival prop_stutter_invariant() const
Whether the automaton is stutter-invariant.
Definition: twa.hh:1172
void release_named_properties()
Destroy all named properties.
Definition: twa.hh:978
void prop_deterministic(trival val)
Set the deterministic property.
Definition: twa.hh:1121
Definition: acc.hh:31
trival prop_terminal() const
Whether the automaton is terminal.
Definition: twa.hh:1051
const acc_cond::acc_code & get_acceptance() const
Acceptance formula used by the automaton.
Definition: twa.hh:815
trival prop_weak() const
Whether the automaton is weak.
Definition: twa.hh:1077
int register_ap(formula ap)
Register an atomic proposition designated by ap.
Definition: twa.hh:723
const state * operator()(const state *s)
Canonicalize state pointer.
Definition: twa.hh:207
void prop_terminal(trival val)
Set the terminal property.
Definition: twa.hh:1063
bool state_based
preserve state-based acceptnace
Definition: twa.hh:1218
A class implementing Kleene's three-valued logic.
Definition: trival.hh:33
void release_iter(twa_succ_iterator *i) const
Release an iterator after usage.
Definition: twa.hh:682
A structure for selecting a set of automaton properties to copy.
Definition: twa.hh:1216
const state * is_new(const state *s)
Canonicalize state pointer.
Definition: twa.hh:219
unsigned num_sets() const
Number of acceptance sets used by the automaton.
Definition: twa.hh:809
Hash Function for state*.
Definition: twa.hh:167
const acc_cond & acc() const
The acceptance condition of the automaton.
Definition: twa.hh:780
T * get_named_prop(std::string s) const
Retrieve a named property.
Definition: twa.hh:965
const std::vector< formula > & ap() const
The vector of atomic propositions registered by this automaton.
Definition: twa.hh:743
void prop_keep(prop_set p)
Keep only a subset of properties of the current automaton.
Definition: twa.hh:1278
virtual int compare(const state *other) const =0
Compares two states (that come from the same automaton).
int register_ap(std::string ap)
Register an atomic proposition designated by ap.
Definition: twa.hh:735
virtual size_t hash() const =0
Hash a state.
trival prop_deterministic() const
Whether the automaton is deterministic.
Definition: twa.hh:1110
void prop_copy(const const_twa_ptr &other, prop_set p)
Copy the properties of another automaton.
Definition: twa.hh:1254
Definition: acc.hh:300
trival is_sba() const
Whether this is a state-based Büchi automaton.
Definition: twa.hh:1010
Strict Weak Ordering for state*.
Definition: twa.hh:120
Atomic proposition.
bdd_dict_ptr get_dict() const
Get the dictionary associated to the automaton.
Definition: twa.hh:706
acc_cond::mark_t set_buchi()
Set Büchi acceptance.
Definition: twa.hh:883
Definition: acc.hh:34
void copy_ap_of(const const_twa_ptr &a)
Copy the atomic propositions of another TωA.
Definition: twa.hh:842
An Equivalence Relation for shared_state (shared_ptr).
Definition: twa.hh:298

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Thu Feb 18 2016 13:37:05 for spot by doxygen 1.8.9.1