

import importlib
import os
import platform
from pathlib import Path

from packaging import version

from .utils.logging import get_logger


_a	 =     get_logger(__name__)

# Datasets
_a	 =     '''https://s3.amazonaws.com/datasets.huggingface.co/datasets/datasets'''
_a	 =     '''https://cdn-datasets.huggingface.co/datasets/datasets'''
_a	 =     '''https://raw.githubusercontent.com/huggingface/datasets/{revision}/datasets/{path}/{name}'''

# Metrics
_a	 =     '''https://s3.amazonaws.com/datasets.huggingface.co/datasets/metrics'''
_a	 =     '''https://cdn-datasets.huggingface.co/datasets/metric'''
_a	 =     '''https://raw.githubusercontent.com/huggingface/datasets/{revision}/metrics/{path}/{name}'''

# Hub
_a	 =     os.environ.get('''HF_ENDPOINT''', '''https://huggingface.co''')
_a	 =     HF_ENDPOINT + '''/datasets/{repo_id}/resolve/{revision}/{path}'''
_a	 =     '''main'''

_a	 =     version.parse(platform.python_version())

if PY_VERSION < version.parse('''3.8'''):
  import importlib_metadata
else:
  import importlib.metadata as importlib_metadata

# General environment variables accepted values for booleans
_a	 =     {'''1''', '''ON''', '''YES''', '''TRUE'''}
_a	 =     ENV_VARS_TRUE_VALUES.union({'''AUTO'''})


# Imports
_a	 =     version.parse(importlib_metadata.version('''dill'''))
_a	 =     version.parse(importlib_metadata.version('''pandas'''))
_a	 =     version.parse(importlib_metadata.version('''pyarrow'''))

_a	 =     os.environ.get('''USE_TF''', '''AUTO''').upper()
_a	 =     os.environ.get('''USE_TORCH''', '''AUTO''').upper()
_a	 =     os.environ.get('''USE_JAX''', '''AUTO''').upper()

_a	 =     '''N/A'''
_a	 =     False

if USE_TORCH in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TF not in ENV_VARS_TRUE_VALUES:
  _a	 =     importlib.util.find_spec('''torch''') is not None
  if TORCH_AVAILABLE:
    try:
      _a	 =     version.parse(importlib_metadata.version('''torch'''))
      logger.info(f"PyTorch version {TORCH_VERSION} available.")
    except importlib_metadata.PackageNotFoundError:
      pass
else:
  logger.info('''Disabling PyTorch because USE_TF is set''')

_a	 =     '''N/A'''
_a	 =     False

if USE_TF in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TORCH not in ENV_VARS_TRUE_VALUES:
  _a	 =     importlib.util.find_spec('''tensorflow''') is not None
  if TF_AVAILABLE:
    # For the metadata, we have to look for both tensorflow and tensorflow-cpu
    for package in [
        "tensorflow",
        "tensorflow-cpu",
        "tensorflow-gpu",
        "tf-nightly",
        "tf-nightly-cpu",
        "tf-nightly-gpu",
        "intel-tensorflow",
        "tensorflow-rocm",
        "tensorflow-macos",
    ]:
      try:
        _a	 =     version.parse(importlib_metadata.version(package))
      except importlib_metadata.PackageNotFoundError:
        continue
      else:
        break
    else:
      _a	 =     False
  if TF_AVAILABLE:
    if TF_VERSION.major < 2:
      logger.info(f"TensorFlow found but with version {TF_VERSION}. `datasets` requires version 2 minimum.")
      _a	 =     False
    else:
      logger.info(f"TensorFlow version {TF_VERSION} available.")
else:
  logger.info('''Disabling Tensorflow because USE_TORCH is set''')


_a	 =     '''N/A'''
_a	 =     False

if USE_JAX in ENV_VARS_TRUE_AND_AUTO_VALUES:
  _a	 =     importlib.util.find_spec('''jax''') is not None and importlib.util.find_spec('''jaxlib''') is not None
  if JAX_AVAILABLE:
    try:
      _a	 =     version.parse(importlib_metadata.version('''jax'''))
      logger.info(f"JAX version {JAX_VERSION} available.")
    except importlib_metadata.PackageNotFoundError:
      pass
else:
  logger.info('''Disabling JAX because USE_JAX is set to False''')


_a	 =     os.environ.get('''USE_BEAM''', '''AUTO''').upper()
_a	 =     '''N/A'''
_a	 =     False
if USE_BEAM in ENV_VARS_TRUE_AND_AUTO_VALUES:
  try:
    _a	 =     version.parse(importlib_metadata.version('''apache_beam'''))
    _a	 =     True
    logger.info(f"Apache Beam version {BEAM_VERSION} available.")
  except importlib_metadata.PackageNotFoundError:
    pass
else:
  logger.info('''Disabling Apache Beam because USE_BEAM is set to False''')


# Optional tools for data loading
_a	 =     importlib.util.find_spec('''sqlalchemy''') is not None

# Optional tools for feature decoding
_a	 =     importlib.util.find_spec('''PIL''') is not None
_a	 =     importlib.util.find_spec('''soundfile''') is not None and version.parse(
    importlib.import_module('''soundfile''').__libsndfile_version__
) >= version.parse('''1.0.31''')
_a	 =     importlib.util.find_spec('''soundfile''') is not None and version.parse(
    importlib.import_module('''soundfile''').__libsndfile_version__
) >= version.parse('''1.1.0''')

# Optional compression tools
_a	 =     importlib.util.find_spec('''rarfile''') is not None
_a	 =     importlib.util.find_spec('''zstandard''') is not None
_a	 =     importlib.util.find_spec('''lz4''') is not None
_a	 =     importlib.util.find_spec('''py7zr''') is not None


# Cache location
_a	 =     '''~/.cache'''
_a	 =     os.getenv('''XDG_CACHE_HOME''', DEFAULT_XDG_CACHE_HOME)
_a	 =     os.path.join(XDG_CACHE_HOME, '''huggingface''')
_a	 =     os.path.expanduser(os.getenv('''HF_HOME''', DEFAULT_HF_CACHE_HOME))

_a	 =     os.path.join(HF_CACHE_HOME, '''datasets''')
_a	 =     Path(os.getenv('''HF_DATASETS_CACHE''', DEFAULT_HF_DATASETS_CACHE))

_a	 =     os.path.join(HF_CACHE_HOME, '''metrics''')
_a	 =     Path(os.getenv('''HF_METRICS_CACHE''', DEFAULT_HF_METRICS_CACHE))

_a	 =     os.path.join(HF_CACHE_HOME, '''modules''')
_a	 =     Path(os.getenv('''HF_MODULES_CACHE''', DEFAULT_HF_MODULES_CACHE))

_a	 =     '''downloads'''
_a	 =     os.path.join(HF_DATASETS_CACHE, DOWNLOADED_DATASETS_DIR)
_a	 =     Path(os.getenv('''HF_DATASETS_DOWNLOADED_DATASETS_PATH''', DEFAULT_DOWNLOADED_DATASETS_PATH))

_a	 =     '''extracted'''
_a	 =     os.path.join(DEFAULT_DOWNLOADED_DATASETS_PATH, EXTRACTED_DATASETS_DIR)
_a	 =     Path(os.getenv('''HF_DATASETS_EXTRACTED_DATASETS_PATH''', DEFAULT_EXTRACTED_DATASETS_PATH))

# Download count for the website
_a	 =     (
    os.environ.get('''HF_UPDATE_DOWNLOAD_COUNTS''', '''AUTO''').upper() in ENV_VARS_TRUE_AND_AUTO_VALUES
)

# Batch size constants. For more info, see:
# https://github.com/apache/arrow/blob/master/docs/source/cpp/arrays.rst#size-limitations-and-recommendations)
_a	 =     1_0_0_0

# Size of the preloaded record batch in `Dataset.__iter__`
_a	 =     1_0

# Pickling tables works only for small tables (<4GiB)
# For big tables, we write them on disk instead
_a	 =     4 << 3_0

# Max shard size in bytes (e.g. to shard parquet datasets in push_to_hub or download_and_prepare)
_a	 =     '''500MB'''

# Parquet configuration
_a	 =     1_0_0
_a	 =     1_0_0
_a	 =     1_0_0

# Offline mode
_a	 =     os.environ.get('''HF_DATASETS_OFFLINE''', '''AUTO''').upper() in ENV_VARS_TRUE_VALUES

# In-memory
_a	 =     0  # Disabled
_a	 =     float(os.environ.get('''HF_DATASETS_IN_MEMORY_MAX_SIZE''', DEFAULT_IN_MEMORY_MAX_SIZE))

# File names
_a	 =     '''dataset.arrow'''
_a	 =     '''indices.arrow'''
_a	 =     '''state.json'''
_a	 =     '''dataset_info.json'''
_a	 =     '''dataset_infos.json'''
_a	 =     '''LICENSE'''
_a	 =     '''metric_info.json'''
_a	 =     '''dataset_dict.json'''

_a	 =     '''datasets_modules'''

_a	 =     2_5_5

# Streaming
_a	 =     2_0
_a	 =     5

# Datasets without script
_a	 =     2_0_0
_a	 =     1_0
_a	 =     2_0_0

# Progress bars
_a	 =     0.05  # 20 progress updates per sec








from collections import Counter

import sacrebleu
import sacremoses
from packaging import version

import datasets


_a	 =     '''\
@inproceedings{xu-etal-2016-optimizing,
title = {Optimizing Statistical Machine Translation for Text Simplification},
authors={Xu, Wei and Napoles, Courtney and Pavlick, Ellie and Chen, Quanze and Callison-Burch, Chris},
journal = {Transactions of the Association for Computational Linguistics},
volume = {4},
year={2016},
url = {https://www.aclweb.org/anthology/Q16-1029},
pages = {401--415},
}
'''

_a	 =     '''\
SARI is a metric used for evaluating automatic text simplification systems.
The metric compares the predicted simplified sentences against the reference
and the source sentences. It explicitly measures the goodness of words that are
added, deleted and kept by the system.
Sari = (F1_add + F1_keep + P_del) / 3
where
F1_add: n-gram F1 score for add operation
F1_keep: n-gram F1 score for keep operation
P_del: n-gram precision score for delete operation
n = 4, as in the original paper.

This implementation is adapted from Tensorflow\'s tensor2tensor implementation [3].
It has two differences with the original GitHub [1] implementation:
  (1) Defines 0/0=1 instead of 0 to give higher scores for predictions that match
      a target exactly.
  (2) Fixes an alleged bug [2] in the keep score computation.
[1] https://github.com/cocoxu/simplification/blob/master/SARI.py
    (commit 0210f15)
[2] https://github.com/cocoxu/simplification/issues/6
[3] https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/utils/sari_hook.py
'''


_a	 =     '''
Calculates sari score (between 0 and 100) given a list of source and predicted
sentences, and a list of lists of reference sentences.
Args:
    sources: list of source sentences where each sentence should be a string.
    predictions: list of predicted sentences where each sentence should be a string.
    references: list of lists of reference sentences where each sentence should be a string.
Returns:
    sari: sari score
Examples:
    >>> sources=["About 95 species are currently accepted ."]
    >>> predictions=["About 95 you now get in ."]
    >>> references=[["About 95 species are currently known .","About 95 species are now accepted .","95 species are now accepted ."]]
    >>> sari = datasets.load_metric("sari")
    >>> results = sari.compute(sources=sources, predictions=predictions, references=references)
    >>> print(results)
    {\'sari\': 26.953601953601954}
'''







def _a				( SCREAMING_SNAKE_CASE	:    Dict					,      SCREAMING_SNAKE_CASE	:    Optional[Any]					,      SCREAMING_SNAKE_CASE	:    Tuple					,      SCREAMING_SNAKE_CASE	:    Optional[Any]	)					->					Dict:

 """simple docstring"""






 __lowerCAmelCase:     str     			=   [rgram for rgrams in rgramslist for rgram in rgrams]
 __lowerCAmelCase:     List[Any]     			=   Counter(SCREAMING_SNAKE_CASE	)

 __lowerCAmelCase:     List[str]     			=   Counter(SCREAMING_SNAKE_CASE	)
 __lowerCAmelCase:     int     			=   Counter()
 for sgram, scount in sgramcounter.items():
  __lowerCAmelCase:     Optional[int]     			=   scount * numref

 __lowerCAmelCase:     Optional[Any]     			=   Counter(SCREAMING_SNAKE_CASE	)
 __lowerCAmelCase:     Optional[Any]     			=   Counter()
 for cgram, ccount in cgramcounter.items():
  __lowerCAmelCase:     Tuple     			=   ccount * numref

 # KEEP
 __lowerCAmelCase:     int     			=   sgramcounter_rep & cgramcounter_rep
 __lowerCAmelCase:     Union[str, Any]     			=   keepgramcounter_rep & rgramcounter
 __lowerCAmelCase:     Optional[int]     			=   sgramcounter_rep & rgramcounter

 __lowerCAmelCase:     Union[str, Any]     			=   0
 __lowerCAmelCase:     Any     			=   0
 for keepgram in keepgramcountergood_rep:
  keeptmpscorea += keepgramcountergood_rep[keepgram] / keepgramcounter_rep[keepgram]
  # Fix an alleged bug [2] in the keep score computation.
  # keeptmpscore2 += keepgramcountergood_rep[keepgram] / keepgramcounterall_rep[keepgram]
  keeptmpscorea += keepgramcountergood_rep[keepgram]
 # Define 0/0=1 instead of 0 to give higher scores for predictions that match
 #      a target exactly.
 __lowerCAmelCase:     Tuple     			=   1
 __lowerCAmelCase:     List[Any]     			=   1
 if len(SCREAMING_SNAKE_CASE	) > 0:
  __lowerCAmelCase:     Tuple     			=   keeptmpscorea / len(SCREAMING_SNAKE_CASE	)
 if len(SCREAMING_SNAKE_CASE	) > 0:
  # Fix an alleged bug [2] in the keep score computation.
  # keepscore_recall = keeptmpscore2 / len(keepgramcounterall_rep)
  __lowerCAmelCase:     str     			=   keeptmpscorea / sum(keepgramcounterall_rep.values()	)
 __lowerCAmelCase:     List[str]     			=   0
 if keepscore_precision > 0 or keepscore_recall > 0:
  __lowerCAmelCase:     List[Any]     			=   2 * keepscore_precision * keepscore_recall / (keepscore_precision + keepscore_recall)

 # DELETION
 __lowerCAmelCase:     List[Any]     			=   sgramcounter_rep - cgramcounter_rep
 __lowerCAmelCase:     Optional[Any]     			=   delgramcounter_rep - rgramcounter
 __lowerCAmelCase:     str     			=   sgramcounter_rep - rgramcounter
 __lowerCAmelCase:     int     			=   0
 __lowerCAmelCase:     Optional[int]     			=   0
 for delgram in delgramcountergood_rep:
  deltmpscorea += delgramcountergood_rep[delgram] / delgramcounter_rep[delgram]
  deltmpscorea += delgramcountergood_rep[delgram] / delgramcounterall_rep[delgram]
 # Define 0/0=1 instead of 0 to give higher scores for predictions that match
 # a target exactly.
 __lowerCAmelCase:     List[str]     			=   1
 if len(SCREAMING_SNAKE_CASE	) > 0:
  __lowerCAmelCase:     List[Any]     			=   deltmpscorea / len(SCREAMING_SNAKE_CASE	)

 # ADDITION
 __lowerCAmelCase:     Optional[Any]     			=   set(SCREAMING_SNAKE_CASE	) - set(SCREAMING_SNAKE_CASE	)
 __lowerCAmelCase:     int     			=   set(SCREAMING_SNAKE_CASE	) & set(SCREAMING_SNAKE_CASE	)
 __lowerCAmelCase:     Tuple     			=   set(SCREAMING_SNAKE_CASE	) - set(SCREAMING_SNAKE_CASE	)

 __lowerCAmelCase:     Union[str, Any]     			=   0
 for addgram in addgramcountergood:
  addtmpscore += 1

 # Define 0/0=1 instead of 0 to give higher scores for predictions that match
 # a target exactly.
 __lowerCAmelCase:     Optional[Any]     			=   1
 __lowerCAmelCase:     Union[str, Any]     			=   1
 if len(SCREAMING_SNAKE_CASE	) > 0:
  __lowerCAmelCase:     int     			=   addtmpscore / len(SCREAMING_SNAKE_CASE	)
 if len(SCREAMING_SNAKE_CASE	) > 0:
  __lowerCAmelCase:     str     			=   addtmpscore / len(SCREAMING_SNAKE_CASE	)
 __lowerCAmelCase:     Dict     			=   0
 if addscore_precision > 0 or addscore_recall > 0:
  __lowerCAmelCase:     str     			=   2 * addscore_precision * addscore_recall / (addscore_precision + addscore_recall)

 return (keepscore, delscore_precision, addscore)







def _a				( SCREAMING_SNAKE_CASE	:    Optional[int]					,      SCREAMING_SNAKE_CASE	:    List[Any]					,      SCREAMING_SNAKE_CASE	:    Optional[Any]	)					->					List[str]:

 """simple docstring"""






 __lowerCAmelCase:     List[Any]     			=   len(SCREAMING_SNAKE_CASE	)

 __lowerCAmelCase:     int     			=   ssent.split(' '	)
 __lowerCAmelCase:     List[str]     			=   csent.split(' '	)
 __lowerCAmelCase:     Dict     			=   []
 __lowerCAmelCase:     Any     			=   []
 __lowerCAmelCase:     Optional[int]     			=   []
 __lowerCAmelCase:     str     			=   []
 __lowerCAmelCase:     Dict     			=   []
 __lowerCAmelCase:     str     			=   []

 __lowerCAmelCase:     str     			=   []
 __lowerCAmelCase:     Dict     			=   []
 __lowerCAmelCase:     Dict     			=   []
 __lowerCAmelCase:     Optional[Any]     			=   []
 for rsent in rsents:
  __lowerCAmelCase:     List[Any]     			=   rsent.split(' '	)
  __lowerCAmelCase:     Optional[int]     			=   []
  __lowerCAmelCase:     List[str]     			=   []
  __lowerCAmelCase:     Optional[int]     			=   []
  ragramslist.append(SCREAMING_SNAKE_CASE	)
  for i in range(0					,      len(SCREAMING_SNAKE_CASE	) - 1	):
   if i < len(SCREAMING_SNAKE_CASE	) - 1:
    __lowerCAmelCase:     List[str]     			=   ragrams[i] + ' ' + ragrams[i + 1]
    ragrams.append(SCREAMING_SNAKE_CASE	)
   if i < len(SCREAMING_SNAKE_CASE	) - 2:
    __lowerCAmelCase:     Union[str, Any]     			=   ragrams[i] + ' ' + ragrams[i + 1] + ' ' + ragrams[i + 2]
    ragrams.append(SCREAMING_SNAKE_CASE	)
   if i < len(SCREAMING_SNAKE_CASE	) - 3:
    __lowerCAmelCase:     Optional[int]     			=   ragrams[i] + ' ' + ragrams[i + 1] + ' ' + ragrams[i + 2] + ' ' + ragrams[i + 3]
    ragrams.append(SCREAMING_SNAKE_CASE	)
  ragramslist.append(SCREAMING_SNAKE_CASE	)
  ragramslist.append(SCREAMING_SNAKE_CASE	)
  ragramslist.append(SCREAMING_SNAKE_CASE	)

 for i in range(0					,      len(SCREAMING_SNAKE_CASE	) - 1	):
  if i < len(SCREAMING_SNAKE_CASE	) - 1:
   __lowerCAmelCase:     Optional[int]     			=   sagrams[i] + ' ' + sagrams[i + 1]
   sagrams.append(SCREAMING_SNAKE_CASE	)
  if i < len(SCREAMING_SNAKE_CASE	) - 2:
   __lowerCAmelCase:     Any     			=   sagrams[i] + ' ' + sagrams[i + 1] + ' ' + sagrams[i + 2]
   sagrams.append(SCREAMING_SNAKE_CASE	)
  if i < len(SCREAMING_SNAKE_CASE	) - 3:
   __lowerCAmelCase:     Optional[int]     			=   sagrams[i] + ' ' + sagrams[i + 1] + ' ' + sagrams[i + 2] + ' ' + sagrams[i + 3]
   sagrams.append(SCREAMING_SNAKE_CASE	)

 for i in range(0					,      len(SCREAMING_SNAKE_CASE	) - 1	):
  if i < len(SCREAMING_SNAKE_CASE	) - 1:
   __lowerCAmelCase:     Optional[int]     			=   cagrams[i] + ' ' + cagrams[i + 1]
   cagrams.append(SCREAMING_SNAKE_CASE	)
  if i < len(SCREAMING_SNAKE_CASE	) - 2:
   __lowerCAmelCase:     str     			=   cagrams[i] + ' ' + cagrams[i + 1] + ' ' + cagrams[i + 2]
   cagrams.append(SCREAMING_SNAKE_CASE	)
  if i < len(SCREAMING_SNAKE_CASE	) - 3:
   __lowerCAmelCase:     str     			=   cagrams[i] + ' ' + cagrams[i + 1] + ' ' + cagrams[i + 2] + ' ' + cagrams[i + 3]
   cagrams.append(SCREAMING_SNAKE_CASE	)

 ((__lowerCAmelCase)			,							(__lowerCAmelCase)			,							(__lowerCAmelCase)):     Union[str, Any]     			=   SARIngram(SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE	)
 ((__lowerCAmelCase)			,							(__lowerCAmelCase)			,							(__lowerCAmelCase)):     str     			=   SARIngram(SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE	)
 ((__lowerCAmelCase)			,							(__lowerCAmelCase)			,							(__lowerCAmelCase)):     Union[str, Any]     			=   SARIngram(SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE	)
 ((__lowerCAmelCase)			,							(__lowerCAmelCase)			,							(__lowerCAmelCase)):     Tuple     			=   SARIngram(SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE					,      SCREAMING_SNAKE_CASE	)
 __lowerCAmelCase:     List[Any]     			=   sum([keepascore, keepascore, keepascore, keepascore]	) / 4
 __lowerCAmelCase:     Any     			=   sum([delascore, delascore, delascore, delascore]	) / 4
 __lowerCAmelCase:     Any     			=   sum([addascore, addascore, addascore, addascore]	) / 4
 __lowerCAmelCase:     List[Any]     			=   (avgkeepscore + avgdelscore + avgaddscore) / 3
 return finalscore







def _a				( SCREAMING_SNAKE_CASE	:    int					,      SCREAMING_SNAKE_CASE	:    bool = True					,      SCREAMING_SNAKE_CASE	:    str = "13a"					,      SCREAMING_SNAKE_CASE	:    bool = True	)					->					Optional[Any]:

 """simple docstring"""






 if lowercase:
  __lowerCAmelCase:     str     			=   sentence.lower()

 if tokenizer in ["13a", "intl"]:
  if version.parse(sacrebleu.__version__	).major >= 2:
   __lowerCAmelCase:     Dict     			=   sacrebleu.metrics.bleu._get_tokenizer(SCREAMING_SNAKE_CASE	)()(SCREAMING_SNAKE_CASE	)
  else:
   __lowerCAmelCase:     str     			=   sacrebleu.TOKENIZERS[tokenizer]()(SCREAMING_SNAKE_CASE	)
 elif tokenizer == "moses":
  __lowerCAmelCase:     Optional[int]     			=   sacremoses.MosesTokenizer().tokenize(SCREAMING_SNAKE_CASE					,      return_str=SCREAMING_SNAKE_CASE					,      escape=SCREAMING_SNAKE_CASE	)
 elif tokenizer == "penn":
  __lowerCAmelCase:     List[str]     			=   sacremoses.MosesTokenizer().penn_tokenize(SCREAMING_SNAKE_CASE					,      return_str=SCREAMING_SNAKE_CASE	)
 else:
  __lowerCAmelCase:     Any     			=   sentence

 if not return_str:
  __lowerCAmelCase:     List[Any]     			=   normalized_sent.split()

 return normalized_sent






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


     def 						UpperCAmelCase						(							self    :	int      )							->			Tuple:
      return datasets.MetricInfo(
          description=_DESCRIPTION    ,						citation=_CITATION    ,						inputs_description=_KWARGS_DESCRIPTION    ,						features=datasets.Features(
              {
                  'sources': datasets.Value('string'    ,						id='sequence'      ),
                  'predictions': datasets.Value('string'    ,						id='sequence'      ),
                  'references': datasets.Sequence(datasets.Value('string'    ,						id='sequence'      )    ,						id='references'      ),
              }      )    ,						codebase_urls=[
              'https://github.com/cocoxu/simplification/blob/master/SARI.py',
              'https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/utils/sari_hook.py',
          ]    ,						reference_urls=['https://www.aclweb.org/anthology/Q16-1029.pdf']    ,						)


     def 						UpperCAmelCase						(							self    :	Any    ,						UpperCAmelCase    :	List[Any]    ,						UpperCAmelCase    :	List[str]    ,						UpperCAmelCase    :	int      )							->			Optional[Any]:
      if not (len(UpperCAmelCase      ) == len(UpperCAmelCase      ) == len(UpperCAmelCase      )):
       raise ValueError('Sources length must match predictions and references lengths.'      )
      __lowerCAmelCase:     Optional[int]     			=   0
      for src, pred, refs in zip(UpperCAmelCase    ,						UpperCAmelCase    ,						UpperCAmelCase      ):
       sari_score += SARIsent(normalize(UpperCAmelCase      )    ,						normalize(UpperCAmelCase      )    ,						[normalize(UpperCAmelCase      ) for sent in refs]      )
      __lowerCAmelCase:     int     			=   sari_score / len(UpperCAmelCase      )
      return {"sari": 1_0_0 * sari_score}





