code: def adjoint_binary(adj_sum_op, adj_prod_op, out_adj, op, lhs, rhs):
      if op is adj_prod_op:
          lhs_adj = adj_prod_op(out_adj, rhs)
          rhs_adj = adj_prod_op(out_adj, lhs)
          return ((lhs, lhs_adj), (rhs, rhs_adj))
      elif op is adj_sum_op:
          return ((lhs, out_adj), (rhs, out_adj))
      raise ValueError("should not be here!")
  
imports: from collections import defaultdict
  from collections.abc import Hashable
  from funsor.cnf import Contraction
  from funsor.interpretations import Interpretation, reflect
  from funsor.interpreter import stack_reinterpret
  from funsor.ops import AssociativeOp
  from funsor.registry import KeyedRegistry
  from funsor.terms import Approximate, Binary, Cat, Funsor, Reduce, Scatter, Slice, Subs, substitute, to_funsor
  from .None import instrument, interpreter, ops
label_desc: Use image node_id 5 for calling a global function with example usage: adjoint_binary(adj_sum_op, adj_prod_op, out_adj, op, lhs, rhs) and returns: lhs,  lhs_adj,  rhs,  rhs_adj, lhs,  out_adj,  rhs,  out_adj