/- MISignal.lean - Mutual Information Signal Processing Bindings Ports rows 72-76 from MATH_MODEL_MAP.tsv (Python → Lean). All values are Q16.16. Bits-per-byte range [0, 8] maps to [0, 8·65536]. -/ import Semantics.Bind import Semantics.FixedPoint namespace Semantics.MISignal open Q16_16 def epsilon : Q16_16 := ⟨1⟩ -- Scale constant: 8.0 in Q16.16 = 8 * 65536 def bitsPerByteMax : Q16_16 := ⟨8 * 65536⟩ structure MIRecord where baselineBpb : Q16_16 -- baseline bits-per-byte (uncompressed context) actualBpb : Q16_16 -- actual bits-per-byte achieved miPredicted : Q16_16 -- kNN-predicted MI value deriving Repr, Inhabited, DecidableEq -- Row 72: MI(x) = baseline_bpb - actual_bpb -- Mutual information extracted through compression improvement def mutualInformationSignal (r : MIRecord) : Q16_16 := if r.baselineBpb.val ≥ r.actualBpb.val then sub r.baselineBpb r.actualBpb else zero -- Row 73: MI_pred = Σ(w_i · MI_i · S_i) / Σ(w_i · S_i) -- kNN weighted MI prediction; w_i = 1/(d_i + ε) -- distances, mis, similarities are parallel arrays def knnMIPrediction (distances mis similarities : Array Q16_16) : Q16_16 := let n := distances.size if n == 0 || mis.size != n || similarities.size != n then zero else let num := Array.foldl (fun acc i => let w := div one (add distances[i]! epsilon) add acc (mul (mul w mis[i]!) similarities[i]!) ) zero (Array.range n) let den := Array.foldl (fun acc i => let w := div one (add distances[i]! epsilon) add acc (mul w similarities[i]!) ) zero (Array.range n) if den.val == 0 then zero else div num den -- Row 74: surprise = log(1 + |MI_actual - MI_predicted|) -- Approximated in Q16.16: surprise ≈ |diff| (natural log not available in integer—use diff directly as ordinal surprise) def surpriseMetric (r : MIRecord) : Q16_16 := let miActual := mutualInformationSignal r let diff := abs (sub miActual r.miPredicted) -- log(1+x) ≈ x for small x; represent as direct delta in Q16.16 add one diff -- Row 75: ρ(x) = MI(x) / (cost(x) + ε) -- Structure yield: information per unit compute cost def structureYield (mi cost : Q16_16) : Q16_16 := div mi (add cost epsilon) -- Row 76: d(z₁, z₂) = √( Σ w_i · ((z₁_i - z₂_i) / s_i)² ) -- Weighted feature distance over 9-dim vector -- Uses integer arithmetic: no float sqrt; return squared distance as cost proxy def weightedFeatureDistanceSq (z1 z2 weights scales : Array Q16_16) : Q16_16 := let n := z1.size if n == 0 then zero else Array.foldl (fun acc i => if i < z2.size && i < weights.size && i < scales.size then let diff := abs (sub z1[i]! z2[i]!) let scaled := div diff (add scales[i]! epsilon) let sq := mul scaled scaled add acc (mul weights[i]! sq) else acc ) zero (Array.range n) def miInvariant (r : MIRecord) : String := s!"mi:baseline={r.baselineBpb.val},actual={r.actualBpb.val}" def miCost (a b : MIRecord) (_m : Metric) : UInt32 := let ma := mutualInformationSignal a let mb := mutualInformationSignal b (abs (sub ma mb)).val def miSignalBind (a b : MIRecord) (m : Metric) : Bind MIRecord MIRecord := informationalBind a b m miCost miInvariant miInvariant -- Verify #eval mutualInformationSignal { baselineBpb := ⟨5 * 65536⟩, actualBpb := ⟨3 * 65536⟩, miPredicted := ⟨2 * 65536⟩ } #eval surpriseMetric { baselineBpb := ⟨5 * 65536⟩, actualBpb := ⟨3 * 65536⟩, miPredicted := ⟨65536⟩ } end Semantics.MISignal