aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
O3NameSolver_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
50
52
53namespace gum {
54 namespace prm {
55 namespace o3prm {
56
57 template < typename GUM_SCALAR >
59 O3PRM& o3_prm,
60 ErrorsContainer& errors) :
61 _prm_(&prm), _o3_prm_(&o3_prm), _errors_(&errors) {
62 GUM_CONSTRUCTOR(O3NameSolver);
63 }
64
65 template < typename GUM_SCALAR >
72
73 template < typename GUM_SCALAR >
75 _prm_(std::move(src._prm_)), _o3_prm_(std::move(src._o3_prm_)),
76 _errors_(std::move(src._errors_)), _typeName_(std::move(src._typeName_)),
77 _eltName_(std::move(src._eltName_)), _refName_(std::move(src._refName_)),
79 GUM_CONS_MOV(O3NameSolver);
80 }
81
82 template < typename GUM_SCALAR >
84 GUM_DESTRUCTOR(O3NameSolver);
85 }
86
87 template < typename GUM_SCALAR >
90 if (this == &src) { return *this; }
91 _prm_ = src._prm_;
92 _o3_prm_ = src._o3_prm_;
93 _errors_ = src._errors_;
95 _eltName_ = src._eltName_;
96 _refName_ = src._refName_;
99 return *this;
100 }
101
102 template < typename GUM_SCALAR >
105 if (this == &src) { return *this; }
106 _prm_ = std::move(src._prm_);
107 _o3_prm_ = std::move(src._o3_prm_);
108 _errors_ = std::move(src._errors_);
109 _typeName_ = std::move(src._typeName_);
110 _eltName_ = std::move(src._eltName_);
111 _refName_ = std::move(src._refName_);
112 _interfaceName_ = std::move(src._interfaceName_);
113 _className_ = std::move(src._className_);
114 return *this;
115 }
116
117 template < typename GUM_SCALAR >
119 // If empty string, we return an empty string
120 if (name.label().empty()) { return true; }
121 // If we've already found the element real name
122 if (_eltName_.exists(name.label())) {
123 name.label() = _eltName_[name.label()];
124 return true;
125 }
126 // If name exists as is
127 if (_prm_->isType(name.label())) {
128 _eltName_.insert(name.label(), name.label());
129 return true;
130 }
131 // If name exists as is
132 if (_prm_->isInterface(name.label())) {
133 _eltName_.insert(name.label(), name.label());
134 return true;
135 }
136 // If name exists as is
137 if (_prm_->isClass(name.label())) {
138 _eltName_.insert(name.label(), name.label());
139 return true;
140 }
141 // If name exists as is in O3PRM types
142 for (auto& t: _o3_prm_->types()) {
143 if (t->name().label() == name.label()) {
144 _eltName_.insert(name.label(), name.label());
145 return true;
146 }
147 }
148 // If name exists as is in O3PRM interfaces
149 for (auto& i: _o3_prm_->interfaces()) {
150 if (i->name().label() == name.label()) {
151 _eltName_.insert(name.label(), name.label());
152 return true;
153 }
154 }
155 // If name exists as is in O3PRM classes
156 for (auto& c: _o3_prm_->classes()) {
157 if (c->name().label() == name.label()) {
158 _eltName_.insert(name.label(), name.label());
159 return true;
160 }
161 }
162
163 auto lookup = "." + name.label();
164 auto found = Set< std::string >();
165 auto matches = std::vector< std::string >();
166
167 // Trying with types
168 for (auto t: _prm_->types()) {
169 if (endsWith(t->name(), lookup)) {
170 if (!found.exists(t->name())) {
171 found.insert(t->name());
172 matches.push_back(t->name());
173 }
174 }
175 }
176 // Trying with O3Types
177 for (auto& t: _o3_prm_->types()) {
178 if (endsWith(t->name().label(), lookup)) {
179 if (!found.exists(t->name().label())) {
180 found.insert(t->name().label());
181 matches.push_back(t->name().label());
182 }
183 }
184 }
185
186 // Trying with interfaces
187 for (auto i: _prm_->interfaces()) {
188 if (endsWith(i->name(), lookup)) {
189 if (!found.exists(i->name())) {
190 found.insert(i->name());
191 matches.push_back(i->name());
192 }
193 }
194 }
195 // Trying with O3Interface
196 for (auto& i: _o3_prm_->interfaces()) {
197 if (endsWith(i->name().label(), lookup)) {
198 if (!found.exists(i->name().label())) {
199 found.insert(i->name().label());
200 matches.push_back(i->name().label());
201 }
202 }
203 }
204
205 // Trying with class
206 for (auto c: _prm_->classes()) {
207 if (endsWith(c->name(), lookup)) {
208 if (!found.exists(c->name())) {
209 found.insert(c->name());
210 matches.push_back(c->name());
211 }
212 }
213 }
214 // Trying with O3Class
215 for (auto& c: _o3_prm_->classes()) {
216 if (endsWith(c->name().label(), lookup)) {
217 if (!found.exists(c->name().label())) {
218 found.insert(c->name().label());
219 matches.push_back(c->name().label());
220 }
221 }
222 }
223
224 if (matches.size() == 1) { // One match is good
225 _eltName_.insert(name.label(), matches.back());
226 name.label() = matches.back();
227 return true;
228
229 } else if (matches.size() == 0) { // 0 match is not found
230
231 // Unknown name type
232 O3PRM_TYPE_NOT_FOUND(name, *_errors_);
233 return false;
234
235 } else { // More than one match is ambiguous
236
237 // Ambiguous name
238 O3PRM_TYPE_AMBIGUOUS(name, matches, *_errors_);
239 return false;
240 }
241 }
242
243 template < typename GUM_SCALAR >
245 // If empty string, we return an empty string
246 if (name.label().empty()) { return true; }
247
248 // If we've already found the type real name
249 if (_typeName_.exists(name.label())) {
250 name.label() = _typeName_[name.label()];
251 return true;
252 }
253
254 // If name exists as is in PRM
255 if (_prm_->isType(name.label())) {
256 _typeName_.insert(name.label(), name.label());
257 return true;
258 }
259
260 // If name exists as is in O3PRM
261 for (auto& t: _o3_prm_->types()) {
262 if (t->name().label() == name.label()) {
263 _typeName_.insert(name.label(), name.label());
264 return true;
265 }
266 }
267
268 // If we didn't find it as is, then we must find a namespace
269 // in which it was declared
270 auto lookup = "." + name.label();
271 auto found = Set< std::string >();
272 auto matches = std::vector< std::string >();
273
274 // Trying with types
275 for (auto t: _prm_->types()) {
276 if (endsWith(t->name(), lookup)) {
277 if (!found.exists(t->name())) {
278 found.insert(t->name());
279 matches.push_back(t->name());
280 }
281 }
282 }
283
284 // Trying with O3Types
285 for (auto& t: _o3_prm_->types()) {
286 if (endsWith(t->name().label(), lookup)) {
287 if (!found.exists(t->name().label())) {
288 found.insert(t->name().label());
289 matches.push_back(t->name().label());
290 }
291 }
292 }
293
294 if (matches.size() == 1) { // One match is good
295 _typeName_.insert(name.label(), matches.back());
296 name.label() = matches.back();
297 return true;
298
299 } else if (matches.size() == 0) { // 0 match is not found
300
301 // Unknown name type
302 O3PRM_TYPE_NOT_FOUND(name, *_errors_);
303 return false;
304
305 } else { // More than one match is ambiguous
306
307 // Ambiguous name
308 O3PRM_TYPE_AMBIGUOUS(name, matches, *_errors_);
309 return false;
310 }
311 }
312
313 template < typename GUM_SCALAR >
315 // If empty string, we return an empty string
316 if (name.label().empty()) { return true; }
317
318 // If we've already found the interface real name
319 if (_interfaceName_.exists(name.label())) {
320 name.label() = _interfaceName_[name.label()];
321 return true;
322 }
323
324 // If name exists as is
325 if (_prm_->isInterface(name.label())) {
326 _interfaceName_.insert(name.label(), name.label());
327 return true;
328 }
329
330 for (auto& i: _o3_prm_->interfaces()) {
331 if (i->name().label() == name.label()) {
332 _interfaceName_.insert(name.label(), name.label());
333 return true;
334 }
335 }
336
337 // If we didn't find it as is, then we must find a namespace
338 // in which it was declared
339 auto lookup = "." + name.label();
340 auto found = Set< std::string >();
341 auto matches = std::vector< std::string >();
342
343 // Trying with interfaces
344 for (auto i: _prm_->interfaces()) {
345 if (endsWith(i->name(), lookup)) {
346 if (!found.exists(i->name())) {
347 found.insert(i->name());
348 matches.push_back(i->name());
349 }
350 }
351 }
352
353 // Trying with O3Interface
354 for (auto& i: _o3_prm_->interfaces()) {
355 if (endsWith(i->name().label(), lookup)) {
356 if (!found.exists(i->name().label())) {
357 found.insert(i->name().label());
358 matches.push_back(i->name().label());
359 }
360 }
361 }
362
363 if (matches.size() == 1) { // One match is good
364
365 _interfaceName_.insert(name.label(), matches.back());
366 name.label() = matches.back();
367 return true;
368
369 } else if (matches.size() == 0) { // 0 match is not found
370
371 // Unknown name type
372 O3PRM_INTERFACE_NOT_FOUND(name, *_errors_);
373 return false;
374
375 } else { // More than one match is ambiguous
376
377 // Ambiguous name
378 O3PRM_INTERFACE_AMBIGUOUS(name, matches, *_errors_);
379 return false;
380 }
381 }
382
383 template < typename GUM_SCALAR >
385 // If empty string, we return an empty string
386 if (name.label().empty()) { return true; }
387
388 // If we've already found super real name
389 if (_className_.exists(name.label())) {
390 name.label() = _className_[name.label()];
391 return true;
392 }
393
394 // If class name exists as is
395 if (_prm_->isClass(name.label())) {
396 _className_.insert(name.label(), name.label());
397 return true;
398 }
399
400 for (auto& c: _o3_prm_->classes()) {
401 if (c->name().label() == name.label()) {
402 _className_.insert(name.label(), name.label());
403 return true;
404 }
405 }
406
407 // If we didn't find it as is, then we must find a namespace
408 // in which it was declared
409 auto lookup = "." + name.label();
410 auto matches = std::vector< std::string >();
411 auto found = Set< std::string >();
412
413 // Try to complete with Class
414 for (auto c: _prm_->classes()) {
415 if (endsWith(c->name(), lookup)) {
416 if (!found.exists(c->name())) {
417 found.insert(c->name());
418 matches.push_back(c->name());
419 }
420 }
421 }
422
423 // Try to complete with O3Class
424 for (auto& c: _o3_prm_->classes()) {
425 if (endsWith(c->name().label(), lookup)) {
426 if (!found.exists(c->name().label())) {
427 found.insert(c->name().label());
428 matches.push_back(c->name().label());
429 }
430 }
431 }
432
433 if (matches.size() == 1) { // One match is good
434
435 _className_.insert(name.label(), matches.back());
436 name.label() = matches.back();
437 return true;
438
439 } else if (matches.size() == 0) { // 0 match is not found
440
441 // Unknown super class
442 O3PRM_CLASS_NOT_FOUND(name, *_errors_);
443 return false;
444
445 } else { // More than one match is ambiguous
446
447 // Ambiguous name
448 O3PRM_CLASS_AMBIGUOUS(name, matches, *_errors_);
449 return false;
450 }
451 }
452
453 template < typename GUM_SCALAR >
455 // If empty string, we return an empty string
456 if (name.label().empty()) { return true; }
457 // If we've already found the reference real name
458 if (_refName_.exists(name.label())) {
459 name.label() = _refName_[name.label()];
460 return true;
461 }
462 // If name exists as is
463 if (_prm_->isInterface(name.label()) || _prm_->isClass(name.label())) {
464 _refName_.insert(name.label(), name.label());
465 return true;
466 }
467
468 // We check if it matches an O3Interface
469 for (auto& i: _o3_prm_->interfaces()) {
470 if (i->name().label() == name.label()) {
471 _interfaceName_.insert(name.label(), name.label());
472 return true;
473 }
474 }
475
476 // We check if it matches an O3Class
477 for (auto& c: _o3_prm_->classes()) {
478 if (c->name().label() == name.label()) {
479 _className_.insert(name.label(), name.label());
480 return true;
481 }
482 }
483
484 // If we didn't find it as is, then we must find a namespace
485 // in which it was declared
486 auto lookup = "." + name.label();
487 auto found = Set< std::string >();
488 auto matches = std::vector< std::string >();
489
490 // Trying with interfaces
491 for (auto i: _prm_->interfaces()) {
492 if (endsWith(i->name(), lookup)) {
493 if (!found.exists(i->name())) {
494 found.insert(i->name());
495 matches.push_back(i->name());
496 }
497 }
498 }
499
500 // Trying with O3Interface
501 for (auto& i: _o3_prm_->interfaces()) {
502 if (endsWith(i->name().label(), lookup)) {
503 if (!found.exists(i->name().label())) {
504 found.insert(i->name().label());
505 matches.push_back(i->name().label());
506 }
507 }
508 }
509
510 // Try to complete with Class
511 for (auto c: _prm_->classes()) {
512 if (endsWith(c->name(), lookup)) {
513 if (!found.exists(c->name())) {
514 found.insert(c->name());
515 matches.push_back(c->name());
516 }
517 }
518 }
519
520 // Try to complete with O3Class
521 for (auto& c: _o3_prm_->classes()) {
522 if (endsWith(c->name().label(), lookup)) {
523 if (!found.exists(c->name().label())) {
524 found.insert(c->name().label());
525 matches.push_back(c->name().label());
526 }
527 }
528 }
529
530 if (matches.size() == 1) { // One match is good
531
532 _refName_.insert(name.label(), matches.back());
533 name.label() = matches.back();
534 return true;
535
536 } else if (matches.size() == 0) { // 0 match is not found
537
538 // Unknown name type
539 O3PRM_REFERENCE_NOT_FOUND(name, *_errors_);
540 return false;
541
542 } else { // More than one match is ambiguous
543
544 // Ambiguous name
545 O3PRM_REFERENCE_AMBIGUOUS(name, matches, *_errors_);
546 return false;
547 }
548 }
549
550
551 } // namespace o3prm
552 } // namespace prm
553} // namespace gum
Headers for the O3NameSolver class.
This class is used contain and manipulate gum::ParseError.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition PRM.h:74
The O3Label is part of the AST of the O3PRM language.
Definition O3prm.h:192
std::string & label()
Definition O3prm.cpp:287
Resolves names for the different O3PRM factories.
bool resolveSlotType(O3Label &name)
bool resolveInterface(O3Label &name)
PRM< GUM_SCALAR > * _prm_
bool resolveClassElement(O3Label &name)
O3NameSolver< GUM_SCALAR > & operator=(const O3NameSolver< GUM_SCALAR > &src)
O3NameSolver(PRM< GUM_SCALAR > &prm, O3PRM &o3_prm, ErrorsContainer &errors)
The O3PRM is part of the AST of the O3PRM language.
Definition O3prm.h:913
bool endsWith(std::string const &value, std::string const &ending)
Returns true if value ends with ending.
namespace for all probabilistic relational models entities
Definition agrum.h:68
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
STL namespace.