aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
PRMClassElement.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::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
127  isReferenceSlot(const PRMClassElement< GUM_SCALAR >& elt) {
128  return elt.elt_type() == prm_refslot;
129  }
130 
131  /// Returns true if obj_ptr is of type PRMAttribute.
132  static INLINE bool isAttribute(const PRMClassElement< GUM_SCALAR >& elt) {
133  return elt.elt_type() == prm_attribute;
134  }
135 
136  /// Return true if obj is of type PRMAggregate
137  static INLINE bool isAggregate(const PRMClassElement< GUM_SCALAR >& elt) {
138  return elt.elt_type() == prm_aggregate;
139  }
140 
141  /// Return true if obj is of type PRMSlotChain
142  static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR >& elt) {
143  return elt.elt_type() == prm_slotchain;
144  }
145 
146  /// Return true if obj is of type PRMParameter
147  static INLINE bool isParameter(const PRMClassElement< GUM_SCALAR >& elt) {
148  return elt.elt_type() == prm_parameter;
149  }
150 
151  /// @}
152  // ========================================================================
153  /// @name Getters & setters
154  // ========================================================================
155  /// @{
156 
157  /// Returns the NodeId of this element in it's class DAG.
158  NodeId id() const;
159 
160  /// Used to assign the id of this element.
161  virtual void setId(NodeId id);
162 
163  /**
164  * @brief Add a parent to this element.
165  *
166  * This method is called by gum::Class when en parent is added
167  * to this elememnt.
168  */
169  virtual void addParent(const PRMClassElement< GUM_SCALAR >& elt) = 0;
170 
171  /**
172  * @brief Add a child to this element.
173  *
174  * This methos is called by gum::Class when a child is added
175  * to this element.
176  */
177  virtual void addChild(const PRMClassElement< GUM_SCALAR >& elt) = 0;
178 
179  /// @see gum::PRMObject::obj_type().
180  virtual typename PRMObject::prm_type obj_type() const;
181 
182  /// Return the type of class element this object is.
183  virtual ClassElementType elt_type() const = 0;
184 
185  /// @}
186  // ========================================================================
187  /// @name Fast access to random variable's properties
188  // ========================================================================
189  /// @{
190 
191  /**
192  * Return a reference over the gum::PRMType of this class element.
193  * @throw OperationNotAllowed Raised if this class element doesn't have
194  * any gum::Potential (like a
195  * gum::PRMReferenceSlot).
196  */
197  virtual PRMType& type() = 0;
198 
199  /**
200  * Return a constant reference over the gum::PRMType of this class
201  * element.
202  * @throw OperationNotAllowed Raised if this class element doesn't have
203  * any gum::Potential (like a
204  * gum::PRMReferenceSlot).
205  */
206  virtual const PRMType& type() const = 0;
207 
208  /**
209  * @brief Returns a proper cast descendant of this PRMAttribute.
210  *
211  * A cast descendant is an PRMAttribute depending on this one which
212  * cast it in this->type().super().
213  *
214  * The pointer is not deleted by this PRMAttribute, so delete it yourself
215  * after use.
216  *
217  * A new cast descendant is created for each call of this method.
218  *
219  * @return The cast descendant of this PRMAttribute.
220  *
221  * @throw OperationNotAllowed Raised if it is not possible to create a
222  * cast descendant for this PRMAttribute.
223  */
224  virtual PRMAttribute< GUM_SCALAR >* getCastDescendant() const = 0;
225 
226  /**
227  * @brief Returns the safe name of this PRMClassElement, if any.
228  *
229  * This will only work if this PRMClassElement is an PRMAttribute or an
230  *PRMAggregate.
231  * @return Returns the safe name of this PRMClassElement.
232  *
233  * @throw NotFound& Raised if this PRMClassElement does not have any safe
234  *name.
235  */
236  const std::string& safeName() const;
237 
238  /**
239  * @brief Returns the name of the cast descendant with PRMType t of this
240  * PRMClassElement.
241  * @param t The type in which we want to cast this PRMClassElement.
242  * @throw OperationNotAllowed If the cast is impossible.
243  */
244  virtual std::string cast(const PRMType& t) const;
245 
246  // /**
247  // * Return a reference over the gum::Potential of this class element.
248  // * @throw OperationNotAllowed Raised if this class element doesn't have
249  // * any gum::Potential (like a
250  // gum::PRMReferenceSlot).
251  // */
252  // virtual Potential<GUM_SCALAR>& cpf() = 0;
253 
254  /**
255  * Return a constant reference over the gum::Potential of this class
256  * element.
257  * @throw OperationNotAllowed Raised if the class element doesn't have
258  * any gum::Potential (like a
259  * gum::PRMReferenceSlot).
260  */
261  virtual const Potential< GUM_SCALAR >& cpf() const = 0;
262 
263  /// @}
264  protected:
265  /// The safe name of this PRMClassElement.
266  std::string safeName_;
267 
268  private:
269  /// The node's id of this element
270  NodeId id__;
271  };
272 
273 
274 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
275  extern template class PRMClassElement< double >;
276 #endif
277 
278  } /* namespace prm */
279 } // namespace gum
280 
281 #include <agrum/PRM/elements/PRMClassElement_tpl.h>
282 
283 #endif /* GUM_CLASS_ELEMENT_H */