






'''simple docstring'''







import datasets

from .nmt_bleu import compute_bleu  # From: https://github.com/tensorflow/nmt/blob/master/nmt/scripts/bleu.py


__lowerCAmelCase        =							"\\n@INPROCEEDINGS{Papineni02bleu:a,\n    author = {Kishore Papineni and Salim Roukos and Todd Ward and Wei-jing Zhu},\n    title = {BLEU: a Method for Automatic Evaluation of Machine Translation},\n    booktitle = {},\n    year = {2002},\n    pages = {311--318}\n}\n@inproceedings{lin-och-2004-orange,\n    title = \"{ORANGE}: a Method for Evaluating Automatic Evaluation Metrics for Machine Translation\",\n    author = \"Lin, Chin-Yew  and\n      Och, Franz Josef\",\n    booktitle = \"{COLING} 2004: Proceedings of the 20th International Conference on Computational Linguistics\",\n    month = \"aug 23{--}aug 27\",\n    year = \"2004\",\n    address = \"Geneva, Switzerland\",\n    publisher = \"COLING\",\n    url = \"https://www.aclweb.org/anthology/C04-1072\",\n    pages = \"501--507\",\n}\n"

__lowerCAmelCase        =							"\\nBLEU (bilingual evaluation understudy) is an algorithm for evaluating the quality of text which has been machine-translated from one natural language to another.\nQuality is considered to be the correspondence between a machine\'s output and that of a human: \"the closer a machine translation is to a professional human translation,\nthe better it is\" – this is the central idea behind BLEU. BLEU was one of the first metrics to claim a high correlation with human judgements of quality, and\nremains one of the most popular automated and inexpensive metrics.\n\nScores are calculated for individual translated segments—generally sentences—by comparing them with a set of good quality reference translations.\nThose scores are then averaged over the whole corpus to reach an estimate of the translation\'s overall quality. Intelligibility or grammatical correctness\nare not taken into account[citation needed].\n\nBLEU\'s output is always a number between 0 and 1. This value indicates how similar the candidate text is to the reference texts, with values closer to 1\nrepresenting more similar texts. Few human translations will attain a score of 1, since this would indicate that the candidate is identical to one of the\nreference translations. For this reason, it is not necessary to attain a score of 1. Because there are more opportunities to match, adding additional\nreference translations will increase the BLEU score.\n"

__lowerCAmelCase        =							"\nComputes BLEU score of translated segments against one or more references.\nArgs:\n    predictions: list of translations to score.\n        Each translation should be tokenized into a list of tokens.\n    references: list of lists of references for each translation.\n        Each reference should be tokenized into a list of tokens.\n    max_order: Maximum n-gram order to use when computing BLEU score.\n    smooth: Whether or not to apply Lin et al. 2004 smoothing.\nReturns:\n    \'bleu\': bleu score,\n    \'precisions\': geometric mean of n-gram precisions,\n    \'brevity_penalty\': brevity penalty,\n    \'length_ratio\': ratio of lengths,\n    \'translation_length\': translation_length,\n    \'reference_length\': reference_length\nExamples:\n\n    >>> predictions = [\n    ...     [\"hello\", \"there\", \"general\", \"kenobi\"],                             # tokenized prediction of the first sample\n    ...     [\"foo\", \"bar\", \"foobar\"]                                             # tokenized prediction of the second sample\n    ... ]\n    >>> references = [\n    ...     [[\"hello\", \"there\", \"general\", \"kenobi\"], [\"hello\", \"there\", \"!\"]],  # tokenized references for the first sample (2 references)\n    ...     [[\"foo\", \"bar\", \"foobar\"]]                                           # tokenized references for the second sample (1 reference)\n    ... ]\n    >>> bleu = datasets.load_metric(\"bleu\")\n    >>> results = bleu.compute(predictions=predictions, references=references)\n    >>> print(results[\"bleu\"])\n    1.0\n"




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


  """simple docstring"""


  def    _a       (			self	):






         """simple docstring"""


         return datasets.MetricInfo(
             description=_DESCRIPTION   ,	citation=_CITATION   ,	inputs_description=_KWARGS_DESCRIPTION   ,	features=datasets.Features(
                 {
                     'predictions': datasets.Sequence(datasets.Value('string'   ,	id='token'	)   ,	id='sequence'	),
                     'references': datasets.Sequence(
                         datasets.Sequence(datasets.Value('string'   ,	id='token'	)   ,	id='sequence'	)   ,	id='references'	),
                 }	)   ,	codebase_urls=['https://github.com/tensorflow/nmt/blob/master/nmt/scripts/bleu.py']   ,	reference_urls=[
                 'https://en.wikipedia.org/wiki/BLEU',
                 'https://towardsdatascience.com/evaluating-text-output-in-nlp-bleu-at-your-own-risk-e8609665a213',
             ]   ,	)







  def    _a       (			self   ,	UpperCamelCase__   ,	UpperCamelCase__   ,	UpperCamelCase__=4   ,	UpperCamelCase__=False	):






         """simple docstring"""


         a_						     =			compute_bleu(
             reference_corpus=lowercase_   ,	translation_corpus=lowercase_   ,	max_order=lowercase_   ,	smooth=lowercase_	)
         ((a_)     ,	(a_)     ,	(a_)     ,	(a_)     ,	(a_)     ,	(a_))						     =			score
         return {
             "bleu": bleu,
             "precisions": precisions,
             "brevity_penalty": bp,
             "length_ratio": ratio,
             "translation_length": translation_length,
             "reference_length": reference_length,
         }





import os
import unicodedata
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tuple

import sentencepiece as spm

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


lowerCamelCase__  =					logging.get_logger(__name__)

lowerCamelCase__  =					{'''vocab_file''': '''spiece.model'''}

lowerCamelCase__  =					{
    '''vocab_file''': {
        '''xlnet-base-cased''': '''https://huggingface.co/xlnet-base-cased/resolve/main/spiece.model''',
        '''xlnet-large-cased''': '''https://huggingface.co/xlnet-large-cased/resolve/main/spiece.model''',
    }
}

lowerCamelCase__  =					{
    '''xlnet-base-cased''': None,
    '''xlnet-large-cased''': None,
}

# Segments (not really needed)
lowerCamelCase__  =					0
lowerCamelCase__  =					1
lowerCamelCase__  =					2
lowerCamelCase__  =					3
lowerCamelCase__  =					4




class 					_UpperCAmelCase			(     lowerCAmelCase  ):



 '''simple docstring'''




 __A			       =					VOCAB_FILES_NAMES
 __A			       =					PRETRAINED_VOCAB_FILES_MAP
 __A			       =					PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
 __A			       =					'''left'''







 def __init__(		self				:   int							, lowercase_				:   Optional[int]							, lowercase_				:   Dict=False							, lowercase_				:   Any=True							, lowercase_				:   Any=False							, lowercase_				:   Any="<s>"							, lowercase_				:   Dict="</s>"							, lowercase_				:   Optional[Any]="<unk>"							, lowercase_				:   Optional[int]="<sep>"							, lowercase_				:   Optional[Any]="<pad>"							, lowercase_				:   Tuple="<cls>"							, lowercase_				:   Union[str, Any]="<mask>"							, lowercase_				:   Dict=["<eop>", "<eod>"]							, lowercase_				:   Optional[Dict[str, Any]] = None							, **lowercase_				:   int							, )						->	None:


   """simple docstring"""







   _UpperCamelCase           =    AddedToken(lowercase_							, lstrip=lowercase_							, rstrip=lowercase_) if isinstance(lowercase_							, lowercase_) else mask_token

   _UpperCamelCase           =    {} if sp_model_kwargs is None else sp_model_kwargs

   super().__init__(
       do_lower_case=lowercase_							, remove_space=lowercase_							, keep_accents=lowercase_							, bos_token=lowercase_							, eos_token=lowercase_							, unk_token=lowercase_							, sep_token=lowercase_							, pad_token=lowercase_							, cls_token=lowercase_							, mask_token=lowercase_							, additional_special_tokens=lowercase_							, sp_model_kwargs=self.sp_model_kwargs							, **lowercase_							, )

   _UpperCamelCase           =    3

   _UpperCamelCase           =    do_lower_case
   _UpperCamelCase           =    remove_space
   _UpperCamelCase           =    keep_accents
   _UpperCamelCase           =    vocab_file

   _UpperCamelCase           =    spm.SentencePieceProcessor(**self.sp_model_kwargs)
   self.sp_model.Load(lowercase_)







 @property
 def 		__UpperCAmelCase				(		self				:   List[str])						->	Dict:


   """simple docstring"""







   return len(self.sp_model)







 def 		__UpperCAmelCase				(		self				:   List[str])						->	Union[str, Any]:


   """simple docstring"""







   _UpperCamelCase           =    {self.convert_ids_to_tokens(lowercase_): i for i in range(self.vocab_size)}
   vocab.update(self.added_tokens_encoder)
   return vocab







 def __getstate__(		self				:   Optional[int])						->	Any:


   """simple docstring"""







   _UpperCamelCase           =    self.__dict__.copy()
   _UpperCamelCase           =    None
   return state







 def __setstate__(		self				:   Tuple							, lowercase_				:   List[str])						->	Dict:


   """simple docstring"""







   _UpperCamelCase           =    d

   # for backward compatibility
   if not hasattr(self							, "sp_model_kwargs"):
     _UpperCamelCase           =    {}

   _UpperCamelCase           =    spm.SentencePieceProcessor(**self.sp_model_kwargs)
   self.sp_model.Load(self.vocab_file)







 def 		__UpperCAmelCase				(		self				:   str							, lowercase_				:   Optional[Any])						->	Tuple:


   """simple docstring"""







   if self.remove_space:
     _UpperCamelCase           =    " ".join(inputs.strip().split())
   else:
     _UpperCamelCase           =    inputs
   _UpperCamelCase           =    outputs.replace("``"							, "\"").replace("''"							, "\"")

   if not self.keep_accents:
     _UpperCamelCase           =    unicodedata.normalize("NFKD"							, lowercase_)
     _UpperCamelCase           =    "".join([c for c in outputs if not unicodedata.combining(lowercase_)])
   if self.do_lower_case:
     _UpperCamelCase           =    outputs.lower()

   return outputs







 def 		__UpperCAmelCase				(		self				:   str							, lowercase_				:   str)						->	List[str]:


   """simple docstring"""







   _UpperCamelCase           =    self.preprocess_text(lowercase_)
   _UpperCamelCase           =    self.sp_model.encode(lowercase_							, out_type=lowercase_)
   _UpperCamelCase           =    []
   for piece in pieces:
     if len(lowercase_) > 1 and piece[-1] == str(",") and piece[-2].isdigit():
       _UpperCamelCase           =    self.sp_model.EncodeAsPieces(piece[:-1].replace(lowercase_							, ""))
       if piece[0] != SPIECE_UNDERLINE and cur_pieces[0][0] == SPIECE_UNDERLINE:
         if len(cur_pieces[0]) == 1:
           _UpperCamelCase           =    cur_pieces[1:]
         else:
           _UpperCamelCase           =    cur_pieces[0][1:]
       cur_pieces.append(piece[-1])
       new_pieces.extend(lowercase_)
     else:
       new_pieces.append(lowercase_)

   return new_pieces







 def 		__UpperCAmelCase				(		self				:   Optional[Any]							, lowercase_				:   Tuple)						->	List[str]:


   """simple docstring"""







   return self.sp_model.PieceToId(lowercase_)







 def 		__UpperCAmelCase				(		self				:   Optional[Any]							, lowercase_				:   int)						->	Any:


   """simple docstring"""







   return self.sp_model.IdToPiece(lowercase_)







 def 		__UpperCAmelCase				(		self				:   Optional[int]							, lowercase_				:   Union[str, Any])						->	Tuple:


   """simple docstring"""







   _UpperCamelCase           =    "".join(lowercase_).replace(lowercase_							, " ").strip()
   return out_string







 def 		__UpperCAmelCase				(		self				:   Optional[Any]							, lowercase_				:   List[int]							, lowercase_				:   bool = False							, lowercase_				:   bool = None							, lowercase_				:   bool = True							, **lowercase_				:   int							, )						->	str:


   """simple docstring"""







   _UpperCamelCase           =    kwargs.pop("use_source_tokenizer"							, lowercase_)

   _UpperCamelCase           =    self.convert_ids_to_tokens(lowercase_							, skip_special_tokens=lowercase_)

   # To avoid mixing byte-level and unicode for byte-level BPT
   # we need to build string separately for added tokens and byte-level tokens
   # cf. https://github.com/huggingface/transformers/issues/1133
   _UpperCamelCase           =    []
   _UpperCamelCase           =    []
   for token in filtered_tokens:
     if skip_special_tokens and token in self.all_special_ids:
       continue
     if token in self.added_tokens_encoder:
       if current_sub_text:
         sub_texts.append(self.convert_tokens_to_string(lowercase_))
         _UpperCamelCase           =    []
       sub_texts.append(lowercase_)
     else:
       current_sub_text.append(lowercase_)
   if current_sub_text:
     sub_texts.append(self.convert_tokens_to_string(lowercase_))

   # Mimic the behavior of the Rust tokenizer:
   # By default, there are no spaces between special tokens
   _UpperCamelCase           =    "".join(lowercase_)

   _UpperCamelCase           =    (
       clean_up_tokenization_spaces
       if clean_up_tokenization_spaces is not None
       else self.clean_up_tokenization_spaces
   )
   if clean_up_tokenization_spaces:
     _UpperCamelCase           =    self.clean_up_tokenization(lowercase_)
     return clean_text
   else:
     return text







 def 		__UpperCAmelCase				(		self				:   str							, lowercase_				:   List[int]							, lowercase_				:   Optional[List[int]] = None)						->	List[int]:


   """simple docstring"""







   _UpperCamelCase           =    [self.sep_token_id]
   _UpperCamelCase           =    [self.cls_token_id]
   if token_ids_a is None:
     return token_ids_a + sep + cls
   return token_ids_a + sep + token_ids_a + sep + cls







 def 		__UpperCAmelCase				(		self				:   Tuple							, lowercase_				:   List[int]							, lowercase_				:   Optional[List[int]] = None							, lowercase_				:   bool = 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_)

   if token_ids_a is not None:
     return ([0] * len(lowercase_)) + [1] + ([0] * len(lowercase_)) + [1, 1]
   return ([0] * len(lowercase_)) + [1, 1]







 def 		__UpperCAmelCase				(		self				:   str							, lowercase_				:   List[int]							, lowercase_				:   Optional[List[int]] = None)						->	List[int]:


   """simple docstring"""







   _UpperCamelCase           =    [self.sep_token_id]
   _UpperCamelCase           =    [2]

   if token_ids_a is None:
     return len(token_ids_a + sep) * [0] + cls_segment_id
   return len(token_ids_a + sep) * [0] + len(token_ids_a + sep) * [1] + cls_segment_id







 def 		__UpperCAmelCase				(		self				:   Tuple							, lowercase_				:   str							, lowercase_				:   Optional[str] = None)						->	Tuple[str]:


   """simple docstring"""







   if not os.path.isdir(lowercase_):
     logger.error(f'Vocabulary path ({save_directory}) should be a directory')
     return
   _UpperCamelCase           =    os.path.join(
       lowercase_							, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"])

   if os.path.abspath(self.vocab_file) != os.path.abspath(lowercase_) and os.path.isfile(self.vocab_file):
     copyfile(self.vocab_file							, lowercase_)
   elif not os.path.isfile(self.vocab_file):
     with open(lowercase_							, "wb") as fi:
       _UpperCamelCase           =    self.sp_model.serialized_model_proto()
       fi.write(lowercase_)

   return (out_vocab_file,)




