docstr: Inserting this sepset into
  a forest, providing the two
  cliques are in different trees,
  means that effectively we are
  collapsing the two trees into
  one. We will explicitely perform
  this collapse by adding the
  sepset node into the tree
  and adding edges between itself
  and its clique node neighbours.
  Finally we must remove the
  second tree from the forest
  as it is now joined to the
  first.
docstr_tok: ["Inserting","this","sepset","into","a","forest",",","providing","the","two","cliques","are","in","different","trees",",","means","that","effectively","we","are","collapsing","the","two","trees","into","one",".","We","will","explicitely","perform","this","collapse","by","adding","the","sepset","node","into","the","tree","and","adding","edges","between","itself","and","its","clique","node","neighbours",".","Finally","we","must","remove","the","second","tree","from","the","forest","as","it","is","now","joined","to","the","first","."]
code: def insert(self, forest):
      """Inserting this sepset into
      a forest, providing the two
      cliques are in different trees,
      means that effectively we are
      collapsing the two trees into
      one. We will explicitely perform
      this collapse by adding the
      sepset node into the tree
      and adding edges between itself
      and its clique node neighbours.
      Finally we must remove the
      second tree from the forest
      as it is now joined to the
      first.
      """
      X_tree = [
          t
          for t in forest
          if self.X in [n.clique for n in t.clique_nodes]
      ][0]
      Y_tree = [
          t
          for t in forest
          if self.Y in [n.clique for n in t.clique_nodes]
      ][0]
  
      # Now create and insert a sepset node into the Xtree
      ss_node = JoinTreeSepSetNode(self, self)
      X_tree.nodes.append(ss_node)
  
      # And connect them
      self.X.node.neighbours.append(ss_node)
      ss_node.neighbours.append(self.X.node)
  
      # Now lets keep the X_tree and drop the Y_tree
      # this means we need to copy all the nodes
      # in the Y_tree that are not already in the X_tree
      for node in Y_tree.nodes:
          if node in X_tree.nodes:
              continue
          X_tree.nodes.append(node)
  
      # Now connect the sepset node to the
      # Y_node (now residing in the X_tree)
      self.Y.node.neighbours.append(ss_node)
      ss_node.neighbours.append(self.Y.node)
  
      # And finally we must remove the Y_tree from
      # the forest...
      forest.remove(Y_tree)
  
imports: import copy
  import heapq
  import logging
  from collections import defaultdict
  from io import StringIO
  from itertools import combinations, product
  from random import choice, random
  from .exceptions import VariableNotInGraphError, VariableValueNotInDomainError
  from .graph import Node, UndirectedGraph, UndirectedNode, connect
  from .utils import get_args, get_original_factors
label_desc: Use image node_id 5 for calling the SepSet obj's underlying member method code with example usage: obj.insert(forest) without return types