"""Two authored suffix rules versus a six-entry manual lemma table; not Snowball/Hazm."""
import json
ROWS=[('S1','کتاب‌ها','کتاب‌ها روی میز هستند.','کتاب'),('S2','کتاب‌های','کتاب‌های تازه رسیدند.','کتاب'),('S3','می‌روند','آن‌ها به خانه می‌روند.','رفتن'),('S4','رفتند','آن‌ها دیروز رفتند.','رفتن'),('S5','شیراز','شیراز مقصد این جمله است.','شیراز'),('S6','باشد','امیدوارم آماده باشد.','بودن')]
def limited_suffix(token):
    if not isinstance(token,str) or not token or any(x.isspace() for x in token):raise ValueError('one nonempty exact token')
    for suffix in ['‌های','‌ها']:
        if token.endswith(suffix) and len(token[:-len(suffix)])>=3:
            return {'input':token,'output':token[:-len(suffix)],'rule':'remove exact ZWNJ plural suffix','removed':suffix}
    return {'input':token,'output':token,'rule':'no rule in this limited profile','removed':None}
def demo():
    manual={(token,context):lemma for _,token,context,lemma in ROWS};out=[]
    for sid,token,context,lemma in ROWS:
        stem=limited_suffix(token);out.append({'id':sid,'token':token,'context':context,'limited_suffix_trace':stem,'manual_lemma':manual[(token,context)],'lemma_origin':'authored table, not engine prediction'})
    assert [r['limited_suffix_trace']['output'] for r in out]==['کتاب','کتاب','می‌روند','رفتند','شیراز','باشد']
    assert out[2]['manual_lemma']==out[3]['manual_lemma']=='رفتن'
    assert limited_suffix('اژدها')['output']=='اژدها'
    naive='اژدها'[:-2];assert naive=='اژد'
    unknown=manual.get(('نوشته‌ها','نوشته‌ها پیدا شدند.'));assert unknown is None
    return {'rows':out,'limited_stem_rules':2,'naive_unguarded_suffix_counterexample':{'input':'اژدها','output':naive,'recommended':False},'unknown_manual_lemma':unknown,'unseen_token_suffix_trace':limited_suffix('نوشته‌ها'),'automatic_morphological_analysis':False,'Snowball_or_Hazm_executed':False}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=False,indent=2))
