Version: 1.0
drag.h
Go to the documentation of this file.
1 // Copyright (c) 2020, the GRAPHGEN contributors, as
2 // shown by the AUTHORS file. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6 
7 #ifndef GRAPHGEN_DRAG_H_
8 #define GRAPHGEN_DRAG_H_
9 
10 #include <algorithm>
11 #include <cassert>
12 #include <iostream>
13 #include <memory>
14 #include <unordered_map>
15 #include <unordered_set>
16 #include <istream>
17 #include <vector>
18 
19 
27 template<typename T>
28 class BinaryDrag {
29 public:
31  struct node
32  {
33  T data;
34  node *left = nullptr, *right = nullptr;
35  //std::vector<node *> parents_;
36 
37  node() {}
38  node(T d) : data(std::move(d)) {}
39  node(T d, node* l, node* r) : data(std::move(d)), left(l), right(r) {}
40  //node(T d, node* l, node* r, std::vector<node *> parents) : data(std::move(d)), left(l), right(r), parents_(parents) {}
41 
42  bool isleaf() const {
43  return left == nullptr && right == nullptr;
44  }
45  };
46 
49  std::vector<std::unique_ptr<node>> nodes_;
50 
52  template<typename... Args>
53  node* make_node(Args&&... args) {
54  nodes_.emplace_back(std::make_unique<node>(std::forward<Args>(args)...));
55  return nodes_.back().get();
56  }
57 
58  std::vector<node *> roots_;
59 
61  void AddRoot(node* r) {
62  roots_.push_back(r);
63  }
64 
66  node* GetRoot() const {
67  return roots_.front();
68  }
69 
71  friend void swap(BinaryDrag& bd1, BinaryDrag& bd2) {
72  using std::swap;
73  swap(bd1.roots_, bd2.roots_);
74  swap(bd1.nodes_, bd2.nodes_);
75  }
76 
86  node *MakeCopyRecursive(node* n, std::unordered_map<node*, node*>& copies) {
87  if (n == nullptr)
88  return nullptr;
89 
90  if (!copies[n]) {
91  node *nn = make_node();
92  nn->data = n->data;
93  nn->left = MakeCopyRecursive(n->left, copies);
94  nn->right = MakeCopyRecursive(n->right, copies);
95  return copies[n] = nn;
96  }
97  return copies[n];
98  }
99 
102 
104  BinaryDrag(const BinaryDrag& bd) {
105  std::unordered_map<node*, node*> copies;
106  for (const auto& x : bd.roots_) {
107  roots_.push_back(MakeCopyRecursive(x, copies));
108  }
109  /*for (const auto& n : bd.nodes_) {
110  auto& nn = copies[n.get()];
111  for (const auto& p : n->parents_) {
112  nn->parents_.push_back(copies[p]);
113  }
114  }*/
115  }
116 
118  BinaryDrag(const BinaryDrag& bd, std::vector<node*>& tracked_nodes) {
119  std::unordered_map<node*, node*> copies;
120  for (const auto& x : bd.roots_) {
121  roots_.push_back(MakeCopyRecursive(x, copies));
122  }
123  /*for (const auto& n : bd.nodes_) {
124  auto& nn = copies[n.get()];
125  for (const auto& p : n->parents_) {
126  nn->parents_.push_back(copies[p]);
127  }
128  }*/
129  for (auto& n : tracked_nodes) {
130  n = copies[n];
131  }
132  }
133 
135  swap(*this, t);
136  }
137 
140  swap(*this, t);
141  return *this;
142  }
143 
146  roots_.push_back(make_node());
147  return roots_.back();
148  }
149 };
150 
151 //class ConactBinaryDrag : BinaryDrag<conact> {
152 //public:
153 // ConactBinaryDrag(std::istream& is) {
154 // Load(is, *this);
155 // }
156 //
157 // bool Serialize(const std::string& filename) {
158 // std::ofstream os(filename);
159 //
160 // if (!os) {
161 // return false;
162 // }
163 //
164 // return Serialize(os);
165 // }
166 //
167 // bool Serialize(std::ostream& os = std::cout) {
168 // if (!os) {
169 // return false;
170 // }
171 //
172 // Save(os, *this);
173 // return true;
174 // }
175 //
176 //private:
177 // struct Save {
178 // std::ostream& os_;
179 // std::unordered_set<ConactBinaryDrag::node*> visited_;
180 // std::unordered_map<ConactBinaryDrag::node*, int> nodes_with_refs_;
181 // int id_ = 0;
182 //
183 // void CheckNodesTraversalRec(BinaryDrag<conact>::node *n)
184 // {
185 // if (nodes_with_refs_.find(n) != end(nodes_with_refs_)) {
186 // if (!nodes_with_refs_[n])
187 // nodes_with_refs_[n] = ++id_;
188 // }
189 // else {
190 // nodes_with_refs_[n] = 0;
191 // if (!n->isleaf()) {
192 // CheckNodesTraversalRec(n->left);
193 // CheckNodesTraversalRec(n->right);
194 // }
195 // }
196 // }
197 //
198 // Save(std::ostream& os, ConactBinaryDrag& bd) : os_(os)
199 // {
200 // for (auto& x : bd.roots_) {
201 // CheckNodesTraversalRec(x);
202 // }
203 // for (auto& x : bd.roots_) {
204 // SaveRec(x);
205 // }
206 // }
207 //
208 // void SaveRec(ConactBinaryDrag::node* n, int tab = 0)
209 // {
210 // os_ << std::string(tab, '\t');
211 //
212 // if (!visited_.insert(n).second) {
213 // os_ << "@ " << nodes_with_refs_[n] << "\n";
214 // return;
215 // }
216 //
217 // if (nodes_with_refs_[n]) {
218 // os_ << "^ " << nodes_with_refs_[n] << " ";
219 // }
220 //
221 // if (n->isleaf()) {
222 // assert(n->data.t == conact::type::ACTION);
223 // auto a = n->data.actions();
224 // os_ << ". " << a[0];
225 // for (size_t i = 1; i < a.size(); ++i) {
226 // os_ << "," << a[i];
227 // }
228 // os_ << " - " << n->data.next << "\n";
229 // }
230 // else {
231 // assert(n->data.t == conact::type::CONDITION);
232 // os_ << n->data.condition << "\n";
233 // SaveRec(n->left, tab + 1);
234 // SaveRec(n->right, tab + 1);
235 // }
236 // }
237 // };
238 //
239 // struct Load {
240 // std::istream& is_;
241 // ConactBinaryDrag& bd_;
242 // std::vector<ConactBinaryDrag::node*> np_;
243 //
244 // Load(std::istream& is, ConactBinaryDrag& bd) : is_(is), bd_(bd)
245 // {
246 // np_.push_back(nullptr);
247 // while (true) {
248 // ConactBinaryDrag::node* n = LoadConactTreeRec();
249 // if (n == nullptr)
250 // break;
251 // bd_.AddRoot(n);
252 // }
253 // }
254 //
255 // ConactBinaryDrag::node* LoadConactTreeRec()
256 // {
257 // std::string s;
258 // while (is_ >> s) {
259 // if (s[0] == '#') {
260 // getline(is_, s);
261 // }
262 // else {
263 // break;
264 // }
265 // }
266 //
267 // if (!is_) {
268 // return nullptr;
269 // }
270 //
271 // if (s == "@") {
272 // int pos;
273 // is_ >> pos;
274 // return np_[pos];
275 // }
276 //
277 // auto n = bd_.make_node();
278 //
279 // if (s == "^") {
280 // int pos;
281 // is_ >> pos >> s;
282 // if (pos != np_.size()) {
283 // throw;
284 // }
285 // np_.push_back(n);
286 // }
287 //
288 // if (s == ".") {
289 // // leaf
290 // n->data.t = conact::type::ACTION;
291 // do {
292 // int action;
293 // is_ >> action >> std::ws;
294 // n->data.action.set(action - 1);
295 // } while (is_.peek() == ',' && is_.get());
296 //
297 // if (is_.get() != '-') {
298 // throw;
299 // }
300 // is_ >> n->data.next;
301 // }
302 // else {
303 // // real node with branches
304 // n->data.t = conact::type::CONDITION;
305 // n->data.condition = s;
306 //
307 // n->left = LoadConactTreeRec();
308 // n->right = LoadConactTreeRec();
309 // }
310 //
311 // return n;
312 // }
313 // };
314 //};
315 
316 #endif // !GRAPHGEN_DRAG_H_
A BinaryDrag is the GRAPHGEN implementation of a Binary Directed Rooted Acyclic Graph (DRAG in short)
Definition: drag.h:28
friend void swap(BinaryDrag &bd1, BinaryDrag &bd2)
Definition: drag.h:71
node * MakeCopyRecursive(node *n, std::unordered_map< node *, node * > &copies)
Recursive function to copy a BinaryDrag.
Definition: drag.h:86
BinaryDrag(BinaryDrag &&t)
Definition: drag.h:134
node * make_root()
Creates a new root updating the roots_ vector.
Definition: drag.h:145
node * GetRoot() const
Returns the last root of the BinaryDrag.
Definition: drag.h:66
BinaryDrag & operator=(BinaryDrag t)
Copy assignment.
Definition: drag.h:139
BinaryDrag(const BinaryDrag &bd, std::vector< node * > &tracked_nodes)
Special copy constructor that allows to track where the nodes in a tree have been copied to.
Definition: drag.h:118
BinaryDrag()
Empty constructor.
Definition: drag.h:101
BinaryDrag(const BinaryDrag &bd)
Copy constructor.
Definition: drag.h:104
void AddRoot(node *r)
Adds a new root to the vector of roots.
Definition: drag.h:61
std::vector< node * > roots_
Definition: drag.h:58
node * make_node(Args &&... args)
Creates and returns a new node updating the nodes_ vector.
Definition: drag.h:53
std::vector< std::unique_ptr< node > > nodes_
Vector of unique pointers to BinaryDrag nodes. This is useful to automatically free the memory of the...
Definition: drag.h:49
Defines a node of the BinaryDrag.
Definition: drag.h:32
node(T d)
Definition: drag.h:38
node(T d, node *l, node *r)
Definition: drag.h:39
node * left
Definition: drag.h:34
node * right
Definition: drag.h:34
bool isleaf() const
Definition: drag.h:42