


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 				lowerCamelCase__       (	lowerCAmelCase):





     def __call__(self		,					UpperCAmelCase=None		,					UpperCAmelCase=None		,					**UpperCAmelCase	)					->       int:
      # 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(UpperCAmelCase		,					UpperCAmelCase	) and table.get('''query'''	) is not None and table.get('''table'''	) is not None:
        _lowercase											=[table]
       elif isinstance(UpperCAmelCase		,					UpperCAmelCase	) and len(UpperCAmelCase	) > 0:
        if not all(isinstance(UpperCAmelCase		,					UpperCAmelCase	) for d in table	):
         raise ValueError(
             f"Keyword argument `table` should be a list of dict, but is {(type(UpperCAmelCase	) for d in table)}"	)

        if table[0].get('''query'''	) is not None and table[0].get('''table'''	) is not None:
         _lowercase											=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(UpperCAmelCase		,					UpperCAmelCase	) or isinstance(UpperCAmelCase		,					types.GeneratorType	):
        return table
       else:
        raise ValueError(
            '''Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but '''
            f"is {type(UpperCAmelCase	)})"	)
      else:
       _lowercase											=[{'''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.'''	)

        _lowercase											=pd.DataFrame(tqa_pipeline_input['''table''']	)

      return tqa_pipeline_inputs







@add_end_docstrings(lowerCAmelCase)
class 				lowerCamelCase__       (	lowerCAmelCase):
     SCREAMING_SNAKE_CASE__				      =      '''table,query'''





     def __init__(self		,					UpperCAmelCase=TableQuestionAnsweringArgumentHandler()		,					*UpperCAmelCase		,					**UpperCAmelCase	)					->       str:
      super().__init__(*UpperCAmelCase		,					**UpperCAmelCase	)
      _lowercase											=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()	)	)

      _lowercase											=bool(getattr(self.model.config		,					'''aggregation_labels'''		,					UpperCAmelCase	)	) and bool(
          getattr(self.model.config		,					'''num_aggregation_labels'''		,					UpperCAmelCase	)	)
      _lowercase											='''tapas''' if hasattr(self.model.config		,					'''aggregation_labels'''	) else None





     def 					__A (self		,					**UpperCAmelCase	)					->       int:
      return self.model(**UpperCAmelCase	)





     def 					__A (self		,					**UpperCAmelCase	)					->       Optional[Any]:
      if self.framework == "pt":
       _lowercase											=[]
       _lowercase											=[]
       _lowercase											=None
       _lowercase											=inputs['''input_ids'''].shape[0]

       _lowercase											=inputs['''input_ids'''].to(self.device	)
       _lowercase											=inputs['''attention_mask'''].to(self.device	)
       _lowercase											=inputs['''token_type_ids'''].to(self.device	)
       _lowercase											=None

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

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

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

         _lowercase											=torch.from_numpy(UpperCAmelCase	).type(torch.long	).to(self.device	)

        _lowercase											=input_ids[index]
        _lowercase											=attention_mask[index]  # shape (seq_len,)
        _lowercase											=token_type_ids[index]  # shape (seq_len, 7)
        _lowercase											=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	)		,					)
        _lowercase											=outputs.logits

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

        all_logits.append(UpperCAmelCase	)

        _lowercase											=torch.distributions.Bernoulli(logits=UpperCAmelCase	)
        _lowercase											=dist_per_token.probs * attention_mask_example.type(torch.floataa	).to(
            dist_per_token.probs.device	)

        _lowercase											=collections.defaultdict(UpperCAmelCase	)
        for i, p in enumerate(probabilities.squeeze().tolist()	):
         _lowercase											=token_type_ids_example[:, 0].tolist()[i]
         _lowercase											=token_type_ids_example[:, 1].tolist()[i] - 1
         _lowercase											=token_type_ids_example[:, 2].tolist()[i] - 1
         if col >= 0 and row >= 0 and segment_id == 1:
          coords_to_probs[(col, row)].append(UpperCAmelCase	)

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

       _lowercase											=torch.cat(tuple(UpperCAmelCase	)		,					0	)

       return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(UpperCAmelCase	)		,					0	))
      else:
       _lowercase											=[]
       _lowercase											=[]
       _lowercase											=None
       _lowercase											=inputs['''input_ids'''].shape[0]

       _lowercase											=inputs['''input_ids''']
       _lowercase											=inputs['''attention_mask''']
       _lowercase											=inputs['''token_type_ids'''].numpy()
       _lowercase											=None

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

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

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

         _lowercase											=model_labels

        _lowercase											=input_ids[index]
        _lowercase											=attention_mask[index]  # shape (seq_len,)
        _lowercase											=token_type_ids[index]  # shape (seq_len, 7)
        _lowercase											=self.model(
            input_ids=np.expand_dims(UpperCAmelCase		,					axis=0	)		,					attention_mask=np.expand_dims(UpperCAmelCase		,					axis=0	)		,					token_type_ids=np.expand_dims(UpperCAmelCase		,					axis=0	)		,					)
        _lowercase											=outputs.logits

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

        all_logits.append(UpperCAmelCase	)

        _lowercase											=tfp.distributions.Bernoulli(logits=UpperCAmelCase	)
        _lowercase											=dist_per_token.probs_parameter() * tf.cast(UpperCAmelCase		,					tf.floataa	)

        _lowercase											=collections.defaultdict(UpperCAmelCase	)
        _lowercase											=token_type_ids_example
        for i, p in enumerate(tf.squeeze(UpperCAmelCase	).numpy().tolist()	):
         _lowercase											=token_type_ids_example[:, 0].tolist()[i]
         _lowercase											=token_type_ids_example[:, 1].tolist()[i] - 1
         _lowercase											=token_type_ids_example[:, 2].tolist()[i] - 1
         if col >= 0 and row >= 0 and segment_id == 1:
          coords_to_probs[(col, row)].append(UpperCAmelCase	)

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

       _lowercase											=tf.concat(tuple(UpperCAmelCase	)		,					0	)

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





     def __call__(self		,					*UpperCAmelCase		,					**UpperCAmelCase	)					->       Optional[int]:
      _lowercase											=self._args_parser(*UpperCAmelCase		,					**UpperCAmelCase	)

      _lowercase											=super().__call__(UpperCAmelCase		,					**UpperCAmelCase	)
      if len(UpperCAmelCase	) == 1:
       return results[0]
      return results





     def 					__A (self		,					UpperCAmelCase=None		,					UpperCAmelCase=None		,					UpperCAmelCase=None		,					**UpperCAmelCase	)					->       List[Any]:
      _lowercase											={}
      if padding is not None:
       _lowercase											=padding
      if truncation is not None:
       _lowercase											=truncation

      _lowercase											={}
      if sequential is not None:
       _lowercase											=sequential
      return preprocess_params, forward_params, {}





     def 					__A (self		,					UpperCAmelCase		,					UpperCAmelCase=None		,					UpperCAmelCase=True		,					UpperCAmelCase=None	)					->       Optional[int]:
      if truncation is None:
       if self.type == "tapas":
        _lowercase											='''drop_rows_to_fit'''
       else:
        _lowercase											='''do_not_truncate'''

      _lowercase				,   _lowercase											=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'''	)
      _lowercase											=self.tokenizer(UpperCAmelCase		,					UpperCAmelCase		,					return_tensors=self.framework		,					truncation=UpperCAmelCase		,					padding=UpperCAmelCase	)
      _lowercase											=table
      return inputs





     def 					__A (self		,					UpperCAmelCase		,					UpperCAmelCase=False	)					->       Optional[Any]:
      _lowercase											=model_inputs.pop('''table'''	)

      if self.type == "tapas":
       if sequential:
        _lowercase											=self.sequential_inference(**UpperCAmelCase	)
       else:
        _lowercase											=self.batch_inference(**UpperCAmelCase	)
      else:
       _lowercase											=self.model.generate(**UpperCAmelCase	)
      _lowercase											={'''model_inputs''': model_inputs, '''table''': table, '''outputs''': outputs}
      return model_outputs





     def 					__A (self		,					UpperCAmelCase	)					->       List[Any]:
      _lowercase											=model_outputs['''model_inputs''']
      _lowercase											=model_outputs['''table''']
      _lowercase											=model_outputs['''outputs''']
      if self.type == "tapas":
       if self.aggregate:
        _lowercase				,   _lowercase											=outputs[:2]
        _lowercase											=self.tokenizer.convert_logits_to_predictions(UpperCAmelCase		,					UpperCAmelCase		,					UpperCAmelCase	)
        _lowercase				,   _lowercase											=predictions
        _lowercase											={i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(UpperCAmelCase	)}

        _lowercase											=self.model.config.no_aggregation_label_index
        _lowercase											={
            i: aggregators[i] + ''' > ''' for i, pred in enumerate(UpperCAmelCase	) if pred != no_agg_label_index
        }
       else:
        _lowercase											=outputs[0]
        _lowercase											=self.tokenizer.convert_logits_to_predictions(UpperCAmelCase		,					UpperCAmelCase	)
        _lowercase											=predictions[0]
        _lowercase											={}
        _lowercase											={}
       _lowercase											=[]
       for index, coordinates in enumerate(UpperCAmelCase	):
        _lowercase											=[table.iat[coordinate] for coordinate in coordinates]
        _lowercase											=aggregators.get(UpperCAmelCase		,					''''''	)
        _lowercase											=aggregators_prefix.get(UpperCAmelCase		,					''''''	)
        _lowercase											={
            '''answer''': aggregator_prefix + ''', '''.join(UpperCAmelCase	),
            '''coordinates''': coordinates,
            '''cells''': [table.iat[coordinate] for coordinate in coordinates],
        }
        if aggregator:
         _lowercase											=aggregator

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

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





UpperCAmelCase__            =							[
    [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
    [0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0],
    [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
]
def     UpperCAmelCase_ (							__snake_case					,						__snake_case					,						__snake_case					,						__snake_case						)					->      bool:







 """simple docstring"""


 return 0 <= row < rows and 0 <= col < cols
def     UpperCAmelCase_ (							__snake_case					,						__snake_case					,						__snake_case					,						__snake_case						)					->      int:







 """simple docstring"""


 _lowercase											=len(__snake_case						)
 _lowercase											=len(mat[0]						)
 if is_safe(__snake_case					,						__snake_case					,						__snake_case					,						__snake_case						) and (row, col) not in seen and mat[row][col] == 1:
  seen.add((row, col)						)
  return (
      1
      + depth_first_search(row + 1					,						__snake_case					,						__snake_case					,						__snake_case						)
      + depth_first_search(row - 1					,						__snake_case					,						__snake_case					,						__snake_case						)
      + depth_first_search(__snake_case					,						col + 1					,						__snake_case					,						__snake_case						)
      + depth_first_search(__snake_case					,						col - 1					,						__snake_case					,						__snake_case						)
  )
 else:
  return 0
def     UpperCAmelCase_ (							__snake_case						)					->      int:







 """simple docstring"""


 _lowercase											=set()

 _lowercase											=0
 for row, line in enumerate(__snake_case						):
  for col, item in enumerate(__snake_case						):
   if item == 1 and (row, col) not in seen:
    # Maximizing the area
    _lowercase											=max(__snake_case					,						depth_first_search(__snake_case					,						__snake_case					,						__snake_case					,						__snake_case						)						)
 return max_area


if __name__ == "__main__":
  import doctest

  print(find_max_area(matrix))  # Output -> 6
  doctest.testmod()

