code: def _log_P(self, X , Z, k):
          
          r_ = self._r_
          Z_ = self._Z_
          # zero case
          if k == 0 :
              log_P = Z['log_p'] + log_K(X, Z, r_[k])
          # recursice case
          else :
              P_zk_z = np.exp( self._log_P(Z_[k], Z, k-1) )
              P_z_zk = np.exp( self._log_P(Z, Z_[k], k-1) ) 
              # flag
              if P_zk_z <= P_z_zk :
                  self._N_is_0 = True
                  log_P = -np.inf
              else : 
                  log_P = np.log( P_zk_z - P_z_zk ) + log_K(X, Z, r_[k])
          return log_P
docs: Log of the probability of transition from z to x with k steps
          log ( P_k (x, z) )
      Inputs : 
          X :
              state to be proposed to
          Z : 
              state to be proposed from
          k : 
              number of recursions, depth