reachiter.hh 6.74 KB
Newer Older
1
// -*- coding: utf-8 -*-
2
3
// Copyright (C) 2008, 2009, 2011, 2013, 2016 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
Guillaume Sadegh's avatar
Guillaume Sadegh committed
4
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
5
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
6
// Pierre et Marie Curie.
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
7
8
9
10
11
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
12
// the Free Software Foundation; either version 3 of the License, or
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
13
14
15
16
17
18
19
20
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
// License for more details.
//
// 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/>.
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
22

23
#pragma once
24

25
26
#include <spot/misc/hash.hh>
#include <spot/twa/twa.hh>
27
28
29
30
31
#include <stack>
#include <deque>

namespace spot
{
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
32
  /// \ingroup twa_generic
33
  /// \brief Iterate over all reachable states of a spot::tgba.
34
  class SPOT_API tgba_reachable_iterator
35
36
  {
  public:
37
    tgba_reachable_iterator(const const_twa_ptr& a);
38
39
40
41
    virtual ~tgba_reachable_iterator();

    /// \brief Iterate over all reachable states of a spot::tgba.
    ///
42
43
44
45
    /// This is a template method that will call add_state(),
    /// next_state(), want_state(), start(), end(), process_state(),
    /// and process_link(), while it iterates over states.
    virtual void run();
46
47
48

    /// \name Todo list management.
    ///
49
50
    /// See e.g.
    /// spot::tgba_reachable_iterator_breadth_first for precanned
51
52
53
54
    /// implementations for these functions.
    /// \{
    /// \brief Called by run() to register newly discovered states.
    virtual void add_state(const state* s) = 0;
55
    /// \brief Called by run() to obtain the next state to process.
56
57
58
    virtual const state* next_state() = 0;
    /// \}

59
60
61
62
    /// Called by add_state or next_states implementations to filter
    /// states.  Default implementation always return true.
    virtual bool want_state(const state* s) const;

63
64
65
66
67
68
69
70
    /// Called by run() before starting its iteration.
    virtual void start();
    /// Called by run() once all states have been explored.
    virtual void end();

    /// Called by run() to process a state.
    ///
    /// \param s The current state.
71
    /// \param n A unique number assigned to \a s.
72
73
    /// \param si The spot::twa_succ_iterator for \a s.
    virtual void process_state(const state* s, int n, twa_succ_iterator* si);
74
75
    /// Called by run() to process a transition.
    ///
76
    /// \param in_s The source state
77
    /// \param in The source state number.
78
    /// \param out_s The destination state
79
    /// \param out The destination state number.
80
    /// \param si The spot::twa_succ_iterator positionned on the current
81
    ///             transition.
82
83
84
85
86
87
    ///
    /// The in_s and out_s states are owned by the
    /// spot::tgba_reachable_iterator instance and destroyed when the
    /// instance is destroyed.
    virtual void process_link(const state* in_s, int in,
			      const state* out_s, int out,
88
			      const twa_succ_iterator* si);
89
90

  protected:
91
    const_twa_ptr aut_;	///< The spot::tgba to explore.
92

93
    state_map<int> seen;	///< States already seen.
94
95
  };

Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
96
  /// \ingroup twa_generic
97
  /// \brief An implementation of spot::tgba_reachable_iterator that browses
98
99
  /// states breadth first.
  class SPOT_API tgba_reachable_iterator_breadth_first :
100
    public tgba_reachable_iterator
101
102
  {
  public:
103
    tgba_reachable_iterator_breadth_first(const const_twa_ptr& a);
104
105
106
107
108

    virtual void add_state(const state* s);
    virtual const state* next_state();

  protected:
109
    std::deque<const state*> todo; ///< A queue of states yet to explore.
110
111
  };

Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
112
  /// \ingroup twa_generic
113
114
  /// \brief Iterate over all states of an automaton using a DFS.
  class SPOT_API tgba_reachable_iterator_depth_first
115
116
  {
  public:
117
    tgba_reachable_iterator_depth_first(const const_twa_ptr& a);
118
    virtual ~tgba_reachable_iterator_depth_first();
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    /// \brief Iterate over all reachable states of a spot::tgba.
    ///
    /// This is a template method that will call start(), end(),
    /// want_state(), process_state(), and process_link(), while it
    /// iterates over states.
    virtual void run();

    /// Called by add_state or next_states implementations to filter
    /// states.  Default implementation always return true.
    virtual bool want_state(const state* s) const;

    /// Called by run() before starting its iteration.
    virtual void start();
    /// Called by run() once all states have been explored.
    virtual void end();

    /// Called by run() to process a state.
    ///
    /// \param s The current state.
    /// \param n A unique number assigned to \a s.
140
141
    /// \param si The spot::twa_succ_iterator for \a s.
    virtual void process_state(const state* s, int n, twa_succ_iterator* si);
142
143
144
145
146
147
    /// Called by run() to process a transition.
    ///
    /// \param in_s The source state
    /// \param in The source state number.
    /// \param out_s The destination state
    /// \param out The destination state number.
148
    /// \param si The spot::twa_succ_iterator positionned on the current
149
150
151
152
153
154
155
    ///             transition.
    ///
    /// The in_s and out_s states are owned by the
    /// spot::tgba_reachable_iterator instance and destroyed when the
    /// instance is destroyed.
    virtual void process_link(const state* in_s, int in,
			      const state* out_s, int out,
156
			      const twa_succ_iterator* si);
157
158

  protected:
159
    const_twa_ptr aut_;		///< The spot::tgba to explore.
160

161
    state_map<int> seen;	///< States already seen.
162
163
164
165
    struct stack_item
    {
      const state* src;
      int src_n;
166
      twa_succ_iterator* it;
167
168
169
170
171
172
173
    };
    std::deque<stack_item> todo; ///< the DFS stack

    /// Push a new state in todo.
    virtual void push(const state* s, int sn);
    /// Pop the DFS stack.
    virtual void pop();
174
175
  };

Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
176
  /// \ingroup twa_generic
177
178
179
180
181
182
183
184
  /// \brief Iterate over all states of an automaton using a DFS.
  ///
  /// This variant also maintains a set of states that are on the DFS
  /// stack.  It can be checked using the on_stack() method.
  class tgba_reachable_iterator_depth_first_stack
    : public tgba_reachable_iterator_depth_first
  {
  public:
185
    tgba_reachable_iterator_depth_first_stack(const const_twa_ptr& a);
186
187
188
189
190
191
192
193
    /// \brief Whether state sn is on the DFS stack.
    ///
    /// Note the destination state of a transition is only pushed to
    /// the stack after process_link() has been called.
    bool on_stack(int sn) const;
  protected:
    virtual void push(const state* s, int sn);
    virtual void pop();
194

195
    std::unordered_set<int> stack_;
196
  };
197
}