code: def is_blocked(graph: nx.DiGraph, path, conditioned_nodes):
      """Uses d-separation criteria to decide if conditioned_nodes block given path."""
  
      blocked_by_conditioning = False
      has_unconditioned_collider = False
  
      for i in range(len(path) - 2):
          if graph.has_edge(path[i], path[i + 1]) and graph.has_edge(
              path[i + 2], path[i + 1]
          ):  # collider
              collider_descendants = nx.descendants(graph, path[i + 1])
              if path[i + 1] not in conditioned_nodes and all(
                  cdesc not in conditioned_nodes
                  for cdesc in collider_descendants
              ):
                  has_unconditioned_collider = True
          else:  # chain or fork
              if path[i + 1] in conditioned_nodes:
                  blocked_by_conditioning = True
                  break
      if blocked_by_conditioning:
          return True
      elif has_unconditioned_collider:
          return True
      else:
          return False
  
imports: import itertools
  import logging
  import re
  from abc import abstractmethod
  from typing import Any, List, Protocol
  import networkx
  from networkx.algorithms.dag import has_cycle
  from dowhy.utils.api import parse_state
  from dowhy.utils.graph_operations import daggity_to_dot
label_desc: Use image node_id 9 for calling a global function with example usage: is_blocked(graph, path, conditioned_nodes) and returns: True, True, False