aGrUM  0.16.0
PRMInterface_tpl.h
Go to the documentation of this file.
1 
30 
32 
33 namespace gum {
34  namespace prm {
35 
36  template < typename GUM_SCALAR >
37  PRMInterface< GUM_SCALAR >::PRMInterface(const std::string& name) :
38  PRMClassElementContainer< GUM_SCALAR >(name), __superInterface(0) {
39  GUM_CONSTRUCTOR(PRMInterface);
40  }
41 
42  template < typename GUM_SCALAR >
45  bool delayInheritance) :
46  PRMClassElementContainer< GUM_SCALAR >(name),
47  __superInterface(&super) {
48  GUM_CONSTRUCTOR(PRMInterface);
49  if (!delayInheritance) { __inheritInterface(super); }
50  }
51 
52  template < typename GUM_SCALAR >
54  const PRMInterface< GUM_SCALAR >& source) :
55  PRMClassElementContainer< GUM_SCALAR >(source.name()),
56  __dag(source.__dag), __superInterface(source.__superInterface) {
57  GUM_CONS_CPY(PRMInterface);
58  GUM_ERROR(FatalError, "don't copy an interface");
59  }
60 
61  template < typename GUM_SCALAR >
63  GUM_DESTRUCTOR(PRMInterface);
64 
65  for (const auto& elt : __nodeIdMap) {
66  delete elt.second;
67  }
68  }
69 
70  template < typename GUM_SCALAR >
72  if (__superInterface != nullptr) { __inheritInterface(*__superInterface); }
73  }
74 
75  template < typename GUM_SCALAR >
77  const PRMInterface< GUM_SCALAR >& i) {
78  // Copying attributes
79  for (const auto i_attr : i.__attributes) {
80  auto attr =
81  new PRMScalarAttribute< GUM_SCALAR >(i_attr->name(), i_attr->type());
82  attr->setId(i_attr->id());
83  __nodeIdMap.insert(attr->id(), attr);
84  __attributes.insert(attr);
85 
86  if (i.__nameMap[i_attr->name()] == i.__nameMap[i_attr->safeName()]) {
87  __nameMap.insert(attr->name(), attr);
88  }
89 
90  __nameMap.insert(attr->safeName(), attr);
91  __dag.addNodeWithId(attr->id());
92  }
93 
94  // Copying reference slots
95  for (const auto i_ref : i.__referenceSlots) {
96  auto ref = new PRMReferenceSlot< GUM_SCALAR >(
97  i_ref->name(),
99  i_ref->slotType()),
100  i_ref->isArray());
101 
102  ref->setId(i_ref->id());
103  __nodeIdMap.insert(ref->id(), ref);
104  __referenceSlots.insert(ref);
105 
106  if (i.__nameMap.exists(ref->name())) {
107  __nameMap.insert(ref->name(), ref);
108  }
109 
110  __nameMap.insert(ref->safeName(), ref);
111  __dag.addNodeWithId(ref->id());
112  }
113  }
114 
115  template < typename GUM_SCALAR >
117  if (__nameMap.exists(elt->name())) {
119  "name '" << elt->name()
120  << "' is already used by another ClassElement");
121  }
122 
125  static_cast< PRMAttribute< GUM_SCALAR >* >(elt);
126  __nameMap.insert(attr->name(), attr);
127 
128  while (true) {
129  attr->setId(nextNodeId());
130  __dag.addNodeWithId(attr->id());
131  __nodeIdMap.insert(attr->id(), attr);
132  __nameMap.insert(attr->safeName(), attr);
133  __attributes.insert(attr);
134 
135  if (attr->type().isSubType()) {
136  attr = attr->getCastDescendant();
137  } else {
138  break;
139  }
140  }
142  elt->setId(nextNodeId());
143  __dag.addNodeWithId(elt->id());
144  __nodeIdMap.insert(elt->id(), elt);
145  __referenceSlots.insert(
146  static_cast< PRMReferenceSlot< GUM_SCALAR >* >(elt));
147  __nameMap.insert(elt->name(), elt);
148  __nameMap.insert(elt->safeName(), elt);
149  } else {
151  "illegal ClassElement<GUM_SCALAR> for an Interface");
152  }
153 
154  return elt->id();
155  }
156 
157  template < typename GUM_SCALAR >
159  PRMClassElement< GUM_SCALAR >* overloader) {
160  try {
161  if (!super().exists(overloader->name())) {
163  "found no ClassElement<GUM_SCALAR> to overload");
164  }
165  } catch (NotFound&) {
167  "overload is possible only with sub interfaces");
168  }
169 
170  PRMClassElement< GUM_SCALAR >* overloaded = __nameMap[overloader->name()];
171  if (overloaded == overloader) {
173  "duplicate ClassElement '" << overloader->name() << "'");
174  }
175  if (!__checkOverloadLegality(overloaded, overloader)) {
176  GUM_ERROR(OperationNotAllowed, "illegal overload");
177  }
178 
179  switch (overloader->elt_type()) {
181  auto attr_overloader =
182  static_cast< PRMAttribute< GUM_SCALAR >* >(overloader);
183  auto attr_overloaded =
184  static_cast< PRMAttribute< GUM_SCALAR >* >(overloaded);
185  __overloadAttribute(attr_overloader, attr_overloaded);
186  break;
187  }
188 
190  auto ref_overloader =
191  static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloader);
192  auto ref_overloaded =
193  static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
194  __overloadReferenceSlot(ref_overloader, ref_overloaded);
195  break;
196  }
197 
200  auto msg = "element can ! be overloaded";
202  break;
203  }
204 
205  default: {
206  GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR> type");
207  }
208  }
209 
210  return overloader->id();
211  }
212 
213  template < typename GUM_SCALAR >
215  PRMAttribute< GUM_SCALAR >* overloader,
216  PRMAttribute< GUM_SCALAR >* overloaded) {
217  if (overloader->type() != overloaded->type()) {
218  overloader->setId(nextNodeId());
219  __dag.addNodeWithId(overloader->id());
220  __nodeIdMap.insert(overloader->id(), overloader);
221  __nameMap[overloader->name()] = overloader;
222  __nameMap.insert(overloader->safeName(), overloader);
223  __attributes.insert(overloader);
224  __addCastDescendants(overloader, overloaded);
225  } else {
226  overloader->setId(overloaded->id());
227  __nodeIdMap[overloader->id()] = overloader;
228  __nameMap[overloader->name()] = overloader;
229  __nameMap[overloader->safeName()] = overloader;
230  __attributes.erase(overloaded);
231  __attributes.insert(overloader);
232  // Swapping types, ugly but necessary to preserve the
233  // PRMType<GUM_SCALAR>
234  // pointer of overloaded
235  overloader->overload(overloaded);
236  delete overloaded;
237  }
238  }
239 
240  template < typename GUM_SCALAR >
242  PRMReferenceSlot< GUM_SCALAR >* overloader,
243  PRMReferenceSlot< GUM_SCALAR >* overloaded) {
244  // Adding overloading reference
245  overloader->setId(overloaded->id());
246  __nodeIdMap[overloader->id()] = overloader;
247  __nameMap[overloader->name()] = overloader;
248  __nameMap.insert(overloader->safeName(), overloader);
249  __referenceSlots.insert(overloader);
250  // Removing overloaded PRMReferenceSlot<GUM_SCALAR>
251  __referenceSlots.erase(overloaded);
252  __nameMap.erase(overloaded->safeName());
253  delete overloaded;
254  }
255 
256  template < typename GUM_SCALAR >
259  PRMAttribute< GUM_SCALAR >* parent = start;
260  PRMAttribute< GUM_SCALAR >* child = nullptr;
261 
262  while (parent->type().superType() != end->type()) {
263  child = parent->getCastDescendant();
264  child->setId(nextNodeId());
265  __dag.addNodeWithId(child->id());
266  __nodeIdMap.insert(child->id(), child);
267  // Only use child's safe name when adding to the name map!
268  __nameMap.insert(child->safeName(), child);
269  __attributes.insert(child);
270  // Do ! use Class<GUM_SCALAR>::insertArc(), child's CPF is already
271  // initialized properly
272  parent = child;
273  }
274 
275  parent->setAsCastDescendant(end);
276  }
277 
278  template < typename GUM_SCALAR >
280  const PRMClassElement< GUM_SCALAR >* overloaded,
281  const PRMClassElement< GUM_SCALAR >* overloader) {
282  if (overloaded->elt_type() != overloader->elt_type()) { return false; }
283 
285  if (!overloader->type().isSubTypeOf(overloaded->type())) { return false; }
286  } else if (overloaded->elt_type()
288  auto ref_overloader =
289  static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloader);
290  auto ref_overloaded =
291  static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
292  if (!ref_overloader->slotType().isSubTypeOf(ref_overloaded->slotType())) {
293  return false;
294  }
295  } else {
296  return false;
297  }
298  return true;
299  }
300 
301  template < typename GUM_SCALAR >
303  const PRMClassElementContainer< GUM_SCALAR >& cec) const {
304  switch (cec.obj_type()) {
306  return false;
307  }
308 
310  const PRMInterface* current = this;
311 
312  while (current != 0) {
313  if (current == &(cec)) return true;
314 
315  current = current->__superInterface;
316  }
317 
318  return false;
319  }
320 
321  default: {
322  GUM_ERROR(FatalError, "unknown ClassElementContainer<GUM_SCALAR>");
323  }
324  }
325  }
326 
327  template < typename GUM_SCALAR >
329  const PRMClassElement< GUM_SCALAR >& elt) {
330  // for ( const auto ext : __extensions )
331  // if ( !ext->isOutputNode( elt ) ) ext->setOutputNode( elt, true );
332 
333  // for ( const auto impl : __implementations ) {
334  // // Because of cyclic dependencies we must use a reinterpret cast.
335  // PRMClassElementContainer<GUM_SCALAR>* c =
336  // reinterpret_cast<PRMClassElementContainer<GUM_SCALAR>*>( impl );
337 
338  // if ( ! c->isOutputNode( elt ) ) c->setOutputNode( elt, true );
339  //}
340  }
341 
342  template < typename GUM_SCALAR >
345  return __nodeIdMap.begin();
346  }
347 
348  template < typename GUM_SCALAR >
349  INLINE const typename PRMInterface< GUM_SCALAR >::ClassEltIterator&
351  return __nodeIdMap.end();
352  }
353 
354  template < typename GUM_SCALAR >
357  return __nodeIdMap.begin();
358  }
359 
360  template < typename GUM_SCALAR >
363  return __nodeIdMap.end();
364  }
365 
366  template < typename GUM_SCALAR >
367  INLINE void PRMInterface< GUM_SCALAR >::addArc(const std::string& tail,
368  const std::string& head) {
369  GUM_ERROR(OperationNotAllowed, "an Interface does ! have arcs");
370  }
371 
372  template < typename GUM_SCALAR >
374  if (__superInterface)
375  return *__superInterface;
376  else
377  GUM_ERROR(NotFound, "this Interface is ! a sub interface");
378  }
379 
380  template < typename GUM_SCALAR >
381  INLINE const PRMInterface< GUM_SCALAR >&
383  if (__superInterface)
384  return *__superInterface;
385  else
386  GUM_ERROR(NotFound, "this Interface is ! a sub interface");
387  }
388 
389  template < typename GUM_SCALAR >
390  INLINE void
392  __implementations.insert(c);
393  }
394 
395  template < typename GUM_SCALAR >
396  INLINE void
398  __extensions.insert(i);
399  }
400 
401  template < typename GUM_SCALAR >
404  return get(id);
405  }
406 
407  template < typename GUM_SCALAR >
409  operator[](NodeId id) const {
410  return get(id);
411  }
412 
413  template < typename GUM_SCALAR >
415  operator[](const std::string& name) {
416  return get(name);
417  }
418 
419  template < typename GUM_SCALAR >
421  operator[](const std::string& name) const {
422  return get(name);
423  }
424 
425  template < typename GUM_SCALAR >
426  INLINE typename PRMObject::prm_type
428  return PRMObject::prm_type::PRM_INTERFACE;
429  }
430 
431  template < typename GUM_SCALAR >
432  INLINE const DAG& PRMInterface< GUM_SCALAR >::_dag() const {
433  return __dag;
434  }
435 
436  template < typename GUM_SCALAR >
438  return __dag;
439  }
440 
441  template < typename GUM_SCALAR >
444  try {
445  return *(__nodeIdMap[id]);
446  } catch (NotFound&) {
447  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId");
448  }
449  }
450 
451  template < typename GUM_SCALAR >
452  INLINE const PRMClassElement< GUM_SCALAR >&
454  try {
455  return *(__nodeIdMap[id]);
456  } catch (NotFound&) {
457  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId");
458  }
459  }
460 
461  template < typename GUM_SCALAR >
463  PRMInterface< GUM_SCALAR >::get(const std::string& name) {
464  try {
465  return *(__nameMap[name]);
466  } catch (NotFound&) {
467  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name");
468  }
469  }
470 
471  template < typename GUM_SCALAR >
472  INLINE const PRMClassElement< GUM_SCALAR >&
473  PRMInterface< GUM_SCALAR >::get(const std::string& name) const {
474  try {
475  return *(__nameMap[name]);
476  } catch (NotFound&) {
477  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name");
478  }
479  }
480 
481  template < typename GUM_SCALAR >
482  INLINE const Set< PRMAttribute< GUM_SCALAR >* >&
484  return __attributes;
485  }
486 
487  template < typename GUM_SCALAR >
488  INLINE const Set< PRMReferenceSlot< GUM_SCALAR >* >&
490  return __referenceSlots;
491  }
492 
493  template < typename GUM_SCALAR >
494  INLINE Set< PRMClass< GUM_SCALAR >* >&
496  return __implementations;
497  }
498 
499  template < typename GUM_SCALAR >
500  INLINE const Set< PRMClass< GUM_SCALAR >* >&
502  return __implementations;
503  }
504 
505  template < typename GUM_SCALAR >
508  for (const auto impl : __implementations) {
509  set.insert(impl);
510  impl->_findAllSubtypes(set);
511  }
512 
513  for (const auto ext : __extensions) {
514  set.insert(ext);
515  ext->_findAllSubtypes(set);
516  }
517  }
518 
519  template < typename GUM_SCALAR >
521  const PRMClassElement< GUM_SCALAR >& elt) const {
522  try {
523  if (!this->_getIOFlag(elt).second) {
524  for (auto i : __implementations) {
525  if (i->isOutputNode(elt)) { return true; }
526  }
527 
528  if (__superInterface && __superInterface->isOutputNode(elt)) {
529  return true;
530  }
531 
532  } else {
533  return true;
534  }
535  } catch (NotFound&) {}
536  return false;
537  }
538  } /* namespace prm */
539 } /* namespace gum */
Unsafe Const Iterators for hashtablesHashTableConstIterator provides a fast but unsafe way to parse H...
Definition: hashTable.h:2465
virtual PRMAttribute< GUM_SCALAR > * getCastDescendant() const =0
Returns a proper cast descendant of this PRMAttribute.
ClassEltIterator begin()
const std::string & name() const
Returns the name of this object.
Definition: PRMObject_inl.h:35
virtual PRMType & type()=0
See gum::PRMClassElement::type().
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
Definition: hashTable.h:2750
virtual prm_type obj_type() const =0
Returns the type of this object.
Abstract class representing an element of PRM class.
void _findAllSubtypes(Set< PRMClassElementContainer< GUM_SCALAR > * > &set)
Fills set with all the subtypes of this PRMInterface, this includes extensions and implementations...
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
A PRMReferenceSlot represent a relation between two PRMClassElementContainer.
Definition: PRMObject.h:223
PRMClassElementContainer< GUM_SCALAR > & slotType()
Returns the type of this slot, which is a PRMClassElementContainer (it is not the type of PRMObject)...
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
prm_type
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:69
HashTable< std::string, PRMClassElement< GUM_SCALAR > *> __nameMap
Mapping between a member&#39;s name and itself. Used for fast access to a member given it&#39;s name...
Definition: PRMInterface.h:341
virtual void overload(PRMAttribute< GUM_SCALAR > *source)
Set this as overload of source (necessayr to preserver internal pointers for MultiDims).
PRMInterface(const std::string &name)
Default constructor.
An PRMInterface is implemented by a Class<GUM_SCALAR> and defines a set of PRMReferenceSlot<GUM_SCALA...
Definition: PRMClass.h:54
virtual ClassElementType elt_type() const =0
Return the type of class element this object is.
virtual PRMType & type()=0
Return a reference over the gum::PRMType of this class element.
NodeId nextNodeId()
Returns the next value of an unique counter for PRM&#39;s node id.
Definition: utils_prm.cpp:65
<agrum/PRM/classElementContainer.h>
NodeId id() const
Returns the NodeId of this element in it&#39;s class DAG.
virtual void setId(NodeId id)
Used to assign the id of this element.
Set< PRMAttribute< GUM_SCALAR > *> __attributes
The sequence of PRMAttribute<GUM_SCALAR>s.
Definition: PRMInterface.h:344
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
Definition: PRMClass.h:66
virtual void setAsCastDescendant(PRMAttribute< GUM_SCALAR > *attr)=0
Define attr as a cast descendant of this PRMAttribute.
const ClassEltIterator & end()
PRMInterface< GUM_SCALAR > * __superInterface
The alternate PRMClassElementContainer<GUM_SCALAR> searched for elements defined in this...
Definition: PRMInterface.h:359
Set< PRMReferenceSlot< GUM_SCALAR > *> __referenceSlots
The sequence of PRMReferenceSlot<GUM_SCALAR>.
Definition: PRMInterface.h:347
PRMAttribute is a member of a Class in a PRM.
Definition: PRMAttribute.h:61
<agrum/PRM/elements/scalarAttribute.h>
Base class for dag.
Definition: DAG.h:102
Size NodeId
Type for node ids.
Definition: graphElements.h:98
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55