aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
PRMClassElement.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::PRMClassElement.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef GUM_CLASS_ELEMENT_H
30 #define GUM_CLASS_ELEMENT_H
31 
32 #include <sstream>
33 
34 #include <agrum/agrum.h>
35 
36 #include <agrum/tools/graphs/graphElements.h>
37 
38 #include <agrum/tools/multidim/potential.h>
39 
40 #include <agrum/PRM/elements/PRMObject.h>
41 #include <agrum/PRM/utils_prm.h>
42 
43 namespace gum {
44  namespace prm {
45  template < typename GUM_SCALAR >
46  class PRMAttribute;
47 
48  /**
49  * @class PRMClassElement
50  * @headerfile classElement.h <agrum/PRM/classElement.h>
51  * @brief Abstract class representing an element of PRM class.
52  *
53  * All class elements are nodes in the class's DAG and a unique name in
54  *their
55  * class.
56  *
57  * @ingroup prm_group
58  */
59  template < typename GUM_SCALAR >
60  class PRMClassElement: public PRMObject {
61  public:
62  // ========================================================================
63  /// @name Constructor & Destructor.
64  // ========================================================================
65  /// @{
66 
67  /**
68  * @brief Default constructor of a PRMClassElement.
69  *
70  * The PRMClassElement will automatically add itself to c.
71  *
72  * @param name The name of this element, must be unique in it's class.
73  * @throw DupplicateElement Raised if c contains already an element with
74  * the same name.
75  */
76  explicit PRMClassElement(const std::string& name);
77 
78  /**
79  * Copy constructor.
80  */
81  PRMClassElement(const PRMClassElement< GUM_SCALAR >& source);
82 
83  /**
84  * Destructor of this class.
85  */
86  virtual ~PRMClassElement();
87 
88  /// @}
89  // ========================================================================
90  /// @name Built-in type
91  // ========================================================================
92  /// @{
93 
94  enum ClassElementType
95  {
96  prm_attribute,
97  prm_aggregate,
98  prm_refslot,
99  prm_slotchain,
100  prm_parameter
101  };
102 
103  static std::string enum2str(ClassElementType type) {
104  switch (type) {
105  case prm_attribute:
106  return "prm_attribute";
107 
108  case prm_aggregate:
109  return "prm_aggregate";
110 
111  case prm_refslot:
112  return "prm_refslot";
113 
114  case prm_slotchain:
115  return "prm_slotchain";
116 
117  case prm_parameter:
118  return "prm_parameter";
119 
120  default:
121  return "unknown";
122  }
123  }
124 
125  /// Returns true if obj_ptr is of type PRMReferenceSlot.
126  static INLINE bool isReferenceSlot(const PRMClassElement< GUM_SCALAR >& elt) {
127  return elt.elt_type() == prm_refslot;
128  }
129 
130  /// Returns true if obj_ptr is of type PRMAttribute.
131  static INLINE bool isAttribute(const PRMClassElement< GUM_SCALAR >& elt) {
132  return elt.elt_type() == prm_attribute;
133  }
134 
135  /// Return true if obj is of type PRMAggregate
136  static INLINE bool isAggregate(const PRMClassElement< GUM_SCALAR >& elt) {
137  return elt.elt_type() == prm_aggregate;
138  }
139 
140  /// Return true if obj is of type PRMSlotChain
141  static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR >& elt) {
142  return elt.elt_type() == prm_slotchain;
143  }
144 
145  /// Return true if obj is of type PRMParameter
146  static INLINE bool isParameter(const PRMClassElement< GUM_SCALAR >& elt) {
147  return elt.elt_type() == prm_parameter;
148  }
149 
150  /// @}
151  // ========================================================================
152  /// @name Getters & setters
153  // ========================================================================
154  /// @{
155 
156  /// Returns the NodeId of this element in it's class DAG.
157  NodeId id() const;
158 
159  /// Used to assign the id of this element.
160  virtual void setId(NodeId id);
161 
162  /**
163  * @brief Add a parent to this element.
164  *
165  * This method is called by gum::Class when en parent is added
166  * to this elememnt.
167  */
168  virtual void addParent(const PRMClassElement< GUM_SCALAR >& elt) = 0;
169 
170  /**
171  * @brief Add a child to this element.
172  *
173  * This methos is called by gum::Class when a child is added
174  * to this element.
175  */
176  virtual void addChild(const PRMClassElement< GUM_SCALAR >& elt) = 0;
177 
178  /// @see gum::PRMObject::obj_type().
179  virtual typename PRMObject::prm_type obj_type() const;
180 
181  /// Return the type of class element this object is.
182  virtual ClassElementType elt_type() const = 0;
183 
184  /// @}
185  // ========================================================================
186  /// @name Fast access to random variable's properties
187  // ========================================================================
188  /// @{
189 
190  /**
191  * Return a reference over the gum::PRMType of this class element.
192  * @throw OperationNotAllowed Raised if this class element doesn't have
193  * any gum::Potential (like a
194  * gum::PRMReferenceSlot).
195  */
196  virtual PRMType& type() = 0;
197 
198  /**
199  * Return a constant reference over the gum::PRMType of this class
200  * element.
201  * @throw OperationNotAllowed Raised if this class element doesn't have
202  * any gum::Potential (like a
203  * gum::PRMReferenceSlot).
204  */
205  virtual const PRMType& type() const = 0;
206 
207  /**
208  * @brief Returns a proper cast descendant of this PRMAttribute.
209  *
210  * A cast descendant is an PRMAttribute depending on this one which
211  * cast it in this->type().super().
212  *
213  * The pointer is not deleted by this PRMAttribute, so delete it yourself
214  * after use.
215  *
216  * A new cast descendant is created for each call of this method.
217  *
218  * @return The cast descendant of this PRMAttribute.
219  *
220  * @throw OperationNotAllowed Raised if it is not possible to create a
221  * cast descendant for this PRMAttribute.
222  */
223  virtual PRMAttribute< GUM_SCALAR >* getCastDescendant() const = 0;
224 
225  /**
226  * @brief Returns the safe name of this PRMClassElement, if any.
227  *
228  * This will only work if this PRMClassElement is an PRMAttribute or an
229  *PRMAggregate.
230  * @return Returns the safe name of this PRMClassElement.
231  *
232  * @throw NotFound& Raised if this PRMClassElement does not have any safe
233  *name.
234  */
235  const std::string& safeName() const;
236 
237  /**
238  * @brief Returns the name of the cast descendant with PRMType t of this
239  * PRMClassElement.
240  * @param t The type in which we want to cast this PRMClassElement.
241  * @throw OperationNotAllowed If the cast is impossible.
242  */
243  virtual std::string cast(const PRMType& t) const;
244 
245  // /**
246  // * Return a reference over the gum::Potential of this class element.
247  // * @throw OperationNotAllowed Raised if this class element doesn't have
248  // * any gum::Potential (like a
249  // gum::PRMReferenceSlot).
250  // */
251  // virtual Potential<GUM_SCALAR>& cpf() = 0;
252 
253  /**
254  * Return a constant reference over the gum::Potential of this class
255  * element.
256  * @throw OperationNotAllowed Raised if the class element doesn't have
257  * any gum::Potential (like a
258  * gum::PRMReferenceSlot).
259  */
260  virtual const Potential< GUM_SCALAR >& cpf() const = 0;
261 
262  /// @}
263  protected:
264  /// The safe name of this PRMClassElement.
265  std::string safeName_;
266 
267  private:
268  /// The node's id of this element
269  NodeId _id_;
270  };
271 
272 
273 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
274  extern template class PRMClassElement< double >;
275 #endif
276 
277  } /* namespace prm */
278 } // namespace gum
279 
280 #include <agrum/PRM/elements/PRMClassElement_tpl.h>
281 
282 #endif /* GUM_CLASS_ELEMENT_H */