






"""simple docstring"""





import datasets

from .evaluate import evaluate


__lowerCamelCase							=  '\\n@article{hendrycks2021cuad,\n      title={CUAD: An Expert-Annotated NLP Dataset for Legal Contract Review},\n      author={Dan Hendrycks and Collin Burns and Anya Chen and Spencer Ball},\n      journal={arXiv preprint arXiv:2103.06268},\n      year={2021}\n}\n'

__lowerCamelCase							=  '\nThis metric wrap the official scoring script for version 1 of the Contract\nUnderstanding Atticus Dataset (CUAD).\nContract Understanding Atticus Dataset (CUAD) v1 is a corpus of more than 13,000 labels in 510\ncommercial legal contracts that have been manually labeled to identify 41 categories of important\nclauses that lawyers look for when reviewing contracts in connection with corporate transactions.\n'

__lowerCamelCase							=  '\nComputes CUAD scores (EM, F1, AUPR, Precision@80%Recall, and Precision@90%Recall).\nArgs:\n    predictions: List of question-answers dictionaries with the following key-values:\n        - \'id\': id of the question-answer pair as given in the references (see below)\n        - \'prediction_text\': list of possible texts for the answer, as a list of strings\n        depending on a threshold on the confidence probability of each prediction.\n    references: List of question-answers dictionaries with the following key-values:\n        - \'id\': id of the question-answer pair (see above),\n        - \'answers\': a Dict in the CUAD dataset format\n            {\n                \'text\': list of possible texts for the answer, as a list of strings\n                \'answer_start\': list of start positions for the answer, as a list of ints\n            }\n            Note that answer_start values are not taken into account to compute the metric.\nReturns:\n    \'exact_match\': Exact match (the normalized answer exactly match the gold answer)\n    \'f1\': The F-score of predicted tokens versus the gold answer\n    \'aupr\': Area Under the Precision-Recall curve\n    \'prec_at_80_recall\': Precision at 80% recall\n    \'prec_at_90_recall\': Precision at 90% recall\nExamples:\n    >>> predictions = [{\'prediction_text\': [\'The seller:\', \'The buyer/End-User: Shenzhen LOHAS Supply Chain Management Co., Ltd.\'], \'id\': \'LohaCompanyltd_20191209_F-1_EX-10.16_11917878_EX-10.16_Supply Agreement__Parties\'}]\n    >>> references = [{\'answers\': {\'answer_start\': [143, 49], \'text\': [\'The seller:\', \'The buyer/End-User: Shenzhen LOHAS Supply Chain Management Co., Ltd.\']}, \'id\': \'LohaCompanyltd_20191209_F-1_EX-10.16_11917878_EX-10.16_Supply Agreement__Parties\'}]\n    >>> cuad_metric = datasets.load_metric("cuad")\n    >>> results = cuad_metric.compute(predictions=predictions, references=references)\n    >>> print(results)\n    {\'exact_match\': 100.0, \'f1\': 100.0, \'aupr\': 0.0, \'prec_at_80_recall\': 1.0, \'prec_at_90_recall\': 1.0}\n'



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

					def   lowerCamelCase__   (			self  :      Tuple					)			->							int:
											return datasets.MetricInfo(
											    description=_DESCRIPTION     ,		citation=_CITATION     ,		inputs_description=_KWARGS_DESCRIPTION     ,		features=datasets.Features(
											        {
											            """predictions""": {
											                """id""": datasets.Value("""string"""					),
											                """prediction_text""": datasets.features.Sequence(datasets.Value("""string"""					)					),
											            },
											            """references""": {
											                """id""": datasets.Value("""string"""					),
											                """answers""": datasets.features.Sequence(
											                    {
											                        """text""": datasets.Value("""string"""					),
											                        """answer_start""": datasets.Value("""int32"""					),
											                    }					),
											            },
											        }					)     ,		codebase_urls=["""https://www.atticusprojectai.org/cuad"""]     ,		reference_urls=["""https://www.atticusprojectai.org/cuad"""]     ,		)






					def   lowerCamelCase__   (			self  :      List[str]     ,		__snake_case  :      List[str]     ,		__snake_case  :      Dict					)			->							List[str]:
											__magic_name__:	Union[str, Any]							=       {prediction["""id"""]: prediction["""prediction_text"""] for prediction in predictions}
											__magic_name__:	List[str]							=       [
											    {
											        """paragraphs""": [
											            {
											                """qas""": [
											                    {
											                        """answers""": [{"""text""": answer_text} for answer_text in ref["""answers"""]["""text"""]],
											                        """id""": ref["""id"""],
											                    }
											                    for ref in references
											                ]
											            }
											        ]
											    }
											]
											__magic_name__:	Tuple							=       evaluate(dataset=__snake_case     ,		predictions=__snake_case					)
											return score











"""simple docstring"""





from typing import List, Union

import numpy as np

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, logging
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline


__lowerCamelCase							=  logging.get_logger(__name__)



class       __A		(   SCREAMING_SNAKE_CASE_			):

					def   lowerCamelCase__   (			self  :      Optional[Any]     ,		__snake_case  :      Any					)			->							List[Any]:
											if isinstance(__snake_case     ,		__snake_case					):
																	__magic_name__:	Dict							=       [label.strip() for label in labels.split(""","""					) if label.strip()]
											return labels






					def __call__(			self  :      Optional[Any]     ,		__snake_case  :      str     ,		__snake_case  :      List[Any]     ,		__snake_case  :      List[Any]					)			->							int:
											if len(__snake_case					) == 0 or len(__snake_case					) == 0:
																	raise ValueError("""You must include at least one label and at least one sequence."""					)
											if hypothesis_template.format(labels[0]					) == hypothesis_template:
																	raise ValueError(
																	    (
																	        """The provided hypothesis_template \"{}\" was not able to be formatted with the target labels. """
																	        """Make sure the passed template includes formatting syntax such as {{}} where the label should go."""
																	    ).format(__snake_case					)					)

											if isinstance(__snake_case     ,		__snake_case					):
																	__magic_name__:	Any							=       [sequences]

											__magic_name__:	List[Any]							=       []
											for sequence in sequences:
																	sequence_pairs.extend([[sequence, hypothesis_template.format(__snake_case					)] for label in labels]					)

											return sequence_pairs, sequences



@add_end_docstrings(SCREAMING_SNAKE_CASE_			)
class       __A		(   SCREAMING_SNAKE_CASE_			):

					def __init__(			self  :      Dict     ,		__snake_case  :      Dict=ZeroShotClassificationArgumentHandler()     ,		*__snake_case  :      Dict     ,		**__snake_case  :      Optional[int]					)			->							int:
											__magic_name__:	List[str]							=       args_parser
											super().__init__(*__snake_case     ,		**__snake_case					)
											if self.entailment_id == -1:
																	logger.warning(
																	    """Failed to determine 'entailment' label id from the label2id mapping in the model config. Setting to """
																	    """-1. Define a descriptive label2id mapping in the model config to ensure correct outputs."""					)

					@property
					def   lowerCamelCase__   (			self  :      List[str]					)			->							str:
											for label, ind in self.model.config.labelaid.items():
																	if label.lower().startswith("""entail"""					):
																							return ind
											return -1

					def   lowerCamelCase__   (			self  :      Union[str, Any]     ,		__snake_case  :      Tuple     ,		__snake_case  :      List[Any]=True     ,		__snake_case  :      Tuple=True     ,		__snake_case  :      Tuple=TruncationStrategy.ONLY_FIRST     ,		**__snake_case  :      Union[str, Any]					)			->							int:
											__magic_name__:	Optional[int]							=       self.framework
											if self.tokenizer.pad_token is None:
																	# Override for tokenizers not supporting padding
																	logger.error(
																	    """Tokenizer was not supporting padding necessary for zero-shot, attempting to use """
																	    """ `pad_token=eos_token`"""					)
																	__magic_name__:	Tuple							=       self.tokenizer.eos_token
											try:
																	__magic_name__:	List[Any]							=       self.tokenizer(
																	    __snake_case     ,		add_special_tokens=__snake_case     ,		return_tensors=__snake_case     ,		padding=__snake_case     ,		truncation=__snake_case     ,		)
											except Exception as e:
																	if "too short" in str(__snake_case					):
																							# tokenizers might yell that we want to truncate
																							# to a value that is not even reached by the input.
																							# In that case we don't want to truncate.
																							# It seems there's not a really better way to catch that
																							# exception.

																							__magic_name__:	List[str]							=       self.tokenizer(
																							    __snake_case     ,		add_special_tokens=__snake_case     ,		return_tensors=__snake_case     ,		padding=__snake_case     ,		truncation=TruncationStrategy.DO_NOT_TRUNCATE     ,		)
																	else:
																							raise e

											return inputs

					def   lowerCamelCase__   (			self  :      Any     ,		**__snake_case  :      Optional[Any]					)			->							int:
											if kwargs.get("""multi_class"""     ,		__snake_case					) is not None:
																	__magic_name__:	List[str]							=       kwargs["""multi_class"""]
																	logger.warning(
																	    """The `multi_class` argument has been deprecated and renamed to `multi_label`. """
																	    """`multi_class` will be removed in a future version of Transformers."""					)
											__magic_name__:	Optional[Any]							=       {}
											if "candidate_labels" in kwargs:
																	__magic_name__:	str							=       self._args_parser._parse_labels(kwargs["""candidate_labels"""]					)
											if "hypothesis_template" in kwargs:
																	__magic_name__:	Optional[Any]							=       kwargs["""hypothesis_template"""]

											__magic_name__:	int							=       {}
											if "multi_label" in kwargs:
																	__magic_name__:	int							=       kwargs["""multi_label"""]
											return preprocess_params, {}, postprocess_params

					def __call__(			self  :      Any     ,		__snake_case  :      Union[str, List[str]]     ,		*__snake_case  :      Optional[int]     ,		**__snake_case  :      List[str]     ,		)			->							List[str]:
											if len(__snake_case					) == 0:
																	pass
											elif len(__snake_case					) == 1 and "candidate_labels" not in kwargs:
																	__magic_name__:	str							=       args[0]
											else:
																	raise ValueError(F'Unable to understand extra arguments {args}'					)

											return super().__call__(__snake_case     ,		**__snake_case					)

					def   lowerCamelCase__   (			self  :      Any     ,		__snake_case  :      int     ,		__snake_case  :      List[Any]=None     ,		__snake_case  :      Tuple="This example is {}."					)			->							List[Any]:
											__magic_name__,			__magic_name__:	int							=       self._args_parser(__snake_case     ,		__snake_case     ,		__snake_case					)

											for i, (candidate_label, sequence_pair) in enumerate(zip(__snake_case     ,		__snake_case					)					):
																	__magic_name__:	Dict							=       self._parse_and_tokenize([sequence_pair]					)

																	yield {
																	    "candidate_label": candidate_label,
																	    "sequence": sequences[0],
																	    "is_last": i == len(__snake_case					) - 1,
																	    **model_input,
																	}

					def   lowerCamelCase__   (			self  :      Dict     ,		__snake_case  :      int					)			->							Tuple:
											__magic_name__:	Optional[Any]							=       inputs["""candidate_label"""]
											__magic_name__:	List[str]							=       inputs["""sequence"""]
											__magic_name__:	Any							=       {k: inputs[k] for k in self.tokenizer.model_input_names}
											__magic_name__:	Optional[int]							=       self.model(**__snake_case					)

											__magic_name__:	Optional[Any]							=       {
											    """candidate_label""": candidate_label,
											    """sequence""": sequence,
											    """is_last""": inputs["""is_last"""],
											    **outputs,
											}
											return model_outputs






					def   lowerCamelCase__   (			self  :      Optional[int]     ,		__snake_case  :      str     ,		__snake_case  :      List[Any]=False					)			->							Any:
											__magic_name__:	List[Any]							=       [outputs["""candidate_label"""] for outputs in model_outputs]
											__magic_name__:	Any							=       [outputs["""sequence"""] for outputs in model_outputs]
											__magic_name__:	Tuple							=       np.concatenate([output["""logits"""].numpy() for output in model_outputs]					)
											__magic_name__:	Any							=       logits.shape[0]
											__magic_name__:	Any							=       len(__snake_case					)
											__magic_name__:	List[str]							=       N // n
											__magic_name__:	int							=       logits.reshape((num_sequences, n, -1)					)

											if multi_label or len(__snake_case					) == 1:
																	# softmax over the entailment vs. contradiction dim for each label independently
																	__magic_name__:	List[Any]							=       self.entailment_id
																	__magic_name__:	List[str]							=       -1 if entailment_id == 0 else 0
																	__magic_name__:	Tuple							=       reshaped_outputs[..., [contradiction_id, entailment_id]]
																	__magic_name__:	int							=       np.exp(__snake_case					) / np.exp(__snake_case					).sum(-1     ,		keepdims=__snake_case					)
																	__magic_name__:	List[str]							=       scores[..., 1]
											else:
																	# softmax the "entailment" logits over all candidate labels
																	__magic_name__:	List[str]							=       reshaped_outputs[..., self.entailment_id]
																	__magic_name__:	Tuple							=       np.exp(__snake_case					) / np.exp(__snake_case					).sum(-1     ,		keepdims=__snake_case					)

											__magic_name__:	Optional[Any]							=       list(reversed(scores[0].argsort()					)					)
											return {
											    "sequence": sequences[0],
											    "labels": [candidate_labels[i] for i in top_inds],
											    "scores": scores[0, top_inds].tolist(),
											}



