aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
PRMInterface_tpl.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 Inline implementation of gum::prm::PRMInterface
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 #include <agrum/PRM/elements/PRMInterface.h>
29 
30 #include <agrum/PRM/elements/PRMClass.h>
31 
32 namespace gum {
33  namespace prm {
34 
35  template < typename GUM_SCALAR >
36  PRMInterface< GUM_SCALAR >::PRMInterface(const std::string& name) :
37  PRMClassElementContainer< GUM_SCALAR >(name), _superInterface_(0) {
38  GUM_CONSTRUCTOR(PRMInterface);
39  }
40 
41  template < typename GUM_SCALAR >
44  bool delayInheritance) :
49  }
50 
51  template < typename GUM_SCALAR >
56  GUM_ERROR(FatalError, "don't copy an interface")
57  }
58 
59  template < typename GUM_SCALAR >
62 
63  for (const auto& elt: _nodeIdMap_) {
64  delete elt.second;
65  }
66  }
67 
68  template < typename GUM_SCALAR >
71  }
72 
73  template < typename GUM_SCALAR >
75  // Copying attributes
76  for (const auto i_attr: i._attributes_) {
77  auto attr = new PRMScalarAttribute< GUM_SCALAR >(i_attr->name(), i_attr->type());
78  attr->setId(i_attr->id());
81 
82  if (i._nameMap_[i_attr->name()] == i._nameMap_[i_attr->safeName()]) {
84  }
85 
88  }
89 
90  // Copying reference slots
91  for (const auto i_ref: i._referenceSlots_) {
92  auto ref = new PRMReferenceSlot< GUM_SCALAR >(
93  i_ref->name(),
94  const_cast< PRMClassElementContainer< GUM_SCALAR >& >(i_ref->slotType()),
95  i_ref->isArray());
96 
97  ref->setId(i_ref->id());
100 
101  if (i._nameMap_.exists(ref->name())) { _nameMap_.insert(ref->name(), ref); }
102 
105  }
106  }
107 
108  template < typename GUM_SCALAR >
110  if (_nameMap_.exists(elt->name())) {
112  "name '" << elt->name() << "' is already used by another ClassElement");
113  }
114 
116  PRMAttribute< GUM_SCALAR >* attr = static_cast< PRMAttribute< GUM_SCALAR >* >(elt);
118 
119  while (true) {
120  attr->setId(nextNodeId());
125 
126  if (attr->type().isSubType()) {
128  } else {
129  break;
130  }
131  }
132  } else if (PRMClassElement< GUM_SCALAR >::isReferenceSlot(*elt)) {
133  elt->setId(nextNodeId());
135  _nodeIdMap_.insert(elt->id(), elt);
137  _nameMap_.insert(elt->name(), elt);
139  } else {
140  GUM_ERROR(WrongClassElement, "illegal ClassElement<GUM_SCALAR> for an Interface")
141  }
142 
143  return elt->id();
144  }
145 
146  template < typename GUM_SCALAR >
148  try {
149  if (!super().exists(overloader->name()))
150  GUM_ERROR(OperationNotAllowed, "found no ClassElement<GUM_SCALAR> to overload")
151 
152  } catch (NotFound&) {
153  GUM_ERROR(OperationNotAllowed, "overload is possible only with sub interfaces")
154  }
155 
157  if (overloaded == overloader)
158  GUM_ERROR(DuplicateElement, "duplicate ClassElement '" << overloader->name() << "'")
159 
161  GUM_ERROR(OperationNotAllowed, "illegal overload")
162 
163  switch (overloader->elt_type()) {
165  auto attr_overloader = static_cast< PRMAttribute< GUM_SCALAR >* >(overloader);
166  auto attr_overloaded = static_cast< PRMAttribute< GUM_SCALAR >* >(overloaded);
168  break;
169  }
170 
172  auto ref_overloader = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloader);
173  auto ref_overloaded = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
175  break;
176  }
177 
181  "Element " << overloader->name() << " can not be overloaded")
182  default:
183  GUM_ERROR(FatalError, "Unknown ClassElement<GUM_SCALAR> type for " << overloader->name())
184  }
185 
186  return overloader->id();
187  }
188 
189  template < typename GUM_SCALAR >
192  if (overloader->type() != overloaded->type()) {
200  } else {
207  // Swapping types, ugly but necessary to preserve the
208  // PRMType<GUM_SCALAR>
209  // pointer of overloaded
211  delete overloaded;
212  }
213  }
214 
215  template < typename GUM_SCALAR >
219  // Adding overloading reference
225  // Removing overloaded PRMReferenceSlot<GUM_SCALAR>
228  delete overloaded;
229  }
230 
231  template < typename GUM_SCALAR >
235  PRMAttribute< GUM_SCALAR >* child = nullptr;
236 
237  while (parent->type().superType() != end->type()) {
239  child->setId(nextNodeId());
242  // Only use child's safe name when adding to the name map!
245  // Do ! use Class<GUM_SCALAR>::insertArc(), child's CPF is already
246  // initialized properly
247  parent = child;
248  }
249 
251  }
252 
253  template < typename GUM_SCALAR >
257  if (overloaded->elt_type() != overloader->elt_type()) { return false; }
258 
260  if (!overloader->type().isSubTypeOf(overloaded->type())) { return false; }
262  auto ref_overloader = static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloader);
263  auto ref_overloaded = static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
264  if (!ref_overloader->slotType().isSubTypeOf(ref_overloaded->slotType())) { return false; }
265  } else {
266  return false;
267  }
268  return true;
269  }
270 
271  template < typename GUM_SCALAR >
273  const PRMClassElementContainer< GUM_SCALAR >& cec) const {
274  switch (cec.obj_type()) {
276  return false;
277  }
278 
280  const PRMInterface* current = this;
281 
282  while (current != 0) {
283  if (current == &(cec)) return true;
284 
286  }
287 
288  return false;
289  }
290 
291  default: {
292  GUM_ERROR(FatalError, "unknown ClassElementContainer<GUM_SCALAR>")
293  }
294  }
295  }
296 
297  template < typename GUM_SCALAR >
299  // for ( const auto ext : _extensions_ )
300  // if ( !ext->isOutputNode( elt ) ) ext->setOutputNode( elt, true );
301 
302  // for ( const auto impl : _implementations_ ) {
303  // // Because of cyclic dependencies we must use a reinterpret cast.
304  // PRMClassElementContainer<GUM_SCALAR>* c =
305  // reinterpret_cast<PRMClassElementContainer<GUM_SCALAR>*>( impl );
306 
307  // if ( ! c->isOutputNode( elt ) ) c->setOutputNode( elt, true );
308  //}
309  }
310 
311  template < typename GUM_SCALAR >
314  return _nodeIdMap_.begin();
315  }
316 
317  template < typename GUM_SCALAR >
318  INLINE const typename PRMInterface< GUM_SCALAR >::ClassEltIterator&
320  return _nodeIdMap_.end();
321  }
322 
323  template < typename GUM_SCALAR >
326  return _nodeIdMap_.begin();
327  }
328 
329  template < typename GUM_SCALAR >
332  return _nodeIdMap_.end();
333  }
334 
335  template < typename GUM_SCALAR >
337  const std::string& head) {
338  GUM_ERROR(OperationNotAllowed, "an Interface does ! have arcs")
339  }
340 
341  template < typename GUM_SCALAR >
343  if (_superInterface_)
344  return *_superInterface_;
345  else
346  GUM_ERROR(NotFound, "this Interface is ! a sub interface")
347  }
348 
349  template < typename GUM_SCALAR >
351  if (_superInterface_)
352  return *_superInterface_;
353  else
354  GUM_ERROR(NotFound, "this Interface is ! a sub interface")
355  }
356 
357  template < typename GUM_SCALAR >
360  }
361 
362  template < typename GUM_SCALAR >
365  }
366 
367  template < typename GUM_SCALAR >
369  return get(id);
370  }
371 
372  template < typename GUM_SCALAR >
375  return get(id);
376  }
377 
378  template < typename GUM_SCALAR >
381  return get(name);
382  }
383 
384  template < typename GUM_SCALAR >
387  return get(name);
388  }
389 
390  template < typename GUM_SCALAR >
393  }
394 
395  template < typename GUM_SCALAR >
396  INLINE const DAG& PRMInterface< GUM_SCALAR >::dag_() const {
397  return _dag_;
398  }
399 
400  template < typename GUM_SCALAR >
402  return _dag_;
403  }
404 
405  template < typename GUM_SCALAR >
407  try {
408  return *(_nodeIdMap_[id]);
409  } catch (NotFound&) {
410  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId")
411  }
412  }
413 
414  template < typename GUM_SCALAR >
416  try {
417  return *(_nodeIdMap_[id]);
418  } catch (NotFound&) {
419  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId")
420  }
421  }
422 
423  template < typename GUM_SCALAR >
425  try {
426  return *(_nameMap_[name]);
427  } catch (NotFound&) { GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name") }
428  }
429 
430  template < typename GUM_SCALAR >
432  PRMInterface< GUM_SCALAR >::get(const std::string& name) const {
433  try {
434  return *(_nameMap_[name]);
435  } catch (NotFound&) { GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name") }
436  }
437 
438  template < typename GUM_SCALAR >
439  INLINE const Set< PRMAttribute< GUM_SCALAR >* >&
441  return _attributes_;
442  }
443 
444  template < typename GUM_SCALAR >
445  INLINE const Set< PRMReferenceSlot< GUM_SCALAR >* >&
447  return _referenceSlots_;
448  }
449 
450  template < typename GUM_SCALAR >
452  return _implementations_;
453  }
454 
455  template < typename GUM_SCALAR >
456  INLINE const Set< PRMClass< GUM_SCALAR >* >&
458  return _implementations_;
459  }
460 
461  template < typename GUM_SCALAR >
464  for (const auto impl: _implementations_) {
465  set.insert(impl);
467  }
468 
469  for (const auto ext: _extensions_) {
470  set.insert(ext);
472  }
473  }
474 
475  template < typename GUM_SCALAR >
476  INLINE bool
478  try {
479  if (!this->getIOFlag_(elt).second) {
480  for (auto i: _implementations_) {
481  if (i->isOutputNode(elt)) { return true; }
482  }
483 
484  if (_superInterface_ && _superInterface_->isOutputNode(elt)) { return true; }
485 
486  } else {
487  return true;
488  }
489  } catch (NotFound&) {}
490  return false;
491  }
492  } /* namespace prm */
493 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)