spot  2.16
ngraph.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) by the Spot authors, see the AUTHORS file for details.
3 //
4 // This file is part of Spot, a model checking library.
5 //
6 // Spot is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // Spot is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 #pragma once
20 
21 #include <unordered_map>
22 #include <vector>
23 #include <spot/graph/graph.hh>
24 
25 namespace spot
26 {
28  template <typename Graph,
29  typename State_Name,
30  typename Name_Hash = std::hash<State_Name>,
31  typename Name_Equal = std::equal_to<State_Name>>
32  class SPOT_API named_graph
33  {
34  protected:
35  Graph& g_;
36  public:
37 
38  typedef typename Graph::state state;
39  typedef typename Graph::edge edge;
40  typedef State_Name name;
41 
43  typedef std::unordered_map<name, state,
44  Name_Hash, Name_Equal> name_to_state_t;
47  typedef std::vector<name> state_to_name_t;
49 
51  named_graph(Graph& g)
52  : g_(g)
53  {
54  }
55 
57  Graph& graph()
58  {
59  return g_;
60  }
61 
63  Graph& graph() const
64  {
65  return g_;
66  }
67 
69  template <typename... Args>
70  state new_state(name n, Args&&... args)
71  {
72  auto p = name_to_state.emplace(n, 0U);
73  if (p.second)
74  {
75  unsigned s = g_.new_state(std::forward<Args>(args)...);
76  p.first->second = s;
77  if (state_to_name.size() < s + 1)
78  state_to_name.resize(s + 1);
79  state_to_name[s] = n;
80  return s;
81  }
82  return p.first->second;
83  }
84 
91  bool alias_state(state s, name newname)
92  {
93  auto p = name_to_state.emplace(newname, s);
94  if (!p.second)
95  {
96  // The state already exists. Change its number.
97  auto old = p.first->second;
98  p.first->second = s;
99  // Add the successor of OLD to those of S.
100  auto& trans = g_.edge_vector();
101  auto& states = g_.states();
102  trans[states[s].succ_tail].next_succ = states[old].succ;
103  states[s].succ_tail = states[old].succ_tail;
104  states[old].succ = 0;
105  states[old].succ_tail = 0;
106  // Remove all references to old in edges:
107  unsigned tend = trans.size();
108  for (unsigned t = 1; t < tend; ++t)
109  {
110  if (trans[t].src == old)
111  trans[t].src = s;
112  if (trans[t].dst == old)
113  trans[t].dst = s;
114  }
115  }
116  return !p.second;
117  }
118 
121  {
122  return name_to_state.at(n);
123  }
124 
126  name get_name(state s) const
127  {
128  return state_to_name.at(s);
129  }
130 
132  bool has_state(name n) const
133  {
134  return name_to_state.contains(n);
135  }
136 
138  const state_to_name_t& names() const
139  {
140  return state_to_name;
141  }
142 
144  template <typename... Args>
145  edge
146  new_edge(name src, name dst, Args&&... args)
147  {
148  return g_.new_edge(get_state(src), get_state(dst),
149  std::forward<Args>(args)...);
150  }
151 
153  template <typename I, typename... Args>
154  edge
155  new_univ_edge(name src, I dst_begin, I dst_end, Args&&... args)
156  {
157  std::vector<unsigned> d;
158  d.reserve(std::distance(dst_begin, dst_end));
159  while (dst_begin != dst_end)
160  d.emplace_back(get_state(*dst_begin++));
161  return g_.new_univ_edge(get_state(src), d.begin(), d.end(),
162  std::forward<Args>(args)...);
163  }
164 
166  template <typename... Args>
167  edge
169  const std::initializer_list<State_Name>& dsts, Args&&... args)
170  {
171  return new_univ_edge(src, dsts.begin(), dsts.end(),
172  std::forward<Args>(args)...);
173  }
174  };
175 }
A graph wrapper associating named states to graph state indices.
Definition: ngraph.hh:33
edge new_edge(name src, name dst, Args &&... args)
Add a new edge.
Definition: ngraph.hh:146
const state_to_name_t & names() const
Return all state names.
Definition: ngraph.hh:138
state_to_name_t state_to_name
Map from state number to name.
Definition: ngraph.hh:48
Graph & graph() const
Return the underlying graph.
Definition: ngraph.hh:63
state get_state(name n) const
Return the state number for the given name.
Definition: ngraph.hh:120
named_graph(Graph &g)
Construct wrapping graph g.
Definition: ngraph.hh:51
Graph::state state
State type.
Definition: ngraph.hh:38
std::vector< name > state_to_name_t
Map from state number to name type.
Definition: ngraph.hh:47
state new_state(name n, Args &&... args)
Create a new state with the given name.
Definition: ngraph.hh:70
Graph & g_
The underlying graph.
Definition: ngraph.hh:35
name get_name(state s) const
Return the name for the given state number.
Definition: ngraph.hh:126
bool has_state(name n) const
Return true iff a state with the given name exists.
Definition: ngraph.hh:132
State_Name name
Name type.
Definition: ngraph.hh:40
std::unordered_map< name, state, Name_Hash, Name_Equal > name_to_state_t
Map from name to state number type.
Definition: ngraph.hh:44
name_to_state_t name_to_state
Definition: ngraph.hh:45
edge new_univ_edge(name src, I dst_begin, I dst_end, Args &&... args)
Add a new universal edge.
Definition: ngraph.hh:155
Graph & graph()
Return the underlying graph.
Definition: ngraph.hh:57
Graph::edge edge
Edge type.
Definition: ngraph.hh:39
edge new_univ_edge(name src, const std::initializer_list< State_Name > &dsts, Args &&... args)
Add a new universal edge.
Definition: ngraph.hh:168
bool alias_state(state s, name newname)
Give an alternate name to a state.
Definition: ngraph.hh:91
@ U
until
Definition: automata.hh:26

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Feb 27 2015 10:00:07 for spot by doxygen 1.9.1