from itertools import combinations def covers(groups,target): allrows=[] for count in range(1,len(groups)+1): for selection in combinations(groups,count): union=set().union(*(set(g['indices']) for g in selection)) if target<=union:allrows.append({'size':count,'groups':[g['id'] for g in selection],'indices':sorted(union)}) return allrows def run(load,check): seg=load('C302_DATA.json')['complete_segments'];pairs=[p for p in seg if p['profile']=='LXX_OFF'] grouped={};geared={} for p in pairs: t=p['upper']['regular'];u=p['lower']['regular'];key=(t['tradition'],t['Cainan'],t['Terah60'],t['full430'],t['role'],u['role']) grouped.setdefault(key,set()).add(p['index']);geared.setdefault(key+(t['gear'],),set()).add(p['index']) groups=[{'id':'family'+str(j+1),'tradition':k[0],'Cainan':k[1],'Terah60':k[2],'full430':k[3],'upper_role':k[4],'lower_role':k[5],'indices':sorted(v)} for j,(k,v) in enumerate(sorted(grouped.items()))] geargroups=[{'id':'gear_family'+str(j+1),'key':list(k),'indices':sorted(v)} for j,(k,v) in enumerate(sorted(geared.items()))] available=set(p['index'] for p in pairs);allcovers=covers(groups,available);minimal=[c for c in allcovers if c['size']==min(x['size'] for x in allcovers)] gearcovers=covers(geargroups,available);gearminimum=min(c['size'] for c in gearcovers);mingear=[c for c in gearcovers if c['size']==gearminimum] check('tenLXXprofile labeledsegments sevenindices',len(pairs)==10 and sorted(available)==[0,2,3,4,5,6,7]) check('three regularcontextfamilies',len(groups)==3) check('familyindexcounts3LXX2MT5SP',[(g['tradition'],len(g['indices'])) for g in groups]==[('LXX',3),('MT',2),('SP',5)]) check('unique minimum twofamilycover',len(minimal)==1 and minimal[0]['size']==2) chosen=[g for g in groups if g['id'] in minimal[0]['groups']] check('minimum cover isMTbaselineandSPalternate',[g['tradition'] for g in chosen]==['MT','SP'] and [(g['Cainan'],g['Terah60'],g['full430']) for g in chosen]==[(0,0,1),(0,1,0)]) check('endpointroleschange',[g['upper_role'] for g in chosen]==['Noah birth','Shem birth'] and [g['lower_role'] for g in chosen]==['Flood start','Shem death']) check('noonefamilycover',all(c['size']>1 for c in allcovers)) check('full eightindexcover impossible',not covers(groups,set(range(8)))) check('LXXcoordinatecover redundant',set(next(g['indices'] for g in groups if g['tradition']=='LXX'))<=set(next(g['indices'] for g in groups if g['tradition']=='SP'))) check('gearretained minimumfivefamilies twochoices',gearminimum==5 and len(mingear)==2) check('contextshift separately60minus215',60-215==-155) core=load('C287_DATA.json');reflection=load('C295_DATA.json');audit=load('C309_DATA.json') check('corestatementfourcompletecoordinate rows',sum(r['complete'] for r in core['rows'])==4) check('finalsummaryretainsreflection incompatibility',reflection['counts']['both']==0) check('finalsummaryretainsrankandplacement',audit['fixedK_rank']==3 and audit['fixedK_translation_freedom']==1) anchors=load('C308_DATA.json')['anchor_cases'] check('finalsummaryretainsanchorpointpathdistinction',anchors[0]['labeled_segments']==12 and anchors[1]['labeled_segments']==0) return {'LXX_OFF_target_indices':sorted(available),'missing_annual_index':[1],'context_family_definition':'Tradition,Cainan,Terah,sojourn and endpoint roles fixed; existing Gear and rail labels remain on each segment.','families':groups,'all_context_covers':allcovers,'minimum_context_covers':minimal,'gear_specific_families':geargroups,'minimum_gear_specific_covers':mingear,'net_regular_context_shift':-155,'coverage_status':'Unique minimum two-context cover, with a role change and one missing annual index.','full_single_context_chronology_claimed':False,'batch_end':'C310','next_unexecuted':'C311 source-rule audit of the MT-to-SP context and endpoint-role switch; no new endpoint search.'}