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