class_docstr: This is an inference class for performing Causal Inference over Bayesian
  Networks or Structural Equation Models.
  
  Parameters
  ----------
  model: pgmpy.base.DAG | pgmpy.models.BayesianNetwork
      The model that we'll perform inference over.
  
  set_nodes: list[node:str] or None
      A list (or set/tuple) of nodes in the Bayesian Network which have been
      set to a specific value per the do-operator.
  
  Examples
  --------
  Create a small Bayesian Network.
  
  >>> from pgmpy.models import BayesianNetwork
  >>> game = BayesianNetwork([('X', 'A'),
  ...                         ('A', 'Y'),
  ...                         ('A', 'B')])
  
  Load the graph into the CausalInference object to make causal queries.
  
  >>> from pgmpy.inference.CausalInference import CausalInference
  >>> inference = CausalInference(game)
  >>> inference.get_all_backdoor_adjustment_sets(X="X", Y="Y")
  >>> inference.get_all_frontdoor_adjustment_sets(X="X", Y="Y")
  
  References
  ----------
  'Causality: Models, Reasoning, and Inference' - Judea Pearl (2000)
class_docstr_tok: ["This","is","an","inference","class","for","performing","Causal","Inference","over","Bayesian","Networks","or","Structural","Equation","Models",".","Parameters","--","--","--","--","--","model",":","pgmpy.base.DAG","|","pgmpy.models.BayesianNetwork","The","model","that","we","'ll","perform","inference","over",".","set_nodes",":","list","[","node",":","str","]","or","None","A","list","(","or","set\/tuple",")","of","nodes","in","the","Bayesian","Network","which","have","been","set","to","a","specific","value","per","the","do-operator",".","Examples","--","--","--","--","Create","a","small","Bayesian","Network",".",">",">",">","from","pgmpy.models","import","BayesianNetwork",">",">",">","game","=","BayesianNetwork","(","[","(","'","X","'",",","'","A","'",")",",","...","(","'","A","'",",","'","Y","'",")",",","...","(","'","A","'",",","'","B","'",")","]",")","Load","the","graph","into","the","CausalInference","object","to","make","causal","queries",".",">",">",">","from","pgmpy.inference.CausalInference","import","CausalInference",">",">",">","inference","=","CausalInference","(","game",")",">",">",">","inference.get_all_backdoor_adjustment_sets","(","X=","''","X","''",",","Y=","''","Y","''",")",">",">",">","inference.get_all_frontdoor_adjustment_sets","(","X=","''","X","''",",","Y=","''","Y","''",")","References","--","--","--","--","--","'Causality",":","Models",",","Reasoning",",","and","Inference","'","-","Judea","Pearl","(","2000",")"]
docstr: Returns a list of all adjustment sets per the back-door criterion.
  
  A set of variables Z satisfies the back-door criterion relative to an ordered pair of variabies (Xi, Xj) in a DAG G if:
      (i) no node in Z is a descendant of Xi; and
      (ii) Z blocks every path between Xi and Xj that contains an arrow into Xi.
  
  Parameters
  ----------
  X: str (variable name)
      The cause/exposure variables.
  
  Y: str (variable name)
      The outcome variable.
  
  Returns
  -------
  frozenset: A frozenset of frozensets
  
  Y: str
      Target Variable
  
  Examples
  --------
  >>> game1 = BayesianNetwork([('X', 'A'),
  ...                          ('A', 'Y'),
  ...                          ('A', 'B')])
  >>> inference = CausalInference(game1)
  >>> inference.get_all_backdoor_adjustment_sets("X", "Y")
  frozenset()
docstr_tok: ["Returns","a","list","of","all","adjustment","sets","per","the","back-door","criterion",".","A","set","of","variables","Z","satisfies","the","back-door","criterion","relative","to","an","ordered","pair","of","variabies","(","Xi",",","Xj",")","in","a","DAG","G","if",":","(","i",")","no","node","in","Z","is","a","descendant","of","Xi",";","and","(","ii",")","Z","blocks","every","path","between","Xi","and","Xj","that","contains","an","arrow","into","Xi",".","Parameters","--","--","--","--","--","X",":","str","(","variable","name",")","The","cause\/exposure","variables",".","Y",":","str","(","variable","name",")","The","outcome","variable",".","Returns","--","--","--","-","frozenset",":","A","frozenset","of","frozensets","Y",":","str","Target","Variable","Examples","--","--","--","--",">",">",">","game1","=","BayesianNetwork","(","[","(","'","X","'",",","'","A","'",")",",","...","(","'","A","'",",","'","Y","'",")",",","...","(","'","A","'",",","'","B","'",")","]",")",">",">",">","inference","=","CausalInference","(","game1",")",">",">",">","inference.get_all_backdoor_adjustment_sets","(","``","X","''",",","``","Y","''",")","frozenset","(",")"]
code: def get_all_backdoor_adjustment_sets(self, X, Y):
      """
      Returns a list of all adjustment sets per the back-door criterion.
  
      A set of variables Z satisfies the back-door criterion relative to an ordered pair of variabies (Xi, Xj) in a DAG G if:
          (i) no node in Z is a descendant of Xi; and
          (ii) Z blocks every path between Xi and Xj that contains an arrow into Xi.
  
      Parameters
      ----------
      X: str (variable name)
          The cause/exposure variables.
  
      Y: str (variable name)
          The outcome variable.
  
      Returns
      -------
      frozenset: A frozenset of frozensets
  
      Y: str
          Target Variable
  
      Examples
      --------
      >>> game1 = BayesianNetwork([('X', 'A'),
      ...                          ('A', 'Y'),
      ...                          ('A', 'B')])
      >>> inference = CausalInference(game1)
      >>> inference.get_all_backdoor_adjustment_sets("X", "Y")
      frozenset()
      """
      try:
          assert X in self.observed_variables
          assert Y in self.observed_variables
      except AssertionError:
          raise AssertionError("Make sure both X and Y are observed.")
  
      if self.is_valid_backdoor_adjustment_set(X, Y, Z=frozenset()):
          return frozenset()
  
      possible_adjustment_variables = (
          set(self.observed_variables)
          - {X}
          - {Y}
          - set(nx.descendants(self.model, X))
      )
  
      valid_adjustment_sets = []
      for s in _powerset(possible_adjustment_variables):
          super_of_complete = []
          for vs in valid_adjustment_sets:
              super_of_complete.append(vs.intersection(set(s)) == vs)
          if any(super_of_complete):
              continue
          if self.is_valid_backdoor_adjustment_set(X, Y, s):
              valid_adjustment_sets.append(frozenset(s))
  
      if len(valid_adjustment_sets) == 0:
          raise ValueError(
              f"No valid adjustment set found for {X} -> {Y}"
          )
  
      return frozenset(valid_adjustment_sets)
  
imports: from collections.abc import Iterable
  from itertools import chain, product
  import networkx
  import numpy
  from tqdm.auto import tqdm
  from pgmpy import config
  from pgmpy.estimators.LinearModel import LinearEstimator
  from pgmpy.factors.discrete import DiscreteFactor
  from pgmpy.models import BayesianNetwork
  from pgmpy.utils.sets import _powerset, _variable_or_iterable_to_set
label_desc: Use image node_id 4 for calling the CausalInference obj's underlying member method code with example usage: obj.get_all_backdoor_adjustment_sets(X, Y) and returns: frozenset, frozenset