Spaces:
Running on Zero
Running on Zero
Fetching metadata from the HF Docker repository...
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>AQARION v20.6 – Interactive Reproducibility Lab</title> | |
| <style> | |
| /* minimal reset and base styling; all other styles are in the React component */ | |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { background: #0a0a0f; color: #f4f4f5; font-family: 'Inter', system-ui, sans-serif; } | |
| .mono { font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace; } | |
| ::-webkit-scrollbar { width: 6px; height: 6px; } | |
| ::-webkit-scrollbar-thumb { background: #2a2a3a; border-radius: 10px; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="root"></div> | |
| <script type="module"> | |
| // ------------------------------------------------------------ | |
| // AQARION v20.6 – Interactive Lab (standalone React + JSX) | |
| // Uses React 18 and Babel standalone for in‑browser transpilation. | |
| // All core logic (defect computation, refinement, certificates) | |
| // is bundled here. | |
| // ------------------------------------------------------------ | |
| // Load React and ReactDOM from CDN | |
| import React from 'https://esm.sh/react@18.3.1'; | |
| import ReactDOM from 'https://esm.sh/react-dom@18.3.1'; | |
| // Babel standalone for JSX transformation | |
| import Babel from 'https://esm.sh/@babel/standalone@7.26.0'; | |
| // Immediately transform the JSX code below | |
| const jsxCode = ` | |
| // ----- AQARION v20.6 React Component ----- | |
| // (the full interactive app) | |
| const { useState, useEffect, useMemo, useRef } = React; | |
| // ---- Core mathematical functions ---- | |
| const COLORS = ['#7c3aed','#06b6d4','#f59e0b','#10b981','#ef4444','#ec4899','#6366f1','#84cc16']; | |
| const COLOR_ALPHA = ['rgba(124,58,237,0.18)','rgba(6,182,214,0.18)','rgba(245,158,11,0.18)','rgba(16,185,129,0.18)','rgba(239,68,68,0.18)','rgba(236,72,153,0.18)','rgba(99,102,241,0.18)','rgba(132,204,22,0.18)']; | |
| // ---- helpers ---- | |
| function renumber(part) { | |
| const map = new Map(); | |
| let next = 0; | |
| return part.map(x => { if (!map.has(x)) map.set(x, next++); return map.get(x); }); | |
| } | |
| function partitionBlocks(part) { | |
| const blocks = new Map(); | |
| part.forEach((b, i) => { if (!blocks.has(b)) blocks.set(b, []); blocks.get(b).push(i); }); | |
| return Array.from(blocks.entries()).sort((a,b) => a[0]-b[0]); | |
| } | |
| function buildProjection(part) { | |
| const n = part.length; | |
| const P = Array.from({ length: n }, () => Array(n).fill(0)); | |
| const blocks = new Map(); | |
| part.forEach((b,i) => { if (!blocks.has(b)) blocks.set(b, []); blocks.get(b).push(i); }); | |
| for (const [, members] of blocks) { | |
| const m = members.length; | |
| for (const i of members) for (const j of members) P[i][j] = 1 / m; | |
| } | |
| return P; | |
| } | |
| function matMul(A, B) { | |
| const n = A.length, m = B[0].length, p = B.length; | |
| const C = Array.from({ length: n }, () => Array(m).fill(0)); | |
| for (let i = 0; i < n; i++) for (let k = 0; k < p; k++) { | |
| if (A[i][k] === 0) continue; | |
| for (let j = 0; j < m; j++) C[i][j] += A[i][k] * B[k][j]; | |
| } | |
| return C; | |
| } | |
| function matSub(A, B) { | |
| const n = A.length, m = A[0].length; | |
| return A.map((row,i) => row.map((v,j) => v - B[i][j])); | |
| } | |
| function identity(n) { | |
| return Array.from({ length: n }, (_,i) => Array.from({ length: n }, (_,j) => i===j ? 1 : 0)); | |
| } | |
| function frobeniusNorm(M) { | |
| let sum = 0; | |
| for (const row of M) for (const v of row) sum += v*v; | |
| return Math.sqrt(sum); | |
| } | |
| // spectral norm via power iteration | |
| function spectralNorm(M, maxIter=40) { | |
| const n = M.length, m = M[0].length; | |
| if (frobeniusNorm(M) < 1e-12) return 0; | |
| let x = Array.from({ length: m }, () => Math.random() * 2 - 1); | |
| let norm = Math.sqrt(x.reduce((s,v) => s + v*v, 0)); | |
| x = x.map(v => v / norm); | |
| let prev = 0; | |
| for (let iter = 0; iter < maxIter; iter++) { | |
| const y = Array(n).fill(0); | |
| for (let i=0; i<n; i++) for (let j=0; j<m; j++) y[i] += M[i][j] * x[j]; | |
| const z = Array(m).fill(0); | |
| for (let i=0; i<m; i++) for (let j=0; j<n; j++) z[i] += M[j][i] * y[j]; | |
| const nz = Math.sqrt(z.reduce((s,v) => s + v*v, 0)); | |
| if (nz < 1e-12) return 0; | |
| x = z.map(v => v / nz); | |
| if (Math.abs(nz - prev) < 1e-12) return nz; | |
| prev = nz; | |
| } | |
| return prev; | |
| } | |
| function buildKoopman(T) { | |
| const n = T.length; | |
| const U = Array.from({ length: n }, () => Array(n).fill(0)); | |
| for (let i = 0; i < n; i++) U[i][T[i]] = 1; | |
| return U; | |
| } | |
| function computeDefects(T, part) { | |
| const n = T.length; | |
| const P = buildProjection(part); | |
| const U = buildKoopman(T); | |
| const I = identity(n); | |
| // D_F = (I-P) U P | |
| const UP = matMul(U, P); | |
| const IminusP = matSub(I, P); | |
| const DF = matMul(IminusP, UP); | |
| // D_B = P U (I-P) | |
| const UIminusP = matMul(U, IminusP); | |
| const DB = matMul(P, UIminusP); | |
| return { P, U, DF, DB, IminusP }; | |
| } | |
| function refineForward(T, init) { | |
| const n = T.length; | |
| let part = init ? [...init] : Array(n).fill(0); | |
| const history = [ [...part] ]; | |
| let changed = true; | |
| while (changed) { | |
| changed = false; | |
| const blocks = new Map(); | |
| part.forEach((b,i) => { if (!blocks.has(b)) blocks.set(b, []); blocks.get(b).push(i); }); | |
| const blockList = Array.from(blocks.keys()).sort((a,b)=>a-b); | |
| const newPart = Array(n).fill(null); | |
| let nextId = 0; | |
| for (const bid of blockList) { | |
| const members = blocks.get(bid); | |
| const groups = new Map(); | |
| for (const s of members) { | |
| const img = part[T[s]]; | |
| if (!groups.has(img)) groups.set(img, []); | |
| groups.get(img).push(s); | |
| } | |
| for (const [, group] of groups) { | |
| for (const s of group) newPart[s] = nextId; | |
| nextId++; | |
| } | |
| } | |
| if (newPart.some((v,i) => v !== part[i])) { | |
| part = newPart; | |
| history.push([...part]); | |
| changed = true; | |
| } | |
| } | |
| return part; | |
| } | |
| function refineBisim(T, init) { | |
| const n = T.length; | |
| const pre = Array.from({ length: n }, () => []); | |
| for (let i=0; i<n; i++) pre[T[i]].push(i); | |
| let part = init ? [...init] : Array(n).fill(0); | |
| const history = [ [...part] ]; | |
| let changed = true; | |
| while (changed) { | |
| changed = false; | |
| const blocks = new Map(); | |
| part.forEach((b,i) => { if (!blocks.has(b)) blocks.set(b, []); blocks.get(b).push(i); }); | |
| const blockList = Array.from(blocks.keys()).sort((a,b)=>a-b); | |
| const newPart = Array(n).fill(null); | |
| let nextId = 0; | |
| for (const bid of blockList) { | |
| const members = blocks.get(bid); | |
| const groups = new Map(); | |
| for (const s of members) { | |
| const img = part[T[s]]; | |
| const pc = blockList.map(b => pre[s].filter(p => part[p] === b).length); | |
| const key = JSON.stringify([img, pc]); | |
| if (!groups.has(key)) groups.set(key, []); | |
| groups.get(key).push(s); | |
| } | |
| for (const [, group] of groups) { | |
| for (const s of group) newPart[s] = nextId; | |
| nextId++; | |
| } | |
| } | |
| if (newPart.some((v,i) => v !== part[i])) { | |
| part = newPart; | |
| history.push([...part]); | |
| changed = true; | |
| } | |
| } | |
| return part; | |
| } | |
| // ---- coarsest check for forward track ---- | |
| function isCoarsestForward(T, part, tol=1e-9) { | |
| const n = T.length; | |
| const blocks = Array.from(new Set(part)).sort((a,b)=>a-b); | |
| if (blocks.length <= 1) return true; | |
| for (let i=0; i<blocks.length; i++) { | |
| for (let j=i+1; j<blocks.length; j++) { | |
| const merged = part.map(b => (b === blocks[j]) ? blocks[i] : b); | |
| const relabeled = renumber(merged); | |
| const { DF } = computeDefects(T, relabeled); | |
| const norm = spectralNorm(DF); | |
| if (norm < tol) return false; | |
| } | |
| } | |
| return true; | |
| } | |
| // ---- presets ---- | |
| const PRESETS = [ | |
| { label: 'T=[2,2,2] strict', T: [2,2,2], desc: 'Π*_F single block, Π*_B splits {0,1} vs {2}' }, | |
| { label: 'T=[0,0] collapse', T: [0,0], desc: 'D_F=0 but D_B≠0' }, | |
| { label: 'T=[1,0,1] chain', T: [1,0,1], desc: '3-node chain with leak' }, | |
| { label: 'Kaprekar-6 cond', T: [1,2,3,4,5,5], desc: '6-state condensation of 6174 transient' }, | |
| { label: 'T=[1,2,0] cycle', T: [1,2,0], desc: 'Pure 3-cycle invariant' } | |
| ]; | |
| // ---- main component ---- | |
| function App() { | |
| const [n, setN] = useState(3); | |
| const [T, setT] = useState([2,2,2]); | |
| const [track, setTrack] = useState('F'); // 'F' or 'B' | |
| const [step, setStep] = useState(0); | |
| const [certHash, setCertHash] = useState(''); | |
| const [toast, setToast] = useState(''); | |
| const [showMatrices, setShowMatrices] = useState(false); | |
| const inputRef = useRef(null); | |
| // ensure T length matches n | |
| useEffect(() => { | |
| if (T.length !== n) { | |
| const newT = T.length < n ? [...T, ...Array(n-T.length).fill(0)] : T.slice(0,n); | |
| setT(newT.map(v => Math.min(Math.max(v,0), n-1))); | |
| } | |
| }, [n]); | |
| // history | |
| const history = useMemo(() => { | |
| const init = Array(n).fill(0); | |
| if (track === 'F') { | |
| const parts = []; | |
| let part = [...init]; | |
| parts.push([...part]); | |
| let changed = true; | |
| while (changed) { | |
| changed = false; | |
| const blocks = new Map(); | |
| part.forEach((b,i) => { if (!blocks.has(b)) blocks.set(b, []); blocks.get(b).push(i); }); | |
| const blockList = Array.from(blocks.keys()).sort((a,b)=>a-b); | |
| const newPart = Array(n).fill(null); | |
| let nextId = 0; | |
| for (const bid of blockList) { | |
| const members = blocks.get(bid); | |
| const groups = new Map(); | |
| for (const s of members) { | |
| const img = part[T[s]]; | |
| if (!groups.has(img)) groups.set(img, []); | |
| groups.get(img).push(s); | |
| } | |
| for (const [, group] of groups) { | |
| for (const s of group) newPart[s] = nextId; | |
| nextId++; | |
| } | |
| } | |
| if (newPart.some((v,i) => v !== part[i])) { | |
| part = newPart; | |
| parts.push([...part]); | |
| changed = true; | |
| } | |
| } | |
| return parts; | |
| } else { | |
| // Track B | |
| const pre = Array.from({ length: n }, () => []); | |
| for (let i=0; i<n; i++) pre[T[i]].push(i); | |
| const parts = []; | |
| let part = [...init]; | |
| parts.push([...part]); | |
| let changed = true; | |
| while (changed) { | |
| changed = false; | |
| const blocks = new Map(); | |
| part.forEach((b,i) => { if (!blocks.has(b)) blocks.set(b, []); blocks.get(b).push(i); }); | |
| const blockList = Array.from(blocks.keys()).sort((a,b)=>a-b); | |
| const newPart = Array(n).fill(null); | |
| let nextId = 0; | |
| for (const bid of blockList) { | |
| const members = blocks.get(bid); | |
| const groups = new Map(); | |
| for (const s of members) { | |
| const img = part[T[s]]; | |
| const pc = blockList.map(b => pre[s].filter(p => part[p] === b).length); | |
| const key = JSON.stringify([img, pc]); | |
| if (!groups.has(key)) groups.set(key, []); | |
| groups.get(key).push(s); | |
| } | |
| for (const [, group] of groups) { | |
| for (const s of group) newPart[s] = nextId; | |
| nextId++; | |
| } | |
| } | |
| if (newPart.some((v,i) => v !== part[i])) { | |
| part = newPart; | |
| parts.push([...part]); | |
| changed = true; | |
| } | |
| } | |
| return parts; | |
| } | |
| }, [T, n, track]); | |
| // current partition | |
| const currentPart = history[Math.min(step, history.length-1)] || history[0]; | |
| const finalPart = history[history.length-1]; | |
| // defects for current and final | |
| const defsCurrent = useMemo(() => computeDefects(T, currentPart), [T, currentPart]); | |
| const defsFinal = useMemo(() => computeDefects(T, finalPart), [T, finalPart]); | |
| const normF_fro = frobeniusNorm(defsCurrent.DF); | |
| const normF_spec = spectralNorm(defsCurrent.DF); | |
| const normB_fro = frobeniusNorm(defsCurrent.DB); | |
| const normB_spec = spectralNorm(defsCurrent.DB); | |
| const theta_deg = Math.asin(Math.min(1, normF_spec)) * 180 / Math.PI; | |
| // coarsest check | |
| const coarsest = useMemo(() => isCoarsestForward(T, finalPart), [T, finalPart]); | |
| // certificate hash | |
| useEffect(() => { | |
| const obj = { | |
| version: 'v20.6', | |
| track, | |
| T, | |
| partition: finalPart, | |
| defects: { | |
| DF_fro: frobeniusNorm(defsFinal.DF), | |
| DF_spec: spectralNorm(defsFinal.DF), | |
| DB_fro: frobeniusNorm(defsFinal.DB), | |
| DB_spec: spectralNorm(defsFinal.DB) | |
| }, | |
| theta_max_deg: Math.asin(Math.min(1, spectralNorm(defsFinal.DF))) * 180 / Math.PI, | |
| coarsest, | |
| timestamp: new Date().toISOString() | |
| }; | |
| const str = JSON.stringify(obj); | |
| crypto.subtle.digest('SHA-256', new TextEncoder().encode(str)).then(buf => { | |
| const hash = Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2,'0')).join('').slice(0,16); | |
| setCertHash(hash); | |
| }); | |
| }, [T, finalPart, track]); | |
| // export certificate | |
| const exportCert = () => { | |
| const obj = { | |
| version: 'v20.6', | |
| track, | |
| T, | |
| n, | |
| partition: finalPart, | |
| history: history.map(p => ({ partition: p, blocks: new Set(p).size })), | |
| defects: { | |
| DF_fro: frobeniusNorm(defsFinal.DF), | |
| DF_spec: spectralNorm(defsFinal.DF), | |
| DB_fro: frobeniusNorm(defsFinal.DB), | |
| DB_spec: spectralNorm(defsFinal.DB) | |
| }, | |
| theta_max_deg: Math.asin(Math.min(1, spectralNorm(defsFinal.DF))) * 180 / Math.PI, | |
| coarsest, | |
| theorem: 'D_F=(I-P)UP=0 ⇔ forward-invariant; Track B adds D_B=PU(I-P)=0 for bisimulation', | |
| timestamp: new Date().toISOString(), | |
| hash: certHash | |
| }; | |
| const blob = new Blob([JSON.stringify(obj, null, 2)], { type: 'application/json' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = `aqarion_cert_${T.join('-')}_${certHash}.json`; | |
| a.click(); | |
| URL.revokeObjectURL(url); | |
| setToast('Certificate exported ✓'); | |
| setTimeout(() => setToast(''), 2000); | |
| }; | |
| // graph coordinates | |
| const coords = useMemo(() => { | |
| return T.map((_, i) => { | |
| const angle = 2 * Math.PI * i / T.length - Math.PI/2; | |
| return { x: 120 + 78 * Math.cos(angle), y: 120 + 78 * Math.sin(angle) }; | |
| }); | |
| }, [T]); | |
| return React.createElement('div', { | |
| className: 'min-h-screen bg-[#0a0a0f] text-zinc-100 selection:bg-violet-500/30 font-[Inter,system-ui,sans-serif]' | |
| }, [ | |
| React.createElement('style', { key: 'style', children: ` | |
| @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=IBM+Plex+Mono:wght@400;600&display=swap'); | |
| .mono { font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace; } | |
| ` }), | |
| // Header | |
| React.createElement('header', { key: 'header', className: 'sticky top-0 z-20 backdrop-blur-xl bg-[#0a0a0f]/80 border-b border-zinc-800' }, | |
| React.createElement('div', { className: 'max-w-[1600px] mx-auto px-4 md:px-6 py-3 flex flex-wrap items-center justify-between gap-3' }, | |
| React.createElement('div', { className: 'flex items-center gap-3' }, | |
| React.createElement('div', { className: 'h-8 w-8 rounded-lg bg-gradient-to-br from-violet-500 to-cyan-400 grid place-items-center font-bold text-black text-[11px] tracking-widest' }, 'AQ'), | |
| React.createElement('div', null, | |
| React.createElement('div', { className: 'flex items-center gap-2' }, | |
| React.createElement('h1', { className: 'text-[13px] md:text-[15px] font-semibold tracking-tight' }, 'AQARION v20.6 — Interactive Reproducibility Lab'), | |
| React.createElement('span', { className: 'mono text-[10px] px-2 py-0.5 rounded-full bg-emerald-500/20 text-emerald-300 border border-emerald-500/30' }, 'FINAL CORRECTED') | |
| ), | |
| React.createElement('div', { className: 'mono text-[11px] text-zinc-400 hidden md:block' }, 'for AI/ML Teams • NeurIPS/ICLR Reproducibility') | |
| ) | |
| ), | |
| React.createElement('div', { className: 'flex items-center gap-3' }, | |
| React.createElement('div', { className: 'mono text-[11px] md:text-[12px] px-3 py-1.5 rounded-full bg-zinc-900 border border-zinc-800 flex items-center gap-2' }, | |
| React.createElement('span', { className: 'text-zinc-500' }, 'defect'), | |
| React.createElement('span', { className: 'text-white font-semibold' }, 'D_F=(I-P)UP'), | |
| React.createElement('span', { className: 'h-3 w-px bg-zinc-700' }), | |
| React.createElement('span', { className: 'text-violet-300' }, '‖D_F‖=sin(θ_max)') | |
| ), | |
| React.createElement('div', { className: 'flex flex-col items-end gap-1' }, | |
| React.createElement('div', { className: 'flex rounded-full bg-zinc-900 border border-zinc-800 p-0.5' }, | |
| ['F','B'].map(t => React.createElement('button', { | |
| key: t, | |
| onClick: () => { setTrack(t); setStep(0); setToast(`Switched to Track ${t}`); setTimeout(()=>setToast(''),1500); }, | |
| className: `mono text-[11px] px-3 py-1 rounded-full transition-all ${track===t ? 'bg-white text-black font-bold shadow' : 'text-zinc-400 hover:text-zinc-100'}` | |
| }, `Track ${t} ${t==='F'?'• forward':'• bisim'}`)) | |
| ), | |
| toast && React.createElement('div', { className: 'mono text-[10px] text-violet-300 bg-zinc-900 border border-zinc-800 px-2 py-0.5 rounded-full' }, toast) | |
| ) | |
| ) | |
| ) | |
| ), | |
| // Main grid | |
| React.createElement('div', { key: 'main', className: 'max-w-[1600px] mx-auto px-3 md:px-6 py-4 grid grid-cols-1 lg:grid-cols-[340px_1fr_380px] gap-4' }, | |
| // Left panel: graph editor | |
| React.createElement('section', { className: 'rounded-[18px] bg-zinc-900/60 border border-zinc-800 backdrop-blur p-4 flex flex-col gap-4 h-fit lg:sticky lg:top-[66px]' }, | |
| React.createElement('div', { className: 'flex items-center justify-between' }, | |
| React.createElement('h2', { className: 'text-[12px] font-semibold tracking-widest uppercase text-zinc-400' }, 'Functional Graph Editor'), | |
| React.createElement('span', { className: 'mono text-[10px] text-zinc-500' }, `n = ${n}`) | |
| ), | |
| React.createElement('div', { className: 'space-y-3' }, | |
| React.createElement('div', null, | |
| React.createElement('label', { className: 'mono text-[11px] text-zinc-400' }, `Size n = ${n}`), | |
| React.createElement('input', { type: 'range', min: 2, max: 8, value: n, onChange: e => setN(parseInt(e.target.value)), className: 'w-full accent-violet-500' }), | |
| React.createElement('div', { className: 'flex justify-between mono text-[10px] text-zinc-600' }, | |
| React.createElement('span', null, '2'), React.createElement('span', null, '8') | |
| ) | |
| ), | |
| React.createElement('div', null, | |
| React.createElement('label', { className: 'mono text-[11px] text-zinc-400' }, 'T as comma list (T[i]=image)'), | |
| React.createElement('input', { | |
| ref: inputRef, | |
| value: T.join(','), | |
| onChange: e => { | |
| const raw = e.target.value.split(',').map(s => parseInt(s.trim(), 10)).filter(v => !isNaN(v)); | |
| if (raw.length >= 2 && raw.length <= 8) { | |
| const clamped = raw.map(v => Math.min(Math.max(v,0), raw.length-1)); | |
| setT(clamped); | |
| setN(clamped.length); | |
| } | |
| }, | |
| className: 'mono w-full mt-1 bg-black/50 border border-zinc-800 rounded-lg px-3 py-2 text-[13px] focus:outline-none focus:border-violet-500/50', | |
| placeholder: '2,2,2' | |
| }), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 mt-1' }, `Current: [${T.join(', ')}]`) | |
| ), | |
| React.createElement('div', { className: 'flex gap-2' }, | |
| React.createElement('button', { | |
| onClick: () => { | |
| const newT = Array.from({ length: n }, () => Math.floor(Math.random() * n)); | |
| setT(newT); | |
| setStep(0); | |
| setToast('randomized'); | |
| setTimeout(()=>setToast(''),1000); | |
| }, | |
| className: 'flex-1 mono text-[11px] px-3 py-2 rounded-lg bg-zinc-800 hover:bg-zinc-700 border border-zinc-700 transition' | |
| }, '🎲 Random'), | |
| React.createElement('button', { | |
| onClick: () => { | |
| const clamped = T.map(v => Math.min(Math.max(v,0), n-1)); | |
| if (clamped.some((v,i) => v !== T[i])) { | |
| setT(clamped); | |
| setToast('clamped'); | |
| setTimeout(()=>setToast(''),1000); | |
| } else { | |
| setToast('already clamped ✓'); | |
| setTimeout(()=>setToast(''),1000); | |
| } | |
| }, | |
| className: 'mono text-[11px] px-3 py-2 rounded-lg bg-zinc-800 hover:bg-zinc-700 border border-zinc-700 transition' | |
| }, 'Clamp') | |
| ) | |
| ), | |
| React.createElement('div', null, | |
| React.createElement('div', { className: 'mono text-[11px] uppercase tracking-widest text-zinc-500 mb-2' }, 'Presets'), | |
| React.createElement('div', { className: 'grid gap-1.5' }, | |
| PRESETS.map(p => React.createElement('button', { | |
| key: p.label, | |
| onClick: () => { setT(p.T); setN(p.T.length); setStep(0); setToast(p.label); setTimeout(()=>setToast(''),1500); }, | |
| className: `text-left px-3 py-2 rounded-lg border transition ${T.join(',')===p.T.join(',') ? 'bg-violet-500/15 border-violet-500/40' : 'bg-black/40 border-zinc-800 hover:border-zinc-700'}` | |
| }, | |
| React.createElement('div', { className: 'mono text-[12px] font-semibold' }, p.label), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 truncate' }, p.desc) | |
| )) | |
| ) | |
| ), | |
| // Graph viz | |
| React.createElement('div', { className: 'rounded-xl bg-black/60 border border-zinc-800 p-2' }, | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 mb-1 px-1' }, `Graph • colored by block Π_${Math.min(step, history.length-1)}`), | |
| React.createElement('svg', { viewBox: '0 0 240 240', className: 'w-full h-[240px]' }, | |
| React.createElement('defs', null, | |
| React.createElement('marker', { id: 'arrow', viewBox: '0 0 10 10', refX: '8', refY: '5', markerWidth: '6', markerHeight: '6', orient: 'auto-start-reverse' }, | |
| React.createElement('path', { d: 'M 0 0 L 10 5 L 0 10 z', fill: '#a1a1aa' }) | |
| ) | |
| ), | |
| T.map((target, i) => { | |
| const src = coords[i], dst = coords[target]; | |
| if (!src || !dst) return null; | |
| if (i === target) { | |
| return React.createElement('path', { key: `loop-${i}`, d: `M ${src.x} ${src.y} c 18 -18 18 18 0 0`, fill: 'none', stroke: '#3f3f46', strokeWidth: '1.2', markerEnd: 'url(#arrow)', opacity: 0.9 }); | |
| } | |
| const mx = (src.x + dst.x)/2 + (dst.y - src.y)*0.12; | |
| const my = (src.y + dst.y)/2 + (src.x - dst.x)*-0.12; | |
| return React.createElement('path', { key: `edge-${i}`, d: `M ${src.x} ${src.y} Q ${mx} ${my} ${dst.x} ${dst.y}`, fill: 'none', stroke: '#52525b', strokeWidth: '1.1', markerEnd: 'url(#arrow)', opacity: 0.8 }); | |
| }), | |
| coords.map((p, i) => { | |
| const block = currentPart[i]; | |
| const color = COLORS[block % COLORS.length]; | |
| const alpha = COLOR_ALPHA[block % COLOR_ALPHA.length]; | |
| return React.createElement('g', { key: i }, | |
| React.createElement('circle', { cx: p.x, cy: p.y, r: 18, fill: color, stroke: 'white', strokeOpacity: 0.25, strokeWidth: 1.5 }), | |
| React.createElement('circle', { cx: p.x, cy: p.y, r: 18, fill: alpha }), | |
| React.createElement('text', { x: p.x, y: p.y+4, textAnchor: 'middle', className: 'mono', fontSize: 13, fontWeight: 700, fill: 'white' }, i) | |
| ); | |
| }) | |
| ), | |
| React.createElement('div', { className: 'flex flex-wrap gap-1 px-1' }, | |
| partitionBlocks(currentPart).map(([b, members]) => | |
| React.createElement('span', { key: b, className: 'mono text-[10px] px-2 py-0.5 rounded-full border', style: { background: COLOR_ALPHA[b%8], borderColor: COLORS[b%8]+'55', color: COLORS[b%8] } }, | |
| `B${b}: ${members.join(',')}` | |
| ) | |
| ) | |
| ) | |
| ), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 leading-relaxed bg-zinc-950/60 rounded-lg p-3 border border-zinc-900' }, | |
| React.createElement('span', { className: 'text-zinc-300' }, 'T'), ' is deterministic. Color = block membership. Splitting occurs when ', | |
| React.createElement('span', { className: 'text-violet-300' }, 'sig_F(s)=block(T(s))'), ' differs inside a block. Track B also checks preimage counts ', | |
| React.createElement('span', { className: 'text-cyan-300' }, '|T⁻¹(s)∩B|'), '.' | |
| ) | |
| ), | |
| // Middle panel: timeline and details | |
| React.createElement('section', { className: 'rounded-[18px] bg-zinc-900/50 border border-zinc-800 backdrop-blur flex flex-col overflow-hidden' }, | |
| React.createElement('div', { className: 'px-5 py-4 border-b border-zinc-800 flex items-center justify-between' }, | |
| React.createElement('h2', { className: 'text-[12px] font-semibold tracking-widest uppercase text-zinc-400' }, 'Partition Refinement Timeline'), | |
| React.createElement('div', { className: 'flex items-center gap-2 mono text-[11px]' }, | |
| React.createElement('span', { className: 'text-zinc-500' }, 'step'), | |
| React.createElement('input', { type: 'range', min: 0, max: history.length-1, value: Math.min(step, history.length-1), onChange: e => setStep(parseInt(e.target.value)), className: 'w-24 accent-white' }), | |
| React.createElement('span', { className: 'px-2 py-0.5 rounded bg-white text-black font-bold' }, Math.min(step, history.length-1)), | |
| React.createElement('span', { className: 'text-zinc-500' }, `/ ${history.length-1}`) | |
| ) | |
| ), | |
| React.createElement('div', { className: 'px-5 py-4 flex items-center gap-2 overflow-x-auto' }, | |
| history.map((p, idx) => | |
| React.createElement('div', { key: idx, className: 'flex items-center gap-2 shrink-0' }, | |
| React.createElement('button', { | |
| onClick: () => setStep(idx), | |
| className: `group relative rounded-xl border px-3 py-2 mono text-[11px] transition ${idx === Math.min(step, history.length-1) ? 'bg-white text-black border-white' : 'bg-zinc-800/80 border-zinc-700 text-zinc-300 hover:border-zinc-600'}` | |
| }, | |
| React.createElement('div', { className: 'font-bold' }, `Π${idx}`), | |
| React.createElement('div', { className: 'text-[10px] opacity-70' }, `${new Set(p).size} block${new Set(p).size>1?'s':''}`), | |
| React.createElement('div', { className: 'mt-1 flex gap-0.5' }, | |
| Array.from({ length: Math.min(8, p.length) }).map((_, j) => | |
| React.createElement('div', { key: j, className: 'h-1.5 w-1.5 rounded-full', style: { background: COLORS[p[j]%8] } }) | |
| ) | |
| ) | |
| ), | |
| idx < history.length-1 && React.createElement('div', { className: 'h-px w-6 bg-zinc-700' }) | |
| ) | |
| ) | |
| ), | |
| React.createElement('div', { className: 'grid md:grid-cols-2 gap-4 px-5 pb-5' }, | |
| // Left: current partition details | |
| React.createElement('div', { className: 'rounded-xl bg-black/50 border border-zinc-800 p-3' }, | |
| React.createElement('div', { className: 'mono text-[11px] uppercase tracking-widest text-zinc-500 mb-3' }, `Current Partition Π${Math.min(step, history.length-1)} — ${new Set(currentPart).size} blocks`), | |
| React.createElement('div', { className: 'space-y-2' }, | |
| partitionBlocks(currentPart).map(([b, members]) => | |
| React.createElement('div', { key: b, className: 'rounded-lg border px-3 py-2 flex items-center justify-between', style: { background: COLOR_ALPHA[b%8], borderColor: COLORS[b%8]+'33' } }, | |
| React.createElement('div', { className: 'flex items-center gap-2' }, | |
| React.createElement('div', { className: 'h-3 w-3 rounded-full', style: { background: COLORS[b%8] } }), | |
| React.createElement('span', { className: 'mono text-[12px] font-semibold' }, `B${b}`), | |
| React.createElement('span', { className: 'mono text-[11px] text-zinc-300' }, `{ ${members.join(', ')} }`) | |
| ), | |
| React.createElement('span', { className: 'mono text-[10px] text-zinc-400' }, `|B|=${members.length}`) | |
| ) | |
| ) | |
| ), | |
| React.createElement('div', { className: 'mt-3 mono text-[10px] text-zinc-500' }, | |
| 'Refinement invariant: Π', String.fromCharCode(0x7B), 'k+1', String.fromCharCode(0x7D), ' ⪯ Π', String.fromCharCode(0x7B), 'k', String.fromCharCode(0x7D), '. Blocks only split, never merge. At most n−1 steps.' | |
| ) | |
| ), | |
| // Right: signatures | |
| React.createElement('div', { className: 'rounded-xl bg-black/50 border border-zinc-800 p-3' }, | |
| React.createElement('div', { className: 'mono text-[11px] uppercase tracking-widest text-zinc-500 mb-3' }, `Signatures sig${track==='F'?'_F':'_B'} at step ${Math.min(step, history.length-1)}`), | |
| React.createElement('div', { className: 'overflow-auto' }, | |
| React.createElement('table', { className: 'w-full mono text-[11px]' }, | |
| React.createElement('thead', null, | |
| React.createElement('tr', { className: 'text-zinc-500' }, | |
| React.createElement('th', { className: 'text-left py-1' }, 's'), | |
| React.createElement('th', { className: 'text-left' }, 'block(s)'), | |
| React.createElement('th', { className: 'text-left' }, 'T(s)'), | |
| React.createElement('th', { className: 'text-left' }, 'img=block(T(s))'), | |
| track === 'B' && React.createElement('th', { className: 'text-left' }, 'preCounts') | |
| ) | |
| ), | |
| React.createElement('tbody', null, | |
| T.map((target, i) => { | |
| const block = currentPart[i]; | |
| const imgBlock = currentPart[target]; | |
| const preCounts = {}; | |
| for (let k=0; k<T.length; k++) { | |
| if (T[k] === i) preCounts[currentPart[k]] = (preCounts[currentPart[k]] || 0) + 1; | |
| } | |
| return React.createElement('tr', { key: i, className: 'border-t border-zinc-900' }, | |
| React.createElement('td', { className: 'py-1.5' }, | |
| React.createElement('span', { className: 'inline-grid place-items-center h-5 w-5 rounded-full text-[11px] font-bold', style: { background: COLORS[block%8], color: 'white' } }, i) | |
| ), | |
| React.createElement('td', { className: 'text-zinc-300' }, `B${block}`), | |
| React.createElement('td', null, target), | |
| React.createElement('td', null, | |
| React.createElement('span', { className: 'px-1.5 py-0.5 rounded bg-zinc-800 border border-zinc-700' }, `B${imgBlock}`) | |
| ), | |
| track === 'B' && React.createElement('td', { className: 'text-zinc-400' }, | |
| Object.entries(preCounts).map(([b, cnt]) => `B${b}:${cnt}`).join(' ') || '∅' | |
| ) | |
| ); | |
| }) | |
| ) | |
| ) | |
| ), | |
| React.createElement('div', { className: 'mt-3 rounded-lg bg-violet-950/30 border border-violet-900/50 p-2 mono text-[10px] leading-relaxed' }, | |
| React.createElement('span', { className: 'text-violet-300 font-bold' }, 'Lemma 3.1 necessity:'), | |
| ' ', React.createElement('span', { className: 'text-zinc-300' }, 'If sig_F(s)≠sig_F(t) inside same block, any forward-invariant refinement must separate s,t. Hence split is mandatory.') | |
| ) | |
| ) | |
| ), | |
| // history encoding footer | |
| React.createElement('div', { className: 'mt-auto px-5 py-3 border-t border-zinc-800 bg-zinc-950/40 mono text-[10px] text-zinc-500 flex flex-wrap gap-2' }, | |
| React.createElement('span', null, 'History encoding: '), | |
| history.map((p, idx) => | |
| React.createElement('span', { key: idx, className: idx === Math.min(step, history.length-1) ? 'text-white font-bold' : '' }, | |
| `[${p.join('')}]`, idx < history.length-1 ? ' → ' : '' | |
| ) | |
| ) | |
| ) | |
| ), | |
| // Right panel: certificates and metrics | |
| React.createElement('section', { className: 'rounded-[18px] bg-zinc-900/60 border border-zinc-800 backdrop-blur p-4 flex flex-col gap-4 h-fit lg:sticky lg:top-[66px]' }, | |
| React.createElement('div', { className: 'flex items-center justify-between' }, | |
| React.createElement('h2', { className: 'text-[12px] font-semibold tracking-widest uppercase text-zinc-400' }, 'Certificates'), | |
| React.createElement('button', { onClick: () => setShowMatrices(!showMatrices), className: 'mono text-[10px] px-2 py-1 rounded bg-zinc-800 border border-zinc-700 hover:bg-zinc-700' }, showMatrices ? 'Hide matrices' : 'Show matrices') | |
| ), | |
| // Stability badge | |
| React.createElement('div', { className: `rounded-xl border p-3 flex items-center justify-between ${spectralNorm(defsFinal.DF) < 1e-9 ? 'bg-emerald-500/10 border-emerald-500/30' : 'bg-amber-500/10 border-amber-500/30'}` }, | |
| React.createElement('div', null, | |
| React.createElement('div', { className: 'mono text-[11px] text-zinc-400' }, 'Π* stability'), | |
| React.createElement('div', { className: `mono text-[13px] font-bold ${spectralNorm(defsFinal.DF) < 1e-9 ? 'text-emerald-300' : 'text-amber-300'}` }, | |
| spectralNorm(defsFinal.DF) < 1e-9 ? 'STABLE — D_F=0' : `LEAKING — ‖D_F‖=${spectralNorm(defsFinal.DF).toFixed(4)}` | |
| ) | |
| ), | |
| React.createElement('div', { className: `h-10 w-10 rounded-full grid place-items-center text-[16px] ${spectralNorm(defsFinal.DF) < 1e-9 ? 'bg-emerald-500/20' : 'bg-amber-500/20'}` }, | |
| spectralNorm(defsFinal.DF) < 1e-9 ? '✓' : '⚠' | |
| ) | |
| ), | |
| // Defect metrics | |
| React.createElement('div', { className: 'grid grid-cols-2 gap-2' }, | |
| React.createElement('div', { className: 'rounded-lg bg-black/60 border border-zinc-800 p-3' }, | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, '‖D_F‖₂ spec (sin θ_max)'), | |
| React.createElement('div', { className: 'mono text-[16px] font-bold text-white' }, spectralNorm(defsCurrent.DF).toExponential(2)), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, `at Π${Math.min(step, history.length-1)}`) | |
| ), | |
| React.createElement('div', { className: 'rounded-lg bg-black/60 border border-zinc-800 p-3' }, | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, '‖D_F‖_F'), | |
| React.createElement('div', { className: 'mono text-[16px] font-bold text-violet-300' }, frobeniusNorm(defsCurrent.DF).toExponential(2)), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, 'Frobenius') | |
| ), | |
| React.createElement('div', { className: 'rounded-lg bg-black/60 border border-zinc-800 p-3' }, | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, '‖D_B‖₂ = ‖P U(I-P)‖'), | |
| React.createElement('div', { className: 'mono text-[16px] font-bold text-cyan-300' }, spectralNorm(defsCurrent.DB).toExponential(2)) | |
| ), | |
| React.createElement('div', { className: 'rounded-lg bg-black/60 border border-zinc-800 p-3' }, | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, 'θ_max = arcsin‖D_F‖₂'), | |
| React.createElement('div', { className: 'mono text-[16px] font-bold text-amber-200' }, `${theta_deg.toFixed(1)}°`), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500' }, 'principal angle') | |
| ) | |
| ), | |
| // Final partition summary | |
| React.createElement('div', { className: 'rounded-xl bg-zinc-950 border border-zinc-800 p-3 mono text-[11px] leading-relaxed' }, | |
| React.createElement('div', { className: 'text-zinc-400' }, `Final Π* (Track ${track})`), | |
| React.createElement('div', { className: 'text-white font-semibold mt-1' }, | |
| `Defects: F₂=${frobeniusNorm(defsFinal.DF).toExponential(2)} • spec=${spectralNorm(defsFinal.DF).toExponential(2)} • θ_max=${(Math.asin(Math.min(1, spectralNorm(defsFinal.DF)))*180/Math.PI).toFixed(2)}°` | |
| ), | |
| React.createElement('div', { className: `mt-2 inline-flex px-2 py-0.5 rounded-full text-[10px] border ${coarsest ? 'bg-emerald-500/15 border-emerald-500/30 text-emerald-300' : 'bg-red-500/15 border-red-500/30 text-red-300'}` }, | |
| coarsest ? '✓ Coarsest check PASS — no merge preserves D_F=0' : '✗ Not coarsest — some merge still D_F=0' | |
| ) | |
| ), | |
| // Matrices | |
| showMatrices && React.createElement('div', { className: 'space-y-3 max-h-[320px] overflow-auto' }, | |
| [ | |
| { name: 'P — averaging projector', mat: defsCurrent.P }, | |
| { name: 'U — Koopman (U[i,T[i]]=1)', mat: defsCurrent.U }, | |
| { name: 'D_F=(I-P)UP — forward leakage', mat: defsCurrent.DF }, | |
| { name: 'D_B=PU(I-P) — backward', mat: defsCurrent.DB } | |
| ].map(({name, mat}) => | |
| React.createElement('div', { key: name, className: 'rounded-lg bg-black border border-zinc-800 p-2' }, | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 mb-1' }, name), | |
| React.createElement('div', { className: 'mono text-[9px] leading-[1.1] text-zinc-300 overflow-auto' }, | |
| mat.map((row, i) => | |
| React.createElement('div', { key: i, className: 'whitespace-nowrap' }, | |
| row.map(v => v.toFixed(2).padStart(5)).join(' ') | |
| ) | |
| ) | |
| ) | |
| ) | |
| ) | |
| ), | |
| // AI/ML differentiable loss | |
| React.createElement('div', { className: 'rounded-xl bg-gradient-to-br from-violet-950/40 to-zinc-900 border border-violet-900/30 p-3' }, | |
| React.createElement('div', { className: 'mono text-[11px] font-bold text-violet-200' }, 'For AI/ML Teams — Differentiable Loss'), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-400 mt-1' }, | |
| 'Forward leakage is differentiable and equals sin(θ_max)² in Frobenius sense. Use as regularizer for trustworthy Koopman learning.' | |
| ), | |
| React.createElement('pre', { className: 'mono text-[11px] mt-2 bg-black/70 rounded-lg p-2 border border-zinc-800 overflow-auto text-emerald-200' }, | |
| `# PyTorch — Shah & Cortés 2026\nloss = torch.norm((I - P) @ U @ P, p='fro')**2\n# = sin(theta_max)^2 proxy\n# Add: loss_total = pred_loss + λ*loss\n# P = averaging projector onto block-const\n# or learned subspace projector` | |
| ), | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 mt-2' }, | |
| 'Theorem: ‖L‖=‖(I-P)UP‖=sin(θ_max) between V and U(V). L=0 ⇔ exact quotient.' | |
| ) | |
| ), | |
| // Certificate hash and export | |
| React.createElement('div', { className: 'rounded-xl bg-zinc-950 border border-zinc-800 p-3 flex items-center justify-between gap-3' }, | |
| React.createElement('div', { className: 'mono text-[11px]' }, | |
| React.createElement('div', { className: 'text-zinc-400' }, 'Certificate hash (SHA256[:16])'), | |
| React.createElement('div', { className: 'font-bold text-white tracking-widest' }, certHash || 'computing...'), | |
| React.createElement('div', { className: 'text-[10px] text-zinc-500' }, `T=${T.join(',')} Π*=${finalPart.join('')} Track ${track}`) | |
| ), | |
| React.createElement('button', { onClick: exportCert, className: 'mono text-[11px] px-3 py-2 rounded-lg bg-white text-black font-bold hover:bg-zinc-200 transition shrink-0' }, 'Export JSON') | |
| ), | |
| // Theorem footer | |
| React.createElement('div', { className: 'mono text-[10px] text-zinc-500 leading-relaxed border-t border-zinc-800 pt-3' }, | |
| React.createElement('span', { className: 'text-violet-300 font-bold' }, 'Track F'), | |
| ' = coarsest forward-invariant (exact lumpable quotient) — uses only ', | |
| React.createElement('span', { className: 'text-white' }, 'sig_F(s)=block(T(s))'), | |
| '. ', | |
| React.createElement('span', { className: 'text-cyan-300 font-bold' }, 'Track B'), | |
| ' = coarsest bisimulation — uses ', | |
| React.createElement('span', { className: 'text-white' }, 'sig_B = (img, preCounts)'), | |
| ', refines F. Example ', | |
| React.createElement('span', { className: 'text-white' }, 'T=[2,2,2]'), | |
| ' shows strict refinement: Π*_F=single block D_F=0, Π*_B={{0,1},{2}}.', | |
| React.createElement('div', { className: 'mt-2 p-2 rounded bg-zinc-900 border border-zinc-800' }, | |
| React.createElement('span', { className: 'text-amber-300' }, 'D_F'), | |
| ' = (I-P)UP measures forward leakage, = sin(θ_max) principal angle between V and U(V) — Shah & Cortés 2026' | |
| ) | |
| ) | |
| ) | |
| ), | |
| // Footer | |
| React.createElement('footer', { key: 'footer', className: 'max-w-[1600px] mx-auto px-6 py-8 mono text-[11px] text-zinc-500 border-t border-zinc-900 mt-6 flex flex-col md:flex-row gap-3 justify-between' }, | |
| React.createElement('div', null, | |
| 'Proof: AQARION_v20.6_FINAL_PROOF.md • D_F=(I-P)UP • Theorem: D=0 ⇔ forward-invariant ⇔ sig_F constant' | |
| ), | |
| React.createElement('div', { className: 'flex gap-3' }, | |
| React.createElement('span', { className: 'text-zinc-300' }, '50,021 graphs verified n=1..5 exhaustive'), | |
| React.createElement('span', null, '•'), | |
| React.createElement('span', { className: 'text-violet-300' }, 'Contribute your graph — export certificate') | |
| ) | |
| ) | |
| ]); | |
| } | |
| // ---- render ---- | |
| ReactDOM.createRoot(document.getElementById('root')).render( | |
| React.createElement(React.StrictMode, null, React.createElement(App)) | |
| ); | |
| `; | |
| // Run Babel to transform JSX | |
| const transformed = Babel.transform(jsxCode, { presets: ['react'] }).code; | |
| // Execute the transformed code in the module context | |
| eval(transformed); | |
| </script> | |
| </body> | |
| </html> |