spot  1.99.4a
proviso.hh
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2015 Laboratoire de Recherche et
3 // Developpement de l'Epita (LRDE)
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 <string>
23 #include <vector>
24 #include <unordered_map>
25 #include "twa/twa.hh"
26 #include "misc/common.hh"
27 
28 namespace spot
29 {
30  // \brief Interface for proviso
31  class SPOT_API proviso
32  {
33  public:
34  typedef std::unordered_map<const state*, int,
36 
37  virtual bool expand_new_state(int n, bool expanded,
38  // This part of the protoype is ugly but
39  // needed by some proviso
40  twa_succ_iterator*, seen_map&,
41  const state*, const const_twa_ptr&) = 0;
42 
43  virtual bool expand_src_closingedge(int src, int dst) = 0;
44 
45  virtual bool expand_before_pop(int n,
46  // This part of the protoype is ugly but
47  // needed by some proviso
48  twa_succ_iterator*, seen_map&) = 0;
49 
50  virtual ~proviso()
51  { }
52  };
53 
54  // \brief Implementation of an empty proviso : no states will be
55  // expanded
56  class SPOT_API no_proviso: public proviso
57  {
58  public:
59  bool expand_new_state(int, bool, twa_succ_iterator*,
60  seen_map&, const state*, const const_twa_ptr&);
61  bool expand_src_closingedge(int, int);
62  bool expand_before_pop(int, twa_succ_iterator*, seen_map&);
63  ~no_proviso();
64  };
65 
66  // \brief Implementation of an empty proviso : no states will be
67  // expanded
68  class SPOT_API fireall_proviso: public proviso
69  {
70  public:
71  bool expand_new_state(int, bool, twa_succ_iterator*,
72  seen_map&, const state*, const const_twa_ptr&);
73  bool expand_src_closingedge(int, int);
74  bool expand_before_pop(int, twa_succ_iterator*, seen_map&);
75  ~fireall_proviso();
76  };
77 
78  // \brief Implementation of the cycle proviso of SPIN. All states
79  // with a backedge are expanded.
80  class SPOT_API stack_proviso: public proviso
81  {
82  public:
83  bool expand_new_state(int n, bool expanded,
84  twa_succ_iterator*, seen_map&,
85  const state*, const const_twa_ptr&);
86 
87  bool expand_src_closingedge(int, int dst);
88 
89  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
90 
91  ~stack_proviso();
92  private:
93  std::unordered_set<int> on_dfs_;
94  std::vector<bool> expanded_;
95  };
96 
97  // \brief This cycle proviso always expand the destination if the destination
98  // is on the DFS. This proviso is the dual of the stack proviso. Note that
99  // if the source is already expanded the destination is not marked as to
100  // be expanded.
101  class SPOT_API destination_proviso: public proviso
102  {
103  public:
104  bool expand_new_state(int n, bool expanded,
105  twa_succ_iterator*, seen_map&,
106  const state*, const const_twa_ptr&);
107 
108  // Here we detect backegdes to mark the destination as to be expanded
109  bool expand_src_closingedge(int, int dst);
110 
111  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
112 
114 
115  private:
116  // Store foreach state wether it must be expanded or not
117  std::unordered_map<int, bool> on_dfs_;
118  std::vector<bool> expanded_;
119  };
120 
121 
122  // \brief this cycle proviso expand randomly one state between the source and
123  // the destinationn iff they are both on DFS stack.
124  class SPOT_API rnd_sd_proviso: public proviso
125  {
126  public:
127  bool expand_new_state(int n, bool expanded,
128  twa_succ_iterator*, seen_map&,
129  const state*, const const_twa_ptr&);
130 
131  // Here we detect backegdes to mark the destination as to be expanded
132  bool expand_src_closingedge(int, int dst);
133 
134  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
135 
136  ~rnd_sd_proviso();
137 
138  private:
139  // Store foreach state wether it must be expanded or not
140  std::unordered_map<int, bool> on_dfs_;
141  std::vector<bool> expanded_;
142  };
143 
144 
145 
146  // \brief This proviso always expand the destination but uses color
147  // to avoid useless firing.
148  class SPOT_API delayed_proviso: public proviso
149  {
150  public:
151 
152  bool expand_new_state(int n, bool expanded, twa_succ_iterator*,
153  seen_map&, const state*, const const_twa_ptr&);
154 
155  bool expand_src_closingedge(int src, int dst);
156 
157  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
158 
159  ~delayed_proviso();
160 
161  private:
162  // FIXME duplicated with dfs exploration, must be passed by reference?
163  std::vector<int> todo_;
164  std::unordered_map<int, bool> reach_;
165  struct dfs_element
166  {
167  bool expanded;
168  bool to_be_expanded;
169  };
170  std::unordered_map<int, dfs_element> on_dfs_;
171  };
172 
173  // \brief the above delayed proviso but ignoring dead states.
174  // This implies that we compute SCCs here
175  class SPOT_API delayed_proviso_dead: public proviso
176  {
177  public:
178 
179  bool expand_new_state(int n, bool expanded, twa_succ_iterator*,
180  seen_map&, const state*, const const_twa_ptr&);
181 
182  bool expand_src_closingedge(int src, int dst);
183 
184  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
185 
187 
188  private:
189  // FIXME duplicated with dfs exploration, must be passed by reference?
190  std::vector<int> todo_;
191 
192  struct root_element
193  {
194  int n;
195  std::vector<int> same_scc;
196  };
197  std::vector<root_element> root_stack_;
198  struct reach_element
199  {
200  bool nongreen;
201  bool dead;
202  };
203  std::unordered_map<int, reach_element> reach_;
204  struct dfs_element
205  {
206  bool expanded;
207  bool to_be_expanded;
208  };
209  std::unordered_map<int, dfs_element> on_dfs_;
210  };
211 
212 
213  // This proviso is the one described by Evangelista (2007) in
214  // "Some Solutions to the Ignoring Problem"
215  class SPOT_API color_proviso: public proviso
216  {
217  public:
218 
219  color_proviso();
220 
221  bool is_cl2l_persistent_set(int n, twa_succ_iterator* it, seen_map& map);
222 
223  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
224  seen_map& map, const state*, const const_twa_ptr&);
225 
226  bool expand_src_closingedge(int src, int dst);
227 
228  bool expand_before_pop(int n, twa_succ_iterator* it, seen_map& map);
229 
230  ~color_proviso();
231 
232  private:
233  enum class color
234  {
235  Orange,
236  Green,
237  Red
238  };
239  struct element
240  {
241  bool in_stack;
242  spot::color_proviso::color color;
243  int expanded;
244  };
245  int expanded_;
246  std::unordered_map<int, element> reach_;
247  std::vector<bool> st_expanded_;
248  };
249 
250 
251  // This proviso is the one described by Evangelista (2007) in
252  // "Some Solutions to the Ignoring Problem"
253  class SPOT_API color_proviso_dead: public proviso
254  {
255  public:
256 
258 
259  bool is_cl2l_persistent_set(int n, twa_succ_iterator* it, seen_map& map);
260 
261  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
262  seen_map& map, const state*, const const_twa_ptr&);
263 
264  bool expand_src_closingedge(int src, int dst);
265 
266  bool expand_before_pop(int n, twa_succ_iterator* it, seen_map& map);
267 
269 
270  private:
271  enum class color
272  {
273  Orange,
274  Green,
275  Red
276  };
277  struct element
278  {
279  bool in_stack;
280  spot::color_proviso_dead::color color;
281  int expanded;
282  bool dead;
283  };
284  int expanded_;
285  std::unordered_map<int, element> reach_;
286  struct root_element
287  {
288  int n;
289  std::vector<int> same_scc;
290  };
291  std::vector<root_element> root_stack_;
292  std::vector<bool> st_expanded_;
293  };
294 
295 
296  // \brief This cycle proviso expand randomly a state between the root
297  // and the top of the stack if the destination is on dfs, otherwise it
298  // expands randomly a state between the destination and the top of the
299  // stack
300  class SPOT_API rnd_one_proviso: public proviso
301  {
302  public:
303  bool expand_new_state(int n, bool expanded, twa_succ_iterator*,
304  seen_map&, const state*, const const_twa_ptr&);
305 
306  bool expand_src_closingedge(int, int dst);
307 
308  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
309 
310  ~rnd_one_proviso();
311 
312  private:
313  struct reach_element
314  {
315  bool dead;
316  bool on_dfs;
317  unsigned dfs_id;
318  };
319  std::unordered_map<int, reach_element> reach_;
320  std::vector<bool> expanded_;
321  std::vector<bool> to_be_expanded_;
322  struct root_element
323  {
324  int n;
325  std::vector<int> same_scc;
326  };
327  std::vector<root_element> root_stack_;
328  };
329 
330  // \brief This cycle proviso expands the state with minimal succ between root
331  // and the top of the stack if the destination is on dfs, otherwise it
332  // expands the state with minimal between the destination and the top of the
333  // stack
334  class SPOT_API min_succ_proviso: public proviso
335  {
336  public:
337  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
338  seen_map&, const state*, const const_twa_ptr&);
339 
340  bool expand_src_closingedge(int, int dst);
341 
342  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
343 
344  ~min_succ_proviso();
345 
346  private:
347  struct reach_element
348  {
349  bool dead;
350  bool on_dfs;
351  unsigned dfs_id;
352  };
353  std::unordered_map<int, reach_element> reach_;
354  std::vector<bool> expanded_;
355  std::vector<bool> to_be_expanded_;
356  std::vector<unsigned> succ_;
357  struct root_element
358  {
359  int n;
360  std::vector<int> same_scc;
361  };
362  std::vector<root_element> root_stack_;
363  };
364 
365  // \brief This cycle proviso expands the state with minimal enabled
366  // succ between root and the top of the stack if the destination is on dfs,
367  // otherwise it expands the state with minimal between the destination and
368  // the top of the stack
369  class SPOT_API min_succ_en_proviso: public proviso
370  {
371  public:
372  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
373  seen_map&, const state*, const const_twa_ptr&);
374 
375  bool expand_src_closingedge(int, int dst);
376 
377  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
378 
380 
381  private:
382  struct reach_element
383  {
384  bool dead;
385  bool on_dfs;
386  unsigned dfs_id;
387  };
388  std::unordered_map<int, reach_element> reach_;
389  std::vector<bool> expanded_;
390  std::vector<bool> to_be_expanded_;
391  std::vector<unsigned> succ_;
392  struct root_element
393  {
394  int n;
395  std::vector<int> same_scc;
396  };
397  std::vector<root_element> root_stack_;
398  };
399 
400  // \brief This cycle proviso expands the state with maximal enabled
401  // succ between root and the top of the stack if the destination is on dfs,
402  // otherwise it expands the state with maximal between the destination and
403  // the top of the stack
404  class SPOT_API max_succ_en_proviso: public proviso
405  {
406  public:
407  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
408  seen_map&, const state*, const const_twa_ptr&);
409 
410  bool expand_src_closingedge(int, int dst);
411 
412  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
413 
415 
416  private:
417  struct reach_element
418  {
419  bool dead;
420  bool on_dfs;
421  unsigned dfs_id;
422  };
423  std::unordered_map<int, reach_element> reach_;
424  std::vector<bool> expanded_;
425  std::vector<bool> to_be_expanded_;
426  std::vector<unsigned> succ_;
427  struct root_element
428  {
429  int n;
430  std::vector<int> same_scc;
431  };
432  std::vector<root_element> root_stack_;
433  };
434 
435  // \brief This cycle proviso expands the state with maximal succ between root
436  // and the top of the stack if the destination is on dfs, otherwise it
437  // expands the state with maximal between the destination and the top of the
438  // stack
439  class SPOT_API max_succ_proviso: public proviso
440  {
441  public:
442  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
443  seen_map&, const state*, const const_twa_ptr&);
444 
445  bool expand_src_closingedge(int, int dst);
446 
447  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
448 
449  ~max_succ_proviso();
450 
451  private:
452  struct reach_element
453  {
454  bool dead;
455  bool on_dfs;
456  unsigned dfs_id;
457  };
458  std::unordered_map<int, reach_element> reach_;
459  std::vector<bool> expanded_;
460  std::vector<bool> to_be_expanded_;
461  std::vector<unsigned> succ_;
462  struct root_element
463  {
464  int n;
465  std::vector<int> same_scc;
466  };
467  std::vector<root_element> root_stack_;
468  };
469 
470  // \brief expand the state with the smallest number of reduced
471  // successors.
472  class SPOT_API min_succ_sd_proviso: public proviso
473  {
474  public:
475 
476  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
477  seen_map&, const state*, const const_twa_ptr&);
478 
479  bool expand_src_closingedge(int src, int dst);
480 
481  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
482 
484 
485  private:
486  struct dfs_element
487  {
488  int nb_succ;
489  bool expanded;
490  bool to_be_expanded;
491  };
492  std::unordered_map<int, dfs_element> on_dfs_;
493  };
494 
495  // \brief expand the state with the smallest number of reduced
496  // successors.
497  class SPOT_API max_succ_sd_proviso: public proviso
498  {
499  public:
500 
501  bool expand_new_state(int n, bool expanded, twa_succ_iterator* it,
502  seen_map&, const state*, const const_twa_ptr&);
503 
504  bool expand_src_closingedge(int src, int dst);
505 
506  bool expand_before_pop(int n, twa_succ_iterator*, seen_map&);
507 
509 
510  private:
511  struct dfs_element
512  {
513  int nb_succ;
514  bool expanded;
515  bool to_be_expanded;
516  };
517  std::unordered_map<int, dfs_element> on_dfs_;
518  };
519 }
Definition: graph.hh:32
An Equivalence Relation for state*.
Definition: twa.hh:140
Definition: proviso.hh:101
Definition: proviso.hh:369
Definition: proviso.hh:439
Abstract class for states.
Definition: twa.hh:42
Definition: proviso.hh:215
Definition: proviso.hh:175
Definition: proviso.hh:300
Definition: proviso.hh:497
Definition: proviso.hh:68
Definition: proviso.hh:334
Iterate over the successors of a state.
Definition: twa.hh:331
Definition: proviso.hh:56
Hash Function for state*.
Definition: twa.hh:164
Definition: proviso.hh:404
Definition: proviso.hh:148
Definition: proviso.hh:253
Definition: proviso.hh:31
Definition: proviso.hh:124
Definition: proviso.hh:472
Definition: proviso.hh:80

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Sun Oct 11 2015 10:50:08 for spot by doxygen 1.8.9.1