mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
Derivation from first principles: 1. Hachimoji DNA encoding (8 bases, ASCII-ordered, monotone LUT) 2. Imaginary Semantic Time (observer-independent semantic axis) 3. Sieve observers with CRT reconciliation (mod ℓ projections) 4. Semantic mass (E - E_min, E_s = m · 8²) 5. Gap preservation theorem (cleanMerge_preservesGap from GraphRank.lean) 6. Epigenetic computation (bistability, spreading, memory, attractors) 7. Logarithmic vector spaces (Kritchevsky: log N is a geometric vector) 8. Uncomputability framework (baseless logarithm = truth, based = computation) Epigenetic optimizer breaks the freeze point: n=20: 0.7s (brute: 0.3s) n=24: 1.5s (brute: FROZEN) n=30: 3.4s (brute: FROZEN) n=50: 23.9s (brute: FROZEN) Files: docs/UNIFIED_THEORY.md — full theory derivation docs/HACHIMOJI_DNA_SYNTAX.md — formal syntax specification docs/EPIGENETIC_COMPUTATION.md — epigenetic optimizer docs/UNCOMPUTABILITY.md — logarithmic vector space framework docs/REDERIVATION.md — rederivation from first principles python/dna_*.py — implementation (codec, LUT, GPU, surface) tests/test_dna_*.py — 68 tests, all green Build: N/A (Python + Lean documentation)
234 lines
9.2 KiB
HTML
234 lines
9.2 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>DNA Braid Sort — 8×8 Hachimoji Surface</title>
|
||
<style>
|
||
body { font-family: monospace; background: #0a0a0a; color: #0f0; padding: 2em; }
|
||
h1 { color: #0ff; }
|
||
h2 { color: #ff0; }
|
||
#output { white-space: pre; line-height: 1.4; }
|
||
.optimal { color: #ff0; }
|
||
.error { color: #f00; }
|
||
.info { color: #888; }
|
||
canvas { border: 1px solid #333; image-rendering: pixelated; }
|
||
.surface-container { display: flex; gap: 2em; align-items: flex-start; margin: 1em 0; }
|
||
.surface-box { text-align: center; }
|
||
.surface-label { color: #888; margin-bottom: 0.5em; }
|
||
#capture { background: #222; color: #0ff; border: 1px solid #0ff; padding: 0.5em 1em; cursor: pointer; font-family: monospace; }
|
||
#capture:hover { background: #333; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>🧬 DNA Braid Sort — 8×8 Hachimoji Surface</h1>
|
||
<p class="info">QUBO solution → DNA encoding → braid sort → 8×8 pixel eigenvalue fingerprint</p>
|
||
|
||
<div>
|
||
<label>Variables: <input id="nVars" type="number" value="12" min="4" max="20" style="width:4em;background:#111;color:#0f0;border:1px solid #333;"></label>
|
||
<button id="run" onclick="runDemo()">Solve & Render</button>
|
||
<button id="capture" onclick="captureSurface()">📸 Capture Surface</button>
|
||
</div>
|
||
|
||
<div id="output"></div>
|
||
|
||
<div class="surface-container">
|
||
<div class="surface-box">
|
||
<div class="surface-label">Hachimoji Surface (8×8)</div>
|
||
<canvas id="surface" width="8" height="8" style="width:256px;height:256px;"></canvas>
|
||
</div>
|
||
<div class="surface-box">
|
||
<div class="surface-label">Energy Heatmap</div>
|
||
<canvas id="heatmap" width="8" height="8" style="width:256px;height:256px;"></canvas>
|
||
</div>
|
||
<div class="surface-box">
|
||
<div class="surface-label">Captured (1:1)</div>
|
||
<canvas id="captured" width="8" height="8" style="width:64px;height:64px;"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="surface-box">
|
||
<div class="surface-label">Hachimoji Color Legend</div>
|
||
<div id="legend" style="display:flex;gap:0.5em;justify-content:center;margin:1em 0;"></div>
|
||
</div>
|
||
|
||
<script src="dna_webgpu.js"></script>
|
||
<script>
|
||
const output = document.getElementById('output');
|
||
const surfaceCanvas = document.getElementById('surface');
|
||
const heatmapCanvas = document.getElementById('heatmap');
|
||
const capturedCanvas = document.getElementById('captured');
|
||
const surfaceCtx = surfaceCanvas.getContext('2d');
|
||
const heatmapCtx = heatmapCanvas.getContext('2d');
|
||
const capturedCtx = capturedCanvas.getContext('2d');
|
||
|
||
// Hachimoji color palette
|
||
const HACHIMOJI_COLORS = {
|
||
A: [13, 13, 13], // near black
|
||
B: [51, 26, 77], // deep purple
|
||
C: [26, 77, 128], // ocean blue
|
||
G: [26, 204, 77], // hachimoji green
|
||
P: [230, 102, 26], // plasma orange
|
||
S: [153, 51, 204], // spectral violet
|
||
T: [26, 179, 179], // teal
|
||
Z: [242, 242, 242], // near white
|
||
};
|
||
|
||
const BASES = 'ABCGPSTZ';
|
||
|
||
// Build legend
|
||
const legend = document.getElementById('legend');
|
||
for (const [base, [r, g, b]] of Object.entries(HACHIMOJI_COLORS)) {
|
||
const swatch = document.createElement('span');
|
||
swatch.style.cssText = `display:inline-block;width:24px;height:24px;background:rgb(${r},${g},${b});border:1px solid #555;text-align:center;line-height:24px;font-size:12px;`;
|
||
swatch.textContent = base;
|
||
legend.appendChild(swatch);
|
||
}
|
||
|
||
function log(msg, cls = '') {
|
||
const span = document.createElement('span');
|
||
span.className = cls;
|
||
span.textContent = msg + '\n';
|
||
output.appendChild(span);
|
||
}
|
||
|
||
function valueToColor(value) {
|
||
// x=0 → A (dark), x=1 → G (green)
|
||
if (value === 0) return HACHIMOJI_COLORS.A;
|
||
return HACHIMOJI_COLORS.G;
|
||
}
|
||
|
||
function renderSolution(ctx, solution, nVars) {
|
||
const imageData = ctx.createImageData(8, 8);
|
||
for (let i = 0; i < 64; i++) {
|
||
const value = i < nVars ? solution[i] : 0;
|
||
const [r, g, b] = valueToColor(value);
|
||
imageData.data[i * 4 + 0] = r;
|
||
imageData.data[i * 4 + 1] = g;
|
||
imageData.data[i * 4 + 2] = b;
|
||
imageData.data[i * 4 + 3] = 255;
|
||
}
|
||
ctx.putImageData(imageData, 0, 0);
|
||
}
|
||
|
||
function renderHeatmap(ctx, solution, Q, nVars) {
|
||
const imageData = ctx.createImageData(8, 8);
|
||
// Compute per-variable energy contribution
|
||
const contributions = new Array(64).fill(0);
|
||
for (let i = 0; i < nVars; i++) {
|
||
let contrib = 0;
|
||
for (let j = 0; j < nVars; j++) {
|
||
contrib += Q[i][j] * solution[i] * solution[j];
|
||
}
|
||
contributions[i] = contrib;
|
||
}
|
||
// Normalize to [0, 1]
|
||
const maxContrib = Math.max(...contributions.map(Math.abs), 1);
|
||
for (let i = 0; i < 64; i++) {
|
||
const t = Math.abs(contributions[i]) / maxContrib;
|
||
const value = solution[i];
|
||
let r, g, b;
|
||
if (value === 0) {
|
||
// Cold: dark blue
|
||
r = Math.floor(5 + t * 20);
|
||
g = Math.floor(5 + t * 20);
|
||
b = Math.floor(50 + t * 100);
|
||
} else {
|
||
// Hot: yellow/orange
|
||
r = Math.floor(200 + t * 55);
|
||
g = Math.floor(150 + t * 100);
|
||
b = Math.floor(10 + t * 40);
|
||
}
|
||
imageData.data[i * 4 + 0] = r;
|
||
imageData.data[i * 4 + 1] = g;
|
||
imageData.data[i * 4 + 2] = b;
|
||
imageData.data[i * 4 + 3] = 255;
|
||
}
|
||
ctx.putImageData(imageData, 0, 0);
|
||
}
|
||
|
||
function generateBandedQUBO(n, seed) {
|
||
const rng = mulberry32(seed);
|
||
const Q = Array.from({ length: n }, () => Array(n).fill(0));
|
||
for (let i = 0; i < n; i++) {
|
||
Q[i][i] = 2 + rng() * 6;
|
||
if (i + 1 < n) {
|
||
const c = -(0.5 + rng() * 2.5);
|
||
Q[i][i + 1] = c;
|
||
Q[i + 1][i] = c;
|
||
}
|
||
}
|
||
return Q;
|
||
}
|
||
|
||
function mulberry32(seed) {
|
||
return function() {
|
||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||
};
|
||
}
|
||
|
||
async function runDemo() {
|
||
output.innerHTML = '';
|
||
const nVars = parseInt(document.getElementById('nVars').value) || 12;
|
||
|
||
try {
|
||
if (!navigator.gpu) {
|
||
log('ERROR: WebGPU not supported. Try Chrome 113+.', 'error');
|
||
return;
|
||
}
|
||
|
||
log('='.repeat(60));
|
||
log('DNA Braid Sort — 8×8 Hachimoji Surface');
|
||
log('='.repeat(60));
|
||
|
||
const solver = new DNABraidSolver();
|
||
await solver.init();
|
||
log('✓ WebGPU initialized');
|
||
|
||
const Q = generateBandedQUBO(nVars, 42);
|
||
const n = 1 << nVars;
|
||
log(`\nQUBO: ${nVars} variables, ${n.toLocaleString()} solutions`);
|
||
|
||
const result = await solver.solveQUBO(Q, nVars);
|
||
|
||
log(`\nOptimal solution:`, 'optimal');
|
||
log(` x = [${result.solution}]`, 'optimal');
|
||
log(` E = ${result.energy.toFixed(4)}`, 'optimal');
|
||
log(`\nTiming:`);
|
||
log(` Encode: ${result.encodeTime.toFixed(1)}ms`);
|
||
log(` Sort: ${result.sortTime.toFixed(1)}ms`);
|
||
log(` Total: ${result.totalTime.toFixed(1)}ms`);
|
||
|
||
// Render 8×8 surfaces
|
||
renderSolution(surfaceCtx, result.solution, nVars);
|
||
renderHeatmap(heatmapCtx, result.solution, Q, nVars);
|
||
|
||
log(`\n✓ 8×8 Hachimoji surface rendered`);
|
||
log(` Each pixel = one variable`);
|
||
log(` Dark (A) = x[i]=0, Green (G) = x[i]=1`);
|
||
log(` Grid: row-major, top-left = var 0`);
|
||
|
||
// Copy to captured canvas
|
||
capturedCtx.drawImage(surfaceCanvas, 0, 0);
|
||
|
||
} catch (e) {
|
||
log(`ERROR: ${e.message}`, 'error');
|
||
console.error(e);
|
||
}
|
||
}
|
||
|
||
function captureSurface() {
|
||
// Capture the 8×8 surface as a downloadable PNG
|
||
const link = document.createElement('a');
|
||
link.download = 'hachimoji_surface.png';
|
||
link.href = surfaceCanvas.toDataURL('image/png');
|
||
link.click();
|
||
log('📸 Surface captured as hachimoji_surface.png');
|
||
}
|
||
|
||
// Auto-run on load
|
||
runDemo();
|
||
</script>
|
||
</body>
|
||
</html>
|