"""Authored extractive spans round-trip against exact source hash; not semantic verification."""
import json,hashlib
SENTENCES=['سارا نسخهٔ آبی طرح را انتخاب کرد.','مهلتِ بازبینی دوشنبه است.','قیمت هنوز تصویب نشده است.','فایلِ پیشین برای مقایسه نگه داشته می‌شود.']
SOURCE=' '.join(SENTENCES)
def sha(text):return hashlib.sha256(text.encode('utf-8')).hexdigest()
def extract(source,spans,expected_sha):
    if sha(source)!=expected_sha:raise ValueError('source version mismatch')
    previous=0;pieces=[]
    for row in spans:
        start,end=row['start'],row['end']
        if type(start) is not int or type(end) is not int or not previous<=start<end<=len(source):raise ValueError('ordered nonoverlapping codepoint ranges')
        quote=source[start:end]
        if quote!=row['quote']:raise ValueError('quote not exact source span')
        pieces.append(quote);previous=end
    return chr(10).join(pieces)
def demo():
    spans=[]
    for i in [0,2]:
        start=SOURCE.index(SENTENCES[i]);spans.append({'sentence_id':'S'+str(i+1),'start':start,'end':start+len(SENTENCES[i]),'quote':SENTENCES[i]})
    extracted=extract(SOURCE,spans,sha(SOURCE));assert extracted==SENTENCES[0]+chr(10)+SENTENCES[2]
    paraphrase='سارا طرح آبی را برگزید، اما مبلغ آن هنوز نهایی نیست.'
    units=[{'unit':'انتخابِ طرح آبی توسط سارا','source_sentence_id':'S1','review_origin':'author manual annotation'},{'unit':'نهایی‌نبودنِ مبلغ','source_sentence_id':'S3','review_origin':'author manual annotation'}]
    rejected=0
    bad_spans=[dict(spans[0],end=len(SOURCE)+1),dict(spans[0],quote='قیمت قطعی است.'),dict(spans[0],start=True)]
    for bad in bad_spans:
        try:extract(SOURCE,[bad],sha(SOURCE))
        except ValueError:rejected+=1
        else:raise AssertionError('invalid span accepted')
    try:extract(SOURCE+' ',spans,sha(SOURCE))
    except ValueError:rejected+=1
    else:raise AssertionError('changed source accepted')
    return {'source_sentences':{'S'+str(i+1):s for i,s in enumerate(SENTENCES)},'source':SOURCE,'source_utf8_sha256':sha(SOURCE),'extractive_spans':spans,'extractive_text':extracted,'abstractive_example_authored_manually':paraphrase,'manual_paraphrase_unit_links':units,'not_selected_source_sentences':['S2','S4'],'rejected_span_or_version_mutations':rejected,'span_unit':'Python Unicode codepoints, end exclusive','summary_model_executed':False,'paraphrase_factuality_automatically_proven':False}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=False,indent=2))
