class_docstr: PCL (Path Consistency Learning).
  
  Not only the batch PCL algorithm proposed in the paper but also its
  asynchronous variant is implemented.
  
  See https://arxiv.org/abs/1702.08892
  
  Args:
      model (chainer.Link): Model to train. It must be a callable that
          accepts a batch of observations as input and return two values:
  
          - action distributions (Distribution)
          - state values (chainer.Variable)
      optimizer (chainer.Optimizer): optimizer used to train the model
      t_max (int or None): The model is updated after every t_max local
          steps. If set None, the model is updated after every episode.
      gamma (float): Discount factor [0,1]
      tau (float): Weight coefficient for the entropy regularizaiton term.
      phi (callable): Feature extractor function
      pi_loss_coef (float): Weight coefficient for the loss of the policy
      v_loss_coef (float): Weight coefficient for the loss of the value
          function
      rollout_len (int): Number of rollout steps
      batchsize (int): Number of episodes or sub-trajectories used for an
          update. The total number of transitions used will be
          (batchsize x t_max).
      disable_online_update (bool): If set true, disable online on-policy
          update and rely only on experience replay.
      n_times_replay (int): Number of times experience replay is repeated per
          one time of online update.
      replay_start_size (int): Experience replay is disabled if the number of
          transitions in the replay buffer is lower than this value.
      normalize_loss_by_steps (bool): If set true, losses are normalized by
          the number of steps taken to accumulate the losses
      act_deterministically (bool): If set true, choose most probable actions
          in act method.
      average_loss_decay (float): Decay rate of average loss. Used only
          to record statistics.
      average_entropy_decay (float): Decay rate of average entropy. Used only
          to record statistics.
      average_value_decay (float): Decay rate of average value. Used only
          to record statistics.
      explorer (Explorer or None): If not None, this explorer is used for
          selecting actions.
      logger (None or Logger): Logger to be used
      batch_states (callable): Method which makes a batch of observations.
          default is `chainerrl.misc.batch_states.batch_states`
      backprop_future_values (bool): If set True, value gradients are
          computed not only wrt V(s_t) but also V(s_{t+d}).
      train_async (bool): If set True, use a process-local model to compute
          gradients and update the globally shared model.
code: def act_and_train(self, obs, reward):
      statevar = self.batch_states([obs], self.xp, self.phi)
  
      if self.last_state is not None:
          self.past_rewards[self.t - 1] = reward
  
      if self.t - self.t_start == self.t_max:
          self.update_on_policy(statevar)
          if len(self.online_batch_losses) == 0:
              for _ in range(self.n_times_replay):
                  self.update_from_replay()
  
      action_distrib, v = self.model(statevar)
      action = chainer.cuda.to_cpu(action_distrib.sample().array)[0]
      if self.explorer is not None:
          action = self.explorer.select_action(self.t, lambda: action)
  
      # Save values for a later update
      self.past_values[self.t] = v
      self.past_actions[self.t] = action
      self.past_action_distrib[self.t] = action_distrib
  
      self.t += 1
  
      if self.process_idx == 0:
          self.logger.debug(
              "t:%s r:%s a:%s action_distrib:%s v:%s",
              self.t,
              reward,
              action,
              action_distrib,
              float(v.array),
          )
      # Update stats
      self.average_value += (1 - self.average_value_decay) * (
          float(v.array[0]) - self.average_value
      )
      self.average_entropy += (1 - self.average_entropy_decay) * (
          float(action_distrib.entropy.array[0]) - self.average_entropy
      )
  
      if self.last_state is not None:
          assert self.last_action is not None
          assert self.last_action_distrib is not None
          # Add a transition to the replay buffer
          self.replay_buffer.append(
              state=self.last_state,
              action=self.last_action,
              reward=reward,
              next_state=obs,
              next_action=action,
              is_state_terminal=False,
              mu=self.last_action_distrib,
          )
  
      self.last_state = obs
      self.last_action = action
      self.last_action_distrib = action_distrib.copy()
  
      return action
  
imports: import copy
  from logging import getLogger
  import chainer
  from chainer import functions
  import chainerrl
  from chainerrl import agent
  from chainerrl.agents import a3c
  from chainerrl.misc import async_
  from chainerrl.misc.batch_states import batch_states
  from chainerrl.misc import copy_param
  from chainerrl.recurrent import Recurrent
  from chainerrl.recurrent import state_kept
  from chainerrl.recurrent import state_reset
  from chainerrl.replay_buffer import batch_experiences
label_desc: Use image node_id 8 for calling the PCL obj's underlying member method code with example usage: obj.act_and_train(obs, reward) and returns: action