spot  1.99.6
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
twa.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2009, 2011, 2013, 2014, 2015 Laboratoire de Recherche
3 // 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 "fwd.hh"
26 #include "acc.hh"
27 #include "bdddict.hh"
28 #include <cassert>
29 #include <memory>
30 #include <unordered_map>
31 #include <functional>
32 #include <array>
33 #include <vector>
34 #include "misc/casts.hh"
35 #include "misc/hash.hh"
36 #include "tl/formula.hh"
37 
38 namespace spot
39 {
42  class SPOT_API state
43  {
44  public:
55  virtual int compare(const state* other) const = 0;
56 
76  virtual size_t hash() const = 0;
77 
79  virtual state* clone() const = 0;
80 
90  virtual void destroy() const
91  {
92  delete this;
93  }
94 
95  protected:
100  virtual ~state()
101  {
102  }
103  };
104 
118  {
119  bool
120  operator()(const state* left, const state* right) const
121  {
122  assert(left);
123  return left->compare(right) < 0;
124  }
125  };
126 
141  {
142  bool
143  operator()(const state* left, const state* right) const
144  {
145  assert(left);
146  return 0 == left->compare(right);
147  }
148  };
149 
165  {
166  size_t
167  operator()(const state* that) const
168  {
169  assert(that);
170  return that->hash();
171  }
172  };
173 
174  typedef std::unordered_set<const state*,
175  state_ptr_hash, state_ptr_equal> state_set;
176 
177 
180  class SPOT_API state_unicity_table
181  {
182  state_set m;
183  public:
184 
193  const state* operator()(const state* s)
194  {
195  auto p = m.insert(s);
196  if (!p.second)
197  s->destroy();
198  return *p.first;
199  }
200 
205  const state* is_new(const state* s)
206  {
207  auto p = m.insert(s);
208  if (!p.second)
209  {
210  s->destroy();
211  return nullptr;
212  }
213  return *p.first;
214  }
215 
217  {
218  for (state_set::iterator i = m.begin(); i != m.end();)
219  {
220  // Advance the iterator before destroying its key. This
221  // avoid issues with old g++ implementations.
222  state_set::iterator old = i++;
223  (*old)->destroy();
224  }
225  }
226 
227  size_t
228  size()
229  {
230  return m.size();
231  }
232  };
233 
234 
235 
236  // Functions related to shared_ptr.
238 
239  typedef std::shared_ptr<const state> shared_state;
240 
241  inline void shared_state_deleter(state* s) { s->destroy(); }
242 
257  {
258  bool
259  operator()(shared_state left,
260  shared_state right) const
261  {
262  assert(left);
263  return left->compare(right.get()) < 0;
264  }
265  };
266 
283  {
284  bool
285  operator()(shared_state left,
286  shared_state right) const
287  {
288  assert(left);
289  return 0 == left->compare(right.get());
290  }
291  };
292 
310  {
311  size_t
312  operator()(shared_state that) const
313  {
314  assert(that);
315  return that->hash();
316  }
317  };
318 
319  typedef std::unordered_set<shared_state,
321  state_shared_ptr_equal> shared_state_set;
322 
331  class SPOT_API twa_succ_iterator
332  {
333  public:
334  virtual
336  {
337  }
338 
340 
341 
353  virtual bool first() = 0;
354 
361  virtual bool next() = 0;
362 
372  virtual bool done() const = 0;
373 
375 
377 
378 
388  virtual const state* dst() const = 0;
392  virtual bdd cond() const = 0;
395  virtual acc_cond::mark_t acc() const = 0;
396 
398  };
399 
400  namespace internal
401  {
402  struct SPOT_API succ_iterator
403  {
404  protected:
405  twa_succ_iterator* it_;
406  public:
407 
409  it_(it)
410  {
411  }
412 
413  bool operator==(succ_iterator o) const
414  {
415  return it_ == o.it_;
416  }
417 
418  bool operator!=(succ_iterator o) const
419  {
420  return it_ != o.it_;
421  }
422 
423  const twa_succ_iterator* operator*() const
424  {
425  return it_;
426  }
427 
428  void operator++()
429  {
430  if (!it_->next())
431  it_ = nullptr;
432  }
433  };
434  }
435 
445 
448 
482  class SPOT_API twa: public std::enable_shared_from_this<twa>
483  {
484  protected:
485  twa(const bdd_dict_ptr& d);
486  // Any iterator returned via release_iter.
487  mutable twa_succ_iterator* iter_cache_;
488  bdd_dict_ptr dict_;
489  public:
490 
491 #ifndef SWIG
493  {
494  protected:
495  const twa* aut_;
496  twa_succ_iterator* it_;
497  public:
498  succ_iterable(const twa* aut, twa_succ_iterator* it)
499  : aut_(aut), it_(it)
500  {
501  }
502 
504  : aut_(other.aut_), it_(other.it_)
505  {
506  other.it_ = nullptr;
507  }
508 
509  ~succ_iterable()
510  {
511  if (it_)
512  aut_->release_iter(it_);
513  }
514 
516  {
517  return it_->first() ? it_ : nullptr;
518  }
519 
521  {
522  return nullptr;
523  }
524  };
525 #endif
526 
527  virtual ~twa();
528 
534  virtual const state* get_init_state() const = 0;
535 
541  virtual twa_succ_iterator*
542  succ_iter(const state* local_state) const = 0;
543 
544 #ifndef SWIG
550  succ(const state* s) const
551  {
552  return {this, succ_iter(s)};
553  }
554 #endif
555 
560  void release_iter(twa_succ_iterator* i) const
561  {
562  if (iter_cache_)
563  delete i;
564  else
565  iter_cache_ = i;
566  }
567 
581  bdd support_conditions(const state* state) const;
582 
590  bdd_dict_ptr get_dict() const
591  {
592  return dict_;
593  }
594 
598  int register_ap(formula ap)
599  {
600  aps_.push_back(ap);
601  int res = dict_->register_proposition(ap, this);
602  bddaps_ &= bdd_ithvar(res);
603  return res;
604  }
605 
609  int register_ap(std::string name)
610  {
611  return register_ap(formula::ap(name));
612  }
613 
616  const std::vector<formula>& ap() const
617  {
618  return aps_;
619  }
620 
621  bdd ap_var() const
622  {
623  return bddaps_;
624  }
625 
630  virtual std::string format_state(const state* state) const = 0;
631 
648  virtual std::string
649  transition_annotation(const twa_succ_iterator* t) const;
650 
664  virtual state* project_state(const state* s,
665  const const_twa_ptr& t) const;
666 
667 
668  const acc_cond& acc() const
669  {
670  return acc_;
671  }
672 
673  acc_cond& acc()
674  {
675  return acc_;
676  }
677 
678  virtual bool is_empty() const;
679 
680  protected:
681  acc_cond acc_;
682 
683  void set_num_sets_(unsigned num)
684  {
685  if (num < acc_.num_sets())
686  {
687  acc_.~acc_cond();
688  new (&acc_) acc_cond;
689  }
690  acc_.add_sets(num - acc_.num_sets());
691  }
692 
693  public:
694  unsigned num_sets() const
695  {
696  return acc_.num_sets();
697  }
698 
699  const acc_cond::acc_code& get_acceptance() const
700  {
701  return acc_.get_acceptance();
702  }
703 
704  void set_acceptance(unsigned num, const acc_cond::acc_code& c)
705  {
706  set_num_sets_(num);
707  acc_.set_acceptance(c);
708  if (num == 0)
709  prop_state_acc(true);
710  }
711 
713  void copy_acceptance_of(const const_twa_ptr& a)
714  {
715  acc_ = a->acc();
716  unsigned num = acc_.num_sets();
717  if (num == 0)
718  prop_state_acc(true);
719  }
720 
721  void copy_ap_of(const const_twa_ptr& a)
722  {
723  get_dict()->register_all_propositions_of(a, this);
724  for (auto f: a->ap())
725  this->register_ap(f);
726  }
727 
728  void set_generalized_buchi(unsigned num)
729  {
730  set_num_sets_(num);
731  acc_.set_generalized_buchi();
732  if (num == 0)
733  prop_state_acc(true);
734  }
735 
736  acc_cond::mark_t set_buchi()
737  {
738  set_generalized_buchi(1);
739  return acc_.mark(0);
740  }
741 
742  protected:
744  virtual bdd compute_support_conditions(const state* state) const = 0;
745  mutable const state* last_support_conditions_input_;
746  private:
747  mutable bdd last_support_conditions_output_;
748  std::vector<formula> aps_;
749  bdd bddaps_;
750 
751  protected:
752 
753  // Boolean properties. Beware: true means that the property
754  // holds, but false means the property is unknown.
755  struct bprop
756  {
757  bool state_based_acc:1; // State-based acceptance.
758  bool inherently_weak:1; // Inherently Weak automaton.
759  bool weak:1; // Weak automaton.
760  bool terminal:1; // Terminal automaton.
761  bool deterministic:1; // Deterministic automaton.
762  bool unambiguous:1; // Unambiguous automaton.
763  bool stutter_invariant:1; // Stutter invariant language.
764  bool stutter_sensitive:1; // Stutter sensitive language.
765  };
766  union
767  {
768  unsigned props;
769  bprop is;
770  };
771 
772 #ifndef SWIG
773  // Dynamic properties, are given with a name and a destructor function.
774  std::unordered_map<std::string,
775  std::pair<void*,
776  std::function<void(void*)>>> named_prop_;
777 #endif
778  void* get_named_prop_(std::string s) const;
779 
780  public:
781 
782 #ifndef SWIG
783  void set_named_prop(std::string s,
784  void* val, std::function<void(void*)> destructor);
785 
786  template<typename T>
787  void set_named_prop(std::string s, T* val)
788  {
789  set_named_prop(s, val, [](void *p) { delete static_cast<T*>(p); });
790  }
791 
792  template<typename T>
793  T* get_named_prop(std::string s) const
794  {
795  void* p = get_named_prop_(s);
796  if (!p)
797  return nullptr;
798  return static_cast<T*>(p);
799  }
800 #endif
801 
802  void release_named_properties()
803  {
804  // Destroy all named properties.
805  for (auto& np: named_prop_)
806  np.second.second(np.second.first);
807  named_prop_.clear();
808  }
809 
810  bool prop_state_acc() const
811  {
812  return is.state_based_acc;
813  }
814 
815  void prop_state_acc(bool val)
816  {
817  is.state_based_acc = val;
818  }
819 
820  bool is_sba() const
821  {
822  return prop_state_acc() && acc().is_buchi();
823  }
824 
825  bool prop_inherently_weak() const
826  {
827  return is.inherently_weak;
828  }
829 
830  void prop_inherently_weak(bool val)
831  {
832  is.inherently_weak = val;
833  }
834 
835  bool prop_terminal() const
836  {
837  return is.terminal;
838  }
839 
840  void prop_terminal(bool val)
841  {
842  if (val)
843  is.inherently_weak = is.weak = is.terminal = true;
844  else
845  is.terminal = false;
846  }
847 
848  bool prop_weak() const
849  {
850  return is.weak;
851  }
852 
853  void prop_weak(bool val)
854  {
855  if (val)
856  is.inherently_weak = is.weak = true;
857  else
858  is.weak = false;
859  }
860 
861  bool prop_deterministic() const
862  {
863  return is.deterministic;
864  }
865 
866  void prop_deterministic(bool val)
867  {
868  if (val)
869  {
870  // deterministic implies unambiguous
871  is.deterministic = true;
872  is.unambiguous = true;
873  }
874  else
875  {
876  is.deterministic = false;
877  }
878  }
879 
880  bool prop_unambiguous() const
881  {
882  return is.unambiguous;
883  }
884 
885  void prop_unambiguous(bool val)
886  {
887  is.unambiguous = val;
888  }
889 
890  bool prop_stutter_invariant() const
891  {
892  return is.stutter_invariant;
893  }
894 
895  bool prop_stutter_sensitive() const
896  {
897  return is.stutter_sensitive;
898  }
899 
900  void prop_stutter_invariant(bool val)
901  {
902  is.stutter_invariant = val;
903  }
904 
905  void prop_stutter_sensitive(bool val)
906  {
907  is.stutter_sensitive = val;
908  }
909 
910  struct prop_set
911  {
912  bool state_based;
913  bool inherently_weak; // and weak
914  bool deterministic; // and unambiguous
915  bool stutter_inv; // and stutter_sensitive
916 
917  static prop_set all()
918  {
919  return { true, true, true, true };
920  }
921  };
922 
923  // There is no default value here on purpose. This way any time we
924  // add a new property we have to update every call to prop_copy().
925  void prop_copy(const const_twa_ptr& other, prop_set p)
926  {
927  if (p.state_based)
928  prop_state_acc(other->prop_state_acc());
929  if (p.inherently_weak)
930  {
931  prop_terminal(other->prop_terminal());
932  prop_weak(other->prop_weak());
933  prop_inherently_weak(other->prop_inherently_weak());
934  }
935  if (p.deterministic)
936  {
937  prop_deterministic(other->prop_deterministic());
938  prop_unambiguous(other->prop_unambiguous());
939  }
940  if (p.stutter_inv)
941  {
942  prop_stutter_invariant(other->prop_stutter_invariant());
943  prop_stutter_sensitive(other->prop_stutter_sensitive());
944  }
945  }
946 
947  void prop_keep(prop_set p)
948  {
949  if (!p.state_based)
950  prop_state_acc(false);
951  if (!p.inherently_weak)
952  {
953  prop_terminal(false);
954  prop_weak(false);
955  prop_inherently_weak(false);
956  }
957  if (!p.deterministic)
958  {
959  prop_deterministic(false);
960  prop_unambiguous(false);
961  }
962  if (!p.stutter_inv)
963  {
964  prop_stutter_invariant(false);
965  prop_stutter_sensitive(false);
966  }
967  }
968 
969  };
970 
973 
976 
979 
982 
985 
988 
991 
994 }
virtual ~state()
Destructor.
Definition: twa.hh:100
Definition: graph.hh:32
Definition: twa.hh:755
Definition: twa.hh:402
An Equivalence Relation for state*.
Definition: twa.hh:140
Render state pointers unique via a hash table.
Definition: twa.hh:180
static formula ap(const std::string &name)
Build an atomic proposition.
Definition: formula.hh:705
A Transition-based ω-Automaton.
Definition: twa.hh:482
LTL/PSL formula interface.
Abstract class for states.
Definition: twa.hh:42
Strict Weak Ordering for shared_state (shared_ptr).
Definition: twa.hh:256
Definition: twa.hh:492
Definition: twa.hh:910
virtual bool next()=0
Jump to the next successor (if any).
virtual bool first()=0
Position the iterator on the first successor (if any).
virtual void destroy() const
Release a state.
Definition: twa.hh:90
Hash Function for shared_state (shared_ptr).
Definition: twa.hh:309
Iterate over the successors of a state.
Definition: twa.hh:331
const state * operator()(const state *s)
Canonicalize state pointer.
Definition: twa.hh:193
const state * is_new(const state *s)
Canonicalize state pointer.
Definition: twa.hh:205
Hash Function for state*.
Definition: twa.hh:164
virtual int compare(const state *other) const =0
Compares two states (that come from the same automaton).
virtual size_t hash() const =0
Hash a state.
Strict Weak Ordering for state*.
Definition: twa.hh:117
Atomic proposition.
Definition: acc.hh:34
An Equivalence Relation for shared_state (shared_ptr).
Definition: twa.hh:282

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Dec 4 2015 07:31:52 for spot by doxygen 1.8.8