aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
PRMClass_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
49
50// to ease parsing
51#include <queue>
52
55
56namespace gum {
57 namespace prm {
58 template < typename GUM_SCALAR >
60 PRMClassElementContainer< GUM_SCALAR >(name), _superClass_(nullptr), _implements_(nullptr),
61 _bijection_(nullptr) {
62 GUM_CONSTRUCTOR(PRMClass);
63 }
64
65 template < typename GUM_SCALAR >
68 bool delayInheritance) :
71 GUM_CONSTRUCTOR(PRMClass);
72 if (!delayInheritance) {
73 _dag_ = super.containerDag();
75 }
76 }
77
78 template < typename GUM_SCALAR >
80 const Set< PRMInterface< GUM_SCALAR >* >& set,
81 bool delayInheritance) :
82 PRMClassElementContainer< GUM_SCALAR >(name), _superClass_(nullptr),
83 _implements_(new Set< PRMInterface< GUM_SCALAR >* >(set)), _bijection_(nullptr) {
84 GUM_CONSTRUCTOR(PRMClass);
85
86 if (!delayInheritance) { _implementInterfaces_(false); }
87 }
88
89 template < typename GUM_SCALAR >
92 const Set< PRMInterface< GUM_SCALAR >* >& set,
93 bool delayInheritance) :
96 GUM_CONSTRUCTOR(PRMClass);
97 if (!delayInheritance) {
98 _dag_ = super.containerDag();
100 }
101
102 // Adding other implementation
103 if (_implements_ == nullptr) { // super has not created _implements_
105 } else { // we just add the new implementations
106 for (const auto elt: set) {
107 _implements_->insert(elt);
108 }
109 }
110
111 if (!delayInheritance) { _implementInterfaces_(false); }
112 }
113
114 template < typename GUM_SCALAR >
115 void PRMClass< GUM_SCALAR >::_implementInterfaces_(bool delayedInheritance) {
116 for (const auto impl: *_implements_) {
117 impl->_addImplementation_(this);
118 if ((!_superClass_) || (!super().isSubTypeOf(*impl)) || delayedInheritance) {
119 // Reserve reference id in DAG
120 for (auto ref: impl->referenceSlots()) {
121 _dag_.addNodeWithId(ref->id());
122 }
123 // Reserve attribute id in DAG
124 for (auto attr: impl->attributes()) {
125 _dag_.addNodeWithId(attr->id());
126 }
127 }
128 }
129 }
130
131 template < typename GUM_SCALAR >
133 GUM_DESTRUCTOR(PRMClass);
134
135 for (const auto& elt: _nodeIdMap_) {
136 delete elt.second;
137 }
138
139 if (_implements_) { delete _implements_; }
140
141 if (_bijection_) { delete _bijection_; }
142 }
143
144 template < typename GUM_SCALAR >
146 if (_superClass_) {
147 _superClass_->_addExtension_(this);
148 // Adding implemented interfaces, if any
149 if (_superClass_->_implements_) {
150 if (!_implements_) {
152 } else {
153 for (auto i: *(_superClass_->_implements_)) {
154 _implements_->insert(i);
155 }
156 }
157 }
158 }
159 if (_implements_) { _implementInterfaces_(true); }
160 }
161
162 template < typename GUM_SCALAR >
164 if (_superClass_) {
165 // Copying reference slots
166 for (const auto c_refslot: _superClass_->_referenceSlots_) {
167 auto ref = new PRMReferenceSlot< GUM_SCALAR >(
168 c_refslot->name(),
169 const_cast< PRMClassElementContainer< GUM_SCALAR >& >(c_refslot->slotType()),
170 c_refslot->isArray());
171
172 ref->setId(c_refslot->id());
173 // Not reserved by an interface
174 if (!_dag_.existsNode(ref->id())) { _dag_.addNodeWithId(ref->id()); }
175 _nodeIdMap_.insert(ref->id(), ref);
176 _referenceSlots_.insert(ref);
178 if (_superClass_->_nameMap_[c_refslot->name()]
179 == _superClass_->_nameMap_[c_refslot->safeName()]) {
180 _nameMap_.insert(ref->name(), ref);
181 }
182
183 _nameMap_.insert(ref->safeName(), ref);
184 }
185 }
186 }
187
188 template < typename GUM_SCALAR >
190 if (_superClass_) {
191 // Copying parameters
192 for (const auto c_param: _superClass_->_parameters_) {
193 auto param = new PRMParameter< GUM_SCALAR >(c_param->name(),
194 c_param->valueType(),
195 c_param->value());
196
197 _parameters_.insert(param);
198
199 param->setId(c_param->id());
200 _dag_.addNodeWithId(param->id());
201 _nodeIdMap_.insert(param->id(), param);
202 _nameMap_.insert(param->name(), param);
203 }
204 }
205 }
206
207 template < typename GUM_SCALAR >
209 if (_superClass_) {
210 for (const auto c_attr: _superClass_->_attributes_) {
211 // using multiDimSparse to prevent unecessary memory allocation for
212 // large arrays (the tensors are copied latter)
213 auto attr = c_attr->newFactory(*this);
214
215 _bijection_->insert(&(c_attr->type().variable()), &(attr->type().variable()));
216 attr->setId(c_attr->id());
217 try {
218 _dag_.addNodeWithId(attr->id());
219 } catch (gum::Exception&) {
220 // Node reserved by an interface
221 }
222 _nodeIdMap_.insert(attr->id(), attr);
223 _attributes_.insert(attr);
224
225 if (_superClass_->_nameMap_[c_attr->name()]
226 == _superClass_->_nameMap_[c_attr->safeName()]) {
227 _nameMap_.insert(attr->name(), attr);
229
230 _nameMap_.insert(attr->safeName(), attr);
231 }
232 }
233 }
234
235 template < typename GUM_SCALAR >
237 if (_superClass_) {
238 for (const auto c_agg: _superClass_->_aggregates_) {
239 PRMAggregate< GUM_SCALAR >* agg = nullptr;
240
241 try {
242 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(),
243 c_agg->agg_type(),
244 c_agg->type(),
245 c_agg->label());
246 } catch (OperationNotAllowed const&) {
247 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(), c_agg->agg_type(), c_agg->type());
248 agg->sharedLabel(c_agg->sharedLabel());
249 agg->setLabel(c_agg->labelValue());
250 }
251
252 _bijection_->insert(&(c_agg->type().variable()), &(agg->type().variable()));
253 agg->setId(c_agg->id());
254 _dag_.addNodeWithId(agg->id());
255 _nodeIdMap_.insert(agg->id(), agg);
256 _aggregates_.insert(agg);
257
258 if (_superClass_->_nameMap_[c_agg->name()] == _superClass_->_nameMap_[c_agg->safeName()])
259 _nameMap_.insert(agg->name(), agg);
260
261 _nameMap_.insert(agg->safeName(), agg);
262 }
264 }
265
266 template < typename GUM_SCALAR >
268 if (_superClass_) {
269 // Copying slot chains
270 for (const auto c_sc: _superClass_->_slotChains_) {
271 // Because of aggregators, some slotchains may exists already
272 if (!(_nameMap_.exists(c_sc->name()) && _nameMap_.exists(c_sc->safeName()))) {
273 // We just need to change the first PRMReferenceSlot<GUM_SCALAR> in
274 // the
275 // chain
276 auto chain = c_sc->chain();
277
278 chain.setAtPos(0, _nameMap_[c_sc->chain().front()->name()]);
279
280 auto sc = new PRMSlotChain< GUM_SCALAR >(c_sc->name(), chain);
281 _bijection_->insert(&(c_sc->type().variable()), &(sc->type().variable()));
282 sc->setId(c_sc->id());
283 _dag_.addNodeWithId(sc->id());
284 _nodeIdMap_.insert(sc->id(), sc);
285 _slotChains_.insert(sc);
286
287 if (!_nameMap_.exists(sc->name())) { _nameMap_.insert(sc->name(), sc); }
288 if (!_nameMap_.exists(sc->safeName())) { _nameMap_.insert(sc->safeName(), sc); }
289 }
290 }
291 }
292 }
293
294 template < typename GUM_SCALAR >
296 if (_superClass_) {
297 auto& elt = this->get(name);
300 GUM_ERROR(OperationNotAllowed, "you can only complete inheritance for attributes")
301 }
302
303 for (const auto& prnt: super().containerDag().parents(elt.id())) {
304 this->addArc(super().get(prnt).safeName(), elt.safeName());
305 }
306
308 auto& attr = static_cast< PRMAttribute< GUM_SCALAR >& >(elt);
309 auto& super_attr = static_cast< const PRMAttribute< GUM_SCALAR >& >(super().get(name));
310 attr.copyCpf(*_bijection_, super_attr);
311 }
315 template < typename GUM_SCALAR >
318 _superClass_->_addExtension_(this);
319 // Adding implemented interfaces of c, if any
320 if (c._implements_) {
321 if (!_implements_) {
323 } else {
324 for (auto i: *(c._implements_)) {
325 _implements_->insert(i);
326 }
327 }
328 }
329
330 // Copying attributes, the bijection's firsts are attributes in this and
331 // its
332 // seconds are attributes
333 // in c.
335
336 // Copying parameters
337 for (const auto c_param: c._parameters_) {
338 auto param = new PRMParameter< GUM_SCALAR >(c_param->name(),
339 c_param->valueType(),
340 c_param->value());
341
342 _parameters_.insert(param);
343
344 param->setId(c_param->id());
345 _nodeIdMap_.insert(param->id(), param);
346 _nameMap_.insert(param->name(), param);
347 }
348
349 // Copying attributes
350 for (const auto c_attr: c._attributes_) {
351 // using multiDimSparse to prevent unecessary memory allocation for
352 // large arrays (the tensors are copied latter)
353 auto attr = c_attr->newFactory(*this);
354
355 bij.insert(&(c_attr->type().variable()), &(attr->type().variable()));
356 attr->setId(c_attr->id());
357 _nodeIdMap_.insert(attr->id(), attr);
358 _attributes_.insert(attr);
359
360 if (c._nameMap_[c_attr->name()] == c._nameMap_[c_attr->safeName()]) {
361 _nameMap_.insert(attr->name(), attr);
362 }
363
364 _nameMap_.insert(attr->safeName(), attr);
365 }
366
367 // Copying aggregates
368 for (const auto c_agg: c._aggregates_) {
369 PRMAggregate< GUM_SCALAR >* agg = nullptr;
370
371 try {
372 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(),
373 c_agg->agg_type(),
374 c_agg->type(),
375 c_agg->label());
376 } catch (OperationNotAllowed const&) {
377 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(), c_agg->agg_type(), c_agg->type());
378 }
380 bij.insert(&(c_agg->type().variable()), &(agg->type().variable()));
381 agg->setId(c_agg->id());
382 _nodeIdMap_.insert(agg->id(), agg);
383 _aggregates_.insert(agg);
384
385 if (c._nameMap_[c_agg->name()] == c._nameMap_[c_agg->safeName()])
386 _nameMap_.insert(agg->name(), agg);
387
388 _nameMap_.insert(agg->safeName(), agg);
389 }
390
391 // Copying reference slots
392 for (const auto c_refslot: c._referenceSlots_) {
394 c_refslot->name(),
395 const_cast< PRMClassElementContainer< GUM_SCALAR >& >(c_refslot->slotType()),
396 c_refslot->isArray());
397
398 ref->setId(c_refslot->id());
399 _nodeIdMap_.insert(ref->id(), ref);
400 _referenceSlots_.insert(ref);
401
402 if (c._nameMap_[c_refslot->name()] == c._nameMap_[c_refslot->safeName()])
403 _nameMap_.insert(ref->name(), ref);
404
405 _nameMap_.insert(ref->safeName(), ref);
406 }
407
408 // Copying slot chains
409 for (const auto c_slotchain: c._slotChains_) {
410 // We just need to change the first PRMReferenceSlot<GUM_SCALAR> in
411 // the
412 // chain
413 Sequence< PRMClassElement< GUM_SCALAR >* > chain(c_slotchain->chain());
415 chain.setAtPos(0, _nameMap_[c_slotchain->chain().front()->name()]);
416
418 = new PRMSlotChain< GUM_SCALAR >(c_slotchain->name(), chain);
419 bij.insert(&(c_slotchain->type().variable()), &(sc->type().variable()));
420 sc->setId(c_slotchain->id());
421 _nodeIdMap_.insert(sc->id(), sc);
422 _slotChains_.insert(sc);
424 _nameMap_.insert(sc->name(), sc);
425 _nameMap_.insert(sc->safeName(), sc);
427
428 // Copying dependencies yield by arcs
429 for (const auto& arc: c.containerDag().arcs()) {
430 _nodeIdMap_[arc.tail()]->addChild(*(_nodeIdMap_[arc.head()]));
431 _nodeIdMap_[arc.head()]->addParent(*(_nodeIdMap_[arc.tail()]));
432 }
434 // Copying the IO flag
435 this->copyIOFlags_(c);
436 // Copying content of CPF
437 for (const auto attr: c._attributes_) {
438 auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(_nameMap_[attr->safeName()]);
439 a->copyCpf(bij, *attr);
440 }
441 }
442 }
444 template < typename GUM_SCALAR >
447 switch (cec.obj_type()) {
449 const PRMClass< GUM_SCALAR >* current = this;
451 while (current != 0) {
452 if (current == &(cec)) return true;
453
454 current = current->_superClass_;
455 }
456
457 return false;
459
461 if (_implements_ != nullptr) {
463 = static_cast< const PRMInterface< GUM_SCALAR >& >(cec);
464
465 if (_implements_->exists(const_cast< PRMInterface< GUM_SCALAR >* >(&i))) return true;
466
467 for (const auto impl: *_implements_)
468 if (impl->isSubTypeOf(i)) return true;
469 }
470
471 return false;
472 }
473
474 default : {
475 GUM_ERROR(FatalError, "unknown ClassElementContainer<GUM_SCALAR>")
476 }
477 }
478 }
479
480 template < typename GUM_SCALAR >
481 void PRMClass< GUM_SCALAR >::addArc(const std::string& tail_name,
482 const std::string& head_name) {
485
486 try {
487 tail = _nameMap_[tail_name];
488 head = _nameMap_[head_name];
489 } catch (NotFound const&) {
490 GUM_ERROR(NotFound, "tail and/or head of arc does not exists in this Class")
491 }
492
496 "a PRMReferenceSlot<GUM_SCALAR> can "
497 "not on neither side of an arc");
498 }
499
503 "illegal insertion of an arc between two SlotChain<GUM_SCALAR>")
504 }
505
506 if (!_dag_.existsArc(Arc(tail->id(), head->id()))) {
507 _dag_.addArc(tail->id(), head->id());
508 } else {
509 GUM_ERROR(DuplicateElement, "duplicate arc " << tail_name << "->" << head_name)
510 }
511
512 get(tail->id()).addChild(get(head->id()));
513 get(head->id()).addParent(get(tail->id()));
514
515 // Defining input / output nodes
517 PRMSlotChain< GUM_SCALAR >* sc = static_cast< PRMSlotChain< GUM_SCALAR >* >(tail);
518 this->setInputNode(*head, true);
519 sc->end().setOutputNode(sc->end().get(sc->lastElt().safeName()), true);
520 }
521 }
522
523 template < typename GUM_SCALAR >
525 try {
526 for (auto i: implements()) {
527 if (i->exists(elt->name())) { _checkInterface_(elt, i); }
528 }
529 } catch (NotFound const&) {
530 // No interface
531 }
532 }
533
534 template < typename GUM_SCALAR >
537 const auto& i_elt = i->get(elt->name());
538 bool is_attr = PRMClassElement< GUM_SCALAR >::isAttribute(i_elt);
540
541 if (!(is_attr || is_agg)) {
542 GUM_ERROR(OperationNotAllowed, "Class does not respect it's interface")
543 }
544
545 if (!elt->type().isSubTypeOf(i_elt.type())) {
546 GUM_ERROR(OperationNotAllowed, "Attribute type does not respect class interface")
547 }
548
549 if (elt->type() != i_elt.type()) {
550 if (!this->exists(i_elt.safeName())) {
551 GUM_ERROR(OperationNotAllowed, "Attribute type does not respect class interface")
552 }
553 elt = &(this->get(i_elt.safeName()));
554 }
555
556 // Node must be reserved by constructor
557 if (!_dag_.existsNode(i_elt.id())) {
558 GUM_ERROR(FatalError, "Class does not reserved implemented nodes")
559 }
560
561 // Removing unused node and changing to proper node
562 if (elt->id() != i_elt.id()) {
563 // Update cast descendants
564 for (auto child: _dag_.children(elt->id())) {
565 _dag_.addArc(i_elt.id(), child);
566 }
567 _dag_.eraseNode(elt->id());
568 }
569 _nodeIdMap_.erase(elt->id());
570 elt->setId(i_elt.id());
571 _nodeIdMap_.insert(elt->id(), elt);
572 }
573
574 template < typename GUM_SCALAR >
576 try {
577 for (auto i: implements()) {
578 if (i->exists(ref->name())) { _checkRefInterface_(ref, i); }
579 }
580 } catch (NotFound const&) {
581 // No interface to check
582 }
583 }
584
585 template < typename GUM_SCALAR >
588 auto& i_elt = i->get(ref->name());
589 if (i_elt.elt_type() != ref->elt_type()) {
590 GUM_ERROR(OperationNotAllowed, "Class does not respect it's interface")
591 }
592 auto& i_ref = static_cast< PRMReferenceSlot< GUM_SCALAR >& >(i_elt);
593 if (!ref->slotType().isSubTypeOf(i_ref.slotType())) {
594 GUM_ERROR(OperationNotAllowed, "ReferenceSlot type does not respect class interface")
595 }
596 // Node must be reserved by constructor
597 if (!_dag_.exists(i_ref.id())) {
599 "class " << this->name() << " does not respect interface " << i->name()
600 << " implementation");
601 }
602 // Removing unused node and changin to propoer node
603 if (ref->id() != i_ref.id()) { _dag_.eraseNode(ref->id()); }
604 _nodeIdMap_.erase(ref->id());
605 ref->setId(i_ref.id());
606 _nodeIdMap_.insert(ref->id(), ref);
607 }
608
609 template < typename GUM_SCALAR >
611 if (_nameMap_.exists(elt->name())) {
613 "name " << elt->name() << " already used by another ClassElement");
614 }
615
616 elt->setId(nextNodeId());
617 _dag_.addNodeWithId(elt->id());
618 _nodeIdMap_.insert(elt->id(), elt);
619 _nameMap_.insert(elt->name(), elt);
620
621 try {
622 _nameMap_.insert(elt->safeName(), elt);
623 } catch (DuplicateElement& e) {
626 throw DuplicateElement(e);
627 }
628 }
629
630 switch (elt->elt_type()) {
632 _attributes_.insert(static_cast< PRMAttribute< GUM_SCALAR >* >(elt));
634
635 // Update attribute or cast descendant id to respect implemented
636 // interface
638
640 break;
641 }
642
644 _aggregates_.insert(static_cast< PRMAggregate< GUM_SCALAR >* >(elt));
646
647 // Update attribute or cast descendant id to respect implemented
648 // interface
650
652 break;
653 }
654
656 auto ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(elt);
657 _referenceSlots_.insert(ref);
658
659 // Updating ref's id if ref implements an interface
661 break;
662 }
663
665 _slotChains_.insert(static_cast< PRMSlotChain< GUM_SCALAR >* >(elt));
666 break;
667 }
668
670 _parameters_.insert(static_cast< PRMParameter< GUM_SCALAR >* >(elt));
671 break;
672 }
673
674 default : {
675 GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR> type")
676 }
677 }
678
679 return elt->id();
680 }
681
682 template < typename GUM_SCALAR >
684 auto parent = attr;
686
687 while (parent->type().isSubType()) {
688 child = parent->getCastDescendant();
689
690 // Check if id was reserved by one of the class interfaces
691 bool found = false;
692 try {
693 for (auto i: implements()) {
694 if (i->exists(child->safeName())) {
695 child->setId(i->get(child->safeName()).id());
696 found = true;
697 break;
698 }
699 }
700 } catch (NotFound const&) {
701 // No interface
702 }
703 if (!found) {
704 child->setId(nextNodeId());
705 _dag_.addNodeWithId(child->id());
706 }
707 _nodeIdMap_.insert(child->id(), child);
708 // Only use child's safe name when adding to the name map!
709 _nameMap_.insert(child->safeName(), child);
710 _attributes_.insert(child);
711 // Do not use Class<GUM_SCALAR>::insertArc(), child's CPF is already
712 // initialized properly
713 _dag_.addArc(parent->id(), child->id());
714
715 parent = child;
716 }
717 }
718
719 template < typename GUM_SCALAR >
721 try {
722 if (!super().exists(overloader->name())) {
723 GUM_ERROR(OperationNotAllowed, "found no ClassElement<GUM_SCALAR> to overload")
724 }
725 } catch (NotFound const&) {
726 GUM_ERROR(OperationNotAllowed, "overload is possible only with subclasses")
727 }
728
729 PRMClassElement< GUM_SCALAR >* overloaded = _nameMap_[overloader->name()];
730 if (overloaded == overloader) {
731 GUM_ERROR(DuplicateElement, "dupplicate ClassElement " << overloader->name())
732 }
733 // Checking overload legality
734 if (!_checkOverloadLegality_(overloaded, overloader)) {
735 GUM_ERROR(OperationNotAllowed, "illegal overload")
736 }
737
738 switch (overloader->elt_type()) {
740 auto overloader_attr = static_cast< PRMAttribute< GUM_SCALAR >* >(overloader);
741 auto overloaded_attr = static_cast< PRMAttribute< GUM_SCALAR >* >(overloaded);
742 _overloadAttribute_(overloader_attr, overloaded_attr);
743 _addIOInterfaceFlags_(overloader);
744 break;
745 }
746
748 _overloadAggregate_(static_cast< PRMAggregate< GUM_SCALAR >* >(overloader), overloaded);
749 _addIOInterfaceFlags_(overloader);
750 break;
751 }
752
754 // _checkOverloadLegality_ guaranties that overloaded is a
755 // PRMReferenceSlot<GUM_SCALAR>
756 auto overloader_ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloader);
757 auto overloaded_ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
758 _overloadReference_(overloader_ref, overloaded_ref);
759 break;
760 }
761
763 GUM_ERROR(OperationNotAllowed, "SlotChain<GUM_SCALAR> can not be overloaded")
764 break;
765 }
766
768 auto overloaded_param = static_cast< PRMParameter< GUM_SCALAR >* >(overloaded);
769 auto overloader_param = static_cast< PRMParameter< GUM_SCALAR >* >(overloader);
770 _overloadParameter_(overloader_param, overloaded_param);
771 break;
772 }
773 default : {
774 GUM_ERROR(OperationNotAllowed, "unknown ClassElement<GUM_SCALAR> type")
775 }
776 }
777
778 return overloader->id();
779 }
780
781 template < typename GUM_SCALAR >
783 PRMAttribute< GUM_SCALAR >* overloaded) {
784 _dag_.eraseParents(overloaded->id());
785
786 // Checking if we have to add cast descendant
787 if (overloader->type() != overloaded->type()) {
788 overloader->setId(nextNodeId());
789 _dag_.addNodeWithId(overloader->id());
790 _nodeIdMap_.insert(overloader->id(), overloader);
791 _nameMap_[overloader->name()] = overloader;
792 _nameMap_.insert(overloader->safeName(), overloader);
793 _attributes_.insert(overloader);
794 _addCastDescendants_(overloader, overloaded);
795 } else {
796 overloader->setId(overloaded->id());
797 _nodeIdMap_[overloader->id()] = overloader;
798 _nameMap_[overloader->name()] = overloader;
799 _nameMap_[overloader->safeName()] = overloader;
800 _attributes_.erase(overloaded);
801 _attributes_.insert(overloader);
802 overloader->overload(overloaded);
803 delete overloaded;
804 }
805 }
806
807 template < typename GUM_SCALAR >
809 PRMReferenceSlot< GUM_SCALAR >* overloaded) {
810 // Adding overloading reference
811 overloader->setId(overloaded->id());
812 _nodeIdMap_[overloader->id()] = overloader;
813 _nameMap_[overloader->name()] = overloader;
814 _nameMap_.insert(overloader->safeName(), overloader);
815 _referenceSlots_.insert(overloader);
819 std::vector< PRMSlotChain< GUM_SCALAR >* > toRemove, toAdd;
820
821 // Updating PRMSlotChain<GUM_SCALAR> which started with overloaded
822 for (const auto slotchain: _slotChains_) {
823 // If the attribute pointed by this slotchain is overloaded, we need to
824 // change the slotchain
825 // names to it's safename version: ref.attr is replaced by
826 // ref.(type)attr.
827 if ((slotchain->chain().atPos(0) == overloaded)) {
829 seq.insert(overloader);
830
831 auto elt = ++(slotchain->chain().begin());
832
833 while (elt != slotchain->chain().end()) {
834 ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(seq.back());
835 next = &(ref->slotType().get((*elt)->name()));
836 seq.insert(next);
837 ++elt;
838 }
839
840 // If the slotchain last element type changes, we change the slotchain
841 // to
842 // point towards the cast decendant
843 // with the correct type
844 if (seq.back()->type() != slotchain->lastElt().type()) {
845 seq.erase(seq.back());
846 seq.insert(&(static_cast< PRMReferenceSlot< GUM_SCALAR >* >(seq.back())
847 ->slotType()
848 .get(slotchain->lastElt().safeName())));
849 std::string sc_name;
850 std::string dot = ".";
851
852 for (Size i = 0; i < seq.size() - 1; ++i) {
853 sc_name += seq.atPos(i)->name() + dot;
854 }
855
856 sc_name += seq.back()->safeName();
857 sc = new PRMSlotChain< GUM_SCALAR >(sc_name, seq);
858 sc->setId(slotchain->id());
859
860 for (const auto child: this->containerDag().children(sc->id())) {
861 auto& elt = get(child);
863 auto& attr = static_cast< PRMAttribute< GUM_SCALAR >& >(elt);
864 auto& old_type = slotchain->lastElt().type();
865 auto& new_type = sc->lastElt().type();
866 attr.swap(old_type, new_type);
867 } else {
868 GUM_ERROR(OperationNotAllowed, "unexpected ClassElement")
869 // get( child ).cpf().replace(
870 // slotchain->lastElt().type().variable(),
871 // sc->lastElt().type().variable() );
872 }
873 }
874
875 toAdd.push_back(sc);
876 toRemove.push_back(slotchain);
877 } else {
878 // Types are identical, we just need to change the first reference
879 slotchain->chain().setAtPos(0, overloader);
880 }
881 }
882 }
883
884 for (const auto torem: toRemove) {
885 _nameMap_.erase(torem->name());
886 _slotChains_.erase(torem);
887 delete torem;
888 }
889
890 for (const auto toadd: toAdd) {
891 _nameMap_.insert(toadd->name(), toadd);
892 _nodeIdMap_[toadd->id()] = toadd;
893 _slotChains_.insert(sc);
894 }
895
896 // Removing overloaded PRMReferenceSlot<GUM_SCALAR>
897 _referenceSlots_.erase(overloaded);
898 _nameMap_.erase(overloaded->safeName());
899 delete overloaded;
900 }
901
902 template < typename GUM_SCALAR >
904 PRMParameter< GUM_SCALAR >* overloaded) {
905 overloader->setId(overloaded->id());
906 _nodeIdMap_[overloader->id()] = overloader;
907 _nameMap_[overloader->name()] = overloader;
908 _nameMap_[overloader->safeName()] = overloader;
909 _parameters_.erase(overloaded);
910 _parameters_.insert(overloader);
911 delete overloaded;
912 }
913
914 template < typename GUM_SCALAR >
917 PRMAttribute< GUM_SCALAR >* parent = start;
919
920 while (parent->type().superType() != end->type()) {
921 child = parent->getCastDescendant();
922 child->setId(nextNodeId());
923 _nodeIdMap_.insert(child->id(), child);
924 _dag_.addNodeWithId(child->id());
925 // Only use child's safe name when adding to the name map!
926 _nameMap_.insert(child->safeName(), child);
927 _attributes_.insert(child);
929 // Do not use Class<GUM_SCALAR>::insertArc(), child's CPF is already
930 // initialized properly
931 _dag_.addArc(parent->id(), child->id());
932 parent = child;
933 }
934
935 parent->setAsCastDescendant(end);
936 _dag_.addArc(parent->id(), end->id());
937 }
938
939 template < typename GUM_SCALAR >
942 for (auto ext: _extensions_) {
943 set.insert(ext);
944 ext->findAllSubtypes_(set);
945 }
946 }
947
948 template < typename GUM_SCALAR >
950 // We only add IO Flags if elt matches is required by and interface
951 if (_implements_ != nullptr) {
952 for (const auto impl: *_implements_) {
954 while (super) {
955 // If the attribute is defined in an interface, we set it as an
956 // OutputNode
957 if (impl->exists(elt->name())) {
958 try {
959 this->getIOFlag_(*elt).second = true;
960 } catch (NotFound const&) { this->setIOFlag_(*elt, std::make_pair(false, true)); }
961 }
962 try {
963 super = &(super->super());
964 } catch (NotFound const&) { super = nullptr; }
965 }
966 }
967 }
968 }
969
970 template < typename GUM_SCALAR >
972 // for ( const auto ext : _extensions_ ) {
973 // // We test to prevent unnecessary recursive call from iter
974 // if ( !ext->isOutputNode( elt ) ) {
975 // ext->setOutputNode( elt, true );
976 // }
977 //}
978 }
979
980 template < typename GUM_SCALAR >
984
985 template < typename GUM_SCALAR >
986 INLINE const DAG& PRMClass< GUM_SCALAR >::dag_() const {
987 return _dag_;
988 }
989
990 template < typename GUM_SCALAR >
992 return _dag_;
993 }
994
995 template < typename GUM_SCALAR >
997 try {
998 return *(_nodeIdMap_[id]);
999 } catch (NotFound const&) {
1000 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId")
1001 }
1002 }
1003
1004 template < typename GUM_SCALAR >
1006 try {
1007 return *(_nodeIdMap_[id]);
1008 } catch (NotFound const&) {
1009 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId (" << id << ")");
1010 }
1011 }
1012
1013 template < typename GUM_SCALAR >
1015 try {
1016 return *(_nameMap_[name]);
1017 } catch (NotFound const&) {
1018 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name (" << name << ")");
1019 }
1020 }
1021
1022 template < typename GUM_SCALAR >
1023 INLINE const PRMClassElement< GUM_SCALAR >&
1024 PRMClass< GUM_SCALAR >::get(const std::string& name) const {
1025 try {
1026 return *(_nameMap_[name]);
1027 } catch (NotFound const&) {
1028 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name (" << name << ")");
1029 }
1030 }
1031
1032 template < typename GUM_SCALAR >
1036
1037 template < typename GUM_SCALAR >
1041
1042 // Private struct for retrieving all params in scope
1043 template < typename GUM_SCALAR >
1045 std::string prefix;
1048
1049 ParamScopeData(const std::string& s, const PRMReferenceSlot< GUM_SCALAR >& ref, Idx d) :
1050 prefix(s + ref.name() + "."),
1051 c(static_cast< const PRMClass< GUM_SCALAR >* >(&(ref.slotType()))), depth(d) {}
1052 };
1053
1054 template < typename GUM_SCALAR >
1058
1059 for (const auto p: parameters()) {
1060 params.insert(p->name(), p);
1061 }
1062
1063 std::queue< ParamScopeData< GUM_SCALAR > > queue;
1064
1065 for (const auto ref: referenceSlots()) {
1066 if (PRMObject::isClass(ref->slotType())) {
1067 queue.push(ParamScopeData< GUM_SCALAR >("", *ref, 1));
1068 }
1069 }
1070
1071 while (!queue.empty()) {
1072 auto data = queue.front();
1073 queue.pop();
1074
1075 if (data.depth < 5) {
1076 for (const auto p: data.c->parameters()) {
1077 params.insert(data.prefix + p->name(), p);
1078 }
1079
1080 for (const auto ref: data.c->referenceSlots()) {
1081 if (PRMObject::isClass(ref->slotType())) {
1082 queue.push(ParamScopeData< GUM_SCALAR >(data.prefix, *ref, data.depth + 1));
1083 }
1084 }
1085 } else {
1086 // @todo depth>5 is a workaround. Cycle detection is needed here !
1087 GUM_ERROR(FatalError, "Depth limit reached when looking up parameters")
1088 }
1089 }
1090
1091 return params;
1092 }
1093
1094 template < typename GUM_SCALAR >
1098
1099 template < typename GUM_SCALAR >
1104
1105 template < typename GUM_SCALAR >
1109
1110 template < typename GUM_SCALAR >
1112 if (_superClass_) {
1113 return *_superClass_;
1114 } else {
1115 GUM_ERROR(NotFound, "this Class is not a subclass")
1116 }
1117 }
1118
1119 template < typename GUM_SCALAR >
1121 if (_implements_) {
1122 return *_implements_;
1123 } else {
1124 GUM_ERROR(NotFound, "this Class does not implement any Interface<GUM_SCALAR>")
1125 }
1126 }
1127
1128 template < typename GUM_SCALAR >
1132
1133 template < typename GUM_SCALAR >
1134 INLINE const PRMClassElement< GUM_SCALAR >&
1136 return get(id);
1137 }
1138
1139 template < typename GUM_SCALAR >
1142 return get(name);
1143 }
1144
1145 template < typename GUM_SCALAR >
1146 INLINE const PRMClassElement< GUM_SCALAR >&
1147 PRMClass< GUM_SCALAR >::operator[](const std::string& name) const {
1148 return get(name);
1149 }
1150
1151 template < typename GUM_SCALAR >
1152 INLINE void
1154 PRMClassElement< GUM_SCALAR >* overloaded) {
1155 _nameMap_.insert(overloader->safeName(), overloader);
1156 _aggregates_.insert(overloader);
1157 }
1158
1159 template < typename GUM_SCALAR >
1161 const PRMClassElement< GUM_SCALAR >* overloaded,
1162 const PRMClassElement< GUM_SCALAR >* overloader) {
1163 if (overloaded->elt_type() != overloader->elt_type()) { return false; }
1164
1165 switch (overloaded->elt_type()) {
1167 if (!overloader->type().isSubTypeOf(overloaded->type())) { return false; }
1168 break;
1169 }
1170
1172 const auto& new_slot_type
1173 = static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloader)->slotType();
1174 const auto& old_slot_type
1175 = static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloaded)->slotType();
1176
1177 if (!new_slot_type.isSubTypeOf(old_slot_type)) { return false; }
1178
1179 break;
1180 }
1181
1183 auto overloaded_param = static_cast< const PRMParameter< GUM_SCALAR >* >(overloaded);
1184 auto overloader_param = static_cast< const PRMParameter< GUM_SCALAR >* >(overloader);
1185
1186 return overloaded_param->valueType() == overloader_param->valueType();
1187 break;
1188 }
1189
1190 default : {
1191 return false;
1192 }
1193 }
1194 return true;
1195 }
1196
1197 template < typename GUM_SCALAR >
1201
1202 template < typename GUM_SCALAR >
1206
1207 template < typename GUM_SCALAR >
1208 INLINE bool PRMClass< GUM_SCALAR >::isCastDescendant(const std::string& safe_name) const {
1209 const PRMClassElement< GUM_SCALAR >& elt = get(safe_name);
1210
1211 try {
1212 return elt.type().name() == get(elt.name()).type().name();
1213 } catch (OperationNotAllowed const&) {
1214 GUM_ERROR(NotFound, "no attribute with the given name")
1215 }
1216 }
1217
1218 template < typename GUM_SCALAR >
1219 INLINE bool
1221 try {
1222 if (!this->getIOFlag_(elt).second) {
1223 if (_implements_) {
1224 for (auto i: *_implements_) {
1225 if (i->isOutputNode(elt)) { return true; }
1226 }
1227 }
1228
1229 if (_superClass_ && (_superClass_->isOutputNode(elt))) { return true; }
1230
1231 } else {
1232 return true;
1233 }
1234 } catch (NotFound const&) {}
1235 return false;
1236 }
1237
1238
1239 } /* namespace prm */
1240} /* namespace gum */
Headers of gum::prm::Class<GUM_SCALAR>.
Headers of gum::prm::PRMInterface.
const ArcSet & arcs() const
returns the set of arcs stored within the ArcGraphPart
The base class for all directed edges.
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
Set of pairs of elements with fast search for both elements.
Definition bijection.h:1594
Base class for dag.
Definition DAG.h:121
Base class for discrete random variable.
Exception : a similar element already exists.
Base class for all aGrUM's exceptions.
Definition exceptions.h:118
Exception : fatal (unknown ?) error.
The class for generic Hash Tables.
Definition hashTable.h:637
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
Defines an aggregate in a PRM.
void erase(const Key &k)
Remove an element from the sequence.
Size size() const noexcept
Returns the size of the sequence.
const Key & back() const
Returns the last element of the sequence.
const Key & atPos(Idx i) const
Returns the object at the pos i.
void insert(const Key &k)
Insert an element at the end of the sequence.
The generic class for storing (ordered) sequences of objects.
Definition sequence.h:972
Representation of a set.
Definition set.h:131
virtual PRMType & type()
See gum::PRMClassElement::type().
std::shared_ptr< Idx > sharedLabel() const
Returns the shared_ptr holding this Aggregate label.
void setLabel(Idx idx)
Set the aggregator's label.
PRMAttribute is a member of a Class in a PRM.
virtual void overload(PRMAttribute< GUM_SCALAR > *source)
Set this as overload of source (necessayr to preserver internal pointers for MultiDims).
virtual void copyCpf(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bif, const PRMAttribute< GUM_SCALAR > &source)=0
See gum::PRMClassElement::elt_type().
virtual void setAsCastDescendant(PRMAttribute< GUM_SCALAR > *attr)=0
Define attr as a cast descendant of this PRMAttribute.
virtual PRMAttribute< GUM_SCALAR > * getCastDescendant() const =0
Returns a proper cast descendant of this PRMAttribute.
virtual PRMType & type()=0
See gum::PRMClassElement::type().
<agrum/PRM/classElementContainer.h>
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
virtual std::pair< bool, bool > & getIOFlag_(const PRMClassElement< GUM_SCALAR > &elt)
Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
virtual void copyIOFlags_(const PRMClassElementContainer< double > &c)
virtual void setIOFlag_(const PRMClassElement< GUM_SCALAR > &elt, const std::pair< bool, bool > &flags)
Defines the IO flags of a PRMClassElement<GUM_SCALAR>.
PRMClassElementContainer(const std::string &name)
Default constructor.
virtual bool exists(const std::string &name) const
Returns true if a member with the given name exists in this PRMClassElementContainer or in the PRMCla...
virtual void setInputNode(const PRMClassElement< GUM_SCALAR > &elt, bool b)
Set the input flag value of id at b.
Abstract class representing an element of PRM class.
static INLINE bool isParameter(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMParameter.
static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMSlotChain.
static INLINE bool isAggregate(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMAggregate.
virtual void setId(NodeId id)
Used to assign the id of this element.
NodeId id() const
Returns the NodeId of this element in it's class DAG.
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.
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
static INLINE bool isAttribute(const PRMClassElement< GUM_SCALAR > &elt)
Returns true if obj_ptr is of type PRMAttribute.
A PRMClass is an object of a PRM representing a fragment of a Bayesian network which can be instantia...
Definition PRMClass.h:75
void _addExtension_(PRMClass< GUM_SCALAR > *c)
This method is called when a sub-Class<GUM_SCALAR> of this Class<GUM_SCALAR> is created.
Set< PRMReferenceSlot< GUM_SCALAR > * > _referenceSlots_
The sequence of PRMReferenceSlot<GUM_SCALAR>.
Definition PRMClass.h:367
void _overloadReference_(PRMReferenceSlot< GUM_SCALAR > *overloader, PRMReferenceSlot< GUM_SCALAR > *overloaded)
Overloads a reference slot.
bool _checkOverloadLegality_(const PRMClassElement< GUM_SCALAR > *overloaded, const PRMClassElement< GUM_SCALAR > *overloader)
Return true of overloaded can be overload by overloader.
const Set< PRMReferenceSlot< GUM_SCALAR > * > & referenceSlots() const
Returns the set of PRMReferenceSlot<GUM_SCALAR> of this Class<GUM_SCALAR>.
virtual bool isSubTypeOf(const PRMClassElementContainer< GUM_SCALAR > &cec) const
Test if this Class<GUM_SCALAR> is a subclass of cec.
PRMClass< GUM_SCALAR > * _superClass_
The alternate PRMClassElementContainer<GUM_SCALAR> searched for elements defined in this....
Definition PRMClass.h:395
virtual void addArc(const std::string &tail, const std::string &head)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::addArc().
void _addCastDescendants_(PRMClassElement< GUM_SCALAR > *attr)
Recursively adds cast descendant of attr in this Class<GUM_SCALAR>.
void _checkInterfaces_(PRMClassElement< GUM_SCALAR > *elt)
Check that a given element respects all the class interfaces.
PRMClass(const std::string &name)
Default constructor.
void _overloadAggregate_(PRMAggregate< GUM_SCALAR > *overloader, PRMClassElement< GUM_SCALAR > *overloaded)
Overloads an aggregate.
void findAllSubtypes_(Set< PRMClassElementContainer< GUM_SCALAR > * > &set)
Fills set with all the subtypes of this Class<GUM_SCALAR>.
Bijection< const DiscreteVariable *, const DiscreteVariable * > * _bijection_
The bijection between variables in super and variables in this The bijection's firsts are attributes ...
Definition PRMClass.h:407
Set< PRMSlotChain< double > * > _slotChains_
Definition PRMClass.h:373
void _checkInterface_(PRMClassElement< GUM_SCALAR > *elt, PRMInterface< GUM_SCALAR > *i)
Check that a given element respects a specific interface.
virtual ~PRMClass()
Destructor.
virtual PRMObject::prm_type obj_type() const
Implementation of pure virtual method of PRMObject.
PRMClassElement< GUM_SCALAR > & get(NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
void _implementInterfaces_(bool delayInheritance)
Proceed with the implementation of interfaces.
DAG _dag_
The dag representing dependencies between formal attributes and slots.
Definition PRMClass.h:347
void _checkRefInterface_(PRMReferenceSlot< GUM_SCALAR > *elt, PRMInterface< GUM_SCALAR > *i)
Check that a given element respects a specific interface.
virtual const DAG & dag_() const
returns a constant reference over this interface's dag.
NodeProperty< PRMClassElement< GUM_SCALAR > * > _nodeIdMap_
Mapping between node's id and their name (being an attribute or a slot). Used for fast access to a me...
Definition PRMClass.h:351
Set< PRMAggregate< GUM_SCALAR > * > _aggregates_
The sequence of aggregate.
Definition PRMClass.h:370
void _overloadParameter_(PRMParameter< GUM_SCALAR > *overloader, PRMParameter< GUM_SCALAR > *overloaded)
Overloads a parameter.
const Set< PRMParameter< GUM_SCALAR > * > & parameters() const
Returns the set of parameters of this Class<GUM_SCALAR>.
void _inheritClass_(const PRMClass< GUM_SCALAR > &c)
Proceed with the copy when this inherits c.
const Set< PRMClass< GUM_SCALAR > * > & extensions() const
Returns the set of Class<GUM_SCALAR> which are direct sub-Class<GUM_SCALAR> of this Class<GUM_SCALAR>...
const Set< PRMAttribute< GUM_SCALAR > * > & attributes() const
Returns the set of PRMAttribute<GUM_SCALAR> of this Class<GUM_SCALAR>.
HashTable< std::string, const PRMParameter< GUM_SCALAR > * > scope() const
Returns all the parameters in the scope of this class.
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::add(PRMClassElement<GUM_SCALAR>*).
virtual bool isOutputNode(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if elt is an output node.
Set< PRMParameter< double > * > _parameters_
Definition PRMClass.h:376
PRMClassElement< GUM_SCALAR > & operator[](NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::operator[](NodeId).
void _addIOInterfaceFlags_(PRMClassElement< GUM_SCALAR > *elt)
Check if elt is present in an implementation. If it is, its IO flags are updated.
Set< PRMClass< GUM_SCALAR > * > _extensions_
The set of Class<GUM_SCALAR> which are extension of this Class<GUM_SCALAR> (i.e. direct subtypes).
Definition PRMClass.h:402
HashTable< std::string, PRMClassElement< double > * > _nameMap_
Definition PRMClass.h:361
friend class PRMInterface< GUM_SCALAR >
Definition PRMClass.h:76
const Set< PRMAggregate< GUM_SCALAR > * > & aggregates() const
Returns the set of PRMAggregate<GUM_SCALAR> of this Class<GUM_SCALAR>.
void completeInheritance(const std::string &attr)
const Set< PRMInterface< GUM_SCALAR > * > & implements() const
Returns the Set of PRMInterface<GUM_SCALAR> implemented by this Class<GUM_SCALAR>.
const Set< PRMSlotChain< GUM_SCALAR > * > & slotChains() const
Returns the set of PRMSlotChain<GUM_SCALAR> of this Class<GUM_SCALAR>.
void _overloadAttribute_(PRMAttribute< GUM_SCALAR > *overloader, PRMAttribute< GUM_SCALAR > *overloaded)
Overloads an attribute.
const PRMClass< GUM_SCALAR > & super() const
Returns the super Class<GUM_SCALAR> of this Class<GUM_SCALAR>.
Set< PRMAttribute< GUM_SCALAR > * > _attributes_
The sequence of PRMAttribute<GUM_SCALAR>s.
Definition PRMClass.h:364
void updateDescendants_(const PRMClassElement< GUM_SCALAR > &elt)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>(constPRMClassElement<GUM_SCALAR>&).
virtual NodeId overload(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::overload(PRMClassElement<GUM_SCALAR>*).
void _checkRefInterfaces_(PRMReferenceSlot< GUM_SCALAR > *elt)
Check that a given element respects all the class interfaces.
Set< PRMInterface< GUM_SCALAR > * > * _implements_
The Set of implemented interface of this.
Definition PRMClass.h:398
bool isCastDescendant(const std::string &safe_name) const
Return true if the attribute named safe_name is a cast descendant.
An PRMInterface is implemented by a Class<GUM_SCALAR> and defines a set of PRMReferenceSlot<GUM_SCALA...
virtual PRMClassElement< GUM_SCALAR > & get(NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
const std::string & name() const
Returns the name of this object.
prm_type
Enumeration of the different types of objects handled by a PRM.
Definition PRMObject.h:88
static INLINE bool isClass(const PRMObject &obj)
Returns true if obj_ptr is of type Class.
Definition PRMObject.h:114
virtual prm_type obj_type() const =0
Returns the type of this object.
PRMParameter is a member of a Class in a PRM.
ParameterType valueType() const
See gum::PRMClassElement::elt_type().
A PRMReferenceSlot represent a relation between two PRMClassElementContainer.
PRMClassElementContainer< GUM_SCALAR > & slotType()
Returns the type of this slot, which is a PRMClassElementContainer (it is not the type of PRMObject).
virtual PRMClassElement< GUM_SCALAR >::ClassElementType elt_type() const
Implementation of the pure virtual method of PRMObject.
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
PRMClassElementContainer< GUM_SCALAR > & end()
Returns the PRMClassElement<GUM_SCALAR>Container over which this slot chain ends.
PRMClassElement< GUM_SCALAR > & lastElt()
Returns the last element of the slot chain, typically this is an gum::PRMAttribute or a gum::PRMAggre...
virtual PRMType & type()
This is similar to the following call: this->lastElt().type().
PRMType & superType()
Returns the super type of this type.
Definition PRMType_inl.h:56
bool isSubTypeOf(const PRMType &super) const
Returns true if this is a subtype of super.
Definition PRMType.cpp:116
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition PRMType_inl.h:64
const std::string & name() const
Returns the name of this object.
Definition PRMType_inl.h:78
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
Size NodeId
Type for node ids.
namespace for all probabilistic relational models entities
Definition agrum.h:68
NodeId nextNodeId()
Returns the next value of an unique counter for PRM's node id.
Definition utils_prm.cpp:84
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
const PRMClass< GUM_SCALAR > * c
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)