spot  2.14.5
zlktree.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 <iosfwd>
22 #include <deque>
23 #include <memory>
24 #include <spot/misc/bitvect.hh>
25 #include <spot/twa/twagraph.hh>
26 #include <spot/twaalgos/sccinfo.hh>
27 
28 namespace spot
29 {
33  {
35  NONE = 0,
39  CHECK_RABIN = 1,
43  CHECK_STREETT = 2,
55  MERGE_SUBTREES = 8,
59  NO_EMPTY_LAYER = 16,
60  };
61 
62 #ifndef SWIG
63  inline
64  bool operator!(zielonka_tree_options me)
65  {
66  return me == zielonka_tree_options::NONE;
67  }
68 
69  inline
72  {
73  typedef std::underlying_type_t<zielonka_tree_options> ut;
74  return static_cast<zielonka_tree_options>(static_cast<ut>(left)
75  & static_cast<ut>(right));
76  }
77 
78  inline
81  {
82  typedef std::underlying_type_t<zielonka_tree_options> ut;
83  return static_cast<zielonka_tree_options>(static_cast<ut>(left)
84  | static_cast<ut>(right));
85  }
86 
87  inline
90  {
91  typedef std::underlying_type_t<zielonka_tree_options> ut;
92  return static_cast<zielonka_tree_options>(static_cast<ut>(left)
93  & ~static_cast<ut>(right));
94  }
95 #endif
105  class SPOT_API zielonka_tree
106  {
107  public:
109  zielonka_tree(const acc_cond& cond,
111 
116  unsigned num_branches() const
117  {
118  return num_branches_;
119  }
120 
124  unsigned first_branch() const
125  {
126  return one_branch_;
127  }
128 
148  std::pair<unsigned, unsigned>
149  step(unsigned branch, acc_cond::mark_t colors) const;
150 
153  bool is_even() const
154  {
155  return is_even_;
156  }
157 
165  bool empty_layer_is_even() const
166  {
167  return empty_is_even_;
168  }
169 
174  bool has_rabin_shape() const
175  {
176  return has_rabin_shape_;
177  }
178 
183  bool has_streett_shape() const
184  {
185  return has_streett_shape_;
186  }
187 
191  bool has_parity_shape() const
192  {
193  return has_streett_shape_ && has_rabin_shape_;
194  }
195 
197  void dot(std::ostream&) const;
198 
200  {
201  unsigned parent;
202  unsigned next_sibling = 0;
203  unsigned first_child = 0;
204  unsigned level;
205  acc_cond::mark_t colors;
206  };
207  std::vector<zielonka_node> nodes_;
208  private:
209  unsigned one_branch_ = 0;
210  unsigned num_branches_ = 0;
211  bool is_even_;
212  bool empty_is_even_;
213  bool has_rabin_shape_ = true;
214  bool has_streett_shape_ = true;
215  };
216 
228  SPOT_API
229  twa_graph_ptr zielonka_tree_transform(const const_twa_graph_ptr& aut);
230 
231 
234  enum class acd_options
235  {
237  NONE = 0,
239  CHECK_RABIN = 1,
241  CHECK_STREETT = 2,
247  ABORT_WRONG_SHAPE = 4,
252  ORDER_HEURISTIC = 8,
253  };
254 
255 #ifndef SWIG
256  inline
257  bool operator!(acd_options me)
258  {
259  return me == acd_options::NONE;
260  }
261 
262  inline
263  acd_options operator&(acd_options left, acd_options right)
264  {
265  typedef std::underlying_type_t<acd_options> ut;
266  return static_cast<acd_options>(static_cast<ut>(left)
267  & static_cast<ut>(right));
268  }
269 
270  inline
272  {
273  typedef std::underlying_type_t<acd_options> ut;
274  return static_cast<acd_options>(static_cast<ut>(left)
275  | static_cast<ut>(right));
276  }
277 
278  inline
279  acd_options operator-(acd_options left, acd_options right)
280  {
281  typedef std::underlying_type_t<acd_options> ut;
282  return static_cast<acd_options>(static_cast<ut>(left)
283  & ~static_cast<ut>(right));
284  }
285 
286 #endif
287 
297  class SPOT_API acd
298  {
299  public:
302  acd(const const_twa_graph_ptr& aut, acd_options opt = acd_options::NONE);
303 
304  ~acd();
305 
314  std::pair<unsigned, unsigned>
315  step(unsigned branch, unsigned edge) const;
316 
323  unsigned state_step(unsigned node, unsigned edge) const;
324 
328  std::vector<unsigned> edges_of_node(unsigned n) const;
329 
331  unsigned node_count() const
332  {
333  return nodes_.size();
334  }
335 
339  bool node_acceptance(unsigned n) const;
340 
342  unsigned node_level(unsigned n) const;
343 
345  const acc_cond::mark_t& node_colors(unsigned n) const;
346 
349  bool is_even(unsigned scc) const
350  {
351  if (scc >= scc_count_)
352  report_invalid_scc_number(scc, "is_even");
353  return trees_[scc].is_even;
354  }
355 
362  bool is_even() const
363  {
364  return is_even_;
365  }
366 
368  unsigned first_branch(unsigned state) const;
369 
370  unsigned scc_max_level(unsigned scc) const
371  {
372  if (scc >= scc_count_)
373  report_invalid_scc_number(scc, "scc_max_level");
374  return trees_[scc].max_level;
375  }
376 
382  bool has_rabin_shape() const;
383 
389  bool has_streett_shape() const;
390 
396  bool has_parity_shape() const;
397 
399  const const_twa_graph_ptr get_aut() const
400  {
401  return aut_;
402  }
403 
408  void dot(std::ostream&, const char* id = nullptr) const;
409 
410  private:
411  const scc_info* si_;
412  bool own_si_ = false;
413  acd_options opt_;
414 
415  // This structure is used to represent one node in the ACD forest.
416  // The tree use a left-child / right-sibling representation
417  // (called here first_child, next_sibling). Each node
418  // additionally store a level (depth in the ACD, adjusted at the
419  // end of the construction so that all node on the same level have
420  // the same parity), the SCC (which is also it's tree number), and
421  // some bit vectors representing the edges and states of that
422  // node. Those bit vectors are as large as the original
423  // automaton, and they are shared among nodes from the different
424  // trees of the ACD forest (since each tree correspond to a
425  // different SCC, they cannot share state or edges).
426  struct acd_node
427  {
428  unsigned parent;
429  unsigned next_sibling = 0;
430  unsigned first_child = 0;
431  unsigned level;
432  unsigned scc;
433  acc_cond::mark_t colors;
434  unsigned minstate;
435  bitvect& edges;
436  bitvect& states;
437  acd_node(bitvect& e, bitvect& s) noexcept
438  : edges(e), states(s)
439  {
440  }
441  };
442  // We store the nodes in a deque so that their addresses do not
443  // change.
444  std::deque<acd_node> nodes_;
445  // Likewise for bitvectors: this is the support for all edge vectors
446  // and state vectors used in acd_node.
447  std::deque<std::unique_ptr<bitvect>> bitvectors;
448  // Information about a tree of the ACD. Each treinserte correspond
449  // to an SCC.
450  struct scc_data
451  {
452  bool trivial; // whether the SCC is trivial we do
453  // not store any node for trivial
454  // SCCs.
455  unsigned root = 0; // root node of a non-trivial SCC.
456  bool is_even; // parity of the tree, used at the end
457  // of the construction to adjust
458  // levels.
459  unsigned max_level = 0; // Maximum level for this SCC.
460  unsigned num_nodes = 0; // Number of node in this tree. This
461  // is only used to share bitvectors
462  // between SCC: node with the same
463  // "rank" in each tree share the same
464  // bitvectors.
465  };
466  std::vector<scc_data> trees_;
467  unsigned scc_count_;
468  const_twa_graph_ptr aut_;
469  // Information about the overall ACD.
470  bool is_even_;
471  bool has_rabin_shape_ = true;
472  bool has_streett_shape_ = true;
473 
474  // Build the ACD structure. Called by the constructors.
475  void build_();
476 
477  // leftmost branch of \a node that contains \a state
478  unsigned leftmost_branch_(unsigned node, unsigned state) const;
479 
480 #ifndef SWIG
481  [[noreturn]] static
482  void report_invalid_scc_number(unsigned num, const char* fn);
483  [[noreturn]] static void report_need_opt(const char* opt);
484  [[noreturn]] static void report_empty_acd(const char* fn);
485 #endif
486  };
487 
510  SPOT_API
511  twa_graph_ptr acd_transform(const const_twa_graph_ptr& aut,
512  bool colored = false);
513  SPOT_API
514  twa_graph_ptr acd_transform_sbacc(const const_twa_graph_ptr& aut,
515  bool colored = false,
516  bool order_heuristic = true);
518 }
An acceptance condition.
Definition: acc.hh:61
Alternating Cycle Decomposition implementation.
Definition: zlktree.hh:298
bool has_parity_shape() const
Whether the ACD has Streett shape.
unsigned first_branch(unsigned state) const
Return the first branch for state.
bool node_acceptance(unsigned n) const
const const_twa_graph_ptr get_aut() const
Return the automaton on which the ACD is defined.
Definition: zlktree.hh:399
bool is_even(unsigned scc) const
Whether the ACD corresponds to a min even or min odd parity acceptance in SCC scc.
Definition: zlktree.hh:349
bool has_rabin_shape() const
Whether the ACD has Rabin shape.
const acc_cond::mark_t & node_colors(unsigned n) const
Return the colors of a node.
std::pair< unsigned, unsigned > step(unsigned branch, unsigned edge) const
Step through the ACD.
unsigned node_level(unsigned n) const
Return the level of a node.
std::vector< unsigned > edges_of_node(unsigned n) const
Return the list of edges covered by node n of the ACD.
unsigned node_count() const
Return the number of nodes in the ACD forest.
Definition: zlktree.hh:331
void dot(std::ostream &, const char *id=nullptr) const
Render the ACD as in GraphViz format.
bool is_even() const
Whether the ACD globally corresponds to a min even or min odd parity acceptance.
Definition: zlktree.hh:362
unsigned state_step(unsigned node, unsigned edge) const
Step through the ACD, with rules for state-based output.
acd(const scc_info &si, acd_options opt=acd_options::NONE)
Build a Alternating Cycle Decomposition an SCC decomposition.
bool has_streett_shape() const
Whether the ACD has Streett shape.
A bit vector.
Definition: bitvect.hh:51
Compute an SCC map and gather assorted information.
Definition: sccinfo.hh:449
Abstract class for states.
Definition: twa.hh:47
Zielonka Tree implementation.
Definition: zlktree.hh:106
bool has_rabin_shape() const
Whether the Zielonka tree has Rabin shape.
Definition: zlktree.hh:174
bool has_parity_shape() const
Whether the Zielonka tree has parity shape.
Definition: zlktree.hh:191
bool has_streett_shape() const
Whether the Zielonka tree has Streett shape.
Definition: zlktree.hh:183
std::pair< unsigned, unsigned > step(unsigned branch, acc_cond::mark_t colors) const
Walk through the Zielonka tree.
zielonka_tree(const acc_cond &cond, zielonka_tree_options opt=zielonka_tree_options::NONE)
Build a Zielonka tree from the acceptance condition.
bool is_even() const
Whether the tree corresponds to a min even or min odd parity acceptance.
Definition: zlktree.hh:153
void dot(std::ostream &) const
Render the tree as in GraphViz format.
unsigned first_branch() const
The number of one branch in the tree.
Definition: zlktree.hh:124
bool empty_layer_is_even() const
Whether the layer corresponding to {} is even.
Definition: zlktree.hh:165
unsigned num_branches() const
The number of branches in the Zielonka tree.
Definition: zlktree.hh:116
zielonka_tree_options
Options to alter the behavior of acd.
Definition: zlktree.hh:33
acd_options
Options to alter the behavior of acd.
Definition: zlktree.hh:235
twa_graph_ptr zielonka_tree_transform(const const_twa_graph_ptr &aut)
Paritize an automaton using Zielonka tree.
twa_graph_ptr acd_transform(const const_twa_graph_ptr &aut, bool colored=false)
Paritize an automaton using ACD.
twa_graph_ptr acd_transform_sbacc(const const_twa_graph_ptr &aut, bool colored=false, bool order_heuristic=true)
Paritize an automaton using ACD.
@ NONE
Build the ZlkTree, without checking its shape.
@ CHECK_STREETT
Check if the ACD has Streett shape.
@ CHECK_RABIN
Check if the ACD has Rabin shape.
@ CHECK_PARITY
Check if the ACD has Parity shape.
@ NONE
Build the ACD, without checking its shape.
Definition: automata.hh:26
const mc_rvalue operator|(const mc_rvalue &lhs, const mc_rvalue &rhs)
This function helps to find the output value from a set of threads that may have different values.
Definition: mc.hh:130
An acceptance mark.
Definition: acc.hh:84
Definition: zlktree.hh:200

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