





"""simple docstring"""




import re
import string
from collections import Counter

import sacrebleu
import sacremoses
from packaging import version

import datasets


UpperCamelCase_									="""
@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
},
@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\",
}
"""

UpperCamelCase_									="""\
WIKI_SPLIT is the combination of three metrics SARI, EXACT and SACREBLEU
It can be used to evaluate the quality of machine-generated texts.
"""


UpperCamelCase_									="""
Calculates sari score (between 0 and 100) given a list of source and predicted
sentences, and a list of lists of reference sentences. It also computes the BLEU score as well as the exact match score.
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
    sacrebleu: sacrebleu score
    exact: exact score

Examples:
    >>> sources=[\"About 95 species are currently accepted .\"]
    >>> predictions=[\"About 95 you now get in .\"]
    >>> references=[[\"About 95 species are currently known .\"]]
    >>> wiki_split = datasets.load_metric(\"wiki_split\")
    >>> results = wiki_split.compute(sources=sources, predictions=predictions, references=references)
    >>> print(results)
    {'sari': 21.805555555555557, 'sacrebleu': 14.535768424205482, 'exact': 0.0}
"""





def 	a_    (							_lowercase       ):

						def remove_articles(_lowercase       ):
												_UpperCamelCase      : Dict         =   re.compile(R'''\b(a|an|the)\b'''	,						re.UNICODE       )
												return re.sub(_lowercase	,						''' '''	,						_lowercase       )

						def white_space_fix(_lowercase       ):
												return " ".join(text.split()       )

						def remove_punc(_lowercase       ):
												_UpperCamelCase      : Optional[Any]         =   set(string.punctuation       )
												return "".join(ch for ch in text if ch not in exclude       )

						def lower(_lowercase       ):
												return text.lower()

						return white_space_fix(remove_articles(remove_punc(lower(_lowercase       )       )       )       )





def 	a_    (							_lowercase	,						_lowercase       ):
						return int(normalize_answer(_lowercase       ) == normalize_answer(_lowercase       )       )





def 	a_    (							_lowercase	,						_lowercase       ):
						_UpperCamelCase      : Optional[int]         =   [any(compute_exact(_lowercase	,						_lowercase       ) for ref in refs       ) for pred, refs in zip(_lowercase	,						_lowercase       )]
						return (sum(_lowercase       ) / len(_lowercase       )) * 100





def 	a_    (							_lowercase	,						_lowercase	,						_lowercase	,						_lowercase       ):
						_UpperCamelCase      : List[str]         =   [rgram for rgrams in rgramslist for rgram in rgrams]
						_UpperCamelCase      : Any         =   Counter(_lowercase       )

						_UpperCamelCase      : Tuple         =   Counter(_lowercase       )
						_UpperCamelCase      : List[str]         =   Counter()
						for sgram, scount in sgramcounter.items():
												_UpperCamelCase      : Dict         =   scount * numref

						_UpperCamelCase      : int         =   Counter(_lowercase       )
						_UpperCamelCase      : Any         =   Counter()
						for cgram, ccount in cgramcounter.items():
												_UpperCamelCase      : List[Any]         =   ccount * numref

						# KEEP
						_UpperCamelCase      : List[str]         =   sgramcounter_rep & cgramcounter_rep
						_UpperCamelCase      : Tuple         =   keepgramcounter_rep & rgramcounter
						_UpperCamelCase      : Optional[Any]         =   sgramcounter_rep & rgramcounter

						_UpperCamelCase      : List[str]         =   0
						_UpperCamelCase      : Optional[int]         =   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.
						_UpperCamelCase      : Tuple         =   1
						_UpperCamelCase      : int         =   1
						if len(_lowercase       ) > 0:
												_UpperCamelCase      : Dict         =   keeptmpscorea / len(_lowercase       )
						if len(_lowercase       ) > 0:
												# Fix an alleged bug [2] in the keep score computation.
												# keepscore_recall = keeptmpscore2 / len(keepgramcounterall_rep)
												_UpperCamelCase      : Optional[Any]         =   keeptmpscorea / sum(keepgramcounterall_rep.values()       )
						_UpperCamelCase      : Union[str, Any]         =   0
						if keepscore_precision > 0 or keepscore_recall > 0:
												_UpperCamelCase      : str         =   2 * keepscore_precision * keepscore_recall / (keepscore_precision + keepscore_recall)

						# DELETION
						_UpperCamelCase      : int         =   sgramcounter_rep - cgramcounter_rep
						_UpperCamelCase      : Union[str, Any]         =   delgramcounter_rep - rgramcounter
						_UpperCamelCase      : int         =   sgramcounter_rep - rgramcounter
						_UpperCamelCase      : Tuple         =   0
						_UpperCamelCase      : Optional[Any]         =   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.
						_UpperCamelCase      : Union[str, Any]         =   1
						if len(_lowercase       ) > 0:
												_UpperCamelCase      : Tuple         =   deltmpscorea / len(_lowercase       )

						# ADDITION
						_UpperCamelCase      : Union[str, Any]         =   set(_lowercase       ) - set(_lowercase       )
						_UpperCamelCase      : int         =   set(_lowercase       ) & set(_lowercase       )
						_UpperCamelCase      : Dict         =   set(_lowercase       ) - set(_lowercase       )

						_UpperCamelCase      : Dict         =   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.
						_UpperCamelCase      : List[Any]         =   1
						_UpperCamelCase      : Dict         =   1
						if len(_lowercase       ) > 0:
												_UpperCamelCase      : List[str]         =   addtmpscore / len(_lowercase       )
						if len(_lowercase       ) > 0:
												_UpperCamelCase      : List[str]         =   addtmpscore / len(_lowercase       )
						_UpperCamelCase      : Dict         =   0
						if addscore_precision > 0 or addscore_recall > 0:
												_UpperCamelCase      : Optional[int]         =   2 * addscore_precision * addscore_recall / (addscore_precision + addscore_recall)

						return (keepscore, delscore_precision, addscore)





def 	a_    (							_lowercase	,						_lowercase	,						_lowercase       ):
						_UpperCamelCase      : Optional[Any]         =   len(_lowercase       )

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

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

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

						for i in range(0	,						len(_lowercase       ) - 1       ):
												if i < len(_lowercase       ) - 1:
																		_UpperCamelCase      : Tuple         =   cagrams[i] + ''' ''' + cagrams[i + 1]
																		cagrams.append(_lowercase       )
												if i < len(_lowercase       ) - 2:
																		_UpperCamelCase      : List[Any]         =   cagrams[i] + ''' ''' + cagrams[i + 1] + ''' ''' + cagrams[i + 2]
																		cagrams.append(_lowercase       )
												if i < len(_lowercase       ) - 3:
																		_UpperCamelCase      : str         =   cagrams[i] + ''' ''' + cagrams[i + 1] + ''' ''' + cagrams[i + 2] + ''' ''' + cagrams[i + 3]
																		cagrams.append(_lowercase       )

						(_UpperCamelCase)      : str         =   SARIngram(_lowercase	,						_lowercase	,						_lowercase	,						_lowercase       )
						(_UpperCamelCase)      : Optional[Any]         =   SARIngram(_lowercase	,						_lowercase	,						_lowercase	,						_lowercase       )
						(_UpperCamelCase)      : int         =   SARIngram(_lowercase	,						_lowercase	,						_lowercase	,						_lowercase       )
						(_UpperCamelCase)      : Any         =   SARIngram(_lowercase	,						_lowercase	,						_lowercase	,						_lowercase       )
						_UpperCamelCase      : List[str]         =   sum([keepascore, keepascore, keepascore, keepascore]       ) / 4
						_UpperCamelCase      : str         =   sum([delascore, delascore, delascore, delascore]       ) / 4
						_UpperCamelCase      : Any         =   sum([addascore, addascore, addascore, addascore]       ) / 4
						_UpperCamelCase      : Optional[int]         =   (avgkeepscore + avgdelscore + avgaddscore) / 3
						return finalscore





def 	a_    (							_lowercase	,						_lowercase = True	,						_lowercase = "13a"	,						_lowercase = True       ):
						# Normalization is requried for the ASSET dataset (one of the primary
						# datasets in sentence simplification) to allow using space
						# to split the sentence. Even though Wiki-Auto and TURK datasets,
						# do not require normalization, we do it for consistency.
						# Code adapted from the EASSE library [1] written by the authors of the ASSET dataset.
						# [1] https://github.com/feralvam/easse/blob/580bba7e1378fc8289c663f864e0487188fe8067/easse/utils/preprocessing.py#L7

						if lowercase:
												_UpperCamelCase      : int         =   sentence.lower()

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

						if not return_str:
												_UpperCamelCase      : str         =   normalized_sent.split()

						return normalized_sent





def 	a_    (							_lowercase	,						_lowercase	,						_lowercase       ):
						if not (len(_lowercase       ) == len(_lowercase       ) == len(_lowercase       )):
												raise ValueError('''Sources length must match predictions and references lengths.'''       )
						_UpperCamelCase      : Any         =   0
						for src, pred, refs in zip(_lowercase	,						_lowercase	,						_lowercase       ):
												sari_score += SARIsent(normalize(_lowercase       )	,						normalize(_lowercase       )	,						[normalize(_lowercase       ) for sent in refs]       )
						_UpperCamelCase      : Any         =   sari_score / len(_lowercase       )
						return 100 * sari_score





def 	a_    (							_lowercase	,						_lowercase	,						_lowercase="exp"	,						_lowercase=None	,						_lowercase=False	,						_lowercase=False	,						_lowercase=False	,						):
						_UpperCamelCase      : Any         =   len(references[0]       )
						if any(len(_lowercase       ) != references_per_prediction for refs in references       ):
												raise ValueError('''Sacrebleu requires the same number of references for each prediction'''       )
						_UpperCamelCase      : Any         =   [[refs[i] for refs in references] for i in range(_lowercase       )]
						_UpperCamelCase      : int         =   sacrebleu.corpus_bleu(
						    _lowercase	,						_lowercase	,						smooth_method=_lowercase	,						smooth_value=_lowercase	,						force=_lowercase	,						lowercase=_lowercase	,						use_effective_order=_lowercase	,						)
						return output.score






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






				def     snake_case     (			self		:   Tuple							)     ->				List[str]:




										'''simple docstring'''



										return datasets.MetricInfo(
										    description=_DESCRIPTION,			citation=_CITATION,			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/huggingface/transformers/blob/master/src/transformers/data/metrics/squad_metrics.py''',
										        '''https://github.com/cocoxu/simplification/blob/master/SARI.py''',
										        '''https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/utils/sari_hook.py''',
										        '''https://github.com/mjpost/sacreBLEU''',
										    ],			reference_urls=[
										        '''https://www.aclweb.org/anthology/Q16-1029.pdf''',
										        '''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		:   Dict,			lowerCAmelCase__		:   int,			lowerCAmelCase__		:   Any,			lowerCAmelCase__		:   Dict							)     ->				Any:




										'''simple docstring'''



										_UpperCamelCase      : Tuple         =   {}
										result.update({'''sari''': compute_sari(sources=lowerCAmelCase__,			predictions=lowerCAmelCase__,			references=lowerCAmelCase__							)}							)
										result.update({'''sacrebleu''': compute_sacrebleu(predictions=lowerCAmelCase__,			references=lowerCAmelCase__							)}							)
										result.update({'''exact''': compute_em(predictions=lowerCAmelCase__,			references=lowerCAmelCase__							)}							)
										return result










"""simple docstring"""




class 			_a						:






				def __init__(			self		:   Optional[int],			lowerCAmelCase__		:   list							)     ->				None:




										'''simple docstring'''



										_UpperCamelCase      : Optional[int]         =   set_counts
										_UpperCamelCase      : Any         =   max(lowerCAmelCase__							)
										_UpperCamelCase      : int         =   len(lowerCAmelCase__							)
										_UpperCamelCase      : int         =   [1] * num_sets
										_UpperCamelCase      : List[Any]         =   list(range(lowerCAmelCase__							)							)






				def     snake_case     (			self		:   int,			lowerCAmelCase__		:   int,			lowerCAmelCase__		:   int							)     ->				bool:




										'''simple docstring'''



										_UpperCamelCase      : Optional[Any]         =   self.get_parent(lowerCAmelCase__							)
										_UpperCamelCase      : Any         =   self.get_parent(lowerCAmelCase__							)

										if src_parent == dst_parent:
																return False

										if self.ranks[dst_parent] >= self.ranks[src_parent]:
																self.set_counts[dst_parent] += self.set_counts[src_parent]
																_UpperCamelCase      : List[Any]         =   0
																_UpperCamelCase      : str         =   dst_parent
																if self.ranks[dst_parent] == self.ranks[src_parent]:
																						self.ranks[dst_parent] += 1
																_UpperCamelCase      : Union[str, Any]         =   self.set_counts[dst_parent]
										else:
																self.set_counts[src_parent] += self.set_counts[dst_parent]
																_UpperCamelCase      : Tuple         =   0
																_UpperCamelCase      : Optional[Any]         =   src_parent
																_UpperCamelCase      : int         =   self.set_counts[src_parent]

										_UpperCamelCase      : Optional[Any]         =   max(self.max_set,			lowerCAmelCase__							)
										return True






				def     snake_case     (			self		:   Optional[Any],			lowerCAmelCase__		:   int							)     ->				int:




										'''simple docstring'''



										if self.parents[disj_set] == disj_set:
																return disj_set
										_UpperCamelCase      : Union[str, Any]         =   self.get_parent(self.parents[disj_set]							)
										return self.parents[disj_set]



