o
    5ti)                     @   s   d Z ddlmZmZmZmZ ddlmZ ddlm	Z	 ddl
mZmZmZ ddlmZmZ G d	d
 d
eZG dd deZG dd deZdS )uN   The implementation of chrF (Popović 2015) and chrF++ (Popović 2017) metrics.    )ListSequenceOptionalDict)Counter   )sum_of_lists   )Score	SignatureMetric)extract_all_char_ngramsextract_word_ngramsc                       s&   e Zd ZdZdef fddZ  ZS )CHRFSignaturezA convenience class to represent the reproducibility signature for chrF.

    :param args: key-value dictionary passed from the actual metric instance.
    argsc                    sl   t  | | jdddddd | j|d rdnd	|d
 s"dnd|d |d |d r/dndd dS )z`CHRFSignature` initializer.cencnws)caseeffr   r   space	lowercaselcmixedeps_smoothingyesno
char_order
word_order
whitespaceN)super__init___abbrupdateinfo)selfr   	__class__ J/home/ubuntu/.local/lib/python3.10/site-packages/sacrebleu/metrics/chrf.pyr#      s   zCHRFSignature.__init__)__name__
__module____qualname____doc__dictr#   __classcell__r*   r*   r(   r+   r      s    r   c                       s2   e Zd ZdZdedededef fddZ  ZS )	CHRFScorea9  A convenience class to represent chrF scores.

    :param score: The chrF (chrF++) score.
    :param char_order: The character n-gram order.
    :param word_order: The word n-gram order. If equals to 2, the metric is referred to as chrF++.
    :param beta: Determine the importance of recall w.r.t precision.
    scorer   r    betac                    s:   || _ || _|| _d| j  d| j  }t || dS )z`CHRFScore` initializer.chrF+N)r4   r   r    r"   r#   )r'   r3   r   r    r4   namer(   r*   r+   r#   ,   s
   zCHRFScore.__init__)r,   r-   r.   r/   floatintr#   r1   r*   r*   r(   r+   r2   $   s    &r2   c                       s>  e Zd ZdZdZdZdZedZe	Z
eeeddddfded	ed
ededededeeee   f fddZedededee fddZdedee fddZdedefddZdee defddZdee defdd Zdeee  defd!d"Zd#ee deeeee  f fd$d%Zd&ed'edee fd(d)Z  ZS )*CHRFal  Computes the chrF(++) metric given hypotheses and references.

    :param char_order: Character n-gram order.
    :param word_order: Word n-gram order. If equals to 2, the metric is referred to as chrF++.
    :param beta: Determine the importance of recall w.r.t precision.
    :param lowercase: Enable case-insensitivity.
    :param whitespace: If `True`, include whitespaces when extracting character n-grams.
    :param eps_smoothing: If `True`, applies epsilon smoothing similar
    to reference chrF++.py, NLTK and Moses implementations. Otherwise,
    it takes into account effective match order similar to sacreBLEU < 2.0.0.
    :param references: A sequence of reference documents with document being
    defined as a sequence of reference strings. If given, the reference n-grams
    will be pre-computed and cached for faster re-computation across many systems.
       r   r   z !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~FNr   r    r4   r   r!   r   
referencesc                    sX   t    || _|| _|| _| j| j | _|| _|| _|| _|dur*| 	|| _
dS dS )z`CHRF` initializer.N)r"   r#   r4   r   r    orderr   r!   r   _cache_references
_ref_cache)r'   r   r    r4   r   r!   r   r<   r(   r*   r+   r#   V   s   
zCHRF.__init__
hyp_ngrams
ref_ngramsreturnc                 C   sV   d\}}|   D ]\}}||7 }||v r|t||| 7 }q|r"|ndt| |gS )a`  Computes the match statistics between hypothesis and reference n-grams.

        :param hyp_ngrams: A `Counter` holding hypothesis n-grams.
        :param ref_ngrams: A `Counter` holding reference n-grams.
        :return: A list of three numbers denoting hypothesis n-gram count,
            reference n-gram count and the intersection count.
        )r   r   r   )itemsminsumvalues)r@   rA   match_count	hyp_countngcountr*   r*   r+   _get_match_statisticsl   s   


zCHRF._get_match_statisticssentc                 C   s   g }|  D ];}t|dkr|| q|d | jv r(||dd |d g7 }q|d | jv r<||d |dd g7 }q|| q|S )zSeparates out punctuations from beginning and end of words for chrF.
        Adapted from https://github.com/m-popovic/chrF

        :param sent: A string.
        :return: A list of words.
        r	   Nr   )splitlenappend_PUNCTS)r'   rL   	tokenizedwr*   r*   r+   _remove_punctuation   s   zCHRF._remove_punctuationc                 C   s   | j r| S |S )zGiven a sentence, apply optional lowercasing.

        :param sent: The input sentence string.
        :return: The pre-processed output string.
        )r   lower)r'   rL   r*   r*   r+   _preprocess_segment   s   zCHRF._preprocess_segment
statisticsc                 C   s6  d}d}d}| j d }d\}}t| jD ]Q}|d| d| d  \}	}
}|	dkr-||	 n|}|
dkr7||
 n|}|| | }||dkrNd| | | | n|7 }|	dkre|
dkre||7 }||7 }|d7 }q| jrpd| | j S |dkryd }}n|| }|| }|| rd| | | }||| |  }d| S dS )	a  Compute the chrF score given the n-gram match statistics.

        :param statistics: A flattened list of 3 * (`char_order` + `word_order`)
            elements giving the [hyp, ref, match] counts for each order.
        :return: The final f_beta score between [0, 100].
        gؗҜ<        r   r   )rX   rX      r	   d   )r4   ranger=   r   )r'   rW   epsr3   effective_orderfactoravg_precavg_recin_hypn_refn_matchprecrecdenomr*   r*   r+   _compute_f_score   s6   
$
zCHRF._compute_f_scorestatsc                 C   s   t | || j| j| jS )zComputes the final score from already aggregated statistics.

        :param stats: A list or numpy array of segment-level statistics.
        :return: A `CHRFScore` object.
        )r2   rh   r   r    r4   r'   ri   r*   r*   r+   _compute_score_from_stats   s   zCHRF._compute_score_from_statsc                 C   s   |  t|S )zComputes the final score given the pre-computed corpus statistics.

        :param stats: A list of segment-level statistics
        :return: A `CHRFScore` object.
        )rk   r   rj   r*   r*   r+   _aggregate_and_compute   s   zCHRF._aggregate_and_computerefsc                 C   sh   g }|D ]+}t || j| j}| jdkr*| |}t| jD ]}|t||d  q|| qd|iS )zGiven a list of reference segments, extract the character and word n-grams.

        :param refs: A sequence of reference segments.
        :return: A list where each element contains n-grams per reference segment.
        r   r	   rA   )r   r   r!   r    rT   r[   rP   r   )r'   rm   ngramsrefri   	ref_wordsnr*   r*   r+   _extract_reference_info   s   

zCHRF._extract_reference_info
hypothesis
ref_kwargsc                    s   g }d}t || j| j}| jdkr*| | td| jd }| fdd|D  |d D ]$}g }t||D ]\}	}
|| |	|
 q7| 	|}||krR|}|}q.|S )a  Given a (pre-processed) hypothesis sentence and already computed
        reference n-grams, returns the best match statistics across the
        references.

        :param hypothesis: Hypothesis sentence.
        :param ref_kwargs: A dictionary with key `ref_ngrams` which is a list
        where each sublist contains n-gram counters for a particular reference sentence.
        :return: A list of integers where each triplet denotes [hyp, ref, match]
        statistics.
        g      r   r	   c                    s   g | ]}t  |qS r*   )r   ).0rq   hwordsr*   r+   
<listcomp>  s    z4CHRF._compute_segment_statistics.<locals>.<listcomp>rA   )
r   r   r!   r    rT   r[   extendziprK   rh   )r'   rs   rt   
best_statsbest_f_scoreall_hyp_ngrams_range_ref_ngramsri   hrf_scorer*   rv   r+   _compute_segment_statistics   s&   



z CHRF._compute_segment_statistics) r,   r-   r.   r/   
CHAR_ORDER
WORD_ORDERBETAsetrQ   r   _SIGNATURE_TYPEr9   boolr   r   strr#   staticmethodr   r   rK   rT   rV   r8   rh   r2   rk   rl   r   rr   r   r1   r*   r*   r(   r+   r:   8   sT    -
&r:   N)r/   typingr   r   r   r   collectionsr   utilsr   baser
   r   r   helpersr   r   r   r2   r:   r*   r*   r*   r+   <module>   s    