spot  2.3.3.dev
reachability.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2015, 2016 Laboratoire de Recherche et
3 // Developpement de l'Epita
4 //
5 // This file is part of Spot, a model checking library.
6 //
7 // Spot is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // Spot is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20 #pragma once
21 
22 #include <functional>
23 #include <spot/kripke/kripke.hh>
24 
25 namespace spot
26 {
30  template<typename State, typename SuccIterator,
31  typename StateHash, typename StateEqual,
32  typename Visitor>
33  class SPOT_API seq_reach_kripke
34  {
35  public:
37  bool& stop):
38  sys_(sys), tid_(tid), stop_(stop)
39  {
40  SPOT_ASSERT(is_a_kripkecube(sys));
41  visited.reserve(2000000);
42  todo.reserve(100000);
43  }
44 
46  {
47  // States will be destroyed by the system, so just clear map
48  visited.clear();
49  }
50 
51  Visitor& self()
52  {
53  return static_cast<Visitor&>(*this);
54  }
55 
56  void run()
57  {
58  self().setup();
59  State initial = sys_.initial(tid_);
60  if (SPOT_LIKELY(self().push(initial, dfs_number)))
61  {
62  todo.push_back({initial, sys_.succ(initial, tid_)});
63  visited[initial] = ++dfs_number;
64  }
65  while (!todo.empty() && !stop_)
66  {
67  if (todo.back().it->done())
68  {
69  if (SPOT_LIKELY(self().pop(todo.back().s)))
70  {
71  sys_.recycle(todo.back().it, tid_);
72  todo.pop_back();
73  }
74  }
75  else
76  {
77  ++transitions;
78  State dst = todo.back().it->state();
79  auto it = visited.insert({dst, dfs_number+1});
80  if (it.second)
81  {
82  ++dfs_number;
83  if (SPOT_LIKELY(self().push(dst, dfs_number)))
84  {
85  todo.back().it->next();
86  todo.push_back({dst, sys_.succ(dst, tid_)});
87  }
88  }
89  else
90  {
91  self().edge(visited[todo.back().s], visited[dst]);
92  todo.back().it->next();
93  }
94  }
95  }
96  self().finalize();
97  }
98 
99  unsigned int states()
100  {
101  return dfs_number;
102  }
103 
104  unsigned int trans()
105  {
106  return transitions;
107  }
108 
109  protected:
111  {
112  State s;
113  SuccIterator* it;
114  };
116  std::vector<todo_element> todo;
117  // FIXME: The system already handle a set of visited states so
118  // this map is redundant: an we avoid this new map?
119  typedef std::unordered_map<const State, int,
120  StateHash, StateEqual> visited_map;
121  visited_map visited;
122  unsigned int dfs_number = 0;
123  unsigned int transitions = 0;
124  unsigned int tid_;
125  bool& stop_; // Do not need to be atomic.
126  };
127 }
Definition: graph.hh:33
Definition: reachability.hh:110
bool is_a_kripkecube(kripkecube< State, SuccIter > &)
This method allows to ensure (at compile time) if a given parameter is of type kripkecube. It also check if the iterator has the good interface.
Definition: kripke.hh:63
This class is a template representation of a Kripke structure. It is composed of two template paramet...
Definition: kripke.hh:37
This template class provide a sequential reachability of a kripkecube. The algorithm uses a single DF...
Definition: reachability.hh:33

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Tue Apr 18 2017 14:42:56 for spot by doxygen 1.8.13