class_docstr: An ``InferenceEngine`` provides methods to query marginals based on observations and
  make interventions (Do-Calculus) on a ``BayesianNetwork``.
  
  Example:
  ::
      >>> # Create a Bayesian Network with a manually defined DAG
      >>> from causalnex.structure.structuremodel import StructureModel
      >>> from causalnex.network import BayesianNetwork
      >>> from causalnex.inference import InferenceEngine
      >>>
      >>> sm = StructureModel()
      >>> sm.add_edges_from([
      >>>                    ('rush_hour', 'traffic'),
      >>>                    ('weather', 'traffic')
      >>>                    ])
      >>> data = pd.DataFrame({
      >>>                      'rush_hour': [True, False, False, False, True, False, True],
      >>>                      'weather': ['Terrible', 'Good', 'Bad', 'Good', 'Bad', 'Bad', 'Good'],
      >>>                      'traffic': ['heavy', 'light', 'heavy', 'light', 'heavy', 'heavy', 'heavy']
      >>>                      })
      >>> bn = BayesianNetwork(sm)
      >>> # Inference can only be performed on the `BayesianNetwork` with learned nodes states and CPDs
      >>> bn = bn.fit_node_states_and_cpds(data)
      >>>
      >>> # Create an `InferenceEngine` to query marginals and make interventions
      >>> ie = InferenceEngine(bn)
      >>> # Query the marginals as learned from data
      >>> ie.query()['traffic']
      {'heavy': 0.7142857142857142, 'light': 0.2857142857142857}
      >>> # Query the marginals given observations
      >>> ie.query({'rush_hour': True, 'weather': 'Terrible'})['traffic']
      {'heavy': 1.0, 'light': 0.0}
      >>> # Make an intervention on the `BayesianNetwork`
      >>> ie.do_intervention('rush_hour', False)
      >>> # Query marginals on the intervened `BayesianNetwork`
      >>> ie.query()['traffic']
      {'heavy': 0.5, 'light': 0.5}
      >>> # Reset interventions
      >>> ie.reset_do('rush_hour')
      >>> ie.query()['traffic']
      {'heavy': 0.7142857142857142, 'light': 0.2857142857142857}
class_docstr_tok: ["An","``","InferenceEngine","``","provides","methods","to","query","marginals","based","on","observations","and","make","interventions","(","Do-Calculus",")","on","a","``","BayesianNetwork","``",".","Example",":",":",":",">",">",">","#","Create","a","Bayesian","Network","with","a","manually","defined","DAG",">",">",">","from","causalnex.structure.structuremodel","import","StructureModel",">",">",">","from","causalnex.network","import","BayesianNetwork",">",">",">","from","causalnex.inference","import","InferenceEngine",">",">",">",">",">",">","sm","=","StructureModel","(",")",">",">",">","sm.add_edges_from","(","[",">",">",">","(","'rush_hour","'",",","'traffic","'",")",",",">",">",">","(","'weather","'",",","'traffic","'",")",">",">",">","]",")",">",">",">","data","=","pd.DataFrame","(","{",">",">",">","'rush_hour","'",":","[","True",",","False",",","False",",","False",",","True",",","False",",","True","]",",",">",">",">","'weather","'",":","[","'Terrible","'",",","'Good","'",",","'Bad","'",",","'Good","'",",","'Bad","'",",","'Bad","'",",","'Good","'","]",",",">",">",">","'traffic","'",":","[","'heavy","'",",","'light","'",",","'heavy","'",",","'light","'",",","'heavy","'",",","'heavy","'",",","'heavy","'","]",">",">",">","}",")",">",">",">","bn","=","BayesianNetwork","(","sm",")",">",">",">","#","Inference","can","only","be","performed","on","the","`","BayesianNetwork","`","with","learned","nodes","states","and","CPDs",">",">",">","bn","=","bn.fit_node_states_and_cpds","(","data",")",">",">",">",">",">",">","#","Create","an","`","InferenceEngine","`","to","query","marginals","and","make","interventions",">",">",">","ie","=","InferenceEngine","(","bn",")",">",">",">","#","Query","the","marginals","as","learned","from","data",">",">",">","ie.query","(",")","[","'traffic","'","]","{","'heavy","'",":","0.7142857142857142",",","'light","'",":","0.2857142857142857","}",">",">",">","#","Query","the","marginals","given","observations",">",">",">","ie.query","(","{","'rush_hour","'",":","True",",","'weather","'",":","'Terrible","'","}",")","[","'traffic","'","]","{","'heavy","'",":","1.0",",","'light","'",":","0.0","}",">",">",">","#","Make","an","intervention","on","the","`","BayesianNetwork","`",">",">",">","ie.do_intervention","(","'rush_hour","'",",","False",")",">",">",">","#","Query","marginals","on","the","intervened","`","BayesianNetwork","`",">",">",">","ie.query","(",")","[","'traffic","'","]","{","'heavy","'",":","0.5",",","'light","'",":","0.5","}",">",">",">","#","Reset","interventions",">",">",">","ie.reset_do","(","'rush_hour","'",")",">",">",">","ie.query","(",")","[","'traffic","'","]","{","'heavy","'",":","0.7142857142857142",",","'light","'",":","0.2857142857142857","}"]
docstr: Queries the ``BayesianNetwork`` for marginals given one or more observations.
  
  Args:
      observations: one or more observations of states of nodes in the Bayesian Network.
      parallel: if True, run the query using multiprocessing
      num_cores: only applicable if parallel=True. The number of cores used during multiprocessing.
                 If num_cores is not provided, number of processors will be autodetected and used
  
  Returns:
      A dictionary or a list of dictionaries of marginal probabilities of the network.
  
  Raises:
      TypeError: if observations is neither None nor a dictionary nor a list
docstr_tok: ["Queries","the","``","BayesianNetwork","``","for","marginals","given","one","or","more","observations",".","Args",":","observations",":","one","or","more","observations","of","states","of","nodes","in","the","Bayesian","Network",".","parallel",":","if","True",",","run","the","query","using","multiprocessing","num_cores",":","only","applicable","if","parallel=True",".","The","number","of","cores","used","during","multiprocessing",".","If","num_cores","is","not","provided",",","number","of","processors","will","be","autodetected","and","used","Returns",":","A","dictionary","or","a","list","of","dictionaries","of","marginal","probabilities","of","the","network",".","Raises",":","TypeError",":","if","observations","is","neither","None","nor","a","dictionary","nor","a","list"]
code: def query(
      self,
      observations: Optional[
          Union[Dict[str, Any], List[Dict[str, Any]]]
      ] = None,
      parallel: bool = False,
      num_cores: Optional[int] = None,
  ) -> Union[
      Dict[str, Dict[Hashable, float]],
      List[Dict[str, Dict[Hashable, float]]],
  ]:
      """
      Queries the ``BayesianNetwork`` for marginals given one or more observations.
  
      Args:
          observations: one or more observations of states of nodes in the Bayesian Network.
          parallel: if True, run the query using multiprocessing
          num_cores: only applicable if parallel=True. The number of cores used during multiprocessing.
                     If num_cores is not provided, number of processors will be autodetected and used
  
      Returns:
          A dictionary or a list of dictionaries of marginal probabilities of the network.
  
      Raises:
          TypeError: if observations is neither None nor a dictionary nor a list
      """
      if observations is not None and not isinstance(
          observations, (dict, list)
      ):
          raise TypeError(
              "Expecting observations to be a dict, list or None"
          )
  
      if isinstance(observations, list):
          if parallel:
              with multiprocessing.Pool(num_cores) as p:
                  result = p.map(self._single_query, observations)
          else:
              result = [self._single_query(obs) for obs in observations]
      else:  # dictionary or None
          result = self._single_query(observations)
  
      return result
  
imports: import copy
  import inspect
  import math
  import re
  import types
  from typing import Any, Callable, Dict, Hashable, List, Optional, Tuple, Union
  import networkx
  import pandas
  from pathos import multiprocessing
  from causalnex.ebaybbn import build_bbn
  from causalnex.network import BayesianNetwork
label_desc: Use image node_id 3 for calling the InferenceEngine obj's underlying member method code with example usage: obj.query(observations, parallel, num_cores) and returns: result