






def 					lowercase__				(					__snake_case   :							int  ):


					'''simple docstring'''


					if number < 0:
										raise ValueError('number must not be negative'  )
					return number & (number - 1) == 0


if __name__ == "__main__":
		import doctest

		doctest.testmod()














import re
import string
from collections import Counter

import sacrebleu
import sacremoses
from packaging import version

import datasets


__UpperCAmelCase     							=						'\n@inproceedings{xu-etal-2016-optimizing,\n    title = {Optimizing Statistical Machine Translation for Text Simplification},\n    authors={Xu, Wei and Napoles, Courtney and Pavlick, Ellie and Chen, Quanze and Callison-Burch, Chris},\n    journal = {Transactions of the Association for Computational Linguistics},\n    volume = {4},\n    year={2016},\n    url = {https://www.aclweb.org/anthology/Q16-1029},\n    pages = {401--415\n},\n@inproceedings{post-2018-call,\n    title = "A Call for Clarity in Reporting {BLEU} Scores",\n    author = "Post, Matt",\n    booktitle = "Proceedings of the Third Conference on Machine Translation: Research Papers",\n    month = oct,\n    year = "2018",\n    address = "Belgium, Brussels",\n    publisher = "Association for Computational Linguistics",\n    url = "https://www.aclweb.org/anthology/W18-6319",\n    pages = "186--191",\n}\n'

__UpperCAmelCase     							=						'\\nWIKI_SPLIT is the combination of three metrics SARI, EXACT and SACREBLEU\nIt can be used to evaluate the quality of machine-generated texts.\n'


__UpperCAmelCase     							=						'\nCalculates sari score (between 0 and 100) given a list of source and predicted\nsentences, and a list of lists of reference sentences. It also computes the BLEU score as well as the exact match score.\nArgs:\n    sources: list of source sentences where each sentence should be a string.\n    predictions: list of predicted sentences where each sentence should be a string.\n    references: list of lists of reference sentences where each sentence should be a string.\nReturns:\n    sari: sari score\n    sacrebleu: sacrebleu score\n    exact: exact score\n\nExamples:\n    >>> sources=["About 95 species are currently accepted ."]\n    >>> predictions=["About 95 you now get in ."]\n    >>> references=[["About 95 species are currently known ."]]\n    >>> wiki_split = datasets.load_metric("wiki_split")\n    >>> results = wiki_split.compute(sources=sources, predictions=predictions, references=references)\n    >>> print(results)\n    {\'sari\': 21.805555555555557, \'sacrebleu\': 14.535768424205482, \'exact\': 0.0}\n'




def 					lowercase__				(					__snake_case   :							Optional[int]  ):


					'''simple docstring'''


					def remove_articles(__snake_case   :							Tuple  ):
										UpperCAmelCase_   :				Optional[int]						=						re.compile(R'\b(a|an|the)\b'					,	re.UNICODE  )
										return re.sub(__snake_case					,	' '					,	__snake_case  )

					def white_space_fix(__snake_case   :							int  ):
										return " ".join(text.split()  )

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

					def lower(__snake_case   :							List[str]  ):
										return text.lower()

					return white_space_fix(remove_articles(remove_punc(lower(__snake_case  )  )  )  )




def 					lowercase__				(					__snake_case   :							List[str]					,	__snake_case   :							List[Any]  ):


					'''simple docstring'''


					return int(normalize_answer(__snake_case  ) == normalize_answer(__snake_case  )  )




def 					lowercase__				(					__snake_case   :							Optional[Any]					,	__snake_case   :							Tuple  ):


					'''simple docstring'''


					UpperCAmelCase_   :				Tuple						=						[any(compute_exact(__snake_case					,	__snake_case  ) for ref in refs  ) for pred, refs in zip(__snake_case					,	__snake_case  )]
					return (sum(__snake_case  ) / len(__snake_case  )) * 100




def 					lowercase__				(					__snake_case   :							Optional[Any]					,	__snake_case   :							Any					,	__snake_case   :							Optional[int]					,	__snake_case   :							Optional[Any]  ):


					'''simple docstring'''


					UpperCAmelCase_   :				str						=						[rgram for rgrams in rgramslist for rgram in rgrams]
					UpperCAmelCase_   :				str						=						Counter(__snake_case  )

					UpperCAmelCase_   :				List[Any]						=						Counter(__snake_case  )
					UpperCAmelCase_   :				int						=						Counter()
					for sgram, scount in sgramcounter.items():
										UpperCAmelCase_   :				Any						=						scount * numref

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

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

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

					# DELETION
					UpperCAmelCase_   :				Optional[int]						=						sgramcounter_rep - cgramcounter_rep
					UpperCAmelCase_   :				Dict						=						delgramcounter_rep - rgramcounter
					UpperCAmelCase_   :				Optional[Any]						=						sgramcounter_rep - rgramcounter
					UpperCAmelCase_   :				str						=						0
					UpperCAmelCase_   :				str						=						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_   :				List[Any]						=						1
					if len(__snake_case  ) > 0:
										UpperCAmelCase_   :				Dict						=						deltmpscorea / len(__snake_case  )

					# ADDITION
					UpperCAmelCase_   :				Tuple						=						set(__snake_case  ) - set(__snake_case  )
					UpperCAmelCase_   :				Union[str, Any]						=						set(__snake_case  ) & set(__snake_case  )
					UpperCAmelCase_   :				Dict						=						set(__snake_case  ) - set(__snake_case  )

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

					return (keepscore, delscore_precision, addscore)




def 					lowercase__				(					__snake_case   :							str					,	__snake_case   :							Any					,	__snake_case   :							Union[str, Any]  ):


					'''simple docstring'''


					UpperCAmelCase_   :				int						=						len(__snake_case  )

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

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

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

					for i in range(0					,	len(__snake_case  ) - 1  ):
										if i < len(__snake_case  ) - 1:
															UpperCAmelCase_   :				Optional[int]						=						cagrams[i] + ' ' + cagrams[i + 1]
															cagrams.append(__snake_case  )
										if i < len(__snake_case  ) - 2:
															UpperCAmelCase_   :				Tuple						=						cagrams[i] + ' ' + cagrams[i + 1] + ' ' + cagrams[i + 2]
															cagrams.append(__snake_case  )
										if i < len(__snake_case  ) - 3:
															UpperCAmelCase_   :				Union[str, Any]						=						cagrams[i] + ' ' + cagrams[i + 1] + ' ' + cagrams[i + 2] + ' ' + cagrams[i + 3]
															cagrams.append(__snake_case  )

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




def 					lowercase__				(					__snake_case   :							List[Any]					,	__snake_case   :							bool = True					,	__snake_case   :							str = "13a"					,	__snake_case   :							bool = True  ):


					'''simple docstring'''


					if lowercase:
										UpperCAmelCase_   :				Optional[Any]						=						sentence.lower()

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

					if not return_str:
										UpperCAmelCase_   :				Any						=						normalized_sent.split()

					return normalized_sent




def 					lowercase__				(					__snake_case   :							Optional[int]					,	__snake_case   :							List[str]					,	__snake_case   :							Dict  ):


					'''simple docstring'''


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




def 					lowercase__				(					__snake_case   :							int					,	__snake_case   :							Union[str, Any]					,	__snake_case   :							str="exp"					,	__snake_case   :							Any=None					,	__snake_case   :							Union[str, Any]=False					,	__snake_case   :							Union[str, Any]=False					,	__snake_case   :							List[str]=False					,	):


					'''simple docstring'''


					UpperCAmelCase_   :				int						=						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'  )
					UpperCAmelCase_   :				Dict						=						[[refs[i] for refs in references] for i in range(__snake_case  )]
					UpperCAmelCase_   :				str						=						sacrebleu.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					,	)
					return output.score






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







		'''simple docstring'''



		def  __UpperCAmelCase      (							self       )     ->							Any:
							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  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							str:
							UpperCAmelCase_   :				List[Any]						=						{}
							result.update({'sari': compute_sari(sources=_UpperCamelCase    ,		predictions=_UpperCamelCase    ,		references=_UpperCamelCase       )}       )
							result.update({'sacrebleu': compute_sacrebleu(predictions=_UpperCamelCase    ,		references=_UpperCamelCase       )}       )
							result.update({'exact': compute_em(predictions=_UpperCamelCase    ,		references=_UpperCamelCase       )}       )
							return result






