aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
PRMClassElementContainer.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 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 >& get(const std::string& name) const = 0;
117 
118  /**
119  * @brief Add a PRMClassElement<GUM_SCALAR> to this
120  *PRMClassElementContainer.
121  *
122  * The pointer is "given" to this class, which will delete it when
123  * ~Class() is called.
124  *
125  * The NodeId of elt is defined when it is added to this, discarding any
126  * previous value.
127  *
128  * If you want to overload an inherited PRMClassElement<GUM_SCALAR> call
129  * Class::overload().
130  *
131  * When adding an PRMAttribute or an PRMAggregate its type safe name is
132  * automatically added, the syntax is <type>name. So you can either use
133  * its type safe name or its real name. See the ref prm_typ_inh "type
134  * inheritance section" for further details.
135  *
136  * @param elt The PRMClassElement<GUM_SCALAR> added to this Class.
137  * @return Returns the NodeId assigned to elt.
138  *
139  * @throw DuplicateElement Raised if elt's name is already used in this
140  *class.
141  */
142  virtual NodeId add(PRMClassElement< GUM_SCALAR >* elt) = 0;
143 
144  /**
145  * @brief Add a PRMClassElement<GUM_SCALAR> which overload an inherited
146  *PRMClassElement<GUM_SCALAR>.
147  *
148  * The pointer is "given" to this class, which will delete it when
149  * ~PRMClassElementContainer() is called.
150  *
151  * The NodeId of elt is defined when it is added to this, discarding any
152  * previous value. There is no guaranty that elt will have the same NodeId
153  * than the PRMClassElement<GUM_SCALAR> it overloaded.
154  *
155  * You can only overload inherited PRMClassElement<GUM_SCALAR> and only if
156  *elt is
157  * a subtype of the inherited PRMClassElement<GUM_SCALAR>. Thus you can
158  *only
159  * overload PRMReferenceSlot and PRMAttribute. In the case of PRMAttribute
160  *you can
161  * overload an inherited PRMAttribute even if they are of the same type:
162  *this
163  *is
164  * useful when you want to redefine the dependencies of an PRMAttribute or
165  *its
166  * CPF. You can also overload an PRMAttribute with an PRMAggregate, as
167  *long as
168  *their
169  * respective PRMType allow it.
170  *
171  * @param elt The PRMClassElement<GUM_SCALAR> overloading an inherited
172  * PRMClassElement<GUM_SCALAR> in this
173  *PRMClassElementContainer.
174  * @return the NodeId assigned to elt.
175  *
176  * @throw OperationNotAllowed Raised if overloading is illegal.
177  */
178  virtual NodeId overload(PRMClassElement< GUM_SCALAR >* elt) = 0;
179 
180  /**
181  * Add an arc between two PRMClassElement<GUM_SCALAR>.
182  */
183  virtual void addArc(const std::string& tail, const std::string& head) = 0;
184 
185  /**
186  * @brief Returns true if the node is an input node.
187  *
188  * PRMAttribute or PRMAggregate can either be input, output, both
189  * or internal nodes.
190  *
191  * By defaut, attributes and aggregates are inner nodes.
192  *
193  * @param elt A PRMClassElement<GUM_SCALAR>.
194  * @return Returns true if id is an input node.
195  */
196  virtual bool isInputNode(const PRMClassElement< GUM_SCALAR >& elt) const;
197 
198  /**
199  * @brief Set the input flag value of id at b.
200  *
201  * PRMAttribute or PRMAggregate can either be input, output, both
202  * or internal nodes.
203  *
204  * By defaut, attributes and aggregates are inner nodes.
205  *
206  * @param elt A PRMClassElement<GUM_SCALAR>.
207  * @param b The flag value.
208  *
209  * @throw NotFound Raised if id does'nt match any
210  *PRMClassElement<GUM_SCALAR>
211  *in
212  *this.
213  * @throw WrongClassElement Raised if NodeId is neither an PRMAttribute
214  *nor
215  * an PRMAggregate.
216  */
217  virtual void setInputNode(const PRMClassElement< GUM_SCALAR >& elt, bool b);
218 
219  /**
220  * @brief Returns true if the node is an output node.
221  *
222  * PRMAttribute or PRMAggregate can either be input, output, both
223  * or internal nodes.
224  *
225  * By defaut, attributes and aggregates are inner nodes.
226  *
227  * @param elt A PRMClassElement<GUM_SCALAR>.
228  * @return Returns true if id is an input node.
229  */
230  virtual bool isOutputNode(const PRMClassElement< GUM_SCALAR >& elt) const = 0;
231 
232  /**
233  * @brief Set the output flag value of id at b.
234  *
235  * PRMAttribute or PRMAggregate can either be input, output, both
236  * or internal nodes.
237  *
238  * By defaut, attributes and aggregates are inner nodes.
239  *
240  * @param elt A PRMClassElement<GUM_SCALAR>.
241  * @param b The flag value.
242  *
243  * @throw NotFound Raised if id does'nt match any
244  *PRMClassElement<GUM_SCALAR>
245  *in
246  *this.
247  * @throw WrongClassElement Raised if NodeId is neither an PRMAttribute
248  *nor
249  * an PRMAggregate.
250  */
251  virtual void setOutputNode(const PRMClassElement< GUM_SCALAR >& elt, bool b);
252 
253  /**
254  * @brief Returns true if the node is an inner node.
255  *
256  * PRMAttribute or PRMAggregate can either be input, output, both
257  * or internal nodes.
258  *
259  * By defaut, attributes and aggregates are inner nodes.
260  *
261  * @param elt A PRMClassElement<GUM_SCALAR>.
262  * @return true if elt is an inner node.
263  *
264  * @throw NotFound Raised if NodeId does'nt match any
265  *PRMClassElement<GUM_SCALAR>
266  *in this.
267  * @throw WrongClassElement Raised if NodeId is neither an PRMAttribute
268  *nor
269  * an PRMAggregate.
270  */
271  virtual bool isInnerNode(const PRMClassElement< GUM_SCALAR >& elt) const;
272  /// @}
273  // ========================================================================
274  /// @name Graphical operator
275  // ========================================================================
276  /// @{
277 
278  /**
279  * @brief Returns the gum::DAG of this PRMClassElementContainer.
280  *
281  * Be very careful when using NodeId with PRMClassElement<GUM_SCALAR>:
282  * there is no guarantee that an inherited PRMClassElement<GUM_SCALAR> will
283  * have the same NodeId than its superclass counterpart.
284  *
285  * When dealing with different classes and interfaces ALWAYS use safe-name
286  * as identifier.
287  *
288  * @return the DAG of this PRMClassElementContainer.
289  */
290  virtual const DAG& containerDag() const;
291 
292  /**
293  * Returns true if a member with the given id exists in this
294  * PRMClassElementContainer or
295  * in the PRMClassElementContainer hierarchy.
296  * @param id A NodeId.
297  * @return true if id matches a PRMClassElement<GUM_SCALAR>.
298  */
299  virtual bool exists(NodeId id) const;
300 
301  /**
302  * Getter on a member of this PRMClassElementContainer.
303  * @param id The member's id.
304  * @return Returns a constant reference on the member.
305  * @throw NotFound Raised if no attribute matches name.
306  */
307  virtual PRMClassElement< GUM_SCALAR >& get(NodeId id) = 0;
308 
309  /**
310  * Constant getter on a member of this PRMClassElementContainer.
311  * @param id The member's id.
312  * @return Returns a constant reference on the member.
313  * @throw NotFound Raised if no attribute matches name.
314  */
315  virtual const PRMClassElement< GUM_SCALAR >& get(NodeId id) const = 0;
316 
317  /// @}
318  // ========================================================================
319  /// @name Getters & setters operators
320  // ========================================================================
321  /// @{
322 
323  /**
324  * Getter on a member of this PRMClassElementContainer.
325  * @param id The member's id.
326  * @return Returns a constant reference on the member.
327  * @throw NotFound Raised if no attribute matches name.
328  */
329  virtual PRMClassElement< GUM_SCALAR >& operator[](NodeId id) = 0;
330 
331  /**
332  * Constant getter on a member of this PRMClassElementContainer.
333  * @param id The member's id.
334  * @return Returns a constant reference on the member.
335  * @throw NotFound Raised if no attribute matches name.
336  */
337  virtual const PRMClassElement< GUM_SCALAR >& operator[](NodeId id) const = 0;
338 
339  /**
340  * Getter on a member of this PRMClassElementContainer.
341  * @param name The member's name.
342  * @return Returns a constant reference on the member.
343  * @throw NotFound Raised if no attribute matches name.
344  */
345  virtual PRMClassElement< GUM_SCALAR >& operator[](const std::string& name) = 0;
346 
347  /**
348  * Constant getter on a member of this PRMClassElementContainer.
349  * @param name The member's name.
350  * @return Returns a constant reference on the member.
351  * @throw NotFound Raised if no attribute matches name.
352  */
353  virtual const PRMClassElement< GUM_SCALAR >& operator[](const std::string& name) const = 0;
354 
355  /// @}
356  // ========================================================================
357  /// @name Inheritance getters and setters
358  // ========================================================================
359  /// @{
360 
361  /**
362  * @brief Test if this PRMClassElementContainer is a subtype of cec.
363  *
364  * @param cec
365  * @return return true if this PRMClassElementContainer is a subtype of
366  * cec.
367  */
368  virtual bool isSubTypeOf(const PRMClassElementContainer< GUM_SCALAR >& cec) const = 0;
369 
370  /**
371  * @brief Test if this PRMClassElementContainer is a super type of cec.
372  *
373  * This returns cec.isSubTypeOf(*this).
374  *
375  * @param cec
376  * @return return true if this PRMClassElementContainer is a super type of
377  *cec.
378  */
379  virtual bool isSuperTypeOf(const PRMClassElementContainer< GUM_SCALAR >& cec) const;
380 
381  /// @}
382 
383  protected:
384  /// Copy operator. Don't use it.
385  PRMClassElementContainer< GUM_SCALAR >&
386  operator=(const PRMClassElementContainer< GUM_SCALAR >& source);
387 
388  /// Copy constructor. Don't use it.
389  PRMClassElementContainer(const PRMClassElementContainer< GUM_SCALAR >& source);
390 
391  virtual const DAG& dag_() const = 0;
392 
393  /// Returns a non constant reference over this PRMClassElementContainer's
394  /// DAG.
395  virtual DAG& dag_() = 0;
396 
397  /// Fills set with all the subtypes of this PRMInterface, this includes
398  /// extensions
399  /// and implementations.
400  virtual void findAllSubtypes_(Set< PRMClassElementContainer< GUM_SCALAR >* >& set) = 0;
401 
402  /// Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
403  /// @param elt The PRMClassElement<GUM_SCALAR>.
404  /// @return elt's IO flags.
405  /// @throw NotFound Raised if elt does not have any IO flags.
406  virtual std::pair< bool, bool >& getIOFlag_(const PRMClassElement< GUM_SCALAR >& elt);
407 
408  /// Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
409  /// @param elt The PRMClassElement<GUM_SCALAR>.
410  /// @return elt's IO flags.
411  /// @throw NotFound Raised if elt does not have any IO flags.
412  virtual const std::pair< bool, bool >&
413  getIOFlag_(const PRMClassElement< GUM_SCALAR >& elt) const;
414 
415  /// Defines the IO flags of a PRMClassElement<GUM_SCALAR>.
416  /// @param elt The PRMClassElement<GUM_SCALAR>.
417  /// @param flags The IO flags of elt. Overwrite any existing flags.
418  /// @return elt's IO flags.
419  /// @throw NotFound Raised if elt does not have any IO flags.
420  virtual void setIOFlag_(const PRMClassElement< GUM_SCALAR >& elt,
421  const std::pair< bool, bool >& flags);
422 
423  /// Copy the IO Flags of c in this PRMClassElementContainer.
424  /// @param c A PRMClassElementContainer.
425  virtual void copyIOFlags_(const PRMClassElementContainer< GUM_SCALAR >& c);
426 
427  /// When a PRMClassElement<GUM_SCALAR> becomes an Output node we must
428  /// update
429  /// any the IO flags of every descendant of this PRMClassElementContainer.
430  /// Note that after its declaration, input flags can not be changed and
431  /// output flags can only become true.
432  ///
433  /// @param elt A PRMClassElement<GUM_SCALAR>.
434  virtual void updateDescendants_(const PRMClassElement< GUM_SCALAR >& elt) = 0;
435 
436  private:
437  /// input / output flags, useful when inheriting or copying.
438  HashTable< std::string, std::pair< bool, bool > > _IOFlags_;
439  };
440 
441 
442 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
443  extern template class PRMClassElementContainer< double >;
444 #endif
445 
446 
447  } /* namespace prm */
448 
449 } // namespace gum
450 
451 /// @brief An << operator for PRMClassElementContainer.
452 /// Output in the graphviz-dot format.
453 template < typename GUM_SCALAR >
456 
457 #include <agrum/PRM/elements/PRMClassElementContainer_tpl.h>
458 
459 #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.
HashTable< std::string, std::pair< bool, bool > > _IOFlags_
input / output flags, useful when inheriting or copying.
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:643
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>.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.