


import collections
import types

import numpy as np

from ..utils import (
    add_end_docstrings,
    is_tensorflow_probability_available,
    is_tf_available,
    is_torch_available,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, Dataset, Pipeline, PipelineException


if is_torch_available():
						import torch

						from ..models.auto.modeling_auto import (
						    MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
						    MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
						)

if is_tf_available() and is_tensorflow_probability_available():
						import tensorflow as tf
						import tensorflow_probability as tfp

						from ..models.auto.modeling_tf_auto import (
						    TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
						    TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
						)







class 			snake_case__(							UpperCAmelCase__							):







						'''simple docstring'''




						def __call__(			self				,  __lowercase=None				,  __lowercase=None				,  **__lowercase							)   ->      Tuple:
										# Returns tqa_pipeline_inputs of shape:
										# [
										#   {"table": pd.DataFrame, "query": List[str]},
										#   ...,
										#   {"table": pd.DataFrame, "query" : List[str]}
										# ]
										requires_backends(self				,  '''pandas'''							)
										import pandas as pd

										if table is None:
														raise ValueError('''Keyword argument `table` cannot be None.'''							)
										elif query is None:
														if isinstance(__lowercase				,  __lowercase							) and table.get('''query'''							) is not None and table.get('''table'''							) is not None:
																		lowerCAmelCase_	: Optional[Any]      			=			[table]
														elif isinstance(__lowercase				,  __lowercase							) and len(__lowercase							) > 0:
																		if not all(isinstance(__lowercase				,  __lowercase							) for d in table							):
																						raise ValueError(
																						    f"""Keyword argument `table` should be a list of dict, but is {(type(__lowercase							) for d in table)}"""							)

																		if table[0].get('''query'''							) is not None and table[0].get('''table'''							) is not None:
																						lowerCAmelCase_	: int      			=			table
																		else:
																						raise ValueError(
																						    '''If keyword argument `table` is a list of dictionaries, each dictionary should have a `table`'''
																						    f""" and `query` key, but only dictionary has keys {table[0].keys()} `table` and `query` keys."""							)
														elif Dataset is not None and isinstance(__lowercase				,  __lowercase							) or isinstance(__lowercase				,  types.GeneratorType							):
																		return table
														else:
																		raise ValueError(
																		    '''Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but '''
																		    f"""is {type(__lowercase							)})"""							)
										else:
														lowerCAmelCase_	: Optional[Any]      			=			[{'''table''': table, '''query''': query}]

										for tqa_pipeline_input in tqa_pipeline_inputs:
														if not isinstance(tqa_pipeline_input['''table''']				,  pd.DataFrame							):
																		if tqa_pipeline_input["table"] is None:
																						raise ValueError('''Table cannot be None.'''							)

																		lowerCAmelCase_	: Dict      			=			pd.DataFrame(tqa_pipeline_input['''table''']							)

										return tqa_pipeline_inputs







@add_end_docstrings(UpperCAmelCase__							)
class 			snake_case__(							UpperCAmelCase__							):







						'''simple docstring'''




						SCREAMING_SNAKE_CASE__ :					Tuple   =							"""table,query"""




						def __init__(			self				,  __lowercase=TableQuestionAnsweringArgumentHandler()				,  *__lowercase				,  **__lowercase							)   ->      Union[str, Any]:
										super().__init__(*__lowercase				,  **__lowercase							)
										lowerCAmelCase_	: Any      			=			args_parser

										self.check_model_type(
										    dict(
										        TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items()
										        + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()							)
										    if self.framework == '''tf'''
										    else dict(
										        MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items()							)							)

										lowerCAmelCase_	: Any      			=			bool(getattr(self.model.config				,  '''aggregation_labels'''				,  __lowercase							)							) and bool(
										    getattr(self.model.config				,  '''num_aggregation_labels'''				,  __lowercase							)							)
										lowerCAmelCase_	: Dict      			=			'''tapas''' if hasattr(self.model.config				,  '''aggregation_labels'''							) else None




						def   lowercase_	(			self				,  **__lowercase							)   ->      List[Any]:
										return self.model(**__lowercase							)




						def   lowercase_	(			self				,  **__lowercase							)   ->      Optional[Any]:
										if self.framework == "pt":
														lowerCAmelCase_	: Tuple      			=			[]
														lowerCAmelCase_	: int      			=			[]
														lowerCAmelCase_	: Dict      			=			None
														lowerCAmelCase_	: Optional[int]      			=			inputs['''input_ids'''].shape[0]

														lowerCAmelCase_	: int      			=			inputs['''input_ids'''].to(self.device							)
														lowerCAmelCase_	: Tuple      			=			inputs['''attention_mask'''].to(self.device							)
														lowerCAmelCase_	: Union[str, Any]      			=			inputs['''token_type_ids'''].to(self.device							)
														lowerCAmelCase_	: str      			=			None

														for index in range(__lowercase							):
																		# If sequences have already been processed, the token type IDs will be created according to the previous
																		# answer.
																		if prev_answers is not None:
																						lowerCAmelCase_	: Any      			=			token_type_ids_example[:, 3]  # shape (seq_len,)
																						lowerCAmelCase_	: List[str]      			=			np.zeros_like(prev_labels_example.cpu().numpy()							)  # shape (seq_len,)

																						lowerCAmelCase_	: int      			=			token_type_ids[index]  # shape (seq_len, 7)
																						for i in range(model_labels.shape[0]							):
																										lowerCAmelCase_	: int      			=			token_type_ids_example[:, 0].tolist()[i]
																										lowerCAmelCase_	: Optional[Any]      			=			token_type_ids_example[:, 1].tolist()[i] - 1
																										lowerCAmelCase_	: Tuple      			=			token_type_ids_example[:, 2].tolist()[i] - 1

																										if row_id >= 0 and col_id >= 0 and segment_id == 1:
																														lowerCAmelCase_	: List[Any]      			=			int(prev_answers[(col_id, row_id)]							)

																						lowerCAmelCase_	: Tuple      			=			torch.from_numpy(__lowercase							).type(torch.long							).to(self.device							)

																		lowerCAmelCase_	: List[str]      			=			input_ids[index]
																		lowerCAmelCase_	: int      			=			attention_mask[index]  # shape (seq_len,)
																		lowerCAmelCase_	: Optional[Any]      			=			token_type_ids[index]  # shape (seq_len, 7)
																		lowerCAmelCase_	: Any      			=			self.model(
																		    input_ids=input_ids_example.unsqueeze(0							)				,  attention_mask=attention_mask_example.unsqueeze(0							)				,  token_type_ids=token_type_ids_example.unsqueeze(0							)				,  )
																		lowerCAmelCase_	: str      			=			outputs.logits

																		if self.aggregate:
																						all_aggregations.append(outputs.logits_aggregation							)

																		all_logits.append(__lowercase							)

																		lowerCAmelCase_	: str      			=			torch.distributions.Bernoulli(logits=__lowercase							)
																		lowerCAmelCase_	: Dict      			=			dist_per_token.probs * attention_mask_example.type(torch.floataa							).to(
																		    dist_per_token.probs.device							)

																		lowerCAmelCase_	: Dict      			=			collections.defaultdict(__lowercase							)
																		for i, p in enumerate(probabilities.squeeze().tolist()							):
																						lowerCAmelCase_	: List[Any]      			=			token_type_ids_example[:, 0].tolist()[i]
																						lowerCAmelCase_	: int      			=			token_type_ids_example[:, 1].tolist()[i] - 1
																						lowerCAmelCase_	: List[Any]      			=			token_type_ids_example[:, 2].tolist()[i] - 1
																						if col >= 0 and row >= 0 and segment_id == 1:
																										coords_to_probs[(col, row)].append(__lowercase							)

																		lowerCAmelCase_	: List[Any]      			=			{key: np.array(coords_to_probs[key]							).mean() > 0.5 for key in coords_to_probs}

														lowerCAmelCase_	: Union[str, Any]      			=			torch.cat(tuple(__lowercase							)				,  0							)

														return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(__lowercase							)				,  0							))
										else:
														lowerCAmelCase_	: int      			=			[]
														lowerCAmelCase_	: Dict      			=			[]
														lowerCAmelCase_	: str      			=			None
														lowerCAmelCase_	: int      			=			inputs['''input_ids'''].shape[0]

														lowerCAmelCase_	: Dict      			=			inputs['''input_ids''']
														lowerCAmelCase_	: Dict      			=			inputs['''attention_mask''']
														lowerCAmelCase_	: Dict      			=			inputs['''token_type_ids'''].numpy()
														lowerCAmelCase_	: Optional[Any]      			=			None

														for index in range(__lowercase							):
																		# If sequences have already been processed, the token type IDs will be created according to the previous
																		# answer.
																		if prev_answers is not None:
																						lowerCAmelCase_	: Optional[Any]      			=			token_type_ids_example[:, 3]  # shape (seq_len,)
																						lowerCAmelCase_	: Any      			=			np.zeros_like(__lowercase				,  dtype=np.intaa							)  # shape (seq_len,)

																						lowerCAmelCase_	: Dict      			=			token_type_ids[index]  # shape (seq_len, 7)
																						for i in range(model_labels.shape[0]							):
																										lowerCAmelCase_	: Tuple      			=			token_type_ids_example[:, 0].tolist()[i]
																										lowerCAmelCase_	: List[Any]      			=			token_type_ids_example[:, 1].tolist()[i] - 1
																										lowerCAmelCase_	: List[Any]      			=			token_type_ids_example[:, 2].tolist()[i] - 1

																										if row_id >= 0 and col_id >= 0 and segment_id == 1:
																														lowerCAmelCase_	: Dict      			=			int(prev_answers[(col_id, row_id)]							)

																						lowerCAmelCase_	: Tuple      			=			model_labels

																		lowerCAmelCase_	: str      			=			input_ids[index]
																		lowerCAmelCase_	: Tuple      			=			attention_mask[index]  # shape (seq_len,)
																		lowerCAmelCase_	: Any      			=			token_type_ids[index]  # shape (seq_len, 7)
																		lowerCAmelCase_	: List[str]      			=			self.model(
																		    input_ids=np.expand_dims(__lowercase				,  axis=0							)				,  attention_mask=np.expand_dims(__lowercase				,  axis=0							)				,  token_type_ids=np.expand_dims(__lowercase				,  axis=0							)				,  )
																		lowerCAmelCase_	: List[str]      			=			outputs.logits

																		if self.aggregate:
																						all_aggregations.append(outputs.logits_aggregation							)

																		all_logits.append(__lowercase							)

																		lowerCAmelCase_	: List[str]      			=			tfp.distributions.Bernoulli(logits=__lowercase							)
																		lowerCAmelCase_	: str      			=			dist_per_token.probs_parameter() * tf.cast(__lowercase				,  tf.floataa							)

																		lowerCAmelCase_	: Tuple      			=			collections.defaultdict(__lowercase							)
																		lowerCAmelCase_	: str      			=			token_type_ids_example
																		for i, p in enumerate(tf.squeeze(__lowercase							).numpy().tolist()							):
																						lowerCAmelCase_	: Optional[Any]      			=			token_type_ids_example[:, 0].tolist()[i]
																						lowerCAmelCase_	: int      			=			token_type_ids_example[:, 1].tolist()[i] - 1
																						lowerCAmelCase_	: str      			=			token_type_ids_example[:, 2].tolist()[i] - 1
																						if col >= 0 and row >= 0 and segment_id == 1:
																										coords_to_probs[(col, row)].append(__lowercase							)

																		lowerCAmelCase_	: str      			=			{key: np.array(coords_to_probs[key]							).mean() > 0.5 for key in coords_to_probs}

														lowerCAmelCase_	: Optional[Any]      			=			tf.concat(tuple(__lowercase							)				,  0							)

														return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(__lowercase							)				,  0							))




						def __call__(			self				,  *__lowercase				,  **__lowercase							)   ->      str:
										lowerCAmelCase_	: str      			=			self._args_parser(*__lowercase				,  **__lowercase							)

										lowerCAmelCase_	: List[Any]      			=			super().__call__(__lowercase				,  **__lowercase							)
										if len(__lowercase							) == 1:
														return results[0]
										return results




						def   lowercase_	(			self				,  __lowercase=None				,  __lowercase=None				,  __lowercase=None				,  **__lowercase							)   ->      List[Any]:
										lowerCAmelCase_	: Union[str, Any]      			=			{}
										if padding is not None:
														lowerCAmelCase_	: Union[str, Any]      			=			padding
										if truncation is not None:
														lowerCAmelCase_	: Dict      			=			truncation

										lowerCAmelCase_	: Union[str, Any]      			=			{}
										if sequential is not None:
														lowerCAmelCase_	: Dict      			=			sequential
										return preprocess_params, forward_params, {}




						def   lowercase_	(			self				,  __lowercase				,  __lowercase=None				,  __lowercase=True				,  __lowercase=None							)   ->      List[Any]:
										if truncation is None:
														if self.type == "tapas":
																		lowerCAmelCase_	: Tuple      			=			'''drop_rows_to_fit'''
														else:
																		lowerCAmelCase_	: Union[str, Any]      			=			'''do_not_truncate'''

										lowerCAmelCase_			,					lowerCAmelCase_	: int      			=			pipeline_input['''table'''], pipeline_input['''query''']
										if table.empty:
														raise ValueError('''table is empty'''							)
										if query is None or query == "":
														raise ValueError('''query is empty'''							)
										lowerCAmelCase_	: List[Any]      			=			self.tokenizer(__lowercase				,  __lowercase				,  return_tensors=self.framework				,  truncation=__lowercase				,  padding=__lowercase							)
										lowerCAmelCase_	: Tuple      			=			table
										return inputs




						def   lowercase_	(			self				,  __lowercase				,  __lowercase=False							)   ->      List[Any]:
										lowerCAmelCase_	: str      			=			model_inputs.pop('''table'''							)

										if self.type == "tapas":
														if sequential:
																		lowerCAmelCase_	: int      			=			self.sequential_inference(**__lowercase							)
														else:
																		lowerCAmelCase_	: Any      			=			self.batch_inference(**__lowercase							)
										else:
														lowerCAmelCase_	: int      			=			self.model.generate(**__lowercase							)
										lowerCAmelCase_	: Union[str, Any]      			=			{'''model_inputs''': model_inputs, '''table''': table, '''outputs''': outputs}
										return model_outputs




						def   lowercase_	(			self				,  __lowercase							)   ->      List[str]:
										lowerCAmelCase_	: Optional[int]      			=			model_outputs['''model_inputs''']
										lowerCAmelCase_	: Dict      			=			model_outputs['''table''']
										lowerCAmelCase_	: Dict      			=			model_outputs['''outputs''']
										if self.type == "tapas":
														if self.aggregate:
																		lowerCAmelCase_			,					lowerCAmelCase_	: List[str]      			=			outputs[:2]
																		lowerCAmelCase_	: str      			=			self.tokenizer.convert_logits_to_predictions(__lowercase				,  __lowercase				,  __lowercase							)
																		lowerCAmelCase_			,					lowerCAmelCase_	: List[str]      			=			predictions
																		lowerCAmelCase_	: Optional[Any]      			=			{i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(__lowercase							)}

																		lowerCAmelCase_	: List[Any]      			=			self.model.config.no_aggregation_label_index
																		lowerCAmelCase_	: Optional[Any]      			=			{
																		    i: aggregators[i] + ''' > ''' for i, pred in enumerate(__lowercase							) if pred != no_agg_label_index
																		}
														else:
																		lowerCAmelCase_	: int      			=			outputs[0]
																		lowerCAmelCase_	: Union[str, Any]      			=			self.tokenizer.convert_logits_to_predictions(__lowercase				,  __lowercase							)
																		lowerCAmelCase_	: Optional[Any]      			=			predictions[0]
																		lowerCAmelCase_	: List[Any]      			=			{}
																		lowerCAmelCase_	: Dict      			=			{}
														lowerCAmelCase_	: Optional[int]      			=			[]
														for index, coordinates in enumerate(__lowercase							):
																		lowerCAmelCase_	: Tuple      			=			[table.iat[coordinate] for coordinate in coordinates]
																		lowerCAmelCase_	: Dict      			=			aggregators.get(__lowercase				,  ''''''							)
																		lowerCAmelCase_	: Tuple      			=			aggregators_prefix.get(__lowercase				,  ''''''							)
																		lowerCAmelCase_	: Optional[int]      			=			{
																		    '''answer''': aggregator_prefix + ''', '''.join(__lowercase							),
																		    '''coordinates''': coordinates,
																		    '''cells''': [table.iat[coordinate] for coordinate in coordinates],
																		}
																		if aggregator:
																						lowerCAmelCase_	: str      			=			aggregator

																		answers.append(__lowercase							)
														if len(__lowercase							) == 0:
																		raise PipelineException('''Empty answer'''							)
										else:
														lowerCAmelCase_	: Any      			=			[{'''answer''': answer} for answer in self.tokenizer.batch_decode(__lowercase				,  skip_special_tokens=__lowercase							)]

										return answers if len(__lowercase							) > 1 else answers[0]



from __future__ import annotations



def      lowerCAmelCase	(						lowerCAmelCase_	,				lowerCAmelCase_	,				lowerCAmelCase_	)->	int | float:
				if len(lowerCAmelCase_	) == 0:
								raise ValueError('''find_min() arg is an empty sequence'''	)
				if (
				    left >= len(lowerCAmelCase_	)
				    or left < -len(lowerCAmelCase_	)
				    or right >= len(lowerCAmelCase_	)
				    or right < -len(lowerCAmelCase_	)
				):
								raise IndexError('''list index out of range'''	)
				if left == right:
								return nums[left]
				lowerCAmelCase_	: Any      			=			(left + right) >> 1  # the middle
				lowerCAmelCase_	: Tuple      			=			find_min(lowerCAmelCase_	,				lowerCAmelCase_	,				lowerCAmelCase_	)  # find min in range[left, mid]
				lowerCAmelCase_	: Any      			=			find_min(lowerCAmelCase_	,				mid + 1	,				lowerCAmelCase_	)  # find min in range[mid + 1, right]

				return left_min if left_min <= right_min else right_min


if __name__ == "__main__":
						import doctest

						doctest.testmod(verbose=True)