aGrUM  0.14.2
PRMFactory_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
26 #include <agrum/PRM/PRMFactory.h>
27 
28 #include <iostream>
29 #include <sstream>
30 
32 
35 
38 
39 namespace gum {
40 
41  namespace prm {
42 
43  template < typename GUM_SCALAR >
44  INLINE void
45  PRMFactory< GUM_SCALAR >::startClass(const std::string& name,
46  const std::string& extends,
47  const Set< std::string >* implements,
48  bool delayInheritance) {
49  std::string real_name = __addPrefix(name);
50  if (__prm->__classMap.exists(real_name)
51  || __prm->__interfaceMap.exists(real_name)) {
52  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
53  }
54  PRMClass< GUM_SCALAR >* c = nullptr;
55  PRMClass< GUM_SCALAR >* mother = nullptr;
57 
58  if (implements != 0) {
59  for (const auto& imp : *implements) {
60  impl.insert(__retrieveInterface(imp));
61  }
62  }
63 
64  if (extends != "") { mother = __retrieveClass(extends); }
65 
66  if ((extends == "") && impl.empty()) {
67  c = new PRMClass< GUM_SCALAR >(real_name);
68  } else if ((extends != "") && impl.empty()) {
69  c = new PRMClass< GUM_SCALAR >(real_name, *mother, delayInheritance);
70  } else if ((extends == "") && (!impl.empty())) {
71  c = new PRMClass< GUM_SCALAR >(real_name, impl, delayInheritance);
72  } else if ((extends != "") && (!impl.empty())) {
73  c = new PRMClass< GUM_SCALAR >(real_name, *mother, impl, delayInheritance);
74  }
75 
76  __prm->__classMap.insert(c->name(), c);
77  __prm->__classes.insert(c);
78  __stack.push_back(c);
79  }
80 
81  template < typename GUM_SCALAR >
82  INLINE void PRMFactory< GUM_SCALAR >::continueClass(const std::string& name) {
83  std::string real_name = __addPrefix(name);
84  if (!(__prm->__classMap.exists(real_name))) {
85  std::stringstream msg;
86  msg << "'" << real_name << "' not found";
87  GUM_ERROR(NotFound, msg.str());
88  }
89  __stack.push_back(&(__prm->getClass(real_name)));
90  }
91 
92  template < typename GUM_SCALAR >
93  INLINE void PRMFactory< GUM_SCALAR >::endClass(bool checkImplementations) {
95  __checkStack(1, PRMObject::prm_type::CLASS));
96 
97  if (checkImplementations) { __checkInterfaceImplementation(c); }
98 
99  __stack.pop_back();
100  }
101 
102  template < typename GUM_SCALAR >
105  try {
106  for (const auto& i : c->implements()) {
107  try {
108  for (const auto& node : i->containerDag().nodes()) {
109  std::string name = i->get(node).name();
110 
111  switch (i->get(node).elt_type()) {
114  if ((c->get(name).elt_type()
116  || (c->get(name).elt_type()
118  if (!c->get(name).type().isSubTypeOf(i->get(name).type())) {
119  std::stringstream msg;
120  msg << "class " << c->name()
121  << " does not respect interface ";
122  GUM_ERROR(TypeError, msg.str() + i->name());
123  }
124  } else {
125  std::stringstream msg;
126  msg << "class " << c->name() << " does not respect interface ";
127  GUM_ERROR(TypeError, msg.str() + i->name());
128  }
129 
130  break;
131  }
132 
134  if (c->get(name).elt_type()
136  const PRMReferenceSlot< GUM_SCALAR >& ref_i =
137  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
138  i->get(name));
139  const PRMReferenceSlot< GUM_SCALAR >& ref_this =
140  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
141  c->get(name));
142 
143  if (!ref_this.slotType().isSubTypeOf(ref_i.slotType())) {
144  std::stringstream msg;
145  msg << "class " << c->name()
146  << " does not respect interface ";
147  GUM_ERROR(TypeError, msg.str() + i->name());
148  }
149  } else {
150  std::stringstream msg;
151  msg << "class " << c->name() << " does not respect interface ";
152  GUM_ERROR(TypeError, msg.str() + i->name());
153  }
154 
155  break;
156  }
157 
159  // Nothing to check: they are automatically inherited
160  break;
161  }
162 
163  default: {
164  std::string msg =
165  "unexpected ClassElement<GUM_SCALAR> in interface ";
166  GUM_ERROR(FatalError, msg + i->name());
167  }
168  }
169  }
170  } catch (NotFound&) {
171  std::stringstream msg;
172  msg << "class " << c->name() << " does not respect interface ";
173  GUM_ERROR(TypeError, msg.str() + i->name());
174  }
175  }
176  } catch (NotFound&) {
177  // this Class<GUM_SCALAR> does not implement any
178  // PRMInterface<GUM_SCALAR>
179  }
180  }
181 
182  template < typename GUM_SCALAR >
183  INLINE void
185  const std::string& extends,
186  bool delayInheritance) {
187  std::string real_name = __addPrefix(name);
188  if (__prm->__classMap.exists(real_name)
189  || __prm->__interfaceMap.exists(real_name)) {
190  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
191  }
192  PRMInterface< GUM_SCALAR >* i = nullptr;
193  PRMInterface< GUM_SCALAR >* super = nullptr;
194 
195  if (extends != "") { super = __retrieveInterface(extends); }
196 
197  if (super != nullptr) {
198  i = new PRMInterface< GUM_SCALAR >(real_name, *super, delayInheritance);
199  } else {
200  i = new PRMInterface< GUM_SCALAR >(real_name);
201  }
202 
203  __prm->__interfaceMap.insert(i->name(), i);
204  __prm->__interfaces.insert(i);
205  __stack.push_back(i);
206  }
207 
208  template < typename GUM_SCALAR >
209  INLINE void
211  std::string real_name = __addPrefix(name);
212  if (!__prm->__interfaceMap.exists(real_name)) {
213  GUM_ERROR(DuplicateElement, "'" << real_name << "' not found.");
214  }
215 
216  PRMInterface< GUM_SCALAR >* i = __retrieveInterface(real_name);
217  __stack.push_back(i);
218  }
219 
220  template < typename GUM_SCALAR >
221  INLINE void
223  PRMClass< GUM_SCALAR >* c = static_cast< PRMClass< GUM_SCALAR >* >(
224  __checkStack(1, PRMObject::prm_type::CLASS));
225  c->add(attr);
226  Size count = 0;
228  attr->cpf().variablesSequence();
229 
230  for (const auto& node : c->containerDag().nodes()) {
231  try {
232  if (vars.exists(&(c->get(node).type().variable()))) {
233  ++count;
234 
235  if (&(attr->type().variable()) != &(c->get(node).type().variable())) {
236  c->addArc(c->get(node).safeName(), attr->safeName());
237  }
238  }
239  } catch (OperationNotAllowed&) {}
240  }
241 
242  if (count != attr->cpf().variablesSequence().size()) {
243  GUM_ERROR(NotFound, "unable to found all parents of this attribute");
244  }
245  }
246 
247  template < typename GUM_SCALAR >
251  const std::string& name) {
252  try {
253  PRMClassElement< GUM_SCALAR >& elt = c->get(name);
254 
255  switch (elt.elt_type()) {
258  "can not add a reference slot as a parent of an attribute");
259  break;
260  }
261 
263  if (static_cast< PRMSlotChain< GUM_SCALAR >& >(elt).isMultiple()) {
265  "can not add a multiple slot chain to an attribute");
266  }
267 
268  c->addArc(name, a->name());
269 
270  break;
271  }
272 
275  c->addArc(name, a->name());
276  break;
277  }
278 
279  default: { GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR>"); }
280  }
281  } catch (NotFound&) {
282  // Check if name is a slot chain
283  PRMSlotChain< GUM_SCALAR >* sc = __buildSlotChain(c, name);
284 
285  if (sc == nullptr) {
286  std::string msg =
287  "found no ClassElement<GUM_SCALAR> with the given name ";
288  GUM_ERROR(NotFound, msg + name);
289  } else if (!sc->isMultiple()) {
290  c->add(sc);
291  c->addArc(sc->name(), a->name());
292  } else {
293  delete sc;
295  "Impossible to add a multiple reference slot as"
296  " direct parent of an PRMAttribute<GUM_SCALAR>.");
297  }
298  }
299  }
300 
301 
302  template < typename GUM_SCALAR >
303  INLINE void PRMFactory< GUM_SCALAR >::addParent(const std::string& name) {
304  PRMClassElementContainer< GUM_SCALAR >* c = __checkStackContainter(2);
305  try {
306  // Retrieving pointers
309  __addParent(c, a, name);
310  } catch (FactoryInvalidState&) {
311  auto agg = static_cast< PRMAggregate< GUM_SCALAR >* >(
313  __addParent(static_cast< PRMClass< GUM_SCALAR >* >(c), agg, name);
314  }
315  }
316 
317  template < typename GUM_SCALAR >
319  const std::vector< float >& array) {
322  __checkStack(2, PRMObject::prm_type::CLASS);
323 
324  if (a->cpf().domainSize() != array.size())
325  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
326 
327  std::vector< GUM_SCALAR > array2(array.begin(), array.end());
328  a->cpf().fillWith(array2);
329  }
330 
331  template < typename GUM_SCALAR >
333  const std::vector< GUM_SCALAR >& array) {
334  auto elt = __checkStack(1, PRMClassElement< GUM_SCALAR >::prm_attribute);
335  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(elt);
336  __checkStack(2, PRMObject::prm_type::CLASS);
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 >
347  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 >
361  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();
376  idx != inst.variablesSequence().rend();
377  --idx) {
378  jnst.add(**idx);
379  }
380 
381  jnst.setFirst();
382  auto idx = (std::size_t)0;
383  while ((!jnst.end()) && idx < array.size()) {
384  inst.setVals(jnst);
385  a->cpf().set(inst, array[idx]);
386  jnst.inc();
387  ++idx;
388  }
389  }
390  }
391 
392  template < typename GUM_SCALAR >
394  const std::vector< std::string >& parents,
395  const std::vector< float >& values) {
396  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
398 
399  if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
400  GUM_ERROR(OperationNotAllowed, "wrong number of parents");
401  }
402 
403  if (values.size() != a->type().variable().domainSize()) {
404  GUM_ERROR(OperationNotAllowed, "wrong number of values");
405  }
406 
407  std::vector< GUM_SCALAR > values2(values.begin(), values.end());
408  setCPFByRule(parents, values2);
409  }
410 
411  template < typename GUM_SCALAR >
413  const std::vector< std::string >& parents,
414  const std::vector< GUM_SCALAR >& values) {
415  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
417 
418  if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
419  GUM_ERROR(OperationNotAllowed, "wrong number of parents");
420  }
421 
422  if (values.size() != a->type().variable().domainSize()) {
423  GUM_ERROR(OperationNotAllowed, "wrong number of values");
424  }
425 
426  if (dynamic_cast< PRMFormAttribute< GUM_SCALAR >* >(a)) {
427  auto form = static_cast< PRMFormAttribute< GUM_SCALAR >* >(a);
428  // jnst holds parents with a specific value (not "*")
429  // knst holds parents without a specific value ("*")
430  Instantiation jnst, knst;
431  const DiscreteVariable* var = 0;
432  // not_used Size pos = 0;
433  bool found = false;
434 
435  for (Idx i = 0; i < parents.size(); ++i) {
436  var = form->formulas().variablesSequence().atPos(1 + i);
437 
438  if (parents[i] == "*") {
439  knst.add(*var);
440  } else {
441  jnst.add(*var);
442  // not_used pos = 0;
443  found = false;
444 
445  for (Size j = 0; j < var->domainSize(); ++j) {
446  if (var->label(j) == parents[i]) {
447  jnst.chgVal(*var, j);
448  found = true;
449  break;
450  }
451  }
452 
453  if (!found) {
454  std::string msg = "could not find label ";
455  GUM_ERROR(NotFound, msg + parents[i]);
456  }
457  }
458  }
459 
460  Instantiation inst(form->formulas());
461  inst.setVals(jnst);
462 
463  for (Size i = 0; i < form->type()->domainSize(); ++i) {
464  inst.chgVal(form->type().variable(), i);
465 
466  for (inst.setFirstIn(knst); !inst.end(); inst.incIn(knst)) {
467  form->formulas().set(inst, std::to_string(values[i]));
468  }
469  }
470 
471  } else {
472  GUM_ERROR(OperationNotAllowed, "invalide attribute type");
473  }
474  }
475 
476  template < typename GUM_SCALAR >
478  const std::vector< std::string >& parents,
479  const std::vector< std::string >& values) {
480  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
482 
483  if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
484  GUM_ERROR(OperationNotAllowed, "wrong number of parents");
485  }
486 
487  if (values.size() != a->type().variable().domainSize()) {
488  GUM_ERROR(OperationNotAllowed, "wrong number of values");
489  }
490 
491  if (dynamic_cast< PRMFormAttribute< GUM_SCALAR >* >(a)) {
492  auto form = static_cast< PRMFormAttribute< GUM_SCALAR >* >(a);
493  // jnst holds parents with a specific value (not "*")
494  // knst holds parents without a specific value ("*")
495  Instantiation jnst, knst;
496  const DiscreteVariable* var = 0;
497  // not_used Size pos = 0;
498  bool found = false;
499 
500  for (Idx i = 0; i < parents.size(); ++i) {
501  var = form->formulas().variablesSequence().atPos(1 + i);
502 
503  if (parents[i] == "*") {
504  knst.add(*var);
505  } else {
506  jnst.add(*var);
507  // not_used pos = 0;
508  found = false;
509 
510  for (Size j = 0; j < var->domainSize(); ++j) {
511  if (var->label(j) == parents[i]) {
512  jnst.chgVal(*var, j);
513  found = true;
514  break;
515  }
516  }
517 
518  if (!found) {
519  std::string msg = "could not find label ";
520  GUM_ERROR(NotFound, msg + parents[i]);
521  }
522  }
523  }
524 
525  Instantiation inst(form->formulas());
526  inst.setVals(jnst);
527 
528  for (Size i = 0; i < form->type()->domainSize(); ++i) {
529  inst.chgVal(form->type().variable(), i);
530 
531  for (inst.setFirstIn(knst); !inst.end(); inst.incIn(knst)) {
532  form->formulas().set(inst, values[i]);
533  }
534  }
535 
536  } else {
537  GUM_ERROR(OperationNotAllowed, "invalide attribute type");
538  }
539  }
540 
541  template < typename GUM_SCALAR >
542  INLINE void PRMFactory< GUM_SCALAR >::addParameter(const std::string& type,
543  const std::string& name,
544  double value) {
545  auto c = static_cast< PRMClass< GUM_SCALAR >* >(
546  __checkStack(1, PRMObject::prm_type::CLASS));
547 
548  PRMParameter< GUM_SCALAR >* p = nullptr;
549  if (type == "int") {
551  name,
553  (GUM_SCALAR)value);
554  } else if (type == "real") {
556  name,
558  (GUM_SCALAR)value);
559  }
560 
561  try {
562  c->add(p);
563  } catch (DuplicateElement&) { c->overload(p); }
564  }
565 
566  template < typename GUM_SCALAR >
568  const std::string& name,
569  const std::string& agg_type,
570  const std::string& rv_type,
571  const std::vector< std::string >& params) {
572  PRMClass< GUM_SCALAR >* c = static_cast< PRMClass< GUM_SCALAR >* >(
573  __checkStack(1, PRMObject::prm_type::CLASS));
574 
575  auto agg = new PRMAggregate< GUM_SCALAR >(
576  name,
578  *__retrieveType(rv_type));
579 
580  try {
581  c->add(agg);
582  } catch (DuplicateElement&) { c->overload(agg); }
583 
584  switch (agg->agg_type()) {
588  if (params.size() != 1) {
589  GUM_ERROR(OperationNotAllowed, "aggregate requires a parameter");
590  }
591  agg->setLabel(params.front());
592  break;
593  }
594  default: {
595  // Nothing to do
596  }
597  }
598  __stack.push_back(agg);
599  }
600 
601  template < typename GUM_SCALAR >
602  INLINE void
604  PRMClassElementContainer< GUM_SCALAR >* c = __checkStackContainter(1);
605  if (!c->exists(name)) { GUM_ERROR(NotFound, name << "not found"); }
606  auto& agg = c->get(name);
608  GUM_ERROR(OperationNotAllowed, name << " not an aggregate");
609  }
610  __stack.push_back(&agg);
611  }
612 
613  template < typename GUM_SCALAR >
614  INLINE void
617  const std::string& name) {
618  auto chains = std::vector< std::string >{name};
619  auto inputs = std::vector< PRMClassElement< GUM_SCALAR >* >();
620  __retrieveInputs(c, chains, inputs);
621 
622  switch (agg->agg_type()) {
625  if (inputs.front()->type() != *(__retrieveType("boolean"))) {
626  GUM_ERROR(WrongType, "expected booleans");
627  }
628 
629  break;
630  }
631 
635  if (!agg->hasLabel()) {
636  auto param = agg->labelValue();
637  Idx label_idx = 0;
638 
639  while (label_idx < inputs.front()->type()->domainSize()) {
640  if (inputs.front()->type()->label(label_idx) == param) { break; }
641 
642  ++label_idx;
643  }
644 
645  if (label_idx == inputs.front()->type()->domainSize()) {
646  GUM_ERROR(NotFound, "could not find label");
647  }
648 
649  agg->setLabel(label_idx);
650  }
651 
652  break;
653  }
654 
659  break;
660  }
661 
662  default: { GUM_ERROR(FatalError, "Unknown aggregator."); }
663  }
664 
665  c->addArc(inputs.front()->safeName(), agg->safeName());
666  }
667 
668  template < typename GUM_SCALAR >
671  __stack.pop_back();
672  }
673 
674  template < typename GUM_SCALAR >
676  const std::string& name,
677  const std::string& agg_type,
678  const std::vector< std::string >& chains,
679  const std::vector< std::string >& params,
680  std::string type) {
681  PRMClass< GUM_SCALAR >* c = static_cast< PRMClass< GUM_SCALAR >* >(
682  __checkStack(1, PRMObject::prm_type::CLASS));
683  // Checking call legality
684 
685  if (chains.size() == 0) {
687  "a PRMAggregate<GUM_SCALAR> requires at least one parent");
688  }
689 
690  // Retrieving the parents of the aggregate
691  std::vector< PRMClassElement< GUM_SCALAR >* > inputs;
692 
693  // This helps knowing if the aggregate has parents outside the current
694  // class
695  // (see below)
696  bool hasSC = __retrieveInputs(c, chains, inputs);
697 
698  // Checking that all inputs shares the same PRMType (trivial
699  // if
700  // inputs.size() == 1)
701  if (inputs.size() > 1) {
702  for (auto iter = inputs.begin() + 1; iter != inputs.end(); ++iter) {
703  if ((**(iter - 1)).type() != (**iter).type()) {
704  GUM_ERROR(WrongType, "found different types");
705  }
706  }
707  }
708 
709  // Different treatments for different types of aggregate.
710  PRMAggregate< GUM_SCALAR >* agg = nullptr;
711 
712  switch (PRMAggregate< GUM_SCALAR >::str2enum(agg_type)) {
715  if (inputs.front()->type() != *(__retrieveType("boolean"))) {
716  GUM_ERROR(WrongType, "expected booleans");
717  }
718  if (params.size() != 0) {
719  GUM_ERROR(OperationNotAllowed, "invalid number of paramaters");
720  }
721 
722  agg = new PRMAggregate< GUM_SCALAR >(
723  name,
725  inputs.front()->type());
726 
727  break;
728  }
729 
732  if (params.size() != 1) {
733  GUM_ERROR(OperationNotAllowed, "invalid number of parameters");
734  }
735 
736  Idx label_idx = 0;
737 
738  while (label_idx < inputs.front()->type()->domainSize()) {
739  if (inputs.front()->type()->label(label_idx) == params.front()) {
740  break;
741  }
742 
743  ++label_idx;
744  }
745 
746  if (label_idx == inputs.front()->type()->domainSize()) {
747  GUM_ERROR(NotFound, "could not find label");
748  }
749 
750  // Creating and adding the PRMAggregate<GUM_SCALAR>
751  agg = new PRMAggregate< GUM_SCALAR >(
752  name,
754  *(__retrieveType("boolean")),
755  label_idx);
756  agg->label();
757 
758  break;
759  }
760 
765  if (params.size() != 0) {
766  GUM_ERROR(OperationNotAllowed, "invalid number of parameters");
767  }
768 
769  auto output_type = __retrieveType(type);
770 
771  // Creating and adding the PRMAggregate<GUM_SCALAR>
772  agg = new PRMAggregate< GUM_SCALAR >(
773  name, PRMAggregate< GUM_SCALAR >::str2enum(agg_type), *output_type);
774 
775  break;
776  }
777 
779  if (params.size() != 1) {
780  GUM_ERROR(OperationNotAllowed, "invalid number of parameters");
781  }
782 
783  Idx label_idx = 0;
784 
785  while (label_idx < inputs.front()->type()->domainSize()) {
786  if (inputs.front()->type()->label(label_idx) == params.front()) {
787  break;
788  }
789 
790  ++label_idx;
791  }
792 
793  if (label_idx == inputs.front()->type()->domainSize()) {
794  GUM_ERROR(NotFound, "could not find label");
795  }
796 
797  auto output_type = __retrieveType(type);
798 
799  // Creating and adding the PRMAggregate<GUM_SCALAR>
800  agg = new PRMAggregate< GUM_SCALAR >(
801  name,
803  *output_type,
804  label_idx);
805 
806  break;
807  }
808 
809  default: { GUM_ERROR(FatalError, "Unknown aggregator."); }
810  }
811 
812  std::string safe_name = agg->safeName();
813 
814  try {
815  if (hasSC) {
816  try {
817  c->add(agg);
818  } catch (DuplicateElement&) { c->overload(agg); }
819  } else {
820  // Inner aggregators can be directly used as attributes
821  auto attr = new PRMScalarAttribute< GUM_SCALAR >(
822  agg->name(), agg->type(), agg->buildImpl());
823 
824  try {
825  c->add(attr);
826  } catch (DuplicateElement&) { c->overload(attr); }
827 
828  delete agg;
829  }
830  } catch (DuplicateElement&) {
831  delete agg;
832  throw;
833  }
834 
835  for (const auto& elt : inputs) {
836  c->addArc(elt->safeName(), safe_name);
837  }
838  }
839 
840  template < typename GUM_SCALAR >
841  INLINE void PRMFactory< GUM_SCALAR >::addReferenceSlot(const std::string& type,
842  const std::string& name,
843  bool isArray) {
844  PRMClassElementContainer< GUM_SCALAR >* owner = __checkStackContainter(1);
846 
847  try {
848  slotType = __retrieveClass(type);
849  } catch (NotFound&) {
850  try {
851  slotType = __retrieveInterface(type);
852  } catch (NotFound&) {
853  GUM_ERROR(NotFound, "unknown ReferenceSlot<GUM_SCALAR> slot type");
854  }
855  }
856 
858  new PRMReferenceSlot< GUM_SCALAR >(name, *slotType, isArray);
859 
860  try {
861  owner->add(ref);
862  } catch (DuplicateElement&) { owner->overload(ref); }
863  }
864 
865  template < typename GUM_SCALAR >
866  INLINE void PRMFactory< GUM_SCALAR >::addArray(const std::string& type,
867  const std::string& name,
868  Size size) {
869  PRMSystem< GUM_SCALAR >* model = static_cast< PRMSystem< GUM_SCALAR >* >(
870  __checkStack(1, PRMObject::prm_type::SYSTEM));
871  PRMClass< GUM_SCALAR >* c = __retrieveClass(type);
872  PRMInstance< GUM_SCALAR >* inst = 0;
873 
874  try {
875  model->addArray(name, *c);
876 
877  for (Size i = 0; i < size; ++i) {
878  std::stringstream elt_name;
879  elt_name << name << "[" << i << "]";
880  inst = new PRMInstance< GUM_SCALAR >(elt_name.str(), *c);
881  model->add(name, inst);
882  }
883  } catch (TypeError&) {
884  delete inst;
885  throw;
886  } catch (NotFound&) {
887  delete inst;
888  throw;
889  }
890  }
891 
892  template < typename GUM_SCALAR >
893  INLINE void PRMFactory< GUM_SCALAR >::incArray(const std::string& l_i,
894  const std::string& r_i) {
895  PRMSystem< GUM_SCALAR >* model = static_cast< PRMSystem< GUM_SCALAR >* >(
896  __checkStack(1, PRMObject::prm_type::SYSTEM));
897 
898  if (model->isArray(l_i)) {
899  if (model->isInstance(r_i)) {
900  model->add(l_i, model->get(r_i));
901  } else {
902  GUM_ERROR(NotFound, "right value is not an instance");
903  }
904  } else {
905  GUM_ERROR(NotFound, "left value is no an array");
906  }
907  }
908 
909  template < typename GUM_SCALAR >
911  const std::string& l_i, const std::string& l_ref, const std::string& r_i) {
912  auto model = static_cast< PRMSystem< GUM_SCALAR >* >(
913  __checkStack(1, PRMObject::prm_type::SYSTEM));
914  std::vector< PRMInstance< GUM_SCALAR >* > lefts;
915  std::vector< PRMInstance< GUM_SCALAR >* > rights;
916 
917  if (model->isInstance(l_i)) {
918  lefts.push_back(&(model->get(l_i)));
919  } else if (model->isArray(l_i)) {
920  for (const auto& elt : model->getArray(l_i))
921  lefts.push_back(elt);
922  } else {
923  GUM_ERROR(NotFound, "left value does not name an instance or an array");
924  }
925 
926  if (model->isInstance(r_i)) {
927  rights.push_back(&(model->get(r_i)));
928  } else if (model->isArray(r_i)) {
929  for (const auto& elt : model->getArray(r_i))
930  rights.push_back(elt);
931  } else {
932  GUM_ERROR(NotFound, "left value does not name an instance or an array");
933  }
934 
935  for (const auto l : lefts) {
936  for (const auto r : rights) {
937  auto& elt = l->type().get(l_ref);
939  l->add(elt.id(), *r);
940 
941  } else {
942  GUM_ERROR(NotFound, "unfound reference slot");
943  }
944  }
945  }
946  }
947 
948  template < typename GUM_SCALAR >
950  PRMClassElementContainer< GUM_SCALAR >* start, const std::string& name) {
951  std::vector< std::string > v;
952  decomposePath(name, v);
954  PRMReferenceSlot< GUM_SCALAR >* ref = nullptr;
956 
957  for (size_t i = 0; i < v.size(); ++i) {
958  try {
959  switch (current->get(v[i]).elt_type()) {
961  ref = &(static_cast< PRMReferenceSlot< GUM_SCALAR >& >(
962  current->get(v[i])));
963  elts.insert(ref);
964  current = &(/*const_cast<PRMClassElementContainer<GUM_SCALAR>&>*/ (
965  ref->slotType()));
966  break;
967 
970 
971  if (i == v.size() - 1) {
972  elts.insert(&(current->get(v[i])));
973  break;
974  } else {
975  return nullptr;
976  }
977 
978  default: { return nullptr; }
979  }
980  } catch (NotFound&) { return nullptr; }
981  }
982 
983  GUM_ASSERT(v.size() == elts.size());
984 
985  current->setOutputNode(*(elts.back()), true);
986 
987  return new PRMSlotChain< GUM_SCALAR >(name, elts);
988  }
989 
990  template < typename GUM_SCALAR >
993  const std::vector< std::string >& chains,
994  std::vector< PRMClassElement< GUM_SCALAR >* >& inputs) {
995  bool retVal = false;
996 
997  for (size_t i = 0; i < chains.size(); ++i) {
998  try {
999  inputs.push_back(&(c->get(chains[i])));
1000  retVal = retVal
1001  || PRMClassElement< GUM_SCALAR >::isSlotChain(*(inputs.back()));
1002  } catch (NotFound&) {
1003  inputs.push_back(__buildSlotChain(c, chains[i]));
1004  retVal = true;
1005 
1006  if (inputs.back()) {
1007  c->add(inputs.back());
1008  } else {
1009  GUM_ERROR(NotFound, "unknown slot chain");
1010  }
1011  }
1012  }
1013 
1014  PRMType* t = __retrieveCommonType(inputs);
1015 
1016  std::vector< std::pair< PRMClassElement< GUM_SCALAR >*,
1018  toAdd;
1019 
1020  for (const auto& elt : inputs) {
1021  if ((*elt).type() != (*t)) {
1024  static_cast< PRMSlotChain< GUM_SCALAR >* >(elt);
1025  std::stringstream name;
1026 
1027  for (Size idx = 0; idx < sc->chain().size() - 1; ++idx) {
1028  name << sc->chain().atPos(idx)->name() << ".";
1029  }
1030 
1031  name << ".(" << t->name() << ")" << sc->lastElt().name();
1032 
1033  try {
1034  toAdd.push_back(std::make_pair(elt, &(c->get(name.str()))));
1035  } catch (NotFound&) {
1036  toAdd.push_back(
1037  std::make_pair(elt, __buildSlotChain(c, name.str())));
1038  }
1039  } else {
1040  std::stringstream name;
1041  name << "(" << t->name() << ")" << elt->name();
1042  toAdd.push_back(std::make_pair(elt, &(c->get(name.str()))));
1043  }
1044  }
1045  }
1046 
1047  return retVal;
1048  }
1049 
1050  template < typename GUM_SCALAR >
1052  const std::vector< PRMClassElement< GUM_SCALAR >* >& elts) {
1053  const PRMType* current = nullptr;
1055  // Finding all types and super types
1056 
1057  for (const auto& elt : elts) {
1058  try {
1059  current = &((*elt).type());
1060 
1061  while (current != 0) {
1062  // Filling counters
1063  if (counters.exists(current->name())) {
1064  ++(counters[current->name()]);
1065  } else {
1066  counters.insert(current->name(), 1);
1067  }
1068 
1069  // Loop guard
1070  if (current->isSubType()) {
1071  current = &(current->superType());
1072  } else {
1073  current = nullptr;
1074  }
1075  }
1076  } catch (OperationNotAllowed&) {
1078  "found a ClassElement<GUM_SCALAR> without a type");
1079  }
1080  }
1081 
1082  // We need to find the most specialized (i.e. max depth) common type
1083  current = nullptr;
1084 
1085  int max_depth = -1;
1086 
1087  int current_depth = 0;
1088 
1089  for (const auto& elt : counters) {
1090  if ((elt.second) == elts.size()) {
1091  current_depth = __typeDepth(__retrieveType(elt.first));
1092 
1093  if (current_depth > max_depth) {
1094  max_depth = current_depth;
1095  current = __retrieveType(elt.first);
1096  }
1097  }
1098  }
1099 
1100  if (current) { return const_cast< PRMType* >(current); }
1101 
1102  GUM_ERROR(NotFound, "could not find a common type");
1103  }
1104 
1105  template < typename GUM_SCALAR >
1107  const std::string& name,
1108  const std::vector< std::string >& chains,
1109  const std::vector< float >& numbers,
1110  float leak,
1111  const std::vector< std::string >& labels) {
1112  if (currentType() != PRMObject::prm_type::CLASS) {
1113  GUM_ERROR(gum::FactoryInvalidState, "invalid state to add a noisy-or");
1114  }
1115 
1117  dynamic_cast< gum::prm::PRMClass< GUM_SCALAR >* >(getCurrent());
1118 
1119  std::vector< PRMClassElement< GUM_SCALAR >* > parents;
1120 
1121  for (const auto& elt : chains)
1122  parents.push_back(&(c->get(elt)));
1123 
1124  PRMType* common_type = __retrieveCommonType(parents);
1125 
1126  for (size_t idx = 0; idx < parents.size(); ++idx) {
1127  if (parents[idx]->type() != (*common_type)) {
1128  PRMClassElement< GUM_SCALAR >* parent = parents[idx];
1129  // Either safe_name is an non existing slot chain or an existing cast
1130  // descendant
1131  std::string safe_name = parent->cast(*common_type);
1132 
1133  if (!c->exists(safe_name)) {
1135  parents[idx] = __buildSlotChain(c, safe_name);
1136  c->add(parents[idx]);
1137  } else {
1138  GUM_ERROR(NotFound, "unable to find parent");
1139  }
1140  } else {
1141  parents[idx] = &(c->get(safe_name));
1142  }
1143  }
1144  }
1145 
1146  if (numbers.size() == 1) {
1147  auto impl =
1148  new gum::MultiDimNoisyORCompound< GUM_SCALAR >(leak, numbers.front());
1149  auto attr = new PRMScalarAttribute< GUM_SCALAR >(
1150  name, retrieveType("boolean"), impl);
1151  addAttribute(attr);
1152  } else if (numbers.size() == parents.size()) {
1157  name, retrieveType("boolean"), noisy);
1158 
1159  for (size_t idx = 0; idx < numbers.size(); ++idx) {
1160  noisy->causalWeight(parents[idx]->type().variable(), numbers[idx]);
1161  }
1162 
1163  addAttribute(attr);
1164  } else {
1165  GUM_ERROR(OperationNotAllowed, "invalid parameters for a noisy or");
1166  }
1167 
1168  if (!labels.empty()) {
1170  "labels definitions not handle for noisy-or");
1171  }
1172  }
1173 
1174  template < typename GUM_SCALAR >
1175  INLINE PRMType*
1176  PRMFactory< GUM_SCALAR >::__retrieveType(const std::string& name) const {
1177  PRMType* type = nullptr;
1178  std::string full_name;
1179 
1180  // Looking for the type using its name
1181  if (__prm->__typeMap.exists(name)) {
1182  type = __prm->__typeMap[name];
1183  full_name = name;
1184  }
1185 
1186  // Looking for the type in current package
1187  std::string prefixed = __addPrefix(name);
1188  if (__prm->__typeMap.exists(prefixed)) {
1189  if (type == 0) {
1190  type = __prm->__typeMap[prefixed];
1191  full_name = prefixed;
1192  } else if (full_name != prefixed) {
1194  "Type name '" << name << "' is ambiguous: specify full name.");
1195  }
1196  }
1197 
1198  // Looking for the type relatively to current package
1199  std::string relatif_ns = currentPackage();
1200  size_t last_dot = relatif_ns.find_last_of('.');
1201  if (last_dot != std::string::npos) {
1202  relatif_ns = relatif_ns.substr(0, last_dot) + '.' + name;
1203  if (__prm->__typeMap.exists(relatif_ns)) {
1204  if (type == 0) {
1205  type = __prm->__typeMap[relatif_ns];
1206  full_name = relatif_ns;
1207  } else if (full_name != relatif_ns) {
1209  "Type name '" << name
1210  << "' is ambiguous: specify full name.");
1211  }
1212  }
1213  }
1214 
1215 
1216  // Looking for the type using all declared namespaces
1217  if (!__namespaces.empty()) {
1218  auto ns_list = __namespaces.back();
1219  for (gum::Size i = 0; i < ns_list->size(); ++i) {
1220  std::string ns = (*ns_list)[i];
1221  std::string ns_name = ns + "." + name;
1222  if (__prm->__typeMap.exists(ns_name)) {
1223  if (type == 0) {
1224  type = __prm->__typeMap[ns_name];
1225  full_name = ns_name;
1226  } else if (full_name != ns_name) {
1228  "Type name '" << name
1229  << "' is ambiguous: specify full name.");
1230  }
1231  }
1232  }
1233  }
1234 
1235  if (type == 0) {
1236  GUM_ERROR(NotFound, "Type '" << name << "' not found, check imports.");
1237  }
1238 
1239  return type;
1240  }
1241 
1242  template < typename GUM_SCALAR >
1244  PRMFactory< GUM_SCALAR >::__retrieveClass(const std::string& name) const {
1245  PRMClass< GUM_SCALAR >* a_class = nullptr;
1246  std::string full_name;
1247 
1248  // Looking for the type using its name
1249  if (__prm->__classMap.exists(name)) {
1250  a_class = __prm->__classMap[name];
1251  full_name = name;
1252  }
1253 
1254  // Looking for the type using current package
1255  std::string prefixed = __addPrefix(name);
1256  if (__prm->__classMap.exists(prefixed)) {
1257  if (a_class == nullptr) {
1258  a_class = __prm->__classMap[prefixed];
1259  full_name = prefixed;
1260  } else if (full_name != prefixed) {
1262  "Class name '" << name
1263  << "' is ambiguous: specify full name.");
1264  }
1265  }
1266 
1267  // Looking for the class using all declared namespaces
1268  if (!__namespaces.empty()) {
1269  auto ns_list = __namespaces.back();
1270  for (gum::Size i = 0; i < ns_list->size(); ++i) {
1271  std::string ns = (*ns_list)[i];
1272  std::string ns_name = ns + "." + name;
1273  if (__prm->__classMap.exists(ns_name)) {
1274  if (a_class == 0) {
1275  a_class = __prm->__classMap[ns_name];
1276  full_name = ns_name;
1277  } else if (full_name != ns_name) {
1279  "Class name '" << name
1280  << "' is ambiguous: specify full name.");
1281  }
1282  }
1283  }
1284  }
1285 
1286  if (a_class == 0) {
1287  GUM_ERROR(NotFound, "Class '" << name << "' not found, check imports.");
1288  }
1289 
1290  return a_class;
1291  }
1292 
1293  template < typename GUM_SCALAR >
1295  const std::string& name) const {
1296  PRMInterface< GUM_SCALAR >* interface = nullptr;
1297  std::string full_name;
1298 
1299  // Looking for the type using its name
1300  if (__prm->__interfaceMap.exists(name)) {
1301  interface = __prm->__interfaceMap[name];
1302  full_name = name;
1303  }
1304 
1305  // Looking for the type using current package
1306  std::string prefixed = __addPrefix(name);
1307  if (__prm->__interfaceMap.exists(prefixed)) {
1308  if (interface == nullptr) {
1309  interface = __prm->__interfaceMap[prefixed];
1310  full_name = prefixed;
1311  } else if (full_name != prefixed) {
1313  "Interface name '" << name
1314  << "' is ambiguous: specify full name.");
1315  }
1316  }
1317 
1318  // Looking for the interf using all declared namespaces
1319  if (!__namespaces.empty()) {
1320  auto ns_list = __namespaces.back();
1321  // for( const auto & ns : *(__namespaces.top()) ) {
1322  for (gum::Size i = 0; i < ns_list->size(); ++i) {
1323  std::string ns = (*ns_list)[i];
1324  std::string ns_name = ns + "." + name;
1325 
1326  if (__prm->__interfaceMap.exists(ns_name)) {
1327  if (interface == nullptr) {
1328  interface = __prm->__interfaceMap[ns_name];
1329  full_name = ns_name;
1330  } else if (full_name != ns_name) {
1332  "Interface name '"
1333  << name << "' is ambiguous: specify full name.");
1334  }
1335  }
1336  }
1337  }
1338 
1339  if (interface == nullptr) {
1341  "Interface '" << name << "' not found, check imports.");
1342  }
1343 
1344  return interface;
1345  }
1346 
1347  template < typename GUM_SCALAR >
1349  GUM_CONSTRUCTOR(PRMFactory);
1350  __prm = new PRM< GUM_SCALAR >();
1351  }
1352 
1353  template < typename GUM_SCALAR >
1355  IPRMFactory(), __prm(prm) {
1356  GUM_CONSTRUCTOR(PRMFactory);
1357  }
1358 
1359  template < typename GUM_SCALAR >
1361  GUM_DESTRUCTOR(PRMFactory);
1362  while (!__namespaces.empty()) {
1363  auto ns = __namespaces.back();
1364  __namespaces.pop_back();
1365  delete ns;
1366  }
1367  }
1368 
1369  template < typename GUM_SCALAR >
1371  return __prm;
1372  }
1373 
1374  template < typename GUM_SCALAR >
1376  if (__stack.size() == 0) { GUM_ERROR(NotFound, "no object being built"); }
1377 
1378  return __stack.back()->obj_type();
1379  }
1380 
1381  template < typename GUM_SCALAR >
1383  if (__stack.size() == 0) { GUM_ERROR(NotFound, "no object being built"); }
1384 
1385  return __stack.back();
1386  }
1387 
1388  template < typename GUM_SCALAR >
1390  if (__stack.size() == 0) { GUM_ERROR(NotFound, "no object being built"); }
1391 
1392  return __stack.back();
1393  }
1394 
1395  template < typename GUM_SCALAR >
1397  if (__stack.size() > 0) {
1398  PRMObject* obj = __stack.back();
1399  __stack.pop_back();
1400  return obj;
1401  } else {
1402  return 0;
1403  }
1404  }
1405 
1406  template < typename GUM_SCALAR >
1407  INLINE std::string PRMFactory< GUM_SCALAR >::currentPackage() const {
1408  return (__packages.empty()) ? "" : __packages.back();
1409  }
1410 
1411  template < typename GUM_SCALAR >
1412  INLINE void
1414  std::string super) {
1415  std::string real_name = __addPrefix(name);
1416  if (__prm->__typeMap.exists(real_name)) {
1417  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
1418  }
1419  if (super == "") {
1420  auto t = new PRMType(LabelizedVariable(real_name, "", 0));
1421  __stack.push_back(t);
1422  } else {
1423  auto t = new PRMType(LabelizedVariable(real_name, "", 0));
1424  t->__superType = __retrieveType(super);
1425  t->__label_map = new std::vector< Idx >();
1426  __stack.push_back(t);
1427  }
1428  }
1429 
1430  template < typename GUM_SCALAR >
1431  INLINE void PRMFactory< GUM_SCALAR >::addLabel(const std::string& l,
1432  std::string extends) {
1433  if (extends == "") {
1434  PRMType* t =
1435  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1436  LabelizedVariable* var = dynamic_cast< LabelizedVariable* >(t->__var);
1437 
1438  if (!var) {
1440  "the current type's variable is not a LabelizedVariable.");
1441  } else if (t->__superType) {
1442  GUM_ERROR(OperationNotAllowed, "current type is a subtype.");
1443  }
1444 
1445  try {
1446  var->addLabel(l);
1447  } catch (DuplicateElement&) {
1448  GUM_ERROR(DuplicateElement, "a label '" << l << "' already exists");
1449  }
1450  } else {
1451  PRMType* t =
1452  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1453  LabelizedVariable* var = dynamic_cast< LabelizedVariable* >(t->__var);
1454 
1455  if (!var) {
1457  "the current type's variable is not a LabelizedVariable.");
1458  } else if (!t->__superType) {
1459  GUM_ERROR(OperationNotAllowed, "current type is not a subtype.");
1460  }
1461 
1462  bool found = false;
1463 
1464  for (Idx i = 0; i < t->__superType->__var->domainSize(); ++i) {
1465  if (t->__superType->__var->label(i) == extends) {
1466  try {
1467  var->addLabel(l);
1468  } catch (DuplicateElement&) {
1469  GUM_ERROR(DuplicateElement, "a label '" << l << "' already exists");
1470  }
1471 
1472  t->__label_map->push_back(i);
1473 
1474  found = true;
1475  break;
1476  }
1477  }
1478 
1479  if (!found) { GUM_ERROR(NotFound, "inexistent label in super type."); }
1480  }
1481  }
1482 
1483  template < typename GUM_SCALAR >
1485  PRMType* t =
1486  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1487 
1488  if (!t->__isValid()) {
1489  GUM_ERROR(OperationNotAllowed, "current type is not a valid subtype");
1490  } else if (t->variable().domainSize() < 2) {
1492  "current type is not a valid discrete type");
1493  }
1494 
1495  __prm->__typeMap.insert(t->name(), t);
1496 
1497  __prm->__types.insert(t);
1498  __stack.pop_back();
1499  }
1500 
1501  template < typename GUM_SCALAR >
1502  INLINE void
1504  std::string real_name = __addPrefix(name);
1505  if (__prm->__typeMap.exists(real_name)) {
1506  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
1507  }
1508  auto var = DiscretizedVariable< double >(real_name, "");
1509  auto t = new PRMType(var);
1510  __stack.push_back(t);
1511  }
1512 
1513  template < typename GUM_SCALAR >
1514  INLINE void PRMFactory< GUM_SCALAR >::addTick(double tick) {
1515  PRMType* t =
1516  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1518  dynamic_cast< DiscretizedVariable< double >* >(t->__var);
1519 
1520  if (!var) {
1522  "the current type's variable is not a LabelizedVariable.");
1523  }
1524 
1525  try {
1526  var->addTick(tick);
1527  } catch (DefaultInLabel&) {
1528  GUM_ERROR(OperationNotAllowed, "tick already in used for this variable");
1529  }
1530  }
1531 
1532  template < typename GUM_SCALAR >
1534  PRMType* t =
1535  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1536 
1537  if (t->variable().domainSize() < 2) {
1539  "current type is not a valid discrete type");
1540  }
1541 
1542  __prm->__typeMap.insert(t->name(), t);
1543 
1544  __prm->__types.insert(t);
1545  __stack.pop_back();
1546  }
1547 
1548  template < typename GUM_SCALAR >
1549  INLINE void PRMFactory< GUM_SCALAR >::addRangeType(const std::string& name,
1550  long minVal,
1551  long maxVal) {
1552  std::string real_name = __addPrefix(name);
1553  if (__prm->__typeMap.exists(real_name)) {
1554  std::stringstream msg;
1555  msg << "\"" << real_name << "' is already used.";
1556  GUM_ERROR(DuplicateElement, msg.str());
1557  }
1558 
1559  auto var = RangeVariable(real_name, "", minVal, maxVal);
1560  auto t = new PRMType(var);
1561 
1562  if (t->variable().domainSize() < 2) {
1564  "current type is not a valid discrete type");
1565  }
1566 
1567  __prm->__typeMap.insert(t->name(), t);
1568  __prm->__types.insert(t);
1569  }
1570 
1571  template < typename GUM_SCALAR >
1574  __stack.pop_back();
1575  }
1576 
1577  template < typename GUM_SCALAR >
1578  INLINE void PRMFactory< GUM_SCALAR >::addAttribute(const std::string& type,
1579  const std::string& name) {
1581  startAttribute(type, name);
1582  endAttribute();
1583  }
1584 
1585  template < typename GUM_SCALAR >
1586  INLINE void PRMFactory< GUM_SCALAR >::startAttribute(const std::string& type,
1587  const std::string& name,
1588  bool scalar_attr) {
1590  PRMAttribute< GUM_SCALAR >* a = nullptr;
1591 
1592  if (PRMObject::isClass(*c) && (!scalar_attr)) {
1594  static_cast< PRMClass< GUM_SCALAR >& >(*c),
1595  name,
1596  *__retrieveType(type));
1597 
1598  } else {
1599  a = new PRMScalarAttribute< GUM_SCALAR >(name, *__retrieveType(type));
1600  }
1601 
1602  std::string dot = ".";
1603 
1604  try {
1605  try {
1606  c->add(a);
1607  } catch (DuplicateElement&) { c->overload(a); }
1608  } catch (Exception&) {
1609  if (a != nullptr && (!c->exists(a->id()))) { delete a; }
1610  }
1611 
1612  __stack.push_back(a);
1613  }
1614 
1615  template < typename GUM_SCALAR >
1616  INLINE void
1619  if (!c->exists(name)) { GUM_ERROR(NotFound, name << "not found"); }
1620  auto& a = c->get(name);
1622  GUM_ERROR(OperationNotAllowed, name << " not an attribute");
1623  }
1624  __stack.push_back(&a);
1625  }
1626 
1627  template < typename GUM_SCALAR >
1630  __stack.pop_back();
1631  }
1632 
1633  template < typename GUM_SCALAR >
1634  INLINE void PRMFactory< GUM_SCALAR >::startSystem(const std::string& name) {
1635  if (__prm->__systemMap.exists(name)) {
1636  GUM_ERROR(DuplicateElement, "'" << name << "' is already used.");
1637  }
1638  PRMSystem< GUM_SCALAR >* model =
1640  __stack.push_back(model);
1641  __prm->__systemMap.insert(model->name(), model);
1642  __prm->__systems.insert(model);
1643  }
1644 
1645  template < typename GUM_SCALAR >
1647  try {
1648  PRMSystem< GUM_SCALAR >* model = static_cast< PRMSystem< GUM_SCALAR >* >(
1650  __stack.pop_back();
1651  model->instantiate();
1652  } catch (Exception&) { GUM_ERROR(FatalError, "could not create system"); }
1653  }
1654 
1655  template < typename GUM_SCALAR >
1656  INLINE void PRMFactory< GUM_SCALAR >::addInstance(const std::string& type,
1657  const std::string& name) {
1658  auto c = __retrieveClass(type);
1659 
1660  // If class contains parameters, calls the proper addIsntance method
1661  if (c->parameters().size() > 0) {
1663  addInstance(type, name, params);
1664 
1665  } else {
1666  __addInstance(c, name);
1667  }
1668  }
1669 
1670  template < typename GUM_SCALAR >
1672  const std::string& type,
1673  const std::string& name,
1674  const HashTable< std::string, double >& params) {
1675  auto c = __retrieveClass(type);
1676 
1677  if (c->parameters().empty()) {
1678  if (params.empty()) {
1679  __addInstance(c, name);
1680  } else {
1682  "Class " + type + " does not have parameters");
1683  }
1684 
1685  } else {
1686  auto my_params = params;
1687  // Adding all parameters to my_params
1688  for (const auto& p : c->parameters()) {
1689  if (!my_params.exists(p->name())) {
1690  my_params.insert(p->name(), p->value());
1691  }
1692  }
1693 
1694  // Building sub class name using my_params
1695  std::stringstream sBuff;
1696  sBuff << c->name() << "<";
1697 
1698  for (const auto& p : my_params) {
1699  sBuff << p.first << "=" << p.second << ",";
1700  }
1701 
1702  // Removing last , and adding closing >
1703  std::string sub_c = sBuff.str().substr(0, sBuff.str().size() - 1) + ">";
1704 
1705  // Adding class in current package
1706  try {
1707  auto pck_cpy = __packages;
1708  __packages.clear();
1709 
1710  startClass(sub_c, c->name());
1711 
1712  // Update inherited parameters
1713  for (auto p : my_params) {
1714  auto type = static_cast< PRMParameter< GUM_SCALAR >& >(c->get(p.first))
1715  .valueType();
1717  addParameter("int", p.first, p.second);
1718 
1719  } else {
1720  addParameter("real", p.first, p.second);
1721  }
1722  }
1723 
1724  endClass();
1725 
1726  __packages = pck_cpy;
1727 
1728  } catch (DuplicateElement&) {
1729  // Sub Class already exists in this system
1730  }
1731  c = __retrieveClass(sub_c);
1732  __addInstance(c, name);
1733  }
1734  }
1735 
1736  template < typename GUM_SCALAR >
1737  INLINE void
1739  const std::string& name) {
1740  PRMInstance< GUM_SCALAR >* i = nullptr;
1741  try {
1742  auto s = static_cast< PRMSystem< GUM_SCALAR >* >(
1744  i = new PRMInstance< GUM_SCALAR >(name, *type);
1745  s->add(i);
1746 
1747  } catch (OperationNotAllowed&) {
1748  if (i) { delete i; }
1749  throw;
1750  }
1751  }
1752 
1753  template < typename GUM_SCALAR >
1754  INLINE std::string
1755  PRMFactory< GUM_SCALAR >::__addPrefix(const std::string& str) const {
1756  if (!__packages.empty()) {
1757  std::string full_name = __packages.back();
1758  full_name.append(".");
1759  full_name.append(str);
1760  return full_name;
1761  } else {
1762  return str;
1763  }
1764  }
1765 
1766  template < typename GUM_SCALAR >
1767  INLINE PRMObject*
1769  PRMObject::prm_type obj_type) {
1770  // Don't forget that Idx are unsigned int
1771  if (__stack.size() - i > __stack.size()) {
1772  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1773  }
1774 
1775  PRMObject* obj = __stack[__stack.size() - i];
1776 
1777  if (obj->obj_type() != obj_type) {
1778  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1779  }
1780 
1781  return obj;
1782  }
1783 
1784  template < typename GUM_SCALAR >
1787  // Don't forget that Idx are unsigned int
1788  if (__stack.size() - i > __stack.size()) {
1789  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1790  }
1791 
1792  PRMObject* obj = __stack[__stack.size() - i];
1793 
1794  if ((obj->obj_type() == PRMObject::prm_type::CLASS)
1796  return static_cast< PRMClassElementContainer< GUM_SCALAR >* >(obj);
1797  } else {
1798  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1799  }
1800  }
1801 
1802  template < typename GUM_SCALAR >
1805  // Don't forget that Idx are unsigned int
1806  if (__stack.size() - i > __stack.size()) {
1807  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1808  }
1809 
1811  dynamic_cast< PRMClassElement< GUM_SCALAR >* >(
1812  __stack[__stack.size() - i]);
1813 
1814  if (obj == 0) {
1815  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1816  }
1817 
1818  if (obj->elt_type() != elt_type) {
1819  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1820  }
1821 
1822  return obj;
1823  }
1824 
1825  template < typename GUM_SCALAR >
1827  int depth = 0;
1828  const PRMType* current = t;
1829 
1830  while (current->isSubType()) {
1831  ++depth;
1832  current = &(current->superType());
1833  }
1834 
1835  return depth;
1836  }
1837 
1838  template < typename GUM_SCALAR >
1839  INLINE void PRMFactory< GUM_SCALAR >::pushPackage(const std::string& name) {
1840  __packages.push_back(name);
1841  __namespaces.push_back(new List< std::string >());
1842  }
1843 
1844  template < typename GUM_SCALAR >
1846  std::string plop = currentPackage();
1847 
1848  if (!__packages.empty()) {
1849  std::string s = __packages.back();
1850  __packages.pop_back();
1851 
1852  if (__namespaces.size() > 0) {
1853  delete __namespaces.back();
1854  __namespaces.pop_back();
1855  }
1856  return s;
1857  }
1858 
1859  return plop;
1860  }
1861 
1862  template < typename GUM_SCALAR >
1863  INLINE void PRMFactory< GUM_SCALAR >::addImport(const std::string& name) {
1864  if (name.size() == 0) {
1865  GUM_ERROR(OperationNotAllowed, "illegal import name");
1866  }
1867  if (__namespaces.empty()) {
1868  __namespaces.push_back(new List< std::string >());
1869  }
1870  __namespaces.back()->push_back(name);
1871  }
1872 
1873  template < typename GUM_SCALAR >
1874  INLINE void
1876  const std::string& r_i) {
1877  size_t pos = l_i.find_last_of('.');
1878 
1879  if (pos != std::string::npos) {
1880  std::string l_ref = l_i.substr(pos + 1, std::string::npos);
1881  setReferenceSlot(l_i.substr(0, pos), l_ref, r_i);
1882  } else {
1883  GUM_ERROR(NotFound, "left value does not name an instance or an array");
1884  }
1885  }
1886 
1887  template < typename GUM_SCALAR >
1888  INLINE PRMClass< GUM_SCALAR >&
1889  PRMFactory< GUM_SCALAR >::retrieveClass(const std::string& name) {
1890  return *__retrieveClass(name);
1891  }
1892 
1893  template < typename GUM_SCALAR >
1894  INLINE PRMType&
1895  PRMFactory< GUM_SCALAR >::retrieveType(const std::string& name) {
1896  return *__retrieveType(name);
1897  }
1898 
1899  template < typename GUM_SCALAR >
1901  const std::vector< PRMClassElement< GUM_SCALAR >* >& elts) {
1902  return *(__retrieveCommonType(elts));
1903  }
1904 
1905 
1906  template < typename GUM_SCALAR >
1908  const std::string& type) const {
1909  try {
1910  __retrieveClass(type);
1911  return true;
1912 
1913  } catch (NotFound&) {
1914  } catch (DuplicateElement&) {}
1915 
1916  try {
1917  __retrieveInterface(type);
1918  return true;
1919 
1920  } catch (NotFound&) {
1921  } catch (DuplicateElement&) {}
1922 
1923  return false;
1924  }
1925 
1926  template < typename GUM_SCALAR >
1928  const std::string& name) const {
1929  const PRMSystem< GUM_SCALAR >* system =
1930  static_cast< const PRMSystem< GUM_SCALAR >* >(getCurrent());
1931  return (system && system->isArray(name));
1932  }
1933 
1934  template < typename GUM_SCALAR >
1936  const std::vector< std::string >& array) {
1938 
1939  auto a = static_cast< PRMFormAttribute< GUM_SCALAR >* >(
1941 
1942  if (a->formulas().domainSize() != array.size()) {
1943  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
1944  }
1945 
1946  if (a->formulas().nbrDim() == 1) {
1947  setRawCPFByLines(array);
1948 
1949  } else {
1950  Instantiation inst(a->formulas());
1951  Instantiation jnst;
1952  for (auto idx = inst.variablesSequence().rbegin();
1953  idx != inst.variablesSequence().rend();
1954  --idx) {
1955  jnst.add(**idx);
1956  }
1957 
1958  jnst.setFirst();
1959  auto idx = (std::size_t)0;
1960  while ((!jnst.end()) && idx < array.size()) {
1961  inst.setVals(jnst);
1962  a->formulas().set(inst, array[idx]);
1963  jnst.inc();
1964  ++idx;
1965  }
1966 
1967  // Generate cpf by calling it
1968  a->cpf();
1969  }
1970  }
1971 
1972  template < typename GUM_SCALAR >
1974  const std::vector< std::string >& array) {
1976 
1977  auto a = static_cast< PRMFormAttribute< GUM_SCALAR >* >(
1979 
1980  if (a->formulas().domainSize() != array.size()) {
1981  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
1982  }
1983 
1984  a->formulas().populate(array);
1985 
1987  a->cpf();
1988  }
1989 
1990  } /* namespace prm */
1991 } /* namespace gum */
PRM< GUM_SCALAR > * __prm
The pointer on the PRM<GUM_SCALAR> built by this factory.
Definition: PRMFactory.h:1046
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::add(PRMClassElement<GUM_SCALAR>*).
Definition: PRMClass_tpl.h:618
const Set< PRMInterface< GUM_SCALAR > *> & implements() const
Returns the Set of PRMInterface<GUM_SCALAR> implemented by this Class<GUM_SCALAR>.
PRMParameter is a member of a Class in a PRM.
Definition: PRMParameter.h:49
std::vector< PRMObject *> __stack
A stack used to keep track of created PRMObject.
Definition: PRMFactory.h:1049
virtual void endInterface() override
Tells the factory that we finished an interface declaration.
virtual void pushPackage(const std::string &name) override
Define the current package.
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 addRangeType(const std::string &name, long minVal, long maxVal) override
Add a range variable type declaration.
bool empty() const noexcept
Indicates whether the set is the empty set.
Definition: set_tpl.h:704
static AggregateType str2enum(const std::string &str)
Static method which returns the AggregateType given its string representation.
Definition: PRMAggregate.h:97
static INLINE bool isClass(const PRMObject &obj)
Returns true if obj_ptr is of type Class.
Definition: PRMObject.h:99
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition: PRMType_inl.h:42
MultiDimImplementation< GUM_SCALAR > * buildImpl() const
Returns a pointer over an empty gum::MultiDimImplementation of the good type for this PRMAggregate...
void add(NodeId id, PRMInstance< GUM_SCALAR > &instance)
Add an PRMInstance<GUM_SCALAR> to a given PRMReferenceSlot, PRMSlotChain<GUM_SCALAR> or output node...
class LabelizedVariable
void endAggregator()
Finishes an aggregate 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.
Headers of gum::PRMAttribute.
virtual ~PRMFactory()
Destructor.
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>.
const std::string & name() const
Returns the name of this object.
Definition: PRMObject_inl.h:32
virtual std::string popPackage() override
Pop the current package from the package stack.
Size size() const noexcept
Returns the size of the sequence.
Definition: sequence_tpl.h:35
virtual void addInstance(const std::string &type, const std::string &name) override
Add an instance to the model.
virtual void setRawCPFByFloatColumns(const std::vector< float > &array) override
Gives the factory the CPF in its raw form.
virtual PRMType & type()=0
See gum::PRMClassElement::type().
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.
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Definition: PRMInstance.h:60
virtual void setCPFByFloatRule(const std::vector< std::string > &labels, const std::vector< float > &values) override
Fills the CPF using a rule.
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
Class for discretized random variable.
virtual prm_type obj_type() const =0
Returns the type of this object.
PRMType * __retrieveType(const std::string &name) const
Returns a pointer on a PRMType given it&#39;s name. Since the type can be given either with it&#39;s local na...
virtual void continueClass(const std::string &c) override
Continue the declaration of a class.
PRMClassElementContainer< GUM_SCALAR > * __checkStackContainter(Idx i)
Adds __prefix to str iff __prefix != "".
virtual void continueInterface(const std::string &name) override
Continue the declaration of an interface.
Abstract class representing an element of PRM class.
virtual void addImport(const std::string &name) override
Add an import for namespace lookup.
virtual void startDiscretizedType(const std::string &name) override
Start a discretized type declaration.
PRMClass< GUM_SCALAR > & retrieveClass(const std::string &name)
Returns a reference over a Class<GUM_SCALAR> given its name.
virtual void endAttribute() override
Tells the factory that we finished declaring an attribute.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
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 addReferenceSlot(const std::string &type, const std::string &name, bool isArray) override
Tells the factory that we started declaring a slot.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
virtual PRMClassElement< GUM_SCALAR > & get(const std::string &name)=0
Getter on a member of this PRMClassElementContainer.
PRMType & retrieveCommonType(const std::vector< PRMClassElement< GUM_SCALAR > * > &elts)
Returns a pointer on the PRM<GUM_SCALAR> created by this factory.
Headers files for the gum::FormulaPart and gum::Formula classes.
Base class for discrete random variable.
PRMType & retrieveType(const std::string &name)
Returns a reference over a PRMType given its name.
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...
void __addInstance(PRMClass< GUM_SCALAR > *type, const std::string &name)
Adds a instance to the current model.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
virtual void addAttribute(const std::string &type, const std::string &name) override
Add an attribute to an interface.
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
void setLabel(Idx idx)
Set the aggregator&#39;s label.
A PRMReferenceSlot represent a relation between two PRMClassElementContainer.
Definition: PRMObject.h:220
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.
PRMClassElementContainer< GUM_SCALAR > & slotType()
Returns the type of this slot, which is a PRMClassElementContainer (it is not the type of PRMObject)...
void continueAggregator(const std::string &name)
Conitnues an aggregator declaration.
virtual void incArray(const std::string &l_i, const std::string &r_i) override
Add an instance to an array.
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.
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.
virtual std::string cast(const PRMType &t) const
Returns the name of the cast descendant with PRMType t of this PRMClassElement.
NodeId add(PRMInstance< GUM_SCALAR > *i)
Add an PRMInstance to this system.
Definition: PRMSystem_tpl.h:56
virtual std::string currentPackage() const override
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
virtual Size domainSize() const =0
PRMType * __retrieveCommonType(const std::vector< PRMClassElement< GUM_SCALAR > * > &elts)
Retrieve the common PRMType of a vector of PRMClassElement<GUM_SCALAR>.
void setRawCPFByColumns(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
prm_type
Enumeration of the different types of objects handled by a PRM.
Definition: PRMObject.h:66
virtual PRMObject::prm_type currentType() const override
bool isInstance(const std::string &name) const
Returns true if an PRMInstance with the given name exists.
PRMInstance< GUM_SCALAR > & get(NodeId id)
Returns an PRMInstance given it&#39;s NodeId in the relational skeleton.
Factory which builds a PRM<GUM_SCALAR>.
Definition: PRMType.h:47
const std::string & labelValue() const
See gum::PRMClassElement::elt_type().
std::string to_string(const Formula &f)
Definition: formula_inl.h:479
bool isMultiple() const
Return true if this slot chain contains at least one multiple reference slot.
DiscretizedVariable & addTick(const T_TICKS &aTick)
add a tick.
virtual std::string label(Idx i) const =0
get the indice-th label. This method is pure virtual.
AggregateType agg_type() const
Returns the aggregate of *this.
virtual const Potential< GUM_SCALAR > & cpf() const =0
See gum::PRMClassElement::cpf().
virtual void setCPFByRule(const std::vector< std::string > &labels, const std::vector< GUM_SCALAR > &values)
Fills the CPF using a rule.
<agrum/PRM/elements/funcAttribute.h>
PRMClassElement< GUM_SCALAR > & get(NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
virtual void addArc(const std::string &tail, const std::string &head)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::addArc().
Definition: PRMClass_tpl.h:480
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.
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition: PRMObject.h:226
void __addParent(PRMClassElementContainer< GUM_SCALAR > *c, PRMAttribute< GUM_SCALAR > *agg, const std::string &name)
Add a parent to an attribute.
bool exists(const Key &k) const
Check the existence of k in the sequence.
Definition: sequence_tpl.h:399
Base class for all aGrUM&#39;s exceptions.
Definition: exceptions.h:103
void instantiate()
Instantiate all the PRMInstance in this PRMSystem.
virtual PRMObject * getCurrent() override
virtual NodeId overload(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::overload(PRMClassElement<GUM_SCALAR>*).
Definition: PRMClass_tpl.h:730
std::vector< std::string > __packages
The prefix used for classes and types names. It is normally the namespace of the corresponding compil...
Definition: PRMFactory.h:1040
PRMFactory()
Default constructor.
This is a decoration of the DiscreteVariable class.
Definition: PRMType.h:60
An PRMInterface is implemented by a Class<GUM_SCALAR> and defines a set of PRMReferenceSlot<GUM_SCALA...
Definition: PRMClass.h:51
virtual ClassElementType elt_type() const =0
Return the type of class element this object is.
virtual void endClass(bool checkImplementations=true) override
Tells the factory that we finished a class declaration.
virtual PRMObject * closeCurrent() override
Close current object being built.
Defines a discrete random variable over an integer interval.
Definition: rangeVariable.h:51
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
Definition: PRMObject.h:218
Headers of gum::PRMFormAttribute.
void setRawCPFByLines(const std::vector< GUM_SCALAR > &array)
Gives the factory the CPF in its raw form.
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)=0
Add a PRMClassElement<GUM_SCALAR> to this PRMClassElementContainer.
Abstract base class for any element defined in a PRM.
Definition: PRMObject.h:53
virtual NodeId overload(PRMClassElement< GUM_SCALAR > *elt)=0
Add a PRMClassElement<GUM_SCALAR> which overload an inherited PRMClassElement<GUM_SCALAR>.
void __checkInterfaceImplementation(PRMClass< GUM_SCALAR > *c)
Check if c implements correctly all his interfaces.
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
virtual PRMType & type()
See gum::PRMClassElement::type().
virtual void setOutputNode(const PRMClassElement< GUM_SCALAR > &elt, bool b)
Set the output flag value of id at b.
bool hasLabel() const
Returns true if the label is defined.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:63
std::string __addPrefix(const std::string &str) const
Adds __prefix to str iff __prefix != "".
virtual void startDiscreteType(const std::string &name, std::string super="") override
Start a discrete subtype declaration.
PRMClass< GUM_SCALAR > * __retrieveClass(const std::string &name) const
Returns a pointer on a class given it&#39;s name. Used when building models, meaning that the class name ...
virtual void endDiscretizedType() override
End the current discretized type declaration.
<agrum/PRM/classElementContainer.h>
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 ...
NodeId id() const
Returns the NodeId of this element in it&#39;s class DAG.
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
Definition: PRMClass.h:63
GUM_SCALAR causalWeight(const DiscreteVariable &v) const
Copy of a multiDimICIModel.
bool isArray(const std::string &name) const
Returns true if an array with the given name exists.
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:27
virtual void endDiscreteType() override
End the current discrete type declaration.
virtual void continueAttribute(const std::string &name) override
Continues the declaration of an attribute.
static INLINE bool isSlotChain(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMSlotChain.
Header of gumRangeVariable.
Size Idx
Type for indexes.
Definition: types.h:50
void addParameter(const std::string &type, const std::string &name, double value) override
Add a parameter to the current class with a default value.
std::vector< List< std::string > *> __namespaces
Set of all declared namespaces.
Definition: PRMFactory.h:1043
void add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
int __typeDepth(const PRMType *t)
Returns the inheritance depth of a PRMType.
virtual bool isClassOrInterface(const std::string &type) const override
virtual void addLabel(const std::string &l, std::string ext="") override
Add a label to the current discrete type.
PRMAttribute is a member of a Class in a PRM.
Definition: PRMAttribute.h:58
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
PRMClassElement< GUM_SCALAR > & lastElt()
Returns the last element of the slot chain, typically this is an gum::PRMAttribute or a gum::PRMAggre...
virtual void addArc(const std::string &tail, const std::string &head)=0
Add an arc between two PRMClassElement<GUM_SCALAR>.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
const std::string & name() const
returns the name of the variable
virtual void endSystem() override
Tells the factory that we finished declaring a model.
LabelizedVariable & addLabel(const std::string &aLabel)
add a label with a new index (we assume that we will NEVER remove a label)
bool empty() const noexcept
Indicates whether the hash table is empty.
void addArray(const std::string &array, PRMClassElementContainer< GUM_SCALAR > &type)
Add an array of instances in this system. If the array doesn&#39;t exists it is created.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
<agrum/PRM/elements/formAttribute.h>
<agrum/PRM/elements/scalarAttribute.h>
Idx label() const
Returns the label&#39;s index on which this aggregate applies.
PRMInterface< GUM_SCALAR > * __retrieveInterface(const std::string &name) const
Returns a pointer on an interface given it&#39;s name. Used when building models, meaning that the interf...
PRM< GUM_SCALAR > * prm() const
Returns a pointer on the PRM<GUM_SCALAR> created by this factory.
virtual bool isArrayInCurrentSystem(const std::string &name) const override
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
const Key & back() const
Returns the last element of the sequence.
Definition: sequence_tpl.h:565
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 addParent(const std::string &name) override
Tells the factory that we add a parent to the current declared attribute.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
virtual void addTick(double tick) override
Add a tick to the current discretized type.
Sequence< PRMClassElement< GUM_SCALAR > *> & chain()
Return the sequence representing the chain of elements in this PRMSlotChain.
non-template interface-like parent for every PRM Factory
Definition: IPRMFactory.h:54
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
Headers of PRMFactory.
bool __retrieveInputs(PRMClass< GUM_SCALAR > *c, const std::vector< std::string > &chains, std::vector< PRMClassElement< GUM_SCALAR > * > &inputs)
Retrieve inputs for an PRMAggregate.
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:405