aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
PRMClassElementContainer.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 Headers of gum::prm::PRMClassElementContainer.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef GUM_CLASS_ELEMENT_CONTAINER_H
30 #define GUM_CLASS_ELEMENT_CONTAINER_H
31 
32 #include <agrum/tools/core/hashTable.h>
33 #include <agrum/tools/core/set.h>
34 
35 #include <agrum/tools/graphs/DAG.h>
36 #include <agrum/tools/graphs/graphElements.h>
37 
38 #include <agrum/PRM/utils_prm.h>
39 
40 #include <agrum/PRM/elements/PRMObject.h>
41 
42 namespace gum {
43  namespace prm {
44 
45  template < typename GUM_SCALAR >
46  class PRMClass;
47  template < typename GUM_SCALAR >
48  class PRMInterface;
49  class PRMClassElementContainterIterator;
50  class PRMClassElementContainterConstIterator;
51 
52  /**
53  * @class PRMClassElementContainer classElementContainer.h
54  *<agrum/PRM/classElementContainer.h>
55  * @brief Abstract class for classes containing
56  *gum::PRMClassElement<GUM_SCALAR>.
57  *
58  * To print a PRMClassElementContainer you can use the following operator:
59  * gum::operator<<(std::ostream&, const PRMClassElementContainer&) which
60  *print
61  * the PRMClassElementContainer in the graphviz-dot format.
62  *
63  * @ingroup prm_group
64  */
65  template < typename GUM_SCALAR >
67  friend class PRMClassElementContainterIterator;
68  friend class PRMClassElementContainterConstIterator;
69 
70  public:
71  // ========================================================================
72  /// @name Protected constructors & destructor.
73  // ========================================================================
74  /// @{
75 
76  /// Default constructor.
77  PRMClassElementContainer(const std::string& name);
78 
79  /// Destructor.
80  virtual ~PRMClassElementContainer();
81 
82  /// @}
83  // ========================================================================
84  /// @name Getters on the gum::PRMClassElement<GUM_SCALAR>.
85  // ========================================================================
86  /// @{
87 
88  /**
89  * Returns true if elt belongs to this PRMClassElementContainer.
90  * @param elt A PRMClassElement<GUM_SCALAR>.
91  * @return true if elt beglons to this PRMClassElementContainer.
92  */
93  virtual bool belongsTo(const PRMClassElement< GUM_SCALAR >& elt) const;
94 
95  /**
96  * Returns true if a member with the given name exists in this
97  * PRMClassElementContainer or
98  * in the PRMClassElementContainer hierarchy.
99  */
100  virtual bool exists(const std::string& name) const;
101 
102  /**
103  * Getter on a member of this PRMClassElementContainer.
104  * @param name The member's name.
105  * @return Returns a constant reference on the member.
106  * @throw NotFound Raised if no attribute matches name.
107  */
108  virtual PRMClassElement< GUM_SCALAR >& get(const std::string& name) = 0;
109 
110  /**
111  * Constant getter on a member of this PRMClassElementContainer.
112  * @param name The member's name.
113  * @return Returns a constant reference on the member.
114  * @throw NotFound Raised if no attribute matches name.
115  */
116  virtual const PRMClassElement< GUM_SCALAR >&
117  get(const std::string& name) const = 0;
118 
119  /**
120  * @brief Add a PRMClassElement<GUM_SCALAR> to this
121  *PRMClassElementContainer.
122  *
123  * The pointer is "given" to this class, which will delete it when
124  * ~Class() is called.
125  *
126  * The NodeId of elt is defined when it is added to this, discarding any
127  * previous value.
128  *
129  * If you want to overload an inherited PRMClassElement<GUM_SCALAR> call
130  * Class::overload().
131  *
132  * When adding an PRMAttribute or an PRMAggregate its type safe name is
133  * automatically added, the syntax is <type>name. So you can either use
134  * its type safe name or its real name. See the ref prm_typ_inh "type
135  * inheritance section" for further details.
136  *
137  * @param elt The PRMClassElement<GUM_SCALAR> added to this Class.
138  * @return Returns the NodeId assigned to elt.
139  *
140  * @throw DuplicateElement Raised if elt's name is already used in this
141  *class.
142  */
143  virtual NodeId add(PRMClassElement< GUM_SCALAR >* elt) = 0;
144 
145  /**
146  * @brief Add a PRMClassElement<GUM_SCALAR> which overload an inherited
147  *PRMClassElement<GUM_SCALAR>.
148  *
149  * The pointer is "given" to this class, which will delete it when
150  * ~PRMClassElementContainer() is called.
151  *
152  * The NodeId of elt is defined when it is added to this, discarding any
153  * previous value. There is no guaranty that elt will have the same NodeId
154  * than the PRMClassElement<GUM_SCALAR> it overloaded.
155  *
156  * You can only overload inherited PRMClassElement<GUM_SCALAR> and only if
157  *elt is
158  * a subtype of the inherited PRMClassElement<GUM_SCALAR>. Thus you can
159  *only
160  * overload PRMReferenceSlot and PRMAttribute. In the case of PRMAttribute
161  *you can
162  * overload an inherited PRMAttribute even if they are of the same type:
163  *this
164  *is
165  * useful when you want to redefine the dependencies of an PRMAttribute or
166  *its
167  * CPF. You can also overload an PRMAttribute with an PRMAggregate, as
168  *long as
169  *their
170  * respective PRMType allow it.
171  *
172  * @param elt The PRMClassElement<GUM_SCALAR> overloading an inherited
173  * PRMClassElement<GUM_SCALAR> in this
174  *PRMClassElementContainer.
175  * @return the NodeId assigned to elt.
176  *
177  * @throw OperationNotAllowed Raised if overloading is illegal.
178  */
179  virtual NodeId overload(PRMClassElement< GUM_SCALAR >* elt) = 0;
180 
181  /**
182  * Add an arc between two PRMClassElement<GUM_SCALAR>.
183  */
184  virtual void addArc(const std::string& tail, const std::string& head) = 0;
185 
186  /**
187  * @brief Returns true if the node is an input node.
188  *
189  * PRMAttribute or PRMAggregate can either be input, output, both
190  * or internal nodes.
191  *
192  * By defaut, attributes and aggregates are inner nodes.
193  *
194  * @param elt A PRMClassElement<GUM_SCALAR>.
195  * @return Returns true if id is an input node.
196  */
197  virtual bool isInputNode(const PRMClassElement< GUM_SCALAR >& elt) const;
198 
199  /**
200  * @brief Set the input flag value of id at b.
201  *
202  * PRMAttribute or PRMAggregate can either be input, output, both
203  * or internal nodes.
204  *
205  * By defaut, attributes and aggregates are inner nodes.
206  *
207  * @param elt A PRMClassElement<GUM_SCALAR>.
208  * @param b The flag value.
209  *
210  * @throw NotFound Raised if id does'nt match any
211  *PRMClassElement<GUM_SCALAR>
212  *in
213  *this.
214  * @throw WrongClassElement Raised if NodeId is neither an PRMAttribute
215  *nor
216  * an PRMAggregate.
217  */
218  virtual void setInputNode(const PRMClassElement< GUM_SCALAR >& elt, bool b);
219 
220  /**
221  * @brief Returns true if the node is an output node.
222  *
223  * PRMAttribute or PRMAggregate can either be input, output, both
224  * or internal nodes.
225  *
226  * By defaut, attributes and aggregates are inner nodes.
227  *
228  * @param elt A PRMClassElement<GUM_SCALAR>.
229  * @return Returns true if id is an input node.
230  */
231  virtual bool
232  isOutputNode(const PRMClassElement< GUM_SCALAR >& elt) const = 0;
233 
234  /**
235  * @brief Set the output flag value of id at b.
236  *
237  * PRMAttribute or PRMAggregate can either be input, output, both
238  * or internal nodes.
239  *
240  * By defaut, attributes and aggregates are inner nodes.
241  *
242  * @param elt A PRMClassElement<GUM_SCALAR>.
243  * @param b The flag value.
244  *
245  * @throw NotFound Raised if id does'nt match any
246  *PRMClassElement<GUM_SCALAR>
247  *in
248  *this.
249  * @throw WrongClassElement Raised if NodeId is neither an PRMAttribute
250  *nor
251  * an PRMAggregate.
252  */
253  virtual void setOutputNode(const PRMClassElement< GUM_SCALAR >& elt, bool b);
254 
255  /**
256  * @brief Returns true if the node is an inner node.
257  *
258  * PRMAttribute or PRMAggregate can either be input, output, both
259  * or internal nodes.
260  *
261  * By defaut, attributes and aggregates are inner nodes.
262  *
263  * @param elt A PRMClassElement<GUM_SCALAR>.
264  * @return true if elt is an inner node.
265  *
266  * @throw NotFound Raised if NodeId does'nt match any
267  *PRMClassElement<GUM_SCALAR>
268  *in this.
269  * @throw WrongClassElement Raised if NodeId is neither an PRMAttribute
270  *nor
271  * an PRMAggregate.
272  */
273  virtual bool isInnerNode(const PRMClassElement< GUM_SCALAR >& elt) const;
274  /// @}
275  // ========================================================================
276  /// @name Graphical operator
277  // ========================================================================
278  /// @{
279 
280  /**
281  * @brief Returns the gum::DAG of this PRMClassElementContainer.
282  *
283  * Be very careful when using NodeId with PRMClassElement<GUM_SCALAR>:
284  * there is no guarantee that an inherited PRMClassElement<GUM_SCALAR> will
285  * have the same NodeId than its superclass counterpart.
286  *
287  * When dealing with different classes and interfaces ALWAYS use safe-name
288  * as identifier.
289  *
290  * @return the DAG of this PRMClassElementContainer.
291  */
292  virtual const DAG& containerDag() const;
293 
294  /**
295  * Returns true if a member with the given id exists in this
296  * PRMClassElementContainer or
297  * in the PRMClassElementContainer hierarchy.
298  * @param id A NodeId.
299  * @return true if id matches a PRMClassElement<GUM_SCALAR>.
300  */
301  virtual bool exists(NodeId id) const;
302 
303  /**
304  * Getter on a member of this PRMClassElementContainer.
305  * @param id The member's id.
306  * @return Returns a constant reference on the member.
307  * @throw NotFound Raised if no attribute matches name.
308  */
309  virtual PRMClassElement< GUM_SCALAR >& get(NodeId id) = 0;
310 
311  /**
312  * Constant getter on a member of this PRMClassElementContainer.
313  * @param id The member's id.
314  * @return Returns a constant reference on the member.
315  * @throw NotFound Raised if no attribute matches name.
316  */
317  virtual const PRMClassElement< GUM_SCALAR >& get(NodeId id) const = 0;
318 
319  /// @}
320  // ========================================================================
321  /// @name Getters & setters operators
322  // ========================================================================
323  /// @{
324 
325  /**
326  * Getter on a member of this PRMClassElementContainer.
327  * @param id The member's id.
328  * @return Returns a constant reference on the member.
329  * @throw NotFound Raised if no attribute matches name.
330  */
331  virtual PRMClassElement< GUM_SCALAR >& operator[](NodeId id) = 0;
332 
333  /**
334  * Constant getter on a member of this PRMClassElementContainer.
335  * @param id The member's id.
336  * @return Returns a constant reference on the member.
337  * @throw NotFound Raised if no attribute matches name.
338  */
339  virtual const PRMClassElement< GUM_SCALAR >& operator[](NodeId id) const = 0;
340 
341  /**
342  * Getter on a member of this PRMClassElementContainer.
343  * @param name The member's name.
344  * @return Returns a constant reference on the member.
345  * @throw NotFound Raised if no attribute matches name.
346  */
347  virtual PRMClassElement< GUM_SCALAR >& operator[](const std::string& name)
348  = 0;
349 
350  /**
351  * Constant getter on a member of this PRMClassElementContainer.
352  * @param name The member's name.
353  * @return Returns a constant reference on the member.
354  * @throw NotFound Raised if no attribute matches name.
355  */
356  virtual const PRMClassElement< GUM_SCALAR >&
357  operator[](const std::string& name) const = 0;
358 
359  /// @}
360  // ========================================================================
361  /// @name Inheritance getters and setters
362  // ========================================================================
363  /// @{
364 
365  /**
366  * @brief Test if this PRMClassElementContainer is a subtype of cec.
367  *
368  * @param cec
369  * @return return true if this PRMClassElementContainer is a subtype of
370  * cec.
371  */
372  virtual bool
373  isSubTypeOf(const PRMClassElementContainer< GUM_SCALAR >& cec) const = 0;
374 
375  /**
376  * @brief Test if this PRMClassElementContainer is a super type of cec.
377  *
378  * This returns cec.isSubTypeOf(*this).
379  *
380  * @param cec
381  * @return return true if this PRMClassElementContainer is a super type of
382  *cec.
383  */
384  virtual bool
385  isSuperTypeOf(const PRMClassElementContainer< GUM_SCALAR >& cec) const;
386 
387  /// @}
388 
389  protected:
390  /// Copy operator. Don't use it.
391  PRMClassElementContainer< GUM_SCALAR >&
392  operator=(const PRMClassElementContainer< GUM_SCALAR >& source);
393 
394  /// Copy constructor. Don't use it.
396  const PRMClassElementContainer< GUM_SCALAR >& source);
397 
398  virtual const DAG& dag_() const = 0;
399 
400  /// Returns a non constant reference over this PRMClassElementContainer's
401  /// DAG.
402  virtual DAG& dag_() = 0;
403 
404  /// Fills set with all the subtypes of this PRMInterface, this includes
405  /// extensions
406  /// and implementations.
407  virtual void
408  findAllSubtypes_(Set< PRMClassElementContainer< GUM_SCALAR >* >& set)
409  = 0;
410 
411  /// Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
412  /// @param elt The PRMClassElement<GUM_SCALAR>.
413  /// @return elt's IO flags.
414  /// @throw NotFound Raised if elt does not have any IO flags.
415  virtual std::pair< bool, bool >&
417 
418  /// Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
419  /// @param elt The PRMClassElement<GUM_SCALAR>.
420  /// @return elt's IO flags.
421  /// @throw NotFound Raised if elt does not have any IO flags.
422  virtual const std::pair< bool, bool >&
423  getIOFlag_(const PRMClassElement< GUM_SCALAR >& elt) const;
424 
425  /// Defines the IO flags of a PRMClassElement<GUM_SCALAR>.
426  /// @param elt The PRMClassElement<GUM_SCALAR>.
427  /// @param flags The IO flags of elt. Overwrite any existing flags.
428  /// @return elt's IO flags.
429  /// @throw NotFound Raised if elt does not have any IO flags.
430  virtual void setIOFlag_(const PRMClassElement< GUM_SCALAR >& elt,
431  const std::pair< bool, bool >& flags);
432 
433  /// Copy the IO Flags of c in this PRMClassElementContainer.
434  /// @param c A PRMClassElementContainer.
435  virtual void copyIOFlags_(const PRMClassElementContainer< GUM_SCALAR >& c);
436 
437  /// When a PRMClassElement<GUM_SCALAR> becomes an Output node we must
438  /// update
439  /// any the IO flags of every descendant of this PRMClassElementContainer.
440  /// Note that after its declaration, input flags can not be changed and
441  /// output flags can only become true.
442  ///
443  /// @param elt A PRMClassElement<GUM_SCALAR>.
444  virtual void updateDescendants_(const PRMClassElement< GUM_SCALAR >& elt)
445  = 0;
446 
447  private:
448  /// input / output flags, useful when inheriting or copying.
449  HashTable< std::string, std::pair< bool, bool > > IOFlags__;
450  };
451 
452 
453 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
454  extern template class PRMClassElementContainer< double >;
455 #endif
456 
457 
458  } /* namespace prm */
459 
460 } // namespace gum
461 
462 /// @brief An << operator for PRMClassElementContainer.
463 /// Output in the graphviz-dot format.
464 template < typename GUM_SCALAR >
465 std::ostream&
468 
469 #include <agrum/PRM/elements/PRMClassElementContainer_tpl.h>
470 
471 #endif /* GUM_CLASS_ELEMENT_CONTAINER_H */
virtual void updateDescendants_(const PRMClassElement< GUM_SCALAR > &elt)=0
When a PRMClassElement<GUM_SCALAR> becomes an Output node we must update any the IO flags of every de...
PRMClassElementContainer< GUM_SCALAR > & operator=(const PRMClassElementContainer< GUM_SCALAR > &source)
Copy operator. Don&#39;t use it.
PRMClassElementContainer(const PRMClassElementContainer< GUM_SCALAR > &source)
Copy constructor. Don&#39;t use it.
PRMClassElementContainer(const std::string &name)
Default constructor.
virtual const PRMClassElement< GUM_SCALAR > & get(const std::string &name) const =0
Constant getter on a member of this PRMClassElementContainer.
virtual std::pair< bool, bool > & getIOFlag_(const PRMClassElement< GUM_SCALAR > &elt)
Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
virtual PRMClassElement< GUM_SCALAR > & operator[](NodeId id)=0
Getter on a member of this PRMClassElementContainer.
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
const Set< PRMSlotChain< GUM_SCALAR > *> & slotChains() const
Returns the set of PRMSlotChain<GUM_SCALAR> of this Class<GUM_SCALAR>.
virtual bool isInnerNode(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if the node is an inner node.
virtual void setInputNode(const PRMClassElement< GUM_SCALAR > &elt, bool b)
Set the input flag value of id at b.
virtual PRMClassElement< GUM_SCALAR > & operator[](const std::string &name)=0
Getter on a member of this PRMClassElementContainer.
virtual PRMClassElement< GUM_SCALAR > & get(const std::string &name)=0
Getter on a member of this PRMClassElementContainer.
virtual bool exists(const std::string &name) const
Returns true if a member with the given name exists in this PRMClassElementContainer or in the PRMCla...
virtual DAG & dag_()=0
Returns a non constant reference over this PRMClassElementContainer&#39;s DAG.
virtual bool isSubTypeOf(const PRMClassElementContainer< GUM_SCALAR > &cec) const =0
Test if this PRMClassElementContainer is a subtype of cec.
virtual const DAG & dag_() const =0
virtual const PRMClassElement< GUM_SCALAR > & operator[](NodeId id) const =0
Constant getter on a member of this PRMClassElementContainer.
virtual void findAllSubtypes_(Set< PRMClassElementContainer< GUM_SCALAR > * > &set)=0
Fills set with all the subtypes of this PRMInterface, this includes extensions and implementations...
std::ostream & operator<<(std::ostream &output, const gum::prm::PRMClassElementContainer< GUM_SCALAR > &container)
An << operator for PRMClassElementContainer. Output in the graphviz-dot format.
virtual const PRMClassElement< GUM_SCALAR > & get(NodeId id) const =0
Constant getter on a member of this PRMClassElementContainer.
virtual PRMClassElement< GUM_SCALAR > & get(NodeId id)=0
Getter on a member of this PRMClassElementContainer.
virtual bool belongsTo(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if elt belongs to this PRMClassElementContainer.
virtual void setIOFlag_(const PRMClassElement< GUM_SCALAR > &elt, const std::pair< bool, bool > &flags)
Defines the IO flags of a PRMClassElement<GUM_SCALAR>.
virtual bool exists(NodeId id) const
Returns true if a member with the given id exists in this PRMClassElementContainer or in the PRMClass...
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
virtual bool isInputNode(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if the node is an input node.
const Set< PRMReferenceSlot< GUM_SCALAR > *> & referenceSlots() const
Returns the set of PRMAggregate of this Class<GUM_SCALAR>.
virtual const PRMClassElement< GUM_SCALAR > & operator[](const std::string &name) const =0
Constant getter on a member of this PRMClassElementContainer.
virtual bool isOutputNode(const PRMClassElement< GUM_SCALAR > &elt) const =0
Returns true if the node is an output node.
virtual void copyIOFlags_(const PRMClassElementContainer< GUM_SCALAR > &c)
Copy the IO Flags of c in this PRMClassElementContainer.
virtual bool isSuperTypeOf(const PRMClassElementContainer< GUM_SCALAR > &cec) const
Test if this PRMClassElementContainer is a super type of cec.
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)=0
Add a PRMClassElement<GUM_SCALAR> to this PRMClassElementContainer.
virtual NodeId overload(PRMClassElement< GUM_SCALAR > *elt)=0
Add a PRMClassElement<GUM_SCALAR> which overload an inherited PRMClassElement<GUM_SCALAR>.
virtual void setOutputNode(const PRMClassElement< GUM_SCALAR > &elt, bool b)
Set the output flag value of id at b.
virtual const std::pair< bool, bool > & getIOFlag_(const PRMClassElement< GUM_SCALAR > &elt) const
Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
virtual void addArc(const std::string &tail, const std::string &head)=0
Add an arc between two PRMClassElement<GUM_SCALAR>.
HashTable< std::string, std::pair< bool, bool > > IOFlags__
input / output flags, useful when inheriting or copying.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.