Version: 1.0
conact_tree.cpp
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 #include "conact_tree.h"
8 #include "drag2optimal.h"
9 
10 #include <cassert>
11 
12 using namespace std;
13 
14 static BinaryDrag<conact>::node* LoadConactTreeRec(BinaryDrag<conact>& t, ifstream& is)
15 {
16  string s;
17  while (is >> s) {
18  if (s[0] == '#')
19  getline(is, s);
20  else
21  break;
22  }
23 
25  if (s == ".") {
26  // leaf
27  n->data.t = conact::type::ACTION;
28  do {
29  int action;
30  is >> action >> ws;
31  n->data.action.set(action - 1);
32  } while (is.peek() == ',' && is.get());
33  }
34  else {
35  // real node with branches
36  n->data.t = conact::type::CONDITION;
37  n->data.condition = s;
38 
39  n->left = LoadConactTreeRec(t, is);
40  n->right = LoadConactTreeRec(t, is);
41  }
42 
43  return n;
44 }
45 
46 bool LoadConactTree(BinaryDrag<conact>& t, const string& filename)
47 {
48  ifstream is(filename);
49  if (!is) {
50  return false;
51  }
52 
53  t.AddRoot(LoadConactTreeRec(t, is));
54  return true;
55 }
56 
57 static void WriteConactTreeRec(const BinaryDrag<conact>::node* n, ofstream& os, size_t tab = 0)
58 {
59  os << string(tab, '\t');
60  if (n->isleaf()) {
61  assert(n->data.t == conact::type::ACTION);
62  auto a = n->data.actions();
63  os << ". " << a[0];
64  for (size_t i = 1; i < a.size(); ++i)
65  os << "," << a[i];
66  os << "\n";
67  }
68  else {
69  assert(n->data.t == conact::type::CONDITION);
70  os << n->data.condition << "\n";
71  WriteConactTreeRec(n->left, os, tab + 1);
72  WriteConactTreeRec(n->right, os, tab + 1);
73  }
74 }
75 
76 bool WriteConactTree(const BinaryDrag<conact>& t, const string& filename)
77 {
78  ofstream os(filename);
79  if (!os)
80  return false;
81  WriteConactTreeRec(t.GetRoot(), os);
82  return true;
83 }
84 
85 // Checks if two subtrees 'n1' and 'n2' are equivalent or not
87  if (n1->data.neq(n2->data))
88  return false;
89 
90  if (n1->isleaf())
91  return true;
92  else
93  return equivalent_trees(n1->left, n2->left) && equivalent_trees(n1->right, n2->right);
94 }
95 
97  if (n1->isleaf()) {
98  n2->data.action = n1->data.action &= n2->data.action;
99  }
100  else {
101  intersect_leaves(n1->left, n2->left);
102  intersect_leaves(n1->right, n2->right);
103  }
104 }
105 
106 // Checks if two (sub)trees 'n1' and 'n2' are equal
108  if (n1->data != n2->data)
109  return false;
110 
111  if (n1->isleaf())
112  return true;
113  else
114  return EqualTrees(n1->left, n2->left) && EqualTrees(n1->right, n2->right);
115 }
116 
117 // Works only with equivalent trees
119  if (n1->isleaf()) {
120  n1->data.action &= n2->data.action;
121  n2->data.action = n1->data.action;
122  }
123  else {
124  IntersectTrees(n1->left, n2->left);
125  IntersectTrees(n1->right, n2->right);
126  }
127 }
128 
129 bool LoadConactDrag(BinaryDrag<conact>& t, const string& filename)
130 {
131  if (!LoadConactTree(t, filename))
132  return false;
133 
135 
136  return true;
137 }
138 
139 bool WriteConactDrag(BinaryDrag<conact>& t, const string& filename)
140 {
141  return WriteConactTree(t, filename);
142 }
143 
A BinaryDrag is the GRAPHGEN implementation of a Binary Directed Rooted Acyclic Graph (DRAG in short)
Definition: drag.h:28
node * GetRoot() const
Returns the last root of the BinaryDrag.
Definition: drag.h:66
void AddRoot(node *r)
Adds a new root to the vector of roots.
Definition: drag.h:61
node * make_node(Args &&... args)
Creates and returns a new node updating the nodes_ vector.
Definition: drag.h:53
bool WriteConactTree(const BinaryDrag< conact > &t, const string &filename)
Definition: conact_tree.cpp:76
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 LoadConactDrag(BinaryDrag< conact > &t, const string &filename)
bool LoadConactTree(BinaryDrag< conact > &t, const string &filename)
Definition: conact_tree.cpp:46
bool WriteConactDrag(BinaryDrag< conact > &t, const string &filename)
void intersect_leaves(BinaryDrag< conact >::node *n1, BinaryDrag< conact >::node *n2)
Definition: conact_tree.cpp:96
bool equivalent_trees(const BinaryDrag< conact >::node *n1, const BinaryDrag< conact >::node *n2)
Definition: conact_tree.cpp:86
void Dag2DagUsingIdenties(BinaryDrag< conact > &t)