aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
structuredInference_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Inline implementation of StructuredInference.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #include <agrum/PRM/inference/structuredInference.h>
30 
31 namespace gum {
32  namespace prm {
33 
34  template < typename GUM_SCALAR >
35  StructuredInference< GUM_SCALAR >::StructuredInference(
36  const PRM< GUM_SCALAR >& prm,
37  const PRMSystem< GUM_SCALAR >& system,
38  gspan::SearchStrategy< GUM_SCALAR >* strategy) :
39  PRMInference< GUM_SCALAR >(prm, system),
40  gspan__(0), pdata__(0), mining__(false), dot__(".") {
41  GUM_CONSTRUCTOR(StructuredInference);
42  gspan__ = new GSpan< GUM_SCALAR >(prm, system, strategy);
43  triang_time = 0.0;
44  mining_time = 0.0;
45  pattern_time = 0.0;
46  inner_time = 0.0;
47  obs_time = 0.0;
48  full_time = 0.0;
49  }
50 
51  template < typename GUM_SCALAR >
56  dot__(".") {
58  gspan__ = new GSpan< GUM_SCALAR >(*(this->prm_), *(this->sys_));
59  }
60 
61  template < typename GUM_SCALAR >
64  delete this->gspan__;
65 
66  for (const auto& elt: elim_map__)
67  delete elt.second;
68 
69  for (const auto& elt: cdata_map__)
70  delete elt.second;
71 
72  for (const auto elt: trash__)
73  delete (elt);
74 
75  for (const auto& elt: outputs__)
76  delete elt.second;
77 
78  if (pdata__) delete pdata__;
79  }
80 
81  template < typename GUM_SCALAR >
85  this->prm_ = source.prm_;
86  this->sys_ = source.sys_;
87 
88  if (this->gspan__) delete this->gspan__;
89 
90  this->gspan__ = new GSpan< GUM_SCALAR >(*(this->prm_), *(this->sys_));
91  return *this;
92  }
93 
94  template < typename GUM_SCALAR >
96  const typename PRMInference< GUM_SCALAR >::Chain& chain) {}
97 
98  template < typename GUM_SCALAR >
100  const typename PRMInference< GUM_SCALAR >::Chain& chain) {}
101 
102  template < typename GUM_SCALAR >
104  const typename PRMInference< GUM_SCALAR >::Chain& chain,
105  Potential< GUM_SCALAR >& m) {
106  timer.reset();
107  found_query__ = false;
108  query__ = chain;
110 
111  if (!this->hasEvidence() && (chain.second->cpf().nbrDim() == 1)) {
112  Instantiation i(m);
113 
114  for (i.setFirst(); !i.end(); i.inc())
115  m.set(i, chain.second->cpf().get(i));
116 
117  return;
118  } else if (this->hasEvidence(chain)) {
119  Instantiation i(m);
120  const Potential< GUM_SCALAR >* e
121  = this->evidence(query__.first)[query__.second->id()];
122 
123  for (i.setFirst(); !i.end(); i.inc())
124  m.set(i, e->get(i));
125 
126  return;
127  }
128 
130  Set< const Potential< GUM_SCALAR >* > pots;
131 
132  if (data.pool.size() > 1) {
133  for (const auto pot: data.pool)
135 
136  if (pots.size() == 1) {
138  = const_cast< Potential< GUM_SCALAR >* >(*(pots.begin()));
141  Instantiation i(*pot), j(m);
142 
143  for (i.setFirst(), j.setFirst(); !i.end(); i.inc(), j.inc())
144  m.set(j, pot->get(i));
145  } else {
148  Instantiation i(m), j(*tmp);
149 
150  for (i.setFirst(), j.setFirst(); !i.end(); i.inc(), j.inc())
151  m.set(i, tmp->get(j));
152 
153  delete tmp;
154  }
155  } else {
156  Potential< GUM_SCALAR >* pot = *(data.pool.begin());
159  Instantiation i(*pot), j(m);
160 
161  for (i.setFirst(), j.setFirst(); !i.end(); i.inc(), j.inc())
162  m.set(j, pot->get(i));
163  }
164 
165  m.normalize();
166 
167  if (pdata__) {
168  delete pdata__;
169  pdata__ = 0;
170  }
171 
172  full_time = timer.step();
173  }
174 
175  template < typename GUM_SCALAR >
177  const std::vector< typename PRMInference< GUM_SCALAR >::Chain >& queries,
178  Potential< GUM_SCALAR >& j) {
179  GUM_ERROR(FatalError, "not implemented");
180  }
181 
182  template < typename GUM_SCALAR >
184  std::stringstream s;
185  s << "Triangulation time: " << triang_time << std::endl;
186  s << "Pattern mining time: " << mining_time << std::endl;
187  s << "Pattern elimination time: " << pattern_time << std::endl;
188  s << "Inner node elimination time: " << inner_time << std::endl;
189  s << "Observed node elimination time: " << obs_time << std::endl;
190  s << "Full inference time: " << full_time << std::endl;
191  s << "#patterns: " << gspan__->patterns().size() << std::endl;
192  Size count = 0;
193  typedef std::vector< gspan::Pattern* >::const_iterator Iter;
194 
195  for (Iter p = gspan__->patterns().begin(); p != gspan__->patterns().end();
196  ++p) {
197  if (gspan__->matches(**p).size()) {
198  s << "Pattern n°" << count++
199  << " match count: " << gspan__->matches(**p).size() << std::endl;
200  s << "Pattern n°" << count++ << " instance count: " << (**p).size()
201  << std::endl;
202  }
203  }
204 
205  return s.str();
206  }
207 
208  template < typename GUM_SCALAR >
210  typename StructuredInference< GUM_SCALAR >::RGData& data) {
211  // Launch the pattern mining
212  plopTimer.reset();
213 
215 
217  // Reducing each used pattern
218  plopTimer.reset();
219  typedef std::vector< gspan::Pattern* >::const_iterator Iter;
220 
221  for (Iter p = gspan__->patterns().begin(); p != gspan__->patterns().end();
222  ++p)
223  if (gspan__->matches(**p).size()) reducePattern__(*p);
224 
226  // reducing instance not already reduced in a pattern
228  // Adding edges using the pools
230  // Placing the query where it belongs
232  data.outputs().erase(id);
233  data.queries().insert(id);
234  // Triangulating, then eliminating
236  &(data.mods),
237  &(data.partial_order));
238  const std::vector< NodeId >& elim_order = t.eliminationOrder();
239 
240  for (size_t i = 0; i < data.outputs().size(); ++i)
242  }
243 
244  template < typename GUM_SCALAR >
246  const gspan::Pattern* p) {
247  Set< Potential< GUM_SCALAR >* > pool;
248  typename StructuredInference< GUM_SCALAR >::PData data(*p,
249  gspan__->matches(*p));
253  &(data.mod),
254  data.partial_order());
255  const std::vector< NodeId >& elim_order = t.eliminationOrder();
256 
257  for (size_t i = 0; i < data.inners().size(); ++i)
258  if (!data.barren.exists(elim_order[i]))
260 
263  = data.matches.begin();
264 
265  for (const auto elt: **iter)
267 
268  if (data.obs().size())
270  *iter,
272  else
274 
275  ++iter;
276 
277  if (data.obs().size()) {
278  for (; iter != data.matches.end(); ++iter) {
279  try {
281  *iter,
283  } catch (OperationNotAllowed&) { fake_patterns.insert(*iter); }
284  }
285  } else {
286  for (; iter != data.matches.end(); ++iter) {
287  try {
289  } catch (OperationNotAllowed&) { fake_patterns.insert(*iter); }
290  }
291  }
292 
293  for (const auto pat: fake_patterns) {
294  for (const auto elt: *pat)
296 
298  }
299 
300  obs_time += plopTimer.step();
301 
302  if (data.queries().size())
303  for (const auto m: data.matches)
304  if (!(m->exists(
305  const_cast< PRMInstance< GUM_SCALAR >* >(query__.first))))
308  .type()
309  .variable()),
310  *(elim_map__[m]),
311  trash__);
312  }
313 
314  template < typename GUM_SCALAR >
317  const Sequence< PRMInstance< GUM_SCALAR >* >& match,
320  NodeId id,
321  std::pair< Idx, std::string >& v) {
322  if ((*inst).hasRefAttr((*inst).get(v.second).id())) {
324  = inst->getRefAttr(inst->get(v.second).id());
325 
326  for (auto r = refs.begin(); r != refs.end(); ++r) {
327  if (!match.exists(r->first)) {
328  data.outputs().insert(id);
329  break;
330  }
331  }
332  }
333 
334  if (!(data.outputs().size() && (data.outputs().exists(id)))) {
335  for (const auto m: data.matches) {
336  if (this->hasEvidence(
337  std::make_pair((*m)[v.first], &((*m)[v.first]->get(v.second))))) {
338  GUM_ASSERT(inst->type().name() == (*m)[v.first]->type().name());
340  == (*m)[v.first]->get(v.second).safeName());
341  data.obs().insert(id);
342  break;
343  }
344  }
345 
346  if (!(data.obs().size() && (data.obs().exists(id))))
347  data.inners().insert(id);
348  }
349  }
350 
351  template < typename GUM_SCALAR >
354  Set< Potential< GUM_SCALAR >* >& pool,
355  const Sequence< PRMInstance< GUM_SCALAR >* >& match) {
356  std::pair< Idx, std::string > v;
357  Potential< GUM_SCALAR >* pot = 0;
358 
359  for (const auto inst: match) {
360  for (const auto& elt: *inst) {
361  NodeId id = data.graph.addNode();
363  data.map.insert(id, v);
366  data.vars.insert(id, &(elt.second->type().variable()));
367  pool.insert(
368  const_cast< Potential< GUM_SCALAR >* >(&(elt.second->cpf())));
369  pot = &(
370  const_cast< Potential< GUM_SCALAR >& >(inst->get(v.second).cpf()));
371 
372  for (const auto var: pot->variablesSequence()) {
373  try {
374  if (id != data.vars.first(var))
376  } catch (DuplicateElement&) {
377  } catch (NotFound&) {}
378  }
379 
381 
382  if (data.inners().exists(id)
383  && (inst->type().containerDag().children(elt.second->id()).size()
384  == 0)
386  data.barren.insert(id);
387  }
388  }
389 
390  if (!found_query__) {
391  for (const auto mat: data.matches) {
392  if (mat->exists(
393  const_cast< PRMInstance< GUM_SCALAR >* >(query__.first))) {
394  Idx pos
395  = mat->pos(const_cast< PRMInstance< GUM_SCALAR >* >(query__.first));
397  ->get(query__.second->safeName())
398  .type()
399  .variable();
400  NodeId id = data.vars.first(&var);
401  data.barren.erase(id);
402  data.inners().erase(id);
403  data.obs().erase(id);
404  data.outputs().erase(id);
405  data.queries().insert(id);
406  found_query__ = true;
408  break;
409  }
410  }
411  }
412  }
413 
414  template < typename GUM_SCALAR >
417  std::pair< Idx, std::string > attr) {
418  for (const auto mat: data.matches)
419  if (mat->atPos(attr.first)
421  return false;
422 
423  return true;
424  }
425 
426  template < typename GUM_SCALAR >
429  Set< Potential< GUM_SCALAR >* >& pool) {
431 
432  for (const auto node: data.barren) {
433  for (const auto pot: pool)
434  if (pot->contains(*data.vars.second(node))) {
435  pool.erase(pot);
436  break;
437  }
438 
439  for (const auto nei: data.graph.neighbours(node))
440  if (data.inners().exists(nei)) {
441  try {
443  } catch (DuplicateElement&) {}
444  }
445  }
446 
447  NodeId node;
448  Potential< GUM_SCALAR >* my_pot = nullptr;
449  short count = 0;
450 
451  while (candidates.size()) {
452  node = candidates.back();
454  count = 0;
455 
456  for (const auto pot: pool) {
457  if (pot->contains(*data.vars.second(node))) {
458  ++count;
459  my_pot = pot;
460  }
461  }
462 
463  if (count == 1) {
464  pool.erase(my_pot);
466 
467  for (const auto nei: data.graph.neighbours(node)) {
468  if (data.inners().exists(nei)) {
469  try {
471  } catch (DuplicateElement&) {}
472  }
473  }
474  }
475  }
476  }
477 
478  template < typename GUM_SCALAR >
479  Set< Potential< GUM_SCALAR >* >*
482  const Set< Potential< GUM_SCALAR >* >& pool,
483  const Sequence< PRMInstance< GUM_SCALAR >* >& match,
484  const std::vector< NodeId >& elim_order) {
486  = new Set< Potential< GUM_SCALAR >* >(pool);
487  std::pair< Idx, std::string > target;
488  size_t end = data.inners().size() + data.obs().size();
489 
490  for (size_t idx = data.inners().size(); idx < end; ++idx) {
493  *my_pool,
494  trash__);
495  }
496 
497  return my_pool;
498  }
499 
500  template < typename GUM_SCALAR >
501  Set< Potential< GUM_SCALAR >* >*
504  const Set< Potential< GUM_SCALAR >* >& pool,
505  const Sequence< PRMInstance< GUM_SCALAR >* >& match,
506  const std::vector< NodeId >& elim_order) {
509  std::pair< Idx, std::string > target;
510  size_t end = data.inners().size() + data.obs().size();
511 
512  for (size_t idx = data.inners().size(); idx < end; ++idx) {
515  *my_pool,
516  trash__);
517  }
518 
519  return my_pool;
520  }
521 
522  template < typename GUM_SCALAR >
523  Set< Potential< GUM_SCALAR >* >*
526  const Set< Potential< GUM_SCALAR >* >& pool,
527  const Sequence< PRMInstance< GUM_SCALAR >* >& match) {
528 #ifdef DEBUG
529 
531  = data.matches.begin();
532  iter != data.matches.end();
533  ++iter) {
534  GUM_ASSERT((**iter).size() == match.size());
535 
536  for (Size idx = 0; idx < match.size(); ++idx) {
537  GUM_ASSERT((**iter).atPos(idx)->type() == match.atPos(idx)->type());
538  }
539  }
540 
541 #endif
543  = new Set< Potential< GUM_SCALAR >* >();
544  std::pair< Idx, std::string > target;
546  const Sequence< PRMInstance< GUM_SCALAR >* >& source
547  = **(data.matches.begin());
548 
549  for (Size idx = 0; idx < match.size(); ++idx) {
551  const auto& chains = source[idx]->type().slotChains();
552 
553  for (const auto sc: chains) {
554 #ifdef DEBUG
555  GUM_ASSERT(!(sc->isMultiple()));
556 #endif
557 
558  try {
559  bij.insert(&(source[idx]
560  ->getInstance(sc->id())
561  .get(sc->lastElt().safeName())
562  .type()
563  .variable()),
564  &(match[idx]
565  ->getInstance(sc->id())
566  .get(sc->lastElt().safeName())
567  .type()
568  .variable()));
569  } catch (DuplicateElement&) {
570  try {
571  if (bij.first(&(match[idx]
572  ->getInstance(sc->id())
573  .get(sc->lastElt().safeName())
574  .type()
575  .variable()))
576  != &(source[idx]
577  ->getInstance(sc->id())
578  .get(sc->lastElt().safeName())
579  .type()
580  .variable())) {
581  delete my_pool;
582  GUM_ERROR(OperationNotAllowed, "fake pattern");
583  }
584  } catch (NotFound&) {
585  delete my_pool;
586  GUM_ERROR(OperationNotAllowed, "fake pattern");
587  }
588  }
589  }
590  }
591 
592  for (const auto p: pool) {
593  for (const auto v: p->variablesSequence()) {
594  try {
595  target = data.map[data.vars.first(v)];
596  bij.insert(
597  v,
599  } catch (NotFound&) {
601  } catch (DuplicateElement&) {}
602  }
603 
604  try {
606  } catch (Exception&) {
607  for (const auto pot: *my_pool)
608  delete pot;
609 
610  delete my_pool;
611  GUM_ERROR(OperationNotAllowed, "fake pattern");
612  }
613  }
614 
615  return my_pool;
616  }
617 
618  template < typename GUM_SCALAR >
622  Potential< GUM_SCALAR >* pot = nullptr;
623  PRMInstance< GUM_SCALAR >* inst = nullptr;
624 
625  for (const auto& elt: *this->sys_) {
626  inst = elt.second;
627 
629  // Checking if its not an empty class
630  if (inst->size()) {
631  Set< Potential< GUM_SCALAR >* > pool;
632 
633  try {
634  data = cdata_map__[&(inst->type())];
635  } catch (NotFound&) {
637  cdata_map__.insert(&(inst->type()), data);
638  }
639 
641  // Filling up the partial ordering
643 
645 
646  if (data->aggregators().size())
647  for (const auto agg: data->aggregators())
649 
651 
652  if (query__.first == inst) {
653  // First case, the instance contains the query
655 
656  if (partial_order[0].empty()) partial_order.erase(0);
657 
658  if (partial_order.size() > 1) {
660 
661  if (partial_order[1].empty()) partial_order.erase(1);
662  }
663 
667 
668  // Adding the potentials
669  for (auto attr = inst->begin(); attr != inst->end(); ++attr)
670  pool.insert(&(
671  const_cast< Potential< GUM_SCALAR >& >((*(attr.val())).cpf())));
672 
673  // Adding evidences if any
674  if (this->hasEvidence(inst))
675  for (const auto& elt: this->evidence(inst))
676  pool.insert(const_cast< Potential< GUM_SCALAR >* >(elt.second));
677 
679  &(data->mods),
680  &(partial_order));
681  const std::vector< NodeId >& v = t.eliminationOrder();
682 
683  if (partial_order.size() > 1)
684  for (size_t idx = 0; idx < partial_order[0].size(); ++idx)
685  eliminateNode(&(inst->get(v[idx]).type().variable()),
686  pool,
687  trash__);
688  } else if (this->hasEvidence(inst)) {
689  // Second case, the instance has evidences
690  // Adding the potentials
691  for (const auto elt: *inst)
692  pool.insert(
693  &const_cast< Potential< GUM_SCALAR >& >(elt.second->cpf()));
694 
695  // Adding evidences
696  for (const auto& elt: this->evidence(inst))
697  pool.insert(const_cast< Potential< GUM_SCALAR >* >(elt.second));
698 
700  &(data->mods),
701  &(partial_order));
702 
703  for (size_t idx = 0; idx < partial_order[0].size(); ++idx)
705  &(inst->get(t.eliminationOrder()[idx]).type().variable()),
706  pool,
707  trash__);
708  } else {
709  // Last cast, the instance neither contains evidences nor
710  // instances
711  // We translate the class level potentials into the instance ones
712  // and
713  // proceed with elimination
714  for (const auto srcPot: data->pool) {
716  pool.insert(pot);
717  trash__.insert(pot);
718  }
719 
720  for (const auto agg: data->c.aggregates())
721  pool.insert(&(const_cast< Potential< GUM_SCALAR >& >(
722  inst->get(agg->id()).cpf())));
723 
724  // We eliminate inner aggregators with their parents if necessary
725  // (see
726  // CData constructor)
727  Size size = data->inners().size() + data->aggregators().size();
728 
729  for (size_t idx = data->inners().size(); idx < size; ++idx)
731  &(inst->get(data->elim_order()[idx]).type().variable()),
732  pool,
733  trash__);
734  }
735 
736  for (const auto pot: pool)
738  }
739  }
740  }
741  }
742 
743  template < typename GUM_SCALAR >
745  typename StructuredInference< GUM_SCALAR >::RGData& data) {
746  // We first add edges between variables already in pool (i.e. those of the
747  // reduced instances)
748  NodeId id_1, id_2;
749 
750  for (const auto pot: data.pool) {
751  const Sequence< const DiscreteVariable* >& vars = pot->variablesSequence();
752 
753  for (Size var_1 = 0; var_1 < vars.size(); ++var_1) {
756  } else {
760  data.outputs().insert(id_1);
761  }
762 
763  for (Size var_2 = var_1 + 1; var_2 < vars.size(); ++var_2) {
766  } else {
770  data.outputs().insert(id_2);
771  }
772 
773  try {
775  } catch (DuplicateElement&) {}
776  }
777  }
778  }
779 
780  // Adding potentials obtained from reduced patterns
781  for (const auto& elt: elim_map__) {
782  // We add edges between variables in the same reduced patterns
783  for (const auto pot: *elt.second) {
784  data.pool.insert(pot);
785  const Sequence< const DiscreteVariable* >& vars
786  = pot->variablesSequence();
787 
788  for (Size var_1 = 0; var_1 < vars.size(); ++var_1) {
791  } else {
795  data.outputs().insert(id_1);
796  }
797 
798  for (Size var_2 = var_1 + 1; var_2 < vars.size(); ++var_2) {
801  } else {
805  data.outputs().insert(id_2);
806  }
807 
808  try {
810  } catch (DuplicateElement&) {}
811  }
812  }
813  }
814  }
815  }
816 
817  template < typename GUM_SCALAR >
822  }
823 
824  template < typename GUM_SCALAR >
826  const gspan::Pattern& p,
827  typename GSpan< GUM_SCALAR >::MatchedInstances& m) :
828  pattern(p),
829  matches(m), real_order__(0) {
831 
832  for (int i = 0; i < 4; ++i)
834  }
835 
836  template < typename GUM_SCALAR >
838  const typename StructuredInference< GUM_SCALAR >::PData& source) :
844  }
845 
846  template < typename GUM_SCALAR >
847  const List< NodeSet >*
849  if (!real_order__) {
850  real_order__ = new List< NodeSet >();
851 
852  for (const auto set: partial_order__)
853  if (set.size() > 0) real_order__->insert(set);
854  }
855 
856  return real_order__;
857  }
858 
859  template < typename GUM_SCALAR >
861  const PRMClass< GUM_SCALAR >& a_class) :
862  c(a_class),
863  elim_order__(0) {
865 
866  // First step we add Attributes and Aggregators
867  for (const auto node: c.containerDag().nodes()) {
868  switch (c.get(node).elt_type()) {
870  pool.insert(
871  &(const_cast< Potential< GUM_SCALAR >& >(c.get(node).cpf())));
872  // break omited : We want to execute the next block
873  // for attributes
874  }
875 
879  break;
880  }
881 
882  default: { /* do nothing */
883  }
884  }
885  }
886 
887  // Second, we add edges, moralise the graph and build the partial ordering
888  for (const auto node: moral_graph.nodes()) {
889  const auto& parents = c.containerDag().parents(node);
890 
891  // Adding edges and marrying parents
892  for (auto tail = parents.begin(); tail != parents.end(); ++tail) {
897  ++marry;
898 
899  while (marry != parents.end()) {
903 
904  ++marry;
905  }
906  }
907  }
908 
909  // Adding nodes to the partial ordering
910  switch (c.get(node).elt_type()) {
912  if (c.isOutputNode(c.get(node)))
913  outputs().insert(node);
914  else
916 
917  // If the aggregators is not an output and have parents which are
918  // not outputs, we must eliminate the parents after adding the
919  // aggregator's CPT
920  for (const auto par: c.containerDag().parents(node)) {
921  const auto& prnt = c.get(par);
922 
923  if ((!c.isOutputNode(prnt))
926  inners().erase(prnt.id());
927  aggregators().insert(prnt.id());
928  }
929  }
930 
931  break;
932  }
933 
935  pool.insert(
936  const_cast< Potential< GUM_SCALAR >* >(&(c.get(node).cpf())));
937 
938  if (c.isOutputNode(c.get(node)))
939  outputs().insert(node);
940  else if (!aggregators().exists(node))
941  inners().insert(node);
942 
943  break;
944  }
945 
946  default: { /* Do nothing */
947  }
948  }
949  }
950 
951  if (inners().size()) partial_order.insert(inners());
952 
954 
956 
960 
961  for (size_t i = 0; i < inners().size(); ++i)
963  }
964 
965  template < typename GUM_SCALAR >
968 
969  for (const auto pot: trash__)
970  delete pot;
971  }
972 
973  template < typename GUM_SCALAR >
975  const PRMInstance< GUM_SCALAR >* i = (this->sys_->begin()).val();
976  query__ = std::make_pair(i, i->begin().val());
977  found_query__ = false;
980  }
981 
982  template < typename GUM_SCALAR >
984  mining__ = b;
985  }
986 
987  template < typename GUM_SCALAR >
989  const PRMInstance< GUM_SCALAR >* i,
990  const PRMAttribute< GUM_SCALAR >* a) const {
991  return i->name() + dot__ + a->safeName();
992  }
993 
994  template < typename GUM_SCALAR >
996  const PRMInstance< GUM_SCALAR >* i,
997  const PRMAttribute< GUM_SCALAR >& a) const {
998  return i->name() + dot__ + a.safeName();
999  }
1000 
1001  template < typename GUM_SCALAR >
1003  const PRMInstance< GUM_SCALAR >* i,
1004  const PRMSlotChain< GUM_SCALAR >& a) const {
1005  return i->name() + dot__ + a.lastElt().safeName();
1006  }
1007 
1008  template < typename GUM_SCALAR >
1011  }
1012 
1013  template < typename GUM_SCALAR >
1016  }
1017 
1018  template < typename GUM_SCALAR >
1020  return "StructuredInference";
1021  }
1022 
1023  template < typename GUM_SCALAR >
1025  return *gspan__;
1026  }
1027 
1028  template < typename GUM_SCALAR >
1029  INLINE const GSpan< GUM_SCALAR >&
1031  return *gspan__;
1032  }
1033 
1034  template < typename GUM_SCALAR >
1036  typename StructuredInference< GUM_SCALAR >::PData& data,
1037  NodeId id,
1038  Set< Potential< GUM_SCALAR >* >& pool) {
1041  data.mod.erase(id);
1045  data.map.erase(id);
1049  data.inners().erase(id);
1051  pool.erase(data.pots[id]);
1053  data.pots.erase(id);
1055  }
1056 
1057  } /* namespace prm */
1058 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)