aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
PRMInterface_tpl.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 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 >
53  const PRMInterface< GUM_SCALAR >& source) :
57  GUM_ERROR(FatalError, "don't copy an interface");
58  }
59 
60  template < typename GUM_SCALAR >
63 
64  for (const auto& elt: nodeIdMap__) {
65  delete elt.second;
66  }
67  }
68 
69  template < typename GUM_SCALAR >
72  }
73 
74  template < typename GUM_SCALAR >
76  const PRMInterface< GUM_SCALAR >& i) {
77  // Copying attributes
78  for (const auto i_attr: i.attributes__) {
79  auto attr
81  attr->setId(i_attr->id());
84 
85  if (i.nameMap__[i_attr->name()] == i.nameMap__[i_attr->safeName()]) {
87  }
88 
91  }
92 
93  // Copying reference slots
94  for (const auto i_ref: i.referenceSlots__) {
95  auto ref = new PRMReferenceSlot< GUM_SCALAR >(
96  i_ref->name(),
97  const_cast< PRMClassElementContainer< GUM_SCALAR >& >(
98  i_ref->slotType()),
99  i_ref->isArray());
100 
101  ref->setId(i_ref->id());
102  nodeIdMap__.insert(ref->id(), ref);
104 
105  if (i.nameMap__.exists(ref->name())) {
106  nameMap__.insert(ref->name(), ref);
107  }
108 
111  }
112  }
113 
114  template < typename GUM_SCALAR >
116  if (nameMap__.exists(elt->name())) {
118  "name '" << elt->name()
119  << "' is already used by another ClassElement");
120  }
121 
124  = static_cast< PRMAttribute< GUM_SCALAR >* >(elt);
126 
127  while (true) {
128  attr->setId(nextNodeId());
133 
134  if (attr->type().isSubType()) {
136  } else {
137  break;
138  }
139  }
140  } else if (PRMClassElement< GUM_SCALAR >::isReferenceSlot(*elt)) {
141  elt->setId(nextNodeId());
143  nodeIdMap__.insert(elt->id(), elt);
145  static_cast< PRMReferenceSlot< GUM_SCALAR >* >(elt));
146  nameMap__.insert(elt->name(), elt);
148  } else {
150  "illegal ClassElement<GUM_SCALAR> for an Interface");
151  }
152 
153  return elt->id();
154  }
155 
156  template < typename GUM_SCALAR >
159  try {
160  if (!super().exists(overloader->name())) {
162  "found no ClassElement<GUM_SCALAR> to overload");
163  }
164  } catch (NotFound&) {
166  "overload is possible only with sub interfaces");
167  }
168 
170  if (overloaded == overloader) {
172  "duplicate ClassElement '" << overloader->name() << "'");
173  }
175  GUM_ERROR(OperationNotAllowed, "illegal overload");
176  }
177 
178  switch (overloader->elt_type()) {
180  auto attr_overloader
181  = static_cast< PRMAttribute< GUM_SCALAR >* >(overloader);
182  auto attr_overloaded
183  = static_cast< PRMAttribute< GUM_SCALAR >* >(overloaded);
185  break;
186  }
187 
189  auto ref_overloader
190  = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloader);
191  auto ref_overloaded
192  = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
194  break;
195  }
196 
199  auto msg = "element can ! be overloaded";
201  break;
202  }
203 
204  default: {
205  GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR> type");
206  }
207  }
208 
209  return overloader->id();
210  }
211 
212  template < typename GUM_SCALAR >
216  if (overloader->type() != overloaded->type()) {
224  } else {
231  // Swapping types, ugly but necessary to preserve the
232  // PRMType<GUM_SCALAR>
233  // pointer of overloaded
235  delete overloaded;
236  }
237  }
238 
239  template < typename GUM_SCALAR >
243  // Adding overloading reference
249  // Removing overloaded PRMReferenceSlot<GUM_SCALAR>
252  delete overloaded;
253  }
254 
255  template < typename GUM_SCALAR >
260  PRMAttribute< GUM_SCALAR >* child = nullptr;
261 
262  while (parent->type().superType() != end->type()) {
264  child->setId(nextNodeId());
267  // Only use child's safe name when adding to the name map!
270  // Do ! use Class<GUM_SCALAR>::insertArc(), child's CPF is already
271  // initialized properly
272  parent = child;
273  }
274 
276  }
277 
278  template < typename GUM_SCALAR >
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);
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 
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 >
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
393  }
394 
395  template < typename GUM_SCALAR >
396  INLINE void
399  }
400 
401  template < typename GUM_SCALAR >
404  return get(id);
405  }
406 
407  template < typename GUM_SCALAR >
410  return get(id);
411  }
412 
413  template < typename GUM_SCALAR >
416  return get(name);
417  }
418 
419  template < typename GUM_SCALAR >
422  return get(name);
423  }
424 
425  template < typename GUM_SCALAR >
426  INLINE typename PRMObject::prm_type
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 >
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 >
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 >
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);
511  }
512 
513  for (const auto ext: extensions__) {
514  set.insert(ext);
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 
529  return true;
530  }
531 
532  } else {
533  return true;
534  }
535  } catch (NotFound&) {}
536  return false;
537  }
538  } /* namespace prm */
539 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)