

import unittest

from transformers import BertGenerationTokenizer
from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_torch, slow
from transformers.utils import cached_property

from ...test_tokenization_common import TokenizerTesterMixin


lowercase_             =     '▁'

lowercase_             =     get_tests_dir('fixtures/test_sentencepiece.model')





@require_sentencepiece
class 				__lowerCAmelCase  (      lowerCamelCase__    ,    unittest.TestCase							):
  _a		    =						BertGenerationTokenizer
  _a		    =						False
  _a		    =						True




  def 						A__  (       self      )						->				Tuple:
        '''simple docstring'''






        super().setUp()

        _lowercase			 =BertGenerationTokenizer(__lowerCamelCase							,     keep_accents=__lowerCamelCase      )
        tokenizer.save_pretrained(self.tmpdirname      )




  def 						A__  (       self      )						->				Any:
        '''simple docstring'''






        _lowercase			 ='''<s>'''
        _lowercase			 =1

        self.assertEqual(self.get_tokenizer()._convert_token_to_id(__lowerCamelCase      )							,     __lowerCamelCase      )
        self.assertEqual(self.get_tokenizer()._convert_id_to_token(__lowerCamelCase      )							,     __lowerCamelCase      )




  def 						A__  (       self      )						->				List[Any]:
        '''simple docstring'''






        _lowercase			 =list(self.get_tokenizer().get_vocab().keys()      )

        self.assertEqual(vocab_keys[0]							,     '<unk>'      )
        self.assertEqual(vocab_keys[1]							,     '<s>'      )
        self.assertEqual(vocab_keys[-1]							,     '<pad>'      )
        self.assertEqual(len(__lowerCamelCase      )							,     1_002      )




  def 						A__  (       self      )						->				List[Any]:
        '''simple docstring'''






        self.assertEqual(self.get_tokenizer().vocab_size							,     1_000      )




  def 						A__  (       self      )						->				Union[str, Any]:
        '''simple docstring'''






        _lowercase			 =BertGenerationTokenizer(__lowerCamelCase							,     keep_accents=__lowerCamelCase      )

        _lowercase			 =tokenizer.tokenize('This is a test'      )
        self.assertListEqual(__lowerCamelCase							,     ['▁This', '▁is', '▁a', '▁t', 'est']      )

        self.assertListEqual(
            tokenizer.convert_tokens_to_ids(__lowerCamelCase      )							,     [285, 46, 10, 170, 382]							,     )

        _lowercase			 =tokenizer.tokenize('I was born in 92000, and this is falsé.'      )
        self.assertListEqual(
            __lowerCamelCase							,     [
                SPIECE_UNDERLINE + 'I',
                SPIECE_UNDERLINE + 'was',
                SPIECE_UNDERLINE + 'b',
                'or',
                'n',
                SPIECE_UNDERLINE + 'in',
                SPIECE_UNDERLINE + '',
                '9',
                '2',
                '0',
                '0',
                '0',
                ',',
                SPIECE_UNDERLINE + 'and',
                SPIECE_UNDERLINE + 'this',
                SPIECE_UNDERLINE + 'is',
                SPIECE_UNDERLINE + 'f',
                'al',
                's',
                'é',
                '.',
            ]							,     )
        _lowercase			 =tokenizer.convert_tokens_to_ids(__lowerCamelCase      )
        self.assertListEqual(
            __lowerCamelCase							,     [8, 21, 84, 55, 24, 19, 7, 0, 602, 347, 347, 347, 3, 12, 66, 46, 72, 80, 6, 0, 4]							,     )

        _lowercase			 =tokenizer.convert_ids_to_tokens(__lowerCamelCase      )
        self.assertListEqual(
            __lowerCamelCase							,     [
                SPIECE_UNDERLINE + 'I',
                SPIECE_UNDERLINE + 'was',
                SPIECE_UNDERLINE + 'b',
                'or',
                'n',
                SPIECE_UNDERLINE + 'in',
                SPIECE_UNDERLINE + '',
                '<unk>',
                '2',
                '0',
                '0',
                '0',
                ',',
                SPIECE_UNDERLINE + 'and',
                SPIECE_UNDERLINE + 'this',
                SPIECE_UNDERLINE + 'is',
                SPIECE_UNDERLINE + 'f',
                'al',
                's',
                '<unk>',
                '.',
            ]							,     )




  @cached_property
  def 						A__  (       self      )						->				Tuple:
        '''simple docstring'''






        return BertGenerationTokenizer.from_pretrained('google/bert_for_seq_generation_L-24_bbc_encoder'      )




  @slow
  def 						A__  (       self      )						->				int:
        '''simple docstring'''






        _lowercase			 ='''Hello World!'''
        _lowercase			 =[18_536, 2_260, 101]

        self.assertListEqual(__lowerCamelCase							,     self.big_tokenizer.encode(__lowerCamelCase      )      )




  @slow
  def 						A__  (       self      )						->				List[Any]:
        '''simple docstring'''






        _lowercase			 =(
            '''This is a very long text with a lot of weird characters, such as: . , ~ ? ( ) " [ ] ! : - . Also we will'''
            ''' add words that should not exsist and be tokenized to <unk>, such as saoneuhaoesuth'''
        )
        _lowercase			 =[
            871,
            419,
            358,
            946,
            991,
            2_521,
            452,
            358,
            1_357,
            387,
            7_751,
            3_536,
            112,
            985,
            456,
            126,
            865,
            938,
            5_400,
            5_734,
            458,
            1_368,
            467,
            786,
            2_462,
            5_246,
            1_159,
            633,
            865,
            4_519,
            457,
            582,
            852,
            2_557,
            427,
            916,
            508,
            405,
            34_324,
            497,
            391,
            408,
            11_342,
            1_244,
            385,
            100,
            938,
            985,
            456,
            574,
            362,
            12_597,
            3_200,
            3_129,
            1_172,
        ]

        self.assertListEqual(__lowerCamelCase							,     self.big_tokenizer.encode(__lowerCamelCase      )      )




  @require_torch
  @slow
  def 						A__  (       self      )						->				Dict:
        '''simple docstring'''






        import torch

        from transformers import BertGenerationConfig, BertGenerationEncoder

        # Build sequence
        _lowercase			 =list(self.big_tokenizer.get_vocab().keys()      )[:10]
        _lowercase			 =''' '''.join(__lowerCamelCase      )
        _lowercase			 =self.big_tokenizer.encode_plus(__lowerCamelCase							,     return_tensors='pt'							,     return_token_type_ids=__lowerCamelCase      )
        _lowercase			 =self.big_tokenizer.batch_encode_plus(
            [sequence + ' ' + sequence]							,     return_tensors='pt'							,     return_token_type_ids=__lowerCamelCase      )

        _lowercase			 =BertGenerationConfig()
        _lowercase			 =BertGenerationEncoder(__lowerCamelCase      )

        assert model.get_input_embeddings().weight.shape[0] >= self.big_tokenizer.vocab_size

        with torch.no_grad():
              model(**__lowerCamelCase      )
              model(**__lowerCamelCase      )




  @slow
  def 						A__  (       self      )						->				Tuple:
        '''simple docstring'''






        _lowercase			 ={'''input_ids''': [[39_286, 458, 36_335, 2_001, 456, 13_073, 13_266, 455, 113, 7_746, 1_741, 11_157, 391, 13_073, 13_266, 455, 113, 3_967, 35_412, 113, 4_936, 109, 3_870, 2_377, 113, 30_084, 45_720, 458, 134, 17_496, 112, 503, 11_672, 113, 118, 112, 5_665, 13_347, 38_687, 112, 1_496, 31_389, 112, 3_268, 47_264, 134, 962, 112, 16_377, 8_035, 23_130, 430, 12_169, 15_518, 28_592, 458, 146, 41_697, 109, 391, 12_169, 15_518, 16_689, 458, 146, 41_358, 109, 452, 726, 4_034, 111, 763, 35_412, 5_082, 388, 1_903, 111, 9_051, 391, 2_870, 48_918, 1_900, 1_123, 550, 998, 112, 9_586, 15_985, 455, 391, 410, 22_955, 37_636, 114], [448, 17_496, 419, 3_663, 385, 763, 113, 27_533, 2_870, 3_283, 13_043, 1_639, 24_713, 523, 656, 24_013, 18_550, 2_521, 517, 27_014, 21_244, 420, 1_212, 1_465, 391, 927, 4_833, 388, 578, 11_786, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [484, 2_169, 7_687, 21_932, 18_146, 726, 363, 17_032, 3_391, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], '''attention_mask''': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]}  # noqa: E501
        # fmt: on

        self.tokenizer_integration_test_util(
            expected_encoding=__lowerCamelCase							,     model_name='google/bert_for_seq_generation_L-24_bbc_encoder'							,     revision='c817d1fd1be2ffa69431227a1fe320544943d4db'							,     )





import os
from pathlib import Path

import numpy as np
import pytest
from pack_dataset import pack_data_dir
from parameterized import parameterized
from save_len_file import save_len_file
from torch.utils.data import DataLoader

from transformers import AutoTokenizer
from transformers.models.mbart.modeling_mbart import shift_tokens_right
from transformers.testing_utils import TestCasePlus, slow
from utils import FAIRSEQ_AVAILABLE, DistributedSortishSampler, LegacySeqaSeqDataset, SeqaSeqDataset


lowercase_             =     'bert-base-cased'
lowercase_             =     'google/pegasus-xsum'
lowercase_             =     [' Sam ate lunch today.', 'Sams lunch ingredients.']
lowercase_             =     ['A very interesting story about what I ate for lunch.', 'Avocado, celery, turkey, coffee']
lowercase_             =     'patrickvonplaten/t5-tiny-random'
lowercase_             =     'sshleifer/bart-tiny-random'
lowercase_             =     'sshleifer/tiny-mbart'
lowercase_             =     'sshleifer/tiny-marian-en-de'
def   a   (    A__			:     Path   ,     A__			:     list  )					->   Tuple:





      """simple docstring"""



      _lowercase			 ='\n'.join(A__  )
      Path(A__  ).open('w'  ).writelines(A__  )
def   a   (    A__			:     str  )					->   Union[str, Any]:





      """simple docstring"""



      for split in ["train", "val", "test"]:
            _dump_articles(os.path.join(A__   ,     F'''{split}.source'''  )   ,     A__  )
            _dump_articles(os.path.join(A__   ,     F'''{split}.target'''  )   ,     A__  )
      return tmp_dir







class 				__lowerCAmelCase  (      SCREAMING_SNAKE_CASE							):




  @parameterized.expand(
      [
          MBART_TINY,
          MARIAN_TINY,
          T5_TINY,
          BART_TINY,
          PEGASUS_XSUM,
      ]							,     )
  @slow
  def 						A__  (       self							,     lowerCAmelCase      )						->				List[str]:
        '''simple docstring'''






        _lowercase			 =AutoTokenizer.from_pretrained(lowerCAmelCase      )
        _lowercase			 =make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()      )
        _lowercase			 =max(len(tokenizer.encode(lowerCAmelCase      )      ) for a in ARTICLES      )
        _lowercase			 =max(len(tokenizer.encode(lowerCAmelCase      )      ) for a in SUMMARIES      )
        _lowercase			 =4
        _lowercase			 =8
        assert max_len_target > max_src_len  # Will be truncated
        assert max_len_source > max_src_len  # Will be truncated
        _lowercase , _lowercase			 ='ro_RO', 'de_DE'  # ignored for all but mbart, but never causes error.
        _lowercase			 =SeqaSeqDataset(
            lowerCAmelCase							,     data_dir=lowerCAmelCase							,     type_path='train'							,     max_source_length=lowerCAmelCase							,     max_target_length=lowerCAmelCase							,     src_lang=lowerCAmelCase							,     tgt_lang=lowerCAmelCase							,     )
        _lowercase			 =DataLoader(lowerCAmelCase							,     batch_size=2							,     collate_fn=train_dataset.collate_fn      )
        for batch in dataloader:
              assert isinstance(lowerCAmelCase							,     lowerCAmelCase      )
              assert batch["attention_mask"].shape == batch["input_ids"].shape
              # show that articles were trimmed.
              assert batch["input_ids"].shape[1] == max_src_len
              # show that targets are the same len
              assert batch["labels"].shape[1] == max_tgt_len
              if tok_name != MBART_TINY:
                    continue
              # check language codes in correct place
              _lowercase			 =shift_tokens_right(batch['labels']							,     tokenizer.pad_token_id      )
              assert batch["decoder_input_ids"][0, 0].item() == tokenizer.lang_code_to_id[tgt_lang]
              assert batch["decoder_input_ids"][0, -1].item() == tokenizer.eos_token_id
              assert batch["input_ids"][0, -2].item() == tokenizer.eos_token_id
              assert batch["input_ids"][0, -1].item() == tokenizer.lang_code_to_id[src_lang]

              break  # No need to test every batch




  @parameterized.expand([BART_TINY, BERT_BASE_CASED]      )
  def 						A__  (       self							,     lowerCAmelCase      )						->				str:
        '''simple docstring'''






        _lowercase			 =AutoTokenizer.from_pretrained(lowerCAmelCase      )
        _lowercase			 =make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()      )
        _lowercase			 =max(len(tokenizer.encode(lowerCAmelCase      )      ) for a in ARTICLES      )
        _lowercase			 =max(len(tokenizer.encode(lowerCAmelCase      )      ) for a in SUMMARIES      )
        _lowercase			 =4
        _lowercase			 =LegacySeqaSeqDataset(
            lowerCAmelCase							,     data_dir=lowerCAmelCase							,     type_path='train'							,     max_source_length=20							,     max_target_length=lowerCAmelCase							,     )
        _lowercase			 =DataLoader(lowerCAmelCase							,     batch_size=2							,     collate_fn=train_dataset.collate_fn      )
        for batch in dataloader:
              assert batch["attention_mask"].shape == batch["input_ids"].shape
              # show that articles were trimmed.
              assert batch["input_ids"].shape[1] == max_len_source
              assert 20 >= batch["input_ids"].shape[1]  # trimmed significantly
              # show that targets were truncated
              assert batch["labels"].shape[1] == trunc_target  # Truncated
              assert max_len_target > trunc_target  # Truncated
              break  # No need to test every batch




  def 						A__  (       self      )						->				List[str]:
        '''simple docstring'''






        _lowercase			 =AutoTokenizer.from_pretrained('facebook/mbart-large-cc25'      )

        _lowercase			 =Path(make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()      )      )
        _lowercase			 =tmp_dir.joinpath('train.source'      ).open().readlines()
        _lowercase			 =Path(make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()      )      )
        pack_data_dir(lowerCAmelCase							,     lowerCAmelCase							,     128							,     lowerCAmelCase      )
        _lowercase			 ={x.name for x in tmp_dir.iterdir()}
        _lowercase			 ={x.name for x in save_dir.iterdir()}
        _lowercase			 =save_dir.joinpath('train.source'      ).open().readlines()
        # orig: [' Sam ate lunch today.\n', 'Sams lunch ingredients.']
        # desired_packed: [' Sam ate lunch today.\n Sams lunch ingredients.']
        assert len(lowerCAmelCase      ) < len(lowerCAmelCase      )
        assert len(lowerCAmelCase      ) == 1
        assert len(packed_examples[0]      ) == sum(len(lowerCAmelCase      ) for x in orig_examples      )
        assert orig_paths == new_paths




  @pytest.mark.skipif(not FAIRSEQ_AVAILABLE							,     reason='This test requires fairseq'      )
  def 						A__  (       self      )						->				int:
        '''simple docstring'''






        if not FAIRSEQ_AVAILABLE:
              return
        _lowercase , _lowercase , _lowercase			 =self._get_dataset(max_len=64      )
        _lowercase			 =64
        _lowercase			 =ds.make_dynamic_sampler(lowerCAmelCase							,     required_batch_size_multiple=lowerCAmelCase      )
        _lowercase			 =[len(lowerCAmelCase      ) for x in batch_sampler]
        assert len(set(lowerCAmelCase      )      ) > 1  # it's not dynamic batch size if every batch is the same length
        assert sum(lowerCAmelCase      ) == len(lowerCAmelCase      )  # no dropped or added examples
        _lowercase			 =DataLoader(lowerCAmelCase							,     batch_sampler=lowerCAmelCase							,     collate_fn=ds.collate_fn							,     num_workers=2      )
        _lowercase			 =[]
        _lowercase			 =[]
        for batch in data_loader:
              _lowercase			 =batch['input_ids'].shape
              _lowercase			 =src_shape[0]
              assert bs % required_batch_size_multiple == 0 or bs < required_batch_size_multiple
              _lowercase			 =np.product(batch['input_ids'].shape      )
              num_src_per_batch.append(lowerCAmelCase      )
              if num_src_tokens > (max_tokens * 1.1):
                    failures.append(lowerCAmelCase      )
        assert num_src_per_batch[0] == max(lowerCAmelCase      )
        if failures:
              raise AssertionError(F'''too many tokens in {len(lowerCAmelCase      )} batches'''      )




  def 						A__  (       self      )						->				List[str]:
        '''simple docstring'''






        _lowercase , _lowercase , _lowercase			 =self._get_dataset(max_len=512      )
        _lowercase			 =2
        _lowercase			 =ds.make_sortish_sampler(lowerCAmelCase							,     shuffle=lowerCAmelCase      )

        _lowercase			 =DataLoader(lowerCAmelCase							,     batch_size=lowerCAmelCase							,     collate_fn=ds.collate_fn							,     num_workers=2      )
        _lowercase			 =DataLoader(lowerCAmelCase							,     batch_size=lowerCAmelCase							,     collate_fn=ds.collate_fn							,     num_workers=2							,     sampler=lowerCAmelCase      )

        _lowercase			 =tokenizer.pad_token_id

        def count_pad_tokens(lowerCAmelCase							,     lowerCAmelCase="input_ids"      ):
              return [batch[k].eq(lowerCAmelCase      ).sum().item() for batch in data_loader]

        assert sum(count_pad_tokens(lowerCAmelCase							,     k='labels'      )      ) < sum(count_pad_tokens(lowerCAmelCase							,     k='labels'      )      )
        assert sum(count_pad_tokens(lowerCAmelCase      )      ) < sum(count_pad_tokens(lowerCAmelCase      )      )
        assert len(lowerCAmelCase      ) == len(lowerCAmelCase      )




  def 						A__  (       self							,     lowerCAmelCase=1_000							,     lowerCAmelCase=128      )						->				Union[str, Any]:
        '''simple docstring'''






        if os.getenv('USE_REAL_DATA'							,     lowerCAmelCase      ):
              _lowercase			 ='examples/seq2seq/wmt_en_ro'
              _lowercase			 =max_len * 2 * 64
              if not Path(lowerCAmelCase      ).joinpath('train.len'      ).exists():
                    save_len_file(lowerCAmelCase							,     lowerCAmelCase      )
        else:
              _lowercase			 ='examples/seq2seq/test_data/wmt_en_ro'
              _lowercase			 =max_len * 4
              save_len_file(lowerCAmelCase							,     lowerCAmelCase      )

        _lowercase			 =AutoTokenizer.from_pretrained(lowerCAmelCase      )
        _lowercase			 =SeqaSeqDataset(
            lowerCAmelCase							,     data_dir=lowerCAmelCase							,     type_path='train'							,     max_source_length=lowerCAmelCase							,     max_target_length=lowerCAmelCase							,     n_obs=lowerCAmelCase							,     )
        return ds, max_tokens, tokenizer




  def 						A__  (       self      )						->				int:
        '''simple docstring'''






        _lowercase , _lowercase , _lowercase			 =self._get_dataset()
        _lowercase			 =set(DistributedSortishSampler(lowerCAmelCase							,     256							,     num_replicas=2							,     rank=0							,     add_extra_examples=lowerCAmelCase      )      )
        _lowercase			 =set(DistributedSortishSampler(lowerCAmelCase							,     256							,     num_replicas=2							,     rank=1							,     add_extra_examples=lowerCAmelCase      )      )
        assert idsa.intersection(lowerCAmelCase      ) == set()




  @parameterized.expand(
      [
          MBART_TINY,
          MARIAN_TINY,
          T5_TINY,
          BART_TINY,
          PEGASUS_XSUM,
      ]							,     )
  def 						A__  (       self							,     lowerCAmelCase      )						->				Dict:
        '''simple docstring'''






        _lowercase			 =AutoTokenizer.from_pretrained(lowerCAmelCase							,     use_fast=lowerCAmelCase      )
        if tok_name == MBART_TINY:
              _lowercase			 =SeqaSeqDataset(
                  lowerCAmelCase							,     data_dir=make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()      )							,     type_path='train'							,     max_source_length=4							,     max_target_length=8							,     src_lang='EN'							,     tgt_lang='FR'							,     )
              _lowercase			 =train_dataset.dataset_kwargs
              assert "src_lang" in kwargs and "tgt_lang" in kwargs
        else:
              _lowercase			 =SeqaSeqDataset(
                  lowerCAmelCase							,     data_dir=make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()      )							,     type_path='train'							,     max_source_length=4							,     max_target_length=8							,     )
              _lowercase			 =train_dataset.dataset_kwargs
              assert "add_prefix_space" not in kwargs if tok_name != BART_TINY else "add_prefix_space" in kwargs
              assert len(lowerCAmelCase      ) == 1 if tok_name == BART_TINY else len(lowerCAmelCase      ) == 0


