aGrUM  0.16.0
PRMFactory_tpl.h
Go to the documentation of this file.
1 
29 #include <agrum/PRM/PRMFactory.h>
30 
31 #include <iostream>
32 #include <sstream>
33 
35 
38 
41 
42 namespace gum {
43 
44  namespace prm {
45 
46  template < typename GUM_SCALAR >
47  INLINE void
48  PRMFactory< GUM_SCALAR >::startClass(const std::string& name,
49  const std::string& extends,
50  const Set< std::string >* implements,
51  bool delayInheritance) {
52  std::string real_name = __addPrefix(name);
53  if (__prm->__classMap.exists(real_name)
54  || __prm->__interfaceMap.exists(real_name)) {
55  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
56  }
57  PRMClass< GUM_SCALAR >* c = nullptr;
58  PRMClass< GUM_SCALAR >* mother = nullptr;
60 
61  if (implements != 0) {
62  for (const auto& imp : *implements) {
63  impl.insert(__retrieveInterface(imp));
64  }
65  }
66 
67  if (extends != "") { mother = __retrieveClass(extends); }
68 
69  if ((extends == "") && impl.empty()) {
70  c = new PRMClass< GUM_SCALAR >(real_name);
71  } else if ((extends != "") && impl.empty()) {
72  c = new PRMClass< GUM_SCALAR >(real_name, *mother, delayInheritance);
73  } else if ((extends == "") && (!impl.empty())) {
74  c = new PRMClass< GUM_SCALAR >(real_name, impl, delayInheritance);
75  } else if ((extends != "") && (!impl.empty())) {
76  c = new PRMClass< GUM_SCALAR >(real_name, *mother, impl, delayInheritance);
77  }
78 
79  __prm->__classMap.insert(c->name(), c);
80  __prm->__classes.insert(c);
81  __stack.push_back(c);
82  }
83 
84  template < typename GUM_SCALAR >
85  INLINE void PRMFactory< GUM_SCALAR >::continueClass(const std::string& name) {
86  std::string real_name = __addPrefix(name);
87  if (!(__prm->__classMap.exists(real_name))) {
88  std::stringstream msg;
89  msg << "'" << real_name << "' not found";
90  GUM_ERROR(NotFound, msg.str());
91  }
92  __stack.push_back(&(__prm->getClass(real_name)));
93  }
94 
95  template < typename GUM_SCALAR >
96  INLINE void PRMFactory< GUM_SCALAR >::endClass(bool checkImplementations) {
98  __checkStack(1, PRMObject::prm_type::CLASS));
99 
100  if (checkImplementations) { __checkInterfaceImplementation(c); }
101 
102  __stack.pop_back();
103  }
104 
105  template < typename GUM_SCALAR >
108  try {
109  for (const auto& i : c->implements()) {
110  try {
111  for (const auto& node : i->containerDag().nodes()) {
112  std::string name = i->get(node).name();
113 
114  switch (i->get(node).elt_type()) {
117  if ((c->get(name).elt_type()
119  || (c->get(name).elt_type()
121  if (!c->get(name).type().isSubTypeOf(i->get(name).type())) {
122  std::stringstream msg;
123  msg << "class " << c->name()
124  << " does not respect interface ";
125  GUM_ERROR(TypeError, msg.str() + i->name());
126  }
127  } else {
128  std::stringstream msg;
129  msg << "class " << c->name() << " does not respect interface ";
130  GUM_ERROR(TypeError, msg.str() + i->name());
131  }
132 
133  break;
134  }
135 
137  if (c->get(name).elt_type()
139  const PRMReferenceSlot< GUM_SCALAR >& ref_i =
140  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
141  i->get(name));
142  const PRMReferenceSlot< GUM_SCALAR >& ref_this =
143  static_cast< const PRMReferenceSlot< GUM_SCALAR >& >(
144  c->get(name));
145 
146  if (!ref_this.slotType().isSubTypeOf(ref_i.slotType())) {
147  std::stringstream msg;
148  msg << "class " << c->name()
149  << " does not respect interface ";
150  GUM_ERROR(TypeError, msg.str() + i->name());
151  }
152  } else {
153  std::stringstream msg;
154  msg << "class " << c->name() << " does not respect interface ";
155  GUM_ERROR(TypeError, msg.str() + i->name());
156  }
157 
158  break;
159  }
160 
162  // Nothing to check: they are automatically inherited
163  break;
164  }
165 
166  default: {
167  std::string msg =
168  "unexpected ClassElement<GUM_SCALAR> in interface ";
169  GUM_ERROR(FatalError, msg + i->name());
170  }
171  }
172  }
173  } catch (NotFound&) {
174  std::stringstream msg;
175  msg << "class " << c->name() << " does not respect interface ";
176  GUM_ERROR(TypeError, msg.str() + i->name());
177  }
178  }
179  } catch (NotFound&) {
180  // this Class<GUM_SCALAR> does not implement any
181  // PRMInterface<GUM_SCALAR>
182  }
183  }
184 
185  template < typename GUM_SCALAR >
186  INLINE void
188  const std::string& extends,
189  bool delayInheritance) {
190  std::string real_name = __addPrefix(name);
191  if (__prm->__classMap.exists(real_name)
192  || __prm->__interfaceMap.exists(real_name)) {
193  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
194  }
195  PRMInterface< GUM_SCALAR >* i = nullptr;
196  PRMInterface< GUM_SCALAR >* super = nullptr;
197 
198  if (extends != "") { super = __retrieveInterface(extends); }
199 
200  if (super != nullptr) {
201  i = new PRMInterface< GUM_SCALAR >(real_name, *super, delayInheritance);
202  } else {
203  i = new PRMInterface< GUM_SCALAR >(real_name);
204  }
205 
206  __prm->__interfaceMap.insert(i->name(), i);
207  __prm->__interfaces.insert(i);
208  __stack.push_back(i);
209  }
210 
211  template < typename GUM_SCALAR >
212  INLINE void
214  std::string real_name = __addPrefix(name);
215  if (!__prm->__interfaceMap.exists(real_name)) {
216  GUM_ERROR(DuplicateElement, "'" << real_name << "' not found.");
217  }
218 
219  PRMInterface< GUM_SCALAR >* i = __retrieveInterface(real_name);
220  __stack.push_back(i);
221  }
222 
223  template < typename GUM_SCALAR >
224  INLINE void
226  PRMClass< GUM_SCALAR >* c = static_cast< PRMClass< GUM_SCALAR >* >(
227  __checkStack(1, PRMObject::prm_type::CLASS));
228  c->add(attr);
229  Size count = 0;
231  attr->cpf().variablesSequence();
232 
233  for (const auto& node : c->containerDag().nodes()) {
234  try {
235  if (vars.exists(&(c->get(node).type().variable()))) {
236  ++count;
237 
238  if (&(attr->type().variable()) != &(c->get(node).type().variable())) {
239  c->addArc(c->get(node).safeName(), attr->safeName());
240  }
241  }
242  } catch (OperationNotAllowed&) {}
243  }
244 
245  if (count != attr->cpf().variablesSequence().size()) {
246  GUM_ERROR(NotFound, "unable to found all parents of this attribute");
247  }
248  }
249 
250  template < typename GUM_SCALAR >
254  const std::string& name) {
255  try {
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()) {
268  "can not add a multiple slot chain to an attribute");
269  }
270 
271  c->addArc(name, a->name());
272 
273  break;
274  }
275 
278  c->addArc(name, a->name());
279  break;
280  }
281 
282  default: {
283  GUM_ERROR(FatalError, "unknown ClassElement<GUM_SCALAR>");
284  }
285  }
286  } catch (NotFound&) {
287  // Check if name is a slot chain
288  PRMSlotChain< GUM_SCALAR >* sc = __buildSlotChain(c, name);
289 
290  if (sc == nullptr) {
291  std::string msg =
292  "found no ClassElement<GUM_SCALAR> with the given name ";
293  GUM_ERROR(NotFound, msg + name);
294  } else if (!sc->isMultiple()) {
295  c->add(sc);
296  c->addArc(sc->name(), a->name());
297  } else {
298  delete sc;
300  "Impossible to add a multiple reference slot as"
301  " direct parent of an PRMAttribute<GUM_SCALAR>.");
302  }
303  }
304  }
305 
306 
307  template < typename GUM_SCALAR >
308  INLINE void PRMFactory< GUM_SCALAR >::addParent(const std::string& name) {
309  PRMClassElementContainer< GUM_SCALAR >* c = __checkStackContainter(2);
310  try {
311  // Retrieving pointers
314  __addParent(c, a, name);
315  } catch (FactoryInvalidState&) {
316  auto agg = static_cast< PRMAggregate< GUM_SCALAR >* >(
318  __addParent(static_cast< PRMClass< GUM_SCALAR >* >(c), agg, name);
319  }
320  }
321 
322  template < typename GUM_SCALAR >
324  const std::vector< float >& array) {
327  __checkStack(2, PRMObject::prm_type::CLASS);
328 
329  if (a->cpf().domainSize() != array.size())
330  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
331 
332  std::vector< GUM_SCALAR > array2(array.begin(), array.end());
333  a->cpf().fillWith(array2);
334  }
335 
336  template < typename GUM_SCALAR >
338  const std::vector< GUM_SCALAR >& array) {
339  auto elt = __checkStack(1, PRMClassElement< GUM_SCALAR >::prm_attribute);
340  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(elt);
341  __checkStack(2, PRMObject::prm_type::CLASS);
342 
343  if (a->cpf().domainSize() != array.size()) {
344  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
345  }
346 
347  a->cpf().fillWith(array);
348  }
349 
350  template < typename GUM_SCALAR >
352  const std::vector< float >& array) {
355 
356  if (a->cpf().domainSize() != array.size()) {
357  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
358  }
359 
360  std::vector< GUM_SCALAR > array2(array.begin(), array.end());
361  setRawCPFByColumns(array2);
362  }
363 
364  template < typename GUM_SCALAR >
366  const std::vector< GUM_SCALAR >& array) {
369 
370  if (a->cpf().domainSize() != array.size()) {
371  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
372  }
373 
374  if (a->cpf().nbrDim() == 1) {
375  setRawCPFByLines(array);
376 
377  } else {
378  Instantiation inst(a->cpf());
379  Instantiation jnst;
380  for (auto idx = inst.variablesSequence().rbegin();
381  idx != inst.variablesSequence().rend();
382  --idx) {
383  jnst.add(**idx);
384  }
385 
386  jnst.setFirst();
387  auto idx = (std::size_t)0;
388  while ((!jnst.end()) && idx < array.size()) {
389  inst.setVals(jnst);
390  a->cpf().set(inst, array[idx]);
391  jnst.inc();
392  ++idx;
393  }
394  }
395  }
396 
397  template < typename GUM_SCALAR >
399  const std::vector< std::string >& parents,
400  const std::vector< float >& values) {
401  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
403 
404  if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
405  GUM_ERROR(OperationNotAllowed, "wrong number of parents");
406  }
407 
408  if (values.size() != a->type().variable().domainSize()) {
409  GUM_ERROR(OperationNotAllowed, "wrong number of values");
410  }
411 
412  std::vector< GUM_SCALAR > values2(values.begin(), values.end());
413  setCPFByRule(parents, values2);
414  }
415 
416  template < typename GUM_SCALAR >
418  const std::vector< std::string >& parents,
419  const std::vector< GUM_SCALAR >& values) {
420  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
422 
423  if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
424  GUM_ERROR(OperationNotAllowed, "wrong number of parents");
425  }
426 
427  if (values.size() != a->type().variable().domainSize()) {
428  GUM_ERROR(OperationNotAllowed, "wrong number of values");
429  }
430 
431  if (dynamic_cast< PRMFormAttribute< GUM_SCALAR >* >(a)) {
432  auto form = static_cast< PRMFormAttribute< GUM_SCALAR >* >(a);
433  // jnst holds parents with a specific value (not "*")
434  // knst holds parents without a specific value ("*")
435  Instantiation jnst, knst;
436  const DiscreteVariable* var = 0;
437  // not_used Size pos = 0;
438  bool found = false;
439 
440  for (Idx i = 0; i < parents.size(); ++i) {
441  var = form->formulas().variablesSequence().atPos(1 + i);
442 
443  if (parents[i] == "*") {
444  knst.add(*var);
445  } else {
446  jnst.add(*var);
447  // not_used pos = 0;
448  found = false;
449 
450  for (Size j = 0; j < var->domainSize(); ++j) {
451  if (var->label(j) == parents[i]) {
452  jnst.chgVal(*var, j);
453  found = true;
454  break;
455  }
456  }
457 
458  if (!found) {
459  std::string msg = "could not find label ";
460  GUM_ERROR(NotFound, msg + parents[i]);
461  }
462  }
463  }
464 
465  Instantiation inst(form->formulas());
466  inst.setVals(jnst);
467 
468  for (Size i = 0; i < form->type()->domainSize(); ++i) {
469  inst.chgVal(form->type().variable(), i);
470 
471  for (inst.setFirstIn(knst); !inst.end(); inst.incIn(knst)) {
472  form->formulas().set(inst, std::to_string(values[i]));
473  }
474  }
475 
476  } else {
477  GUM_ERROR(OperationNotAllowed, "invalide attribute type");
478  }
479  }
480 
481  template < typename GUM_SCALAR >
483  const std::vector< std::string >& parents,
484  const std::vector< std::string >& values) {
485  auto a = static_cast< PRMAttribute< GUM_SCALAR >* >(
487 
488  if ((parents.size() + 1) != a->cpf().variablesSequence().size()) {
489  GUM_ERROR(OperationNotAllowed, "wrong number of parents");
490  }
491 
492  if (values.size() != a->type().variable().domainSize()) {
493  GUM_ERROR(OperationNotAllowed, "wrong number of values");
494  }
495 
496  if (dynamic_cast< PRMFormAttribute< GUM_SCALAR >* >(a)) {
497  auto form = static_cast< PRMFormAttribute< GUM_SCALAR >* >(a);
498  // jnst holds parents with a specific value (not "*")
499  // knst holds parents without a specific value ("*")
500  Instantiation jnst, knst;
501  const DiscreteVariable* var = 0;
502  // not_used Size pos = 0;
503  bool found = false;
504 
505  for (Idx i = 0; i < parents.size(); ++i) {
506  var = form->formulas().variablesSequence().atPos(1 + i);
507 
508  if (parents[i] == "*") {
509  knst.add(*var);
510  } else {
511  jnst.add(*var);
512  // not_used pos = 0;
513  found = false;
514 
515  for (Size j = 0; j < var->domainSize(); ++j) {
516  if (var->label(j) == parents[i]) {
517  jnst.chgVal(*var, j);
518  found = true;
519  break;
520  }
521  }
522 
523  if (!found) {
524  std::string msg = "could not find label ";
525  GUM_ERROR(NotFound, msg + parents[i]);
526  }
527  }
528  }
529 
530  Instantiation inst(form->formulas());
531  inst.setVals(jnst);
532 
533  for (Size i = 0; i < form->type()->domainSize(); ++i) {
534  inst.chgVal(form->type().variable(), i);
535 
536  for (inst.setFirstIn(knst); !inst.end(); inst.incIn(knst)) {
537  form->formulas().set(inst, values[i]);
538  }
539  }
540 
541  } else {
542  GUM_ERROR(OperationNotAllowed, "invalide attribute type");
543  }
544  }
545 
546  template < typename GUM_SCALAR >
547  INLINE void PRMFactory< GUM_SCALAR >::addParameter(const std::string& type,
548  const std::string& name,
549  double value) {
550  auto c = static_cast< PRMClass< GUM_SCALAR >* >(
551  __checkStack(1, PRMObject::prm_type::CLASS));
552 
553  PRMParameter< GUM_SCALAR >* p = nullptr;
554  if (type == "int") {
556  name,
558  (GUM_SCALAR)value);
559  } else if (type == "real") {
561  name,
563  (GUM_SCALAR)value);
564  }
565 
566  try {
567  c->add(p);
568  } catch (DuplicateElement&) { c->overload(p); }
569  }
570 
571  template < typename GUM_SCALAR >
573  const std::string& name,
574  const std::string& agg_type,
575  const std::string& rv_type,
576  const std::vector< std::string >& params) {
577  PRMClass< GUM_SCALAR >* c = static_cast< PRMClass< GUM_SCALAR >* >(
578  __checkStack(1, PRMObject::prm_type::CLASS));
579 
580  auto agg = new PRMAggregate< GUM_SCALAR >(
581  name,
583  *__retrieveType(rv_type));
584 
585  try {
586  c->add(agg);
587  } catch (DuplicateElement&) { c->overload(agg); }
588 
589  switch (agg->agg_type()) {
593  if (params.size() != 1) {
594  GUM_ERROR(OperationNotAllowed, "aggregate requires a parameter");
595  }
596  agg->setLabel(params.front());
597  break;
598  }
599  default: {
600  // Nothing to do
601  }
602  }
603  __stack.push_back(agg);
604  }
605 
606  template < typename GUM_SCALAR >
607  INLINE void
609  PRMClassElementContainer< GUM_SCALAR >* c = __checkStackContainter(1);
610  if (!c->exists(name)) { GUM_ERROR(NotFound, name << "not found"); }
611  auto& agg = c->get(name);
613  GUM_ERROR(OperationNotAllowed, name << " not an aggregate");
614  }
615  __stack.push_back(&agg);
616  }
617 
618  template < typename GUM_SCALAR >
619  INLINE void
622  const std::string& name) {
623  auto chains = std::vector< std::string >{name};
624  auto inputs = std::vector< PRMClassElement< GUM_SCALAR >* >();
625  __retrieveInputs(c, chains, inputs);
626 
627  switch (agg->agg_type()) {
630  if (inputs.front()->type() != *(__retrieveType("boolean"))) {
631  GUM_ERROR(WrongType, "expected booleans");
632  }
633 
634  break;
635  }
636 
640  if (!agg->hasLabel()) {
641  auto param = agg->labelValue();
642  Idx label_idx = 0;
643 
644  while (label_idx < inputs.front()->type()->domainSize()) {
645  if (inputs.front()->type()->label(label_idx) == param) { break; }
646 
647  ++label_idx;
648  }
649 
650  if (label_idx == inputs.front()->type()->domainSize()) {
651  GUM_ERROR(NotFound, "could not find label");
652  }
653 
654  agg->setLabel(label_idx);
655  }
656 
657  break;
658  }
659 
664  break;
665  }
666 
667  default: {
668  GUM_ERROR(FatalError, "Unknown aggregator.");
669  }
670  }
671 
672  c->addArc(inputs.front()->safeName(), agg->safeName());
673  }
674 
675  template < typename GUM_SCALAR >
678  __stack.pop_back();
679  }
680 
681  template < typename GUM_SCALAR >
683  const std::string& name,
684  const std::string& agg_type,
685  const std::vector< std::string >& chains,
686  const std::vector< std::string >& params,
687  std::string type) {
688  PRMClass< GUM_SCALAR >* c = static_cast< PRMClass< GUM_SCALAR >* >(
689  __checkStack(1, PRMObject::prm_type::CLASS));
690  // Checking call legality
691 
692  if (chains.size() == 0) {
694  "a PRMAggregate<GUM_SCALAR> requires at least one parent");
695  }
696 
697  // Retrieving the parents of the aggregate
698  std::vector< PRMClassElement< GUM_SCALAR >* > inputs;
699 
700  // This helps knowing if the aggregate has parents outside the current
701  // class
702  // (see below)
703  bool hasSC = __retrieveInputs(c, chains, inputs);
704 
705  // Checking that all inputs shares the same PRMType (trivial
706  // if
707  // inputs.size() == 1)
708  if (inputs.size() > 1) {
709  for (auto iter = inputs.begin() + 1; iter != inputs.end(); ++iter) {
710  if ((**(iter - 1)).type() != (**iter).type()) {
711  GUM_ERROR(WrongType, "found different types");
712  }
713  }
714  }
715 
716  // Different treatments for different types of aggregate.
717  PRMAggregate< GUM_SCALAR >* agg = nullptr;
718 
719  switch (PRMAggregate< GUM_SCALAR >::str2enum(agg_type)) {
722  if (inputs.front()->type() != *(__retrieveType("boolean"))) {
723  GUM_ERROR(WrongType, "expected booleans");
724  }
725  if (params.size() != 0) {
726  GUM_ERROR(OperationNotAllowed, "invalid number of paramaters");
727  }
728 
729  agg = new PRMAggregate< GUM_SCALAR >(
730  name,
732  inputs.front()->type());
733 
734  break;
735  }
736 
739  if (params.size() != 1) {
740  GUM_ERROR(OperationNotAllowed, "invalid number of parameters");
741  }
742 
743  Idx label_idx = 0;
744 
745  while (label_idx < inputs.front()->type()->domainSize()) {
746  if (inputs.front()->type()->label(label_idx) == params.front()) {
747  break;
748  }
749 
750  ++label_idx;
751  }
752 
753  if (label_idx == inputs.front()->type()->domainSize()) {
754  GUM_ERROR(NotFound, "could not find label");
755  }
756 
757  // Creating and adding the PRMAggregate<GUM_SCALAR>
758  agg = new PRMAggregate< GUM_SCALAR >(
759  name,
761  *(__retrieveType("boolean")),
762  label_idx);
763  agg->label();
764 
765  break;
766  }
767 
772  if (params.size() != 0) {
773  GUM_ERROR(OperationNotAllowed, "invalid number of parameters");
774  }
775 
776  auto output_type = __retrieveType(type);
777 
778  // Creating and adding the PRMAggregate<GUM_SCALAR>
779  agg = new PRMAggregate< GUM_SCALAR >(
780  name, PRMAggregate< GUM_SCALAR >::str2enum(agg_type), *output_type);
781 
782  break;
783  }
784 
786  if (params.size() != 1) {
787  GUM_ERROR(OperationNotAllowed, "invalid number of parameters");
788  }
789 
790  Idx label_idx = 0;
791 
792  while (label_idx < inputs.front()->type()->domainSize()) {
793  if (inputs.front()->type()->label(label_idx) == params.front()) {
794  break;
795  }
796 
797  ++label_idx;
798  }
799 
800  if (label_idx == inputs.front()->type()->domainSize()) {
801  GUM_ERROR(NotFound, "could not find label");
802  }
803 
804  auto output_type = __retrieveType(type);
805 
806  // Creating and adding the PRMAggregate<GUM_SCALAR>
807  agg = new PRMAggregate< GUM_SCALAR >(
808  name,
810  *output_type,
811  label_idx);
812 
813  break;
814  }
815 
816  default: {
817  GUM_ERROR(FatalError, "Unknown aggregator.");
818  }
819  }
820 
821  std::string safe_name = agg->safeName();
822 
823  try {
824  if (hasSC) {
825  try {
826  c->add(agg);
827  } catch (DuplicateElement&) { c->overload(agg); }
828  } else {
829  // Inner aggregators can be directly used as attributes
830  auto attr = new PRMScalarAttribute< GUM_SCALAR >(
831  agg->name(), agg->type(), agg->buildImpl());
832 
833  try {
834  c->add(attr);
835  } catch (DuplicateElement&) { c->overload(attr); }
836 
837  delete agg;
838  }
839  } catch (DuplicateElement&) {
840  delete agg;
841  throw;
842  }
843 
844  for (const auto& elt : inputs) {
845  c->addArc(elt->safeName(), safe_name);
846  }
847  }
848 
849  template < typename GUM_SCALAR >
850  INLINE void PRMFactory< GUM_SCALAR >::addReferenceSlot(const std::string& type,
851  const std::string& name,
852  bool isArray) {
853  PRMClassElementContainer< GUM_SCALAR >* owner = __checkStackContainter(1);
855 
856  try {
857  slotType = __retrieveClass(type);
858  } catch (NotFound&) {
859  try {
860  slotType = __retrieveInterface(type);
861  } catch (NotFound&) {
862  GUM_ERROR(NotFound, "unknown ReferenceSlot<GUM_SCALAR> slot type");
863  }
864  }
865 
867  new PRMReferenceSlot< GUM_SCALAR >(name, *slotType, isArray);
868 
869  try {
870  owner->add(ref);
871  } catch (DuplicateElement&) { owner->overload(ref); }
872  }
873 
874  template < typename GUM_SCALAR >
875  INLINE void PRMFactory< GUM_SCALAR >::addArray(const std::string& type,
876  const std::string& name,
877  Size size) {
878  PRMSystem< GUM_SCALAR >* model = static_cast< PRMSystem< GUM_SCALAR >* >(
879  __checkStack(1, PRMObject::prm_type::SYSTEM));
880  PRMClass< GUM_SCALAR >* c = __retrieveClass(type);
881  PRMInstance< GUM_SCALAR >* inst = 0;
882 
883  try {
884  model->addArray(name, *c);
885 
886  for (Size i = 0; i < size; ++i) {
887  std::stringstream elt_name;
888  elt_name << name << "[" << i << "]";
889  inst = new PRMInstance< GUM_SCALAR >(elt_name.str(), *c);
890  model->add(name, inst);
891  }
892  } catch (TypeError&) {
893  delete inst;
894  throw;
895  } catch (NotFound&) {
896  delete inst;
897  throw;
898  }
899  }
900 
901  template < typename GUM_SCALAR >
902  INLINE void PRMFactory< GUM_SCALAR >::incArray(const std::string& l_i,
903  const std::string& r_i) {
904  PRMSystem< GUM_SCALAR >* model = static_cast< PRMSystem< GUM_SCALAR >* >(
905  __checkStack(1, PRMObject::prm_type::SYSTEM));
906 
907  if (model->isArray(l_i)) {
908  if (model->isInstance(r_i)) {
909  model->add(l_i, model->get(r_i));
910  } else {
911  GUM_ERROR(NotFound, "right value is not an instance");
912  }
913  } else {
914  GUM_ERROR(NotFound, "left value is no an array");
915  }
916  }
917 
918  template < typename GUM_SCALAR >
920  const std::string& l_i, const std::string& l_ref, const std::string& r_i) {
921  auto model = static_cast< PRMSystem< GUM_SCALAR >* >(
922  __checkStack(1, PRMObject::prm_type::SYSTEM));
923  std::vector< PRMInstance< GUM_SCALAR >* > lefts;
924  std::vector< PRMInstance< GUM_SCALAR >* > rights;
925 
926  if (model->isInstance(l_i)) {
927  lefts.push_back(&(model->get(l_i)));
928  } else if (model->isArray(l_i)) {
929  for (const auto& elt : model->getArray(l_i))
930  lefts.push_back(elt);
931  } else {
932  GUM_ERROR(NotFound, "left value does not name an instance or an array");
933  }
934 
935  if (model->isInstance(r_i)) {
936  rights.push_back(&(model->get(r_i)));
937  } else if (model->isArray(r_i)) {
938  for (const auto& elt : model->getArray(r_i))
939  rights.push_back(elt);
940  } else {
941  GUM_ERROR(NotFound, "left value does not name an instance or an array");
942  }
943 
944  for (const auto l : lefts) {
945  for (const auto r : rights) {
946  auto& elt = l->type().get(l_ref);
948  l->add(elt.id(), *r);
949 
950  } else {
951  GUM_ERROR(NotFound, "unfound reference slot");
952  }
953  }
954  }
955  }
956 
957  template < typename GUM_SCALAR >
959  PRMClassElementContainer< GUM_SCALAR >* start, const std::string& name) {
960  std::vector< std::string > v;
961  decomposePath(name, v);
963  PRMReferenceSlot< GUM_SCALAR >* ref = nullptr;
965 
966  for (size_t i = 0; i < v.size(); ++i) {
967  try {
968  switch (current->get(v[i]).elt_type()) {
970  ref = &(static_cast< PRMReferenceSlot< GUM_SCALAR >& >(
971  current->get(v[i])));
972  elts.insert(ref);
973  current = &(/*const_cast<PRMClassElementContainer<GUM_SCALAR>&>*/ (
974  ref->slotType()));
975  break;
976 
979 
980  if (i == v.size() - 1) {
981  elts.insert(&(current->get(v[i])));
982  break;
983  } else {
984  return nullptr;
985  }
986 
987  default: {
988  return nullptr;
989  }
990  }
991  } catch (NotFound&) { return nullptr; }
992  }
993 
994  GUM_ASSERT(v.size() == elts.size());
995 
996  current->setOutputNode(*(elts.back()), true);
997 
998  return new PRMSlotChain< GUM_SCALAR >(name, elts);
999  }
1000 
1001  template < typename GUM_SCALAR >
1004  const std::vector< std::string >& chains,
1005  std::vector< PRMClassElement< GUM_SCALAR >* >& inputs) {
1006  bool retVal = false;
1007 
1008  for (size_t i = 0; i < chains.size(); ++i) {
1009  try {
1010  inputs.push_back(&(c->get(chains[i])));
1011  retVal = retVal
1012  || PRMClassElement< GUM_SCALAR >::isSlotChain(*(inputs.back()));
1013  } catch (NotFound&) {
1014  inputs.push_back(__buildSlotChain(c, chains[i]));
1015  retVal = true;
1016 
1017  if (inputs.back()) {
1018  c->add(inputs.back());
1019  } else {
1020  GUM_ERROR(NotFound, "unknown slot chain");
1021  }
1022  }
1023  }
1024 
1025  PRMType* t = __retrieveCommonType(inputs);
1026 
1027  std::vector< std::pair< PRMClassElement< GUM_SCALAR >*,
1029  toAdd;
1030 
1031  for (const auto& elt : inputs) {
1032  if ((*elt).type() != (*t)) {
1035  static_cast< PRMSlotChain< GUM_SCALAR >* >(elt);
1036  std::stringstream name;
1037 
1038  for (Size idx = 0; idx < sc->chain().size() - 1; ++idx) {
1039  name << sc->chain().atPos(idx)->name() << ".";
1040  }
1041 
1042  name << ".(" << t->name() << ")" << sc->lastElt().name();
1043 
1044  try {
1045  toAdd.push_back(std::make_pair(elt, &(c->get(name.str()))));
1046  } catch (NotFound&) {
1047  toAdd.push_back(
1048  std::make_pair(elt, __buildSlotChain(c, name.str())));
1049  }
1050  } else {
1051  std::stringstream name;
1052  name << "(" << t->name() << ")" << elt->name();
1053  toAdd.push_back(std::make_pair(elt, &(c->get(name.str()))));
1054  }
1055  }
1056  }
1057 
1058  return retVal;
1059  }
1060 
1061  template < typename GUM_SCALAR >
1063  const std::vector< PRMClassElement< GUM_SCALAR >* >& elts) {
1064  const PRMType* current = nullptr;
1066  // Finding all types and super types
1067 
1068  for (const auto& elt : elts) {
1069  try {
1070  current = &((*elt).type());
1071 
1072  while (current != 0) {
1073  // Filling counters
1074  if (counters.exists(current->name())) {
1075  ++(counters[current->name()]);
1076  } else {
1077  counters.insert(current->name(), 1);
1078  }
1079 
1080  // Loop guard
1081  if (current->isSubType()) {
1082  current = &(current->superType());
1083  } else {
1084  current = nullptr;
1085  }
1086  }
1087  } catch (OperationNotAllowed&) {
1089  "found a ClassElement<GUM_SCALAR> without a type");
1090  }
1091  }
1092 
1093  // We need to find the most specialized (i.e. max depth) common type
1094  current = nullptr;
1095 
1096  int max_depth = -1;
1097 
1098  int current_depth = 0;
1099 
1100  for (const auto& elt : counters) {
1101  if ((elt.second) == elts.size()) {
1102  current_depth = __typeDepth(__retrieveType(elt.first));
1103 
1104  if (current_depth > max_depth) {
1105  max_depth = current_depth;
1106  current = __retrieveType(elt.first);
1107  }
1108  }
1109  }
1110 
1111  if (current) { return const_cast< PRMType* >(current); }
1112 
1113  GUM_ERROR(NotFound, "could not find a common type");
1114  }
1115 
1116  template < typename GUM_SCALAR >
1118  const std::string& name,
1119  const std::vector< std::string >& chains,
1120  const std::vector< float >& numbers,
1121  float leak,
1122  const std::vector< std::string >& labels) {
1123  if (currentType() != PRMObject::prm_type::CLASS) {
1124  GUM_ERROR(gum::FactoryInvalidState, "invalid state to add a noisy-or");
1125  }
1126 
1128  dynamic_cast< gum::prm::PRMClass< GUM_SCALAR >* >(getCurrent());
1129 
1130  std::vector< PRMClassElement< GUM_SCALAR >* > parents;
1131 
1132  for (const auto& elt : chains)
1133  parents.push_back(&(c->get(elt)));
1134 
1135  PRMType* common_type = __retrieveCommonType(parents);
1136 
1137  for (size_t idx = 0; idx < parents.size(); ++idx) {
1138  if (parents[idx]->type() != (*common_type)) {
1139  PRMClassElement< GUM_SCALAR >* parent = parents[idx];
1140  // Either safe_name is an non existing slot chain or an existing cast
1141  // descendant
1142  std::string safe_name = parent->cast(*common_type);
1143 
1144  if (!c->exists(safe_name)) {
1146  parents[idx] = __buildSlotChain(c, safe_name);
1147  c->add(parents[idx]);
1148  } else {
1149  GUM_ERROR(NotFound, "unable to find parent");
1150  }
1151  } else {
1152  parents[idx] = &(c->get(safe_name));
1153  }
1154  }
1155  }
1156 
1157  if (numbers.size() == 1) {
1158  auto impl =
1159  new gum::MultiDimNoisyORCompound< GUM_SCALAR >(leak, numbers.front());
1160  auto attr = new PRMScalarAttribute< GUM_SCALAR >(
1161  name, retrieveType("boolean"), impl);
1162  addAttribute(attr);
1163  } else if (numbers.size() == parents.size()) {
1168  name, retrieveType("boolean"), noisy);
1169 
1170  for (size_t idx = 0; idx < numbers.size(); ++idx) {
1171  noisy->causalWeight(parents[idx]->type().variable(), numbers[idx]);
1172  }
1173 
1174  addAttribute(attr);
1175  } else {
1176  GUM_ERROR(OperationNotAllowed, "invalid parameters for a noisy or");
1177  }
1178 
1179  if (!labels.empty()) {
1181  "labels definitions not handle for noisy-or");
1182  }
1183  }
1184 
1185  template < typename GUM_SCALAR >
1186  INLINE PRMType*
1187  PRMFactory< GUM_SCALAR >::__retrieveType(const std::string& name) const {
1188  PRMType* type = nullptr;
1189  std::string full_name;
1190 
1191  // Looking for the type using its name
1192  if (__prm->__typeMap.exists(name)) {
1193  type = __prm->__typeMap[name];
1194  full_name = name;
1195  }
1196 
1197  // Looking for the type in current package
1198  std::string prefixed = __addPrefix(name);
1199  if (__prm->__typeMap.exists(prefixed)) {
1200  if (type == 0) {
1201  type = __prm->__typeMap[prefixed];
1202  full_name = prefixed;
1203  } else if (full_name != prefixed) {
1205  "Type name '" << name << "' is ambiguous: specify full name.");
1206  }
1207  }
1208 
1209  // Looking for the type relatively to current package
1210  std::string relatif_ns = currentPackage();
1211  size_t last_dot = relatif_ns.find_last_of('.');
1212  if (last_dot != std::string::npos) {
1213  relatif_ns = relatif_ns.substr(0, last_dot) + '.' + name;
1214  if (__prm->__typeMap.exists(relatif_ns)) {
1215  if (type == 0) {
1216  type = __prm->__typeMap[relatif_ns];
1217  full_name = relatif_ns;
1218  } else if (full_name != relatif_ns) {
1220  "Type name '" << name
1221  << "' is ambiguous: specify full name.");
1222  }
1223  }
1224  }
1225 
1226 
1227  // Looking for the type using all declared namespaces
1228  if (!__namespaces.empty()) {
1229  auto ns_list = __namespaces.back();
1230  for (gum::Size i = 0; i < ns_list->size(); ++i) {
1231  std::string ns = (*ns_list)[i];
1232  std::string ns_name = ns + "." + name;
1233  if (__prm->__typeMap.exists(ns_name)) {
1234  if (type == 0) {
1235  type = __prm->__typeMap[ns_name];
1236  full_name = ns_name;
1237  } else if (full_name != ns_name) {
1239  "Type name '" << name
1240  << "' is ambiguous: specify full name.");
1241  }
1242  }
1243  }
1244  }
1245 
1246  if (type == 0) {
1247  GUM_ERROR(NotFound, "Type '" << name << "' not found, check imports.");
1248  }
1249 
1250  return type;
1251  }
1252 
1253  template < typename GUM_SCALAR >
1255  PRMFactory< GUM_SCALAR >::__retrieveClass(const std::string& name) const {
1256  PRMClass< GUM_SCALAR >* a_class = nullptr;
1257  std::string full_name;
1258 
1259  // Looking for the type using its name
1260  if (__prm->__classMap.exists(name)) {
1261  a_class = __prm->__classMap[name];
1262  full_name = name;
1263  }
1264 
1265  // Looking for the type using current package
1266  std::string prefixed = __addPrefix(name);
1267  if (__prm->__classMap.exists(prefixed)) {
1268  if (a_class == nullptr) {
1269  a_class = __prm->__classMap[prefixed];
1270  full_name = prefixed;
1271  } else if (full_name != prefixed) {
1273  "Class name '" << name
1274  << "' is ambiguous: specify full name.");
1275  }
1276  }
1277 
1278  // Looking for the class using all declared namespaces
1279  if (!__namespaces.empty()) {
1280  auto ns_list = __namespaces.back();
1281  for (gum::Size i = 0; i < ns_list->size(); ++i) {
1282  std::string ns = (*ns_list)[i];
1283  std::string ns_name = ns + "." + name;
1284  if (__prm->__classMap.exists(ns_name)) {
1285  if (a_class == 0) {
1286  a_class = __prm->__classMap[ns_name];
1287  full_name = ns_name;
1288  } else if (full_name != ns_name) {
1290  "Class name '" << name
1291  << "' is ambiguous: specify full name.");
1292  }
1293  }
1294  }
1295  }
1296 
1297  if (a_class == 0) {
1298  GUM_ERROR(NotFound, "Class '" << name << "' not found, check imports.");
1299  }
1300 
1301  return a_class;
1302  }
1303 
1304  template < typename GUM_SCALAR >
1306  const std::string& name) const {
1307  PRMInterface< GUM_SCALAR >* interface = nullptr;
1308  std::string full_name;
1309 
1310  // Looking for the type using its name
1311  if (__prm->__interfaceMap.exists(name)) {
1312  interface = __prm->__interfaceMap[name];
1313  full_name = name;
1314  }
1315 
1316  // Looking for the type using current package
1317  std::string prefixed = __addPrefix(name);
1318  if (__prm->__interfaceMap.exists(prefixed)) {
1319  if (interface == nullptr) {
1320  interface = __prm->__interfaceMap[prefixed];
1321  full_name = prefixed;
1322  } else if (full_name != prefixed) {
1324  "Interface name '" << name
1325  << "' is ambiguous: specify full name.");
1326  }
1327  }
1328 
1329  // Looking for the interf using all declared namespaces
1330  if (!__namespaces.empty()) {
1331  auto ns_list = __namespaces.back();
1332  // for( const auto & ns : *(__namespaces.top()) ) {
1333  for (gum::Size i = 0; i < ns_list->size(); ++i) {
1334  std::string ns = (*ns_list)[i];
1335  std::string ns_name = ns + "." + name;
1336 
1337  if (__prm->__interfaceMap.exists(ns_name)) {
1338  if (interface == nullptr) {
1339  interface = __prm->__interfaceMap[ns_name];
1340  full_name = ns_name;
1341  } else if (full_name != ns_name) {
1343  "Interface name '"
1344  << name << "' is ambiguous: specify full name.");
1345  }
1346  }
1347  }
1348  }
1349 
1350  if (interface == nullptr) {
1352  "Interface '" << name << "' not found, check imports.");
1353  }
1354 
1355  return interface;
1356  }
1357 
1358  template < typename GUM_SCALAR >
1360  GUM_CONSTRUCTOR(PRMFactory);
1361  __prm = new PRM< GUM_SCALAR >();
1362  }
1363 
1364  template < typename GUM_SCALAR >
1366  IPRMFactory(), __prm(prm) {
1367  GUM_CONSTRUCTOR(PRMFactory);
1368  }
1369 
1370  template < typename GUM_SCALAR >
1372  GUM_DESTRUCTOR(PRMFactory);
1373  while (!__namespaces.empty()) {
1374  auto ns = __namespaces.back();
1375  __namespaces.pop_back();
1376  delete ns;
1377  }
1378  }
1379 
1380  template < typename GUM_SCALAR >
1382  return __prm;
1383  }
1384 
1385  template < typename GUM_SCALAR >
1387  if (__stack.size() == 0) { GUM_ERROR(NotFound, "no object being built"); }
1388 
1389  return __stack.back()->obj_type();
1390  }
1391 
1392  template < typename GUM_SCALAR >
1394  if (__stack.size() == 0) { GUM_ERROR(NotFound, "no object being built"); }
1395 
1396  return __stack.back();
1397  }
1398 
1399  template < typename GUM_SCALAR >
1401  if (__stack.size() == 0) { GUM_ERROR(NotFound, "no object being built"); }
1402 
1403  return __stack.back();
1404  }
1405 
1406  template < typename GUM_SCALAR >
1408  if (__stack.size() > 0) {
1409  PRMObject* obj = __stack.back();
1410  __stack.pop_back();
1411  return obj;
1412  } else {
1413  return 0;
1414  }
1415  }
1416 
1417  template < typename GUM_SCALAR >
1418  INLINE std::string PRMFactory< GUM_SCALAR >::currentPackage() const {
1419  return (__packages.empty()) ? "" : __packages.back();
1420  }
1421 
1422  template < typename GUM_SCALAR >
1423  INLINE void
1425  std::string super) {
1426  std::string real_name = __addPrefix(name);
1427  if (__prm->__typeMap.exists(real_name)) {
1428  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
1429  }
1430  if (super == "") {
1431  auto t = new PRMType(LabelizedVariable(real_name, "", 0));
1432  __stack.push_back(t);
1433  } else {
1434  auto t = new PRMType(LabelizedVariable(real_name, "", 0));
1435  t->__superType = __retrieveType(super);
1436  t->__label_map = new std::vector< Idx >();
1437  __stack.push_back(t);
1438  }
1439  }
1440 
1441  template < typename GUM_SCALAR >
1442  INLINE void PRMFactory< GUM_SCALAR >::addLabel(const std::string& l,
1443  std::string extends) {
1444  if (extends == "") {
1445  PRMType* t =
1446  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1447  LabelizedVariable* var = dynamic_cast< LabelizedVariable* >(t->__var);
1448 
1449  if (!var) {
1451  "the current type's variable is not a LabelizedVariable.");
1452  } else if (t->__superType) {
1453  GUM_ERROR(OperationNotAllowed, "current type is a subtype.");
1454  }
1455 
1456  try {
1457  var->addLabel(l);
1458  } catch (DuplicateElement&) {
1459  GUM_ERROR(DuplicateElement, "a label '" << l << "' already exists");
1460  }
1461  } else {
1462  PRMType* t =
1463  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1464  LabelizedVariable* var = dynamic_cast< LabelizedVariable* >(t->__var);
1465 
1466  if (!var) {
1468  "the current type's variable is not a LabelizedVariable.");
1469  } else if (!t->__superType) {
1470  GUM_ERROR(OperationNotAllowed, "current type is not a subtype.");
1471  }
1472 
1473  bool found = false;
1474 
1475  for (Idx i = 0; i < t->__superType->__var->domainSize(); ++i) {
1476  if (t->__superType->__var->label(i) == extends) {
1477  try {
1478  var->addLabel(l);
1479  } catch (DuplicateElement&) {
1480  GUM_ERROR(DuplicateElement, "a label '" << l << "' already exists");
1481  }
1482 
1483  t->__label_map->push_back(i);
1484 
1485  found = true;
1486  break;
1487  }
1488  }
1489 
1490  if (!found) { GUM_ERROR(NotFound, "inexistent label in super type."); }
1491  }
1492  }
1493 
1494  template < typename GUM_SCALAR >
1496  PRMType* t =
1497  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1498 
1499  if (!t->__isValid()) {
1500  GUM_ERROR(OperationNotAllowed, "current type is not a valid subtype");
1501  } else if (t->variable().domainSize() < 2) {
1503  "current type is not a valid discrete type");
1504  }
1505 
1506  __prm->__typeMap.insert(t->name(), t);
1507 
1508  __prm->__types.insert(t);
1509  __stack.pop_back();
1510  }
1511 
1512  template < typename GUM_SCALAR >
1513  INLINE void
1515  std::string real_name = __addPrefix(name);
1516  if (__prm->__typeMap.exists(real_name)) {
1517  GUM_ERROR(DuplicateElement, "'" << real_name << "' is already used.");
1518  }
1519  auto var = DiscretizedVariable< double >(real_name, "");
1520  auto t = new PRMType(var);
1521  __stack.push_back(t);
1522  }
1523 
1524  template < typename GUM_SCALAR >
1525  INLINE void PRMFactory< GUM_SCALAR >::addTick(double tick) {
1526  PRMType* t =
1527  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1529  dynamic_cast< DiscretizedVariable< double >* >(t->__var);
1530 
1531  if (!var) {
1533  "the current type's variable is not a LabelizedVariable.");
1534  }
1535 
1536  try {
1537  var->addTick(tick);
1538  } catch (DefaultInLabel&) {
1539  GUM_ERROR(OperationNotAllowed, "tick already in used for this variable");
1540  }
1541  }
1542 
1543  template < typename GUM_SCALAR >
1545  PRMType* t =
1546  static_cast< PRMType* >(__checkStack(1, PRMObject::prm_type::TYPE));
1547 
1548  if (t->variable().domainSize() < 2) {
1550  "current type is not a valid discrete type");
1551  }
1552 
1553  __prm->__typeMap.insert(t->name(), t);
1554 
1555  __prm->__types.insert(t);
1556  __stack.pop_back();
1557  }
1558 
1559  template < typename GUM_SCALAR >
1560  INLINE void PRMFactory< GUM_SCALAR >::addRangeType(const std::string& name,
1561  long minVal,
1562  long maxVal) {
1563  std::string real_name = __addPrefix(name);
1564  if (__prm->__typeMap.exists(real_name)) {
1565  std::stringstream msg;
1566  msg << "\"" << real_name << "' is already used.";
1567  GUM_ERROR(DuplicateElement, msg.str());
1568  }
1569 
1570  auto var = RangeVariable(real_name, "", minVal, maxVal);
1571  auto t = new PRMType(var);
1572 
1573  if (t->variable().domainSize() < 2) {
1575  "current type is not a valid discrete type");
1576  }
1577 
1578  __prm->__typeMap.insert(t->name(), t);
1579  __prm->__types.insert(t);
1580  }
1581 
1582  template < typename GUM_SCALAR >
1585  __stack.pop_back();
1586  }
1587 
1588  template < typename GUM_SCALAR >
1589  INLINE void PRMFactory< GUM_SCALAR >::addAttribute(const std::string& type,
1590  const std::string& name) {
1592  startAttribute(type, name);
1593  endAttribute();
1594  }
1595 
1596  template < typename GUM_SCALAR >
1597  INLINE void PRMFactory< GUM_SCALAR >::startAttribute(const std::string& type,
1598  const std::string& name,
1599  bool scalar_attr) {
1601  PRMAttribute< GUM_SCALAR >* a = nullptr;
1602 
1603  if (PRMObject::isClass(*c) && (!scalar_attr)) {
1605  static_cast< PRMClass< GUM_SCALAR >& >(*c),
1606  name,
1607  *__retrieveType(type));
1608 
1609  } else {
1610  a = new PRMScalarAttribute< GUM_SCALAR >(name, *__retrieveType(type));
1611  }
1612 
1613  std::string dot = ".";
1614 
1615  try {
1616  try {
1617  c->add(a);
1618  } catch (DuplicateElement&) { c->overload(a); }
1619  } catch (Exception&) {
1620  if (a != nullptr && (!c->exists(a->id()))) { delete a; }
1621  }
1622 
1623  __stack.push_back(a);
1624  }
1625 
1626  template < typename GUM_SCALAR >
1627  INLINE void
1630  if (!c->exists(name)) { GUM_ERROR(NotFound, name << "not found"); }
1631  auto& a = c->get(name);
1633  GUM_ERROR(OperationNotAllowed, name << " not an attribute");
1634  }
1635  __stack.push_back(&a);
1636  }
1637 
1638  template < typename GUM_SCALAR >
1641  __stack.pop_back();
1642  }
1643 
1644  template < typename GUM_SCALAR >
1645  INLINE void PRMFactory< GUM_SCALAR >::startSystem(const std::string& name) {
1646  if (__prm->__systemMap.exists(name)) {
1647  GUM_ERROR(DuplicateElement, "'" << name << "' is already used.");
1648  }
1649  PRMSystem< GUM_SCALAR >* model =
1651  __stack.push_back(model);
1652  __prm->__systemMap.insert(model->name(), model);
1653  __prm->__systems.insert(model);
1654  }
1655 
1656  template < typename GUM_SCALAR >
1658  try {
1659  PRMSystem< GUM_SCALAR >* model = static_cast< PRMSystem< GUM_SCALAR >* >(
1661  __stack.pop_back();
1662  model->instantiate();
1663  } catch (Exception&) { GUM_ERROR(FatalError, "could not create system"); }
1664  }
1665 
1666  template < typename GUM_SCALAR >
1667  INLINE void PRMFactory< GUM_SCALAR >::addInstance(const std::string& type,
1668  const std::string& name) {
1669  auto c = __retrieveClass(type);
1670 
1671  // If class contains parameters, calls the proper addIsntance method
1672  if (c->parameters().size() > 0) {
1674  addInstance(type, name, params);
1675 
1676  } else {
1677  __addInstance(c, name);
1678  }
1679  }
1680 
1681  template < typename GUM_SCALAR >
1683  const std::string& type,
1684  const std::string& name,
1685  const HashTable< std::string, double >& params) {
1686  auto c = __retrieveClass(type);
1687 
1688  if (c->parameters().empty()) {
1689  if (params.empty()) {
1690  __addInstance(c, name);
1691  } else {
1693  "Class " + type + " does not have parameters");
1694  }
1695 
1696  } else {
1697  auto my_params = params;
1698  // Adding all parameters to my_params
1699  for (const auto& p : c->parameters()) {
1700  if (!my_params.exists(p->name())) {
1701  my_params.insert(p->name(), p->value());
1702  }
1703  }
1704 
1705  // Building sub class name using my_params
1706  std::stringstream sBuff;
1707  sBuff << c->name() << "<";
1708 
1709  for (const auto& p : my_params) {
1710  sBuff << p.first << "=" << p.second << ",";
1711  }
1712 
1713  // Removing last , and adding closing >
1714  std::string sub_c = sBuff.str().substr(0, sBuff.str().size() - 1) + ">";
1715 
1716  // Adding class in current package
1717  try {
1718  auto pck_cpy = __packages;
1719  __packages.clear();
1720 
1721  startClass(sub_c, c->name());
1722 
1723  // Update inherited parameters
1724  for (auto p : my_params) {
1725  auto type = static_cast< PRMParameter< GUM_SCALAR >& >(c->get(p.first))
1726  .valueType();
1728  addParameter("int", p.first, p.second);
1729 
1730  } else {
1731  addParameter("real", p.first, p.second);
1732  }
1733  }
1734 
1735  endClass();
1736 
1737  __packages = pck_cpy;
1738 
1739  } catch (DuplicateElement&) {
1740  // Sub Class already exists in this system
1741  }
1742  c = __retrieveClass(sub_c);
1743  __addInstance(c, name);
1744  }
1745  }
1746 
1747  template < typename GUM_SCALAR >
1748  INLINE void
1750  const std::string& name) {
1751  PRMInstance< GUM_SCALAR >* i = nullptr;
1752  try {
1753  auto s = static_cast< PRMSystem< GUM_SCALAR >* >(
1755  i = new PRMInstance< GUM_SCALAR >(name, *type);
1756  s->add(i);
1757 
1758  } catch (OperationNotAllowed&) {
1759  if (i) { delete i; }
1760  throw;
1761  }
1762  }
1763 
1764  template < typename GUM_SCALAR >
1765  INLINE std::string
1766  PRMFactory< GUM_SCALAR >::__addPrefix(const std::string& str) const {
1767  if (!__packages.empty()) {
1768  std::string full_name = __packages.back();
1769  full_name.append(".");
1770  full_name.append(str);
1771  return full_name;
1772  } else {
1773  return str;
1774  }
1775  }
1776 
1777  template < typename GUM_SCALAR >
1778  INLINE PRMObject*
1780  PRMObject::prm_type obj_type) {
1781  // Don't forget that Idx are unsigned int
1782  if (__stack.size() - i > __stack.size()) {
1783  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1784  }
1785 
1786  PRMObject* obj = __stack[__stack.size() - i];
1787 
1788  if (obj->obj_type() != obj_type) {
1789  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1790  }
1791 
1792  return obj;
1793  }
1794 
1795  template < typename GUM_SCALAR >
1798  // Don't forget that Idx are unsigned int
1799  if (__stack.size() - i > __stack.size()) {
1800  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1801  }
1802 
1803  PRMObject* obj = __stack[__stack.size() - i];
1804 
1805  if ((obj->obj_type() == PRMObject::prm_type::CLASS)
1807  return static_cast< PRMClassElementContainer< GUM_SCALAR >* >(obj);
1808  } else {
1809  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1810  }
1811  }
1812 
1813  template < typename GUM_SCALAR >
1816  // Don't forget that Idx are unsigned int
1817  if (__stack.size() - i > __stack.size()) {
1818  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1819  }
1820 
1822  dynamic_cast< PRMClassElement< GUM_SCALAR >* >(
1823  __stack[__stack.size() - i]);
1824 
1825  if (obj == 0) {
1826  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1827  }
1828 
1829  if (obj->elt_type() != elt_type) {
1830  GUM_ERROR(FactoryInvalidState, "illegal sequence of calls");
1831  }
1832 
1833  return obj;
1834  }
1835 
1836  template < typename GUM_SCALAR >
1838  int depth = 0;
1839  const PRMType* current = t;
1840 
1841  while (current->isSubType()) {
1842  ++depth;
1843  current = &(current->superType());
1844  }
1845 
1846  return depth;
1847  }
1848 
1849  template < typename GUM_SCALAR >
1850  INLINE void PRMFactory< GUM_SCALAR >::pushPackage(const std::string& name) {
1851  __packages.push_back(name);
1852  __namespaces.push_back(new List< std::string >());
1853  }
1854 
1855  template < typename GUM_SCALAR >
1857  std::string plop = currentPackage();
1858 
1859  if (!__packages.empty()) {
1860  std::string s = __packages.back();
1861  __packages.pop_back();
1862 
1863  if (__namespaces.size() > 0) {
1864  delete __namespaces.back();
1865  __namespaces.pop_back();
1866  }
1867  return s;
1868  }
1869 
1870  return plop;
1871  }
1872 
1873  template < typename GUM_SCALAR >
1874  INLINE void PRMFactory< GUM_SCALAR >::addImport(const std::string& name) {
1875  if (name.size() == 0) {
1876  GUM_ERROR(OperationNotAllowed, "illegal import name");
1877  }
1878  if (__namespaces.empty()) {
1879  __namespaces.push_back(new List< std::string >());
1880  }
1881  __namespaces.back()->push_back(name);
1882  }
1883 
1884  template < typename GUM_SCALAR >
1885  INLINE void
1887  const std::string& r_i) {
1888  size_t pos = l_i.find_last_of('.');
1889 
1890  if (pos != std::string::npos) {
1891  std::string l_ref = l_i.substr(pos + 1, std::string::npos);
1892  setReferenceSlot(l_i.substr(0, pos), l_ref, r_i);
1893  } else {
1894  GUM_ERROR(NotFound, "left value does not name an instance or an array");
1895  }
1896  }
1897 
1898  template < typename GUM_SCALAR >
1899  INLINE PRMClass< GUM_SCALAR >&
1900  PRMFactory< GUM_SCALAR >::retrieveClass(const std::string& name) {
1901  return *__retrieveClass(name);
1902  }
1903 
1904  template < typename GUM_SCALAR >
1905  INLINE PRMType&
1906  PRMFactory< GUM_SCALAR >::retrieveType(const std::string& name) {
1907  return *__retrieveType(name);
1908  }
1909 
1910  template < typename GUM_SCALAR >
1912  const std::vector< PRMClassElement< GUM_SCALAR >* >& elts) {
1913  return *(__retrieveCommonType(elts));
1914  }
1915 
1916 
1917  template < typename GUM_SCALAR >
1919  const std::string& type) const {
1920  try {
1921  __retrieveClass(type);
1922  return true;
1923 
1924  } catch (NotFound&) {
1925  } catch (DuplicateElement&) {}
1926 
1927  try {
1928  __retrieveInterface(type);
1929  return true;
1930 
1931  } catch (NotFound&) {
1932  } catch (DuplicateElement&) {}
1933 
1934  return false;
1935  }
1936 
1937  template < typename GUM_SCALAR >
1939  const std::string& name) const {
1940  const PRMSystem< GUM_SCALAR >* system =
1941  static_cast< const PRMSystem< GUM_SCALAR >* >(getCurrent());
1942  return (system && system->isArray(name));
1943  }
1944 
1945  template < typename GUM_SCALAR >
1947  const std::vector< std::string >& array) {
1949 
1950  auto a = static_cast< PRMFormAttribute< GUM_SCALAR >* >(
1952 
1953  if (a->formulas().domainSize() != array.size()) {
1954  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
1955  }
1956 
1957  if (a->formulas().nbrDim() == 1) {
1958  setRawCPFByLines(array);
1959 
1960  } else {
1961  Instantiation inst(a->formulas());
1962  Instantiation jnst;
1963  for (auto idx = inst.variablesSequence().rbegin();
1964  idx != inst.variablesSequence().rend();
1965  --idx) {
1966  jnst.add(**idx);
1967  }
1968 
1969  jnst.setFirst();
1970  auto idx = (std::size_t)0;
1971  while ((!jnst.end()) && idx < array.size()) {
1972  inst.setVals(jnst);
1973  a->formulas().set(inst, array[idx]);
1974  jnst.inc();
1975  ++idx;
1976  }
1977 
1978  // Generate cpf by calling it
1979  a->cpf();
1980  }
1981  }
1982 
1983  template < typename GUM_SCALAR >
1985  const std::vector< std::string >& array) {
1987 
1988  auto a = static_cast< PRMFormAttribute< GUM_SCALAR >* >(
1990 
1991  if (a->formulas().domainSize() != array.size()) {
1992  GUM_ERROR(OperationNotAllowed, "illegal CPF size");
1993  }
1994 
1995  a->formulas().populate(array);
1996 
1998  a->cpf();
1999  }
2000 
2001  } /* namespace prm */
2002 } /* namespace gum */
PRM< GUM_SCALAR > * __prm
The pointer on the PRM<GUM_SCALAR> built by this factory.
Definition: PRMFactory.h:1049
virtual NodeId add(PRMClassElement< GUM_SCALAR > *elt)
See gum::prm::add(PRMClassElement<GUM_SCALAR>*).
Definition: PRMClass_tpl.h:621
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:52
std::vector< PRMObject *> __stack
A stack used to keep track of created PRMObject.
Definition: PRMFactory.h:1052
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:707
static AggregateType str2enum(const std::string &str)
Static method which returns the AggregateType given its string representation.
Definition: PRMAggregate.h:100
static INLINE bool isClass(const PRMObject &obj)
Returns true if obj_ptr is of type Class.
Definition: PRMObject.h:102
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition: PRMType_inl.h:45
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:35
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:38
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:63
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:1022
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:223
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:59
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:69
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:50
const std::string & labelValue() const
See gum::PRMClassElement::elt_type().
std::string to_string(const Formula &f)
Definition: formula_inl.h:499
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:483
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:229
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:402
Base class for all aGrUM&#39;s exceptions.
Definition: exceptions.h:106
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:733
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:1043
PRMFactory()
Default constructor.
This is a decoration of the DiscreteVariable class.
Definition: PRMType.h:63
An PRMInterface is implemented by a Class<GUM_SCALAR> and defines a set of PRMReferenceSlot<GUM_SCALA...
Definition: PRMClass.h:54
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:54
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
Definition: PRMObject.h:221
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:56
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:83
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:66
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:66
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:29
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Size Idx
Type for indexes.
Definition: types.h:53
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:1046
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:61
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
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:613
const Key & back() const
Returns the last element of the sequence.
Definition: sequence_tpl.h:568
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:55
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:57
ClassElementType
Returns true if obj_ptr is of type PRMReferenceSlot.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:408