from fractions import Fraction as F from itertools import combinations def run(load,check): rows=[] for field in load('PREVIOUS_DATA.json')['fields']: vals={k:F(v['center']) for k,v in field['records'].items()};spec={'E_N':(F(25,23),vals['N']),'J_R':(F(300,299),vals['R']),'J_M':(F(300,299),vals['M'])};maps=field['maps'] for first,second in combinations(spec,2): a,p=spec[first];b,q=spec[second];want=(a-1)*(b-1)*(p-q);trial=[] for key,x in vals.items(): for e in [F(-1,4),F(1,4)]: f=lambda t:(p+e)+a*(t-p-e);g=lambda t:(q+e)+b*(t-q-e);diff=f(g(x+e))-g(f(x+e));check(f'{field["i"]}/{first}/{second}/{key}/{e}',diff==want) fg=maps[first].get(maps[second].get(key));gf=maps[second].get(maps[first].get(key));trial.append({'input':key,'first_after_second_source_output':fg,'second_after_first_source_output':gf,'both_paths_source_supported':fg is not None and gf is not None}) expected={('E_N','J_R'):F(92,299),('E_N','J_M'):F(40,299),('J_R','J_M'):F(-2,299)}[first,second] check(f'{field["i"]}/{first}/{second} constant',want==expected) check(f'{field["i"]}/{first}/{second} no full square',not any(t['both_paths_source_supported'] for t in trial)) rows.append({'i':field['i'],'first':first,'second':second,'first_after_second_minus_reverse':str(want),'trials':trial}) return {'step':'C350','rows':rows,'general_identity':'f_a,p∘f_b,q - f_b,q∘f_a,p = (a-1)(b-1)(p-q)','interpretation':'Different existing fixed endpoints cause order dependence. Scalar products commute; this does not make fixed-endpoint source expressions interchangeable.','both_orders_source_supported_inputs':0,'new_coordinate_images_adopted':False}