aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
PRMFactory_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
48
49#include <iostream>
50#include <sstream>
51
57
58namespace gum {
59
60 namespace prm {
61
62 template < typename GUM_SCALAR >
63 INLINE void PRMFactory< GUM_SCALAR >::startClass(const std::string& name,
64 const std::string& extends,
65 const Set< std::string >* implements,
66 bool delayInheritance) {
67 std::string real_name = _addPrefix_(name);
68 if (_prm_->_classMap_.exists(real_name) || _prm_->_interfaceMap_.exists(real_name)) {
69 GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.")
70 }
71 PRMClass< GUM_SCALAR >* c = nullptr;
72 PRMClass< GUM_SCALAR >* mother = nullptr;
74
75 if (implements != 0) {
76 for (const auto& imp: *implements) {
77 impl.insert(_retrieveInterface_(imp));
78 }
79 }
80
81 if (extends != "") { mother = _retrieveClass_(extends); }
82
83 if ((extends.empty()) && impl.empty()) {
84 c = new PRMClass< GUM_SCALAR >(real_name);
85 } else if ((extends != "") && impl.empty()) {
86 c = new PRMClass< GUM_SCALAR >(real_name, *mother, delayInheritance);
87 } else if ((extends.empty()) && (!impl.empty())) {
88 c = new PRMClass< GUM_SCALAR >(real_name, impl, delayInheritance);
89 } else if ((extends != "") && (!impl.empty())) {
90 c = new PRMClass< GUM_SCALAR >(real_name, *mother, impl, delayInheritance);
91 }
92
93 _prm_->_classMap_.insert(c->name(), c);
94 _prm_->_classes_.insert(c);
95 _stack_.push_back(c);
96 }
97
98 template < typename GUM_SCALAR >
99 INLINE void PRMFactory< GUM_SCALAR >::continueClass(const std::string& name) {
100 std::string real_name = _addPrefix_(name);
101 if (!(_prm_->_classMap_.exists(real_name))) {
102 std::stringstream msg;
103 msg << "'" << real_name << "' not found";
104 GUM_ERROR(NotFound, msg.str())
105 }
106 _stack_.push_back(&(_prm_->getClass(real_name)));
107 }
108
109 template < typename GUM_SCALAR >
110 INLINE void PRMFactory< GUM_SCALAR >::endClass(bool checkImplementations) {
113
114 if (checkImplementations) { _checkInterfaceImplementation_(c); }
115
116 _stack_.pop_back();
117 }
118
119 template < typename GUM_SCALAR >
120 INLINE void
122 try {
123 for (const auto& i: c->implements()) {
124 try {
125 for (const auto& node: i->containerDag().nodes()) {
126 std::string name = i->get(node).name();
127
128 switch (i->get(node).elt_type()) {
131 if ((c->get(name).elt_type() == PRMClassElement< GUM_SCALAR >::prm_attribute)
132 || (c->get(name).elt_type()
134 if (!c->get(name).type().isSubTypeOf(i->get(name).type())) {
135 std::stringstream msg;
136 msg << "class " << c->name() << " does not respect interface ";
137 GUM_ERROR(PRMTypeError, msg.str() + i->name())
138 }
139 } else {
140 std::stringstream msg;
141 msg << "class " << c->name() << " does not respect interface ";
142 GUM_ERROR(PRMTypeError, msg.str() + i->name())
143 }
144
145 break;
146 }
147
149 if (c->get(name).elt_type() == PRMClassElement< GUM_SCALAR >::prm_refslot) {
151 = static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(i->get(name));
152 const PRMReferenceSlot< GUM_SCALAR >& ref_this
153 = static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(c->get(name));
154
155 if (!ref_this.slotType().isSubTypeOf(ref_i.slotType())) {
156 std::stringstream msg;
157 msg << "class " << c->name() << " does not respect interface ";
158 GUM_ERROR(PRMTypeError, msg.str() + i->name())
159 }
160 } else {
161 std::stringstream msg;
162 msg << "class " << c->name() << " does not respect interface ";
163 GUM_ERROR(PRMTypeError, msg.str() + i->name())
164 }
165
166 break;
167 }
168
170 // Nothing to check: they are automatically inherited
171 break;
172 }
173
174 default : {
175 std::string msg = "unexpected ClassElement<GUM_SCALAR> in interface ";
176 GUM_ERROR(FatalError, msg + i->name())
177 }
178 }
179 }
180 } catch (NotFound const&) {
181 std::stringstream msg;
182 msg << "class " << c->name() << " does not respect interface ";
183 GUM_ERROR(PRMTypeError, msg.str() + i->name())
184 }
185 }
186 } catch (NotFound const&) {
187 // this Class<GUM_SCALAR> does not implement any
188 // PRMInterface<GUM_SCALAR>
189 }
190 }
191
192 template < typename GUM_SCALAR >
193 INLINE void PRMFactory< GUM_SCALAR >::startInterface(const std::string& name,
194 const std::string& extends,
195 bool delayInheritance) {
196 std::string real_name = _addPrefix_(name);
197 if (_prm_->_classMap_.exists(real_name) || _prm_->_interfaceMap_.exists(real_name)) {
198 GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.")
199 }
200 PRMInterface< GUM_SCALAR >* i = nullptr;
201 PRMInterface< GUM_SCALAR >* super = nullptr;
202
203 if (extends != "") { super = _retrieveInterface_(extends); }
204
205 if (super != nullptr) {
206 i = new PRMInterface< GUM_SCALAR >(real_name, *super, delayInheritance);
207 } else {
208 i = new PRMInterface< GUM_SCALAR >(real_name);
209 }
210
211 _prm_->_interfaceMap_.insert(i->name(), i);
212 _prm_->_interfaces_.insert(i);
213 _stack_.push_back(i);
214 }
215
216 template < typename GUM_SCALAR >
217 INLINE void PRMFactory< GUM_SCALAR >::continueInterface(const std::string& name) {
218 std::string real_name = _addPrefix_(name);
219 if (!_prm_->_interfaceMap_.exists(real_name)) {
220 GUM_ERROR(DuplicateElement, "'" << real_name << "' not found.")
221 }
222
224 _stack_.push_back(i);
225 }
226
227 template < typename GUM_SCALAR >
231 c->add(attr);
232 Size count = 0;
233 const Sequence< const DiscreteVariable* >& vars = attr->cpf().variablesSequence();
234
235 for (const auto& node: c->containerDag().nodes()) {
236 try {
237 if (vars.exists(&(c->get(node).type().variable()))) {
238 ++count;
239
240 if (&(attr->type().variable()) != &(c->get(node).type().variable())) {
241 c->addArc(c->get(node).safeName(), attr->safeName());
242 }
243 }
244 } catch (OperationNotAllowed const&) {}
245 }
246
247 if (count != attr->cpf().variablesSequence().size()) {
248 GUM_ERROR(NotFound, "unable to found all parents of this attribute")
249 }
250 }
251
252 template < typename GUM_SCALAR >
255 const std::string& name) {
256 try {
257 PRMClassElement< GUM_SCALAR >& elt = c->get(name);
258
259 switch (elt.elt_type()) {
262 "can not add a reference slot as a parent of an attribute")
263 break;
264 }
265
267 if (static_cast< PRMSlotChain< GUM_SCALAR >& >(elt).isMultiple()) {
268 GUM_ERROR(OperationNotAllowed, "can not add a multiple slot chain to an attribute")
269 }
270
271 c->addArc(name, a->name());
272
273 break;
274 }
275
278 c->addArc(name, a->name());
279 break;
280 }
281
282 default : {
283 GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR>")
284 }
285 }
286 } catch (NotFound const&) {
287 // Check if name is a slot chain
289
290 if (sc == nullptr) {
291 std::string msg = "found no ClassElement<GUM_SCALAR> with the given name ";
292 GUM_ERROR(NotFound, msg + name)
293 } else if (!sc->isMultiple()) {
294 c->add(sc);
295 c->addArc(sc->name(), a->name());
296 } else {
297 delete sc;
299 "Impossible to add a multiple reference slot as"
300 " direct parent of an PRMAttribute<GUM_SCALAR>.");
301 }
302 }
303 }
304
305 template < typename GUM_SCALAR >
306 INLINE void PRMFactory< GUM_SCALAR >::addParent(const std::string& name) {
308 try {
309 // Retrieving pointers
312 _addParent_(c, a, name);
313 } catch (FactoryInvalidState const&) {
314 auto agg = static_cast< PRMAggregate< GUM_SCALAR >* >(
316 _addParent_(static_cast< PRMClass< GUM_SCALAR >* >(c), agg, name);
317 }
318 }
319
320 template < typename GUM_SCALAR >
321 INLINE void PRMFactory< GUM_SCALAR >::setRawCPFByFloatLines(const std::vector< float >& array) {
325
326 if (a->cpf().domainSize() != array.size()) GUM_ERROR(OperationNotAllowed, "illegal CPF size")
327
328 std::vector< GUM_SCALAR > array2(array.begin(), array.end());
329 a->cpf().fillWith(array2);
330 }
331
332 template < typename GUM_SCALAR >
333 INLINE void PRMFactory< GUM_SCALAR >::setRawCPFByLines(const std::vector< GUM_SCALAR >& array) {
335 auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(elt);
337
338 if (a->cpf().domainSize() != array.size()) {
339 GUM_ERROR(OperationNotAllowed, "illegal CPF size")
340 }
341
342 a->cpf().fillWith(array);
343 }
344
345 template < typename GUM_SCALAR >
346 INLINE void
347 PRMFactory< GUM_SCALAR >::setRawCPFByFloatColumns(const std::vector< float >& array) {
350
351 if (a->cpf().domainSize() != array.size()) {
352 GUM_ERROR(OperationNotAllowed, "illegal CPF size")
353 }
354
355 std::vector< GUM_SCALAR > array2(array.begin(), array.end());
356 setRawCPFByColumns(array2);
357 }
358
359 template < typename GUM_SCALAR >
360 INLINE void
361 PRMFactory< GUM_SCALAR >::setRawCPFByColumns(const std::vector< GUM_SCALAR >& array) {
364
365 if (a->cpf().domainSize() != array.size()) {
366 GUM_ERROR(OperationNotAllowed, "illegal CPF size")
367 }
368
369 if (a->cpf().nbrDim() == 1) {
370 setRawCPFByLines(array);
371
372 } else {
373 Instantiation inst(a->cpf());
374 Instantiation jnst;
375 for (auto idx = inst.variablesSequence().rbegin(); idx != inst.variablesSequence().rend();
376 --idx) {
377 jnst.add(**idx);
378 }
379
380 jnst.setFirst();
381 auto idx = (std::size_t)0;
382 while ((!jnst.end()) && idx < array.size()) {
383 inst.setVals(jnst);
384 a->cpf().set(inst, array[idx]);
385 jnst.inc();
386 ++idx;
387 }
388 }
389 }
390
391 template < typename GUM_SCALAR >
392 INLINE void
393 PRMFactory< GUM_SCALAR >::setCPFByFloatRule(const std::vector< std::string >& parents,
394 const std::vector< float >& values) {
395 auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
397
398 if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
399 GUM_ERROR(OperationNotAllowed, "wrong number of parents")
400 }
401
402 if (values.size() != a->type().variable().domainSize()) {
403 GUM_ERROR(OperationNotAllowed, "wrong number of values")
404 }
405
406 std::vector< GUM_SCALAR > values2(values.begin(), values.end());
407 setCPFByRule(parents, values2);
408 }
409
410 template < typename GUM_SCALAR >
411 INLINE void PRMFactory< GUM_SCALAR >::setCPFByRule(const std::vector< std::string >& parents,
412 const std::vector< GUM_SCALAR >& values) {
413 auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
415
416 if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
417 GUM_ERROR(OperationNotAllowed, "wrong number of parents")
418 }
419
420 if (values.size() != a->type().variable().domainSize()) {
421 GUM_ERROR(OperationNotAllowed, "wrong number of values")
422 }
423
424 if (dynamic_cast< PRMFormAttribute< GUM_SCALAR >* >(a)) {
425 auto form = static_cast< PRMFormAttribute< GUM_SCALAR >* >(a);
426 // jnst holds parents with a specific value (not "*")
427 // knst holds parents without a specific value ("*")
428 Instantiation jnst, knst;
429 const DiscreteVariable* var = 0;
430 // not_used Size pos = 0;
431 bool found = false;
432
433 for (Idx i = 0; i < parents.size(); ++i) {
434 var = form->formulas().variablesSequence().atPos(1 + i);
435
436 if (parents[i] == "*") {
437 knst.add(*var);
438 } else {
439 jnst.add(*var);
440 // not_used pos = 0;
441 found = false;
442
443 for (Size j = 0; j < var->domainSize(); ++j) {
444 if (var->label(j) == parents[i]) {
445 jnst.chgVal(*var, j);
446 found = true;
447 break;
448 }
449 }
450
451 if (!found) {
452 std::string msg = "could not find label ";
453 GUM_ERROR(NotFound, msg + parents[i])
454 }
455 }
456 }
457
458 Instantiation inst(form->formulas());
459 inst.setVals(jnst);
460
461 for (Size i = 0; i < form->type()->domainSize(); ++i) {
462 inst.chgVal(form->type().variable(), i);
463
464 for (inst.setFirstIn(knst); !inst.end(); inst.incIn(knst)) {
465 form->formulas().set(inst, std::to_string(values[i]));
466 }
467 }
468
469 } else {
470 GUM_ERROR(OperationNotAllowed, "invalide attribute type")
471 }
472 }
473
474 template < typename GUM_SCALAR >
475 INLINE void PRMFactory< GUM_SCALAR >::setCPFByRule(const std::vector< std::string >& parents,
476 const std::vector< std::string >& values) {
477 auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
479
480 if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
481 GUM_ERROR(OperationNotAllowed, "wrong number of parents")
482 }
483
484 if (values.size() != a->type().variable().domainSize()) {
485 GUM_ERROR(OperationNotAllowed, "wrong number of values")
486 }
487
488 if (dynamic_cast< PRMFormAttribute< GUM_SCALAR >* >(a)) {
489 auto form = static_cast< PRMFormAttribute< GUM_SCALAR >* >(a);
490 // jnst holds parents with a specific value (not "*")
491 // knst holds parents without a specific value ("*")
492 Instantiation jnst, knst;
493 const DiscreteVariable* var = 0;
494 // not_used Size pos = 0;
495 bool found = false;
496
497 for (Idx i = 0; i < parents.size(); ++i) {
498 var = form->formulas().variablesSequence().atPos(1 + i);
499
500 if (parents[i] == "*") {
501 knst.add(*var);
502 } else {
503 jnst.add(*var);
504 // not_used pos = 0;
505 found = false;
506
507 for (Size j = 0; j < var->domainSize(); ++j) {
508 if (var->label(j) == parents[i]) {
509 jnst.chgVal(*var, j);
510 found = true;
511 break;
512 }
513 }
514
515 if (!found) {
516 std::string msg = "could not find label ";
517 GUM_ERROR(NotFound, msg + parents[i])
518 }
519 }
520 }
521
522 Instantiation inst(form->formulas());
523 inst.setVals(jnst);
524
525 for (Size i = 0; i < form->type()->domainSize(); ++i) {
526 inst.chgVal(form->type().variable(), i);
527
528 for (inst.setFirstIn(knst); !inst.end(); inst.incIn(knst)) {
529 form->formulas().set(inst, values[i]);
530 }
531 }
532
533 } else {
534 GUM_ERROR(OperationNotAllowed, "invalide attribute type")
535 }
536 }
537
538 template < typename GUM_SCALAR >
539 INLINE void PRMFactory< GUM_SCALAR >::addParameter(const std::string& type,
540 const std::string& name,
541 double value) {
543
544 PRMParameter< GUM_SCALAR >* p = nullptr;
545 if (type == "int") {
546 p = new PRMParameter< GUM_SCALAR >(name,
548 (GUM_SCALAR)value);
549 } else if (type == "real") {
550 p = new PRMParameter< GUM_SCALAR >(name,
552 (GUM_SCALAR)value);
553 }
554
555 try {
556 c->add(p);
557 } catch (DuplicateElement const&) { c->overload(p); }
558 }
559
560 template < typename GUM_SCALAR >
561 INLINE void
563 const std::string& agg_type,
564 const std::string& rv_type,
565 const std::vector< std::string >& params) {
568
569 auto agg = new PRMAggregate< GUM_SCALAR >(name,
571 *_retrieveType_(rv_type));
572
573 try {
574 c->add(agg);
575 } catch (DuplicateElement const&) { c->overload(agg); }
576
577 switch (agg->agg_type()) {
581 if (params.size() != 1) {
582 GUM_ERROR(OperationNotAllowed, "aggregate requires a parameter")
583 }
584 agg->setLabel(params.front());
585 break;
586 }
587 default : {
588 // Nothing to do
589 }
590 }
591 _stack_.push_back(agg);
592 }
593
594 template < typename GUM_SCALAR >
595 INLINE void PRMFactory< GUM_SCALAR >::continueAggregator(const std::string& name) {
597
598 if (!c->exists(name)) GUM_ERROR(NotFound, "Element " << name << "not found")
599
600 auto& agg = c->get(name);
602 GUM_ERROR(OperationNotAllowed, "Element " << name << " not an aggregate")
603
604 _stack_.push_back(&agg);
605 }
606
607 template < typename GUM_SCALAR >
610 const std::string& name) {
611 auto chains = std::vector< std::string >{name};
612 auto inputs = std::vector< PRMClassElement< GUM_SCALAR >* >();
613 _retrieveInputs_(c, chains, inputs);
614
615 switch (agg->agg_type()) {
618 if (inputs.front()->type() != *(_retrieveType_("boolean"))) {
619 GUM_ERROR(TypeError, "expected booleans")
620 }
621
622 break;
623 }
624
628 if (!agg->hasLabel()) {
629 auto param = agg->labelValue();
630 Idx label_idx = 0;
631
632 while (label_idx < inputs.front()->type()->domainSize()) {
633 if (inputs.front()->type()->label(label_idx) == param) { break; }
634
635 ++label_idx;
636 }
637
638 if (label_idx == inputs.front()->type()->domainSize()) {
639 GUM_ERROR(NotFound, "could not find label")
640 }
641
642 agg->setLabel(label_idx);
643 }
644
645 break;
646 }
647
653 break;
654 }
655
656 default : {
657 GUM_ERROR(FatalError, "Unknown aggregator.")
658 }
659 }
660
661 c->addArc(inputs.front()->safeName(), agg->safeName());
662 }
663
664 template < typename GUM_SCALAR >
669
670 template < typename GUM_SCALAR >
671 INLINE void PRMFactory< GUM_SCALAR >::addAggregator(const std::string& name,
672 const std::string& agg_type,
673 const std::vector< std::string >& chains,
674 const std::vector< std::string >& params,
675 std::string type) {
678 // Checking call legality
679
680 if (chains.size() == 0) {
681 GUM_ERROR(OperationNotAllowed, "a PRMAggregate<GUM_SCALAR> requires at least one parent")
682 }
683
684 // Retrieving the parents of the aggregate
685 std::vector< PRMClassElement< GUM_SCALAR >* > inputs;
686
687 // This helps knowing if the aggregate has parents outside the current
688 // class
689 // (see below)
690 bool hasSC = _retrieveInputs_(c, chains, inputs);
691
692 // Checking that all inputs shares the same PRMType (trivial
693 // if
694 // inputs.size() == 1)
695 if (inputs.size() > 1) {
696 for (auto iter = inputs.begin() + 1; iter != inputs.end(); ++iter) {
697 if ((**(iter - 1)).type() != (**iter).type()) {
698 GUM_ERROR(TypeError, "found different types")
699 }
700 }
701 }
702
703 // Different treatments for different types of aggregate.
704 PRMAggregate< GUM_SCALAR >* agg = nullptr;
705
706 switch (PRMAggregate< GUM_SCALAR >::str2enum(agg_type)) {
709 if (inputs.front()->type() != *(_retrieveType_("boolean"))) {
710 GUM_ERROR(TypeError, "expected booleans")
711 }
712 if (params.size() != 0) { GUM_ERROR(OperationNotAllowed, "invalid number of paramaters") }
713
714 agg = new PRMAggregate< GUM_SCALAR >(name,
716 inputs.front()->type());
717
718 break;
719 }
720
723 if (params.size() != 1) { GUM_ERROR(OperationNotAllowed, "invalid number of parameters") }
724
725 Idx label_idx = 0;
726
727 while (label_idx < inputs.front()->type()->domainSize()) {
728 if (inputs.front()->type()->label(label_idx) == params.front()) { break; }
729
730 ++label_idx;
731 }
732
733 if (label_idx == inputs.front()->type()->domainSize()) {
734 GUM_ERROR(NotFound, "could not find label")
735 }
736
737 // Creating and adding the PRMAggregate<GUM_SCALAR>
738 agg = new PRMAggregate< GUM_SCALAR >(name,
740 *(_retrieveType_("boolean")),
741 label_idx);
742 agg->label();
743
744 break;
745 }
746
752 if (params.size() != 0) { GUM_ERROR(OperationNotAllowed, "invalid number of parameters") }
753
754 auto output_type = _retrieveType_(type);
755
756 // Creating and adding the PRMAggregate<GUM_SCALAR>
757 agg = new PRMAggregate< GUM_SCALAR >(name,
759 *output_type);
760
761 break;
762 }
763
765 if (params.size() != 1) { GUM_ERROR(OperationNotAllowed, "invalid number of parameters") }
766
767 Idx label_idx = 0;
768
769 while (label_idx < inputs.front()->type()->domainSize()) {
770 if (inputs.front()->type()->label(label_idx) == params.front()) { break; }
771
772 ++label_idx;
773 }
774
775 if (label_idx == inputs.front()->type()->domainSize()) {
776 GUM_ERROR(NotFound, "could not find label")
777 }
778
779 auto output_type = _retrieveType_(type);
780
781 // Creating and adding the PRMAggregate<GUM_SCALAR>
782 agg = new PRMAggregate< GUM_SCALAR >(name,
784 *output_type,
785 label_idx);
786
787 break;
788 }
789
790 default : {
791 GUM_ERROR(FatalError, "Unknown aggregator.")
792 }
793 }
794
795 std::string safe_name = agg->safeName();
796
797 try {
798 if (hasSC) {
799 try {
800 c->add(agg);
801 } catch (DuplicateElement const&) { c->overload(agg); }
802 } else {
803 // Inner aggregators can be directly used as attributes
804 auto attr
805 = new PRMScalarAttribute< GUM_SCALAR >(agg->name(), agg->type(), agg->buildImpl());
806
807 try {
808 c->add(attr);
809 } catch (DuplicateElement const&) { c->overload(attr); }
810
811 delete agg;
812 }
813 } catch (DuplicateElement const&) {
814 delete agg;
815 throw;
816 }
817
818 for (const auto& elt: inputs) {
819 c->addArc(elt->safeName(), safe_name);
820 }
821 }
822
823 template < typename GUM_SCALAR >
824 INLINE void PRMFactory< GUM_SCALAR >::addReferenceSlot(const std::string& type,
825 const std::string& name,
826 bool isArray) {
829
830 try {
831 slotType = _retrieveClass_(type);
832 } catch (NotFound const&) {
833 try {
834 slotType = _retrieveInterface_(type);
835 } catch (NotFound const&) {
836 GUM_ERROR(NotFound, "unknown ReferenceSlot<GUM_SCALAR> slot type")
837 }
838 }
839
841 = new PRMReferenceSlot< GUM_SCALAR >(name, *slotType, isArray);
842
843 try {
844 owner->add(ref);
845 } catch (DuplicateElement const&) { owner->overload(ref); }
846 }
847
848 template < typename GUM_SCALAR >
849 INLINE void PRMFactory< GUM_SCALAR >::addArray(const std::string& type,
850 const std::string& name,
851 Size size) {
856
857 try {
858 model->addArray(name, *c);
859
860 for (Size i = 0; i < size; ++i) {
861 std::stringstream elt_name;
862 elt_name << name << "[" << i << "]";
863 inst = new PRMInstance< GUM_SCALAR >(elt_name.str(), *c);
864 model->add(name, inst);
865 }
866 } catch (PRMTypeError const&) {
867 delete inst;
868 throw;
869 } catch (NotFound const&) {
870 delete inst;
871 throw;
872 }
873 }
874
875 template < typename GUM_SCALAR >
876 INLINE void PRMFactory< GUM_SCALAR >::incArray(const std::string& l_i, const std::string& r_i) {
879
880 if (model->isArray(l_i)) {
881 if (model->isInstance(r_i)) {
882 model->add(l_i, model->get(r_i));
883 } else {
884 GUM_ERROR(NotFound, "right value is not an instance")
885 }
886 } else {
887 GUM_ERROR(NotFound, "left value is no an array")
888 }
889 }
890
891 template < typename GUM_SCALAR >
892 INLINE void PRMFactory< GUM_SCALAR >::setReferenceSlot(const std::string& l_i,
893 const std::string& l_ref,
894 const std::string& r_i) {
895 auto model
897 std::vector< PRMInstance< GUM_SCALAR >* > lefts;
898 std::vector< PRMInstance< GUM_SCALAR >* > rights;
899
900 if (model->isInstance(l_i)) {
901 lefts.push_back(&(model->get(l_i)));
902 } else if (model->isArray(l_i)) {
903 for (const auto& elt: model->getArray(l_i))
904 lefts.push_back(elt);
905 } else {
906 GUM_ERROR(NotFound, "left value does not name an instance or an array")
907 }
908
909 if (model->isInstance(r_i)) {
910 rights.push_back(&(model->get(r_i)));
911 } else if (model->isArray(r_i)) {
912 for (const auto& elt: model->getArray(r_i))
913 rights.push_back(elt);
914 } else {
915 GUM_ERROR(NotFound, "left value does not name an instance or an array")
916 }
917
918 for (const auto l: lefts) {
919 for (const auto r: rights) {
920 auto& elt = l->type().get(l_ref);
922 l->add(elt.id(), *r);
923
924 } else {
925 GUM_ERROR(NotFound, "unfound reference slot")
926 }
927 }
928 }
929 }
930
931 template < typename GUM_SCALAR >
934 const std::string& name) {
935 std::vector< std::string > v;
936 decomposePath(name, v);
938 PRMReferenceSlot< GUM_SCALAR >* ref = nullptr;
940
941 for (size_t i = 0; i < v.size(); ++i) {
942 try {
943 switch (current->get(v[i]).elt_type()) {
945 ref = &(static_cast< PRMReferenceSlot< GUM_SCALAR >& >(current->get(v[i])));
946 elts.insert(ref);
947 current = &(/*const_cast<PRMClassElementContainer<GUM_SCALAR>&>*/ (ref->slotType()));
948 break;
949
952
953 if (i == v.size() - 1) {
954 elts.insert(&(current->get(v[i])));
955 break;
956 } else {
957 return nullptr;
958 }
959
960 default : {
961 return nullptr;
962 }
963 }
964 } catch (NotFound const&) { return nullptr; }
965 }
966
967 GUM_ASSERT(v.size() == elts.size());
968
969 current->setOutputNode(*(elts.back()), true);
970
971 return new PRMSlotChain< GUM_SCALAR >(name, elts);
972 }
973
974 template < typename GUM_SCALAR >
977 const std::vector< std::string >& chains,
978 std::vector< PRMClassElement< GUM_SCALAR >* >& inputs) {
979 bool retVal = false;
980
981 for (size_t i = 0; i < chains.size(); ++i) {
982 try {
983 inputs.push_back(&(c->get(chains[i])));
984 retVal = retVal || PRMClassElement< GUM_SCALAR >::isSlotChain(*(inputs.back()));
985 } catch (NotFound const&) {
986 inputs.push_back(_buildSlotChain_(c, chains[i]));
987 retVal = true;
988
989 if (inputs.back()) {
990 c->add(inputs.back());
991 } else {
992 GUM_ERROR(NotFound, "unknown slot chain")
993 }
994 }
995 }
996
997 PRMType* t = _retrieveCommonType_(inputs);
998
999 std::vector< std::pair< PRMClassElement< GUM_SCALAR >*, PRMClassElement< GUM_SCALAR >* > >
1000 toAdd;
1001
1002 for (const auto& elt: inputs) {
1003 if ((*elt).type() != (*t)) {
1005 PRMSlotChain< GUM_SCALAR >* sc = static_cast< PRMSlotChain< GUM_SCALAR >* >(elt);
1006 std::stringstream name;
1007
1008 for (Size idx = 0; idx < sc->chain().size() - 1; ++idx) {
1009 name << sc->chain().atPos(idx)->name() << ".";
1010 }
1011
1012 name << ".(" << t->name() << ")" << sc->lastElt().name();
1013
1014 try {
1015 toAdd.push_back(std::make_pair(elt, &(c->get(name.str()))));
1016 } catch (NotFound const&) {
1017 toAdd.push_back(std::make_pair(elt, _buildSlotChain_(c, name.str())));
1018 }
1019 } else {
1020 std::stringstream name;
1021 name << "(" << t->name() << ")" << elt->name();
1022 toAdd.push_back(std::make_pair(elt, &(c->get(name.str()))));
1023 }
1024 }
1025 }
1026
1027 return retVal;
1028 }
1029
1030 template < typename GUM_SCALAR >
1032 const std::vector< PRMClassElement< GUM_SCALAR >* >& elts) {
1033 const PRMType* current = nullptr;
1035 // Finding all types and super types
1036
1037 for (const auto& elt: elts) {
1038 try {
1039 current = &((*elt).type());
1040
1041 while (current != 0) {
1042 // Filling counters
1043 if (counters.exists(current->name())) {
1044 ++(counters[current->name()]);
1045 } else {
1046 counters.insert(current->name(), 1);
1047 }
1048
1049 // Loop guard
1050 if (current->isSubType()) {
1051 current = &(current->superType());
1052 } else {
1053 current = nullptr;
1054 }
1055 }
1056 } catch (OperationNotAllowed const&) {
1057 GUM_ERROR(WrongClassElement, "found a ClassElement<GUM_SCALAR> without a type")
1058 }
1059 }
1060
1061 // We need to find the most specialized (i.e. max depth) common type
1062 current = nullptr;
1063
1064 int max_depth = -1;
1065
1066 int current_depth = 0;
1067
1068 for (const auto& elt: counters) {
1069 if ((elt.second) == elts.size()) {
1070 current_depth = _typeDepth_(_retrieveType_(elt.first));
1071
1072 if (current_depth > max_depth) {
1073 max_depth = current_depth;
1074 current = _retrieveType_(elt.first);
1075 }
1076 }
1077 }
1078
1079 if (current) { return const_cast< PRMType* >(current); }
1080
1081 GUM_ERROR(NotFound, "could not find a common type")
1082 }
1083
1084 template < typename GUM_SCALAR >
1085 INLINE void
1087 const std::vector< std::string >& chains,
1088 const std::vector< float >& numbers,
1089 float leak,
1090 const std::vector< std::string >& labels) {
1092 GUM_ERROR(gum::FactoryInvalidState, "invalid state to add a noisy-or")
1093 }
1094
1096
1097 std::vector< PRMClassElement< GUM_SCALAR >* > parents;
1098
1099 for (const auto& elt: chains)
1100 parents.push_back(&(c->get(elt)));
1101
1102 PRMType* common_type = _retrieveCommonType_(parents);
1103
1104 for (size_t idx = 0; idx < parents.size(); ++idx) {
1105 if (parents[idx]->type() != (*common_type)) {
1106 PRMClassElement< GUM_SCALAR >* parent = parents[idx];
1107 // Either safe_name is an non existing slot chain or an existing cast
1108 // descendant
1109 std::string safe_name = parent->cast(*common_type);
1110
1111 if (!c->exists(safe_name)) {
1113 parents[idx] = _buildSlotChain_(c, safe_name);
1114 c->add(parents[idx]);
1115 } else {
1116 GUM_ERROR(NotFound, "unable to find parent")
1117 }
1118 } else {
1119 parents[idx] = &(c->get(safe_name));
1120 }
1121 }
1122 }
1123
1124 if (numbers.size() == 1) {
1125 auto impl = new gum::MultiDimNoisyORCompound< GUM_SCALAR >(leak, numbers.front());
1126 auto attr = new PRMScalarAttribute< GUM_SCALAR >(name, retrieveType("boolean"), impl);
1127 addAttribute(attr);
1128 } else if (numbers.size() == parents.size()) {
1132 = new gum::prm::PRMFuncAttribute< GUM_SCALAR >(name, retrieveType("boolean"), noisy);
1133
1134 for (size_t idx = 0; idx < numbers.size(); ++idx) {
1135 noisy->causalWeight(parents[idx]->type().variable(), numbers[idx]);
1136 }
1137
1138 addAttribute(attr);
1139 } else {
1140 GUM_ERROR(OperationNotAllowed, "invalid parameters for a noisy or")
1141 }
1142
1143 if (!labels.empty()) {
1144 GUM_ERROR(OperationNotAllowed, "labels definitions not handle for noisy-or")
1145 }
1146 }
1147
1148 template < typename GUM_SCALAR >
1149 INLINE PRMType* PRMFactory< GUM_SCALAR >::_retrieveType_(const std::string& name) const {
1150 PRMType* type = nullptr;
1151 std::string full_name;
1152
1153 // Looking for the type using its name
1154 if (_prm_->_typeMap_.exists(name)) {
1155 type = _prm_->_typeMap_[name];
1156 full_name = name;
1157 }
1158
1159 // Looking for the type in current package
1160 std::string prefixed = _addPrefix_(name);
1161 if (_prm_->_typeMap_.exists(prefixed)) {
1162 if (type == 0) {
1163 type = _prm_->_typeMap_[prefixed];
1164 full_name = prefixed;
1165 } else if (full_name != prefixed) {
1166 GUM_ERROR(DuplicateElement, "Type name '" << name << "' is ambiguous: specify full name.")
1167 }
1168 }
1169
1170 // Looking for the type relatively to current package
1171 std::string relatif_ns = currentPackage();
1172 size_t last_dot = relatif_ns.find_last_of('.');
1173 if (last_dot != std::string::npos) {
1174 relatif_ns = relatif_ns.substr(0, last_dot) + '.' + name;
1175 if (_prm_->_typeMap_.exists(relatif_ns)) {
1176 if (type == 0) {
1177 type = _prm_->_typeMap_[relatif_ns];
1178 full_name = relatif_ns;
1179 } else if (full_name != relatif_ns) {
1181 "Type name '" << name << "' is ambiguous: specify full name.");
1182 }
1183 }
1184 }
1185
1186
1187 // Looking for the type using all declared namespaces
1188 if (!_namespaces_.empty()) {
1189 auto ns_list = _namespaces_.back();
1190 for (gum::Size i = 0; i < ns_list->size(); ++i) {
1191 std::string ns = (*ns_list)[i];
1192 std::string ns_name = ns + "." + name;
1193 if (_prm_->_typeMap_.exists(ns_name)) {
1194 if (type == 0) {
1195 type = _prm_->_typeMap_[ns_name];
1196 full_name = ns_name;
1197 } else if (full_name != ns_name) {
1199 "Type name '" << name << "' is ambiguous: specify full name.");
1200 }
1201 }
1202 }
1203 }
1204
1205 if (type == 0) { GUM_ERROR(NotFound, "Type '" << name << "' not found, check imports.") }
1206
1207 return type;
1208 }
1209
1210 template < typename GUM_SCALAR >
1212 PRMFactory< GUM_SCALAR >::_retrieveClass_(const std::string& name) const {
1213 PRMClass< GUM_SCALAR >* a_class = nullptr;
1214 std::string full_name;
1215
1216 // Looking for the type using its name
1217 if (_prm_->_classMap_.exists(name)) {
1218 a_class = _prm_->_classMap_[name];
1219 full_name = name;
1220 }
1221
1222 // Looking for the type using current package
1223 std::string prefixed = _addPrefix_(name);
1224 if (_prm_->_classMap_.exists(prefixed)) {
1225 if (a_class == nullptr) {
1226 a_class = _prm_->_classMap_[prefixed];
1227 full_name = prefixed;
1228 } else if (full_name != prefixed) {
1230 "Class name '" << name << "' is ambiguous: specify full name.");
1231 }
1232 }
1233
1234 // Looking for the class using all declared namespaces
1235 if (!_namespaces_.empty()) {
1236 auto ns_list = _namespaces_.back();
1237 for (gum::Size i = 0; i < ns_list->size(); ++i) {
1238 std::string ns = (*ns_list)[i];
1239 std::string ns_name = ns + "." + name;
1240 if (_prm_->_classMap_.exists(ns_name)) {
1241 if (a_class == 0) {
1242 a_class = _prm_->_classMap_[ns_name];
1243 full_name = ns_name;
1244 } else if (full_name != ns_name) {
1246 "Class name '" << name << "' is ambiguous: specify full name.");
1247 }
1248 }
1249 }
1250 }
1251
1252 if (a_class == 0) { GUM_ERROR(NotFound, "Class '" << name << "' not found, check imports.") }
1253
1254 return a_class;
1255 }
1256
1257 template < typename GUM_SCALAR >
1259 PRMFactory< GUM_SCALAR >::_retrieveInterface_(const std::string& name) const {
1260 PRMInterface< GUM_SCALAR >* interface = nullptr;
1261 std::string full_name;
1262
1263 // Looking for the type using its name
1264 if (_prm_->_interfaceMap_.exists(name)) {
1265 interface = _prm_->_interfaceMap_[name];
1266 full_name = name;
1267 }
1268
1269 // Looking for the type using current package
1270 std::string prefixed = _addPrefix_(name);
1271 if (_prm_->_interfaceMap_.exists(prefixed)) {
1272 if (interface == nullptr) {
1273 interface = _prm_->_interfaceMap_[prefixed];
1274 full_name = prefixed;
1275 } else if (full_name != prefixed) {
1277 "Interface name '" << name << "' is ambiguous: specify full name.");
1278 }
1279 }
1280
1281 // Looking for the interf using all declared namespaces
1282 if (!_namespaces_.empty()) {
1283 auto ns_list = _namespaces_.back();
1284 // for( const auto & ns : *( _namespaces_.top()) ) {
1285 for (gum::Size i = 0; i < ns_list->size(); ++i) {
1286 std::string ns = (*ns_list)[i];
1287 std::string ns_name = ns + "." + name;
1288
1289 if (_prm_->_interfaceMap_.exists(ns_name)) {
1290 if (interface == nullptr) {
1291 interface = _prm_->_interfaceMap_[ns_name];
1292 full_name = ns_name;
1293 } else if (full_name != ns_name) {
1295 "Interface name '" << name << "' is ambiguous: specify full name.");
1296 }
1297 }
1298 }
1299 }
1300
1301 if (interface == nullptr) {
1302 GUM_ERROR(NotFound, "Interface '" << name << "' not found, check imports.")
1303 }
1304
1305 return interface;
1306 }
1307
1308 template < typename GUM_SCALAR >
1310 GUM_CONSTRUCTOR(PRMFactory);
1311 _prm_ = new PRM< GUM_SCALAR >();
1312 }
1313
1314 template < typename GUM_SCALAR >
1316 IPRMFactory(), _prm_(prm) {
1317 GUM_CONSTRUCTOR(PRMFactory);
1318 }
1319
1320 template < typename GUM_SCALAR >
1322 GUM_DESTRUCTOR(PRMFactory);
1323 while (!_namespaces_.empty()) {
1324 auto ns = _namespaces_.back();
1325 _namespaces_.pop_back();
1326 delete ns;
1327 }
1328 }
1329
1330 template < typename GUM_SCALAR >
1332 return _prm_;
1333 }
1334
1335 template < typename GUM_SCALAR >
1337 if (_stack_.size() == 0) { GUM_ERROR(NotFound, "no object being built") }
1338
1339 return _stack_.back()->obj_type();
1340 }
1341
1342 template < typename GUM_SCALAR >
1344 if (_stack_.size() == 0) { GUM_ERROR(NotFound, "no object being built") }
1345
1346 return _stack_.back();
1347 }
1348
1349 template < typename GUM_SCALAR >
1351 if (_stack_.size() == 0) { GUM_ERROR(NotFound, "no object being built") }
1352
1353 return _stack_.back();
1354 }
1355
1356 template < typename GUM_SCALAR >
1358 if (_stack_.size() > 0) {
1359 PRMObject* obj = _stack_.back();
1360 _stack_.pop_back();
1361 return obj;
1362 } else {
1363 return 0;
1364 }
1365 }
1366
1367 template < typename GUM_SCALAR >
1368 INLINE std::string PRMFactory< GUM_SCALAR >::currentPackage() const {
1369 return (_packages_.empty()) ? "" : _packages_.back();
1370 }
1371
1372 template < typename GUM_SCALAR >
1373 INLINE void PRMFactory< GUM_SCALAR >::startDiscreteType(const std::string& name,
1374 std::string super) {
1375 std::string real_name = _addPrefix_(name);
1376 if (_prm_->_typeMap_.exists(real_name)) {
1377 GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.")
1378 }
1379 if (super.empty()) {
1380 auto t = new PRMType(LabelizedVariable(real_name, "", 0));
1381 _stack_.push_back(t);
1382 } else {
1383 auto t = new PRMType(LabelizedVariable(real_name, "", 0));
1384 t->_superType_ = _retrieveType_(super);
1385 t->_label_map_ = new std::vector< Idx >();
1386 _stack_.push_back(t);
1387 }
1388 }
1389
1390 template < typename GUM_SCALAR >
1391 INLINE void PRMFactory< GUM_SCALAR >::addLabel(const std::string& l, std::string extends) {
1392 if (extends.empty()) {
1393 PRMType* t = static_cast< PRMType* >(_checkStack_(1, PRMObject::prm_type::TYPE));
1394 LabelizedVariable* var = dynamic_cast< LabelizedVariable* >(t->_var_);
1395
1396 if (!var) {
1397 GUM_ERROR(FatalError, "the current type's variable is not a LabelizedVariable.")
1398 } else if (t->_superType_) {
1399 GUM_ERROR(OperationNotAllowed, "current type is a subtype.")
1400 }
1401
1402 try {
1403 var->addLabel(l);
1404 } catch (DuplicateElement const&) {
1405 GUM_ERROR(DuplicateElement, "a label '" << l << "' already exists")
1406 }
1407 } else {
1408 PRMType* t = static_cast< PRMType* >(_checkStack_(1, PRMObject::prm_type::TYPE));
1409 LabelizedVariable* var = dynamic_cast< LabelizedVariable* >(t->_var_);
1410
1411 if (!var) {
1412 GUM_ERROR(FatalError, "the current type's variable is not a LabelizedVariable.")
1413 } else if (!t->_superType_) {
1414 GUM_ERROR(OperationNotAllowed, "current type is not a subtype.")
1415 }
1416
1417 bool found = false;
1418
1419 for (Idx i = 0; i < t->_superType_->_var_->domainSize(); ++i) {
1420 if (t->_superType_->_var_->label(i) == extends) {
1421 try {
1422 var->addLabel(l);
1423 } catch (DuplicateElement const&) {
1424 GUM_ERROR(DuplicateElement, "a label '" << l << "' already exists")
1425 }
1426
1427 t->_label_map_->push_back(i);
1428
1429 found = true;
1430 break;
1431 }
1432 }
1433
1434 if (!found) { GUM_ERROR(NotFound, "inexistent label in super type.") }
1435 }
1436 }
1437
1438 template < typename GUM_SCALAR >
1440 PRMType* t = static_cast< PRMType* >(_checkStack_(1, PRMObject::prm_type::TYPE));
1441
1442 if (!t->_isValid_()) {
1443 GUM_ERROR(OperationNotAllowed, "current type is not a valid subtype")
1444 } else if (t->variable().domainSize() < 2) {
1445 GUM_ERROR(OperationNotAllowed, "current type is not a valid discrete type")
1446 }
1447
1448 _prm_->_typeMap_.insert(t->name(), t);
1449
1450 _prm_->_types_.insert(t);
1451 _stack_.pop_back();
1452 }
1453
1454 template < typename GUM_SCALAR >
1455 INLINE void PRMFactory< GUM_SCALAR >::startDiscretizedType(const std::string& name) {
1456 std::string real_name = _addPrefix_(name);
1457 if (_prm_->_typeMap_.exists(real_name)) {
1458 GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.")
1459 }
1460 auto var = DiscretizedVariable< double >(real_name, "");
1461 auto t = new PRMType(var);
1462 _stack_.push_back(t);
1463 }
1464
1465 template < typename GUM_SCALAR >
1466 INLINE void PRMFactory< GUM_SCALAR >::addTick(double tick) {
1467 PRMType* t = static_cast< PRMType* >(_checkStack_(1, PRMObject::prm_type::TYPE));
1468 DiscretizedVariable< double >* var = dynamic_cast< DiscretizedVariable< double >* >(t->_var_);
1469
1470 if (!var) { GUM_ERROR(FatalError, "the current type's variable is not a LabelizedVariable.") }
1471
1472 try {
1473 var->addTick(tick);
1474 } catch (DefaultInLabel const&) {
1475 GUM_ERROR(OperationNotAllowed, "tick already in used for this variable")
1476 }
1477 }
1478
1479 template < typename GUM_SCALAR >
1481 PRMType* t = static_cast< PRMType* >(_checkStack_(1, PRMObject::prm_type::TYPE));
1482
1483 if (t->variable().domainSize() < 2) {
1484 GUM_ERROR(OperationNotAllowed, "current type is not a valid discrete type")
1485 }
1486
1487 _prm_->_typeMap_.insert(t->name(), t);
1488
1489 _prm_->_types_.insert(t);
1490 _stack_.pop_back();
1491 }
1492
1493 template < typename GUM_SCALAR >
1494 INLINE void
1495 PRMFactory< GUM_SCALAR >::addRangeType(const std::string& name, long minVal, long maxVal) {
1496 std::string real_name = _addPrefix_(name);
1497 if (_prm_->_typeMap_.exists(real_name)) {
1498 std::stringstream msg;
1499 msg << "\"" << real_name << "' is already used.";
1500 GUM_ERROR(DuplicateElement, msg.str())
1501 }
1502
1503 auto var = RangeVariable(real_name, "", minVal, maxVal);
1504 auto t = new PRMType(var);
1505
1506 if (t->variable().domainSize() < 2) {
1507 GUM_ERROR(OperationNotAllowed, "current type is not a valid discrete type")
1508 }
1509
1510 _prm_->_typeMap_.insert(t->name(), t);
1511 _prm_->_types_.insert(t);
1512 }
1513
1514 template < typename GUM_SCALAR >
1519
1520 template < typename GUM_SCALAR >
1521 INLINE void PRMFactory< GUM_SCALAR >::addAttribute(const std::string& type,
1522 const std::string& name) {
1524 startAttribute(type, name);
1525 endAttribute();
1526 }
1527
1528 template < typename GUM_SCALAR >
1529 INLINE void PRMFactory< GUM_SCALAR >::startAttribute(const std::string& type,
1530 const std::string& name,
1531 bool scalar_attr) {
1533 PRMAttribute< GUM_SCALAR >* a = nullptr;
1534
1535 if (PRMObject::isClass(*c) && (!scalar_attr)) {
1536 a = new PRMFormAttribute< GUM_SCALAR >(static_cast< PRMClass< GUM_SCALAR >& >(*c),
1537 name,
1538 *_retrieveType_(type));
1539
1540 } else {
1542 }
1543
1544 std::string dot = ".";
1545
1546 try {
1547 try {
1548 c->add(a);
1549 } catch (DuplicateElement const&) { c->overload(a); }
1550 } catch (Exception const&) {
1551 if (a != nullptr && (!c->exists(a->id()))) { delete a; }
1552 }
1553
1554 _stack_.push_back(a);
1555 }
1556
1557 template < typename GUM_SCALAR >
1558 INLINE void PRMFactory< GUM_SCALAR >::continueAttribute(const std::string& name) {
1560
1561 if (!c->exists(name)) GUM_ERROR(NotFound, "Attribute " << name << "not found")
1562
1563 auto& a = c->get(name);
1564
1566 GUM_ERROR(OperationNotAllowed, "Element " << name << " not an attribute")
1567
1568 _stack_.push_back(&a);
1569 }
1570
1571 template < typename GUM_SCALAR >
1576
1577 template < typename GUM_SCALAR >
1578 INLINE void PRMFactory< GUM_SCALAR >::startSystem(const std::string& name) {
1579 if (_prm_->_systemMap_.exists(name)) {
1580 GUM_ERROR(DuplicateElement, "'" << name << "' is already used.")
1581 }
1583 _stack_.push_back(model);
1584 _prm_->_systemMap_.insert(model->name(), model);
1585 _prm_->_systems_.insert(model);
1586 }
1587
1588 template < typename GUM_SCALAR >
1590 try {
1593 _stack_.pop_back();
1594 model->instantiate();
1595 } catch (Exception const&) { GUM_ERROR(FatalError, "could not create system") }
1596 }
1597
1598 template < typename GUM_SCALAR >
1599 INLINE void PRMFactory< GUM_SCALAR >::addInstance(const std::string& type,
1600 const std::string& name) {
1601 auto c = _retrieveClass_(type);
1602
1603 // If class contains parameters, calls the proper addIsntance method
1604 if (c->parameters().size() > 0) {
1606 addInstance(type, name, params);
1607
1608 } else {
1609 _addInstance_(c, name);
1610 }
1611 }
1612
1613 template < typename GUM_SCALAR >
1614 INLINE void
1616 const std::string& name,
1617 const HashTable< std::string, double >& params) {
1618 auto c = _retrieveClass_(type);
1619
1620 if (c->parameters().empty()) {
1621 if (params.empty()) {
1622 _addInstance_(c, name);
1623 } else {
1624 GUM_ERROR(OperationNotAllowed, "Class " + type + " does not have parameters")
1625 }
1626
1627 } else {
1628 auto my_params = params;
1629 // Adding all parameters to my_params
1630 for (const auto& p: c->parameters()) {
1631 if (!my_params.exists(p->name())) { my_params.insert(p->name(), p->value()); }
1632 }
1633
1634 // Building sub class name using my_params
1635 std::stringstream sBuff;
1636 sBuff << c->name() << "<";
1637
1638 for (const auto& p: my_params) {
1639 sBuff << p.first << "=" << p.second << ",";
1640 }
1641
1642 // Removing last , and adding closing >
1643 std::string sub_c = sBuff.str().substr(0, sBuff.str().size() - 1) + ">";
1644
1645 // Adding class in current package
1646 try {
1647 auto pck_cpy = _packages_;
1648 _packages_.clear();
1649
1650 startClass(sub_c, c->name());
1651
1652 // Update inherited parameters
1653 for (auto p: my_params) {
1654 auto type = static_cast< PRMParameter< GUM_SCALAR >& >(c->get(p.first)).valueType();
1656 addParameter("int", p.first, p.second);
1657
1658 } else {
1659 addParameter("real", p.first, p.second);
1660 }
1661 }
1662
1663 endClass();
1664
1665 _packages_ = pck_cpy;
1666
1667 } catch (DuplicateElement const&) {
1668 // Sub Class already exists in this system
1669 }
1670 c = _retrieveClass_(sub_c);
1671 _addInstance_(c, name);
1672 }
1673 }
1674
1675 template < typename GUM_SCALAR >
1677 const std::string& name) {
1678 PRMInstance< GUM_SCALAR >* i = nullptr;
1679 try {
1680 auto s
1682 i = new PRMInstance< GUM_SCALAR >(name, *type);
1683 s->add(i);
1684
1685 } catch (OperationNotAllowed const&) {
1686 if (i) { delete i; }
1687 throw;
1688 }
1689 }
1690
1691 template < typename GUM_SCALAR >
1692 INLINE std::string PRMFactory< GUM_SCALAR >::_addPrefix_(const std::string& str) const {
1693 if (!_packages_.empty()) {
1694 std::string full_name = _packages_.back();
1695 full_name.append(".");
1696 full_name.append(str);
1697 return full_name;
1698 } else {
1699 return str;
1700 }
1701 }
1702
1703 template < typename GUM_SCALAR >
1705 // Don't forget that Idx are unsigned int
1706 if (_stack_.size() - i > _stack_.size()) {
1707 GUM_ERROR(FactoryInvalidState, "illegal sequence of calls")
1708 }
1709
1710 PRMObject* obj = _stack_[_stack_.size() - i];
1711
1712 if (obj->obj_type() != obj_type) {
1713 GUM_ERROR(FactoryInvalidState, "illegal sequence of calls")
1714 }
1715
1716 return obj;
1717 }
1718
1719 template < typename GUM_SCALAR >
1722 // Don't forget that Idx are unsigned int
1723 if (_stack_.size() - i > _stack_.size()) {
1724 GUM_ERROR(FactoryInvalidState, "illegal sequence of calls")
1725 }
1726
1727 PRMObject* obj = _stack_[_stack_.size() - i];
1728
1729 if ((obj->obj_type() == PRMObject::prm_type::CLASS)
1731 return static_cast< PRMClassElementContainer< GUM_SCALAR >* >(obj);
1732 } else {
1733 GUM_ERROR(FactoryInvalidState, "illegal sequence of calls")
1734 }
1735 }
1736
1737 template < typename GUM_SCALAR >
1739 Idx i,
1741 // Don't forget that Idx are unsigned int
1742 if (_stack_.size() - i > _stack_.size()) {
1743 GUM_ERROR(FactoryInvalidState, "illegal sequence of calls")
1744 }
1745
1747 = dynamic_cast< PRMClassElement< GUM_SCALAR >* >(_stack_[_stack_.size() - i]);
1748
1749 if (obj == 0) { GUM_ERROR(FactoryInvalidState, "illegal sequence of calls") }
1750
1751 if (obj->elt_type() != elt_type) {
1752 GUM_ERROR(FactoryInvalidState, "illegal sequence of calls")
1753 }
1754
1755 return obj;
1756 }
1757
1758 template < typename GUM_SCALAR >
1760 int depth = 0;
1761 const PRMType* current = t;
1762
1763 while (current->isSubType()) {
1764 ++depth;
1765 current = &(current->superType());
1766 }
1767
1768 return depth;
1769 }
1770
1771 template < typename GUM_SCALAR >
1772 INLINE void PRMFactory< GUM_SCALAR >::pushPackage(const std::string& name) {
1773 _packages_.push_back(name);
1774 _namespaces_.push_back(new List< std::string >());
1775 }
1776
1777 template < typename GUM_SCALAR >
1779 std::string plop = currentPackage();
1780
1781 if (!_packages_.empty()) {
1782 std::string s = _packages_.back();
1783 _packages_.pop_back();
1784
1785 if (_namespaces_.size() > 0) {
1786 delete _namespaces_.back();
1787 _namespaces_.pop_back();
1788 }
1789 return s;
1790 }
1791
1792 return plop;
1793 }
1794
1795 template < typename GUM_SCALAR >
1796 INLINE void PRMFactory< GUM_SCALAR >::addImport(const std::string& name) {
1797 if (name.size() == 0) { GUM_ERROR(OperationNotAllowed, "illegal import name") }
1798 if (_namespaces_.empty()) { _namespaces_.push_back(new List< std::string >()); }
1799 _namespaces_.back()->push_back(name);
1800 }
1801
1802 template < typename GUM_SCALAR >
1803 INLINE void PRMFactory< GUM_SCALAR >::setReferenceSlot(const std::string& l_i,
1804 const std::string& r_i) {
1805 size_t pos = l_i.find_last_of('.');
1806
1807 if (pos != std::string::npos) {
1808 std::string l_ref = l_i.substr(pos + 1, std::string::npos);
1809 setReferenceSlot(l_i.substr(0, pos), l_ref, r_i);
1810 } else {
1811 GUM_ERROR(NotFound, "left value does not name an instance or an array")
1812 }
1813 }
1814
1815 template < typename GUM_SCALAR >
1818 return *_retrieveClass_(name);
1819 }
1820
1821 template < typename GUM_SCALAR >
1822 INLINE PRMType& PRMFactory< GUM_SCALAR >::retrieveType(const std::string& name) {
1823 return *_retrieveType_(name);
1824 }
1825
1826 template < typename GUM_SCALAR >
1828 const std::vector< PRMClassElement< GUM_SCALAR >* >& elts) {
1829 return *(_retrieveCommonType_(elts));
1830 }
1831
1832 template < typename GUM_SCALAR >
1833 INLINE bool PRMFactory< GUM_SCALAR >::isClassOrInterface(const std::string& type) const {
1834 try {
1835 _retrieveClass_(type);
1836 return true;
1837
1838 } catch (NotFound const&) {
1839 } catch (DuplicateElement const&) {}
1840
1841 try {
1842 _retrieveInterface_(type);
1843 return true;
1844
1845 } catch (NotFound const&) {
1846 } catch (DuplicateElement const&) {}
1847
1848 return false;
1849 }
1850
1851 template < typename GUM_SCALAR >
1852 INLINE bool PRMFactory< GUM_SCALAR >::isArrayInCurrentSystem(const std::string& name) const {
1853 const PRMSystem< GUM_SCALAR >* system
1854 = static_cast< const PRMSystem< GUM_SCALAR >* >(getCurrent());
1855 return (system && system->isArray(name));
1856 }
1857
1858 template < typename GUM_SCALAR >
1859 INLINE void
1860 PRMFactory< GUM_SCALAR >::setRawCPFByColumns(const std::vector< std::string >& array) {
1862
1863 auto a = static_cast< PRMFormAttribute< GUM_SCALAR >* >(
1865
1866 if (a->formulas().domainSize() != array.size()) {
1867 GUM_ERROR(OperationNotAllowed, "illegal CPF size")
1868 }
1869
1870 if (a->formulas().nbrDim() == 1) {
1871 setRawCPFByLines(array);
1872
1873 } else {
1874 Instantiation inst(a->formulas());
1875 Instantiation jnst;
1876 for (auto idx = inst.variablesSequence().rbegin(); idx != inst.variablesSequence().rend();
1877 --idx) {
1878 jnst.add(**idx);
1879 }
1880
1881 jnst.setFirst();
1882 auto idx = (std::size_t)0;
1883 while ((!jnst.end()) && idx < array.size()) {
1884 inst.setVals(jnst);
1885 a->formulas().set(inst, array[idx]);
1886 jnst.inc();
1887 ++idx;
1888 }
1889
1890 // Generate cpf by calling it
1891 a->cpf();
1892 }
1893 }
1894
1895 template < typename GUM_SCALAR >
1896 INLINE void
1897 PRMFactory< GUM_SCALAR >::setRawCPFByLines(const std::vector< std::string >& array) {
1899
1900 auto a = static_cast< PRMFormAttribute< GUM_SCALAR >* >(
1902
1903 if (a->formulas().domainSize() != array.size()) {
1904 GUM_ERROR(OperationNotAllowed, "illegal CPF size")
1905 }
1906
1907 a->formulas().populate(array);
1908
1910 a->cpf();
1911 }
1912
1913 } /* namespace prm */
1914} /* namespace gum */
Headers of PRMFactory.
Headers of gum::PRMFormAttribute.
Headers of gum::PRMAttribute.
Exception : default in label.
Base class for discrete random variable.
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
virtual Size domainSize() const =0
Class for discretized random variable.
DiscretizedVariable & addTick(const T_TICKS &aTick)
add a tick.
Exception : a similar element already exists.
Base class for all aGrUM's exceptions.
Definition exceptions.h:118
Exception : invalid state error.
Exception : fatal (unknown ?) error.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
bool empty() const noexcept
Indicates whether the hash table is empty.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Class for assigning/browsing values to tuples of discrete variables.
const Sequence< const DiscreteVariable * > & variablesSequence() const final
Returns the sequence of DiscreteVariable of this instantiation.
void incIn(const Instantiation &i)
Operator increment for the variables in i.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
bool end() const
Returns true if the Instantiation reached the end.
void setFirstIn(const Instantiation &i)
Assign the first values in the Instantiation for the variables in i.
void add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
void inc()
Operator increment.
void setFirst()
Assign the first values to the tuple of the Instantiation.
class LabelizedVariable
LabelizedVariable & addLabel(const std::string &aLabel)
add a label with a new index (we assume that we will NEVER remove a label)
virtual void populate(const std::vector< GUM_SCALAR > &v) const
Automatically fills this MultiDimContainer with the values in v.
GUM_SCALAR causalWeight(const DiscreteVariable &v) const
Copy of a multiDimICIModel.
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
Exception : wrong subtype or subclass.
Defines a discrete random variable over an integer interval.
Size size() const noexcept
Returns the size of the sequence.
bool exists(const Key &k) const
Check the existence of k in the sequence.
const Key & back() const
Returns the last element of the sequence.
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
void insert(const Key &k)
Inserts a new element into the set.
Definition set_tpl.h:539
bool empty() const noexcept
Indicates whether the set is the empty set.
Definition set_tpl.h:642
Exception : wrong type for this operation.
const std::string & name() const
returns the name of the variable
Exception: wrong PRMClassElement for this operation.
Idx label() const
Returns the label's index on which this aggregate applies.
virtual PRMType & type()
See gum::PRMClassElement::type().
static AggregateType str2enum(const std::string &str)
Static method which returns the AggregateType given its string representation.
AggregateType agg_type() const
Returns the aggregate of *this.
bool hasLabel() const
Returns true if the label is defined.
void setLabel(Idx idx)
Set the aggregator's label.
MultiDimImplementation< GUM_SCALAR > * buildImpl() const
Returns a pointer over an empty gum::MultiDimImplementation of the good type for this PRMAggregate.
const std::string & labelValue() const
See gum::PRMClassElement::elt_type().
PRMAttribute is a member of a Class in a PRM.
virtual const Tensor< GUM_SCALAR > & cpf() const =0
See gum::PRMClassElement::cpf().
virtual PRMType & type()=0
See gum::PRMClassElement::type().
<agrum/PRM/classElementContainer.h>
virtual NodeId overload(PRMClassElement< GUM_SCALAR > *elt)=0
Add a PRMClassElement<GUM_SCALAR> which overload an inherited PRMClassElement<GUM_SCALAR>.
virtual PRMClassElement< GUM_SCALAR > & get(const std::string &name)=0
Getter on a member of this PRMClassElementContainer.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
virtual void addArc(const std::string &tail, const std::string &head)=0
Add an arc between two PRMClassElement<GUM_SCALAR>.
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)=0
Add a PRMClassElement<GUM_SCALAR> to this PRMClassElementContainer.
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 setOutputNode(const PRMClassElement< GUM_SCALAR > &elt, bool b)
Set the output flag value of id at b.
Abstract class representing an element of PRM class.
static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMSlotChain.
virtual std::string cast(const PRMType &t) const
Returns the name of the cast descendant with PRMType t of this PRMClassElement.
static INLINE bool isAggregate(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMAggregate.
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.
static INLINE bool isReferenceSlot(const PRMClassElement< GUM_SCALAR > &elt)
Returns true if obj_ptr is of type PRMReferenceSlot.
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
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
virtual void addArc(const std::string &tail, const std::string &head)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::addArc().
PRMClassElement< GUM_SCALAR > & get(NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::add(PRMClassElement<GUM_SCALAR>*).
const Set< PRMInterface< GUM_SCALAR > * > & implements() const
Returns the Set of PRMInterface<GUM_SCALAR> implemented by this Class<GUM_SCALAR>.
virtual NodeId overload(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::overload(PRMClassElement<GUM_SCALAR>*).
virtual bool isArrayInCurrentSystem(const std::string &name) const override
PRMClassElementContainer< GUM_SCALAR > * _checkStackContainter_(Idx i)
Adds prefix to str iff prefix != "".
virtual void startAttribute(const std::string &type, const std::string &name, bool scalar_atttr=false) override
Tells the factory that we start an attribute declaration.
PRMObject * _checkStack_(Idx i, PRMObject::prm_type obj_type)
Return a pointer on a PRMObject at stack.size() - i position after checking the type of the object gi...
virtual ~PRMFactory()
Destructor.
void endAggregator()
Finishes an aggregate declaration.
virtual void addImport(const std::string &name) override
Add an import for namespace lookup.
std::string _addPrefix_(const std::string &str) const
Adds prefix to str iff prefix != "".
virtual void addAggregator(const std::string &name, const std::string &agg_type, const std::vector< std::string > &chains, const std::vector< std::string > &params, std::string type="") override
Add an aggregator in the current declared class.
virtual void addInstance(const std::string &type, const std::string &name) override
Add an instance to the model.
void addParameter(const std::string &type, const std::string &name, double value) override
Add a parameter to the current class with a default value.
virtual void incArray(const std::string &l_i, const std::string &r_i) override
Add an instance to an array.
PRMSlotChain< GUM_SCALAR > * _buildSlotChain_(PRMClassElementContainer< GUM_SCALAR > *start, const std::string &name)
This methods build a PRMSlotChain<GUM_SCALAR> given a starting element and a string.
virtual void addParent(const std::string &name) override
Tells the factory that we add a parent to the current declared attribute.
virtual void pushPackage(const std::string &name) override
Define the current package.
virtual std::string currentPackage() const override
virtual bool isClassOrInterface(const std::string &type) const override
void setRawCPFByLines(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
void startAggregator(const std::string &name, const std::string &agg_type, const std::string &rv_type, const std::vector< std::string > &params)
Start an aggregator declaration.
virtual void addTick(double tick) override
Add a tick to the current discretized type.
PRMType & retrieveType(const std::string &name)
Returns a reference over a PRMType given its name.
virtual void endSystem() override
Tells the factory that we finished declaring a model.
virtual void addRangeType(const std::string &name, long minVal, long maxVal) override
Add a range variable type declaration.
virtual void setReferenceSlot(const std::string &left_instance, const std::string &left_reference, const std::string &right_instance) override
Instantiate a reference in the current model.
PRMType * _retrieveCommonType_(const std::vector< PRMClassElement< GUM_SCALAR > * > &elts)
Retrieve the common PRMType of a vector of PRMClassElement<GUM_SCALAR>.
virtual void setCPFByFloatRule(const std::vector< std::string > &labels, const std::vector< float > &values) override
Fills the CPF using a rule.
PRMFactory()
Default constructor.
virtual void addArray(const std::string &type, const std::string &name, Size size) override
Creates an array with the given number of instances of the given type.
PRMClass< GUM_SCALAR > & retrieveClass(const std::string &name)
Returns a reference over a Class<GUM_SCALAR> given its name.
virtual void addNoisyOrCompound(const std::string &name, const std::vector< std::string > &chains, const std::vector< float > &numbers, float leak, const std::vector< std::string > &label) override
Add a compound noisy-or as an PRMAttribute<GUM_SCALAR> to the current Class<GUM_SCALAR>.
PRMInterface< GUM_SCALAR > * _retrieveInterface_(const std::string &name) const
Returns a pointer on an interface given it's name. Used when building models, meaning that the interf...
std::vector< PRMObject * > _stack_
A stack used to keep track of created PRMObject.
PRM< GUM_SCALAR > * _prm_
The pointer on the PRM<GUM_SCALAR> built by this factory.
virtual void setRawCPFByFloatColumns(const std::vector< float > &array) override
Gives the factory the CPF in its raw form.
PRMClass< GUM_SCALAR > * _retrieveClass_(const std::string &name) const
Returns a pointer on a class given it's name. Used when building models, meaning that the class name ...
PRMType & retrieveCommonType(const std::vector< PRMClassElement< GUM_SCALAR > * > &elts)
Returns a pointer on the PRM<GUM_SCALAR> created by this factory.
bool _retrieveInputs_(PRMClass< GUM_SCALAR > *c, const std::vector< std::string > &chains, std::vector< PRMClassElement< GUM_SCALAR > * > &inputs)
Retrieve inputs for an PRMAggregate.
void _addParent_(PRMClassElementContainer< GUM_SCALAR > *c, PRMAttribute< GUM_SCALAR > *agg, const std::string &name)
Add a parent to an attribute.
virtual void setCPFByRule(const std::vector< std::string > &labels, const std::vector< GUM_SCALAR > &values)
Fills the CPF using a rule.
virtual void addReferenceSlot(const std::string &type, const std::string &name, bool isArray) override
Tells the factory that we started declaring a slot.
virtual void endAttribute() override
Tells the factory that we finished declaring an attribute.
virtual void startClass(const std::string &c, const std::string &ext="", const Set< std::string > *implements=nullptr, bool delayInheritance=false) override
Tells the factory that we start a class declaration.
virtual std::string popPackage() override
Pop the current package from the package stack.
virtual PRMObject::prm_type currentType() const override
void setRawCPFByColumns(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
int _typeDepth_(const PRMType *t)
Returns the inheritance depth of a PRMType.
virtual PRMObject * getCurrent() override
virtual void continueClass(const std::string &c) override
Continue the declaration of a class.
virtual void endClass(bool checkImplementations=true) override
Tells the factory that we finished a class declaration.
virtual void startSystem(const std::string &name) override
Tells the factory that we started declaring a model.
virtual void setRawCPFByFloatLines(const std::vector< float > &array) override
Gives the factory the CPF in its raw form.
std::vector< std::string > _packages_
The prefix used for classes and types names. It is normally the namespace of the corresponding compil...
void continueAggregator(const std::string &name)
Conitnues an aggregator declaration.
virtual void addAttribute(const std::string &type, const std::string &name) override
Add an attribute to an interface.
virtual void continueAttribute(const std::string &name) override
Continues the declaration of an attribute.
virtual void endDiscretizedType() override
End the current discretized type declaration.
virtual void endInterface() override
Tells the factory that we finished an interface declaration.
virtual void startDiscreteType(const std::string &name, std::string super="") override
Start a discrete subtype declaration.
PRM< GUM_SCALAR > * prm() const
Returns a pointer on the PRM<GUM_SCALAR> created by this factory.
PRMType * _retrieveType_(const std::string &name) const
Returns a pointer on a PRMType given it's name. Since the type can be given either with it's local na...
virtual void startDiscretizedType(const std::string &name) override
Start a discretized type declaration.
void _addInstance_(PRMClass< GUM_SCALAR > *type, const std::string &name)
Adds a instance to the current model.
std::vector< List< std::string > * > _namespaces_
Set of all declared namespaces.
virtual PRMObject * closeCurrent() override
Close current object being built.
virtual void startInterface(const std::string &i, const std::string &ext="", bool delayInheritance=false) override
Tells the factory that we start an interface declaration.
virtual void endDiscreteType() override
End the current discrete type declaration.
virtual void continueInterface(const std::string &name) override
Continue the declaration of an interface.
void _checkInterfaceImplementation_(PRMClass< GUM_SCALAR > *c)
Check if c implements correctly all his interfaces.
virtual void addLabel(const std::string &l, std::string ext="") override
Add a label to the current discrete type.
<agrum/PRM/elements/formAttribute.h>
virtual MultiDimImplementation< std::string > & formulas()
<agrum/PRM/elements/funcAttribute.h>
An PRMInstance is a Bayesian network fragment defined by a Class and used in a PRMSystem.
Definition PRMInstance.h:79
An PRMInterface is implemented by a Class<GUM_SCALAR> and defines a set of PRMReferenceSlot<GUM_SCALA...
Abstract base class for any element defined in a PRM.
Definition PRMObject.h:75
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).
<agrum/PRM/elements/scalarAttribute.h>
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
Sequence< PRMClassElement< GUM_SCALAR > * > & chain()
Return the sequence representing the chain of elements in this PRMSlotChain.
PRMClassElement< GUM_SCALAR > & lastElt()
Returns the last element of the slot chain, typically this is an gum::PRMAttribute or a gum::PRMAggre...
bool isMultiple() const
Return true if this slot chain contains at least one multiple reference slot.
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition PRMSystem.h:70
PRMInstance< GUM_SCALAR > & get(NodeId id)
Returns an PRMInstance given it's NodeId in the relational skeleton.
void instantiate()
Instantiate all the PRMInstance in this PRMSystem.
bool isInstance(const std::string &name) const
Returns true if an PRMInstance with the given name exists.
void addArray(const std::string &array, PRMClassElementContainer< GUM_SCALAR > &type)
Add an array of instances in this system. If the array doesn't exists it is created.
bool isArray(const std::string &name) const
Returns true if an array with the given name exists.
NodeId add(PRMInstance< GUM_SCALAR > *i)
Add an PRMInstance to this system.
This is a decoration of the DiscreteVariable class.
Definition PRMType.h:78
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition PRMType_inl.h:64
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition PRM.h:74
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
Headers files for the gum::FormulaPart and gum::Formula classes.
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
namespace for all probabilistic relational models entities
Definition agrum.h:68
void decomposePath(const std::string &path, std::vector< std::string > &v)
Decompose a string in a vector of strings using "." as separators.
Definition utils_prm.cpp:48
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
non-template interface-like parent for every PRM Factory
Definition IPRMFactory.h:71