spot  1.2.1a
root_stack.hh
1 // Copyright (C) 2013 Laboratoire de Recherche et Développement
2 // de l'Epita (LRDE).
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 #ifndef SPOT_FASTTGBAALGOS_EC_ROOT_STACK_HH
20 # define SPOT_FASTTGBAALGOS_EC_ROOT_STACK_HH
21 
22 #include <stack>
23 #include <tuple>
24 #include <string>
25 #include "misc/hash.hh"
26 #include "union_find.hh"
27 #include "fasttgba/fasttgba.hh"
28 #include "ec.hh"
29 
30 namespace spot
31 {
34  // techniques
36  {
37  public:
39  empty_(new markset(acc)),
40  max_size_(0)
41  { }
42 
43  virtual ~stack_of_roots()
44  {
45  while (!stack_.empty())
46  {
47  pop();
48  }
49  delete empty_;
50  }
51 
52  virtual bool is_empty ()
53  {
54  return stack_.empty();
55  }
56 
57  virtual unsigned int size ()
58  {
59  return stack_.size();
60  }
61 
62  virtual void push_trivial (unsigned int root)
63  {
64  stack_.push(std::make_pair(root, empty_));
65  }
66 
67  virtual void push_non_trivial (unsigned int root,
68  markset m,
69  unsigned int)
70  {
71  if (m == *empty_)
72  stack_.push(std::make_pair(root, empty_));
73  else
74  stack_.push(std::make_pair(root, new markset(m)));
75  }
76 
77  virtual unsigned int root_of_the_top ()
78  {
79  return stack_.top().first;
80  }
81 
82  virtual void pop()
83  {
84  max_size_ = max_size_ > stack_.size()? max_size_ : stack_.size();
85  if (stack_.top().second != empty_)
86  delete stack_.top().second;
87  stack_.pop();
88  }
89 
90  virtual const markset& top_acceptance()
91  {
92  assert(!stack_.empty());
93  return *stack_.top().second;
94  }
95 
96  virtual unsigned int max_size()
97  {
98  return max_size_;
99  }
100 
101  private:
102  std::stack<std::pair<unsigned int, markset*>> stack_; // The stack
103  markset* empty_;
104  unsigned int max_size_;
105  };
106 
108  {
109  struct stack_entry
110  {
111  unsigned int root;
112  bool is_trivial;
113  markset *mark;
114  };
115 
116  // out, trivial, acc
117  std::vector<// std::tuple<unsigned int, bool, markset*>
118  stack_entry> stack_;
119  markset* empty_;
120  unsigned int max_size_;
121 
122  public:
124  stack_of_roots(acc),
125  empty_(new markset(acc)),
126  max_size_(0)
127  {
128  }
129 
130  virtual ~compressed_stack_of_roots()
131  {
132  while (!stack_.empty())
133  {
134  pop();
135  }
136  delete empty_;
137  }
138 
139  virtual bool is_empty ()
140  {
141  return stack_.empty();
142  }
143 
144  virtual unsigned int size ()
145  {
146  return stack_.size();
147  }
148 
149  virtual void push_trivial (unsigned int root)
150  {
151  // std::cout << "Push trivial " << root << std::endl;
152  // The stack is empty just push it!
153  if (is_empty())
154  {
155  assert(root == 0);
156  stack_.push_back({root, true, empty_});
157  }
158  // The stack is empty and the back is a trivial SCC
159  // Update it!
160  else if (stack_.back().is_trivial)
161  {
162  assert(root == stack_.back().root +1);
163  stack_.pop_back();
164  stack_.push_back({root, true, empty_});
165  }
166  // Otherwise it's a non trivial SCC fix out for this SCC
167  // and push the new one.
168  else {
169  assert(root_of_the_top() < root &&
170  root <= stack_.back().root +1);
171  stack_.back().root = root -1;
172  stack_.push_back({root, true, empty_});
173  }
174  }
175 
176  virtual void push_non_trivial (unsigned int root,
177  markset m,
178  unsigned int last = 0)
179  {
180  // std::cout << "Push non trivial " << root << std::endl;
181  assert(root <= last);
182  assert (!is_empty() || root == 0);
183  assert(is_empty() || root == stack_.back().root +1);
184 
185  if (m == *empty_)
186  stack_.push_back({last, false, empty_});
187  else
188  stack_.push_back({last, false, new markset(m)});
189  }
190 
193  virtual unsigned int root_of_the_top ()
194  {
195  assert (!is_empty());
196  if (stack_.back().is_trivial)
197  return stack_.back().root;
198  if (stack_.size() > 1)
199  return (stack_[stack_.size() - 2]).root + 1;
200  return 0;
201  }
202 
203  virtual void pop()
204  {
205  max_size_ = max_size_ > stack_.size()? max_size_ : stack_.size();
206  //std::cout << "Pop " << std::endl;
207  unsigned int r = root_of_the_top();
208 
209  if (stack_.back().is_trivial)
210  {
211  stack_.pop_back();
212  if (is_empty())
213  {
214  if (r > 0)
215  stack_.push_back({r-1, true, empty_});
216  }
217  else
218  {
219  if (r - 1 > stack_.back().root)
220  stack_.push_back({r-1, true, empty_});
221  }
222  }
223  else
224  {
225  if (stack_.back().mark != empty_)
226  delete stack_.back().mark;
227  stack_.pop_back();
228  }
229  }
230 
231  virtual const markset& top_acceptance()
232  {
233  assert(!stack_.empty());
234  return *stack_.back().mark;
235  }
236 
237  virtual unsigned int max_size()
238  {
239  return max_size_;
240  }
241  };
242 
243 
244 
245 
246  // -------------------------------------------
247  // Compressed Stack -- Experimental
248 
249 
251  {
252  public:
253  generic_stack(acc_dict& acc):
254  empty_(new markset(acc)),
255  max_size_(0)
256  { }
257 
258  virtual ~generic_stack()
259  {
260  while (!stack_.empty())
261  {
262  pop(-1/*unused*/);
263  }
264  delete empty_;
265  }
266 
267  virtual unsigned int size ()
268  {
269  return stack_.size();
270  }
271 
272  virtual void push_transient (unsigned int root)
273  {
274  stack_.push(std::make_pair(root, empty_));
275  }
276 
277  virtual void push_non_transient (unsigned int root,
278  const markset& m)
279  {
280  if (*empty_ == m)
281  stack_.push(std::make_pair(root, empty_));
282  else
283  stack_.push(std::make_pair(root, new markset(m)));
284  }
285 
286  struct stack_pair
287  {
288  unsigned int pos;
289  markset acc; // It's a copy you can use it!
290  };
291 
292 
293  virtual stack_pair pop(int)
294  {
295  stack_pair ret_val = {stack_.top().first, *stack_.top().second};
296 
297  max_size_ = max_size_ > stack_.size()? max_size_ : stack_.size();
298  if (stack_.top().second != empty_)
299  delete stack_.top().second;
300  stack_.pop();
301  return ret_val;
302  }
303 
304  virtual stack_pair top(int)
305  {
306  stack_pair ret_val = {stack_.top().first, *stack_.top().second};
307  return ret_val;
308  }
309 
310  virtual unsigned int max_size()
311  {
312  return max_size_;
313  }
314 
315  private:
316  std::stack<std::pair<unsigned int, markset*>> stack_;
317 
318  protected:
320  unsigned int max_size_;
321  };
322 
323 
324 
326  {
327 
328  public:
330  generic_stack(acc)
331  {
332  }
333 
334  virtual ~compressed_generic_stack()
335  {
336  while (!stack_.empty())
337  {
338  if (stack_.top().acc != empty_)
339  delete stack_.top().acc;
340  stack_.pop();
341  }
342  }
343 
344  virtual unsigned int size ()
345  {
346  return stack_.size();
347  }
348 
349  virtual void push_transient (unsigned int p)
350  {
351  if (stack_.empty() || !stack_.top().is_transient)
352  stack_.push({p, empty_, true});
353  }
354 
355  virtual void push_non_transient (unsigned int p,
356  const markset& m)
357  {
358  if (*empty_ == m)
359  stack_.push({p, empty_, false});
360  else
361  stack_.push({p, new markset(m), false});
362  }
363 
364  struct stack_pair
365  {
366  unsigned int pos;
367  markset acc; // It's a copy you can use it!
368  };
369 
370 
371  virtual generic_stack::stack_pair pop(int p)
372  {
373  max_size_ = max_size_ > stack_.size()? max_size_ : stack_.size();
374  if (!stack_.top().is_transient)
375  {
376  generic_stack::stack_pair ret_val = {stack_.top().pos,
377  *stack_.top().acc};
378  if (stack_.top().acc != empty_)
379  delete stack_.top().acc;
380  stack_.pop();
381  return ret_val;
382  }
383  else
384  {
385  if (p == (int)stack_.top().pos)
386  stack_.pop();
387 
388  generic_stack::stack_pair ret_val = {(unsigned)p,*empty_};
389  return ret_val;
390  }
391  }
392 
393  virtual generic_stack::stack_pair top(int p)
394  {
395  if (!stack_.top().is_transient)
396  {
397  generic_stack::stack_pair ret_val = {stack_.top().pos,
398  *stack_.top().acc};
399  return ret_val;
400  }
401  else
402  {
403  generic_stack::stack_pair ret_val = {(unsigned)p,*empty_};
404  return ret_val;
405  }
406  }
407 
408  private:
409  struct stack_entry
410  {
411  unsigned int pos;
412  markset *acc;
413  bool is_transient;
414  };
415 
416  std::stack<stack_entry> stack_;
417  };
418 }
419 
420 
421 #endif // SPOT_FASTTGBAALGOS_EC_ROOT_STACK_HH
this class acts like a wrapper to the C code of the open_set.
Definition: public.hh:32
Definition: root_stack.hh:364
Definition: root_stack.hh:250
Definition: root_stack.hh:107
unsigned int max_size_
The max size of the stack.
Definition: root_stack.hh:320
virtual void push_non_trivial(unsigned int root, markset m, unsigned int last=0)
< Unused for this implem
Definition: root_stack.hh:176
Definition: root_stack.hh:325
Definition: root_stack.hh:286
Definition: root_stack.hh:35
bool empty()
test is a least one mark is set
markset * empty_
The empty markset.
Definition: root_stack.hh:319
int mark
the type that represents a mark
Definition: markset.hh:32
This class represents a set of acceptance marks.
Definition: markset.hh:35
Definition: acc_dict.hh:31
size_t size()
Return the number of marks in the set.
virtual unsigned int root_of_the_top()
Definition: root_stack.hh:193
virtual void push_non_trivial(unsigned int root, markset m, unsigned int)
< Unused for this implem
Definition: root_stack.hh:67

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Jun 5 2015 11:31:18 for spot by doxygen 1.8.9.1