-- SilverSight.PIST.Classify — minimal RRC shape classifier over 8×8 matrices
--
-- Ports only the classifier surface needed for Corpus250:
--   • 8×8 braid adjacency matrix type
--   • spectral-radius → RGB color → shape-name gate
--   • matrix-hash lookup table (proxy classifier)
--   • spectral-radius exact classifier
--   • deterministic blending rules for shared equation_ids
--
-- Photonic/Kubelka-Munk/Quandela extensions from Research Stack are omitted.

import SilverSight.PIST.Spectral
import SilverSight.FixedPoint

namespace SilverSight.PIST.Classify

open SilverSight.FixedPoint
open SilverSight.FixedPoint.Q16_16
open SilverSight.PIST.Spectral

-- ─────────────────────────────────────────────────────────────────────────────
-- §1  Matrix type
-- ─────────────────────────────────────────────────────────────────────────────

abbrev Matrix8 : Type := Array (Array Int)

-- ─────────────────────────────────────────────────────────────────────────────
-- §2  Spectral-radius thresholds
-- ─────────────────────────────────────────────────────────────────────────────

/-- High amplification threshold: λ ≥ 4.0 (Q16.16 raw). -/
def oberthHighThreshold : Int := 262144

/-- Moderate amplification threshold: λ ≥ 2.0 (Q16.16 raw). -/
def signalThreshold : Int := 131072

-- ─────────────────────────────────────────────────────────────────────────────
-- §3  Spectral color gate
-- ─────────────────────────────────────────────────────────────────────────────

structure SpectralColor where
  red   : Q16_16
  green : Q16_16
  blue  : Q16_16
  deriving Repr

/-- Convert a raw spectral radius (Int) to an RGB SpectralColor. -/
def spectralRadiusToColor (lam : Int) : SpectralColor :=
  let max_raw := oberthHighThreshold
  let r := if lam ≥ max_raw then one else zero
  let g := if lam ≥ signalThreshold then
    ofRawInt ((lam - signalThreshold) * 65536 / (max_raw - signalThreshold))
    else zero
  let b := if lam < signalThreshold then
    ofRawInt (lam * 65536 / signalThreshold)
    else zero
  { red := r, green := g, blue := b }

/-- Extract the shape-name string from a SpectralColor. -/
def colorToShapeName (c : SpectralColor) : Option String :=
  if c.red.toInt > 0 then some "CognitiveLoadField"
  else if c.green.toInt > 0 then some "SignalShapedRouteCompiler"
  else none

-- ─────────────────────────────────────────────────────────────────────────────
-- §4  Blending rules for shared equation_ids
-- ─────────────────────────────────────────────────────────────────────────────

inductive BlendType where
  | additive
  | rms
  | vortex
  deriving Repr

def blend_additive (lam1 lam2 : Int) : Int :=
  max lam1 lam2

def blend_rms (lam1 lam2 : Int) : Int :=
  Int.ofNat (Nat.sqrt (((lam1 * lam1 + lam2 * lam2) / 2).toNat))

def blend_vortex (lam1 lam2 : Int) : Int :=
  (lam1 * lam2) / (lam1 + lam2 + 1)

/-- Blend a list of spectral radii under a given topology. -/
def blendRadii (blendType : BlendType) (lams : List Int) : Int :=
  match lams with
  | [] => 0
  | lam :: rest =>
    rest.foldl (fun acc lam2 =>
      match blendType with
      | .additive => if acc ≥ lam2 then acc else lam2
      | .rms => isqrt ((acc * acc + lam2 * lam2) / 2)
      | .vortex => (acc * lam2) / (acc + lam2 + 1)
    ) lam

-- ─────────────────────────────────────────────────────────────────────────────
-- §5  Classifier surface
-- ─────────────────────────────────────────────────────────────────────────────

def hashMatrix (m : Matrix8) : Int :=
  let rec loop (i j : Nat) (pow_5 : Int) (acc : Int) : Int :=
    if i ≥ 8 then acc
    else if j ≥ 8 then loop (i + 1) 0 pow_5 acc
    else
      let val := m.getD i #[] |>.getD j 0
      loop i (j + 1) (pow_5 * 5) (acc + val * pow_5)
  loop 0 0 1 0

/-- Advisory shape proxy via matrix-hash lookup. -/
def classifyProxy (m : Matrix8) : Option String :=
  match hashMatrix m with
  | 0 => some "CognitiveLoadField"
  | 25 => some "CognitiveLoadField"
  | 125 => some "CognitiveLoadField"
  | 625 => some "CognitiveLoadField"
  | 78125 => some "SignalShapedRouteCompiler"
  | 390625 => some "CognitiveLoadField"
  | 1953125 => some "SignalShapedRouteCompiler"
  | 9765625 => some "ProjectableGeometryTopology"
  | 48828125 => some "ProjectableGeometryTopology"
  | 244140625 => some "SignalShapedRouteCompiler"
  | 30517578125 => some "ProjectableGeometryTopology"
  | 152587890625 => some "ProjectableGeometryTopology"
  | 152587968750 => some "ProjectableGeometryTopology"
  | 3814697265625 => some "SignalShapedRouteCompiler"
  | 19073496093750 => some "CognitiveLoadField"
  | 476837158203150 => some "CadForceProbeReceipt"
  | 2384185791015625 => some "ProjectableGeometryTopology"
  | 11920928955078125 => some "ProjectableGeometryTopology"
  | 59604644775390626 => some "ProjectableGeometryTopology"
  | 59604644824218750 => some "CognitiveLoadField"
  | 298023223876953125 => some "ProjectableGeometryTopology"
  | 1490116119384765625 => some "ProjectableGeometryTopology"
  | 1490211486816406250 => some "ProjectableGeometryTopology"
  | 1502037048339843750 => some "CognitiveLoadField"
  | 7450580596923828125 => some "ProjectableGeometryTopology"
  | 7510185241699218875 => some "ProjectableGeometryTopology"
  | 37252902984619140625 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 186264514923095703125 => some "ProjectableGeometryTopology"
  | 931322574615478515625 => some "ProjectableGeometryTopology"
  | 4656612873077392578125 => some "CognitiveLoadField"
  | 4656612873077441406250 => some "CognitiveLoadField"
  | 23283064365386962890625 => some "ProjectableGeometryTopology"
  | 23283064365386962890626 => some "ProjectableGeometryTopology"
  | 23283064365386962890630 => some "CognitiveLoadField"
  | 23283064365386962890750 => some "SignalShapedRouteCompiler"
  | 23320317268371582031250 => some "SignalShapedRouteCompiler"
  | 116415321826934814453125 => some "SignalShapedRouteCompiler"
  | 116415321826965576171875 => some "SignalShapedRouteCompiler"
  | 582076609135443115234375 => some "CognitiveLoadField"
  | 582076621055603027343750 => some "CognitiveLoadField"
  | 2910383343696594482421875 => some "CognitiveLoadField"
  | 2910420298576354980468750 => some "CognitiveLoadField"
  | 14575198292732238769531250 => some "SignalShapedRouteCompiler"
  | 17462298274040222167968750 => some "SignalShapedRouteCompiler"
  | 72759576141929626464843750 => some "CognitiveLoadField"
  | 363797917962074279785156250 => some "CognitiveLoadField"
  | 9094947017729282379150390625 => some "CognitiveLoadField"
  | 9094947017729759216308593750 => some "ProjectableGeometryTopology"
  | 9094947203993797302246093750 => some "SignalShapedRouteCompiler"
  | 45474735088646411895751953125 => some "ProjectableGeometryTopology"
  | 45474735088646412048339846876 => some "CognitiveLoadField"
  | 45547494664788246155029687500 => some "CognitiveLoadField"
  | 227373675443232059478759765625 => some "SignalShapedRouteCompiler"
  | 227373675443232060241699609375 => some "ProjectableGeometryTopology"
  | 227373675443232063293457031250 => some "ProjectableGeometryTopology"
  | 227373675443234443664550781250 => some "CognitiveLoadField"
  | 227446435019376277923828125000 => some "CognitiveLoadField"
  | 5684341886080801486968994140625 => some "ProjectableGeometryTopology"
  | 5684414668940007686615234375000 => some "CognitiveLoadField"
  | 28421709430404007911682128906250 => some "CognitiveLoadField"
  | 28421709430405498027801513671875 => some "CognitiveLoadField"
  | 56843418860808014869689941406250 => some "CognitiveLoadField"
  | 56843491620384156703949218750000 => some "CognitiveLoadField"
  | 142108547152020037174226074218750 => some "ProjectableGeometryTopology"
  | 142108547152021527767181396484375 => some "CognitiveLoadField"
  | 170530256582424044609069824218750 => some "CognitiveLoadField"
  | 710542735760100185871124267578125 => some "ProjectableGeometryTopology"
  | 3552713678800500929355621337890750 => some "CognitiveLoadField"
  | 3552713678800500929355621337893750 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 3694822225952520966529846191409375 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 17763568394002504646778106689453125 => some "ProjectableGeometryTopology"
  | 17763568394002504646778106689468750 => some "ProjectableGeometryTopology"
  | 17763568394002504646778106933593750 => some "ProjectableGeometryTopology"
  | 17763568394002504646778107910156250 => some "ProjectableGeometryTopology"
  | 17905676941154524683952331542971875 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 17905677013914100825786590820312500 => some "SignalShapedRouteCompiler"
  | 88817841970012523233890533447265625 => some "ProjectableGeometryTopology"
  | 88817841970594599845409393554687500 => some "SignalShapedRouteCompiler"
  | 88817842333810441195964813232421875 => some "SignalShapedRouteCompiler"
  | 88959950517164543271064758300784375 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 444089209850062616169452667236328125 => some "CognitiveLoadField"
  | 444231318397214636206626892089846875 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 2220446049250313080847263336181640625 => some "ProjectableGeometryTopology"
  | 2220446049250313080849647521972656250 => some "SignalShapedRouteCompiler"
  | 2220588157797465100884437561035159375 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 11102372354798717424273490905761721875 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 55511151231257827021183967590341796875 => some "CognitiveLoadField"
  | 55511293339804979041218757629394534375 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 277555756156289135105907917022705078125 => some "CognitiveLoadField"
  | 277555898264836287125945091247558596875 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 1387778780781445675529539585113525391250 => some "HoldForUnlawfulOrUnderspecifiedShape"
  | 1387778780781445680186152458190917968750 => some "CognitiveLoadField"
  | 1387778780781446257606160640716552734375 => some "CognitiveLoadField"
  | 1387778780783264664933085441589355468750 => some "CognitiveLoadField"
  | 1387779491324181435629725456237792968750 => some "CognitiveLoadField"
  | 6938893903907228377647697925567628906250 => some "SignalShapedRouteCompiler"
  | 173472347597680709441192448139190673828125 => some "ProjectableGeometryTopology"
  | 173472347597680709441229701042175292968750 => some "ProjectableGeometryTopology"
  | 867361737988403547205963742733001708984375 => some "CognitiveLoadField"
  | 867361737988405366195403039455413818359375 => some "CognitiveLoadField"
  | 867361738698946282966062426567077636718750 => some "CognitiveLoadField"
  | 4336808689947702077915892004966735839843750 => some "SignalShapedRouteCompiler"
  | 4337086245698174025164917111396789550781250 => some "ProjectableGeometryTopology"
  | 4337086245698174025164917113780975341796875 => some "ProjectableGeometryTopology"
  | 8673617380594578207819722592830657958984375 => some "ProjectableGeometryTopology"
  | 21684321005466244969284161925315856933593750 => some "SignalShapedRouteCompiler"
  | 108420217248550443400745280086994171142578125 => some "ProjectableGeometryTopology"
  | 108420217248550443400745280086994201660156250 => some "CognitiveLoadField"
  | 108420217248550443400745280098915100097656250 => some "CognitiveLoadField"
  | _ => none

/-- Attested shape exact match via spectral-radius color gate. -/
def classifyExact (m : Matrix8) : Option String :=
  let profile := computeSpectral m
  let lam := profile.adjacency_eigenvalue_max.toInt
  colorToShapeName (spectralRadiusToColor lam)

end SilverSight.PIST.Classify
