from itertools import product def run(load,check): reg=load('C286_DATA.json')['target_register'];links=load('C410_DATA.json')['labelled_links'];typed=[x for x in links if x['classification']!='additional labelled coincidence'];bridges=[x for x in links if reg[x['input_record']]['center']==3395 and reg[x['output_record']]['center']==2895] edges={(x['input_record'],x['output_record']) for x in typed};extra={(x['input_record'],x['output_record']) for x in bridges};rows=[];rejected=[] for p in load('PREVIOUS_DATA.json')['source_pairs']: if not p['one_step_source_pair']:continue a,z=p['levels'][:2];lifts=[];aug=[];raw=[] for ui,li,uo,lo in product(a['upper_record_indices'],a['lower_record_indices'],z['upper_record_indices'],z['lower_record_indices']): row={'record_indices':[ui,li,uo,lo],'records':[reg[i] for i in [ui,li,uo,lo]]};raw.append(row) if (ui,uo) in edges and (li,lo) in edges:lifts.append(row) else:rejected.append({'original_pair':[p['upper'],p['lower']],**row,'upper_edge_admitted':(ui,uo) in edges,'lower_edge_admitted':(li,lo) in edges}) if (ui,uo) in edges|extra and (li,lo) in edges|extra:aug.append(row) check('bridge does not change paired lifts '+str(p['upper']),lifts==aug) check('all labelled lifts preserve source2K '+str(p['upper']),all(r['records'][0]['center']-r['records'][1]['center']==r['records'][2]['center']-r['records'][3]['center']==1058 for r in lifts)) check('all surviving coordinate pairs have a typed lift '+str(p['upper']),bool(lifts)) rows.append({'original_pair':[p['upper'],p['lower']],'translated_pair':[p['upper']-500,p['lower']-500],'raw_coordinate_lifts':len(raw),'typed_lifts':lifts,'with_bridge_lifts':aug}) check('C411 role-defined inventory',len(edges)==240) check('C411 separate bridge inventory',len(extra)==2 and not edges&extra) return {'step':'C415','pair_transports':rows,'rejected_coordinate_alias_lifts':rejected,'counts':{'paired_coordinate_cases':len(rows),'raw_coordinate_lifts':sum(x['raw_coordinate_lifts'] for x in rows),'typed_record_lifts':sum(len(x['typed_lifts']) for x in rows),'with_bridge_record_lifts':sum(len(x['with_bridge_lifts']) for x in rows),'rejected_alias_lifts':len(rejected)},'interpretation':'Both edges must carry their actual input and output record identities. No SP companion is exported to LXX. The extra3395→2895 arrow is tested separately. These are source comparisons, not a prescribed combined protocol.'}