aGrUM  0.16.0
BayesNetInference_tpl.h
Go to the documentation of this file.
1 
30 
31 namespace gum {
32 
33 
34  // Default Constructor
35  template < typename GUM_SCALAR >
37  const IBayesNet< GUM_SCALAR >* bn) :
38  __bn(bn) {
40 
41  GUM_CONSTRUCTOR(BayesNetInference);
42  }
43 
44 
45  // Default Constructor
46  template < typename GUM_SCALAR >
48  GUM_CONSTRUCTOR(BayesNetInference);
49  }
50 
51 
52  // Destructor
53  template < typename GUM_SCALAR >
55  // clear all evidence.
56  // Warning: Do not use method eraseAllEvidence () because it contains a call
57  // to pure virtual method _onAllEvidenceErased which belongs to an inherited
58  // instance and, therefore, does not exist anymore when ~BayesNetInference ()
59  // is called
60  for (const auto& pair : __evidence) {
61  if (pair.second != nullptr) { delete (pair.second); }
62  }
63 
64  GUM_DESTRUCTOR(BayesNetInference);
65  }
66 
67 
68  // returns whether the inference object is in a ready state
69  template < typename GUM_SCALAR >
72  }
73  // returns whether the inference object is in a OutdatedBNStructure state
74  template < typename GUM_SCALAR >
75  INLINE bool
77  noexcept {
79  }
80  // returns whether the inference object is in a OutdatedBNPotential state
81  template < typename GUM_SCALAR >
82  INLINE bool
84  noexcept {
86  }
87  // returns whether the inference object is in a InferenceDone state
88  template < typename GUM_SCALAR >
89  INLINE bool BayesNetInference< GUM_SCALAR >::isInferenceDone() const noexcept {
90  return (__state == StateOfInference::Done);
91  }
92 
93 
94  // returns whether the inference object is in a done state
95  template < typename GUM_SCALAR >
96  INLINE bool BayesNetInference< GUM_SCALAR >::isDone() const noexcept {
97  return (__state == StateOfInference::Done);
98  }
99 
100 
101  // returns the state of the inference engine
102  template < typename GUM_SCALAR >
105  return __state;
106  }
107 
108  // set the state of the inference
109  template < typename GUM_SCALAR >
110  INLINE void
112  if (__state != state) {
113  __state = state;
114  _onStateChanged();
115  }
116  }
117 
118  // Returns a constant reference over the IBayesNet referenced by this class
119  template < typename GUM_SCALAR >
120  INLINE const IBayesNet< GUM_SCALAR >&
122  if (__bn == nullptr)
124  "No Bayes net has been assigned to "
125  "the inference algorithm.");
126  return *__bn;
127  }
128 
129 
130  // assigns a new BN to the inference engine
131  template < typename GUM_SCALAR >
133  clear();
134  __bn = bn;
136  _onBayesNetChanged(bn);
138  }
139 
140 
141  // assigns a BN to a newly constructed inference engine
142  template < typename GUM_SCALAR >
144  const IBayesNet< GUM_SCALAR >* bn) {
145  __bn = bn;
148  }
149 
150 
151  // clears all the data structures allocated for the last inference
152  template < typename GUM_SCALAR >
156  }
157 
158 
160  template < typename GUM_SCALAR >
162  __domain_sizes.clear();
163  if (__bn != nullptr) {
164  for (const auto node : __bn->dag()) {
165  __domain_sizes.insert(node, __bn->variable(node).domainSize());
166  }
167  }
168  }
169 
170 
171  // get the domain sizes of the random variables of the BN
172  template < typename GUM_SCALAR >
173  INLINE const NodeProperty< Size >&
175  return __domain_sizes;
176  }
177 
178 
179  // ##############################################################################
180  // Evidence
181  // ##############################################################################
182 
183  // create the internal structure for a hard evidence
184  template < typename GUM_SCALAR >
187  const Idx val) const {
188  // check that it is possible to create the evidence
189  if (__bn == nullptr)
191  "No Bayes net has been assigned to the "
192  "inference algorithm");
193 
194  if (!__bn->dag().exists(id)) {
195  GUM_ERROR(UndefinedElement, id << " is not a NodeId in the bn");
196  }
197 
198  if (__bn->variable(id).domainSize() <= val) {
200  "node " << __bn->variable(id) << " has fewer possible values than "
201  << val);
202  }
203 
204  // create the deterministic potential
206  pot.beginMultipleChanges();
207  pot << __bn->variable(id);
208  pot.endMultipleChanges(0.0);
209 
210  Instantiation I(pot);
211  I.chgVal(__bn->variable(id), val);
212  pot.set(I, 1.0);
213 
214  return pot;
215  }
216 
217 
218  // checks wether a potential corresponds to a hard evidence
219  template < typename GUM_SCALAR >
221  const Potential< GUM_SCALAR >& pot, Idx& val) const {
222  // checking if pot is determininstic
223  bool notZero = false;
224  Instantiation I(pot);
225 
226  for (I.setFirst(); !I.end(); I.inc()) {
227  if (pot[I] != 0.0) {
228  if (notZero) { // we already met a non-zero value
229  return false;
230  } else {
231  val = I.val(0);
232  notZero = true; // this is the first met non-zero value
233  }
234  }
235  }
236 
237  if (!notZero) { // we met no non-zero value
238  GUM_ERROR(FatalError, "Evidence of impossibility (vector of 0s)");
239  }
240 
241  return true; // pot is deterministic
242  }
243 
244 
245  // adds a new hard evidence on node id
246  template < typename GUM_SCALAR >
248  const Idx val) {
250  }
251 
252  // adds a new hard evidence on node id
253  template < typename GUM_SCALAR >
254  INLINE void
255  BayesNetInference< GUM_SCALAR >::addEvidence(const std::string& nodeName,
256  const Idx val) {
257  addEvidence(this->BN().idFromName(nodeName), val);
258  }
259 
260  // adds a new hard evidence on node id
261  template < typename GUM_SCALAR >
262  INLINE void
264  const std::string& label) {
265  addEvidence(id, this->BN().variable(id)[label]);
266  }
267 
268  // adds a new hard evidence on node id
269  template < typename GUM_SCALAR >
270  INLINE void
271  BayesNetInference< GUM_SCALAR >::addEvidence(const std::string& nodeName,
272  const std::string& label) {
273  NodeId id = this->BN().idFromName(nodeName);
274  addEvidence(id, this->BN().variable(id)[label]);
275  }
276 
277  // adds a new evidence on node id (might be soft or hard)
278  template < typename GUM_SCALAR >
280  NodeId id, const std::vector< GUM_SCALAR >& vals) {
281  // checks that the evidence is meaningful
282  if (__bn == nullptr)
284  "No Bayes net has been assigned to the "
285  "inference algorithm");
286 
287  if (!__bn->dag().exists(id)) {
288  GUM_ERROR(UndefinedElement, id << " is not a NodeId in the bn");
289  }
290 
291  if (__bn->variable(id).domainSize() != vals.size()) {
293  "node " << __bn->variable(id)
294  << " and its evidence vector have different sizes.");
295  }
296 
298  pot.add(__bn->variable(id));
299  pot.fillWith(vals);
300  addEvidence(std::move(pot));
301  }
302 
303  // adds a new evidence on node id (might be soft or hard)
304  template < typename GUM_SCALAR >
306  const std::string& nodeName, const std::vector< GUM_SCALAR >& vals) {
307  addEvidence(this->BN().idFromName(nodeName), vals);
308  }
309 
310  // adds a new evidence on node id (might be soft or hard)
311  template < typename GUM_SCALAR >
312  void
314  // check if the potential corresponds to an evidence
315  if (pot.nbrDim() != 1) {
316  GUM_ERROR(InvalidArgument, pot << " is not mono-dimensional.");
317  }
318  if (__bn == nullptr)
320  "No Bayes net has been assigned to the "
321  "inference algorithm");
322 
323  NodeId id = __bn->nodeId(pot.variable(0));
324 
325  if (hasEvidence(id)) {
327  " node " << id
328  << " already has an evidence. Please use chgEvidence().");
329  }
330 
331  // check whether we have a hard evidence (and also check whether the
332  // potential only contains 0 (in this case, this will automatically raise
333  // an exception) )
334  Idx val;
335  bool is_hard_evidence = __isHardEvidence(pot, val);
336 
337  // insert the evidence
338  __evidence.insert(
339  id,
340  new Potential< GUM_SCALAR >(std::forward< Potential< GUM_SCALAR > >(pot)));
341  if (is_hard_evidence) { // pot is deterministic
342  __hard_evidence.insert(id, val);
344  } else {
346  }
348  _onEvidenceAdded(id, is_hard_evidence);
349  }
350 
351 
352  // adds a new evidence on node id (might be soft or hard)
353  template < typename GUM_SCALAR >
355  const Potential< GUM_SCALAR >& pot) {
356  Potential< GUM_SCALAR > new_pot(pot);
357  addEvidence(std::move(new_pot));
358  }
359 
360 
362  template < typename GUM_SCALAR >
364  const List< const Potential< GUM_SCALAR >* >& potlist) {
365  for (const auto pot : potlist)
366  addEvidence(*pot);
367  }
368 
369 
371  template < typename GUM_SCALAR >
373  const Set< const Potential< GUM_SCALAR >* >& potset) {
374  for (const auto pot : potset)
375  addEvidence(*pot);
376  }
377 
378 
379  // indicates whether some node(s) have received evidence
380  template < typename GUM_SCALAR >
382  return !__evidence.empty();
383  }
384 
385 
386  // indicates whether node id has received an evidence
387  template < typename GUM_SCALAR >
389  return __evidence.exists(id);
390  }
391 
392 
393  // indicates whether node id has received a hard evidence
394  template < typename GUM_SCALAR >
396  return __hard_evidence_nodes.exists(id);
397  }
398 
399 
400  // indicates whether node id has received a soft evidence
401  template < typename GUM_SCALAR >
403  return __soft_evidence_nodes.exists(id);
404  }
405 
406 
407  // indicates whether node id has received an evidence
408  template < typename GUM_SCALAR >
410  const std::string& nodeName) const {
411  return hasEvidence(this->BN().idFromName(nodeName));
412  }
413 
414 
415  // indicates whether node id has received a hard evidence
416  template < typename GUM_SCALAR >
418  const std::string& nodeName) const {
419  return hasHardEvidence(this->BN().idFromName(nodeName));
420  }
421 
422 
423  // indicates whether node id has received a soft evidence
424  template < typename GUM_SCALAR >
426  const std::string& nodeName) const {
427  return hasSoftEvidence(this->BN().idFromName(nodeName));
428  }
429 
430  // change the value of an already existing hard evidence
431  template < typename GUM_SCALAR >
433  const Idx val) {
435  }
436 
437  // change the value of an already existing hard evidence
438  template < typename GUM_SCALAR >
439  INLINE void
440  BayesNetInference< GUM_SCALAR >::chgEvidence(const std::string& nodeName,
441  const Idx val) {
442  chgEvidence(this->BN().idFromName(nodeName), val);
443  }
444 
445  // change the value of an already existing hard evidence
446  template < typename GUM_SCALAR >
447  INLINE void
449  const std::string& label) {
450  chgEvidence(id, this->BN().variable(id)[label]);
451  }
452 
453  // change the value of an already existing hard evidence
454  template < typename GUM_SCALAR >
455  INLINE void
456  BayesNetInference< GUM_SCALAR >::chgEvidence(const std::string& nodeName,
457  const std::string& label) {
458  NodeId id = this->BN().idFromName(nodeName);
459  chgEvidence(id, this->BN().variable(id)[label]);
460  }
461 
462  // change the value of an already existing evidence (might be soft or hard)
463  template < typename GUM_SCALAR >
465  NodeId id, const std::vector< GUM_SCALAR >& vals) {
466  // check whether this corresponds to an evidence
467  if (__bn == nullptr)
469  "No Bayes net has been assigned to the "
470  "inference algorithm");
471 
472  if (!__bn->dag().exists(id)) {
473  GUM_ERROR(UndefinedElement, id << " is not a NodeId in the bn");
474  }
475 
476  if (__bn->variable(id).domainSize() != vals.size()) {
478  "node " << __bn->variable(id)
479  << " and its evidence have different sizes.");
480  }
481 
482  // create the potential corresponding to vals
484  pot.add(__bn->variable(id));
485  pot.fillWith(vals);
486  chgEvidence(pot);
487  }
488 
489  // change the value of an already existing evidence (might be soft or hard)
490  template < typename GUM_SCALAR >
492  const std::string& nodeName, const std::vector< GUM_SCALAR >& vals) {
493  chgEvidence(this->BN().idFromName(nodeName), vals);
494  }
495 
496 
497  // change the value of an already existing evidence (might be soft or hard)
498  template < typename GUM_SCALAR >
500  const Potential< GUM_SCALAR >& pot) {
501  // check if the potential corresponds to an evidence
502  if (pot.nbrDim() != 1) {
503  GUM_ERROR(InvalidArgument, pot << " is not a mono-dimensional potential.");
504  }
505  if (__bn == nullptr)
507  "No Bayes net has been assigned to the "
508  "inference algorithm");
509 
510  NodeId id = __bn->nodeId(pot.variable(0));
511 
512  if (!hasEvidence(id)) {
514  id << " has no evidence. Please use addEvidence().");
515  }
516 
517  // check whether we have a hard evidence (and also check whether the
518  // potential only contains 0 (in this case, this will automatically raise
519  // an exception) )
520  Idx val;
521  bool is_hard_evidence = __isHardEvidence(pot, val);
522 
523  // modify the evidence already stored
524  const Potential< GUM_SCALAR >* localPot = __evidence[id];
525  Instantiation I(pot);
526  for (I.setFirst(); !I.end(); I.inc()) {
527  localPot->set(I, pot[I]);
528  }
529 
530  // the inference state will be different
531  // whether evidence change from Hard to Soft or not.
532  bool hasChangedSoftHard = false;
533 
534  if (is_hard_evidence) {
535  if (!hasHardEvidence(id)) {
536  hasChangedSoftHard = true;
537  __hard_evidence.insert(id, val);
540  } else {
541  __hard_evidence[id] = val;
542  }
543  } else {
544  if (hasHardEvidence(id)) { // evidence was hard
545  __hard_evidence.erase(id);
548  hasChangedSoftHard = true;
549  }
550  }
551 
552  if (hasChangedSoftHard) {
554  } else {
557  }
558  }
559 
560  _onEvidenceChanged(id, hasChangedSoftHard);
561  }
562 
563 
564  // removed the evidence, if any, corresponding to node id
565  template < typename GUM_SCALAR >
567  if (hasEvidence(id)) {
568  if (hasHardEvidence(id)) {
569  _onEvidenceErased(id, true);
570  __hard_evidence.erase(id);
573  } else {
574  _onEvidenceErased(id, false);
578  }
579  }
580 
581  delete (__evidence[id]);
582  __evidence.erase(id);
583  }
584  }
585  // removed the evidence, if any, corresponding to node of name nodeName
586  template < typename GUM_SCALAR >
587  INLINE void
588  BayesNetInference< GUM_SCALAR >::eraseEvidence(const std::string& nodeName) {
589  eraseEvidence(this->BN().idFromName(nodeName));
590  }
591 
592 
593  // removes all the evidence entered into the network
594  template < typename GUM_SCALAR >
596  bool has_hard_evidence = !__hard_evidence.empty();
597  this->_onAllEvidenceErased(has_hard_evidence);
598 
599  for (const auto& pair : __evidence) {
600  if (pair.second != nullptr) { delete (pair.second); }
601  }
602 
603  __evidence.clear();
604  __hard_evidence.clear();
607 
608  if (has_hard_evidence) {
610  } else {
613  }
614  }
615  }
616 
617 
618  // returns the number of evidence entered into the Bayesian network
619  template < typename GUM_SCALAR >
621  return __evidence.size();
622  }
623 
624 
625  // returns the number of hard evidence entered into the Bayesian network
626  template < typename GUM_SCALAR >
628  return __hard_evidence_nodes.size();
629  }
630 
631 
632  // returns the number of soft evidence entered into the Bayesian network
633  template < typename GUM_SCALAR >
635  return __soft_evidence_nodes.size();
636  }
637 
638 
639  // indicate for each node with hard evidence which value it took
640  template < typename GUM_SCALAR >
641  INLINE const NodeProperty< Idx >&
643  return __hard_evidence;
644  }
645 
646 
647  // the set of evidence entered into the network
648  template < typename GUM_SCALAR >
651  return __evidence;
652  }
653 
654 
656  template < typename GUM_SCALAR >
657  INLINE const NodeSet&
659  return __soft_evidence_nodes;
660  }
661 
662 
664  template < typename GUM_SCALAR >
665  INLINE const NodeSet&
667  return __hard_evidence_nodes;
668  }
669 
670 
671  // ##############################################################################
672  // Inference
673  // ##############################################################################
674 
675  // put the inference into an unprepared state
676  template < typename GUM_SCALAR >
679  }
680 
681 
684  template < typename GUM_SCALAR >
687  }
688 
689 
690  // prepare the internal inference structures for the next inference
691  template < typename GUM_SCALAR >
693  if (isInferenceReady() || isDone()) { return; }
694 
695  if (__bn == nullptr)
697  "No Bayes net has been assigned to the "
698  "inference algorithm");
699 
702  else
704 
706  }
707 
708 
709  // perform the heavy computations needed to compute the targets' posteriors
710  template < typename GUM_SCALAR >
712  if (isDone()) { return; }
713 
714  if (!isInferenceReady()) { prepareInference(); }
715 
716  _makeInference();
717 
719  }
720 
721 
722 } /* namespace gum */
void __setBayesNetDuringConstruction(const IBayesNet< GUM_SCALAR > *bn)
assigns a BN during the inference engine construction
virtual bool hasSoftEvidence(NodeId id) const final
indicates whether node id has received a soft evidence
virtual Size nbrEvidence() const final
returns the number of evidence entered into the Bayesian network
virtual Size nbrSoftEvidence() const final
returns the number of soft evidence entered into the Bayesian network
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:60
NodeProperty< const Potential< GUM_SCALAR > *> __evidence
the set of evidence entered into the network
NodeProperty< Size > __domain_sizes
the domain sizes of the random variables
virtual void _onStateChanged()=0
fired when the stage is changed
virtual void beginMultipleChanges() final
Default implementation of MultiDimContainer::set().
virtual void __setState(const StateOfInference state) final
set the state of the inference engine and call the notification _onStateChanged when necessary (i...
NodeProperty< Idx > __hard_evidence
assign to each node with a hard evidence the index of its observed value
virtual Idx nbrDim() const final
Returns the number of vars in the multidimensional container.
virtual void addSetOfEvidence(const Set< const Potential< GUM_SCALAR > * > &potset) final
adds a new set of evidence
const NodeProperty< const Potential< GUM_SCALAR > *> & evidence() const
returns the set of evidence
virtual bool hasHardEvidence(NodeId id) const final
indicates whether node id has received a hard evidence
virtual void _onBayesNetChanged(const IBayesNet< GUM_SCALAR > *bn)=0
fired after a new Bayes net has been assigned to the engine
virtual void addListOfEvidence(const List< const Potential< GUM_SCALAR > * > &potlist) final
adds a new list of evidence
StateOfInference __state
the current state of the inference (outdated/ready/done)
virtual void _onEvidenceAdded(const NodeId id, bool isHardEvidence)=0
fired after a new evidence is inserted
virtual ~BayesNetInference()
destructor
BayesNetInference()
default constructor with a null BN (useful for virtual inheritance)
virtual void _onAllEvidenceErased(bool contains_hard_evidence)=0
fired before all the evidence are erased
virtual void _onEvidenceChanged(const NodeId id, bool hasChangedSoftHard)=0
fired after an evidence is changed, in particular when its status (soft/hard) changes ...
virtual bool isInferenceOutdatedBNPotentials() const noexcept final
returns whether the inference object is in a OutdatedBNPotential state
virtual void _makeInference()=0
called when the inference has to be performed effectively
virtual bool isInferenceOutdatedBNStructure() const noexcept final
returns whether the inference object is in a OutdatedBNStructure state
virtual void prepareInference() final
prepare the internal inference structures for the next inference
const IBayesNet< GUM_SCALAR > * __bn
the Bayes net on which we perform inferences
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
void erase(const Key &k)
Erases an element from the set.
Definition: set_tpl.h:656
Generic doubly linked lists.
Definition: list.h:372
Class representing the minimal interface for Bayesian Network.
Definition: IBayesNet.h:62
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
bool __isHardEvidence(const Potential< GUM_SCALAR > &pot, Idx &val) const
checks whether a potential corresponds to a hard evidence or not
The class for generic Hash Tables.
Definition: hashTable.h:679
Idx val(Idx i) const
Returns the current value of the variable at position i.
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
virtual void makeInference() final
perform the heavy computations needed to compute the targets&#39; posteriors
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:607
<agrum/BN/inference/BayesNetInference.h>
NodeSet __soft_evidence_nodes
the set of nodes that received soft evidence
const NodeSet & softEvidenceNodes() const
returns the set of nodes with soft evidence
virtual const NodeProperty< Size > & domainSizes() const final
get the domain sizes of the random variables of the BN
void inc()
Operator increment.
virtual void _updateOutdatedBNPotentials()=0
prepares inference when the latter is in OutdatedBNPotentials state
virtual bool isInferenceDone() const noexcept final
returns whether the inference object is in a InferenceDone state
virtual void chgEvidence(NodeId id, const Idx val) final
change the value of an already existing hard evidence
virtual bool hasEvidence() const final
indicates whether some node(s) have received evidence
const NodeProperty< Idx > & hardEvidence() const
indicate for each node with hard evidence which value it took
virtual bool isDone() const noexcept final
returns whether the inference object is in a done state
virtual void addEvidence(NodeId id, const Idx val) final
adds a new hard evidence on node id
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
virtual void _updateOutdatedBNStructure()=0
prepares inference when the latter is in OutdatedBNStructure state
virtual void eraseAllEvidence() final
removes all the evidence entered into the network
Potential< GUM_SCALAR > __createHardEvidence(NodeId id, Idx val) const
create the internal structure for a hard evidence
virtual const DiscreteVariable & variable(Idx) const final
Returns a const ref to the ith var.
virtual void setBN(const IBayesNet< GUM_SCALAR > *bn)
assigns a new BN to the inference engine
void _setOutdatedBNStructureState()
put the inference into an outdated BN structure state
const NodeSet & hardEvidenceNodes() const
returns the set of nodes with hard evidence
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:83
virtual void clear()
clears all the data structures allocated for the last inference
virtual void add(const DiscreteVariable &v) final
Adds a new var to the variables of the multidimensional matrix.
void __computeDomainSizes()
computes the domain sizes of the random variables
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const final
Default implementation of MultiDimContainer::set().
void setFirst()
Assign the first values to the tuple of the Instantiation.
virtual bool isInferenceReady() const noexcept final
returns whether the inference object is in a ready state
NodeSet __hard_evidence_nodes
the set of nodes that received hard evidence
Size Idx
Type for indexes.
Definition: types.h:53
virtual StateOfInference state() const noexcept final
returns the state of the inference engine
void clear()
Removes all the elements, if any, from the set.
Definition: set_tpl.h:375
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
virtual void _onEvidenceErased(const NodeId id, bool isHardEvidence)=0
fired before an evidence is removed
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:701
virtual Size nbrHardEvidence() const final
returns the number of hard evidence entered into the Bayesian network
StateOfInference
current state of the inference
virtual const IBayesNet< GUM_SCALAR > & BN() const final
Returns a constant reference over the IBayesNet referenced by this class.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
void _setOutdatedBNPotentialsState()
puts the inference into an OutdatedBNPotentials state if it is not already in an OutdatedBNStructure ...
virtual void eraseEvidence(NodeId id) final
removed the evidence, if any, corresponding to node id
bool end() const
Returns true if the Instantiation reached the end.