aGrUM 3.1.1
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-2026 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-2026 *
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
41#pragma once
42
43
50
51// to ease parsing
52#include <queue>
53
56
57namespace gum {
58 namespace prm {
59 template < GUM_Numeric GUM_SCALAR >
61 PRMClassElementContainer< GUM_SCALAR >(name), _superClass_(nullptr), _implements_(nullptr),
62 _bijection_(nullptr) {
63 GUM_CONSTRUCTOR(PRMClass);
64 }
65
66 template < GUM_Numeric GUM_SCALAR >
69 bool delayInheritance) :
72 GUM_CONSTRUCTOR(PRMClass);
73 if (!delayInheritance) {
74 _dag_ = super.containerDag();
76 }
77 }
78
79 template < GUM_Numeric GUM_SCALAR >
81 const Set< PRMInterface< GUM_SCALAR >* >& set,
82 bool delayInheritance) :
83 PRMClassElementContainer< GUM_SCALAR >(name), _superClass_(nullptr),
84 _implements_(new Set< PRMInterface< GUM_SCALAR >* >(set)), _bijection_(nullptr) {
85 GUM_CONSTRUCTOR(PRMClass);
86
87 if (!delayInheritance) { _implementInterfaces_(false); }
88 }
89
90 template < GUM_Numeric GUM_SCALAR >
93 const Set< PRMInterface< GUM_SCALAR >* >& set,
94 bool delayInheritance) :
97 GUM_CONSTRUCTOR(PRMClass);
98 if (!delayInheritance) {
99 _dag_ = super.containerDag();
101 }
102
103 // Adding other implementation
104 if (_implements_ == nullptr) { // super has not created _implements_
106 } else { // we just add the new implementations
107 for (const auto elt: set) {
108 _implements_->insert(elt);
109 }
110 }
111
112 if (!delayInheritance) { _implementInterfaces_(false); }
113 }
114
115 template < GUM_Numeric GUM_SCALAR >
116 void PRMClass< GUM_SCALAR >::_implementInterfaces_(bool delayedInheritance) {
117 for (const auto impl: *_implements_) {
118 impl->_addImplementation_(this);
119 if ((!_superClass_) || (!super().isSubTypeOf(*impl)) || delayedInheritance) {
120 // Reserve reference id in DAG
121 for (auto ref: impl->referenceSlots()) {
122 _dag_.addNodeWithId(ref->id());
123 }
124 // Reserve attribute id in DAG
125 for (auto attr: impl->attributes()) {
126 _dag_.addNodeWithId(attr->id());
127 }
128 }
129 }
130 }
131
132 template < GUM_Numeric GUM_SCALAR >
134 GUM_DESTRUCTOR(PRMClass);
135
136 for (const auto& elt: _nodeIdMap_) {
137 delete elt.second;
138 }
139
140 if (_implements_) { delete _implements_; }
141
142 if (_bijection_) { delete _bijection_; }
143 }
144
145 template < GUM_Numeric GUM_SCALAR >
147 if (_superClass_) {
148 _superClass_->_addExtension_(this);
149 // Adding implemented interfaces, if any
150 if (_superClass_->_implements_) {
151 if (!_implements_) {
153 } else {
154 for (auto i: *(_superClass_->_implements_)) {
155 _implements_->insert(i);
156 }
157 }
158 }
159 }
160 if (_implements_) { _implementInterfaces_(true); }
161 }
162
163 template < GUM_Numeric GUM_SCALAR >
165 if (_superClass_) {
166 // Copying reference slots
167 for (const auto c_refslot: _superClass_->_referenceSlots_) {
168 auto ref = new PRMReferenceSlot< GUM_SCALAR >(
169 c_refslot->name(),
170 const_cast< PRMClassElementContainer< GUM_SCALAR >& >(c_refslot->slotType()),
171 c_refslot->isArray());
172
173 ref->setId(c_refslot->id());
174 // Not reserved by an interface
175 if (!_dag_.existsNode(ref->id())) { _dag_.addNodeWithId(ref->id()); }
176 _nodeIdMap_.insert(ref->id(), ref);
177 _referenceSlots_.insert(ref);
178
179 if (_superClass_->_nameMap_[c_refslot->name()]
180 == _superClass_->_nameMap_[c_refslot->safeName()]) {
181 _nameMap_.insert(ref->name(), ref);
182 }
183
184 _nameMap_.insert(ref->safeName(), ref);
185 }
186 }
187 }
188
189 template < GUM_Numeric GUM_SCALAR >
191 if (_superClass_) {
192 // Copying parameters
193 for (const auto c_param: _superClass_->_parameters_) {
194 auto param = new PRMParameter< GUM_SCALAR >(c_param->name(),
195 c_param->valueType(),
196 c_param->value());
197
198 _parameters_.insert(param);
199
200 param->setId(c_param->id());
201 _dag_.addNodeWithId(param->id());
202 _nodeIdMap_.insert(param->id(), param);
203 _nameMap_.insert(param->name(), param);
204 }
205 }
206 }
207
208 template < GUM_Numeric GUM_SCALAR >
210 if (_superClass_) {
211 for (const auto c_attr: _superClass_->_attributes_) {
212 // using multiDimSparse to prevent unecessary memory allocation for
213 // large arrays (the tensors are copied latter)
214 auto attr = c_attr->newFactory(*this);
215
216 _bijection_->insert(&(c_attr->type().variable()), &(attr->type().variable()));
217 attr->setId(c_attr->id());
218 try {
219 _dag_.addNodeWithId(attr->id());
220 } catch (gum::Exception&) {
221 // Node reserved by an interface
222 }
223 _nodeIdMap_.insert(attr->id(), attr);
224 _attributes_.insert(attr);
225
226 if (_superClass_->_nameMap_[c_attr->name()]
227 == _superClass_->_nameMap_[c_attr->safeName()]) {
228 _nameMap_.insert(attr->name(), attr);
229 }
230
231 _nameMap_.insert(attr->safeName(), attr);
232 }
233 }
234 }
235
236 template < GUM_Numeric GUM_SCALAR >
238 if (_superClass_) {
239 for (const auto c_agg: _superClass_->_aggregates_) {
240 PRMAggregate< GUM_SCALAR >* agg = nullptr;
241
242 try {
243 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(),
244 c_agg->agg_type(),
245 c_agg->type(),
246 c_agg->label());
247 } catch (OperationNotAllowed const&) {
248 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(), c_agg->agg_type(), c_agg->type());
249 agg->sharedLabel(c_agg->sharedLabel());
250 agg->setLabel(c_agg->labelValue());
251 }
252
253 _bijection_->insert(&(c_agg->type().variable()), &(agg->type().variable()));
254 agg->setId(c_agg->id());
255 _dag_.addNodeWithId(agg->id());
256 _nodeIdMap_.insert(agg->id(), agg);
257 _aggregates_.insert(agg);
258
259 if (_superClass_->_nameMap_[c_agg->name()] == _superClass_->_nameMap_[c_agg->safeName()])
260 _nameMap_.insert(agg->name(), agg);
261
262 _nameMap_.insert(agg->safeName(), agg);
263 }
264 }
265 }
266
267 template < GUM_Numeric GUM_SCALAR >
269 if (_superClass_) {
270 // Copying slot chains
271 for (const auto c_sc: _superClass_->_slotChains_) {
272 // Because of aggregators, some slotchains may exists already
273 if (!(_nameMap_.exists(c_sc->name()) && _nameMap_.exists(c_sc->safeName()))) {
274 // We just need to change the first PRMReferenceSlot<GUM_SCALAR> in
275 // the
276 // chain
277 auto chain = c_sc->chain();
278
279 chain.setAtPos(0, _nameMap_[c_sc->chain().front()->name()]);
280
281 auto sc = new PRMSlotChain< GUM_SCALAR >(c_sc->name(), chain);
282 _bijection_->insert(&(c_sc->type().variable()), &(sc->type().variable()));
283 sc->setId(c_sc->id());
284 _dag_.addNodeWithId(sc->id());
285 _nodeIdMap_.insert(sc->id(), sc);
286 _slotChains_.insert(sc);
287
288 if (!_nameMap_.exists(sc->name())) { _nameMap_.insert(sc->name(), sc); }
289 if (!_nameMap_.exists(sc->safeName())) { _nameMap_.insert(sc->safeName(), sc); }
290 }
291 }
292 }
293 }
294
295 template < GUM_Numeric GUM_SCALAR >
297 if (_superClass_) {
298 auto& elt = this->get(name);
301 GUM_ERROR(OperationNotAllowed, "you can only complete inheritance for attributes")
302 }
303
304 for (const auto& prnt: super().containerDag().parents(elt.id())) {
305 this->addArc(super().get(prnt).safeName(), elt.safeName());
306 }
307
309 auto& attr = static_cast< PRMAttribute< GUM_SCALAR >& >(elt);
310 auto& super_attr = static_cast< const PRMAttribute< GUM_SCALAR >& >(super().get(name));
311 attr.copyCpf(*_bijection_, super_attr);
312 }
313 }
314 }
315
316 template < GUM_Numeric GUM_SCALAR >
318 if (_superClass_) {
319 _superClass_->_addExtension_(this);
320 // Adding implemented interfaces of c, if any
321 if (c._implements_) {
322 if (!_implements_) {
324 } else {
325 for (auto i: *(c._implements_)) {
326 _implements_->insert(i);
327 }
328 }
329 }
330
331 // Copying attributes, the bijection's firsts are attributes in this and
332 // its
333 // seconds are attributes
334 // in c.
336
337 // Copying parameters
338 for (const auto c_param: c._parameters_) {
339 auto param = new PRMParameter< GUM_SCALAR >(c_param->name(),
340 c_param->valueType(),
341 c_param->value());
342
343 _parameters_.insert(param);
344
345 param->setId(c_param->id());
346 _nodeIdMap_.insert(param->id(), param);
347 _nameMap_.insert(param->name(), param);
348 }
349
350 // Copying attributes
351 for (const auto c_attr: c._attributes_) {
352 // using multiDimSparse to prevent unecessary memory allocation for
353 // large arrays (the tensors are copied latter)
354 auto attr = c_attr->newFactory(*this);
355
356 bij.insert(&(c_attr->type().variable()), &(attr->type().variable()));
357 attr->setId(c_attr->id());
358 _nodeIdMap_.insert(attr->id(), attr);
359 _attributes_.insert(attr);
360
361 if (c._nameMap_[c_attr->name()] == c._nameMap_[c_attr->safeName()]) {
362 _nameMap_.insert(attr->name(), attr);
363 }
364
365 _nameMap_.insert(attr->safeName(), attr);
366 }
367
368 // Copying aggregates
369 for (const auto c_agg: c._aggregates_) {
370 PRMAggregate< GUM_SCALAR >* agg = nullptr;
371
372 try {
373 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(),
374 c_agg->agg_type(),
375 c_agg->type(),
376 c_agg->label());
377 } catch (OperationNotAllowed const&) {
378 agg = new PRMAggregate< GUM_SCALAR >(c_agg->name(), c_agg->agg_type(), c_agg->type());
379 }
380
381 bij.insert(&(c_agg->type().variable()), &(agg->type().variable()));
382 agg->setId(c_agg->id());
383 _nodeIdMap_.insert(agg->id(), agg);
384 _aggregates_.insert(agg);
385
386 if (c._nameMap_[c_agg->name()] == c._nameMap_[c_agg->safeName()])
387 _nameMap_.insert(agg->name(), agg);
388
389 _nameMap_.insert(agg->safeName(), agg);
390 }
391
392 // Copying reference slots
393 for (const auto c_refslot: c._referenceSlots_) {
395 c_refslot->name(),
396 const_cast< PRMClassElementContainer< GUM_SCALAR >& >(c_refslot->slotType()),
397 c_refslot->isArray());
398
399 ref->setId(c_refslot->id());
400 _nodeIdMap_.insert(ref->id(), ref);
401 _referenceSlots_.insert(ref);
402
403 if (c._nameMap_[c_refslot->name()] == c._nameMap_[c_refslot->safeName()])
404 _nameMap_.insert(ref->name(), ref);
405
406 _nameMap_.insert(ref->safeName(), ref);
407 }
408
409 // Copying slot chains
410 for (const auto c_slotchain: c._slotChains_) {
411 // We just need to change the first PRMReferenceSlot<GUM_SCALAR> in
412 // the
413 // chain
414 Sequence< PRMClassElement< GUM_SCALAR >* > chain(c_slotchain->chain());
415
416 chain.setAtPos(0, _nameMap_[c_slotchain->chain().front()->name()]);
417
419 = new PRMSlotChain< GUM_SCALAR >(c_slotchain->name(), chain);
420 bij.insert(&(c_slotchain->type().variable()), &(sc->type().variable()));
421 sc->setId(c_slotchain->id());
422 _nodeIdMap_.insert(sc->id(), sc);
423 _slotChains_.insert(sc);
424
425 _nameMap_.insert(sc->name(), sc);
426 _nameMap_.insert(sc->safeName(), sc);
427 }
428
429 // Copying dependencies yield by arcs
430 for (const auto& arc: c.containerDag().arcs()) {
431 _nodeIdMap_[arc.tail()]->addChild(*(_nodeIdMap_[arc.head()]));
432 _nodeIdMap_[arc.head()]->addParent(*(_nodeIdMap_[arc.tail()]));
433 }
434
435 // Copying the IO flag
436 this->copyIOFlags_(c);
437 // Copying content of CPF
438 for (const auto attr: c._attributes_) {
439 auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(_nameMap_[attr->safeName()]);
440 a->copyCpf(bij, *attr);
441 }
442 }
443 }
444
445 template < GUM_Numeric GUM_SCALAR >
448 switch (cec.obj_type()) {
450 const PRMClass< GUM_SCALAR >* current = this;
451
452 while (current != 0) {
453 if (current == &(cec)) return true;
454
455 current = current->_superClass_;
456 }
457
458 return false;
459 }
460
462 if (_implements_ != nullptr) {
464 = static_cast< const PRMInterface< GUM_SCALAR >& >(cec);
465
466 if (_implements_->exists(const_cast< PRMInterface< GUM_SCALAR >* >(&i))) return true;
467
468 for (const auto impl: *_implements_)
469 if (impl->isSubTypeOf(i)) return true;
470 }
471
472 return false;
473 }
474
475 default : {
476 GUM_ERROR(FatalError, "unknown ClassElementContainer<GUM_SCALAR>")
477 }
478 }
479 }
480
481 template < GUM_Numeric GUM_SCALAR >
482 void PRMClass< GUM_SCALAR >::addArc(std::string_view tail_name, std::string_view head_name) {
483 auto p_tail = _nameMap_.tryGet(tail_name);
484 auto p_head = _nameMap_.tryGet(head_name);
485
486 if (!p_tail || !p_head) {
487 GUM_ERROR(NotFound, "tail and/or head of arc does not exists in this Class")
488 }
489 PRMClassElement< GUM_SCALAR >* tail = *p_tail;
490 PRMClassElement< GUM_SCALAR >* head = *p_head;
491
495 "a PRMReferenceSlot<GUM_SCALAR> can "
496 "not on neither side of an arc");
497 }
498
502 "illegal insertion of an arc between two SlotChain<GUM_SCALAR>")
503 }
504
505 if (!_dag_.existsArc(Arc(tail->id(), head->id()))) {
506 _dag_.addArc(tail->id(), head->id());
507 } else {
508 GUM_ERROR(DuplicateElement, "duplicate arc " << tail_name << "->" << head_name)
509 }
510
511 get(tail->id()).addChild(get(head->id()));
512 get(head->id()).addParent(get(tail->id()));
513
514 // Defining input / output nodes
516 PRMSlotChain< GUM_SCALAR >* sc = static_cast< PRMSlotChain< GUM_SCALAR >* >(tail);
517 this->setInputNode(*head, true);
518 sc->end().setOutputNode(sc->end().get(sc->lastElt().safeName()), true);
519 }
520 }
521
522 template < GUM_Numeric GUM_SCALAR >
524 if (_implements_ != nullptr) {
525 for (auto i: implements()) {
526 if (i->exists(elt->name())) { _checkInterface_(elt, i); }
527 }
528 }
529 }
530
531 template < GUM_Numeric GUM_SCALAR >
534 const auto& i_elt = i->get(elt->name());
535 bool is_attr = PRMClassElement< GUM_SCALAR >::isAttribute(i_elt);
537
538 if (!(is_attr || is_agg)) {
539 GUM_ERROR(OperationNotAllowed, "Class does not respect it's interface")
540 }
541
542 if (!elt->type().isSubTypeOf(i_elt.type())) {
543 GUM_ERROR(OperationNotAllowed, "Attribute type does not respect class interface")
544 }
545
546 if (elt->type() != i_elt.type()) {
547 if (!this->exists(i_elt.safeName())) {
548 GUM_ERROR(OperationNotAllowed, "Attribute type does not respect class interface")
549 }
550 elt = &(this->get(i_elt.safeName()));
551 }
552
553 // Node must be reserved by constructor
554 if (!_dag_.existsNode(i_elt.id())) {
555 GUM_ERROR(FatalError, "Class does not reserved implemented nodes")
556 }
557
558 // Removing unused node and changing to proper node
559 if (elt->id() != i_elt.id()) {
560 // Update cast descendants
561 for (auto child: _dag_.children(elt->id())) {
562 _dag_.addArc(i_elt.id(), child);
563 }
564 _dag_.eraseNode(elt->id());
565 }
566 _nodeIdMap_.erase(elt->id());
567 elt->setId(i_elt.id());
568 _nodeIdMap_.insert(elt->id(), elt);
569 }
570
571 template < GUM_Numeric GUM_SCALAR >
573 if (_implements_ != nullptr) {
574 for (auto i: implements()) {
575 if (i->exists(ref->name())) { _checkRefInterface_(ref, i); }
576 }
577 }
578 }
579
580 template < GUM_Numeric GUM_SCALAR >
583 auto& i_elt = i->get(ref->name());
584 if (i_elt.elt_type() != ref->elt_type()) {
585 GUM_ERROR(OperationNotAllowed, "Class does not respect it's interface")
586 }
587 auto& i_ref = static_cast< PRMReferenceSlot< GUM_SCALAR >& >(i_elt);
588 if (!ref->slotType().isSubTypeOf(i_ref.slotType())) {
589 GUM_ERROR(OperationNotAllowed, "ReferenceSlot type does not respect class interface")
590 }
591 // Node must be reserved by constructor
592 if (!_dag_.exists(i_ref.id())) {
594 "class " << this->name() << " does not respect interface " << i->name()
595 << " implementation");
596 }
597 // Removing unused node and changin to propoer node
598 if (ref->id() != i_ref.id()) { _dag_.eraseNode(ref->id()); }
599 _nodeIdMap_.erase(ref->id());
600 ref->setId(i_ref.id());
601 _nodeIdMap_.insert(ref->id(), ref);
602 }
603
604 template < GUM_Numeric GUM_SCALAR >
606 if (_nameMap_.exists(elt->name())) {
608 "name " << elt->name() << " already used by another ClassElement");
609 }
610
611 elt->setId(nextNodeId());
612 _dag_.addNodeWithId(elt->id());
613 _nodeIdMap_.insert(elt->id(), elt);
614 _nameMap_.insert(elt->name(), elt);
615
616 try {
617 _nameMap_.insert(elt->safeName(), elt);
618 } catch (DuplicateElement& e) {
621 throw DuplicateElement(e);
622 }
623 }
624
625 switch (elt->elt_type()) {
627 _attributes_.insert(static_cast< PRMAttribute< GUM_SCALAR >* >(elt));
629
630 // Update attribute or cast descendant id to respect implemented
631 // interface
633
635 break;
636 }
637
639 _aggregates_.insert(static_cast< PRMAggregate< GUM_SCALAR >* >(elt));
641
642 // Update attribute or cast descendant id to respect implemented
643 // interface
645
647 break;
648 }
649
651 auto ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(elt);
652 _referenceSlots_.insert(ref);
653
654 // Updating ref's id if ref implements an interface
656 break;
657 }
658
660 _slotChains_.insert(static_cast< PRMSlotChain< GUM_SCALAR >* >(elt));
661 break;
662 }
663
665 _parameters_.insert(static_cast< PRMParameter< GUM_SCALAR >* >(elt));
666 break;
667 }
668
669 default : {
670 GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR> type")
671 }
672 }
673
674 return elt->id();
675 }
676
677 template < GUM_Numeric GUM_SCALAR >
679 auto parent = attr;
681
682 while (parent->type().isSubType()) {
683 child = parent->getCastDescendant();
684
685 // Check if id was reserved by one of the class interfaces
686 bool found = false;
687 if (_implements_ != nullptr) {
688 for (auto i: implements()) {
689 if (i->exists(child->safeName())) {
690 child->setId(i->get(child->safeName()).id());
691 found = true;
692 break;
693 }
694 }
695 }
696 if (!found) {
697 child->setId(nextNodeId());
698 _dag_.addNodeWithId(child->id());
699 }
700 _nodeIdMap_.insert(child->id(), child);
701 // Only use child's safe name when adding to the name map!
702 _nameMap_.insert(child->safeName(), child);
703 _attributes_.insert(child);
704 // Do not use Class<GUM_SCALAR>::insertArc(), child's CPF is already
705 // initialized properly
706 _dag_.addArc(parent->id(), child->id());
707
708 parent = child;
709 }
710 }
711
712 template < GUM_Numeric GUM_SCALAR >
714 if (!_superClass_) {
715 GUM_ERROR(OperationNotAllowed, "overload is possible only with subclasses")
716 }
717 if (!super().exists(overloader->name())) {
718 GUM_ERROR(OperationNotAllowed, "found no ClassElement<GUM_SCALAR> to overload")
719 }
720
721 PRMClassElement< GUM_SCALAR >* overloaded = _nameMap_[overloader->name()];
722 if (overloaded == overloader) {
723 GUM_ERROR(DuplicateElement, "dupplicate ClassElement " << overloader->name())
724 }
725 // Checking overload legality
726 if (!_checkOverloadLegality_(overloaded, overloader)) {
727 GUM_ERROR(OperationNotAllowed, "illegal overload")
728 }
729
730 switch (overloader->elt_type()) {
732 auto overloader_attr = static_cast< PRMAttribute< GUM_SCALAR >* >(overloader);
733 auto overloaded_attr = static_cast< PRMAttribute< GUM_SCALAR >* >(overloaded);
734 _overloadAttribute_(overloader_attr, overloaded_attr);
735 _addIOInterfaceFlags_(overloader);
736 break;
737 }
738
740 _overloadAggregate_(static_cast< PRMAggregate< GUM_SCALAR >* >(overloader), overloaded);
741 _addIOInterfaceFlags_(overloader);
742 break;
743 }
744
746 // _checkOverloadLegality_ guaranties that overloaded is a
747 // PRMReferenceSlot<GUM_SCALAR>
748 auto overloader_ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloader);
749 auto overloaded_ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(overloaded);
750 _overloadReference_(overloader_ref, overloaded_ref);
751 break;
752 }
753
755 GUM_ERROR(OperationNotAllowed, "SlotChain<GUM_SCALAR> can not be overloaded")
756 break;
757 }
758
760 auto overloaded_param = static_cast< PRMParameter< GUM_SCALAR >* >(overloaded);
761 auto overloader_param = static_cast< PRMParameter< GUM_SCALAR >* >(overloader);
762 _overloadParameter_(overloader_param, overloaded_param);
763 break;
764 }
765 default : {
766 GUM_ERROR(OperationNotAllowed, "unknown ClassElement<GUM_SCALAR> type")
767 }
768 }
769
770 return overloader->id();
771 }
772
773 template < GUM_Numeric GUM_SCALAR >
775 PRMAttribute< GUM_SCALAR >* overloaded) {
776 _dag_.eraseParents(overloaded->id());
777
778 // Checking if we have to add cast descendant
779 if (overloader->type() != overloaded->type()) {
780 overloader->setId(nextNodeId());
781 _dag_.addNodeWithId(overloader->id());
782 _nodeIdMap_.insert(overloader->id(), overloader);
783 _nameMap_[overloader->name()] = overloader;
784 _nameMap_.insert(overloader->safeName(), overloader);
785 _attributes_.insert(overloader);
786 _addCastDescendants_(overloader, overloaded);
787 } else {
788 overloader->setId(overloaded->id());
789 _nodeIdMap_[overloader->id()] = overloader;
790 _nameMap_[overloader->name()] = overloader;
791 _nameMap_[overloader->safeName()] = overloader;
792 _attributes_.erase(overloaded);
793 _attributes_.insert(overloader);
794 overloader->overload(overloaded);
795 delete overloaded;
796 }
797 }
798
799 template < GUM_Numeric GUM_SCALAR >
801 PRMReferenceSlot< GUM_SCALAR >* overloaded) {
802 // Adding overloading reference
803 overloader->setId(overloaded->id());
804 _nodeIdMap_[overloader->id()] = overloader;
805 _nameMap_[overloader->name()] = overloader;
806 _nameMap_.insert(overloader->safeName(), overloader);
807 _referenceSlots_.insert(overloader);
811 std::vector< PRMSlotChain< GUM_SCALAR >* > toRemove, toAdd;
812
813 // Updating PRMSlotChain<GUM_SCALAR> which started with overloaded
814 for (const auto slotchain: _slotChains_) {
815 // If the attribute pointed by this slotchain is overloaded, we need to
816 // change the slotchain
817 // names to it's safename version: ref.attr is replaced by
818 // ref.(type)attr.
819 if ((slotchain->chain().atPos(0) == overloaded)) {
821 seq.insert(overloader);
822
823 auto elt = ++(slotchain->chain().begin());
824
825 while (elt != slotchain->chain().end()) {
826 ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(seq.back());
827 next = &(ref->slotType().get((*elt)->name()));
828 seq.insert(next);
829 ++elt;
830 }
831
832 // If the slotchain last element type changes, we change the slotchain
833 // to
834 // point towards the cast decendant
835 // with the correct type
836 if (seq.back()->type() != slotchain->lastElt().type()) {
837 seq.erase(seq.back());
838 seq.insert(&(static_cast< PRMReferenceSlot< GUM_SCALAR >* >(seq.back())
839 ->slotType()
840 .get(slotchain->lastElt().safeName())));
841 std::string sc_name;
842 std::string dot = ".";
843
844 for (Size i = 0; i < seq.size() - 1; ++i) {
845 sc_name += seq.atPos(i)->name() + dot;
846 }
847
848 sc_name += seq.back()->safeName();
849 sc = new PRMSlotChain< GUM_SCALAR >(sc_name, seq);
850 sc->setId(slotchain->id());
851
852 for (const auto child: this->containerDag().children(sc->id())) {
853 auto& elt = get(child);
855 auto& attr = static_cast< PRMAttribute< GUM_SCALAR >& >(elt);
856 auto& old_type = slotchain->lastElt().type();
857 auto& new_type = sc->lastElt().type();
858 attr.swap(old_type, new_type);
859 } else {
860 GUM_ERROR(OperationNotAllowed, "unexpected ClassElement")
861 // get( child ).cpf().replace(
862 // slotchain->lastElt().type().variable(),
863 // sc->lastElt().type().variable() );
864 }
865 }
866
867 toAdd.push_back(sc);
868 toRemove.push_back(slotchain);
869 } else {
870 // Types are identical, we just need to change the first reference
871 slotchain->chain().setAtPos(0, overloader);
872 }
873 }
874 }
875
876 for (const auto torem: toRemove) {
877 _nameMap_.erase(torem->name());
878 _slotChains_.erase(torem);
879 delete torem;
880 }
881
882 for (const auto toadd: toAdd) {
883 _nameMap_.insert(toadd->name(), toadd);
884 _nodeIdMap_[toadd->id()] = toadd;
885 _slotChains_.insert(sc);
886 }
887
888 // Removing overloaded PRMReferenceSlot<GUM_SCALAR>
889 _referenceSlots_.erase(overloaded);
890 _nameMap_.erase(overloaded->safeName());
891 delete overloaded;
892 }
893
894 template < GUM_Numeric GUM_SCALAR >
896 PRMParameter< GUM_SCALAR >* overloaded) {
897 overloader->setId(overloaded->id());
898 _nodeIdMap_[overloader->id()] = overloader;
899 _nameMap_[overloader->name()] = overloader;
900 _nameMap_[overloader->safeName()] = overloader;
901 _parameters_.erase(overloaded);
902 _parameters_.insert(overloader);
903 delete overloaded;
904 }
905
906 template < GUM_Numeric GUM_SCALAR >
909 PRMAttribute< GUM_SCALAR >* parent = start;
911
912 while (parent->type().superType() != end->type()) {
913 child = parent->getCastDescendant();
914 child->setId(nextNodeId());
915 _nodeIdMap_.insert(child->id(), child);
916 _dag_.addNodeWithId(child->id());
917 // Only use child's safe name when adding to the name map!
918 _nameMap_.insert(child->safeName(), child);
919 _attributes_.insert(child);
921 // Do not use Class<GUM_SCALAR>::insertArc(), child's CPF is already
922 // initialized properly
923 _dag_.addArc(parent->id(), child->id());
924 parent = child;
925 }
926
927 parent->setAsCastDescendant(end);
928 _dag_.addArc(parent->id(), end->id());
929 }
930
931 template < GUM_Numeric GUM_SCALAR >
934 for (auto ext: _extensions_) {
935 set.insert(ext);
936 ext->findAllSubtypes_(set);
937 }
938 }
939
940 template < GUM_Numeric GUM_SCALAR >
942 // We only add IO Flags if elt matches is required by and interface
943 if (_implements_ != nullptr) {
944 for (const auto impl: *_implements_) {
946 while (super) {
947 // If the attribute is defined in an interface, we set it as an
948 // OutputNode
949 if (impl->exists(elt->name())) {
950 try {
951 this->getIOFlag_(*elt).second = true;
952 } catch (NotFound const&) { this->setIOFlag_(*elt, std::make_pair(false, true)); }
953 }
954 super = super->_superInterface_ ? &(super->super()) : nullptr;
955 }
956 }
957 }
958 }
959
960 template < GUM_Numeric GUM_SCALAR >
962 // for ( const auto ext : _extensions_ ) {
963 // // We test to prevent unnecessary recursive call from iter
964 // if ( !ext->isOutputNode( elt ) ) {
965 // ext->setOutputNode( elt, true );
966 // }
967 //}
968 }
969
970 template < GUM_Numeric GUM_SCALAR >
974
975 template < GUM_Numeric GUM_SCALAR >
977 return _dag_;
978 }
979
980 template < GUM_Numeric GUM_SCALAR >
982 return _dag_;
983 }
984
985 template < GUM_Numeric GUM_SCALAR >
987 auto p = _nodeIdMap_.tryGet(id);
988 if (!p) { GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId") }
989 return **p;
990 }
991
992 template < GUM_Numeric GUM_SCALAR >
994 auto p = _nodeIdMap_.tryGet(id);
995 if (!p) {
996 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given NodeId (" << id << ")");
997 }
998 return **p;
999 }
1000
1001 template < GUM_Numeric GUM_SCALAR >
1003 auto p = _nameMap_.tryGet(name);
1004 if (!p) {
1005 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name (" << name << ")");
1006 }
1007 return **p;
1008 }
1009
1010 template < GUM_Numeric GUM_SCALAR >
1012 auto p = _nameMap_.tryGet(name);
1013 if (!p) {
1014 GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> with the given name (" << name << ")");
1015 }
1016 return **p;
1017 }
1018
1019 template < GUM_Numeric GUM_SCALAR >
1023
1024 template < GUM_Numeric GUM_SCALAR >
1028
1029 // Private struct for retrieving all params in scope
1030 template < GUM_Numeric GUM_SCALAR >
1032 std::string prefix;
1035
1036 ParamScopeData(std::string_view s, const PRMReferenceSlot< GUM_SCALAR >& ref, Idx d) :
1037 prefix(std::string{s}.append(ref.name()).append(".")),
1038 c(static_cast< const PRMClass< GUM_SCALAR >* >(&(ref.slotType()))), depth(d) {}
1039 };
1040
1041 template < GUM_Numeric GUM_SCALAR >
1045
1046 for (const auto p: parameters()) {
1047 params.insert(p->name(), p);
1048 }
1049
1050 std::queue< ParamScopeData< GUM_SCALAR > > queue;
1051
1052 for (const auto ref: referenceSlots()) {
1053 if (PRMObject::isClass(ref->slotType())) {
1054 queue.push(ParamScopeData< GUM_SCALAR >("", *ref, 1));
1055 }
1056 }
1057
1058 while (!queue.empty()) {
1059 auto data = queue.front();
1060 queue.pop();
1061
1062 if (data.depth < 5) {
1063 for (const auto p: data.c->parameters()) {
1064 params.insert(data.prefix + p->name(), p);
1065 }
1066
1067 for (const auto ref: data.c->referenceSlots()) {
1068 if (PRMObject::isClass(ref->slotType())) {
1069 queue.push(ParamScopeData< GUM_SCALAR >(data.prefix, *ref, data.depth + 1));
1070 }
1071 }
1072 } else {
1073 // @todo depth>5 is a workaround. Cycle detection is needed here !
1074 GUM_ERROR(FatalError, "Depth limit reached when looking up parameters")
1075 }
1076 }
1077
1078 return params;
1079 }
1080
1081 template < GUM_Numeric GUM_SCALAR >
1085
1086 template < GUM_Numeric GUM_SCALAR >
1090
1091 template < GUM_Numeric GUM_SCALAR >
1095
1096 template < GUM_Numeric GUM_SCALAR >
1098 if (_superClass_) {
1099 return *_superClass_;
1100 } else {
1101 GUM_ERROR(NotFound, "this Class is not a subclass")
1102 }
1103 }
1104
1105 template < GUM_Numeric GUM_SCALAR >
1107 if (_implements_) {
1108 return *_implements_;
1109 } else {
1110 GUM_ERROR(NotFound, "this Class does not implement any Interface<GUM_SCALAR>")
1111 }
1112 }
1113
1114 template < GUM_Numeric GUM_SCALAR >
1118
1119 template < GUM_Numeric GUM_SCALAR >
1123
1124 template < GUM_Numeric GUM_SCALAR >
1128
1129 template < GUM_Numeric GUM_SCALAR >
1132 return get(name);
1133 }
1134
1135 template < GUM_Numeric GUM_SCALAR >
1137 PRMClassElement< GUM_SCALAR >* overloaded) {
1138 _nameMap_.insert(overloader->safeName(), overloader);
1139 _aggregates_.insert(overloader);
1140 }
1141
1142 template < GUM_Numeric GUM_SCALAR >
1144 const PRMClassElement< GUM_SCALAR >* overloaded,
1145 const PRMClassElement< GUM_SCALAR >* overloader) {
1146 if (overloaded->elt_type() != overloader->elt_type()) { return false; }
1147
1148 switch (overloaded->elt_type()) {
1150 if (!overloader->type().isSubTypeOf(overloaded->type())) { return false; }
1151 break;
1152 }
1153
1155 const auto& new_slot_type
1156 = static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloader)->slotType();
1157 const auto& old_slot_type
1158 = static_cast< const PRMReferenceSlot< GUM_SCALAR >* >(overloaded)->slotType();
1159
1160 if (!new_slot_type.isSubTypeOf(old_slot_type)) { return false; }
1161
1162 break;
1163 }
1164
1166 auto overloaded_param = static_cast< const PRMParameter< GUM_SCALAR >* >(overloaded);
1167 auto overloader_param = static_cast< const PRMParameter< GUM_SCALAR >* >(overloader);
1168
1169 return overloaded_param->valueType() == overloader_param->valueType();
1170 break;
1171 }
1172
1173 default : {
1174 return false;
1175 }
1176 }
1177 return true;
1178 }
1179
1180 template < GUM_Numeric GUM_SCALAR >
1184
1185 template < GUM_Numeric GUM_SCALAR >
1189
1190 template < GUM_Numeric GUM_SCALAR >
1191 bool PRMClass< GUM_SCALAR >::isCastDescendant(std::string_view safe_name) const {
1192 const PRMClassElement< GUM_SCALAR >& elt = get(safe_name);
1193
1194 try {
1195 return elt.type().name() == get(elt.name()).type().name();
1196 } catch (OperationNotAllowed const&) {
1197 GUM_ERROR(NotFound, "no attribute with the given name")
1198 }
1199 }
1200
1201 template < GUM_Numeric GUM_SCALAR >
1203 try {
1204 if (!this->getIOFlag_(elt).second) {
1205 if (_implements_) {
1206 for (auto i: *_implements_) {
1207 if (i->isOutputNode(elt)) { return true; }
1208 }
1209 }
1210
1211 if (_superClass_ && (_superClass_->isOutputNode(elt))) { return true; }
1212
1213 } else {
1214 return true;
1215 }
1216 } catch (NotFound const&) {}
1217 return false;
1218 }
1219
1220
1221 } /* namespace prm */
1222} /* 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:1640
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:122
Exception : fatal (unknown ?) error.
The class for generic Hash Tables.
Definition hashTable.h:640
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.
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.
void erase(const Key &k)
Remove an element from the sequence.
const Key & back() const
Returns the last element of the sequence.
void setAtPos(Idx i, const Key &newKey)
Change the value.
Size size() const noexcept
Returns the size of the sequence.
The generic class for storing (ordered) sequences of objects.
Definition sequence.h:994
Representation of a set.
Definition set.h:129
PRMType & type() override
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.
PRMType & type() override=0
See gum::PRMClassElement::type().
PRMAttribute< GUM_SCALAR > * getCastDescendant() const override=0
Returns a proper cast descendant of this PRMAttribute.
PRMClassElementContainer(std::string_view name)
Default constructor.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
virtual void copyIOFlags_(const PRMClassElementContainer< GUM_SCALAR > &c)
Copy the IO Flags of c in this PRMClassElementContainer.
virtual std::pair< bool, bool > & getIOFlag_(const PRMClassElement< GUM_SCALAR > &elt)
Returns the IO flags of a PRMClassElement<GUM_SCALAR>.
virtual bool exists(std::string_view name) const
Returns true if a member with the given name exists in this PRMClassElementContainer or in the PRMCla...
virtual void setIOFlag_(const PRMClassElement< GUM_SCALAR > &elt, const std::pair< bool, bool > &flags)
Defines the IO flags of a PRMClassElement<GUM_SCALAR>.
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 isAggregate(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMAggregate.
static INLINE bool isParameter(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMParameter.
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.
static INLINE bool isAttribute(const PRMClassElement< GUM_SCALAR > &elt)
Returns true if obj_ptr is of type PRMAttribute.
virtual void setId(NodeId id)
Used to assign the id of this element.
static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMSlotChain.
NodeId id() const
Returns the NodeId of this element in it's class DAG.
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
A PRMClass is an object of a PRM representing a fragment of a Bayesian network which can be instantia...
Definition PRMClass.h:77
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.
PRMClass< GUM_SCALAR > * _superClass_
The alternate PRMClassElementContainer<GUM_SCALAR> searched for elements defined in this....
Definition PRMClass.h:395
bool isSubTypeOf(const PRMClassElementContainer< GUM_SCALAR > &cec) const override
Test if this Class<GUM_SCALAR> is a subclass of cec.
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>...
bool isCastDescendant(std::string_view safe_name) const
Return true if the attribute named safe_name is a cast descendant.
const Set< PRMInterface< GUM_SCALAR > * > & implements() const
Returns the Set of PRMInterface<GUM_SCALAR> implemented by this Class<GUM_SCALAR>.
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.
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
NodeId add(PRMClassElement< GUM_SCALAR > *elt) override
See gum::prm::add(PRMClassElement<GUM_SCALAR>*).
~PRMClass() override
Destructor.
void _overloadAggregate_(PRMAggregate< GUM_SCALAR > *overloader, PRMClassElement< GUM_SCALAR > *overloaded)
Overloads an aggregate.
Set< PRMSlotChain< GUM_SCALAR > * > _slotChains_
The set of gum::PRMSlotChain<GUM_SCALAR>s.
Definition PRMClass.h:373
void _checkInterface_(PRMClassElement< GUM_SCALAR > *elt, PRMInterface< GUM_SCALAR > *i)
Check that a given element respects a specific interface.
const Set< PRMReferenceSlot< GUM_SCALAR > * > & referenceSlots() const
Returns the set of PRMReferenceSlot<GUM_SCALAR> of this Class<GUM_SCALAR>.
PRMClassElement< GUM_SCALAR > & get(NodeId id) override
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
const Set< PRMSlotChain< GUM_SCALAR > * > & slotChains() const
Returns the set of PRMSlotChain<GUM_SCALAR> of this Class<GUM_SCALAR>.
void _implementInterfaces_(bool delayInheritance)
Proceed with the implementation of interfaces.
void addArc(std::string_view tail, std::string_view head) override
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::addArc().
void updateDescendants_(const PRMClassElement< GUM_SCALAR > &elt) override
See gum::prm::PRMClassElementContainer<GUM_SCALAR>(constPRMClassElement<GUM_SCALAR>&).
void findAllSubtypes_(Set< PRMClassElementContainer< GUM_SCALAR > * > &set) override
Fills set with all the subtypes of this Class<GUM_SCALAR>.
NodeId overload(PRMClassElement< GUM_SCALAR > *elt) override
See gum::prm::overload(PRMClassElement<GUM_SCALAR>*).
const Set< PRMParameter< GUM_SCALAR > * > & parameters() const
Returns the set of parameters of this Class<GUM_SCALAR>.
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.
const DAG & dag_() const override
returns a constant reference over this interface's dag.
PRMClass(std::string_view name)
Default constructor.
PRMObject::prm_type obj_type() const override
Implementation of pure virtual method of PRMObject.
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
const Set< PRMAggregate< GUM_SCALAR > * > & aggregates() const
Returns the set of PRMAggregate<GUM_SCALAR> of this Class<GUM_SCALAR>.
Set< PRMAggregate< GUM_SCALAR > * > _aggregates_
The sequence of aggregate.
Definition PRMClass.h:370
void _addExtension_(PRMClass< GUM_SCALAR > *c)
This method is called when a sub-Class<GUM_SCALAR> of this Class<GUM_SCALAR> is created.
void _overloadParameter_(PRMParameter< GUM_SCALAR > *overloader, PRMParameter< GUM_SCALAR > *overloaded)
Overloads a parameter.
PRMClassElement< GUM_SCALAR > & operator[](NodeId id) override
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::operator[](NodeId).
void _inheritClass_(const PRMClass< GUM_SCALAR > &c)
Proceed with the copy when this inherits c.
const Set< PRMAttribute< GUM_SCALAR > * > & attributes() const
Returns the set of PRMAttribute<GUM_SCALAR> of this Class<GUM_SCALAR>.
Set< PRMParameter< GUM_SCALAR > * > _parameters_
The Set of parameters in this Class<GUM_SCALAR>.
Definition PRMClass.h:376
bool isOutputNode(const PRMClassElement< GUM_SCALAR > &elt) const override
Returns true if elt is an output node.
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< GUM_SCALAR > * > _nameMap_
Mapping between a member's name and itself. Used for fast access to a member given it's name.
Definition PRMClass.h:361
friend class PRMInterface< GUM_SCALAR >
Definition PRMClass.h:78
void completeInheritance(std::string_view attr)
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
HashTable< std::string, const PRMParameter< GUM_SCALAR > * > scope() const
Returns all the parameters in the scope of this class.
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
An PRMInterface is implemented by a Class<GUM_SCALAR> and defines a set of PRMReferenceSlot<GUM_SCALA...
PRMClassElement< GUM_SCALAR > & get(NodeId id) override
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:90
static INLINE bool isClass(const PRMObject &obj)
Returns true if obj_ptr is of type Class.
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.
PRMClassElement< GUM_SCALAR >::ClassElementType elt_type() const override
Implementation of the pure virtual method of PRMObject.
PRMClassElementContainer< GUM_SCALAR > & slotType()
Returns the type of this slot, which is a PRMClassElementContainer (it is not the type of PRMObject).
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
PRMType & type() override
This is similar to the following call: this->lastElt().type().
PRMClassElement< GUM_SCALAR > & lastElt()
Returns the last element of the slot chain, typically this is an gum::PRMAttribute or a gum::PRMAggre...
PRMClassElementContainer< GUM_SCALAR > & end()
Returns the PRMClassElement<GUM_SCALAR>Container over which this slot chain ends.
PRMType & superType()
Returns the super type of this type.
Definition PRMType_inl.h:57
bool isSubTypeOf(const PRMType &super) const
Returns true if this is a subtype of super.
Definition PRMType.cpp:114
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition PRMType_inl.h:65
const std::string & name() const
Returns the name of this object.
Definition PRMType_inl.h:79
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
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
STL namespace.
const PRMClass< GUM_SCALAR > * c
ParamScopeData(std::string_view s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)