Version: 1.0
conact_tree.h
Go to the documentation of this file.
1 // Copyright(c) 2019
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met :
6 //
7 // *Redistributions of source code must retain the above copyright notice, this
8 // list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and / or other materials provided with the distribution.
13 //
14 // * Neither the name of GRAPHGEN nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #ifndef GRAPHGEN_CONACT_TREE_H_
30 #define GRAPHGEN_CONACT_TREE_H_
31 
32 #include <fstream>
33 
34 #include "condition_action.h"
35 #include "tree.h"
36 
37 #include "drag.h"
38 
59 bool LoadConactTree(BinaryDrag<conact>& t, const std::string& filename);
60 
62 bool WriteConactTree(const BinaryDrag<conact>& t, const std::string& filename);
63 
66 
75 
77 
78 // Instead of defining a novel format to save DRAGS, we save them as trees, then link
79 // identical sub-trees. Since the order of traversal is the same, the result should be the same.
80 // This should be removed because Save structure replace
81 bool LoadConactDrag(BinaryDrag<conact>& t, const std::string& filename);
82 
83 // Instead of defining a novel format to save DRAGS, we save them as trees, then link
84 // identical sub-trees. Since the order of traversal is the same, the result should be the same.
85 bool WriteConactDrag(BinaryDrag<conact>& t, const std::string& filename);
86 
87 struct Save {
88  std::ostream& os_;
89  std::unordered_set<BinaryDrag<conact>::node*> visited_;
90  std::unordered_map<BinaryDrag<conact>::node*, int> nodes_with_refs_;
91  int id_ = 0;
92 
94  {
95  if (nodes_with_refs_.find(n) != end(nodes_with_refs_)) {
96  if (!nodes_with_refs_[n])
97  nodes_with_refs_[n] = ++id_;
98  }
99  else {
100  nodes_with_refs_[n] = 0;
101  if (!n->isleaf()) {
102  CheckNodesTraversalRec(n->left);
103  CheckNodesTraversalRec(n->right);
104  }
105  }
106  }
107 
108  Save(std::ostream& os, BinaryDrag<conact>& bd) : os_(os)
109  {
110  for (auto& x : bd.roots_) {
112  }
113  for (auto& x : bd.roots_) {
114  SaveRec(x);
115  }
116  }
117 
118  void SaveRec(BinaryDrag<conact>::node* n, int tab = 0)
119  {
120  os_ << std::string(tab, '\t');
121 
122  if (!visited_.insert(n).second) {
123  os_ << "@ " << nodes_with_refs_[n] << "\n";
124  return;
125  }
126 
127  if (nodes_with_refs_[n]) {
128  os_ << "^ " << nodes_with_refs_[n] << " ";
129  }
130 
131  if (n->isleaf()) {
132  assert(n->data.t == conact::type::ACTION);
133  auto a = n->data.actions();
134  os_ << ". " << a[0];
135  for (size_t i = 1; i < a.size(); ++i) {
136  os_ << "," << a[i];
137  }
138  os_ << " - " << n->data.next << "\n";
139  }
140  else {
141  assert(n->data.t == conact::type::CONDITION);
142  os_ << n->data.condition << "\n";
143  SaveRec(n->left, tab + 1);
144  SaveRec(n->right, tab + 1);
145  }
146  }
147 };
148 
149 struct Load {
150  std::istream& is_;
152  std::unordered_map<int, BinaryDrag<conact>::node*> np_;
153 
154  Load(std::istream& is, BinaryDrag<conact>& bd) : is_(is), bd_(bd)
155  {
156  np_[0] = nullptr;
157  while (true) {
159  if (n == nullptr)
160  break;
161  bd_.AddRoot(n);
162  }
163  }
164 
166  {
167  std::string s;
168  while (is_ >> s) {
169  if (s[0] == '#') {
170  getline(is_, s);
171  }
172  else {
173  break;
174  }
175  }
176 
177  if (!is_) {
178  return nullptr;
179  }
180 
181  if (s == "@") {
182  int pos;
183  is_ >> pos;
184  return np_[pos];
185  }
186 
187  auto n = bd_.make_node();
188 
189  if (s == "^") {
190  int pos;
191  is_ >> pos >> s;
192  np_[pos] = n;
193  }
194 
195  if (s == ".") {
196  // leaf
197  n->data.t = conact::type::ACTION;
198  do {
199  int action;
200  is_ >> action >> std::ws;
201  n->data.action.set(action - 1);
202  } while (is_.peek() == ',' && is_.get());
203 
204  if (is_.get() != '-') {
205  throw;
206  }
207  is_ >> n->data.next;
208  }
209  else {
210  // real node with branches
211  n->data.t = conact::type::CONDITION;
212  n->data.condition = s;
213 
214  n->left = LoadConactTreeRec();
215  n->right = LoadConactTreeRec();
216  }
217 
218  return n;
219  }
220 };
221 
222 #endif // !GRAPHGEN_CONACT_TREE_H_
223 
224 
225 
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
bool LoadConactDrag(BinaryDrag< conact > &t, const std::string &filename)
bool WriteConactDrag(BinaryDrag< conact > &t, const std::string &filename)
void IntersectTrees(BinaryDrag< conact >::node *n1, BinaryDrag< conact >::node *n2)
bool EqualTrees(const BinaryDrag< conact >::node *n1, const BinaryDrag< conact >::node *n2)
Checks whether two (sub)trees 'n1' and 'n2' are equal or nor.
bool WriteConactTree(const BinaryDrag< conact > &t, const std::string &filename)
Saves a tree into a file structured as described in the LoadConactTree()
void intersect_leaves(BinaryDrag< conact >::node *n1, BinaryDrag< conact >::node *n2)
Definition: conact_tree.cpp:96
bool LoadConactTree(BinaryDrag< conact > &t, const std::string &filename)
Loads a tree from file.
bool equivalent_trees(const BinaryDrag< conact >::node *n1, const BinaryDrag< conact >::node *n2)
Definition: conact_tree.cpp:86
std::istream & is_
Definition: conact_tree.h:150
Load(std::istream &is, BinaryDrag< conact > &bd)
Definition: conact_tree.h:154
std::unordered_map< int, BinaryDrag< conact >::node * > np_
Definition: conact_tree.h:152
BinaryDrag< conact > & bd_
Definition: conact_tree.h:151
BinaryDrag< conact >::node * LoadConactTreeRec()
Definition: conact_tree.h:165
Save(std::ostream &os, BinaryDrag< conact > &bd)
Definition: conact_tree.h:108
std::ostream & os_
Definition: conact_tree.h:88
void CheckNodesTraversalRec(BinaryDrag< conact >::node *n)
Definition: conact_tree.h:93
std::unordered_map< BinaryDrag< conact >::node *, int > nodes_with_refs_
Definition: conact_tree.h:90
void SaveRec(BinaryDrag< conact >::node *n, int tab=0)
Definition: conact_tree.h:118
int id_
Definition: conact_tree.h:91
std::unordered_set< BinaryDrag< conact >::node * > visited_
Definition: conact_tree.h:89