





from abc import ABC, abstractmethod
from typing import List, Optional
class      UpperCamelCase_						(					__lowercase   ):




					def __init__(						self					)						->							Tuple:
										# test for the above condition
										self.test()




					def 		lowerCAmelCase     (						self					)						->							Tuple:
										_snake_case													=			0
										_snake_case													=			False
										while not completed:
															if counter == 1:
																				self.reset()
															_snake_case													=			self.advance()
															if not self.does_advance(UpperCAmelCase__					):
																				raise Exception(
																				    'Custom Constraint is not defined correctly. self.does_advance(self.advance()) must be true.'					)

															_snake_case							,       _snake_case							,       _snake_case													=			self.update(UpperCAmelCase__					)
															counter += 1

															if counter > 1_0000:
																				raise Exception('update() does not fulfill the constraint.'					)

										if self.remaining() != 0:
															raise Exception('Custom Constraint is not defined correctly.'					)




					@abstractmethod
					def 		lowerCAmelCase     (						self					)						->							Dict:
										raise NotImplementedError(
										    F'''{self.__class__} is an abstract class. Only classes inheriting this class can be called.'''					)




					@abstractmethod
					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Dict:
										raise NotImplementedError(
										    F'''{self.__class__} is an abstract class. Only classes inheriting this class can be called.'''					)




					@abstractmethod
					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Tuple:
										raise NotImplementedError(
										    F'''{self.__class__} is an abstract class. Only classes inheriting this class can be called.'''					)




					@abstractmethod
					def 		lowerCAmelCase     (						self					)						->							Tuple:
										raise NotImplementedError(
										    F'''{self.__class__} is an abstract class. Only classes inheriting this class can be called.'''					)




					@abstractmethod
					def 		lowerCAmelCase     (						self					)						->							Tuple:
										raise NotImplementedError(
										    F'''{self.__class__} is an abstract class. Only classes inheriting this class can be called.'''					)






					@abstractmethod
					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_=False					)						->							Union[str, Any]:
										raise NotImplementedError(
										    F'''{self.__class__} is an abstract class. Only classes inheriting this class can be called.'''					)





class      UpperCamelCase_						(					__lowercase   ):




					def __init__(						self			,  lowerCAmelCase_					)						->							Union[str, Any]:
										super(UpperCAmelCase__			,  self					).__init__()

										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					) or len(UpperCAmelCase__					) == 0:
															raise ValueError(F'''`token_ids` has to be a non-empty list, but is {token_ids}.'''					)
										if any((not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					) or token_id < 0) for token_id in token_ids					):
															raise ValueError(F'''Each list in `token_ids` has to be a list of positive integers, but is {token_ids}.'''					)

										_snake_case													=			token_ids

										_snake_case													=			len(self.token_ids					)
										_snake_case													=			-1  # the index of the currently fulfilled step
										_snake_case													=			False




					def 		lowerCAmelCase     (						self					)						->							Optional[int]:
										if self.completed:
															return None
										return self.token_ids[self.fulfilled_idx + 1]




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							int:
										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
															raise ValueError(F'''`token_id` has to be an `int`, but is {token_id} of type {type(UpperCAmelCase__					)}'''					)

										if self.completed:
															return False

										return token_id == self.token_ids[self.fulfilled_idx + 1]




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							List[str]:
										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
															raise ValueError(F'''`token_id` has to be an `int`, but is {token_id} of type {type(UpperCAmelCase__					)}'''					)

										_snake_case													=			False
										_snake_case													=			False
										_snake_case													=			False

										if self.does_advance(UpperCAmelCase__					):
															self.fulfilled_idx += 1
															_snake_case													=			True
															if self.fulfilled_idx == (self.seqlen - 1):
																				_snake_case													=			True
															_snake_case													=			completed
										else:
															# failed to make progress.
															_snake_case													=			True
															self.reset()
										return stepped, completed, reset




					def 		lowerCAmelCase     (						self					)						->							List[str]:
										_snake_case													=			False
										_snake_case													=			0




					def 		lowerCAmelCase     (						self					)						->							List[str]:
										return self.seqlen - (self.fulfilled_idx + 1)






					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_=False					)						->							Optional[int]:
										_snake_case													=			PhrasalConstraint(self.token_ids					)

										if stateful:
															_snake_case													=			self.seqlen
															_snake_case													=			self.fulfilled_idx
															_snake_case													=			self.completed

										return new_constraint





class      UpperCamelCase_						:




					def __init__(						self			,  lowerCAmelCase_			,  lowerCAmelCase_=True					)						->							str:
										_snake_case													=			max([len(UpperCAmelCase__					) for one in nested_token_ids]					)

										_snake_case													=			{}
										for token_ids in nested_token_ids:
															_snake_case													=			root
															for tidx, token_id in enumerate(UpperCAmelCase__					):
																				if token_id not in level:
																									_snake_case													=			{}

																				_snake_case													=			level[token_id]

										if no_subsets and self.has_subsets(UpperCAmelCase__			,  UpperCAmelCase__					):
															raise ValueError(
															    'Each list in `nested_token_ids` can\'t be a complete subset of another list, but is'
															    F''' {nested_token_ids}.'''					)

										_snake_case													=			root




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Union[str, Any]:
										_snake_case													=			self.trie

										for current_token in current_seq:
															_snake_case													=			start[current_token]

										_snake_case													=			list(start.keys()					)

										return next_tokens




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Dict:
										_snake_case													=			self.next_tokens(UpperCAmelCase__					)

										return len(UpperCAmelCase__					) == 0




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Union[str, Any]:
										_snake_case													=			list(root.values()					)
										if len(UpperCAmelCase__					) == 0:
															return 1
										else:
															return sum([self.count_leaves(UpperCAmelCase__					) for nn in next_nodes]					)






					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_			,  lowerCAmelCase_					)						->							List[Any]:
										_snake_case													=			self.count_leaves(UpperCAmelCase__					)
										return len(UpperCAmelCase__					) != leaf_count





class      UpperCamelCase_						(					__lowercase   ):




					def __init__(						self			,  lowerCAmelCase_					)						->							List[Any]:
										super(UpperCAmelCase__			,  self					).__init__()

										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					) or len(UpperCAmelCase__					) == 0:
															raise ValueError(F'''`nested_token_ids` has to be a non-empty list, but is {nested_token_ids}.'''					)
										if any(not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					) for token_ids in nested_token_ids					):
															raise ValueError(F'''`nested_token_ids` has to be a list of lists, but is {nested_token_ids}.'''					)
										if any(
										    any((not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					) or token_id < 0) for token_id in token_ids					)
										    for token_ids in nested_token_ids					):
															raise ValueError(
															    F'''Each list in `nested_token_ids` has to be a list of positive integers, but is {nested_token_ids}.'''					)

										_snake_case													=			DisjunctiveTrie(UpperCAmelCase__					)
										_snake_case													=			nested_token_ids

										_snake_case													=			self.trie.max_height
										_snake_case													=			[]
										_snake_case													=			False




					def 		lowerCAmelCase     (						self					)						->							Optional[int]:
										_snake_case													=			self.trie.next_tokens(self.current_seq					)

										if len(UpperCAmelCase__					) == 0:
															return None
										else:
															return token_list




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Any:
										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
															raise ValueError(F'''`token_id` is supposed to be type `int`, but is {token_id} of type {type(UpperCAmelCase__					)}'''					)

										_snake_case													=			self.trie.next_tokens(self.current_seq					)

										return token_id in next_tokens




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Tuple:
										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
															raise ValueError(F'''`token_id` is supposed to be type `int`, but is {token_id} of type {type(UpperCAmelCase__					)}'''					)

										_snake_case													=			False
										_snake_case													=			False
										_snake_case													=			False

										if self.does_advance(UpperCAmelCase__					):
															self.current_seq.append(UpperCAmelCase__					)
															_snake_case													=			True
										else:
															_snake_case													=			True
															self.reset()

										_snake_case													=			self.trie.reached_leaf(self.current_seq					)
										_snake_case													=			completed

										return stepped, completed, reset




					def 		lowerCAmelCase     (						self					)						->							int:
										_snake_case													=			False
										_snake_case													=			[]




					def 		lowerCAmelCase     (						self					)						->							Optional[Any]:
										if self.completed:
															# since this can be completed without reaching max height
															return 0
										else:
															return self.seqlen - len(self.current_seq					)






					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_=False					)						->							List[Any]:
										_snake_case													=			DisjunctiveConstraint(self.token_ids					)

										if stateful:
															_snake_case													=			self.seqlen
															_snake_case													=			self.current_seq
															_snake_case													=			self.completed

										return new_constraint





class      UpperCamelCase_						:




					def __init__(						self			,  lowerCAmelCase_					)						->							str:
										_snake_case													=			constraints

										# max # of steps required to fulfill a given constraint
										_snake_case													=			max([c.seqlen for c in constraints]					)
										_snake_case													=			len(UpperCAmelCase__					)
										_snake_case													=			False

										self.init_state()




					def 		lowerCAmelCase     (						self					)						->							List[str]:
										_snake_case													=			[]
										_snake_case													=			None
										_snake_case													=			[constraint.copy(stateful=UpperCAmelCase__					) for constraint in self.constraints]




					def 		lowerCAmelCase     (						self					)						->							Any:
										_snake_case													=			0
										if self.inprogress_constraint:
															# extra points for having a constraint mid-fulfilled
															add += self.max_seqlen - self.inprogress_constraint.remaining()

										return (len(self.complete_constraints					) * self.max_seqlen) + add




					def 		lowerCAmelCase     (						self					)						->							int:
										_snake_case													=			[]
										if self.inprogress_constraint is None:
															for constraint in self.pending_constraints:  # "pending" == "unfulfilled yet"
																				_snake_case													=			constraint.advance()
																				if isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
																									token_list.append(UpperCAmelCase__					)
																				elif isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
																									token_list.extend(UpperCAmelCase__					)
										else:
															_snake_case													=			self.inprogress_constraint.advance()
															if isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
																				token_list.append(UpperCAmelCase__					)
															elif isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
																				token_list.extend(UpperCAmelCase__					)

										if len(UpperCAmelCase__					) == 0:
															return None
										else:
															return token_list




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Dict:
										self.init_state()

										if token_ids is not None:
															for token in token_ids:
																				# completes or steps **one** constraint
																				_snake_case							,       _snake_case													=			self.add(UpperCAmelCase__					)

																				# the entire list of constraints are fulfilled
																				if self.completed:
																									break




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							Optional[Any]:
										if not isinstance(UpperCAmelCase__			,  UpperCAmelCase__					):
															raise ValueError(F'''`token_id` should be an `int`, but is `{token_id}`.'''					)

										_snake_case							,       _snake_case													=			False, False

										if self.completed:
															_snake_case													=			True
															_snake_case													=			False
															return complete, stepped

										if self.inprogress_constraint is not None:
															# In the middle of fulfilling a constraint. If the `token_id` *does* makes an incremental progress to current
															# job, simply update the state

															_snake_case							,       _snake_case							,       _snake_case													=			self.inprogress_constraint.update(UpperCAmelCase__					)
															if reset:
																				# 1. If the next token breaks the progress, then we must restart.
																				#     e.g. constraint = "I love pies" and sequence so far is "I love" but `token_id` == "books".

																				#     But that doesn't mean we self.init_state(), since we only reset the state for this particular
																				#     constraint, not the full list of constraints.

																				self.pending_constraints.append(self.inprogress_constraint.copy(stateful=UpperCAmelCase__					)					)
																				_snake_case													=			None

															if complete:
																				# 2. If the next token completes the constraint, move it to completed list, set
																				#     inprogress to None. If there are no pending constraints either, then this full list of constraints
																				#     is complete.

																				self.complete_constraints.append(self.inprogress_constraint					)
																				_snake_case													=			None

																				if len(self.pending_constraints					) == 0:
																									# we're done!
																									_snake_case													=			True

										else:
															# Not in the middle of fulfilling a constraint. So does this `token_id` helps us step towards any of our list
															# of constraints?

															for cidx, pending_constraint in enumerate(self.pending_constraints					):
																				if pending_constraint.does_advance(UpperCAmelCase__					):
																									_snake_case							,       _snake_case							,       _snake_case													=			pending_constraint.update(UpperCAmelCase__					)

																									if not stepped:
																														raise Exception(
																														    '`constraint.update(token_id)` is not yielding incremental progress, '
																														    'even though `constraint.does_advance(token_id)` is true.'					)

																									if complete:
																														self.complete_constraints.append(UpperCAmelCase__					)
																														_snake_case													=			None

																									if not complete and stepped:
																														_snake_case													=			pending_constraint

																									if complete or stepped:
																														# If we made any progress at all, then it's at least not a "pending constraint".

																														_snake_case													=			(
																														    self.pending_constraints[:cidx] + self.pending_constraints[cidx + 1 :]
																														)

																														if len(self.pending_constraints					) == 0 and self.inprogress_constraint is None:
																																			# If there's no longer any pending after this and no inprogress either, then we must be
																																			# complete.

																																			_snake_case													=			True

																														break  # prevent accidentally stepping through multiple constraints with just one token.

										return complete, stepped






					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_=True					)						->							Optional[int]:
										_snake_case													=			ConstraintListState(self.constraints					)  # we actually never though self.constraints objects
										# throughout this process. So it's at initialization state.

										if stateful:
															_snake_case													=			[
															    constraint.copy(stateful=UpperCAmelCase__					) for constraint in self.complete_constraints
															]
															if self.inprogress_constraint is not None:
																				_snake_case													=			self.inprogress_constraint.copy(stateful=UpperCAmelCase__					)
															_snake_case													=			[constraint.copy() for constraint in self.pending_constraints]

										return new_state










from typing import Dict, List

from nltk.translate import gleu_score

import datasets
from datasets import MetricInfo


UpperCAmelCase_ 							=       """\
@misc{wu2016googles,
      title={Google's Neural Machine Translation System: Bridging the Gap between Human and Machine Translation},
      author={Yonghui Wu and Mike Schuster and Zhifeng Chen and Quoc V. Le and Mohammad Norouzi and Wolfgang Macherey
              and Maxim Krikun and Yuan Cao and Qin Gao and Klaus Macherey and Jeff Klingner and Apurva Shah and Melvin
              Johnson and Xiaobing Liu and Łukasz Kaiser and Stephan Gouws and Yoshikiyo Kato and Taku Kudo and Hideto
              Kazawa and Keith Stevens and George Kurian and Nishant Patil and Wei Wang and Cliff Young and
              Jason Smith and Jason Riesa and Alex Rudnick and Oriol Vinyals and Greg Corrado and Macduff Hughes
              and Jeffrey Dean},
      year={2016},
      eprint={1609.08144},
      archivePrefix={arXiv},
      primaryClass={cs.CL}
}
"""

UpperCAmelCase_ 							=       """\
The BLEU score has some undesirable properties when used for single
sentences, as it was designed to be a corpus measure. We therefore
use a slightly different score for our RL experiments which we call
the 'GLEU score'. For the GLEU score, we record all sub-sequences of
1, 2, 3 or 4 tokens in output and target sequence (n-grams). We then
compute a recall, which is the ratio of the number of matching n-grams
to the number of total n-grams in the target (ground truth) sequence,
and a precision, which is the ratio of the number of matching n-grams
to the number of total n-grams in the generated output sequence. Then
GLEU score is simply the minimum of recall and precision. This GLEU
score's range is always between 0 (no matches) and 1 (all match) and
it is symmetrical when switching output and target. According to
our experiments, GLEU score correlates quite well with the BLEU
metric on a corpus level but does not have its drawbacks for our per
sentence reward objective.
"""

UpperCAmelCase_ 							=       """\
Computes corpus-level Google BLEU (GLEU) score of translated segments against one or more references.
Instead of averaging the sentence level GLEU scores (i.e. macro-average precision), Wu et al. (2016) sum up the matching
tokens and the max of hypothesis and reference tokens for each sentence, then compute using the aggregate values.

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): list of lists of references for each translation.
        Each reference should be tokenized into a list of tokens.
    min_len (int): The minimum order of n-gram this function should extract. Defaults to 1.
    max_len (int): The maximum order of n-gram this function should extract. Defaults to 4.

Returns:
    'google_bleu': google_bleu score

Examples:
    Example 1:
        >>> hyp1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
        ...         'ensures', 'that', 'the', 'rubber', 'duck', 'always',
        ...         'disobeys', 'the', 'commands', 'of', 'the', 'cat']
        >>> ref1a = ['It', 'is', 'the', 'guiding', 'principle', 'which',
        ...          'guarantees', 'the', 'rubber', 'duck', 'forces', 'never',
        ...          'being', 'under', 'the', 'command', 'of', 'the', 'cat']

        >>> hyp2 = ['he', 'read', 'the', 'book', 'because', 'he', 'was',
        ...         'interested', 'in', 'world', 'history']
        >>> ref2a = ['he', 'was', 'interested', 'in', 'world', 'history',
        ...          'because', 'he', 'read', 'the', 'book']

        >>> list_of_references = [[ref1a], [ref2a]]
        >>> hypotheses = [hyp1, hyp2]
        >>> google_bleu = datasets.load_metric(\"google_bleu\")
        >>> results = google_bleu.compute(predictions=hypotheses, references=list_of_references)
        >>> print(round(results[\"google_bleu\"], 2))
        0.44

    Example 2:
        >>> hyp1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
        ...         'ensures', 'that', 'the', 'rubber', 'duck', 'always',
        ...         'disobeys', 'the', 'commands', 'of', 'the', 'cat']
        >>> ref1a = ['It', 'is', 'the', 'guiding', 'principle', 'which',
        ...          'guarantees', 'the', 'rubber', 'duck', 'forces', 'never',
        ...          'being', 'under', 'the', 'command', 'of', 'the', 'cat']
        >>> ref1b = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
        ...          'ensures', 'that', 'the', 'rubber', 'duck', 'will', 'never',
        ...          'heed', 'the', 'cat', 'commands']
        >>> ref1c = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
        ...          'rubber', 'duck', 'army', 'never', 'to', 'heed', 'the', 'directions',
        ...          'of', 'the', 'cat']

        >>> hyp2 = ['he', 'read', 'the', 'book', 'because', 'he', 'was',
        ...         'interested', 'in', 'world', 'history']
        >>> ref2a = ['he', 'was', 'interested', 'in', 'world', 'history',
        ...          'because', 'he', 'read', 'the', 'book']

        >>> list_of_references = [[ref1a, ref1b, ref1c], [ref2a]]
        >>> hypotheses = [hyp1, hyp2]
        >>> google_bleu = datasets.load_metric(\"google_bleu\")
        >>> results = google_bleu.compute(predictions=hypotheses, references=list_of_references)
        >>> print(round(results[\"google_bleu\"], 2))
        0.61

    Example 3:
        >>> hyp1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
        ...         'ensures', 'that', 'the', 'rubber', 'duck', 'always',
        ...         'disobeys', 'the', 'commands', 'of', 'the', 'cat']
        >>> ref1a = ['It', 'is', 'the', 'guiding', 'principle', 'which',
        ...          'guarantees', 'the', 'rubber', 'duck', 'forces', 'never',
        ...          'being', 'under', 'the', 'command', 'of', 'the', 'cat']
        >>> ref1b = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
        ...          'ensures', 'that', 'the', 'rubber', 'duck', 'will', 'never',
        ...          'heed', 'the', 'cat', 'commands']
        >>> ref1c = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
        ...          'rubber', 'duck', 'army', 'never', 'to', 'heed', 'the', 'directions',
        ...          'of', 'the', 'cat']

        >>> hyp2 = ['he', 'read', 'the', 'book', 'because', 'he', 'was',
        ...         'interested', 'in', 'world', 'history']
        >>> ref2a = ['he', 'was', 'interested', 'in', 'world', 'history',
        ...          'because', 'he', 'read', 'the', 'book']

        >>> list_of_references = [[ref1a, ref1b, ref1c], [ref2a]]
        >>> hypotheses = [hyp1, hyp2]
        >>> google_bleu = datasets.load_metric(\"google_bleu\")
        >>> results = google_bleu.compute(predictions=hypotheses, references=list_of_references, min_len=2)
        >>> print(round(results[\"google_bleu\"], 2))
        0.53

    Example 4:
        >>> hyp1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
        ...         'ensures', 'that', 'the', 'rubber', 'duck', 'always',
        ...         'disobeys', 'the', 'commands', 'of', 'the', 'cat']
        >>> ref1a = ['It', 'is', 'the', 'guiding', 'principle', 'which',
        ...          'guarantees', 'the', 'rubber', 'duck', 'forces', 'never',
        ...          'being', 'under', 'the', 'command', 'of', 'the', 'cat']
        >>> ref1b = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
        ...          'ensures', 'that', 'the', 'rubber', 'duck', 'will', 'never',
        ...          'heed', 'the', 'cat', 'commands']
        >>> ref1c = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
        ...          'rubber', 'duck', 'army', 'never', 'to', 'heed', 'the', 'directions',
        ...          'of', 'the', 'cat']

        >>> hyp2 = ['he', 'read', 'the', 'book', 'because', 'he', 'was',
        ...         'interested', 'in', 'world', 'history']
        >>> ref2a = ['he', 'was', 'interested', 'in', 'world', 'history',
        ...          'because', 'he', 'read', 'the', 'book']

        >>> list_of_references = [[ref1a, ref1b, ref1c], [ref2a]]
        >>> hypotheses = [hyp1, hyp2]
        >>> google_bleu = datasets.load_metric(\"google_bleu\")
        >>> results = google_bleu.compute(predictions=hypotheses,references=list_of_references, min_len=2, max_len=6)
        >>> print(round(results[\"google_bleu\"], 2))
        0.4
"""
@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION							,					_KWARGS_DESCRIPTION   )
class      UpperCamelCase_						(					datasets.Metric   ):




					def 		lowerCAmelCase     (						self					)						->							MetricInfo:
										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'					),
										        }					)			,  )






					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_			,  lowerCAmelCase_			,  lowerCAmelCase_ = 1			,  lowerCAmelCase_ = 4			,  )						->							Dict[str, float]:
										return {
										    "google_bleu": gleu_score.corpus_gleu(
										        list_of_references=lowerCAmelCase_			,  hypotheses=lowerCAmelCase_			,  min_len=lowerCAmelCase_			,  max_len=lowerCAmelCase_					)
										}



