aGrUM  0.18.1
a C++ library for (probabilistic) graphical models
O3NameSolver_tpl.h
Go to the documentation of this file.
1 
32 
33 namespace gum {
34  namespace prm {
35  namespace o3prm {
36 
37  template < typename GUM_SCALAR >
39  O3PRM& o3_prm,
40  ErrorsContainer& errors) :
41  prm__(&prm),
42  o3_prm__(&o3_prm), errors__(&errors) {
43  GUM_CONSTRUCTOR(O3NameSolver);
44  }
45 
46  template < typename GUM_SCALAR >
48  const O3NameSolver< GUM_SCALAR >& src) :
49  prm__(src.prm__),
54  GUM_CONS_CPY(O3NameSolver);
55  }
56 
57  template < typename GUM_SCALAR >
60  prm__(std::move(src.prm__)),
61  o3_prm__(std::move(src.o3_prm__)), errors__(std::move(src.errors__)),
62  typeName__(std::move(src.typeName__)),
63  eltName__(std::move(src.eltName__)), refName__(std::move(src.refName__)),
65  className__(std::move(src.className__)) {
66  GUM_CONS_MOV(O3NameSolver);
67  }
68 
69  template < typename GUM_SCALAR >
71  GUM_DESTRUCTOR(O3NameSolver);
72  }
73 
74  template < typename GUM_SCALAR >
76  const O3NameSolver< GUM_SCALAR >& src) {
77  if (this == &src) { return *this; }
78  prm__ = src.prm__;
79  o3_prm__ = src.o3_prm__;
80  errors__ = src.errors__;
81  typeName__ = src.typeName__;
82  eltName__ = src.eltName__;
83  refName__ = src.refName__;
86  return *this;
87  }
88 
89  template < typename GUM_SCALAR >
92  if (this == &src) { return *this; }
93  prm__ = std::move(src.prm__);
94  o3_prm__ = std::move(src.o3_prm__);
95  errors__ = std::move(src.errors__);
96  typeName__ = std::move(src.typeName__);
97  eltName__ = std::move(src.eltName__);
98  refName__ = std::move(src.refName__);
99  interfaceName__ = std::move(src.interfaceName__);
100  className__ = std::move(src.className__);
101  return *this;
102  }
103 
104  template < typename GUM_SCALAR >
106  // If empty string, we return an empty string
107  if (name.label() == "") { return true; }
108  // If we've already found the element real name
109  if (eltName__.exists(name.label())) {
110  name.label() = eltName__[name.label()];
111  return true;
112  }
113  // If name exists as is
114  if (prm__->isType(name.label())) {
115  eltName__.insert(name.label(), name.label());
116  return true;
117  }
118  // If name exists as is
119  if (prm__->isInterface(name.label())) {
120  eltName__.insert(name.label(), name.label());
121  return true;
122  }
123  // If name exists as is
124  if (prm__->isClass(name.label())) {
125  eltName__.insert(name.label(), name.label());
126  return true;
127  }
128  // If name exists as is in O3PRM types
129  for (auto& t: o3_prm__->types()) {
130  if (t->name().label() == name.label()) {
131  eltName__.insert(name.label(), name.label());
132  return true;
133  }
134  }
135  // If name exists as is in O3PRM interfaces
136  for (auto& i: o3_prm__->interfaces()) {
137  if (i->name().label() == name.label()) {
138  eltName__.insert(name.label(), name.label());
139  return true;
140  }
141  }
142  // If name exists as is in O3PRM classes
143  for (auto& c: o3_prm__->classes()) {
144  if (c->name().label() == name.label()) {
145  eltName__.insert(name.label(), name.label());
146  return true;
147  }
148  }
149 
150  auto lookup = "." + name.label();
151  auto found = Set< std::string >();
152  auto matches = std::vector< std::string >();
153 
154  // Trying with types
155  for (auto t: prm__->types()) {
156  if (endsWith(t->name(), lookup)) {
157  if (!found.exists(t->name())) {
158  found.insert(t->name());
159  matches.push_back(t->name());
160  }
161  }
162  }
163  // Trying with O3Types
164  for (auto& t: o3_prm__->types()) {
165  if (endsWith(t->name().label(), lookup)) {
166  if (!found.exists(t->name().label())) {
167  found.insert(t->name().label());
168  matches.push_back(t->name().label());
169  }
170  }
171  }
172 
173  // Trying with interfaces
174  for (auto i: prm__->interfaces()) {
175  if (endsWith(i->name(), lookup)) {
176  if (!found.exists(i->name())) {
177  found.insert(i->name());
178  matches.push_back(i->name());
179  }
180  }
181  }
182  // Trying with O3Interface
183  for (auto& i: o3_prm__->interfaces()) {
184  if (endsWith(i->name().label(), lookup)) {
185  if (!found.exists(i->name().label())) {
186  found.insert(i->name().label());
187  matches.push_back(i->name().label());
188  }
189  }
190  }
191 
192  // Trying with class
193  for (auto c: prm__->classes()) {
194  if (endsWith(c->name(), lookup)) {
195  if (!found.exists(c->name())) {
196  found.insert(c->name());
197  matches.push_back(c->name());
198  }
199  }
200  }
201  // Trying with O3Class
202  for (auto& c: o3_prm__->classes()) {
203  if (endsWith(c->name().label(), lookup)) {
204  if (!found.exists(c->name().label())) {
205  found.insert(c->name().label());
206  matches.push_back(c->name().label());
207  }
208  }
209  }
210 
211  if (matches.size() == 1) { // One match is good
212  eltName__.insert(name.label(), matches.back());
213  name.label() = matches.back();
214  return true;
215 
216  } else if (matches.size() == 0) { // 0 match is not found
217 
218  // Unknown name type
219  O3PRM_TYPE_NOT_FOUND(name, *errors__);
220  return false;
221 
222  } else { // More than one match is ambiguous
223 
224  // Ambiguous name
225  O3PRM_TYPE_AMBIGUOUS(name, matches, *errors__);
226  return false;
227  }
228  }
229 
230  template < typename GUM_SCALAR >
232  // If empty string, we return an empty string
233  if (name.label() == "") { return true; }
234 
235  // If we've already found the type real name
236  if (typeName__.exists(name.label())) {
237  name.label() = typeName__[name.label()];
238  return true;
239  }
240 
241  // If name exists as is in PRM
242  if (prm__->isType(name.label())) {
243  typeName__.insert(name.label(), name.label());
244  return true;
245  }
246 
247  // If name exists as is in O3PRM
248  for (auto& t: o3_prm__->types()) {
249  if (t->name().label() == name.label()) {
250  typeName__.insert(name.label(), name.label());
251  return true;
252  }
253  }
254 
255  // If we didn't find it as is, then we must find a namespace
256  // in which it was declared
257  auto lookup = "." + name.label();
258  auto found = Set< std::string >();
259  auto matches = std::vector< std::string >();
260 
261  // Trying with types
262  for (auto t: prm__->types()) {
263  if (endsWith(t->name(), lookup)) {
264  if (!found.exists(t->name())) {
265  found.insert(t->name());
266  matches.push_back(t->name());
267  }
268  }
269  }
270 
271  // Trying with O3Types
272  for (auto& t: o3_prm__->types()) {
273  if (endsWith(t->name().label(), lookup)) {
274  if (!found.exists(t->name().label())) {
275  found.insert(t->name().label());
276  matches.push_back(t->name().label());
277  }
278  }
279  }
280 
281  if (matches.size() == 1) { // One match is good
282  typeName__.insert(name.label(), matches.back());
283  name.label() = matches.back();
284  return true;
285 
286  } else if (matches.size() == 0) { // 0 match is not found
287 
288  // Unknown name type
289  O3PRM_TYPE_NOT_FOUND(name, *errors__);
290  return false;
291 
292  } else { // More than one match is ambiguous
293 
294  // Ambiguous name
295  O3PRM_TYPE_AMBIGUOUS(name, matches, *errors__);
296  return false;
297  }
298  }
299 
300  template < typename GUM_SCALAR >
302  // If empty string, we return an empty string
303  if (name.label() == "") { return true; }
304 
305  // If we've already found the interface real name
306  if (interfaceName__.exists(name.label())) {
307  name.label() = interfaceName__[name.label()];
308  return true;
309  }
310 
311  // If name exists as is
312  if (prm__->isInterface(name.label())) {
313  interfaceName__.insert(name.label(), name.label());
314  return true;
315  }
316 
317  for (auto& i: o3_prm__->interfaces()) {
318  if (i->name().label() == name.label()) {
319  interfaceName__.insert(name.label(), name.label());
320  return true;
321  }
322  }
323 
324  // If we didn't find it as is, then we must find a namespace
325  // in which it was declared
326  auto lookup = "." + name.label();
327  auto found = Set< std::string >();
328  auto matches = std::vector< std::string >();
329 
330  // Trying with interfaces
331  for (auto i: prm__->interfaces()) {
332  if (endsWith(i->name(), lookup)) {
333  if (!found.exists(i->name())) {
334  found.insert(i->name());
335  matches.push_back(i->name());
336  }
337  }
338  }
339 
340  // Trying with O3Interface
341  for (auto& i: o3_prm__->interfaces()) {
342  if (endsWith(i->name().label(), lookup)) {
343  if (!found.exists(i->name().label())) {
344  found.insert(i->name().label());
345  matches.push_back(i->name().label());
346  }
347  }
348  }
349 
350  if (matches.size() == 1) { // One match is good
351 
352  interfaceName__.insert(name.label(), matches.back());
353  name.label() = matches.back();
354  return true;
355 
356  } else if (matches.size() == 0) { // 0 match is not found
357 
358  // Unknown name type
359  O3PRM_INTERFACE_NOT_FOUND(name, *errors__);
360  return false;
361 
362  } else { // More than one match is ambiguous
363 
364  // Ambiguous name
365  O3PRM_INTERFACE_AMBIGUOUS(name, matches, *errors__);
366  return false;
367  }
368  }
369 
370  template < typename GUM_SCALAR >
372  // If empty string, we return an empty string
373  if (name.label() == "") { return true; }
374 
375  // If we've already found super real name
376  if (className__.exists(name.label())) {
377  name.label() = className__[name.label()];
378  return true;
379  }
380 
381  // If class name exists as is
382  if (prm__->isClass(name.label())) {
383  className__.insert(name.label(), name.label());
384  return true;
385  }
386 
387  for (auto& c: o3_prm__->classes()) {
388  if (c->name().label() == name.label()) {
389  className__.insert(name.label(), name.label());
390  return true;
391  }
392  }
393 
394  // If we didn't find it as is, then we must find a namespace
395  // in which it was declared
396  auto lookup = "." + name.label();
397  auto matches = std::vector< std::string >();
398  auto found = Set< std::string >();
399 
400  // Try to complete with Class
401  for (auto c: prm__->classes()) {
402  if (endsWith(c->name(), lookup)) {
403  if (!found.exists(c->name())) {
404  found.insert(c->name());
405  matches.push_back(c->name());
406  }
407  }
408  }
409 
410  // Try to complete with O3Class
411  for (auto& c: o3_prm__->classes()) {
412  if (endsWith(c->name().label(), lookup)) {
413  if (!found.exists(c->name().label())) {
414  found.insert(c->name().label());
415  matches.push_back(c->name().label());
416  }
417  }
418  }
419 
420  if (matches.size() == 1) { // One match is good
421 
422  className__.insert(name.label(), matches.back());
423  name.label() = matches.back();
424  return true;
425 
426  } else if (matches.size() == 0) { // 0 match is not found
427 
428  // Unknown super class
429  O3PRM_CLASS_NOT_FOUND(name, *errors__);
430  return false;
431 
432  } else { // More than one match is ambiguous
433 
434  // Ambiguous name
435  O3PRM_CLASS_AMBIGUOUS(name, matches, *errors__);
436  return false;
437  }
438  }
439 
440  template < typename GUM_SCALAR >
442  // If empty string, we return an empty string
443  if (name.label() == "") { return true; }
444  // If we've already found the reference real name
445  if (refName__.exists(name.label())) {
446  name.label() = refName__[name.label()];
447  return true;
448  }
449  // If name exists as is
450  if (prm__->isInterface(name.label()) || prm__->isClass(name.label())) {
451  refName__.insert(name.label(), name.label());
452  return true;
453  }
454 
455  // We check if it matches an O3Interface
456  for (auto& i: o3_prm__->interfaces()) {
457  if (i->name().label() == name.label()) {
458  interfaceName__.insert(name.label(), name.label());
459  return true;
460  }
461  }
462 
463  // We check if it matches an O3Class
464  for (auto& c: o3_prm__->classes()) {
465  if (c->name().label() == name.label()) {
466  className__.insert(name.label(), name.label());
467  return true;
468  }
469  }
470 
471  // If we didn't find it as is, then we must find a namespace
472  // in which it was declared
473  auto lookup = "." + name.label();
474  auto found = Set< std::string >();
475  auto matches = std::vector< std::string >();
476 
477  // Trying with interfaces
478  for (auto i: prm__->interfaces()) {
479  if (endsWith(i->name(), lookup)) {
480  if (!found.exists(i->name())) {
481  found.insert(i->name());
482  matches.push_back(i->name());
483  }
484  }
485  }
486 
487  // Trying with O3Interface
488  for (auto& i: o3_prm__->interfaces()) {
489  if (endsWith(i->name().label(), lookup)) {
490  if (!found.exists(i->name().label())) {
491  found.insert(i->name().label());
492  matches.push_back(i->name().label());
493  }
494  }
495  }
496 
497  // Try to complete with Class
498  for (auto c: prm__->classes()) {
499  if (endsWith(c->name(), lookup)) {
500  if (!found.exists(c->name())) {
501  found.insert(c->name());
502  matches.push_back(c->name());
503  }
504  }
505  }
506 
507  // Try to complete with O3Class
508  for (auto& c: o3_prm__->classes()) {
509  if (endsWith(c->name().label(), lookup)) {
510  if (!found.exists(c->name().label())) {
511  found.insert(c->name().label());
512  matches.push_back(c->name().label());
513  }
514  }
515  }
516 
517  if (matches.size() == 1) { // One match is good
518 
519  refName__.insert(name.label(), matches.back());
520  name.label() = matches.back();
521  return true;
522 
523  } else if (matches.size() == 0) { // 0 match is not found
524 
525  // Unknown name type
526  O3PRM_REFERENCE_NOT_FOUND(name, *errors__);
527  return false;
528 
529  } else { // More than one match is ambiguous
530 
531  // Ambiguous name
532  O3PRM_REFERENCE_AMBIGUOUS(name, matches, *errors__);
533  return false;
534  }
535  }
536 
537 
538  } // namespace o3prm
539  } // namespace prm
540 } // namespace gum
O3ClassList & classes()
Definition: O3prm.cpp:503
STL namespace.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
This class is used contain and manipulate gum::ParseError.
The O3Label is part of the AST of the O3PRM language.
Definition: O3prm.h:173
bool resolveType(O3Label &name)
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Definition: agrum.h:25
PRM< GUM_SCALAR > * prm__
Definition: O3NameSolver.h:85
bool endsWith(std::string const &value, std::string const &ending)
Returns true if value ends with ending.
std::string & label()
Definition: O3prm.cpp:242
O3NameSolver< GUM_SCALAR > & operator=(const O3NameSolver< GUM_SCALAR > &src)
Resolves names for the different O3PRM factories.
Definition: O3NameSolver.h:57
bool resolveClassElement(O3Label &name)
bool resolveSlotType(O3Label &name)
O3InterfaceList & interfaces()
Definition: O3prm.cpp:498
O3NameSolver(PRM< GUM_SCALAR > &prm, O3PRM &o3_prm, ErrorsContainer &errors)
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:66
O3TypeList & types()
Definition: O3prm.cpp:487
bool resolveInterface(O3Label &name)
The O3PRM is part of the AST of the O3PRM language.
Definition: O3prm.h:892
ErrorsContainer * errors__
Definition: O3NameSolver.h:87
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:701
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
bool resolveClass(O3Label &name)