SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
ForwardHyperGraph.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <fstream>
4 #include <iostream>
5 #include <map>
6 #include <vector>
7 
8 namespace smtrat {
9 
10 /**
11  * This class implements a forward hypergraph.
12  *
13  * We define a hypergraph to be a graph structure $(V,E)$ where $V$ is a set of vertices and $E \subseteq 2^V$ a set of hyperedges.
14  * A hyperedge can connect an arbitrary number of vertices.
15  *
16  * If a hypergraph is directed if every edge $e \in E$ is partitioned into $I(e)$ and $O(e)$ that are sets of incoming vertices and outgoing vertices, respectively.
17  * A forward hypergraph is directed and every edge has only a single incoming vertices, that is $|I(e)| = 1$.
18  * Note that we store edges as a mapping from the incoming vertex to a set of outgoing vertices and thus do not have an explicit incoming vertex in our edge representation.
19  *
20  * This implementation of a forward hypergraph accepts arbitrary labels (called properties) for both vertices and edges.
21  * It relies on a dense list of vertices that are internally labeled starting from zero.
22  * Therefore, removal of vertices is not supported.
23  *
24  * If the third template parameter UniqueVertices is set to true (being the default), we make sure that every vertex is unique with respect to its property.
25  * To make this possible, a vertex property may not be changed in this case which is enforced using a static assertion.
26  * No requirements are imposed on the edge properties.
27  *
28  * This class supports both printing a simple text representation and writing a description to a dot file.
29  */
30 template<typename VertexProperty, typename EdgeProperty, bool UniqueVertices = true>
32 public:
33  /// Internal type of a vertex.
34  using Vertex = std::size_t;
35  /// Internal type of an edge.
36  struct Edge {
38  private:
39  /// Property of this edge.
40  EdgeProperty mProperty;
41  /// Outgoing vertices.
42  std::vector<Vertex> mOut;
43  public:
44  /// Constructor from a property.
45  Edge(const EdgeProperty& ep): mProperty(ep), mOut() {}
46  /// Add v to the outgoing vertices of this edge.
47  void addOut(Vertex v) {
48  mOut.emplace_back(v);
49  }
50  /// Access the property.
51  const EdgeProperty& operator*() const {
52  return mProperty;
53  }
54  /// Access the property.
55  EdgeProperty& operator*() {
56  return mProperty;
57  }
58  /// Access the property.
59  const EdgeProperty* operator->() const {
60  return &mProperty;
61  }
62  /// Access the property.
63  EdgeProperty* operator->() {
64  return &mProperty;
65  }
66  /// Retrieve the list of outgoing vertices.
67  const std::vector<Vertex>& out() const {
68  return mOut;
69  }
70  };
71 private:
72  /// Storage for all vertex properties.
73  std::vector<VertexProperty> mVertexProperties;
74  /// Mapping from vertices to outgoing edges.
75  std::vector<std::vector<Edge>> mEdges;
76  /// Mapping from vertex properties to vertices to ensure uniqueness.
77  std::map<VertexProperty,Vertex> mVertexMap;
78 public:
79  /// Returns a new vertex that is labeled with the given vertex property.
80  /// If UniqueVertices is set to true and a vector with the given property already exists, this vector is returned.
81  Vertex newVertex(const VertexProperty& vp) {
82  if (UniqueVertices) {
83  auto it = mVertexMap.find(vp);
84  if (it != mVertexMap.end()) return it->second;
85  mVertexMap.emplace(vp, mEdges.size());
86  }
87  mEdges.emplace_back();
88  mVertexProperties.emplace_back(vp);
89  return mEdges.size() - 1;
90  }
91  /// Creates a new edge where the given vertex is the incoming vertex that is labeled with the given edge property.
92  Edge& newEdge(Vertex source, const EdgeProperty& ep) {
93  assert(source < mEdges.size());
94  mEdges[source].emplace_back(ep);
95  return mEdges[source].back();
96  }
97  /// Creates a new edge where the given vertex is the incoming vertex that is labeled with the given edge property.
98  Edge& newEdge(const VertexProperty& source, const EdgeProperty& ep) {
99  return newEdge(getVertex(source), ep);
100  }
101 
102  /// Retrieves the vertex property for the given vertex.
103  const VertexProperty& operator[](Vertex v) const {
104  return mVertexProperties[v];
105  }
106  /// Retrieves the vertex property for the given vertex.
107  /// This method is disabled if UniqueVertices is set to true.
108  VertexProperty& operator[](Vertex v) {
109  static_assert(!UniqueVertices, "Non-const references to vertex properties are not supported if UniqueVertices is set to true.");
110  return mVertexProperties[v];
111  }
112 
113  /// Retrieves all outgoing edges for the given vertex.
114  const std::vector<Edge>& out(Vertex v) const {
115  return mEdges[v];
116  }
117  /// Retrieves all outgoing edges for the given vertex.
118  const std::vector<Edge>& out(const VertexProperty& v) const {
119  return mEdges[getVertex(v)];
120  }
121  /// Returns the first vertex.
122  Vertex begin() const {
123  return 0;
124  }
125  /// Returns the past-the-last vertex.
126  Vertex end() const {
127  return mVertexProperties.size();
128  }
129  /// Returns the number of vertices.
130  std::size_t size() const {
131  return mVertexProperties.size();
132  }
133  /// Writes a representation of this graph to the given file.
134  void toDot(const std::string& filename) const;
135 
136  /// Writes a textual representation of this graph to the given stream.
137  template<typename VP, typename EP>
138  friend std::ostream& operator<<(std::ostream& os, const ForwardHyperGraph<VP,EP>& fhg);
139 };
140 
141 /**
142  * This class encapsulates an algorithm for enumerating all cycles.
143  *
144  * This class implements an adaption of the algorithm described in @cite Johnson75.
145  * Unlike the algorithm described there, this version works on forward hypergraphs as implemented by ForwardHyperGraph.
146  *
147  * Although the algorithm works recursively, this implementation can be used somewhat iteratively.
148  * The cycles are given to the caller using an collector functor. If this functor returns true, the search for more cycles is aborted immediately.
149  * Due to this pattern, there is no need to store the cycles within this class and thus the memory usage is minimized.
150  */
151 template<typename FHG, typename Collector>
153 private:
154  /// Type of a vertex.
155  using Vertex = typename FHG::Vertex;
156  /// Reference to the graph we search cycles in.
157  const FHG& mGraph;
158 
159  /// Stores whether a vector is currently blocked.
160  std::vector<bool> mBlocked;
161  /// Stores vertex dependencies when vertices are blocked.
162  std::vector<std::vector<Vertex>> mBlockDependencies;
163  /// Stores the current list of vertices.
164  std::vector<typename FHG::Vertex> mVertexStack;
165  /// Stores the current list of edges.
166  std::vector<typename FHG::Edge> mEdgeStack;
167  /// The callback object.
168  Collector& mCollector;
169  /// Whether this search has been aborted by the collector.
170  bool mAborted;
171 public:
172  /// Constructor from a graph and a collector object.
173  CycleEnumerator(const FHG& fhg, Collector& c):
174  mGraph(fhg),
175  mBlocked(fhg.size(), false),
176  mBlockDependencies(fhg.size()),
177  mVertexStack(),
178  mEdgeStack(),
179  mCollector(c),
180  mAborted(false)
181  {}
182  /// Start the search for all cycles. Returns whether the search was finished (true) or aborted (false).
183  bool findAll();
184 
185 private:
186  /// Unblocks the given vertex and all vertices that depend on it.
187  void unblock(Vertex v) {
188  if (!mBlocked[v]) return;
189  mBlocked[v] = false;
190  for (auto u: mBlockDependencies[v]) unblock(u);
191  mBlockDependencies[v].clear();
192  }
193  /// Recursively enumerate all cycles that start in src and are currently in v.
194  bool enumerate(Vertex src, Vertex v);
195 };
196 
197 }
198 
199 #include "ForwardHyperGraph.tpp"
This class implements a forward hypergraph.
const std::vector< Edge > & out(const VertexProperty &v) const
Retrieves all outgoing edges for the given vertex.
void toDot(const std::string &filename) const
Writes a representation of this graph to the given file.
Edge & newEdge(const VertexProperty &source, const EdgeProperty &ep)
Creates a new edge where the given vertex is the incoming vertex that is labeled with the given edge ...
const std::vector< Edge > & out(Vertex v) const
Retrieves all outgoing edges for the given vertex.
std::vector< std::vector< Edge > > mEdges
Mapping from vertices to outgoing edges.
std::size_t Vertex
Internal type of a vertex.
const VertexProperty & operator[](Vertex v) const
Retrieves the vertex property for the given vertex.
Vertex end() const
Returns the past-the-last vertex.
Vertex newVertex(const VertexProperty &vp)
Returns a new vertex that is labeled with the given vertex property.
Edge & newEdge(Vertex source, const EdgeProperty &ep)
Creates a new edge where the given vertex is the incoming vertex that is labeled with the given edge ...
VertexProperty & operator[](Vertex v)
Retrieves the vertex property for the given vertex.
std::vector< VertexProperty > mVertexProperties
Storage for all vertex properties.
Vertex begin() const
Returns the first vertex.
std::size_t size() const
Returns the number of vertices.
friend std::ostream & operator<<(std::ostream &os, const ForwardHyperGraph< VP, EP > &fhg)
Writes a textual representation of this graph to the given stream.
std::map< VertexProperty, Vertex > mVertexMap
Mapping from vertex properties to vertices to ensure uniqueness.
Class to create the formulas for axioms.
This class encapsulates an algorithm for enumerating all cycles.
CycleEnumerator(const FHG &fhg, Collector &c)
Constructor from a graph and a collector object.
std::vector< std::vector< Vertex > > mBlockDependencies
Stores vertex dependencies when vertices are blocked.
std::vector< typename FHG::Vertex > mVertexStack
Stores the current list of vertices.
bool findAll()
Start the search for all cycles. Returns whether the search was finished (true) or aborted (false).
bool enumerate(Vertex src, Vertex v)
Recursively enumerate all cycles that start in src and are currently in v.
Collector & mCollector
The callback object.
void unblock(Vertex v)
Unblocks the given vertex and all vertices that depend on it.
const FHG & mGraph
Reference to the graph we search cycles in.
typename FHG::Vertex Vertex
Type of a vertex.
std::vector< typename FHG::Edge > mEdgeStack
Stores the current list of edges.
bool mAborted
Whether this search has been aborted by the collector.
std::vector< bool > mBlocked
Stores whether a vector is currently blocked.
Internal type of an edge.
const EdgeProperty * operator->() const
Access the property.
EdgeProperty * operator->()
Access the property.
EdgeProperty mProperty
Property of this edge.
std::vector< Vertex > mOut
Outgoing vertices.
Edge(const EdgeProperty &ep)
Constructor from a property.
void addOut(Vertex v)
Add v to the outgoing vertices of this edge.
const EdgeProperty & operator*() const
Access the property.
EdgeProperty & operator*()
Access the property.
const std::vector< Vertex > & out() const
Retrieve the list of outgoing vertices.