aGrUM 3.1.1
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-2026 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-2026 *
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
41#pragma once
42
43
51
53
54namespace gum {
55 namespace prm {
56 namespace o3prm {
57
58 template < GUM_Numeric GUM_SCALAR >
60 O3PRM& o3_prm,
61 ErrorsContainer& errors) :
62 _prm_(&prm), _o3_prm_(&o3_prm), _errors_(&errors) {
63 GUM_CONSTRUCTOR(O3NameSolver);
64 }
65
66 template < GUM_Numeric GUM_SCALAR >
73
74 template < GUM_Numeric GUM_SCALAR >
76 _prm_(std::move(src._prm_)), _o3_prm_(std::move(src._o3_prm_)),
77 _errors_(std::move(src._errors_)), _typeName_(std::move(src._typeName_)),
78 _eltName_(std::move(src._eltName_)), _refName_(std::move(src._refName_)),
80 GUM_CONS_MOV(O3NameSolver);
81 }
82
83 template < GUM_Numeric GUM_SCALAR >
87
88 template < GUM_Numeric GUM_SCALAR >
91 if (this == &src) { return *this; }
92 _prm_ = src._prm_;
93 _o3_prm_ = src._o3_prm_;
94 _errors_ = src._errors_;
96 _eltName_ = src._eltName_;
97 _refName_ = src._refName_;
100 return *this;
101 }
102
103 template < GUM_Numeric GUM_SCALAR >
106 if (this == &src) { return *this; }
107 _prm_ = std::move(src._prm_);
108 _o3_prm_ = std::move(src._o3_prm_);
109 _errors_ = std::move(src._errors_);
110 _typeName_ = std::move(src._typeName_);
111 _eltName_ = std::move(src._eltName_);
112 _refName_ = std::move(src._refName_);
113 _interfaceName_ = std::move(src._interfaceName_);
114 _className_ = std::move(src._className_);
115 return *this;
116 }
117
118 template < GUM_Numeric GUM_SCALAR >
120 // If empty string, we return an empty string
121 if (name.label().empty()) { return true; }
122 // If we've already found the element real name
123 if (_eltName_.exists(name.label())) {
124 name.label() = _eltName_[name.label()];
125 return true;
126 }
127 // If name exists as is
128 if (_prm_->isType(name.label())) {
129 _eltName_.insert(name.label(), name.label());
130 return true;
131 }
132 // If name exists as is
133 if (_prm_->isInterface(name.label())) {
134 _eltName_.insert(name.label(), name.label());
135 return true;
136 }
137 // If name exists as is
138 if (_prm_->isClass(name.label())) {
139 _eltName_.insert(name.label(), name.label());
140 return true;
141 }
142 // If name exists as is in O3PRM types
143 for (auto& t: _o3_prm_->types()) {
144 if (t->name().label() == name.label()) {
145 _eltName_.insert(name.label(), name.label());
146 return true;
147 }
148 }
149 // If name exists as is in O3PRM interfaces
150 for (auto& i: _o3_prm_->interfaces()) {
151 if (i->name().label() == name.label()) {
152 _eltName_.insert(name.label(), name.label());
153 return true;
154 }
155 }
156 // If name exists as is in O3PRM classes
157 for (auto& c: _o3_prm_->classes()) {
158 if (c->name().label() == name.label()) {
159 _eltName_.insert(name.label(), name.label());
160 return true;
161 }
162 }
163
164 auto lookup = "." + name.label();
165 auto found = Set< std::string >();
166 auto matches = std::vector< std::string >();
167
168 // Trying with types
169 for (auto t: _prm_->types()) {
170 if (endsWith(t->name(), lookup)) {
171 if (!found.exists(t->name())) {
172 found.insert(t->name());
173 matches.push_back(t->name());
174 }
175 }
176 }
177 // Trying with O3Types
178 for (auto& t: _o3_prm_->types()) {
179 if (endsWith(t->name().label(), lookup)) {
180 if (!found.exists(t->name().label())) {
181 found.insert(t->name().label());
182 matches.push_back(t->name().label());
183 }
184 }
185 }
186
187 // Trying with interfaces
188 for (auto i: _prm_->interfaces()) {
189 if (endsWith(i->name(), lookup)) {
190 if (!found.exists(i->name())) {
191 found.insert(i->name());
192 matches.push_back(i->name());
193 }
194 }
195 }
196 // Trying with O3Interface
197 for (auto& i: _o3_prm_->interfaces()) {
198 if (endsWith(i->name().label(), lookup)) {
199 if (!found.exists(i->name().label())) {
200 found.insert(i->name().label());
201 matches.push_back(i->name().label());
202 }
203 }
204 }
205
206 // Trying with class
207 for (auto c: _prm_->classes()) {
208 if (endsWith(c->name(), lookup)) {
209 if (!found.exists(c->name())) {
210 found.insert(c->name());
211 matches.push_back(c->name());
212 }
213 }
214 }
215 // Trying with O3Class
216 for (auto& c: _o3_prm_->classes()) {
217 if (endsWith(c->name().label(), lookup)) {
218 if (!found.exists(c->name().label())) {
219 found.insert(c->name().label());
220 matches.push_back(c->name().label());
221 }
222 }
223 }
224
225 if (matches.size() == 1) { // One match is good
226 _eltName_.insert(name.label(), matches.back());
227 name.label() = matches.back();
228 return true;
229
230 } else if (matches.size() == 0) { // 0 match is not found
231
232 // Unknown name type
233 O3PRM_TYPE_NOT_FOUND(name, *_errors_);
234 return false;
235
236 } else { // More than one match is ambiguous
237
238 // Ambiguous name
239 O3PRM_TYPE_AMBIGUOUS(name, matches, *_errors_);
240 return false;
241 }
242 }
243
244 template < GUM_Numeric GUM_SCALAR >
246 // If empty string, we return an empty string
247 if (name.label().empty()) { return true; }
248
249 // If we've already found the type real name
250 if (_typeName_.exists(name.label())) {
251 name.label() = _typeName_[name.label()];
252 return true;
253 }
254
255 // If name exists as is in PRM
256 if (_prm_->isType(name.label())) {
257 _typeName_.insert(name.label(), name.label());
258 return true;
259 }
260
261 // If name exists as is in O3PRM
262 for (auto& t: _o3_prm_->types()) {
263 if (t->name().label() == name.label()) {
264 _typeName_.insert(name.label(), name.label());
265 return true;
266 }
267 }
268
269 // If we didn't find it as is, then we must find a namespace
270 // in which it was declared
271 auto lookup = "." + name.label();
272 auto found = Set< std::string >();
273 auto matches = std::vector< std::string >();
274
275 // Trying with types
276 for (auto t: _prm_->types()) {
277 if (endsWith(t->name(), lookup)) {
278 if (!found.exists(t->name())) {
279 found.insert(t->name());
280 matches.push_back(t->name());
281 }
282 }
283 }
284
285 // Trying with O3Types
286 for (auto& t: _o3_prm_->types()) {
287 if (endsWith(t->name().label(), lookup)) {
288 if (!found.exists(t->name().label())) {
289 found.insert(t->name().label());
290 matches.push_back(t->name().label());
291 }
292 }
293 }
294
295 if (matches.size() == 1) { // One match is good
296 _typeName_.insert(name.label(), matches.back());
297 name.label() = matches.back();
298 return true;
299
300 } else if (matches.size() == 0) { // 0 match is not found
301
302 // Unknown name type
303 O3PRM_TYPE_NOT_FOUND(name, *_errors_);
304 return false;
305
306 } else { // More than one match is ambiguous
307
308 // Ambiguous name
309 O3PRM_TYPE_AMBIGUOUS(name, matches, *_errors_);
310 return false;
311 }
312 }
313
314 template < GUM_Numeric GUM_SCALAR >
316 // If empty string, we return an empty string
317 if (name.label().empty()) { return true; }
318
319 // If we've already found the interface real name
320 if (_interfaceName_.exists(name.label())) {
321 name.label() = _interfaceName_[name.label()];
322 return true;
323 }
324
325 // If name exists as is
326 if (_prm_->isInterface(name.label())) {
327 _interfaceName_.insert(name.label(), name.label());
328 return true;
329 }
330
331 for (auto& i: _o3_prm_->interfaces()) {
332 if (i->name().label() == name.label()) {
333 _interfaceName_.insert(name.label(), name.label());
334 return true;
335 }
336 }
337
338 // If we didn't find it as is, then we must find a namespace
339 // in which it was declared
340 auto lookup = "." + name.label();
341 auto found = Set< std::string >();
342 auto matches = std::vector< std::string >();
343
344 // Trying with interfaces
345 for (auto i: _prm_->interfaces()) {
346 if (endsWith(i->name(), lookup)) {
347 if (!found.exists(i->name())) {
348 found.insert(i->name());
349 matches.push_back(i->name());
350 }
351 }
352 }
353
354 // Trying with O3Interface
355 for (auto& i: _o3_prm_->interfaces()) {
356 if (endsWith(i->name().label(), lookup)) {
357 if (!found.exists(i->name().label())) {
358 found.insert(i->name().label());
359 matches.push_back(i->name().label());
360 }
361 }
362 }
363
364 if (matches.size() == 1) { // One match is good
365
366 _interfaceName_.insert(name.label(), matches.back());
367 name.label() = matches.back();
368 return true;
369
370 } else if (matches.size() == 0) { // 0 match is not found
371
372 // Unknown name type
373 O3PRM_INTERFACE_NOT_FOUND(name, *_errors_);
374 return false;
375
376 } else { // More than one match is ambiguous
377
378 // Ambiguous name
379 O3PRM_INTERFACE_AMBIGUOUS(name, matches, *_errors_);
380 return false;
381 }
382 }
383
384 template < GUM_Numeric GUM_SCALAR >
386 // If empty string, we return an empty string
387 if (name.label().empty()) { return true; }
388
389 // If we've already found super real name
390 if (_className_.exists(name.label())) {
391 name.label() = _className_[name.label()];
392 return true;
393 }
394
395 // If class name exists as is
396 if (_prm_->isClass(name.label())) {
397 _className_.insert(name.label(), name.label());
398 return true;
399 }
400
401 for (auto& c: _o3_prm_->classes()) {
402 if (c->name().label() == name.label()) {
403 _className_.insert(name.label(), name.label());
404 return true;
405 }
406 }
407
408 // If we didn't find it as is, then we must find a namespace
409 // in which it was declared
410 auto lookup = "." + name.label();
411 auto matches = std::vector< std::string >();
412 auto found = Set< std::string >();
413
414 // Try to complete with Class
415 for (auto c: _prm_->classes()) {
416 if (endsWith(c->name(), lookup)) {
417 if (!found.exists(c->name())) {
418 found.insert(c->name());
419 matches.push_back(c->name());
420 }
421 }
422 }
423
424 // Try to complete with O3Class
425 for (auto& c: _o3_prm_->classes()) {
426 if (endsWith(c->name().label(), lookup)) {
427 if (!found.exists(c->name().label())) {
428 found.insert(c->name().label());
429 matches.push_back(c->name().label());
430 }
431 }
432 }
433
434 if (matches.size() == 1) { // One match is good
435
436 _className_.insert(name.label(), matches.back());
437 name.label() = matches.back();
438 return true;
439
440 } else if (matches.size() == 0) { // 0 match is not found
441
442 // Unknown super class
443 O3PRM_CLASS_NOT_FOUND(name, *_errors_);
444 return false;
445
446 } else { // More than one match is ambiguous
447
448 // Ambiguous name
449 O3PRM_CLASS_AMBIGUOUS(name, matches, *_errors_);
450 return false;
451 }
452 }
453
454 template < GUM_Numeric GUM_SCALAR >
456 // If empty string, we return an empty string
457 if (name.label().empty()) { return true; }
458 // If we've already found the reference real name
459 if (_refName_.exists(name.label())) {
460 name.label() = _refName_[name.label()];
461 return true;
462 }
463 // If name exists as is
464 if (_prm_->isInterface(name.label()) || _prm_->isClass(name.label())) {
465 _refName_.insert(name.label(), name.label());
466 return true;
467 }
468
469 // We check if it matches an O3Interface
470 for (auto& i: _o3_prm_->interfaces()) {
471 if (i->name().label() == name.label()) {
472 _interfaceName_.insert(name.label(), name.label());
473 return true;
474 }
475 }
476
477 // We check if it matches an O3Class
478 for (auto& c: _o3_prm_->classes()) {
479 if (c->name().label() == name.label()) {
480 _className_.insert(name.label(), name.label());
481 return true;
482 }
483 }
484
485 // If we didn't find it as is, then we must find a namespace
486 // in which it was declared
487 auto lookup = "." + name.label();
488 auto found = Set< std::string >();
489 auto matches = std::vector< std::string >();
490
491 // Trying with interfaces
492 for (auto i: _prm_->interfaces()) {
493 if (endsWith(i->name(), lookup)) {
494 if (!found.exists(i->name())) {
495 found.insert(i->name());
496 matches.push_back(i->name());
497 }
498 }
499 }
500
501 // Trying with O3Interface
502 for (auto& i: _o3_prm_->interfaces()) {
503 if (endsWith(i->name().label(), lookup)) {
504 if (!found.exists(i->name().label())) {
505 found.insert(i->name().label());
506 matches.push_back(i->name().label());
507 }
508 }
509 }
510
511 // Try to complete with Class
512 for (auto c: _prm_->classes()) {
513 if (endsWith(c->name(), lookup)) {
514 if (!found.exists(c->name())) {
515 found.insert(c->name());
516 matches.push_back(c->name());
517 }
518 }
519 }
520
521 // Try to complete with O3Class
522 for (auto& c: _o3_prm_->classes()) {
523 if (endsWith(c->name().label(), lookup)) {
524 if (!found.exists(c->name().label())) {
525 found.insert(c->name().label());
526 matches.push_back(c->name().label());
527 }
528 }
529 }
530
531 if (matches.size() == 1) { // One match is good
532
533 _refName_.insert(name.label(), matches.back());
534 name.label() = matches.back();
535 return true;
536
537 } else if (matches.size() == 0) { // 0 match is not found
538
539 // Unknown name type
540 O3PRM_REFERENCE_NOT_FOUND(name, *_errors_);
541 return false;
542
543 } else { // More than one match is ambiguous
544
545 // Ambiguous name
546 O3PRM_REFERENCE_AMBIGUOUS(name, matches, *_errors_);
547 return false;
548 }
549 }
550
551
552 } // namespace o3prm
553 } // namespace prm
554} // 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:194
std::string & label()
Definition O3prm.cpp:286
Resolves names for the different O3PRM factories.
O3NameSolver< GUM_SCALAR > & operator=(const O3NameSolver< GUM_SCALAR > &src)
O3NameSolver(PRM< GUM_SCALAR > &prm, O3PRM &o3_prm, ErrorsContainer &errors)
PRM< GUM_SCALAR > * _prm_
bool resolveClassElement(O3Label &name)
bool resolveSlotType(O3Label &name)
bool resolveInterface(O3Label &name)
The O3PRM is part of the AST of the O3PRM language.
Definition O3prm.h:915
bool endsWith(const std::string_view &value, const std::string_view &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.