aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
setInst.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 Headers of SetInst.
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  * @author Ariele MAESANO
28  */
29 
30 #ifndef GUM_SETINST_H
31 #define GUM_SETINST_H
32 
33 #include <ostream>
34 
35 #include <agrum/agrum.h>
36 
37 #include <agrum/tools/core/bijection.h>
38 #include <agrum/tools/multidim/implementations/multiDimAdressable.h>
39 #include <agrum/tools/multidim/implementations/multiDimInterface.h>
40 
41 namespace gum {
42 
43  class MultiDimAdressable;
44 
45  class Instantiation;
46  // ==========================================================================
47  // === GUM_SetInst ===
48  // ==========================================================================
49  /**
50  * @class SetInst
51  * @headerfile setInst.h <agrum/tools/multidim/SetInst.h>
52  * @ingroup multidim_group
53  *
54  * @brief Class for assigning/browsing values to tuples of discrete variables.
55  *
56  * SetInst is designed to assign a set of deterministic values to tuples of
57  * variables for contextual dependencies detection.
58  *
59  * For a variable I of possible determinstic instances \f$i1, i2, i3,
60  * \ldots\f$ in the expresion of a set of instantiations is express by the
61  * boolean state of each instance transform in an integer.
62  * For example: \f$i1\f$ or \f$i2\f$ or \f$i4\f$ will be :
63  * \code
64  * i4 i3 i2 i1
65  * 1 0 1 1 -> 11
66  * \endcode
67  *
68  * There is two different types of setters:
69  * - function ending in val take the instance and encode it.
70  * - function ending in vals take allready the encoded expression of the
71  * intances union.
72  *
73  * @warning The model is based on the implementation of aGrUM Instantiation
74  * source code. The only difference is the impossibility to loop since the
75  * SetInst is not create to run through, but to collect all union of the
76  * possible instantiations of each variable, on the multiDimAdressable.
77  *
78  * To print information about a SetInst use the following function:
79  * @see operator<<(std::ostream&, const SetInst&)
80  */
81  class SetInst {
82  public:
83  // =========================================================================
84  /// @name Constructors / Destructors
85  // =========================================================================
86  /// @{
87 
88  /**
89  * @brief Default constructor: creates an empty tuple.
90  */
91  SetInst();
92 
93  /**
94  * @brief Copy constructor.
95  * @param aI The SetInst to copy.
96  */
97  SetInst(const SetInst& aI);
98 
99  /**
100  * @brief Copy constructor.
101  * @param aI The SetInst to copy.
102  */
103  SetInst(const Instantiation& aI);
104 
105  /**
106  * @brief Copy operator.
107  * @warning An OperationNotAllowed will be raised if you use the copy
108  * operator.
109  */
110  SetInst& operator=(const SetInst& aI);
111 
112  /**
113  * @brief Constructor for a SetInst of all the variables of a
114  * MultiDimAdressable.
115  *
116  * @param aMD The array the variables of which are those of the SetInst.
117  */
118  SetInst(MultiDimAdressable& aMD);
119 
120  /**
121  * @brief Constructor for a SetInst of all the variables of a
122  * MultiDimAdressable.
123  *
124  * @param aMD The array the variables of which are those of the SetInst.
125  */
126  SetInst(const MultiDimAdressable& aMD);
127 
128  /**
129  * @brief Constructor for a SetInst of all the variables of a
130  * MultiDimAdressable.
131  *
132  * @param aMD The array the variables of which are those of the SetInst.
133  */
134  SetInst(MultiDimAdressable* aMD);
135 
136  /**
137  * @brief Constructor for a SetInst of all the variables of a
138  * MultiDimAdressable.
139  *
140  * @param aMD The array the variables of which are those of the SetInst
141  */
142  SetInst(const MultiDimAdressable* aMD);
143 
144  /**
145  * @brief Class destructor.
146  */
147  ~SetInst();
148 
149  /// @}
150  // =========================================================================
151  /// @name Accessors / Modifiers
152  // =========================================================================
153  /// @{
154 
155  /**
156  * @brief Returns the number of variables in the SetInst.
157  * @return Returns the number of variables in the SetInst.
158  */
159  Idx nbrDim() const;
160 
161  /**
162  * @brief Adds a new variable in the SetInst.
163  *
164  * @warning Variable v is known to the SetInst only by a pointer to it. As
165  * a result, this is not a copy of v that is used by SetInst But rather v
166  * itself. As such, v should never be deleted from memory until the SetInst
167  * is removed.
168  *
169  * @param v The new variable.
170  *
171  * @throw DuplicateElement Raised if c is already in this SetInst.
172  * @throw OperationNotAllowed Raised if the SetInst is a slave.
173  */
174  void add(const DiscreteVariable& v);
175 
176  /**
177  * @brief Removes a variable from the SetInst.
178  *
179  * @param v The variable to erase.
180  * @throw NotFound Raised if v is not in this SetInst.
181  * @throw OperationNotAllowed Raised if the SetInst is a slave.
182  */
183  void erase(const DiscreteVariable& v);
184 
185  /**
186  * @brief Erase all variables from an SetInst
187  * @throw OperationNotAllowed Raised if the SetInst is a slave.
188  */
189  void clear();
190 
191  /**
192  * @brief Returns the product of the variable's domain size in the SetInst.
193  * @return Returns the product of the variable's domain size in the
194  * SetInst.
195  */
196  Size domainSize() const;
197 
198  /**
199  * @brief Returns the position of the variable v.
200  * @throw NotFound Raised if v does not belong to the SetInst.
201  */
202  Idx pos(const DiscreteVariable& v) const;
203 
204  /**
205  * @brief Returns the current value of the variable at position i.
206  *
207  * @param i The index of the variable.
208  * @return Returns the current value of the variable at position i.
209  *
210  * @throw NotFound Raised if the element cannot be found.
211  */
212  Size vals(Idx i) const;
213 
214  /**
215  * @brief Returns the current value of a given variable.
216  *
217  * @param var The variable the value of which we wish to know.
218  * @return Returns the current value of a given variable.
219  *
220  * @throw NotFound Raised it var does not belong to the SetInst.
221  */
222  Size vals(const DiscreteVariable& var) const;
223 
224  /**
225  * @brief Returns the current value of a given variable.
226  *
227  * @param var The variable the value of which we wish to know.
228  * @return Returns the current value of a given variable.
229  *
230  * @throw NotFound Raised if var does not belong to the SetInst.
231  */
232  Size vals(const DiscreteVariable* var) const;
233 
234  /**
235  * @brief Returns the current value of the variable at position i.
236  *
237  * @param var the variable.
238  * @return Returns the current value of the variable at position i.
239  *
240  * @throw NotFound raised if the element cannot be found.
241  */
242  Idx nbrOccurences(const DiscreteVariable& var) const;
243 
244 
245  /**
246  * @brief Returns the current value of a variable at a given position.
247  *
248  * @param i The position of the variable for which its value is returned.
249  * @return Returns the current value of a variable at a given position.
250  *
251  * @throw NotFound raised it var does not belong to the SetInst.
252  */
253  Idx val(Idx i) const;
254 
255  /**
256  * @brief Returns the current value of a given variable.
257  *
258  * @param var The variable the value of which we wish to know.
259  * @return Returns the current value of a given variable.
260  *
261  * @throw NotFound Raised it var does not belong to the SetInst.
262  */
263  Idx val(const DiscreteVariable& var) const;
264 
265  /**
266  * @brief Returns the current value of a given variable.
267  *
268  * @param var The variable the value of which we wish to know.
269  * @return Returns the current value of a given variable.
270  *
271  * @throw NotFound Raised if var does not belong to the SetInst.
272  */
273  Idx val(const DiscreteVariable* var) const;
274 
275  /**
276  * @brief Returns the variable at position i in the tuple.
277  *
278  * @param i The index of the variable.
279  * @return Returns the variable at position i in the tuple.
280  *
281  * @throw NotFound Raised if the element cannot be found.
282  */
283  const DiscreteVariable& variable(Idx i) const;
284 
285  /**
286  * @brief Assign newVal to variable v in the SetInst.
287  *
288  * @param v The variable whose value is assigned.
289  * @param newVal The index of the value assigned (consider the values of v
290  * as an array indexed from 0 to n of values (which might be anything from
291  * real numbers to strings, etc). Parameter newVal indicates the index in
292  * this array of the new value taken by v.
293  * @return Returns a reference to *this in order to chain the chgVal.
294  *
295  * @throw NotFound Raised if variable v does not belong to the SetInst.
296  * @throw OutOfBound Raised if newVal is not a possible value for v.
297  */
298  SetInst& chgVal(const DiscreteVariable& v, Idx newVal);
299 
300  /**
301  * @brief Assign newVal to variable v in the SetInst.
302  *
303  * @param v The variable whose value is assigned.
304  * @param newVal The index of the value assigned (consider the values of v
305  * as an array indexed from 0 to n of values (which might be anything from
306  * real numbers to strings, etc). Parameter newVal indicates the index in
307  * this array of the new value taken by v.
308  * @return Returns a reference to *this in order to chain the chgVal.
309  *
310  * @throw NotFound Raised if variable v does not belong to the SetInst.
311  * @throw OutOfBound Raised if newVal is not a possible value for v.
312  */
313  SetInst& chgVal(const DiscreteVariable* v, Idx newVal);
314 
315  /**
316  * @brief Assign newVal to variable at position varPos in the SetInst.
317  *
318  * @param varPos The index of the variable whose value is assigned in the
319  * tuple of variables of the SetInst.
320  * @param newVal The index of the value assigned (consider the values of
321  * the variable as an array indexed from 0 to n of values (which might be
322  * anything from real numbers to strings, etc). Parameter newVal indicates
323  * the index in this array of the new value taken by the variable.
324  * @return A reference to *this in order to chain the chgVal.
325  *
326  * @throw NotFound raised if the variable does not belong to this
327  * @throw OutOfBound raised if newVal is not a possible value for
328  * the variable
329  */
330  SetInst& chgVal(Idx varPos, Idx newVal);
331 
332  /**
333  * @brief Assign newVal to variable v in the SetInst.
334  *
335  * @param v The variable whose value is assigned.
336  * @param newVal The index of the value assigned (consider the values of v
337  * as an array indexed from 0 to n of values (which might be anything from
338  * real numbers to strings, etc). Parameter newVal indicates the index in
339  * this array of the new value taken by v.
340  * @return Returns a reference to *this in order to chain the chgVal.
341  *
342  * @throw NotFound Raised if variable v does not belong to the SetInst.
343  * @throw OutOfBound Raised if newVal is not a possible value for v.
344  */
345  SetInst& chgVals(const DiscreteVariable& v, const Size newVal);
346 
347  /**
348  * @brief Add newVal to variable v in the SetInst.
349  *
350  * @param v The variable whose value is assigned.
351  * @param newVal The value added to the index of the value assigned
352  * (consider the values of v as an array indexed from 0 to n of values
353  * (which might be anything from real numbers to strings, etc). Parameter
354  * newVal indicates the index in this array of the new value taken by v.
355  * @return Returns a reference to *this in order to chain the chgVal.
356  *
357  * @throw NotFound Raised if variable v does not belong to the SetInst.
358  * @throw OutOfBound Raised if newVal is not a possible value for v.
359  */
360  SetInst& addVal(const DiscreteVariable& v, Idx newVal);
361 
362  /**
363  * @brief Add newVal to variable v in the SetInst.
364  *
365  * @param v The variable whose value is assigned.
366  * @param newVal The value added to the index of the value assigned
367  * (consider the values of v as an array indexed from 0 to n of values
368  * (which might be anything from real numbers to strings, etc). Parameter
369  * newVal indicates the index in this array of the new value taken by v.
370  * @return Returns a reference to *this in order to chain the chgVal.
371  *
372  * @throw NotFound Raised if variable v does not belong to the SetInst.
373  * @throw OutOfBound Raised if newVal is not a possible value for v.
374  */
375  SetInst& addVals(const DiscreteVariable& v, const Size newVal);
376 
377  /**
378  * @brief Remove newVal from the variable v in the SetInst.
379  *
380  * @param v The variable whose value is assigned.
381  * @param newVal The value removed to the index of the value assigned
382  * (consider the values of v as an array indexed from 0 to n of values
383  * (which might be anything from real numbers to strings, etc). Parameter
384  * newVal indicates the index in this array of the new value taken by v.
385  * @return Returns a reference to *this in order to chain the chgVal.
386  *
387  * @throw NotFound Raised if variable v does not belong to the SetInst.
388  * @throw OutOfBound Raised if newVal is not a possible value for v.
389  */
390  SetInst& remVal(const DiscreteVariable& v, Idx newVal);
391 
392  /**
393  * @brief Remove newVal from the variable v in the SetInst.
394  *
395  * @param v The variable whose value is assigned.
396  * @param newVal The value removed to the index of the value assigned
397  * (consider the values of v as an array indexed from 0 to n of values
398  * (which might be anything from real numbers to strings, etc). Parameter
399  * newVal indicates the index in this array of the new value taken by v.
400  * @return Returns a reference to *this in order to chain the chgVal.
401  *
402  * @throw NotFound Raised if variable v does not belong to the SetInst.
403  * @throw OutOfBound Raised if newVal is not a possible value for v.
404  */
405  SetInst& remVals(const DiscreteVariable& v, const Size newVal);
406 
407  /**
408  * @brief Does an intersection (binary and) between the old value and new
409  * value.
410  *
411  * @param v The variable whose value is assigned.
412  * @param newVal The value intersected with the index of the value assigned
413  * (consider the values of v as an array indexed from 0 to n of values
414  * (which might be anything from real numbers to strings, etc). Parameter
415  * newVal indicates the index in this array of the new value taken by v.
416  * @return Returns a reference to *this in order to chain the chgVal.
417  *
418  * @throw NotFound Raised if variable v does not belong to the SetInst.
419  * @throw OutOfBound Raised if newVal is not a possible value for v.
420  */
421  SetInst& interVals(const DiscreteVariable& v, const Size newVal);
422 
423  /**
424  * @brief Does an intersection (binary and) between the old value and new
425  * value.
426  *
427  * @param v The variable whose value is assigned.
428  * @param newVal The value intersected with the index of the value assigned
429  * (consider the values of v as an array indexed from 0 to n of values
430  * (which might be anything from real numbers to strings, etc). Parameter
431  * newVal indicates the index in this array of the new value taken by v.
432  * @return Returns a reference to *this in order to chain the chgVal.
433  *
434  * @throw NotFound Raised if variable v does not belong to the SetInst.
435  * @throw OutOfBound Raised if newVal is not a possible value for v.
436  */
437  SetInst& interVal(const DiscreteVariable& v, Idx newVal);
438 
439  /**
440  * @brief Assign newVal to variable v in the SetInst.
441  *
442  * @param v The variable whose value is assigned.
443  * @param newVal The index of the value assigned (consider the values of v
444  * as an array indexed from 0 to n of values (which might be anything from
445  * real numbers to strings, etc). Parameter newVal indicates the index in
446  * this array of the new value taken by v.
447  * @return Returns a reference to *this in order to chain the chgVal.
448  *
449  * @throw NotFound Raised if variable v does not belong to the SetInst.
450  * @throw OutOfBound Raised if newVal is not a possible value for v.
451  */
452  SetInst& chgVals(const DiscreteVariable* v, const Size newVal);
453 
454  /**
455  * @brief Add newVal to variable v in the SetInst.
456  *
457  * @param v The variable whose value is assigned.
458  * @param newVal The value added to the index of the value assigned
459  * (consider the values of v as an array indexed from 0 to n of values
460  * (which might be anything from real numbers to strings, etc). Parameter
461  * newVal indicates the index in this array of the new value taken by v.
462  * @return Returns a reference to *this in order to chain the chgVal.
463  *
464  * @throw NotFound Raised if variable v does not belong to the SetInst.
465  * @throw OutOfBound Raised if newVal is not a possible value for v.
466  */
467  SetInst& addVal(const DiscreteVariable* v, Idx newVal);
468 
469  /**
470  * @brief Add newVal to variable v in the SetInst.
471  *
472  * @param v The variable whose value is assigned.
473  * @param newVal The value added to the index of the value assigned
474  * (consider the values of v as an array indexed from 0 to n of values
475  * (which might be anything from real numbers to strings, etc). Parameter
476  * newVal indicates the index in this array of the new value taken by v.
477  * @return Returns a reference to *this in order to chain the chgVal.
478  *
479  * @throw NotFound Raised if variable v does not belong to the SetInst.
480  * @throw OutOfBound Raised if newVal is not a possible value for v.
481  */
482  SetInst& addVals(const DiscreteVariable* v, const Size newVal);
483 
484  /**
485  * @brief Remove newVal from the variable v in the SetInst.
486  *
487  * @param v The variable whose value is assigned.
488  * @param newVal The value removed to the index of the value assigned
489  * (consider the values of v as an array indexed from 0 to n of values
490  * (which might be anything from real numbers to strings, etc). Parameter
491  * newVal indicates the index in this array of the new value taken by v.
492  * @return Returns a reference to *this in order to chain the chgVal.
493  *
494  * @throw NotFound Raised if variable v does not belong to the SetInst.
495  * @throw OutOfBound Raised if newVal is not a possible value for v.
496  */
497  SetInst& remVal(const DiscreteVariable* v, Idx newVal);
498 
499  /**
500  * @brief Remove newVal from the variable v in the SetInst.
501  *
502  * @param v The variable whose value is assigned.
503  * @param newVal The value removed to the index of the value assigned
504  * (consider the values of v as an array indexed from 0 to n of values
505  * (which might be anything from real numbers to strings, etc). Parameter
506  * newVal indicates the index in this array of the new value taken by v.
507  * @return Returns a reference to *this in order to chain the chgVal.
508  *
509  * @throw NotFound Raised if variable v does not belong to the SetInst.
510  * @throw OutOfBound Raised if newVal is not a possible value for v.
511  */
512  SetInst& remVals(const DiscreteVariable* v, const Size newVal);
513 
514  /**
515  * @brief Does an intersection (binary and) between the old value and new
516  * value.
517  *
518  * @param v The variable whose value is assigned.
519  * @param newVal The value intersected with the index of the value assigned
520  * (consider the values of v as an array indexed from 0 to n of values
521  * (which might be anything from real numbers to strings, etc). Parameter
522  * newVal indicates the index in this array of the new value taken by v.
523  * @return Returns a reference to *this in order to chain the chgVal.
524  *
525  * @throw NotFound Raised if variable v does not belong to the SetInst.
526  * @throw OutOfBound Raised if newVal is not a possible value for v.
527  */
528  SetInst& interVals(const DiscreteVariable* v, const Size newVal);
529 
530  /**
531  * @brief Does an intersection (binary and) between the old value and new
532  * value.
533  *
534  * @param v The variable whose value is assigned.
535  * @param newVal The value intersected with the index of the value assigned
536  * (consider the values of v as an array indexed from 0 to n of values
537  * (which might be anything from real numbers to strings, etc). Parameter
538  * newVal indicates the index in this array of the new value taken by v.
539  * @return Returns a reference to *this in order to chain the chgVal.
540  *
541  * @throw NotFound Raised if variable v does not belong to the SetInst.
542  * @throw OutOfBound Raised if newVal is not a possible value for v.
543  */
544  SetInst& interVal(const DiscreteVariable* v, Idx newVal);
545 
546  /**
547  * @brief Assign newVal to variable at position varPos in the SetInst.
548  *
549  * @param varPos The index of the variable whose value is assigned in the
550  * tuple of variables of the SetInst.
551  * @param newVal The index of the value assigned (consider the values of the
552  * variable as an array indexed from 0 to n of values (which might be
553  * anything from real numbers to strings, etc). Parameter newVal
554  * indicates the index in this array of the new value taken by the
555  * variable.
556  * @return A reference to *this in order to chain the chgVal.
557  * @throw NotFound Raised if the variable does not belong to this
558  * @throw OutOfBound Raised if newVal is not a possible value for
559  * the variable
560  */
561  SetInst& chgVals(Idx varPos, const Size newVal);
562 
563  /**
564  * @brief Add newVal to variable v in the SetInst.
565  *
566  * @param varPos The variable whose value is assigned.
567  * @param newVal The value added to the index of the value assigned
568  * (consider the values of varPos as an array indexed from 0 to n of values
569  * (which might be anything from real numbers to strings, etc). Parameter
570  * newVal indicates the index in this array of the new value taken by
571  * varPos.
572  * @return Returns a reference to *this in order to chain the chgVal.
573  *
574  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
575  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
576  */
577  SetInst& addVal(Idx varPos, Idx newVal);
578 
579  /**
580  * @brief Add newVal to variable varPos in the SetInst.
581  *
582  * @param varPos The variable whose value is assigned.
583  * @param newVal The value added to the index of the value assigned
584  * (consider the values of varPos as an array indexed from 0 to n of values
585  * (which might be anything from real numbers to strings, etc). Parameter
586  * newVal indicates the index in this array of the new value taken by
587  * varPos.
588  * @return Returns a reference to *this in order to chain the chgVal.
589  *
590  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
591  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
592  */
593  SetInst& addVals(Idx varPos, const Size newVal);
594 
595  /**
596  * @brief Remove newVal from the variable varPos in the SetInst.
597  *
598  * @param varPos The variable whose value is assigned.
599  * @param newVal The value removed to the index of the value assigned
600  * (consider the values of varPos as an array indexed from 0 to n of values
601  * (which might be anything from real numbers to strings, etc). Parameter
602  * newVal indicates the index in this array of the new value taken by
603  * varPos.
604  * @return Returns a reference to *this in order to chain the chgVal.
605  *
606  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
607  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
608  */
609  SetInst& remVal(Idx varPos, Idx newVal);
610 
611  /**
612  * @brief Remove newVal from the variable varPos in the SetInst.
613  *
614  * @param varPos The variable whose value is assigned.
615  * @param newVal The value removed to the index of the value assigned
616  * (consider the values of varPos as an array indexed from 0 to n of values
617  * (which might be anything from real numbers to strings, etc). Parameter
618  * newVal indicates the index in this array of the new value taken by
619  * varPos.
620  * @return Returns a reference to *this in order to chain the chgVal.
621  *
622  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
623  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
624  */
625  SetInst& remVals(Idx varPos, const Size newVal);
626 
627  /**
628  * @brief Does an intersection (binary and) between the old value and new
629  * value.
630  *
631  * @param varPos The variable whose value is assigned.
632  * @param newVal The value intersected with the index of the value assigned
633  * (consider the values of varPos as an array indexed from 0 to n of values
634  * (which might be anything from real numbers to strings, etc). Parameter
635  * newVal indicates the index in this array of the new value taken by
636  * varPos.
637  * @return Returns a reference to *this in order to chain the chgVal.
638  *
639  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
640  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
641  */
642  SetInst& interVals(Idx varPos, const Size newVal);
643 
644  /**
645  * @brief Does an intersection (binary and) between the old value and new
646  * value.
647  *
648  * @param varPos The variable whose value is assigned.
649  * @param newVal The value intersected with the index of the value assigned
650  * (consider the values of varPos as an array indexed from 0 to n of values
651  * (which might be anything from real numbers to strings, etc). Parameter
652  * newVal indicates the index in this array of the new value taken by
653  * varPos.
654  * @return Returns a reference to *this in order to chain the chgVal.
655  *
656  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
657  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
658  */
659  SetInst& interVal(Idx varPos, Idx newVal);
660 
661  /**
662  * @brief Does the difference (binary or) between the old value and new
663  * value.
664  *
665  * @param varPos The variable whose value is assigned.
666  * @param newVal The value intersected with the index of the value assigned
667  * (consider the values of varPos as an array indexed from 0 to n of values
668  * (which might be anything from real numbers to strings, etc). Parameter
669  * newVal indicates the index in this array of the new value taken by
670  * varPos.
671  * @return Returns a reference to *this in order to chain the chgVal.
672  *
673  * @throw NotFound Raised if variable varPos does not belong to the SetInst.
674  * @throw OutOfBound Raised if newVal is not a possible value for varPos.
675  */
676  SetInst& chgDifVal(Idx varPos, const Size newVal);
677 
678  /**
679  * @brief Change all the values to match does in i.
680  * @param i The new set of value for this SetInst.
681  * @return Returns a reference to *this in order to chain the chgVal.
682  */
683  SetInst& chgValIn(const SetInst& i);
684 
685  /**
686  * Indicates whether a given variable belongs to the SetInst.
687  *
688  * @param v The variable for which the test is made.
689  * @return Returns true if v is in the SetInst.
690  */
691  bool contains(const DiscreteVariable& v) const;
692 
693  /**
694  * Indicates whether a given variable belongs to the SetInst.
695  *
696  * @param v A pointer on the variable for which the test is made.
697  * @return Returns true if *v is in the SetInst.
698  */
699  bool contains(const DiscreteVariable* v) const;
700 
701  /**
702  * @brief Returns the sequence of DiscreteVariable of this SetInst.
703  * @return Returns the sequence of DiscreteVariable of this SetInst.
704  */
705  const Sequence< const DiscreteVariable* >& variablesSequence() const;
706 
707  /**
708  * @brief Returns true if the SetInst is empty.
709  * @return Returns true if the SetInst is empty.
710  */
711  virtual bool empty() const;
712 
713  /**
714  * @brief Give a string version of SetInst.
715  * @return Returns a string version of SetInst.
716  */
717  std::string toString() const;
718 
719  /**
720  * @brief Reorder the variables given v.
721  * @param v The new order of variables in this SetInst.
722  */
723  void reorder(const Sequence< const DiscreteVariable* >& v);
724 
725  /**
726  * @brief Reorder the variables given i.
727  * @param i The new order of variables in this SetInst.
728  */
729  void reorder(const SetInst& i);
730 
731  /// @}
732  // =========================================================================
733  /// @name Overflow management methods.
734  // =========================================================================
735  /// @{
736 
737  /**
738  * @brief Indicates whether the current value of the tuple is correct or
739  * not.
740  *
741  * @code
742  * for(SetInst i.setFirst(); !i.inOverflow(); ++i) {
743  * // code...
744  * }
745  * @endcode
746  */
747  bool inOverflow() const;
748 
749  /**
750  * @brief Removes the flag overflow. See full documentation for details.
751  * (Recommended).
752  *
753  *
754  * @code
755  * // assume the probability has been defined somewhere:
756  * MultiDimArray<double> Prob;
757  *
758  * // create 2 SetInsts for the 2 necessary loops
759  * SetInst i(Prob), j;
760  * j << a << c;
761  * double delta;
762  *
763  * // outer loop: loop over the values of b
764  * for(i.setFirstIn(j); !i.end(); i.incIn(j))
765  * {
766  * delta = 0.0;
767  * // inner loop: loop over the values of a and c
768  * for(i.setFirstOut(j); !i.end(); i.incerr(j))
769  * delta += dd[i];
770  * for(i.setFirstOut(j); !i.end(); i.incerr(j))
771  * dd[i] /= delta;
772  * // indicate that the end() reached after looping over a and c does not
773  * // correspond to an end() for the loop w.r.t. b
774  * i.unsetOverflow();
775  * }
776  * @endcode
777  */
778  void unsetOverflow();
779 
780  /**
781  * @brief Alias for unsetOverflow().
782  * @see unsetOverflow().
783  */
784  void unsetEnd();
785 
786  /**
787  * @brief Returns true if the SetInst reached the end.
788  *
789  * Function end() should be used as in:
790  * @code
791  * for(SetInst i.setFirst();! i.end(); ++i) {
792  * // code
793  * }
794  * @endcode
795  */
796  bool end() const;
797 
798  /**
799  * @brief Returns true if the SetInst reached the rend.
800  *
801  * Function end() should be used as in:
802  * @code
803  * for(SetInst i.setLast();! i.rend(); --i) {
804  * // code
805  * }
806  * @endcode
807  */
808 
809  bool rend() const;
810 
811  /// @}
812  /// @{
813 
814 
815  /// @}
816 
817  // ############################################################################
818  /// @name Static methods
819  // ############################################################################
820  /// @{
821 
822  /**
823  * @brief Assign the values of i in j, using bij as a bijection between i
824  * and j variables.
825  *
826  * @param bij Firsts are variables in i and seconds are variables in j.
827  * @param i An SetInst used to change the values in j.
828  * @param j An SetInst which receives new values from i using bij.
829  *
830  * @throw NotFound raised if a variable in i does not point to a variable
831  * in j or if a variable in i is missing in bij.
832  */
833  static void assign_values(Bijection< const DiscreteVariable*, const DiscreteVariable* >& bij,
834  const SetInst& i,
835  SetInst& j);
836 
837  /// @}
838 
839  protected:
840  virtual void replace_(const DiscreteVariable* x, const DiscreteVariable* y);
841 
842  private:
843  /// The tuple of variables to be instantiated.
844  Sequence< const DiscreteVariable* > _vars_;
845 
846  /// The current SetInst: the value of the tuple.
847  std::vector< Size > _vals_;
848 
849  /// The overflow flag.
850  bool _overflow_;
851 
852  /**
853  * @brief Swap 2 vars in the SetInst.
854  * @param i The first variable to swap.
855  * @param j The second variable to swap.
856  */
857  void _swap_(Idx i, Idx j);
858 
859  /**
860  * @brief Change the value of a variable.
861  * @param varPos The variable index.
862  * @param newVal The new value.
863  */
864  void _chgVal_(Idx varPos, Idx newVal);
865 
866  /**
867  * @brief Change the value of a variable.
868  * @param varPos The variable index.
869  * @param newVal The new value.
870  */
871  void _chgVals_(Idx varPos, const Size newVal);
872 
873  /**
874  * @brief Adds a new var to the sequence of vars.
875  *
876  * If variable v already belongs to the SetInst tuple of variables, then
877  * nothing is done. In particular, no exception is thrown in this case.
878  *
879  * @ warning note that this function does not deassociate the SetInst from
880  * its master MultiDimAdressable, if any. To do so, use function add
881  * instead.
882  *
883  * @warning this function does not notify the master MultiDimAdressable,
884  * if any. Use in addition function chgVal or _chgVal_ if need be.
885  *
886  * @warning variable v is known to the SetInst only by a pointer to it.
887  * As a result, this is not a copy of v that is used by SetInst but rather
888  * v itself. As such, v should never be deleted from memory until the
889  * SetInst is removed.
890  *
891  * @param v The new var.
892  * @throw DuplicateElement Raised if v is already in the SetInst.
893  */
894  void _add_(const DiscreteVariable& v);
895 
896  /**
897  * @brief Removes a variable from the sequence of vars.
898  *
899  * If variable v does not belong to the SetInst tuple of variables, then
900  * nothing is done. In particular, no exception is thrown in this case.
901  *
902  * @warning this function does not notify the master MultiDimAdressable,
903  * if any.
904  *
905  * @warning note that this function does not deassociate the SetInst from
906  * its master MultiDimAdressable, if any. To do so, use function removeDim
907  * instead.
908  *
909  * @param v The variable to remove.
910  */
911  void _erase_(const DiscreteVariable& v);
912 
913  /**
914  * @brief Intialize the SetInst.
915  * @param master The master of this SetInst.
916  */
917  void _init_(MultiDimAdressable* master);
918  };
919 
920  /// Print information of the SetInst in the stream.
921  std::ostream& operator<<(std::ostream&, const SetInst&);
922 
923  /**
924  * @brief Adds a variable to inst.
925  * @param inst The SetInst to which a variable is added.
926  * @param i The variable to add.
927  * @return Returns a reference over inst.
928  * @throw DuplicateElement If i is already in the SetInst.
929  */
930  gum::SetInst& operator<<(gum::SetInst& inst, const gum::DiscreteVariable& i);
931 
932  /**
933  * @brief Removes a variable to inst.
934  * @param inst The SetInst to which a variable is removed.
935  * @param i The variable to remove.
936  * @return Returns a reference over inst.
937  * @throw NotFound Raised if i is not found in inst.
938  */
939  gum::SetInst& operator>>(gum::SetInst& inst, const gum::DiscreteVariable& i);
940 
941 } /* namespace gum */
942 
943 #ifndef GUM_NO_INLINE
944 # include <agrum/tools/multidim/setInst_inl.h>
945 #endif /* GUM_NO_INLINE */
946 
947 #endif /* GUM_SetInst_H */