#!/usr/bin/env python3
"""Write boundary_ibp_identities_PX2.m: Kira's reduction rules (symbolic in d and y) for the target integrals of
the three PX2 top sectors that are not master integrals of the numerator-seeded reduction, with a comment header;
the rule body is copied byte for byte from the Kira output.  usage: build_ibp_identities.py RULES.m MASTERS TARGETS OUT"""
import sys, re
from common import sha256_file
rules, masters, targets, out = sys.argv[1:5]
body = open(rules).read()
mas = [l.split('#')[0].strip() for l in open(masters) if l.strip()]
tg = [l.strip() for l in open(targets) if l.strip()]
nrules = len(re.findall(r'^pm5_2SF_PX2_diss\[', body, flags=re.M))
tmasters = [t for t in tg if t in mas]
hdr = f"""(* Integration-by-parts reduction rules of the undeformed PX2 family (pm5_2SF_PX2_diss) for the boundary target
   integrals of the top sectors S_1, S_2, S_3: the 31 integrals supporting the flow-free directions (listed with names
   in boundary_constants_PX2.json and in the supplementary material) plus the remaining eleven response-matrix rows of S_1.  Produced by Kira: identities seeded on the sector trees of the targets with r <= 15, s <= 2,
   at most 2 dots (together with the first-stage seeds r = 14, s = 1), Kira's sector relations and symmetries included;
   kinematics symbolic (d = 4 - 2 eps, y = u1.u2; q^2 = -1).  {len(tg)} targets; {len(tmasters)} of them are master integrals of this
   reduction and do not appear on a left-hand side; the {nrules} rules below express the others.  The reduction has {len(mas)} master
   integrals (numerator integrals are seeded, so this basis differs from the first-stage list masters/PX2_first_stage_37.txt).
   Format: Mathematica list of rules  integral -> sum of  master*(coefficient(d,y)).  Index vectors as in
   kira/integralfamilies.yaml.  At d = 4 - 2 eps and y = 5/4 the left null vectors of boundary_constants_PX2.json
   annihilate these rules: every flow-free relation of Table 5 (and Eq. (36)) is one of these identities or a
   combination of them, e.g. the first rule is I_3 -> (8/9) I_2 + (1/6) I_0, i.e. I_0 + (16/3) I_2 - 6 I_3 = 0,
   with coefficients independent of d and y.
   Master integrals of this reduction that are targets: *)
(* {', '.join(tmasters)} *)
"""
open(out, 'w').write(hdr + body)
same = open(out).read().endswith(body)
print(f"wrote {out.split('/')[-1]}: {nrules} rules, {len(tg)} targets, {len(tmasters)} target masters, {len(mas)} masters; "
      f"rule body byte-identical: {same}; rules sha256 {sha256_file(rules)[:16]} masters sha256 {sha256_file(masters)[:16]}")
