



import sacrebleu as scb
from packaging import version

import datasets


A__       =			"""\
@inproceedings{post-2018-call,
    title = \"A Call for Clarity in Reporting {BLEU} Scores\",
    author = \"Post, Matt\",
    booktitle = \"Proceedings of the Third Conference on Machine Translation: Research Papers\",
    month = oct,
    year = \"2018\",
    address = \"Belgium, Brussels\",
    publisher = \"Association for Computational Linguistics\",
    url = \"https://www.aclweb.org/anthology/W18-6319\",
    pages = \"186--191\",
}
"""

A__       =			"""\
SacreBLEU provides hassle-free computation of shareable, comparable, and reproducible BLEU scores.
Inspired by Rico Sennrich's `multi-bleu-detok.perl`, it produces the official WMT scores but works with plain text.
It also knows all the standard test sets and handles downloading, processing, and tokenization for you.

See the [README.md] file at https://github.com/mjpost/sacreBLEU for more information.
"""

A__       =			"""
Produces BLEU scores along with its sufficient statistics
from a source against one or more references.

Args:
    predictions (`list` of `str`): list of translations to score. Each translation should be tokenized into a list of tokens.
    references (`list` of `list` of `str`): A list of lists of references. The contents of the first sub-list are the references for the first prediction, the contents of the second sub-list are for the second prediction, etc. Note that there must be the same number of references for each prediction (i.e. all sub-lists must be of the same length).
    smooth_method (`str`): The smoothing method to use, defaults to `'exp'`. Possible values are:
        - `'none'`: no smoothing
        - `'floor'`: increment zero counts
        - `'add-k'`: increment num/denom by k for n>1
        - `'exp'`: exponential decay
    smooth_value (`float`): The smoothing value. Only valid when `smooth_method='floor'` (in which case `smooth_value` defaults to `0.1`) or `smooth_method='add-k'` (in which case `smooth_value` defaults to `1`).
    tokenize (`str`): Tokenization method to use for BLEU. If not provided, defaults to `'zh'` for Chinese, `'ja-mecab'` for Japanese and `'13a'` (mteval) otherwise. Possible values are:
        - `'none'`: No tokenization.
        - `'zh'`: Chinese tokenization.
        - `'13a'`: mimics the `mteval-v13a` script from Moses.
        - `'intl'`: International tokenization, mimics the `mteval-v14` script from Moses
        - `'char'`: Language-agnostic character-level tokenization.
        - `'ja-mecab'`: Japanese tokenization. Uses the [MeCab tokenizer](https://pypi.org/project/mecab-python3).
    lowercase (`bool`): If `True`, lowercases the input, enabling case-insensitivity. Defaults to `False`.
    force (`bool`): If `True`, insists that your tokenized input is actually detokenized. Defaults to `False`.
    use_effective_order (`bool`): If `True`, stops including n-gram orders for which precision is 0. This should be `True`, if sentence-level BLEU will be computed. Defaults to `False`.

Returns:
    'score': BLEU score,
    'counts': Counts,
    'totals': Totals,
    'precisions': Precisions,
    'bp': Brevity penalty,
    'sys_len': predictions length,
    'ref_len': reference length,

Examples:

    Example 1:
        >>> predictions = [\"hello there general kenobi\", \"foo bar foobar\"]
        >>> references = [[\"hello there general kenobi\", \"hello there !\"], [\"foo bar foobar\", \"foo bar foobar\"]]
        >>> sacrebleu = datasets.load_metric(\"sacrebleu\")
        >>> results = sacrebleu.compute(predictions=predictions, references=references)
        >>> print(list(results.keys()))
        ['score', 'counts', 'totals', 'precisions', 'bp', 'sys_len', 'ref_len']
        >>> print(round(results[\"score\"], 1))
        100.0

    Example 2:
        >>> predictions = [\"hello there general kenobi\",
        ...                 \"on our way to ankh morpork\"]
        >>> references = [[\"hello there general kenobi\", \"hello there !\"],
        ...                 [\"goodbye ankh morpork\", \"ankh morpork\"]]
        >>> sacrebleu = datasets.load_metric(\"sacrebleu\")
        >>> results = sacrebleu.compute(predictions=predictions,
        ...                             references=references)
        >>> print(list(results.keys()))
        ['score', 'counts', 'totals', 'precisions', 'bp', 'sys_len', 'ref_len']
        >>> print(round(results[\"score\"], 1))
        39.8
"""





@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION			,		_KWARGS_DESCRIPTION			)
class    __lowerCAmelCase					(	datasets.Metric			):




				def 				snake_case  (				self						):



									"""simple docstring"""





									if version.parse(scb.__version__						) < version.parse("""1.4.12"""						):
														raise ImportWarning(
														    """To use `sacrebleu`, the module `sacrebleu>=1.4.12` is required, and the current version of `sacrebleu` doesn't match this condition.\n"""
														    """You can install it with `pip install \"sacrebleu>=1.4.12\"`."""						)
									return datasets.MetricInfo(
									    description=_DESCRIPTION		,							citation=_CITATION		,							homepage="""https://github.com/mjpost/sacreBLEU"""		,							inputs_description=_KWARGS_DESCRIPTION		,							features=datasets.Features(
									        {
									            """predictions""": datasets.Value("""string"""		,							id="""sequence"""						),
									            """references""": datasets.Sequence(datasets.Value("""string"""		,							id="""sequence"""						)		,							id="""references"""						),
									        }						)		,							codebase_urls=["""https://github.com/mjpost/sacreBLEU"""]		,							reference_urls=[
									        """https://github.com/mjpost/sacreBLEU""",
									        """https://en.wikipedia.org/wiki/BLEU""",
									        """https://towardsdatascience.com/evaluating-text-output-in-nlp-bleu-at-your-own-risk-e8609665a213""",
									    ]		,							)




				def 				snake_case  (				self		,							_snake_case		,							_snake_case		,							_snake_case="exp"		,							_snake_case=None		,							_snake_case=False		,							_snake_case=False		,							_snake_case=None		,							_snake_case=False		,							):



									"""simple docstring"""





									_lowerCAmelCase         =       len(references[0]						)
									if any(len(_snake_case						) != references_per_prediction for refs in references						):
														raise ValueError("""Sacrebleu requires the same number of references for each prediction"""						)
									_lowerCAmelCase         =       [[refs[i] for refs in references] for i in range(_snake_case						)]
									_lowerCAmelCase         =       scb.corpus_bleu(
									    _snake_case		,							_snake_case		,							smooth_method=_snake_case		,							smooth_value=_snake_case		,							force=_snake_case		,							lowercase=_snake_case		,							use_effective_order=_snake_case		,							**({"""tokenize""": tokenize} if tokenize else {})		,							)
									_lowerCAmelCase         =       {
									    """score""": output.score,
									    """counts""": output.counts,
									    """totals""": output.totals,
									    """precisions""": output.precisions,
									    """bp""": output.bp,
									    """sys_len""": output.sys_len,
									    """ref_len""": output.ref_len,
									}
									return output_dict




"""simple docstring"""
from typing import Dict, List, Optional, Tuple

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import logging


lowercase__   			=      logging.get_logger(__name__)




class   __snake_case			(	__lowerCAmelCase							):
      a__								=						["""input_ids""", """attention_mask"""]



      def __init__(		self       ,     lowercase="[PAD]"       ,     lowercase="[BOS]"       ,     lowercase="[EOS]"       ,     lowercase="[MASK]"       ,     lowercase="[CLS]"       ,     lowercase="[SEP]"       ,     lowercase=20_48       ,     **lowercase       ,     )      ->     None:





        '''simple docstring'''





        a__:	Any     				=      AddedToken(lowercase       ,     lstrip=lowercase       ,     rstrip=lowercase) if isinstance(lowercase       ,     lowercase) else pad_token
        a__:	Tuple     				=      AddedToken(lowercase       ,     lstrip=lowercase       ,     rstrip=lowercase) if isinstance(lowercase       ,     lowercase) else bos_token
        a__:	Union[str, Any]     				=      AddedToken(lowercase       ,     lstrip=lowercase       ,     rstrip=lowercase) if isinstance(lowercase       ,     lowercase) else eos_token
        a__:	Tuple     				=      AddedToken(lowercase       ,     lstrip=lowercase       ,     rstrip=lowercase) if isinstance(lowercase       ,     lowercase) else mask_token
        a__:	int     				=      AddedToken(lowercase       ,     lstrip=lowercase       ,     rstrip=lowercase) if isinstance(lowercase       ,     lowercase) else cls_token
        a__:	Any     				=      AddedToken(lowercase       ,     lstrip=lowercase       ,     rstrip=lowercase) if isinstance(lowercase       ,     lowercase) else sep_token

        super().__init__(
            pad_token=lowercase       ,     bos_token=lowercase       ,     eos_token=lowercase       ,     mask_token=lowercase       ,     cls_token=lowercase       ,     sep_token=lowercase       ,     model_max_length=lowercase       ,     **lowercase       ,     )

        a__:	Optional[Any]     				=      2**8  # utf is 8 bits

        # define special tokens dict
        a__:	Dict[str, int]     				=      {
            self.pad_token: 0,
            self.bos_token: 1,
            self.eos_token: 2,
            self.mask_token: 3,
            self.cls_token: 4,
            self.sep_token: 5,
        }
        a__:	Union[str, Any]     				=      len(self.special_tokens_encoder)
        a__:	Dict[int, str]     				=      {v: k for k, v in self.special_tokens_encoder.items()}



      def     lowerCamelCase_  (		self)      ->     Dict[str, int]:





        '''simple docstring'''





        a__:	Optional[int]     				=      self.special_tokens_encoder.copy()
        vocab.update(self.added_tokens_encoder)
        for i in range(self._utf_vocab_size):
          a__:	Optional[int]     				=      chr(lowercase)
          a__:	str     				=      i + len(self.special_tokens_encoder)
        return vocab



      @property
      def     lowerCamelCase_  (		self)      ->     List[Any]:





        '''simple docstring'''





        return self._utf_vocab_size + self._num_special_tokens



      def     lowerCamelCase_  (		self       ,     lowercase       ,     lowercase = None       ,     lowercase = False)      ->     List[int]:





        '''simple docstring'''





        if already_has_special_tokens:
          return super().get_special_tokens_mask(
              token_ids_a=lowercase       ,     token_ids_a=lowercase       ,     already_has_special_tokens=lowercase)

        # normal case: some special tokens
        if token_ids_a is None:
          return [1] + [0] * len(lowercase) + [1]
        return [1] + ([0] * len(lowercase)) + [1] + ([0] * len(lowercase)) + [1]



      def     lowerCamelCase_  (		self       ,     lowercase       ,     lowercase = None)      ->     List[int]:





        '''simple docstring'''





        if token_ids_a is None:
          return [self.cls_token_id] + token_ids_a + [self.sep_token_id]
        else:
          return [self.cls_token_id] + token_ids_a + [self.sep_token_id] + token_ids_a + [self.sep_token_id]



      def     lowerCamelCase_  (		self       ,     lowercase)      ->     List[str]:





        '''simple docstring'''





        a__:	Any     				=      [chr(lowercase) for i in text.encode('utf-8')]
        return tokens



      def     lowerCamelCase_  (		self       ,     lowercase)      ->     Union[str, Any]:





        '''simple docstring'''





        if token in self.special_tokens_encoder:
          a__:	Optional[int]     				=      self.special_tokens_encoder[token]
        elif token in self.added_tokens_encoder:
          a__:	Optional[int]     				=      self.added_tokens_encoder[token]
        elif len(lowercase) != 1:
          a__:	Dict     				=      self.unk_token_id
        else:
          a__:	Optional[Any]     				=      ord(lowercase) + self._num_special_tokens
        return token_id



      def     lowerCamelCase_  (		self       ,     lowercase)      ->     Tuple:





        '''simple docstring'''





        if index in self.special_tokens_decoder:
          a__:	List[Any]     				=      self.special_tokens_decoder[index]
        elif index in self.added_tokens_decoder:
          a__:	Tuple     				=      self.added_tokens_decoder[index]
        else:
          a__:	List[str]     				=      chr(index - self._num_special_tokens)
        return token



      def     lowerCamelCase_  (		self       ,     lowercase)      ->     Optional[int]:





        '''simple docstring'''





        a__:	Any     				=      B''
        for token in tokens:
          if token in self.special_tokens_decoder:
            a__:	str     				=      self.special_tokens_decoder[token].encode('utf-8')
          elif token in self.added_tokens_decoder:
            a__:	Optional[Any]     				=      self.special_tokens_decoder[token].encode('utf-8')
          elif token in self.special_tokens_encoder:
            a__:	Optional[Any]     				=      token.encode('utf-8')
          elif token in self.added_tokens_encoder:
            a__:	str     				=      token.encode('utf-8')
          else:
            a__:	Tuple     				=      bytes([ord(lowercase)])
          bstring += tok_string
        a__:	List[str]     				=      bstring.decode('utf-8'       ,     errors='replace')
        return string



      def     lowerCamelCase_  (		self       ,     lowercase       ,     lowercase = None)      ->     Tuple[str]:





        '''simple docstring'''





        return ()


