<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Single Variable Algebra Playground</title>
<style>
body, input, button, textarea, select { background-color: #002; color: white; }
input:focus, textarea:focus { outline: none; }
#sva { background-color: #134; min-height: 42vh; }
#log, #output { background-color: #333; }
a { color: #0ff; text-decoration: none; }
a:hover { text-decoration: underline; }
input[type="text"],
textarea { min-width: 100%; max-width: 100%; font-style: Consolas; }
</style>
</head>
<body>
<h2>Single Variable Algebra Playground <button id="loadWasmBtn">RUN ▶</button>
<select aria-label="SVA code examples" onchange="updateTextarea(this.value)">
<option value="beaver">4-state Busy Beaver</option>
<option value="floor">floor function</option>
<option value="replace">Replace 1 with 7</option>
</select>
</h2>
<p><input type="checkbox" id="checkbox" onclick="checkbox()"> Translate a 10-symbol space-bounded Turing machine to SVA. Syntax: <a href="https://wiki.bbchallenge.org/wiki/Turing_machine#Standard_text_format">TM standard text format</a>.</p>
<div id="tm_area">
Tape length: <input id="bandLength" onchange="translate_tm_to_sva()" min="15" max="450" step="1" type="number" value="50"></p>
<input type="text" id="tm" onchange="translate_tm_to_sva()" value="1RB1LB_1LA0LC_1RZ1LD_1RD0RA">
</div>
<p><textarea id="sva" style="overflow-wrap: normal; overflow-x: scroll; white-space: pre">decimals(x) = 50
abs(x) = (x^2)^(1/2)
H(x) = (x+abs(x))/(2*x)
tiny(x) = 10^(-decimals(x))
ge0(x) = H(x+tiny(x)/10)
lt1(x) = 1-ge0(x-1)
is0(x) = ge0(x)*lt1(x)
is1(x) = is0(x-1)
is2(x) = is0(x-2)
is3(x) = is0(x-3)
is4(x) = is0(x-4)
is5(x) = is0(x-5)
is6(x) = is0(x-6)
is7(x) = is0(x-7)
is8(x) = is0(x-8)
is9(x) = is0(x-9)
floor1(x) = is1(x)+2*is2(x)+3*is3(x)+4*is4(x)+5*is5(x)+6*is6(x)+7*is7(x)+8*is8(x)+9*is9(x)
right(x) = x*10-floor1(x*10)+floor1(x*10)*tiny(x)
left(x) = right^[49](x)
tm(x) = is0(x)*x+is1(x)*(is0(10*(x-1))*(2+right(x-1+0.1))+is1(10*(x-1))*(2+left(x-1-0.1+0.1)))+is2(x)*(is0(10*(x-2))*(1+left(x-2+0.1))+is1(10*(x-2))*(3+left(x-2-0.1+0.0)))+is3(x)*(is0(10*(x-3))*(0+right(x-3+0.1))+is1(10*(x-3))*(4+left(x-3-0.1+0.1)))+is4(x)*(is0(10*(x-4))*(4+right(x-4+0.1))+is1(10*(x-4))*(1+right(x-4-0.1+0.0)))
f(x) = tm^[10000](x)
f(1)</textarea><br>
<input id="log" type="text" disabled><br><textarea id="output" disabled></textarea></p>
<ul>
<li>For convenience, f(x) = g(g(g(x))) equals f(x) = g^[3](x)</li>
<li><a href="https://github.com/772/single-variable-algebra-compiler">Git Repository</a></li>
</ul>
<script>
function updateTextarea(selectedValue) {
const textarea = document.getElementById("sva");
switch(selectedValue) {
case 'beaver':
textarea.value = `decimals(x) = 50
abs(x) = (x^2)^(1/2)
H(x) = (x+abs(x))/(2*x)
tiny(x) = 10^(-decimals(x))
ge0(x) = H(x+tiny(x)/10)
lt1(x) = 1-ge0(x-1)
is0(x) = ge0(x)*lt1(x)
is1(x) = is0(x-1)
is2(x) = is0(x-2)
is3(x) = is0(x-3)
is4(x) = is0(x-4)
is5(x) = is0(x-5)
is6(x) = is0(x-6)
is7(x) = is0(x-7)
is8(x) = is0(x-8)
is9(x) = is0(x-9)
floor1(x) = is1(x)+2*is2(x)+3*is3(x)+4*is4(x)+5*is5(x)+6*is6(x)+7*is7(x)+8*is8(x)+9*is9(x)
right(x) = x*10-floor1(x*10)+floor1(x*10)*tiny(x)
left(x) = right^[49](x)
tm(x) = is0(x)*x+is1(x)*(is0(10*(x-1))*(2+right(x-1+0.1))+is1(10*(x-1))*(2+left(x-1-0.1+0.1)))+is2(x)*(is0(10*(x-2))*(1+left(x-2+0.1))+is1(10*(x-2))*(3+left(x-2-0.1+0.0)))+is3(x)*(is0(10*(x-3))*(0+right(x-3+0.1))+is1(10*(x-3))*(4+left(x-3-0.1+0.1)))+is4(x)*(is0(10*(x-4))*(4+right(x-4+0.1))+is1(10*(x-4))*(1+right(x-4-0.1+0.0)))
f(x) = tm^[10000](x)
f(1)
`;
break;
case 'floor':
textarea.value = `decimals(x) = 50
abs(x) = (x^2)^(1/2)
H(x) = (x+abs(x))/(2*x)
tiny(x) = 10^(-decimals(x))
ge0(x) = H(x+tiny(x)/10)
lt1(x) = 1-ge0(x-1)
is0(x) = ge0(x)*lt1(x)
is1(x) = is0(x-1)
is2(x) = is0(x-2)
is3(x) = is0(x-3)
is4(x) = is0(x-4)
is5(x) = is0(x-5)
is6(x) = is0(x-6)
is7(x) = is0(x-7)
is8(x) = is0(x-8)
is9(x) = is0(x-9)
floor1(x) = is1(x)+2*is2(x)+3*is3(x)+4*is4(x)+5*is5(x)+6*is6(x)+7*is7(x)+8*is8(x)+9*is9(x)
floor2(x) = floor1(x/10)*10+floor1(x-floor1(x/10)*10)
floor4(x) = floor2(x/10^2)*10^2+floor2(x-floor2(x/10^2)*10^2)
floor8(x) = floor4(x/10^4)*10^4+floor4(x-floor4(x/10^4)*10^4)
floor16(x) = floor8(x/10^8)*10^8+floor8(x-floor8(x/10^8)*10^8)
floor16(1156772000123456.1772731827367126472727728)
`;
break;
case 'replace':
textarea.value = `decimals(x) = 50
abs(x) = (x^2)^(1/2)
H(x) = (x+abs(x))/(2*x)
tiny(x) = 10^(-decimals(x))
ge0(x) = H(x+tiny(x)/10)
lt1(x) = 1-ge0(x-1)
is0(x) = ge0(x)*lt1(x)
is1(x) = is0(x-1)
is2(x) = is0(x-2)
is3(x) = is0(x-3)
is4(x) = is0(x-4)
is5(x) = is0(x-5)
is6(x) = is0(x-6)
is7(x) = is0(x-7)
is8(x) = is0(x-8)
is9(x) = is0(x-9)
floor1(x) = is1(x)+2*is2(x)+3*is3(x)+4*is4(x)+5*is5(x)+6*is6(x)+7*is7(x)+8*is8(x)+9*is9(x)
right(x) = x*10-floor1(x*10)+floor1(x*10)*tiny(x)
left(x) = right^[49](x)
replace_1_by_7(x) = right(x+is1(x*10)*0.6)
f(x) = replace_1_by_7^[50](x)
f(0.2821011111110111236333746311231819159841234293491)
`;
break;
default:
textarea.value = '';
}
document.getElementById("log").value = "Loaded example '" + selectedValue + "'.";
document.getElementById("output").value = "";
}
function turing_machine_translate(currentState, write, action, newstate, i) {
return "+is" + i + "(10*(x-" + currentState + "))*(" + newstate + "+" + action + "(x-" + currentState + "-0." + i + "+0." + write + "))"
}
function translate_tm_to_sva() {
let tmString = document.getElementById("tm").value;
let amount_of_states = (tmString.match(/_/g) || []).length + 1;
let firstSegment = tmString.split('_')[0];
let amount_of_symbols = firstSegment ? firstSegment.length / 3 : 0;
if (amount_of_states * amount_of_symbols * 3 + amount_of_states - 1 != tmString.length) {
document.getElementById("log").value = "Turing machine syntax error.";
return;
}
if (amount_of_symbols > 10) {
document.getElementById("log").value = "Turing machine has more than 10 symbols.";
return;
}
if (amount_of_states < 2) {
document.getElementById("log").value = "Turing machine has no states.";
return;
}
let algebra = `decimals(x) = ` + Number(document.getElementById("bandLength").value) + `\n` + `abs(x) = (x^2)^(1/2)
H(x) = (x+abs(x))/(2*x)
tiny(x) = 10^(-decimals(x))
ge0(x) = H(x+tiny(x)/10)
lt1(x) = 1-ge0(x-1)
is0(x) = ge0(x)*lt1(x)
is1(x) = is0(x-1)
is2(x) = is0(x-2)
is3(x) = is0(x-3)
is4(x) = is0(x-4)
is5(x) = is0(x-5)
is6(x) = is0(x-6)
is7(x) = is0(x-7)
is8(x) = is0(x-8)
is9(x) = is0(x-9)
floor1(x) = is1(x)+2*is2(x)+3*is3(x)+4*is4(x)+5*is5(x)+6*is6(x)+7*is7(x)+8*is8(x)+9*is9(x)
right(x) = x*10-floor1(x*10)+floor1(x*10)*tiny(x)
left(x) = right^[` + (Number(document.getElementById("bandLength").value) - 1) + `](x)
tm(x) = is0(x)*x`;
const blocks = tmString.split("_");
blocks.forEach((block, index) => {
const currentState = index + 1;
algebra += "+is" + currentState + "(x)*(";
for (let i = 0; i < amount_of_symbols; i++) {
const trans0 = block.substring(i*3, i*3+3);
console.log("transe " + trans0);
const write = parseInt(trans0[0]);
const action = trans0[1] == "L" ? "left" : "right";
let newstate_temp = trans0[2].charCodeAt(0) - 64;
const newstate = newstate_temp == 26 ? 0 : newstate_temp;
algebra += turing_machine_translate(currentState, write, action, newstate, i);
}
algebra += ")";
});
document.getElementById("sva").value = algebra + "\n" + `f(x) = tm^[10000](x)\n` + `f(1)`;
document.getElementById("log").value = "Translated Turing machine to SVA. Found " + amount_of_states + " states using " + amount_of_symbols + " symbols.";
}
function checkbox() {
let checked = document.getElementById("checkbox").checked;
document.getElementById("tm_area").style.display = "none";
if (checked) {
document.getElementById("tm_area").style.display = "block";
translate_tm_to_sva();
}
}
window.addEventListener("DOMContentLoaded", (event) => {
const textarea1 = document.getElementById("tm");
const textarea2 = document.getElementById("bandLength");
const textarea3 = document.getElementById("sva");
const textarea4 = document.getElementById("output");
const savedValue1 = sessionStorage.getItem("sessionStorage1");
const savedValue2 = sessionStorage.getItem("sessionStorage2");
const savedValue3 = sessionStorage.getItem("sessionStorage3");
const savedValue4 = sessionStorage.getItem("sessionStorage4");
if(savedValue1) {
textarea1.value = savedValue1;
}
if(savedValue2) {
textarea2.value = savedValue2;
}
if(savedValue3) {
textarea3.value = savedValue3;
}
if(savedValue4) {
textarea4.value = savedValue4;
}
textarea1.addEventListener("input", function() {
sessionStorage.setItem("sessionStorage1", textarea1.value);
});
textarea2.addEventListener("input", function() {
sessionStorage.setItem("sessionStorage2", textarea2.value);
});
textarea3.addEventListener("input", function() {
sessionStorage.setItem("sessionStorage3", textarea3.value);
});
textarea4.addEventListener("input", function() {
sessionStorage.setItem("sessionStorage4", textarea4.value);
});
});
checkbox();
window.addEventListener("beforeunload", function() {
sessionStorage.setItem("sessionStorage1", document.getElementById("tm").value);
sessionStorage.setItem("sessionStorage2", document.getElementById("bandLength").value);
sessionStorage.setItem("sessionStorage3", document.getElementById("sva").value);
sessionStorage.setItem("sessionStorage4", document.getElementById("output").value);
});
</script>
<script type="module">
let wasmInitialized = false;
document.getElementById('loadWasmBtn').addEventListener('click', async () => {
if (wasmInitialized) {
console.log('WASM bereits geladen');
return;
}
try {
const { default: init } = await import('./wasm.js');
await init();
wasmInitialized = true;
console.log('WASM erfolgreich geladen');
location.reload();
} catch (error) {
if (!error.message.startsWith(
"Using exceptions for control flow, don't mind me. This isn't actually an error!"
)) {
console.error('Fehler beim Laden des WASM-Moduls:', error);
throw error;
}
}
});
</script>
</body>
</html>