#!/usr/bin/env python3 """C317 independent fixed-five-case17K rectangle calculation. --sources has PREVIOUS_DATA.json(C316), C271_REGISTER.json, C287_DATA.json. --out writes JSON. Four-node duration rank is incidence-matrix rank. """ import argparse from fractions import Fraction as F from pathlib import Path import hashlib,json def rank(a): a=[[F(x) for x in r] for r in a];m=len(a);n=len(a[0]);r=0 for c in range(n): p=next((z for z in range(r,m) if a[z][c]),None) if p is None:continue a[r],a[p]=a[p],a[r];v=a[r][c];a[r]=[x/v for x in a[r]] for z in range(m): if z!=r: v=a[z][c];a[z]=[x-v*y for x,y in zip(a[z],a[r])] r+=1 if r==m:break return r def main(): ap=argparse.ArgumentParser();ap.add_argument('--sources',type=Path);ap.add_argument('--out',type=Path,default=Path(__file__).parent);a=ap.parse_args();root=Path(__file__).resolve().parents[1] paths={'PREVIOUS_DATA.json':root/'C316/evidence/DATA.json',**{n:root/'C313/sources'/n for n in ['C271_REGISTER.json','C287_DATA.json']}} data={};hashes={} for name,path in paths.items(): raw=(a.sources/name if a.sources else path).read_bytes();data[name]=json.loads(raw);hashes[name]=hashlib.sha256(raw).hexdigest() before=data['PREVIOUS_DATA.json'];anc=data['C271_REGISTER.json'];old=data['C287_DATA.json'];oldby={r['i']:r for r in old['rows']};k=529;leg=17*k edges=[(0,1),(0,2),(0,3),(1,2),(1,3),(2,3)] matrix=[] for u,v in edges: row=[0]*4;row[u]=-1;row[v]=1;matrix.append(row) assert rank(matrix)==3 rows=[] for r in sorted(before['rows'],key=lambda x:x['i']): i,j,g,rail=r['i'],r['j'],r['gear'],r['rail'];p=-5890+i;q=-5290+i;f=3103+i;n=3703+i assert [n,f]==[r['biography_BC'][0],r['biography_BC'][2]] fr=[x for x in anc if x['branch']=='Flood' and x['source_event']['gear']==g and x['source_event']['role']==r['selected_Flood_role']] nr=[x for x in anc if x['branch']=='Noah' and x['source_event']['gear']==g and x['source_event']['rail']==rail] assert len(fr)==len(nr)==1;fr,nr=fr[0],nr[0] assert fr['cumulative_source']['source_role']=='Shem' and fr['cumulative_source']['source_index']==i and -fr['cumulative_source']['source_BC_base']==p assert nr['cumulative_source']['source_role']=='Flood' and nr['cumulative_source']['source_index']==i and -nr['cumulative_source']['source_BC_base']==q assert fr['source_event']['BC_Nisan']==f and nr['source_event']['BC_Nisan']==n coords=[p,q,f,n];dur=[coords[v]-coords[u] for u,v in edges];cross=[[f-p,n-p],[f-q,n-q]] assert cross==[[8993,9593],[8393,8993]] and dur==[600,8993,9593,8393,8993,600] assert rank([row+[rhs] for row,rhs in zip(matrix,dur)])==3 components=[] for e in (F(-1,4),F(1,4)): fp=[x for x in fr['phases'] if F(x['cumulative_coordinate'])==p+e] np=[x for x in nr['phases'] if F(x['cumulative_coordinate'])==q+e] assert len(fp)==len(np)==1;fp,np=fp[0],np[0] assert F(fp['reflected_coordinate'])==f+e and F(np['reflected_coordinate'])==n+e assert F(fp['reflected_coordinate'])-F(fp['cumulative_coordinate'])==leg assert F(np['reflected_coordinate'])-F(np['cumulative_coordinate'])==leg assert F(np['reflected_coordinate'])-F(fp['reflected_coordinate'])==600 components.append({'phase':str(e),'p_cumulative_OFF_Shem':str(p+e),'q_cumulative_OFF_Flood':str(q+e),'f_regular_SP_Flood':str(f+e),'n_regular_SP_Noah':str(n+e),'p_source_phase':fp['cumulative_phase'],'q_source_phase':np['cumulative_phase'],'f_output_phase':fp['reflected_phase'],'n_output_phase':np['reflected_phase'],'two_translations':['8993','8993'],'two_sides':['600','600']}) oldrow=oldby.get(i);comparison=None if oldrow and oldrow['complete']: S,R=oldrow['S'],oldrow['R'];assert oldrow['F']==q and oldrow['Noah_required']==n assert S==p-458 and R==f-458 oldcross=[[R-S,n-S],[R-q,n-q]] assert oldcross==[[17*k,19*k],[15*k,17*k]] assert q-S==n-R==1058==2*k comparison={'C287_S':S,'C287_R':R,'shared_q':q,'shared_n':n,'C287_minus_current_p_f':[-458,-458],'same_side_width_old':1058,'same_side_width_current':600,'width_difference':458,'C287_crosswidths':oldcross,'current_crosswidths':cross,'both_T8993_bridges_retained':True,'C287_source_role':'cumulative LXX_ON Shem at annual index i+2','current_source_role':'cumulative LXX_OFF Shem at annual index i','C287_regular_role':'regular MT Flood (inherited variant context)','current_regular_role':'regular SP Flood (OFF/Terah0/full430)'} rows.append({'i':i,'j':j,'gear':g,'rail':rail,'source_Flood_role':r['selected_Flood_role'],'coordinates_p_q_f_n':coords,'crosswidths':cross,'six_durations':dur,'duration_incidence_rank':3,'common_translation_dimension':1,'exact_components':components,'C287_full_form_at_i':bool(comparison),'C287_comparison':comparison}) assert [r['i'] for r in rows]==[3,4,5,6,7] assert [r['i'] for r in rows if r['C287_full_form_at_i']]==[3,4,5] out={'step':'C317','status':'passed','scope':'Same five source-qualified SP cases only; no census enlargement.','input_sha256':hashes,'rows':rows,'counts':{'source_rectangles':5,'phase_rectangles':10,'C287_complete_comparisons':3,'C287_unavailable_at_same_i':2},'crosswidth_matrix':[[8993,9593],[8393,8993]],'crosswidth_matrix_K_expressions':[['17K','17K+600'],['17K−600','17K']],'duration_algebra':{'vertex_order':['p','q','f','n'],'edge_order':edges,'incidence_matrix':matrix,'rank':3,'augmented_rank':3,'fixed_duration_solution_translation_dimension':1,'empirical_independence_claim':False},'width_comparison':{'current':600,'C287':1058,'difference':458,'difference_decomposition':'460−2; Cainan and annual-index roles remain distinct','600_divisible_by_K':600%529==0},'interpretation':'An admitted equal-17K rectangle with600-year sides exists in all five cases. It is not an all-K rectangle; six displayed durations have rank3 and preserve a common-translation freedom. At three admitted C287 indices, shifting its S and R corners by+458 gives the current p and f corners while q and n remain shared. This coordinate correspondence does not identify the changed source states or establish independent historical intent.','suggested_next_bounded_question':'Audit the paired458-year corner displacement as separately sourced460-year cumulative Cainan insertion and2-year annual offset, and as the declared regular MT→SP variant conversion; test whether those typed paths agree on precisely the three shared C287 cases.','later_step_executed':False} a.out.mkdir(parents=True,exist_ok=True);(a.out/'C317_Independent_Math_Results.json').write_text(json.dumps(out,indent=2)+'\n');print(json.dumps({'status':'passed','rectangles':5,'phase_rectangles':10,'duration_rank':3,'C287_comparisons':3})) if __name__=='__main__':main()