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