1 /**
2  *
3  *   Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_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(_at_AMU) and Pierre-Henri WUILLEMIN(_at_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 */
948