code: def test_sequential_sum_product(
      impl, sum_op, prod_op, batch_inputs, state_domain, num_steps
  ):
      inputs = OrderedDict(batch_inputs)
      inputs.update(prev=state_domain, curr=state_domain)
      if num_steps is None:
          num_steps = 1
      else:
          inputs["time"] = Bint[num_steps]
      if state_domain.dtype == "real":
          trans = random_gaussian(inputs)
      else:
          trans = random_tensor(inputs)
      time = Variable("time", Bint[num_steps])
  
      actual = impl(sum_op, prod_op, trans, time, {"prev": "curr"})
      expected_inputs = batch_inputs.copy()
      expected_inputs.update(prev=state_domain, curr=state_domain)
      assert dict(actual.inputs) == expected_inputs
  
      # Check against contract.
      operands = tuple(
          trans(
              time=t, prev="t_{}".format(t), curr="t_{}".format(t + 1)
          )
          for t in range(num_steps)
      )
      reduce_vars = frozenset(
          "t_{}".format(t) for t in range(1, num_steps)
      )
      with reflect:
          expected = sum_product(sum_op, prod_op, operands, reduce_vars)
      expected = apply_optimizer(expected)
      expected = expected(
          **{"t_0": "prev", "t_{}".format(num_steps): "curr"}
      )
      expected = expected.align(tuple(actual.inputs.keys()))
      with (
          compress_gaussians
      ):  # since actual,expected may differ only in rank
          actual = reinterpret(actual)
          expected = reinterpret(expected)
      assert_close(
          actual, expected, atol=1e-3 * num_steps, rtol=1e-3 * num_steps
      )
  
imports: import os
  import re
  from collections import OrderedDict
  from functools import partial, reduce
  import pytest
  import funsor.ops
  from funsor.domains import Bint, Real, Reals
  from funsor.interpretations import compress_gaussians, eager, eager_or_die, lazy, moment_matching, reflect
  from funsor.interpreter import reinterpret
  from funsor.optimizer import apply_optimizer
  from funsor.sum_product import MarkovProduct, _partition, dynamic_partial_sum_product, mixed_sequential_sum_product, modified_partial_sum_product, naive_sarkka_bilmes_product, naive_sequential_sum_product, partial_sum_product, partial_unroll, sarkka_bilmes_product, sequential_sum_product, sum_product
  from funsor.tensor import Tensor, get_default_prototype
  from funsor.terms import Cat, Variable
  from funsor.testing import assert_close, random_gaussian, random_tensor
  from funsor.util import get_backend
label_desc: Use image node_id 29 for calling a global function with example usage: test_sequential_sum_product(impl, sum_op, prod_op, batch_inputs, state_domain, num_steps) without return types