aGrUM  0.16.0
pattern.cpp
Go to the documentation of this file.
1 
31 
32 #ifdef GUM_NO_INLINE
34 #endif // GUM_NO_INLINE
35 
36 namespace gum {
37  namespace prm {
38  namespace gspan {
39 
40  Pattern::Pattern(const Pattern& source) : DiGraph(), __last(0) {
41  GUM_CONS_CPY(Pattern);
42  NodeProperty< NodeId > node_map;
43 
44  for (NodeId node = 1; node <= source.size(); ++node) {
45  node_map.insert(
46  node, addNodeWithLabel(const_cast< LabelData& >(source.label(node))));
47  }
48 
49  for (const auto edge : source.code().codes)
50  addArc(node_map[edge->i],
51  node_map[edge->j],
52  const_cast< LabelData& >(
53  source.label(node_map[edge->i], node_map[edge->j])));
54  }
55 
57  for (const auto node : nodes()) {
58  for (const auto next : parents(node)) {
59  Size u = label(node).id;
60  Size v = label(next).id;
61  EdgeCode edge_code(1, 2, u, label(next, node).id, v);
62 
63  if (edge_code < *(code().codes.front())) {
64  return false;
65  } else if (edge_code == (*code().codes.front())) {
66  if (__expandCodeIsMinimal(node, next)) { return false; }
67  }
68  }
69 
70  for (const auto next : children(node)) {
71  Size u = label(node).id;
72  Size v = label(next).id;
73  EdgeCode edge_code(1, 2, u, label(node, next).id, v);
74 
75  if (edge_code < *(code().codes.front())) {
76  return false;
77  } else if (edge_code == (*code().codes.front())) {
78  if (__expandCodeIsMinimal(node, next)) { return false; }
79  }
80  }
81  }
82 
83  return true;
84  }
85 
86  std::string Pattern::toDot(size_t name) const {
87  std::stringstream sBuff;
88  sBuff << "digraph " << name << " {\n";
89 
90  for (const auto arc : arcs()) {
91  sBuff << label(arc.tail()).id << " -> ";
92  sBuff << label(arc.head()).id << ";\n";
93  }
94 
95  sBuff << "}\n";
96  return sBuff.str();
97  }
98 
101  Pattern p;
102  node_map.insert(u, p.addNodeWithLabel(label(u)));
103  node_map.insert(v, p.addNodeWithLabel(label(v)));
104 
105  try {
106  p.addArc(1, 2, label(u, v));
107  } catch (NotFound&) { p.addArc(1, 2, label(v, u)); }
108 
109  for (const auto nei : children(u))
110  if (nei != v)
111  if (__rec(p, node_map, u, nei)) return true;
112 
113  for (const auto nei : parents(u))
114  if (nei != v)
115  if (__rec(p, node_map, u, nei)) return true;
116 
117  for (const auto nei : children(v))
118  if (nei != u)
119  if (__rec(p, node_map, v, nei)) return true;
120 
121  for (const auto nei : parents(v))
122  if (nei != u)
123  if (__rec(p, node_map, v, nei)) return true;
124 
125  return false;
126  }
127 
129  Bijection< NodeId, NodeId >& node_map,
130  NodeId u,
131  NodeId v) {
132  if (node_map.existsFirst(v)) {
133  if (node_map.second(u) < node_map.second(v)) {
134  // Invalid forward edge
135  return false;
136  } else if ((p.existsArc(node_map.second(u), node_map.second(v)))
137  || (p.existsArc(node_map.second(v), node_map.second(u)))) {
138  // Duplicate arc !
139  return false;
140  }
141  } else {
142  node_map.insert(v, p.addNodeWithLabel(label(v)));
143  }
144 
145  // Retrieving arc label data
146  LabelData* data = 0;
147 
148  try {
149  data = &(label(u, v));
150  } catch (NotFound&) { data = &(label(v, u)); }
151 
152  // Adding arc
153  try {
154  p.addArc(node_map.second(u), node_map.second(v), *data);
155  } catch (OperationNotAllowed&) {
156  // Invalid neighbor
157  if (node_map.second(u) < node_map.second(v)) {
158  p.remove(node_map.second(v));
159  node_map.eraseFirst(v);
160  }
161 
162  return false;
163  }
164 
165  // Check if this is minimal or if equal find another growth
166  size_t depth = p.code().codes.size() - 1;
167 
168  if (*(p.code().codes.back()) < *(code().codes[depth])) {
169  return true;
170  } else if (*(p.code().codes.back()) == *(code().codes[depth])) {
171  std::list< NodeId > r_path;
172  p.rightmostPath(r_path);
173 
174  for (const auto node : r_path) {
175  for (const auto nei : children(node_map.first(node)))
176  if (__rec(p, node_map, node_map.first(node), nei)) return true;
177 
178  for (const auto nei : parents(node_map.first(node)))
179  if (__rec(p, node_map, node_map.first(node), nei)) return true;
180  }
181  }
182 
183  if (p.code().codes.back()->isForward()) node_map.eraseFirst(v);
184 
185  p.pop_back();
186  return false;
187  }
188 
190  Bijection< NodeId, NodeId >& node_map,
191  NodeId a_u,
192  NodeId a_v) {
193  std::vector< std::pair< NodeId, NodeId > > stack;
194  std::vector< size_t > rec_call;
195  stack.push_back(std::make_pair(a_u, a_v));
196  NodeId u = 0;
197  NodeId v = 0;
198 
199  while (!stack.empty()) {
200  bool go = true;
201  u = stack.back().first;
202  v = stack.back().second;
203  stack.pop_back();
204 
205  if ((u == 0) && (v == 0)) {
206  p.pop_back();
207  } else {
208  if (node_map.existsFirst(v)) {
209  if (node_map.second(u) < node_map.second(v)) {
210  // Invalid forward edge
211  go = false;
212  } else if ((p.existsArc(node_map.second(u), node_map.second(v)))
213  || (p.existsArc(node_map.second(v),
214  node_map.second(u)))) {
215  // Duplicate arc !
216  go = false;
217  }
218  } else {
219  node_map.insert(v, p.addNodeWithLabel(label(v)));
220  }
221 
222  if (go) {
223  // Retrieving arc label data
224  LabelData* data = 0;
225 
226  try {
227  data = &(label(u, v));
228  } catch (NotFound&) { data = &(label(v, u)); }
229 
230  // Adding arc
231  try {
232  p.addArc(node_map.second(u), node_map.second(v), *data);
233  } catch (OperationNotAllowed&) {
234  // Invalid neighbor
235  if (node_map.second(u) < node_map.second(v)) {
236  p.remove(node_map.second(v));
237  node_map.eraseFirst(v);
238  }
239 
240  go = false;
241  }
242 
243  if (go) {
244  // Check if this is minimal or if equal find another growth
245  size_t depth = p.code().codes.size() - 1;
246 
247  if (*(p.code().codes.back()) < *(code().codes[depth])) {
248  return true;
249  } else if (*(p.code().codes.back()) == *(code().codes[depth])) {
250  std::list< NodeId > r_path;
251  p.rightmostPath(r_path);
252  stack.push_back(std::make_pair((NodeId)0, (NodeId)0));
253 
254  for (const auto node : r_path) {
255  for (const auto nei : children(node)) {
256  stack.push_back(std::make_pair(node_map.first(node), nei));
257  ++(rec_call.back());
258  }
259 
260  for (const auto nei : parents(node)) {
261  stack.push_back(std::make_pair(node_map.first(node), nei));
262  ++(rec_call.back());
263  }
264  }
265  }
266 
267  if (p.code().codes.back()->isForward()) node_map.eraseFirst(v);
268  }
269  }
270  }
271  }
272 
273  return false;
274  }
275 
276  } /* namespace gspan */
277  } /* namespace prm */
278 } /* namespace gum */
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
const T1 & first(const T2 &second) const
Returns the first value of a pair given its second value.
Inner class to handle data about labels in this interface graph.
void eraseFirst(const T1 &first)
Erases an association containing the given first element.
Pattern()
Default constructor.
Definition: pattern_inl.h:35
DFSCode & code()
Returns the DFSCode of this Pattern.
Definition: pattern_inl.h:173
NodeId addNodeWithLabel(LabelData &l)
Insert a node with the given LabelData.
Definition: pattern_inl.h:41
bool __expandCodeIsMinimal(NodeId u, NodeId v)
Returns true if the expand code by adding and edge betwenne u and v is minimal with respect to __code...
Definition: pattern.cpp:99
bool isMinimal()
Returns the DFSCode of this Pattern.
Definition: pattern.cpp:56
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
std::vector< EdgeCode *> codes
The vector containing the EdgeCode composing this DFSCode.
Definition: DFSCode.h:90
The class for generic Hash Tables.
Definition: hashTable.h:679
LabelData & label(NodeId node)
Returns the LabelData assigned to node.
Definition: pattern_inl.h:50
represent a DFS code used by gspan.
Definition: edgeCode.h:52
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
Size size() const
Returns the number of nodes in this Pattern.
Definition: pattern_inl.h:147
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Base class for all oriented graphs.
Definition: diGraph.h:111
virtual const std::string toDot() const
to friendly display the content of the graph in the DOT syntax
Definition: diGraph.cpp:68
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1805
bool __not_rec(Pattern &p, Bijection< NodeId, NodeId > &node_map, NodeId u, NodeId v)
A non recursive bugged version of __rec.
Definition: pattern.cpp:189
const NodeGraphPart & nodes() const
Definition: pattern_inl.h:166
void rightmostPath(std::list< NodeId > &r_path) const
Fill r_path with the rightmost path of this Pattern. The list is supposed empty.
Definition: pattern_inl.h:153
const ArcSet & arcs() const
Definition: pattern_inl.h:170
Idx id
An unique identifier for this label.
bool __rec(Pattern &p, Bijection< NodeId, NodeId > &node_map, NodeId u, NodeId v)
Recurisve method used by __expandCodeIsMinimal.
Definition: pattern.cpp:128
void pop_back()
Remove the last EdgeCode of this pattern.
Definition: pattern_inl.h:207
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
void addArc(NodeId i, NodeId j, LabelData &l)
Add an arc to this Pattern.
Definition: pattern_inl.h:118
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
void remove(NodeId node)
Remove a node if it has no neighbors, raise an OperationNotAllowed otherwise.
Definition: pattern_inl.h:225
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
This contains all the information we want for a node in a DFSTree.
Definition: pattern.h:73
bool existsArc(const Arc &arc) const
indicates whether a given arc exists
Size NodeId
Type for node ids.
Definition: graphElements.h:98