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: Identifies and removes from the _cpds the nodes of the bbn which are
  part of one or more upstream subgraphs that could have been formed
  after a do-intervention.
  
  Uses the attribute _cpds to determine the parents of each node.
  Leverages networkX `weakly_connected_component` method to identify the
  subgraphs.
  
  For instance, the network A -> B -> C -> D -> E  would be split into
  two sub networks (A -> B) and (C -> D -> E) if we intervene on
  node C.
  
  Args:
      var: variable we have intervened on
docstr_tok: ["Identifies","and","removes","from","the","_cpds","the","nodes","of","the","bbn","which","are","part","of","one","or","more","upstream","subgraphs","that","could","have","been","formed","after","a","do-intervention",".","Uses","the","attribute","_cpds","to","determine","the","parents","of","each","node",".","Leverages","networkX","`","weakly_connected_component","`","method","to","identify","the","subgraphs",".","For","instance",",","the","network","A","-",">","B","-",">","C","-",">","D","-",">","E","would","be","split","into","two","sub","networks","(","A","-",">","B",")","and","(","C","-",">","D","-",">","E",")","if","we","intervene","on","node","C.","Args",":","var",":","variable","we","have","intervened","on"]
code: def _remove_disconnected_nodes(self, var: str):
      """
      Identifies and removes from the _cpds the nodes of the bbn which are
      part of one or more upstream subgraphs that could have been formed
      after a do-intervention.
  
      Uses the attribute _cpds to determine the parents of each node.
      Leverages networkX `weakly_connected_component` method to identify the
      subgraphs.
  
      For instance, the network A -> B -> C -> D -> E  would be split into
      two sub networks (A -> B) and (C -> D -> E) if we intervene on
      node C.
  
      Args:
          var: variable we have intervened on
      """
      # construct graph from CPDs
      g = nx.DiGraph()
  
      for node, states in self._cpds.items():
          sample_state = next(iter(states.values()))
          parents = next(iter(sample_state.keys()))
          g.add_node(node)  # add nodes as there could be isolates
  
          for parent, _ in parents:
              g.add_edge(parent, node)
  
      # remove nodes in subgraphs which do not contain the intervention node
      for sub_graph in nx.weakly_connected_components(g):
          if var not in sub_graph:
              for node in sub_graph:
                  self._detached_cpds[node] = self._cpds[node]
                  self._cpds.pop(node)
  
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 12 for calling the InferenceEngine obj's underlying member method code with example usage: obj._remove_disconnected_nodes(var) without return types