# Path: chatbot/components/bot_ops.py
# def dynamic_sampled_softmax_loss(labels, logits, output_projection, vocab_size,
#                                  from_scratch=False, num_samples=512, name=None):
# def _dynamic_sampled_map(labels, logits, output_projection, vocab_size,
#                                  num_samples=512, name=None):
#         def sampled_loss(elem):
# def _dynamic_sampled_from_scratch(labels, logits, output_projection, vocab_size,
#                                   num_samples, name=None):
#         def sampled_loss_single_timestep(args):
#                 def fn(s_i): return tf.where(targets == s_i, tf.ones_like(targets), tf.zeros_like(targets))
# def cross_entropy_sequence_loss(logits, labels, weights):
# def dot_prod(x, y):
# def bahdanau_score(attention_dim, h_j, s_i):
# def luong_score(attention_dim, h_j, s_i):
# def linear_map(args, output_size, biases=None):
#                 _W = tf.nn.embedding_lookup(weights, all_ids, partition_strategy='div')
#                 W = {'targets': tf.slice(_W, begin=[0, 0], size=[batch_size, state_size]),
#                      'samples': tf.slice(_W, begin=[batch_size, 0], size=[num_samples, state_size])}
#                 F = tf.concat([true_logits, sampled_logits], 1)


import tensorflow as tf
from tensorflow.python.util import nest
from tensorflow.python.ops import rnn_cell_impl
from chatbot.components import bot_ops
from tensorflow.contrib.rnn import RNNCell
from tensorflow.contrib.rnn import GRUCell, MultiRNNCell, LSTMStateTuple
from tensorflow.python.layers import core as layers_core
    from tensorflow.contrib.seq2seq import DynamicAttentionWrapper \
        as AttentionWrapper
    from tensorflow.contrib.seq2seq import DynamicAttentionWrapperState \
        as AttentionWrapperState
    from tensorflow.contrib.seq2seq import AttentionWrapper
    from tensorflow.contrib.seq2seq import AttentionWrapperState
            time=tf.TensorShape(None),
            alignments=tf.TensorShape([None, None]),
            alignment_history=())


class BasicRNNCell(RNNCell):
    """Same as tf.contrib.rnn.BasicRNNCell, rewritten for clarity.

    For example, many TF implementations have leftover code debt from past 
    versions, so I wanted to show what is actually going on, with the fluff 
    removed. Also, I've removed generally accepted values from parameters/args 
    in favor of just setting them.
    """

    def __init__(self, num_units, reuse=None):
        self._num_units = num_units
        self._reuse = reuse

    @property
    def state_size(self):
        return self._num_units

    @property
    def output_size(self):
        return self._num_units

    def __call__(self, inputs, state, scope=None):
        """Most basic RNN. Define as:
            output = new_state = act(W * input + U * state + B).
        """

# Path: chatbot/components/bot_ops.py
# def dynamic_sampled_softmax_loss(labels, logits, output_projection, vocab_size,
#                                  from_scratch=False, num_samples=512, name=None):
# def _dynamic_sampled_map(labels, logits, output_projection, vocab_size,
#                                  num_samples=512, name=None):
#         def sampled_loss(elem):
# def _dynamic_sampled_from_scratch(labels, logits, output_projection, vocab_size,
#                                   num_samples, name=None):
#         def sampled_loss_single_timestep(args):
#                 def fn(s_i): return tf.where(targets == s_i, tf.ones_like(targets), tf.zeros_like(targets))
# def cross_entropy_sequence_loss(logits, labels, weights):
# def dot_prod(x, y):
# def bahdanau_score(attention_dim, h_j, s_i):
# def luong_score(attention_dim, h_j, s_i):
# def linear_map(args, output_size, biases=None):
#                 _W = tf.nn.embedding_lookup(weights, all_ids, partition_strategy='div')
#                 W = {'targets': tf.slice(_W, begin=[0, 0], size=[batch_size, state_size]),
#                      'samples': tf.slice(_W, begin=[batch_size, 0], size=[num_samples, state_size])}
#                 F = tf.concat([true_logits, sampled_logits], 1)


# Path: chatbot/components/base/_rnn.py
import tensorflow as tf
from tensorflow.python.util import nest
from tensorflow.python.ops import rnn_cell_impl
from chatbot.components import bot_ops
from tensorflow.contrib.rnn import RNNCell
from tensorflow.contrib.rnn import GRUCell, MultiRNNCell, LSTMStateTuple
from tensorflow.python.layers import core as layers_core
    from tensorflow.contrib.seq2seq import DynamicAttentionWrapper \
        as AttentionWrapper
    from tensorflow.contrib.seq2seq import DynamicAttentionWrapperState \
        as AttentionWrapperState
    from tensorflow.contrib.seq2seq import AttentionWrapper
    from tensorflow.contrib.seq2seq import AttentionWrapperState

            time=tf.TensorShape(None),
            alignments=tf.TensorShape([None, None]),
            alignment_history=())


class BasicRNNCell(RNNCell):
    """Same as tf.contrib.rnn.BasicRNNCell, rewritten for clarity.

    For example, many TF implementations have leftover code debt from past 
    versions, so I wanted to show what is actually going on, with the fluff 
    removed. Also, I've removed generally accepted values from parameters/args 
    in favor of just setting them.
    """

    def __init__(self, num_units, reuse=None):
        self._num_units = num_units
        self._reuse = reuse

    @property
    def state_size(self):
        return self._num_units

    @property
    def output_size(self):
        return self._num_units

    def __call__(self, inputs, state, scope=None):
        """Most basic RNN. Define as:
            output = new_state = act(W * input + U * state + B).
        """

        output = tf.tanh(bot_ops.linear_map(