'Args:
y (list): list of predicted sentences
t (list): list of reference sentences where each element is a list
of multiple references
N (int, optional): compute all ngram modified precisions up to this N
brevity_penalty (bool, optional): if True, use brevity penalty
lower_case (bool, optional): if True, convert all words to lower case'

def __call__(self, y, t, N=4, brevity_penalty=False, lower_case=True):

    y_list = list(y)
    t_list = list(t)
    if lower_case:
        for (ii, sent) in enumerate(y_list):
            y_list[ii] = sent.lower()
    for (ii, sent) in enumerate(y_list):
        y_list[ii] = sent.strip(self.end_token).split()
    for (ii, refs) in enumerate(t_list):
        tmp = []
        for ref in refs:
            tmp += [ref.split()]
        t_list[ii] = tmp
    def ngram_counts(sentence, counts, N):
        for n in range(1, (N + 1)):
            num = ((len(sentence) - n) + 1)
            for jj in range(num):
                ngram = '    '.join(sentence[jj:(jj + n)])
                ngram = ((repr(n) + '    ') + ngram)
                counts[ngram] += 1
    totals = np.zeros(N)
    correct = np.zeros(N)
    (len_translation, len_reference) = (0, 0)
    for (ii, sent) in enumerate(y_list):
        counts_ref_max = Counter()
        counts_cand = Counter()
        ngram_counts(sent, counts_cand, N)
        (closest_diff, closest_len) = (float('inf'), float('inf'))
        for ref in t_list[ii]:
            counts_ref = Counter()
            diff = abs((len(sent) - len(ref)))
            if (diff < closest_diff):
                closest_len = len(ref)
            elif (diff == closest_diff):
                closest_len = min(closest_len, len(ref))
            ngram_counts(ref, counts_ref, N)
            for (ngram, count) in counts_ref.items():
                if (counts_ref_max[ngram] < count):
                    counts_ref_max[ngram] = count
        len_reference += closest_len
        len_translation += len(sent)
        for (ngram, count) in counts_cand.items():
            n = int(ngram[0])
            ind = (n - 1)
            totals[ind] += count
            if (ngram.find(self.unk_symbol) == (-1)):
                r = counts_ref_max[ngram]
                c = (count if (r >= count) else r)
                correct[ind] += c
    precision = ((correct / totals) + 1e-07)
    if (brevity_penalty and (len_translation < len_reference)):
        bp = np.exp((1 - (float(len_reference) / len_translation)))
    else:
        bp = 1.0
    logprec = np.log(precision)
    self.bleu_n = [((100 * bp) * np.exp((sum(logprec[:(nn + 1)]) / (nn + 1)))) for nn in range(N)]
    neon_logger.display(('Bleu    scores:    ' + '    '.join([str(np.round(f, 2)) for f in self.bleu_n])))
    return self.bleu_n[(-1)]
