code: def parallel_loss_fn(model, guide, parallel=True):
      # We're doing exact inference, so we don't use the guide here.
      factors = model()
      t_term, new_factors = factors[0], factors[1:]
      t = to_funsor("t", t_term.inputs["t"])
      if parallel:
          result = MarkovProduct(
              ops.logaddexp, ops.add, t_term, t, {"y(t=1)": "y"}
          )
      else:
          result = naive_sequential_sum_product(
              ops.logaddexp, ops.add, t_term, t, {"y(t=1)": "y"}
          )
      new_factors = [result] + new_factors
  
      plates = frozenset(["g", "i"])
      eliminate = frozenset().union(*(f.inputs for f in new_factors))
      with funsor.interpretations.lazy:
          loss = sum_product(
              ops.logaddexp, ops.add, new_factors, eliminate, plates
          )
      loss = apply_optimizer(loss)
      assert not loss.inputs
      return -loss.data
  
file_path: funsor/examples/mixed_hmm/experiment.py
imports: import argparse
  import functools
  import json
  import os
  import uuid
  import pyro
  import pyro.poutine
  import torch
  from model import Guide, Model
  from seal_data import prepare_fake, prepare_seal
  import funsor
  import funsor.ops
  from funsor.optimizer import apply_optimizer
  from funsor.sum_product import MarkovProduct, naive_sequential_sum_product, sum_product
  from funsor.terms import to_funsor
label_desc: Use image node_id 2 for calling a global function with example usage: parallel_loss_fn(model, guide, parallel) and returns: unknown