aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
O3NameSolver_tpl.h
Go to the documentation of this file.
1
/**
2
*
3
* Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4
* info_at_agrum_dot_org
5
*
6
* This library is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18
*
19
*/
20
21
22
/**
23
* @file
24
* @brief Implentation for the O3NameSolver class.
25
*
26
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27
* @author Lionel TORTI
28
*/
29
30
#
include
<
agrum
/
PRM
/
o3prm
/
O3NameSolver
.
h
>
31
32
namespace
gum
{
33
namespace
prm
{
34
namespace
o3prm
{
35
36
template
<
typename
GUM_SCALAR >
37
INLINE O3NameSolver<
GUM_SCALAR
>::
O3NameSolver
(
PRM
<
GUM_SCALAR
>&
prm
,
38
O3PRM
&
o3_prm
,
39
ErrorsContainer
&
errors
) :
40
_prm_
(&
prm
),
41
_o3_prm_
(&
o3_prm
),
_errors_
(&
errors
) {
42
GUM_CONSTRUCTOR
(
O3NameSolver
);
43
}
44
45
template
<
typename
GUM_SCALAR
>
46
INLINE
O3NameSolver
<
GUM_SCALAR
>::
O3NameSolver
(
const
O3NameSolver
<
GUM_SCALAR
>&
src
) :
47
_prm_
(
src
.
_prm_
),
_o3_prm_
(
src
.
_o3_prm_
),
_errors_
(
src
.
_errors_
),
48
_typeName_
(
src
.
_typeName_
),
_eltName_
(
src
.
_eltName_
),
_refName_
(
src
.
_refName_
),
49
_interfaceName_
(
src
.
_interfaceName_
),
_className_
(
src
.
_className_
) {
50
GUM_CONS_CPY
(
O3NameSolver
);
51
}
52
53
template
<
typename
GUM_SCALAR
>
54
INLINE
O3NameSolver
<
GUM_SCALAR
>::
O3NameSolver
(
O3NameSolver
<
GUM_SCALAR
>&&
src
) :
55
_prm_
(
std
::
move
(
src
.
_prm_
)),
_o3_prm_
(
std
::
move
(
src
.
_o3_prm_
)),
56
_errors_
(
std
::
move
(
src
.
_errors_
)),
_typeName_
(
std
::
move
(
src
.
_typeName_
)),
57
_eltName_
(
std
::
move
(
src
.
_eltName_
)),
_refName_
(
std
::
move
(
src
.
_refName_
)),
58
_interfaceName_
(
std
::
move
(
src
.
_interfaceName_
)),
_className_
(
std
::
move
(
src
.
_className_
)) {
59
GUM_CONS_MOV
(
O3NameSolver
);
60
}
61
62
template
<
typename
GUM_SCALAR
>
63
INLINE
O3NameSolver
<
GUM_SCALAR
>::~
O3NameSolver
() {
64
GUM_DESTRUCTOR
(
O3NameSolver
);
65
}
66
67
template
<
typename
GUM_SCALAR
>
68
INLINE
O3NameSolver
<
GUM_SCALAR
>&
69
O3NameSolver
<
GUM_SCALAR
>::
operator
=(
const
O3NameSolver
<
GUM_SCALAR
>&
src
) {
70
if
(
this
== &
src
) {
return
*
this
; }
71
_prm_
=
src
.
_prm_
;
72
_o3_prm_
=
src
.
_o3_prm_
;
73
_errors_
=
src
.
_errors_
;
74
_typeName_
=
src
.
_typeName_
;
75
_eltName_
=
src
.
_eltName_
;
76
_refName_
=
src
.
_refName_
;
77
_interfaceName_
=
src
.
_interfaceName_
;
78
_className_
=
src
.
_className_
;
79
return
*
this
;
80
}
81
82
template
<
typename
GUM_SCALAR
>
83
INLINE
O3NameSolver
<
GUM_SCALAR
>&
84
O3NameSolver
<
GUM_SCALAR
>::
operator
=(
O3NameSolver
<
GUM_SCALAR
>&&
src
) {
85
if
(
this
== &
src
) {
return
*
this
; }
86
_prm_
=
std
::
move
(
src
.
_prm_
);
87
_o3_prm_
=
std
::
move
(
src
.
_o3_prm_
);
88
_errors_
=
std
::
move
(
src
.
_errors_
);
89
_typeName_
=
std
::
move
(
src
.
_typeName_
);
90
_eltName_
=
std
::
move
(
src
.
_eltName_
);
91
_refName_
=
std
::
move
(
src
.
_refName_
);
92
_interfaceName_
=
std
::
move
(
src
.
_interfaceName_
);
93
_className_
=
std
::
move
(
src
.
_className_
);
94
return
*
this
;
95
}
96
97
template
<
typename
GUM_SCALAR
>
98
INLINE
bool
O3NameSolver
<
GUM_SCALAR
>::
resolveClassElement
(
O3Label
&
name
) {
99
// If empty string, we return an empty string
100
if
(
name
.
label
() ==
""
) {
return
true
; }
101
// If we've already found the element real name
102
if
(
_eltName_
.
exists
(
name
.
label
())) {
103
name
.
label
() =
_eltName_
[
name
.
label
()];
104
return
true
;
105
}
106
// If name exists as is
107
if
(
_prm_
->
isType
(
name
.
label
())) {
108
_eltName_
.
insert
(
name
.
label
(),
name
.
label
());
109
return
true
;
110
}
111
// If name exists as is
112
if
(
_prm_
->
isInterface
(
name
.
label
())) {
113
_eltName_
.
insert
(
name
.
label
(),
name
.
label
());
114
return
true
;
115
}
116
// If name exists as is
117
if
(
_prm_
->
isClass
(
name
.
label
())) {
118
_eltName_
.
insert
(
name
.
label
(),
name
.
label
());
119
return
true
;
120
}
121
// If name exists as is in O3PRM types
122
for
(
auto
&
t
:
_o3_prm_
->
types
()) {
123
if
(
t
->
name
().
label
() ==
name
.
label
()) {
124
_eltName_
.
insert
(
name
.
label
(),
name
.
label
());
125
return
true
;
126
}
127
}
128
// If name exists as is in O3PRM interfaces
129
for
(
auto
&
i
:
_o3_prm_
->
interfaces
()) {
130
if
(
i
->
name
().
label
() ==
name
.
label
()) {
131
_eltName_
.
insert
(
name
.
label
(),
name
.
label
());
132
return
true
;
133
}
134
}
135
// If name exists as is in O3PRM classes
136
for
(
auto
&
c
:
_o3_prm_
->
classes
()) {
137
if
(
c
->
name
().
label
() ==
name
.
label
()) {
138
_eltName_
.
insert
(
name
.
label
(),
name
.
label
());
139
return
true
;
140
}
141
}
142
143
auto
lookup
=
"."
+
name
.
label
();
144
auto
found
=
Set
<
std
::
string
>();
145
auto
matches
=
std
::
vector
<
std
::
string
>();
146
147
// Trying with types
148
for
(
auto
t
:
_prm_
->
types
()) {
149
if
(
endsWith
(
t
->
name
(),
lookup
)) {
150
if
(!
found
.
exists
(
t
->
name
())) {
151
found
.
insert
(
t
->
name
());
152
matches
.
push_back
(
t
->
name
());
153
}
154
}
155
}
156
// Trying with O3Types
157
for
(
auto
&
t
:
_o3_prm_
->
types
()) {
158
if
(
endsWith
(
t
->
name
().
label
(),
lookup
)) {
159
if
(!
found
.
exists
(
t
->
name
().
label
())) {
160
found
.
insert
(
t
->
name
().
label
());
161
matches
.
push_back
(
t
->
name
().
label
());
162
}
163
}
164
}
165
166
// Trying with interfaces
167
for
(
auto
i
:
_prm_
->
interfaces
()) {
168
if
(
endsWith
(
i
->
name
(),
lookup
)) {
169
if
(!
found
.
exists
(
i
->
name
())) {
170
found
.
insert
(
i
->
name
());
171
matches
.
push_back
(
i
->
name
());
172
}
173
}
174
}
175
// Trying with O3Interface
176
for
(
auto
&
i
:
_o3_prm_
->
interfaces
()) {
177
if
(
endsWith
(
i
->
name
().
label
(),
lookup
)) {
178
if
(!
found
.
exists
(
i
->
name
().
label
())) {
179
found
.
insert
(
i
->
name
().
label
());
180
matches
.
push_back
(
i
->
name
().
label
());
181
}
182
}
183
}
184
185
// Trying with class
186
for
(
auto
c
:
_prm_
->
classes
()) {
187
if
(
endsWith
(
c
->
name
(),
lookup
)) {
188
if
(!
found
.
exists
(
c
->
name
())) {
189
found
.
insert
(
c
->
name
());
190
matches
.
push_back
(
c
->
name
());
191
}
192
}
193
}
194
// Trying with O3Class
195
for
(
auto
&
c
:
_o3_prm_
->
classes
()) {
196
if
(
endsWith
(
c
->
name
().
label
(),
lookup
)) {
197
if
(!
found
.
exists
(
c
->
name
().
label
())) {
198
found
.
insert
(
c
->
name
().
label
());
199
matches
.
push_back
(
c
->
name
().
label
());
200
}
201
}
202
}
203
204
if
(
matches
.
size
() == 1) {
// One match is good
205
_eltName_
.
insert
(
name
.
label
(),
matches
.
back
());
206
name
.
label
() =
matches
.
back
();
207
return
true
;
208
209
}
else
if
(
matches
.
size
() == 0) {
// 0 match is not found
210
211
// Unknown name type
212
O3PRM_TYPE_NOT_FOUND
(
name
, *
_errors_
);
213
return
false
;
214
215
}
else
{
// More than one match is ambiguous
216
217
// Ambiguous name
218
O3PRM_TYPE_AMBIGUOUS
(
name
,
matches
, *
_errors_
);
219
return
false
;
220
}
221
}
222
223
template
<
typename
GUM_SCALAR
>
224
INLINE
bool
O3NameSolver
<
GUM_SCALAR
>::
resolveType
(
O3Label
&
name
) {
225
// If empty string, we return an empty string
226
if
(
name
.
label
() ==
""
) {
return
true
; }
227
228
// If we've already found the type real name
229
if
(
_typeName_
.
exists
(
name
.
label
())) {
230
name
.
label
() =
_typeName_
[
name
.
label
()];
231
return
true
;
232
}
233
234
// If name exists as is in PRM
235
if
(
_prm_
->
isType
(
name
.
label
())) {
236
_typeName_
.
insert
(
name
.
label
(),
name
.
label
());
237
return
true
;
238
}
239
240
// If name exists as is in O3PRM
241
for
(
auto
&
t
:
_o3_prm_
->
types
()) {
242
if
(
t
->
name
().
label
() ==
name
.
label
()) {
243
_typeName_
.
insert
(
name
.
label
(),
name
.
label
());
244
return
true
;
245
}
246
}
247
248
// If we didn't find it as is, then we must find a namespace
249
// in which it was declared
250
auto
lookup
=
"."
+
name
.
label
();
251
auto
found
=
Set
<
std
::
string
>();
252
auto
matches
=
std
::
vector
<
std
::
string
>();
253
254
// Trying with types
255
for
(
auto
t
:
_prm_
->
types
()) {
256
if
(
endsWith
(
t
->
name
(),
lookup
)) {
257
if
(!
found
.
exists
(
t
->
name
())) {
258
found
.
insert
(
t
->
name
());
259
matches
.
push_back
(
t
->
name
());
260
}
261
}
262
}
263
264
// Trying with O3Types
265
for
(
auto
&
t
:
_o3_prm_
->
types
()) {
266
if
(
endsWith
(
t
->
name
().
label
(),
lookup
)) {
267
if
(!
found
.
exists
(
t
->
name
().
label
())) {
268
found
.
insert
(
t
->
name
().
label
());
269
matches
.
push_back
(
t
->
name
().
label
());
270
}
271
}
272
}
273
274
if
(
matches
.
size
() == 1) {
// One match is good
275
_typeName_
.
insert
(
name
.
label
(),
matches
.
back
());
276
name
.
label
() =
matches
.
back
();
277
return
true
;
278
279
}
else
if
(
matches
.
size
() == 0) {
// 0 match is not found
280
281
// Unknown name type
282
O3PRM_TYPE_NOT_FOUND
(
name
, *
_errors_
);
283
return
false
;
284
285
}
else
{
// More than one match is ambiguous
286
287
// Ambiguous name
288
O3PRM_TYPE_AMBIGUOUS
(
name
,
matches
, *
_errors_
);
289
return
false
;
290
}
291
}
292
293
template
<
typename
GUM_SCALAR
>
294
INLINE
bool
O3NameSolver
<
GUM_SCALAR
>::
resolveInterface
(
O3Label
&
name
) {
295
// If empty string, we return an empty string
296
if
(
name
.
label
() ==
""
) {
return
true
; }
297
298
// If we've already found the interface real name
299
if
(
_interfaceName_
.
exists
(
name
.
label
())) {
300
name
.
label
() =
_interfaceName_
[
name
.
label
()];
301
return
true
;
302
}
303
304
// If name exists as is
305
if
(
_prm_
->
isInterface
(
name
.
label
())) {
306
_interfaceName_
.
insert
(
name
.
label
(),
name
.
label
());
307
return
true
;
308
}
309
310
for
(
auto
&
i
:
_o3_prm_
->
interfaces
()) {
311
if
(
i
->
name
().
label
() ==
name
.
label
()) {
312
_interfaceName_
.
insert
(
name
.
label
(),
name
.
label
());
313
return
true
;
314
}
315
}
316
317
// If we didn't find it as is, then we must find a namespace
318
// in which it was declared
319
auto
lookup
=
"."
+
name
.
label
();
320
auto
found
=
Set
<
std
::
string
>();
321
auto
matches
=
std
::
vector
<
std
::
string
>();
322
323
// Trying with interfaces
324
for
(
auto
i
:
_prm_
->
interfaces
()) {
325
if
(
endsWith
(
i
->
name
(),
lookup
)) {
326
if
(!
found
.
exists
(
i
->
name
())) {
327
found
.
insert
(
i
->
name
());
328
matches
.
push_back
(
i
->
name
());
329
}
330
}
331
}
332
333
// Trying with O3Interface
334
for
(
auto
&
i
:
_o3_prm_
->
interfaces
()) {
335
if
(
endsWith
(
i
->
name
().
label
(),
lookup
)) {
336
if
(!
found
.
exists
(
i
->
name
().
label
())) {
337
found
.
insert
(
i
->
name
().
label
());
338
matches
.
push_back
(
i
->
name
().
label
());
339
}
340
}
341
}
342
343
if
(
matches
.
size
() == 1) {
// One match is good
344
345
_interfaceName_
.
insert
(
name
.
label
(),
matches
.
back
());
346
name
.
label
() =
matches
.
back
();
347
return
true
;
348
349
}
else
if
(
matches
.
size
() == 0) {
// 0 match is not found
350
351
// Unknown name type
352
O3PRM_INTERFACE_NOT_FOUND
(
name
, *
_errors_
);
353
return
false
;
354
355
}
else
{
// More than one match is ambiguous
356
357
// Ambiguous name
358
O3PRM_INTERFACE_AMBIGUOUS
(
name
,
matches
, *
_errors_
);
359
return
false
;
360
}
361
}
362
363
template
<
typename
GUM_SCALAR
>
364
INLINE
bool
O3NameSolver
<
GUM_SCALAR
>::
resolveClass
(
O3Label
&
name
) {
365
// If empty string, we return an empty string
366
if
(
name
.
label
() ==
""
) {
return
true
; }
367
368
// If we've already found super real name
369
if
(
_className_
.
exists
(
name
.
label
())) {
370
name
.
label
() =
_className_
[
name
.
label
()];
371
return
true
;
372
}
373
374
// If class name exists as is
375
if
(
_prm_
->
isClass
(
name
.
label
())) {
376
_className_
.
insert
(
name
.
label
(),
name
.
label
());
377
return
true
;
378
}
379
380
for
(
auto
&
c
:
_o3_prm_
->
classes
()) {
381
if
(
c
->
name
().
label
() ==
name
.
label
()) {
382
_className_
.
insert
(
name
.
label
(),
name
.
label
());
383
return
true
;
384
}
385
}
386
387
// If we didn't find it as is, then we must find a namespace
388
// in which it was declared
389
auto
lookup
=
"."
+
name
.
label
();
390
auto
matches
=
std
::
vector
<
std
::
string
>();
391
auto
found
=
Set
<
std
::
string
>();
392
393
// Try to complete with Class
394
for
(
auto
c
:
_prm_
->
classes
()) {
395
if
(
endsWith
(
c
->
name
(),
lookup
)) {
396
if
(!
found
.
exists
(
c
->
name
())) {
397
found
.
insert
(
c
->
name
());
398
matches
.
push_back
(
c
->
name
());
399
}
400
}
401
}
402
403
// Try to complete with O3Class
404
for
(
auto
&
c
:
_o3_prm_
->
classes
()) {
405
if
(
endsWith
(
c
->
name
().
label
(),
lookup
)) {
406
if
(!
found
.
exists
(
c
->
name
().
label
())) {
407
found
.
insert
(
c
->
name
().
label
());
408
matches
.
push_back
(
c
->
name
().
label
());
409
}
410
}
411
}
412
413
if
(
matches
.
size
() == 1) {
// One match is good
414
415
_className_
.
insert
(
name
.
label
(),
matches
.
back
());
416
name
.
label
() =
matches
.
back
();
417
return
true
;
418
419
}
else
if
(
matches
.
size
() == 0) {
// 0 match is not found
420
421
// Unknown super class
422
O3PRM_CLASS_NOT_FOUND
(
name
, *
_errors_
);
423
return
false
;
424
425
}
else
{
// More than one match is ambiguous
426
427
// Ambiguous name
428
O3PRM_CLASS_AMBIGUOUS
(
name
,
matches
, *
_errors_
);
429
return
false
;
430
}
431
}
432
433
template
<
typename
GUM_SCALAR
>
434
INLINE
bool
O3NameSolver
<
GUM_SCALAR
>::
resolveSlotType
(
O3Label
&
name
) {
435
// If empty string, we return an empty string
436
if
(
name
.
label
() ==
""
) {
return
true
; }
437
// If we've already found the reference real name
438
if
(
_refName_
.
exists
(
name
.
label
())) {
439
name
.
label
() =
_refName_
[
name
.
label
()];
440
return
true
;
441
}
442
// If name exists as is
443
if
(
_prm_
->
isInterface
(
name
.
label
()) ||
_prm_
->
isClass
(
name
.
label
())) {
444
_refName_
.
insert
(
name
.
label
(),
name
.
label
());
445
return
true
;
446
}
447
448
// We check if it matches an O3Interface
449
for
(
auto
&
i
:
_o3_prm_
->
interfaces
()) {
450
if
(
i
->
name
().
label
() ==
name
.
label
()) {
451
_interfaceName_
.
insert
(
name
.
label
(),
name
.
label
());
452
return
true
;
453
}
454
}
455
456
// We check if it matches an O3Class
457
for
(
auto
&
c
:
_o3_prm_
->
classes
()) {
458
if
(
c
->
name
().
label
() ==
name
.
label
()) {
459
_className_
.
insert
(
name
.
label
(),
name
.
label
());
460
return
true
;
461
}
462
}
463
464
// If we didn't find it as is, then we must find a namespace
465
// in which it was declared
466
auto
lookup
=
"."
+
name
.
label
();
467
auto
found
=
Set
<
std
::
string
>();
468
auto
matches
=
std
::
vector
<
std
::
string
>();
469
470
// Trying with interfaces
471
for
(
auto
i
:
_prm_
->
interfaces
()) {
472
if
(
endsWith
(
i
->
name
(),
lookup
)) {
473
if
(!
found
.
exists
(
i
->
name
())) {
474
found
.
insert
(
i
->
name
());
475
matches
.
push_back
(
i
->
name
());
476
}
477
}
478
}
479
480
// Trying with O3Interface
481
for
(
auto
&
i
:
_o3_prm_
->
interfaces
()) {
482
if
(
endsWith
(
i
->
name
().
label
(),
lookup
)) {
483
if
(!
found
.
exists
(
i
->
name
().
label
())) {
484
found
.
insert
(
i
->
name
().
label
());
485
matches
.
push_back
(
i
->
name
().
label
());
486
}
487
}
488
}
489
490
// Try to complete with Class
491
for
(
auto
c
:
_prm_
->
classes
()) {
492
if
(
endsWith
(
c
->
name
(),
lookup
)) {
493
if
(!
found
.
exists
(
c
->
name
())) {
494
found
.
insert
(
c
->
name
());
495
matches
.
push_back
(
c
->
name
());
496
}
497
}
498
}
499
500
// Try to complete with O3Class
501
for
(
auto
&
c
:
_o3_prm_
->
classes
()) {
502
if
(
endsWith
(
c
->
name
().
label
(),
lookup
)) {
503
if
(!
found
.
exists
(
c
->
name
().
label
())) {
504
found
.
insert
(
c
->
name
().
label
());
505
matches
.
push_back
(
c
->
name
().
label
());
506
}
507
}
508
}
509
510
if
(
matches
.
size
() == 1) {
// One match is good
511
512
_refName_
.
insert
(
name
.
label
(),
matches
.
back
());
513
name
.
label
() =
matches
.
back
();
514
return
true
;
515
516
}
else
if
(
matches
.
size
() == 0) {
// 0 match is not found
517
518
// Unknown name type
519
O3PRM_REFERENCE_NOT_FOUND
(
name
, *
_errors_
);
520
return
false
;
521
522
}
else
{
// More than one match is ambiguous
523
524
// Ambiguous name
525
O3PRM_REFERENCE_AMBIGUOUS
(
name
,
matches
, *
_errors_
);
526
return
false
;
527
}
528
}
529
530
531
}
// namespace o3prm
532
}
// namespace prm
533
}
// namespace gum
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::prm::o3prm
Definition:
O3prm.cpp:34
gum::prm::ParamScopeData::ParamScopeData
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
Definition:
PRMClass_tpl.h:1032