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