from fractions import Fraction as Q from itertools import product def run(load,check): reg=load('C286_DATA.json')['target_register'] def get(trad,role,g,c,t,f,rail=None): a=[r for r in reg if r['tradition']==trad and r['role']==role and r['gear']==g and r['Cainan']==c and r['Terah60']==t and r['full430']==f and (role.startswith('Flood') or r.get('rail')==rail)] assert len(a)==1,(trad,role,g,c,t,f,rail);return a[0] rows=[] for g,rail,cs,ts,fs,cm,tm,fm in product([1,2,3],['primary','companion'],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1]): S=lambda role:get('SP',role,g,cs,ts,fs,rail) M=lambda role:get('MT',role,g,cm,tm,fm) B=lambda role:get('MT',role,g,cs,ts,fs) piv=[S('Noah birth'),S('Flood start'),S('Shem death')];inputs=[M('Noah birth'),M('Flood start'),M('Shem death')];outputs=[S('Shem birth'),S('Shem death'),B('Noah death')] x=[p['center']-q['center'] for p,q in zip(piv,inputs)];y=[p['center']-q['center'] for p,q in zip(piv,outputs)] base=650+130*(cs-cm)+60*(ts-tm)+215*(fs-fm);e=int(rail=='companion') check('source normal form '+str((g,rail,cs,ts,fs,cm,tm,fm)),x==[base-e,base,base-e] and y==[500,500+e,500-e]) ok=all(Q(a)*Q(25,23)==bb for a,bb in zip(x,y)) rows.append({'gear':g,'rail':rail,'SP_context':[cs,ts,fs],'MT_input_context':[cm,tm,fm],'MT_output_context':[cs,ts,fs],'pivots':piv,'inputs':inputs,'outputs':outputs,'input_gaps':x,'output_gaps':y,'all_three_E_relations':ok}) hits=[r for r in rows if r['all_three_E_relations']] check('384 controls',len(rows)==384) check('six exact source families',len(hits)==6 and all(r['rail']=='primary' and r['SP_context'][:2]==[0,0] and r['MT_input_context'][:2]==[1,1] and r['SP_context'][2]==r['MT_input_context'][2] and r['input_gaps']==[460]*3 and r['output_gaps']==[500]*3 for r in hits)) for r in hits: for key in ['pivots','inputs','outputs']: v=[x['center'] for x in r[key]];check('600500 sequence '+str((r['gear'],r['SP_context'],key)),v[0]-v[1]==600 and v[1]-v[2]==500) check('source constant reduction',650-(130+60)==460 and 500+600-950==150 and 650-150==500 and Q(460)*Q(25,23)==500) return {'step':'C357','rows':rows,'hits':hits,'counts':{'controls':384,'hits':len(hits),'companion_hits':sum(r['rail']=='companion' for r in hits)},'source_constants':{'SP_minus_MT_same_context':650,'regular_Cainan':130,'Terah':60,'Noah_to_Shem':500,'Noah_to_Flood':600,'Noah_lifespan':950,'Shem_lifespan':600},'normal_form':{'input_gaps':'[D-e,D,D-e]; D=650+130(cS-cM)+60(tS-tM)+215(fS-fM)','output_gaps':'[500,500+e,500-e]','last_row':'650-(500+600-950)=500'},'interpretation':'Three rows follow from shared constants and are dependent realizations. Context selection is unique within this finite menu up to three Gears and the two shared sojourn frames. G3/minimum rows do not create new529 rectangles.'}