a
    dG3                  
   @   s   d dl Z d dlmZ d dlmZmZmZ d dlZd dlmZm	Z	 d dl
mZ d dlmZmZ d dlmZ dZd	ZG d
d dZdee eee  eeed eeee  edddZdS )    N)partial)ClassVarOptionalSequence)Tensortensor)Literal)_bleu_score_compute_bleu_score_update)_REGEX_AVAILABLEnone13azhintlchar))u   㐀u   䶵)u   一u   龥)u   龦u   龻)u   豈u   鶴)u   侮u   頻)u   並u   龎)u    0u   ⩭6)u   ⾀0u   ⾡d)u   ＀u   ￯)u   ⺀u   ⻿)u   　u   〿)u   ㇀u   ㇯)u   ⼀u   ⿟)u   ⿰u   ⿿)u   ㄀u   ㄯ)u   ㆠu   ㆿ)u   ︐u   ︟)u   ︰u   ﹏)u   ☀u   ⛿)u   ✀u   ➿)u   ㈀u   ㋿)u   ㌀u   ㏿c                   @   s  e Zd ZU dZeddfeddfeddfeddffZervd	d
lZeddfeddfeddffZ	ddddddZ
ee ed< d1ed ed
dddZeee dddZed2eed eee dddZeeeddd Zeeed!d"d#Zeeedd$d%Zeeedd&d'Zeeedd(d)Zeeedd*d+Zeeedd,d-Zeeeed.d/d0Zd
S )3_SacreBLEUTokenizerzTokenizer used for SacreBLEU calculation.

    Source: https://github.com/mjpost/sacrebleu/tree/master/sacrebleu/tokenizers

    z([\{-\~\[-\` -\&\(-\+\:-\@\/])z \1 z([^0-9])([\.,])z\1 \2 z([\.,])([^0-9])z \1 \2z
([0-9])(-)r   Nz(\P{N})(\p{P})z(\p{P})(\P{N})z(\p{S})_tokenize_base_tokenize_13a_tokenize_zh_tokenize_international_tokenize_charr   _TOKENIZE_FNF)tokenize	lowercasereturnc                 C   s   t | | j| | _|| _d S N)getattrr   tokenize_fnr   )selfr   r    r    p/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/functional/text/sacre_bleu.py__init__y   s    z_SacreBLEUTokenizer.__init__)liner   c                 C   s   |  |}| || j S r   )r   _lowerr   split)r   r#   tokenized_liner    r    r!   __call__}   s    
z_SacreBLEUTokenizer.__call__)r#   r   r   r   c                 C   s(   t | | j| }||}| || S r   )r   r   r$   r%   )clsr#   r   r   r   r&   r    r    r!   r      s    z_SacreBLEUTokenizer.tokenizec                 C   s*   | j D ]\}}|||}qd| S )zPost-processing tokenizer for `13a` and `zh` tokenizers.

        Args:
            line: a segment to tokenize

        Return:
            the tokenized line

         )_REGEXsubjoinr%   r(   r#   _rereplr    r    r!   _tokenize_regex   s    z#_SacreBLEUTokenizer._tokenize_regex)ucharr   c                    s   t  fddtD S )zCheck if character is chinese.

        Args:
            uchar: input char in unicode.

        Return:
            whether the input char is a Chinese character.

        c                 3   s*   | ]"\}}|   ko|kn  V  qd S r   r    ).0startendr1   r    r!   	<genexpr>       z7_SacreBLEUTokenizer._is_chinese_char.<locals>.<genexpr>)any_UCODE_RANGESr5   r    r5   r!   _is_chinese_char   s    z$_SacreBLEUTokenizer._is_chinese_charc                 C   s   |S )zTokenizes an input line with the tokenizer.

        Args:
            line: a segment to tokenize

        Return:
            the tokenized line

        r    r(   r#   r    r    r!   r      s    z"_SacreBLEUTokenizer._tokenize_basec                 C   sn   | dd}| dd}| dd}d|v r\| dd}| d	d}| d
d}| dd}| d| dS )zTokenizes a line using a relatively minimal tokenization that is equivalent to mteval-v13a, used by WMT.

        Args:
            line: input sentence

        Return:
            tokenized sentence

        z	<skipped> z-

r)   &z&quot;"z&amp;z&lt;<z&gt;>)replacer0   r;   r    r    r!   r      s    z!_SacreBLEUTokenizer._tokenize_13ac                 C   sL   |  }d}|D ]0}| |r8|d7 }||7 }|d7 }q||7 }q| |S )ap  Tokenization of Chinese text.

        This is done in two steps: separate each Chinese characters (by utf-8 encoding) and afterwards tokenize the
        Chinese part (following the `13a` i.e. mteval tokenizer).
        Author: Shujian Huang huangsj@nju.edu.cn.

        Args:
            line: input sentence

        Return:
            tokenized sentence

        r<   r)   )stripr:   r0   )r(   r#   Zline_in_charsr   r    r    r!   r      s    


z _SacreBLEUTokenizer._tokenize_zhc                 C   s*   | j D ]\}}|||}qd| S )a  Tokenizes a string following the official BLEU implementation.

        See github.com/moses-smt/mosesdecoder/blob/master/scripts/generic/mteval-v14.pl#L954-L983

        In our case, the input string is expected to be just one line.
        We just tokenize on punctuation and symbols,
        except when a punctuation is preceded and followed by a digit
        (e.g. a comma/dot as a thousand/decimal separator).
        We do not recover escaped forms of punctuations such as &apos; or &gt;
        as these should never appear in MT system outputs (see issue #138)

        Note that a number (e.g., a year) followed by a dot at the end of
        sentence is NOT tokenized, i.e. the dot stays with the number because
        `s/(\\p{P})(\\P{N})/ $1 $2/g` does not match this case (unless we add a
        space after each sentence). However, this error is already in the
        original mteval-v14.pl and we want to be consistent with it.
        The error is not present in the non-international version,
        which uses `$norm_text = " $norm_text "`.

        Args:
            line: the input string to tokenize.

        Return:
            The tokenized string.

        r)   )
_INT_REGEXr+   r,   r%   r-   r    r    r!   r      s    z+_SacreBLEUTokenizer._tokenize_internationalc                 C   s   d dd |D S )zTokenizes all the characters in the input line.

        Args:
            line: a segment to tokenize

        Return:
            the tokenized line

        r)   c                 s   s   | ]
}|V  qd S r   r    )r2   r   r    r    r!   r6     r7   z5_SacreBLEUTokenizer._tokenize_char.<locals>.<genexpr>)r,   r;   r    r    r!   r     s    z"_SacreBLEUTokenizer._tokenize_char)r#   r   r   c                 C   s   |r|   S | S r   )lower)r#   r   r    r    r!   r$     s    z_SacreBLEUTokenizer._lower)F)F)__name__
__module____qualname____doc__recompiler*   r   regexrD   r   r   dict__annotations__r   boolr"   strr   r'   classmethodr   r0   staticmethodr:   r   r   r   r   r   r$   r    r    r    r!   r   P   sT   

 
 r      Fr   )predstargetn_gramsmoothr   r   weightsr   c              	   C   s(  |t vrtdt  d| d|tj vrDtdttj  t| t|krptdt|  dt| |dkrtstd|d	urt||krtd
t| d| |d	u rd| g| }t	
|}t	
|}td}	td}
ttj||d}t| ||||	|
||\}	}
t|	|
|||||S )a  Calculate `BLEU score`_ [1] of machine translated text with one or more references.

    This implementation follows the behaviour of SacreBLEU [2] implementation from https://github.com/mjpost/sacrebleu.

    Args:
        preds: An iterable of machine translated corpus
        target: An iterable of iterables of reference corpus
        n_gram: Gram value ranged from 1 to 4
        smooth: Whether to apply smoothing - see [2]
        tokenize: Tokenization technique to be used.
            Supported tokenization: ['none', '13a', 'zh', 'intl', 'char']
        lowercase: If ``True``, BLEU score over lowercased text is calculated.
        weights:
            Weights used for unigrams, bigrams, etc. to calculate BLEU score.
            If not provided, uniform weights are used.

    Return:
        Tensor with BLEU Score

    Raises:
        ValueError: If ``preds`` and ``target`` corpus have different lengths.
        ValueError: If a length of a list of weights is not ``None`` and not equal to ``n_gram``.

    Example:
        >>> from torchmetrics.functional.text import sacre_bleu_score
        >>> preds = ['the cat is on the mat']
        >>> target = [['there is a cat on the mat', 'a cat is on the mat']]
        >>> sacre_bleu_score(preds, target)
        tensor(0.7598)

    References:
        [1] BLEU: a Method for Automatic Evaluation of Machine Translation by Papineni,
        Kishore, Salim Roukos, Todd Ward, and Wei-Jing Zhu `BLEU`_

        [2] A Call for Clarity in Reporting BLEU Scores by Matt Post.

        [3] Automatic Evaluation of Machine Translation Quality Using Longest Common Subsequence
        and Skip-Bigram Statistics by Chin-Yew Lin and Franz Josef Och `Machine Translation Evolution`_

    z*Argument `tokenize` expected to be one of z	 but got .z6Unsupported tokenizer selected. Please, choose one of zCorpus has different size z != r   zv`'intl'` tokenization requires that `regex` is installed. Use `pip install regex` or `pip install torchmetrics[text]`.Nz5List of weights has different weights than `n_gram`: g      ?g        )r   r   )AVAILABLE_TOKENIZERS
ValueErrorr   r   keyslistlenr   ModuleNotFoundErrortorchzerosr   r   r   r
   r	   )rT   rU   rV   rW   r   r   rX   	numeratordenominatorZ	preds_lenZ
target_lenr   r    r    r!   sacre_bleu_score  s@    1

rd   )rS   Fr   FN)rJ   	functoolsr   typingr   r   r   r`   r   r   Ztyping_extensionsr   Z!torchmetrics.functional.text.bleur	   r
   Ztorchmetrics.utilities.importsr   rZ   r9   r   rP   intrO   floatrd   r    r    r    r!   <module>(   s4    P     

