aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
instantiation_inl.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 Inline implemenation of gum::Instantiation.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
*/
28
29
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimAdressable
.
h
>
30
31
namespace
gum
{
32
33
// indicates whether a given variable belongs to the Instantiation
34
INLINE
bool
Instantiation
::
contains
(
const
DiscreteVariable
&
v
)
const
{
return
_vars_
.
exists
(&
v
); }
35
36
INLINE
bool
Instantiation
::
contains
(
const
std
::
string
&
name
)
const
{
37
return
contains
(
variable
(
name
));
38
}
39
40
// indicates whether a given variable belongs to the Instantiation
41
INLINE
bool
Instantiation
::
contains
(
const
DiscreteVariable
*
v
)
const
{
return
_vars_
.
exists
(
v
); }
42
43
// modifies internally the value of a given variable of the sequence
44
INLINE
void
Instantiation
::
_chgVal_
(
Idx
varPos
,
Idx
newVal
) {
45
Idx
oldVal
=
_vals_
[
varPos
];
46
_vals_
[
varPos
] =
newVal
;
47
48
_masterChangeNotification_
(
varPos
,
newVal
,
oldVal
);
49
}
50
51
// modifies the value of a given variable of the sequence (external function)
52
INLINE Instantiation&
Instantiation
::
chgVal
(
const
DiscreteVariable
&
v
,
Idx
newVal
) {
53
try
{
54
// check that the variable does belong to the instantiation and that the
55
// new
56
// value is possible.
57
Idx
varPos
=
_vars_
.
pos
(&
v
);
// throws NotFound if v doesn't belong to this
58
59
if
(
newVal
>=
v
.
domainSize
()) {
GUM_ERROR
(
OutOfBounds
,
""
) }
60
61
// if we were in overflow, indicate that we are not anymore
62
_overflow_
=
false
;
63
64
_chgVal_
(
varPos
,
newVal
);
65
66
return
*
this
;
67
}
catch
(
NotFound
&) {
68
std
::
string
name
=
"instantiation does not contain this DiscreteVariable: "
;
69
GUM_ERROR
(
NotFound
,
name
+
v
.
name
())
70
}
71
}
72
73
INLINE
Instantiation
&
Instantiation
::
chgVal
(
const
DiscreteVariable
*
v
,
Idx
newVal
) {
74
try
{
75
// check that the variable does belong to the instantiation and that the
76
// new
77
// value is possible.
78
Idx
varPos
=
_vars_
.
pos
(
v
);
// throws NotFound if v doesn't belong to this
79
80
if
(
newVal
>=
v
->
domainSize
()) {
GUM_ERROR
(
OutOfBounds
,
""
) }
81
82
// if we were in overflow, indicate that we are not anymore
83
_overflow_
=
false
;
84
85
_chgVal_
(
varPos
,
newVal
);
86
87
return
*
this
;
88
}
catch
(
NotFound
&) {
89
std
::
string
name
=
"instantiation does not contain this DiscreteVariable: "
;
90
GUM_ERROR
(
NotFound
,
name
+
v
->
name
())
91
}
92
}
93
94
// modifies the value of a given variable of the sequence (external function)
95
INLINE
Instantiation
&
Instantiation
::
chgVal
(
Idx
varPos
,
Idx
newVal
) {
96
// check that the variable does belong to the instantiation and that the new
97
// value is possible.
98
if
(
_vals_
.
size
() <=
varPos
) {
GUM_ERROR
(
NotFound
,
""
) }
99
100
if
(
newVal
>=
_vars_
[
varPos
]->
domainSize
()) {
GUM_ERROR
(
OutOfBounds
,
""
) }
101
102
// if we were in overflow, indicate that we are not anymore
103
_overflow_
=
false
;
104
105
_chgVal_
(
varPos
,
newVal
);
106
107
return
*
this
;
108
}
109
110
INLINE
Instantiation
&
Instantiation
::
chgVal
(
const
std
::
string
&
var
,
Idx
newVal
) {
111
return
chgVal
(
variable
(
var
),
newVal
);
112
}
113
114
INLINE
Instantiation
&
Instantiation
::
chgVal
(
const
std
::
string
&
var
,
const
std
::
string
&
newVal
) {
115
const
auto
&
vv
=
variable
(
var
);
116
Idx
pos
=
vv
.
index
(
newVal
);
117
return
chgVal
(
vv
,
pos
);
118
}
119
120
// adds a new var to the sequence of vars
121
INLINE
void
Instantiation
::
add
(
const
DiscreteVariable
&
v
) {
122
// if _master_ : not allowed
123
if
(
_master_
) {
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
) }
124
125
// check if the variable already belongs to the tuple of variables
126
// of the Instantiation
127
if
(
_vars_
.
exists
(&
v
)) {
128
GUM_ERROR
(
DuplicateElement
,
"Var <"
<<
v
.
name
() <<
"> already exists in this instantiation"
)
129
}
130
131
for
(
const
auto
&
vv
:
_vars_
) {
132
if
(
vv
->
name
() ==
v
.
name
()) {
133
GUM_ERROR
(
InvalidArgument
,
134
"Var with name <"
<<
v
.
name
() <<
"> already exists in this instantiation"
);
135
}
136
}
137
138
// actually add the new dimension
139
_add_
(
v
);
140
}
141
142
// removes a variable from the sequence of vars
143
INLINE
void
Instantiation
::
erase
(
const
DiscreteVariable
&
v
) {
144
// if _master_ : not allowed
145
if
(
_master_
) {
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
) }
146
147
// check that the variable does actually belong to the Instantiation
148
if
(!
_vars_
.
exists
(&
v
)) {
GUM_ERROR
(
NotFound
,
"Var does not exist in this instantiation"
) }
149
150
// actually delete the dimension
151
_erase_
(
v
);
152
}
153
154
INLINE
void
Instantiation
::
erase
(
const
std
::
string
&
name
) {
erase
(
variable
(
name
)); }
155
156
// removes everything
157
INLINE
void
Instantiation
::
clear
() {
158
if
(
_master_
) {
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
) }
159
160
_vars_
.
clear
();
161
_vals_
.
clear
();
162
}
163
164
// @brief returns the product of the size of the domains of the variables
165
// belonging to the matrix
166
INLINE
Size
Instantiation
::
domainSize
()
const
{
167
Size
s
= 1;
168
169
for
(
const
auto
var
:
_vars_
)
170
s
*=
var
->
domainSize
();
171
172
return
s
;
173
}
174
175
// returns the index of a var
176
INLINE
Idx
Instantiation
::
pos
(
const
DiscreteVariable
&
k
)
const
{
return
_vars_
.
pos
(&
k
); }
177
178
// returns the number of vars in the sequence
179
INLINE
Idx
Instantiation
::
nbrDim
()
const
{
return
_vars_
.
size
(); }
180
181
// returns the current value of a given variable
182
INLINE
Idx
Instantiation
::
val
(
Idx
i
)
const
{
183
if
(
i
>=
_vals_
.
size
()) {
184
GUM_ERROR
(
NotFound
,
i
<<
" is out of bound index for the instantiation."
)
185
}
186
187
return
_vals_
[
i
];
188
}
189
190
// returns the current value of a given variable
191
INLINE
Idx
Instantiation
::
val
(
const
DiscreteVariable
&
var
)
const
{
192
return
_vals_
[
_vars_
.
pos
(&
var
)];
193
}
194
// returns the current value of a given variable
195
INLINE
Idx
Instantiation
::
val
(
const
std
::
string
&
name
)
const
{
return
val
(
variable
(
name
)); }
196
197
198
// returns the current value of a given variable
199
INLINE
Idx
Instantiation
::
valFromPtr
(
const
DiscreteVariable
*
pvar
)
const
{
200
return
_vals_
[
_vars_
.
pos
(
pvar
)];
201
}
202
203
// returns the variable at position i in the tuple
204
INLINE
const
DiscreteVariable
&
Instantiation
::
variable
(
Idx
i
)
const
{
return
*(
_vars_
.
atPos
(
i
)); }
205
// returns the variable with name in the tuple
206
INLINE
const
DiscreteVariable
&
Instantiation
::
variable
(
const
std
::
string
&
name
)
const
{
207
for
(
const
auto
&
v
:
_vars_
) {
208
if
(
v
->
name
() ==
name
)
return
*
v
;
209
}
210
211
GUM_ERROR
(
NotFound
,
"'"
<<
name
<<
"' can not be found in the instantiation."
)
212
}
213
214
// indicates whether the current value of the tuple is correct or not
215
INLINE
bool
Instantiation
::
inOverflow
()
const
{
return
_overflow_
; }
216
217
// end() just is a synonym for inOverflow()
218
INLINE
bool
Instantiation
::
end
()
const
{
return
inOverflow
(); }
219
220
// rend() just is a synonym for inOverflow()
221
INLINE
bool
Instantiation
::
rend
()
const
{
return
inOverflow
(); }
222
223
// indicates that the current value is correct even if it should be in
224
// overflow
225
INLINE
void
Instantiation
::
unsetOverflow
() {
_overflow_
=
false
; }
226
227
// alias for unsetOverflow
228
INLINE
void
Instantiation
::
unsetEnd
() {
_overflow_
=
false
; }
229
230
// operator ++
231
INLINE
void
Instantiation
::
inc
() {
232
Size
p
=
nbrDim
();
233
if
(
p
== 0) {
_overflow_
=
true
; }
234
235
if
(
_overflow_
)
return
;
236
p
-= 1;
237
Idx
cpt
= 0;
238
// if we are in overflow, do nothing
239
240
// perform the increment
241
while
(
true
) {
242
Idx
v
=
_vals_
[
cpt
];
243
244
if
(
v
+ 1 ==
_vars_
[
cpt
]->
domainSize
()) {
245
_vals_
[
cpt
] = 0;
246
247
if
(
cpt
==
p
) {
248
_overflow_
=
true
;
249
_masterFirstNotification_
();
250
return
;
251
}
else
252
++
cpt
;
253
}
else
{
254
++
_vals_
[
cpt
];
255
break
;
256
}
257
}
258
259
_masterIncNotification_
();
260
}
261
262
// operator --
263
INLINE
void
Instantiation
::
dec
() {
264
Size
p
=
nbrDim
();
265
if
(
p
== 0) {
_overflow_
=
true
; }
266
267
if
(
_overflow_
)
return
;
268
p
-= 1;
269
Idx
cpt
= 0;
270
// if we are in overflow, do nothing
271
272
// perform the increment
273
while
(
true
) {
274
Idx
v
=
_vals_
[
cpt
];
275
276
if
(
v
== 0) {
277
_vals_
[
cpt
] =
_vars_
[
cpt
]->
domainSize
() - 1;
278
279
if
(
cpt
==
p
) {
280
_overflow_
=
true
;
281
282
_masterLastNotification_
();
283
284
return
;
285
}
else
286
++
cpt
;
287
}
else
{
288
--
_vals_
[
cpt
];
289
break
;
290
}
291
}
292
293
_masterDecNotification_
();
294
}
295
296
// operator ++
297
INLINE
Instantiation
&
Instantiation
::
operator
++() {
298
inc
();
299
return
*
this
;
300
}
301
302
// operator --
303
INLINE
Instantiation
&
Instantiation
::
operator
--() {
304
dec
();
305
return
*
this
;
306
}
307
308
// operator +=
309
INLINE
Instantiation
&
Instantiation
::
operator
+=(
Size
depl
) {
310
for
(
Idx
i
= 0;
i
<
depl
;
i
++)
311
inc
();
312
313
return
*
this
;
314
}
315
316
// operator -=
317
INLINE
Instantiation
&
Instantiation
::
operator
-=(
Size
depl
) {
318
for
(
Idx
i
= 0;
i
<
depl
;
i
++)
319
dec
();
320
321
return
*
this
;
322
}
323
324
// assign the (0,0,...) first value to the tuple of the Instantiation.
325
INLINE
void
Instantiation
::
setFirst
() {
326
_overflow_
=
false
;
327
Size
s
=
nbrDim
();
328
329
for
(
Idx
p
= 0;
p
<
s
; ++
p
)
330
_vals_
[
p
] = 0;
331
332
_masterFirstNotification_
();
333
}
334
335
// put the (D1-1,D2-1,...) last value in the Instantiation
336
INLINE
void
Instantiation
::
setLast
() {
337
_overflow_
=
false
;
338
Size
s
=
nbrDim
();
339
340
for
(
Idx
p
= 0;
p
<
s
; ++
p
)
341
_vals_
[
p
] =
_vars_
[
p
]->
domainSize
() - 1;
342
343
_masterLastNotification_
();
344
}
345
346
// operator ++ limited only to the variables in i
347
INLINE
void
Instantiation
::
incIn
(
const
Instantiation
&
i
) {
348
// if i is empty, overflow and do nothing
349
if
(
i
.
nbrDim
() == 0) {
350
_overflow_
=
true
;
351
return
;
352
}
353
354
// if we are in overflow, do nothing
355
if
(
_overflow_
)
return
;
356
357
Size
p
=
i
.
nbrDim
() - 1;
358
359
Idx
i_cpt
= 0;
360
361
while
(
true
) {
362
// verify that _vars_[cpt] belongs to i before incrementing its value
363
const
DiscreteVariable
&
v
=
i
.
variable
(
i_cpt
);
364
365
if
(!
contains
(
v
)) {
366
if
(
i_cpt
==
p
) {
367
_overflow_
=
true
;
368
return
;
369
}
else
370
++
i_cpt
;
371
}
else
{
372
Idx
cpt
=
pos
(
v
);
373
Idx
iv
=
_vals_
[
cpt
];
374
375
if
(
iv
+ 1 ==
_vars_
[
cpt
]->
domainSize
()) {
376
_chgVal_
(
cpt
, 0);
377
378
if
(
i_cpt
==
p
) {
379
_overflow_
=
true
;
380
return
;
381
}
else
382
++
i_cpt
;
383
}
else
{
384
_chgVal_
(
cpt
,
iv
+ 1);
385
return
;
386
}
387
}
388
}
389
}
390
391
// operator -- limited only to the variables in i
392
INLINE
void
Instantiation
::
decIn
(
const
Instantiation
&
i
) {
393
Size
p
=
i
.
nbrDim
() - 1;
394
Idx
i_cpt
= 0;
395
// if we are in overflow, do nothing
396
397
if
(
_overflow_
)
return
;
398
399
while
(
true
) {
400
// verify that _vars_[cpt] belongs to i before incrementing its value
401
const
DiscreteVariable
&
v
=
i
.
variable
(
i_cpt
);
402
403
if
(!
contains
(
v
)) {
404
if
(
i_cpt
==
p
) {
405
_overflow_
=
true
;
406
return
;
407
}
else
408
++
i_cpt
;
409
}
else
{
410
Idx
cpt
=
pos
(
v
);
411
Idx
iv
=
_vals_
[
cpt
];
412
413
if
(
iv
== 0) {
414
_chgVal_
(
cpt
,
_vars_
[
cpt
]->
domainSize
() - 1);
415
416
if
(
i_cpt
==
p
) {
417
_overflow_
=
true
;
418
return
;
419
}
else
420
++
i_cpt
;
421
}
else
{
422
_chgVal_
(
cpt
,
iv
- 1);
423
return
;
424
}
425
}
426
}
427
}
428
429
// reorder vars in *this
430
INLINE
void
Instantiation
::
reorder
(
const
Instantiation
&
i
) {
reorder
(
i
.
variablesSequence
()); }
431
432
// put the (0,0,...) first value in the Instantiation for the variables in i
433
INLINE
void
Instantiation
::
setFirstIn
(
const
Instantiation
&
i
) {
434
_overflow_
=
false
;
435
Idx
s
=
nbrDim
();
436
437
for
(
Size
p
= 0;
p
<
s
; ++
p
)
438
if
(
i
.
contains
(
_vars_
[
p
]))
_chgVal_
(
p
, 0);
439
}
440
441
// change values with those in i
442
INLINE
Instantiation
&
Instantiation
::
setVals
(
const
Instantiation
&
i
) {
443
_overflow_
=
false
;
444
Idx
s
=
i
.
nbrDim
();
445
446
for
(
Size
p
= 0;
p
<
s
; ++
p
)
447
if
(
contains
(
i
.
variable
(
p
)))
_chgVal_
(
pos
(
i
.
variable
(
p
)),
i
.
val
(
p
));
448
449
return
*
this
;
450
}
451
452
// put the (D1-1,D2-1,...) lastvalue in the Instantiation for variables in i
453
INLINE
void
Instantiation
::
setLastIn
(
const
Instantiation
&
i
) {
454
_overflow_
=
false
;
455
Idx
s
=
nbrDim
();
456
457
for
(
Size
p
= 0;
p
<
s
; ++
p
)
458
if
(
i
.
contains
(
_vars_
[
p
]))
_chgVal_
(
p
,
_vars_
[
p
]->
domainSize
() - 1);
459
}
460
461
// operator ++ for the variables not in i
462
INLINE
void
Instantiation
::
incOut
(
const
Instantiation
&
i
) {
463
Size
p
=
nbrDim
() - 1;
464
Idx
cpt
= 0;
465
// if we are in overflow, do nothing
466
467
if
(
_overflow_
)
return
;
468
469
while
(
true
) {
470
if
(
i
.
contains
(
_vars_
[
cpt
])) {
471
if
(
cpt
==
p
) {
472
_overflow_
=
true
;
473
return
;
474
}
else
475
++
cpt
;
476
}
else
{
477
Idx
v
=
_vals_
[
cpt
];
478
479
if
(
v
+ 1 ==
_vars_
[
cpt
]->
domainSize
()) {
480
_chgVal_
(
cpt
, 0);
481
482
if
(
cpt
==
p
) {
483
_overflow_
=
true
;
484
return
;
485
}
else
486
++
cpt
;
487
}
else
{
488
_chgVal_
(
cpt
,
v
+ 1);
489
return
;
490
}
491
}
492
}
493
}
494
495
// operator -- for the variables not in i
496
INLINE
void
Instantiation
::
decOut
(
const
Instantiation
&
i
) {
497
Size
p
=
nbrDim
() - 1;
498
Idx
cpt
= 0;
499
// if we are in overflow, do nothing
500
501
if
(
_overflow_
)
return
;
502
503
while
(
true
) {
504
if
(
i
.
contains
(
_vars_
[
cpt
])) {
505
if
(
cpt
==
p
) {
506
_overflow_
=
true
;
507
return
;
508
}
else
509
++
cpt
;
510
}
else
{
511
Idx
v
=
_vals_
[
cpt
];
512
513
if
(
v
== 0) {
514
_chgVal_
(
cpt
,
_vars_
[
cpt
]->
domainSize
() - 1);
515
516
if
(
cpt
==
p
) {
517
_overflow_
=
true
;
518
return
;
519
}
else
520
++
cpt
;
521
}
else
{
522
_chgVal_
(
cpt
,
v
- 1);
523
return
;
524
}
525
}
526
}
527
}
528
529
// put the (0,0,...) first val in the Instantiation for the variables not in
530
// i
531
INLINE
void
Instantiation
::
setFirstOut
(
const
Instantiation
&
i
) {
532
_overflow_
=
false
;
533
Idx
s
=
nbrDim
();
534
535
for
(
Size
p
= 0;
p
<
s
; ++
p
)
536
if
(!
i
.
contains
(
_vars_
[
p
]))
_chgVal_
(
p
, 0);
537
}
538
539
// put the (D1-1,D2-1,...) lastvalue in the Instantiation for vars not in i
540
INLINE
void
Instantiation
::
setLastOut
(
const
Instantiation
&
i
) {
541
_overflow_
=
false
;
542
Idx
s
=
nbrDim
();
543
544
for
(
Size
p
= 0;
p
<
s
; ++
p
)
545
if
(!
i
.
contains
(
_vars_
[
p
]))
_chgVal_
(
p
,
_vars_
[
p
]->
domainSize
() - 1);
546
}
547
548
// operator ++ for vars which are not v.
549
INLINE
void
Instantiation
::
incNotVar
(
const
DiscreteVariable
&
v
) {
550
Size
p
=
nbrDim
() - 1;
551
Idx
cpt
= 0;
552
// if we are in overflow, do nothing
553
554
if
(
_overflow_
)
return
;
555
556
while
(
true
) {
557
if
(
_vars_
[
cpt
] == &
v
) {
558
if
(
cpt
==
p
) {
559
_overflow_
=
true
;
560
return
;
561
}
else
562
++
cpt
;
563
}
else
{
564
Idx
iv
=
_vals_
[
cpt
];
565
566
if
(
iv
+ 1 ==
_vars_
[
cpt
]->
domainSize
()) {
567
_chgVal_
(
cpt
, 0);
568
569
if
(
cpt
==
p
) {
570
_overflow_
=
true
;
571
return
;
572
}
else
573
++
cpt
;
574
}
else
{
575
_chgVal_
(
cpt
,
iv
+ 1);
576
return
;
577
}
578
}
579
}
580
}
581
582
// operator -- for vars which are not v.
583
INLINE
void
Instantiation
::
decNotVar
(
const
DiscreteVariable
&
v
) {
584
Size
p
=
nbrDim
() - 1;
585
Idx
cpt
= 0;
586
// if we are in overflow, do nothing
587
588
if
(
_overflow_
)
return
;
589
590
while
(
true
) {
591
if
(
_vars_
[
cpt
] == &
v
) {
592
if
(
cpt
==
p
) {
593
_overflow_
=
true
;
594
return
;
595
}
else
596
++
cpt
;
597
}
else
{
598
Idx
iv
=
_vals_
[
cpt
];
599
600
if
(
iv
== 0) {
601
_chgVal_
(
cpt
,
_vars_
[
cpt
]->
domainSize
() - 1);
602
603
if
(
cpt
==
p
) {
604
_overflow_
=
true
;
605
return
;
606
}
else
607
++
cpt
;
608
}
else
{
609
_chgVal_
(
cpt
,
iv
- 1);
610
return
;
611
}
612
}
613
}
614
}
615
616
// assign the (0,0,...) first value to variables which are not v.
617
INLINE
void
Instantiation
::
setFirstNotVar
(
const
DiscreteVariable
&
v
) {
618
_overflow_
=
false
;
619
Idx
s
=
nbrDim
();
620
621
for
(
Size
p
= 0;
p
<
s
; ++
p
) {
622
if
(
_vars_
[
p
] == &
v
) {
623
Idx
oldval
=
_vals_
[
p
];
624
setFirst
();
625
_chgVal_
(
p
,
oldval
);
626
return
;
627
}
628
}
629
630
setFirst
();
631
}
632
633
// put the (D1-1,D2-1,...) lastvalue in the Instantiation for vars != v
634
INLINE
void
Instantiation
::
setLastNotVar
(
const
DiscreteVariable
&
v
) {
635
_overflow_
=
false
;
636
Idx
s
=
nbrDim
();
637
638
for
(
Size
p
= 0;
p
<
s
; ++
p
) {
639
if
(
_vars_
[
p
] == &
v
) {
640
Idx
oldval
=
_vals_
[
p
];
641
setLast
();
642
_chgVal_
(
p
,
oldval
);
643
return
;
644
}
645
}
646
647
setLast
();
648
}
649
650
// operator ++ for variable v only
651
INLINE
void
Instantiation
::
incVar
(
const
DiscreteVariable
&
v
) {
652
// get the position of the variable
653
Idx
cpt
=
_vars_
.
pos
(&
v
);
654
// if we are in overflow, do nothing
655
656
if
(
_overflow_
)
return
;
657
658
Idx
p
=
_vals_
[
cpt
];
659
660
if
(
p
+ 1 ==
v
.
domainSize
()) {
661
_chgVal_
(
cpt
, 0);
662
_overflow_
=
true
;
663
}
else
{
664
_chgVal_
(
cpt
,
p
+ 1);
665
}
666
}
667
668
// operator -- for variable v only
669
INLINE
void
Instantiation
::
decVar
(
const
DiscreteVariable
&
v
) {
670
// get the position of the variable
671
Idx
cpt
=
_vars_
.
pos
(&
v
);
672
// if we are in overflow, do nothing
673
674
if
(
_overflow_
)
return
;
675
676
Idx
p
=
_vals_
[
cpt
];
677
678
if
(
p
== 0) {
679
_chgVal_
(
cpt
,
v
.
domainSize
() - 1);
680
_overflow_
=
true
;
681
}
else
{
682
_chgVal_
(
cpt
,
p
- 1);
683
}
684
}
685
686
// assign the first value in the Instantiation for var v.
687
INLINE
void
Instantiation
::
setFirstVar
(
const
DiscreteVariable
&
v
) {
688
_overflow_
=
false
;
689
_chgVal_
(
_vars_
.
pos
(&
v
), 0);
690
}
691
692
// assign the last value to var v.
693
INLINE
void
Instantiation
::
setLastVar
(
const
DiscreteVariable
&
v
) {
694
_overflow_
=
false
;
695
_chgVal_
(
_vars_
.
pos
(&
v
),
v
.
domainSize
() - 1);
696
}
697
698
// indicates whether the Instantiation has a master MultiDimAdressable
699
INLINE
bool
Instantiation
::
isSlave
()
const
{
return
(
_master_
!=
nullptr
); }
700
701
// indicates wether the MultiDimAdressable* m is the master
702
INLINE
bool
Instantiation
::
isMaster
(
const
MultiDimAdressable
*
m
)
const
{
return
(
_master_
==
m
); }
703
704
// indicates wether the MultiDimAdressable* m is the master
705
INLINE
bool
Instantiation
::
isMaster
(
const
MultiDimAdressable
&
m
)
const
{
return
isMaster
(&
m
); }
706
707
// returns the sequence of DiscreteVariable
708
INLINE
const
Sequence
<
const
DiscreteVariable
* >&
Instantiation
::
variablesSequence
()
const
{
709
return
_vars_
;
710
}
711
712
713
// replace 2 vars in the Instantiation
714
INLINE
void
Instantiation
::
_swap_
(
Idx
i
,
Idx
j
) {
715
if
(
i
==
j
)
return
;
716
717
_vars_
.
swap
(
i
,
j
);
718
719
Idx
v
;
720
v
=
_vals_
[
i
];
721
_vals_
[
i
] =
_vals_
[
j
];
722
_vals_
[
j
] =
v
;
723
}
724
725
// reordering
726
INLINE
727
void
Instantiation
::
reorder
(
const
Sequence
<
const
DiscreteVariable
* >&
original
) {
728
if
(
_master_
!=
nullptr
) {
729
GUM_ERROR
(
OperationNotAllowed
,
"Reordering impossible in slave instantiation"
)
730
}
731
732
_reorder_
(
original
);
733
}
734
735
INLINE
736
void
Instantiation
::
_reorder_
(
const
Sequence
<
const
DiscreteVariable
* >&
original
) {
737
Idx
max
=
original
.
size
();
738
Idx
position
= 0;
739
for
(
Idx
i
= 0;
i
<
max
; ++
i
) {
740
const
DiscreteVariable
*
pv
=
original
.
atPos
(
i
);
741
742
if
(
contains
(
pv
)) {
743
auto
p
=
pos
(*
pv
);
744
GUM_ASSERT
(
p
>=
position
);
// this var should not be
745
// already placed.
746
_swap_
(
position
,
p
);
747
position
++;
748
}
749
}
750
}
751
752
753
// add new dim by master
754
INLINE
void
Instantiation
::
addWithMaster
(
const
MultiDimAdressable
*
m
,
const
DiscreteVariable
&
v
) {
755
if
(
m
!=
_master_
) {
GUM_ERROR
(
OperationNotAllowed
,
"only master can do this"
) }
756
757
_add_
(
v
);
758
}
759
760
761
// adds a new var to the sequence of vars
762
INLINE
void
Instantiation
::
_add_
(
const
DiscreteVariable
&
v
) {
763
_vars_
.
insert
(&
v
);
764
_vals_
.
push_back
(0);
765
_overflow_
=
false
;
766
}
767
768
// removes a variable from the sequence of vars
769
INLINE
void
Instantiation
::
_erase_
(
const
DiscreteVariable
&
v
) {
770
// get the position of the variable
771
Idx
pos
=
_vars_
.
pos
(&
v
);
772
_vars_
.
erase
(&
v
);
773
_vals_
.
erase
(
_vals_
.
begin
() +
pos
);
774
}
775
776
// is this empty ?
777
INLINE
bool
Instantiation
::
empty
()
const
{
return
_vals_
.
empty
(); }
778
779
// Replace x by y.
780
INLINE
void
Instantiation
::
replace_
(
const
DiscreteVariable
*
x
,
const
DiscreteVariable
*
y
) {
781
_vars_
.
setAtPos
(
_vars_
.
pos
(
x
),
y
);
782
}
783
784
/// returns a hashed key for hash tables the keys of which are represented
785
/// by vectors of Idx
786
INLINE
Size
HashFunc
<
Instantiation
>::
castToSize
(
const
Instantiation
&
key
) {
787
Size
h
=
Size
(0);
788
for
(
const
DiscreteVariable
*
k
:
789
key
.
variablesSequence
())
// k are unique only by address (not by name)
790
h
+=
HashFunc
<
const
DiscreteVariable
* >::
castToSize
(
k
) *
Size
(
key
.
val
(*
k
));
791
792
return
h
;
793
}
794
795
/// returns a hashed key for hash tables the keys of which are represented
796
/// by vectors of Idx
797
INLINE
Size
HashFunc
<
Instantiation
>::
operator
()(
const
Instantiation
&
key
)
const
{
798
return
castToSize
(
key
) &
this
->
hash_mask_
;
799
}
800
801
INLINE
bool
Instantiation
::
operator
==(
const
Instantiation
&
other
)
const
{
802
if
(
inOverflow
() &&
other
.
inOverflow
())
return
true
;
803
if
(
other
.
nbrDim
() !=
nbrDim
())
return
false
;
804
for
(
const
auto
&
k
:
variablesSequence
()) {
805
if
(!
other
.
contains
(
k
))
return
false
;
806
if
(
val
(*
k
) !=
other
.
val
(*
k
))
return
false
;
807
}
808
return
true
;
809
}
810
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643