| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> |
| <title>Substrate Math Translation Simulator v0.1</title> |
| <style> |
| :root{ |
| --bg:#07090d;--panel:#0f1420;--panel2:#121a2a;--ink:#eef5ff;--muted:#a9b6cc;--line:#263347; |
| --green:#49d17c;--yellow:#ffd166;--orange:#ff9f43;--red:#ff5c7a;--blue:#65b8ff;--violet:#a78bfa;--cyan:#58e6d9; |
| --shadow:0 18px 60px rgba(0,0,0,.35); |
| } |
| *{box-sizing:border-box} |
| body{ |
| margin:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--ink); |
| background: |
| radial-gradient(circle at 10% 10%,rgba(101,184,255,.16),transparent 28%), |
| radial-gradient(circle at 86% 12%,rgba(167,139,250,.14),transparent 30%), |
| radial-gradient(circle at 50% 105%,rgba(88,230,217,.08),transparent 42%), |
| var(--bg); |
| } |
| header{ |
| padding:28px 24px 18px;border-bottom:1px solid var(--line); |
| background:linear-gradient(180deg,rgba(18,26,42,.94),rgba(7,9,13,.72)); |
| position:sticky;top:0;z-index:20;backdrop-filter:blur(12px); |
| } |
| .wrap{max-width:1480px;margin:0 auto} |
| h1{margin:0 0 6px;font-size:clamp(24px,3vw,42px);letter-spacing:-.04em} |
| .subtitle{color:var(--muted);font-size:15px;line-height:1.45;max-width:1120px} |
| .tagrow{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px} |
| .tag{border:1px solid var(--line);background:rgba(255,255,255,.04);color:#dbeafe;padding:6px 9px;border-radius:999px;font-size:12px} |
| main{padding:22px 24px 34px} |
| .grid{display:grid;grid-template-columns:390px minmax(0,1fr) 420px;gap:18px;align-items:start} |
| .panel{ |
| background:linear-gradient(180deg,rgba(18,26,42,.96),rgba(15,20,32,.96)); |
| border:1px solid var(--line);border-radius:20px;box-shadow:var(--shadow);overflow:hidden; |
| } |
| .panel h2{margin:0;padding:16px 18px;border-bottom:1px solid var(--line);font-size:16px;letter-spacing:-.02em} |
| .body{padding:16px 18px} |
| label{display:block;font-size:12px;color:var(--muted);margin-bottom:8px} |
| select,button,textarea,input[type=text]{ |
| width:100%;border:1px solid var(--line);background:#0a0f19;color:var(--ink);border-radius:12px;padding:11px 12px;font-size:14px;outline:none; |
| } |
| textarea{min-height:105px;resize:vertical;line-height:1.4} |
| button{cursor:pointer;transition:.18s ease transform,.18s ease border-color,.18s ease background;font-weight:800} |
| button:hover{transform:translateY(-1px);border-color:#46658f;background:#0c1422} |
| button.primary{background:linear-gradient(135deg,#1f6feb,#5b8cff);border-color:#65b8ff} |
| button.good{background:linear-gradient(135deg,#116e43,#24a861);border-color:#49d17c} |
| button.warn{background:linear-gradient(135deg,#865b0b,#b98200);border-color:#ffd166} |
| .controls{display:grid;gap:14px} |
| .sliderRow{border:1px solid var(--line);border-radius:16px;padding:12px;background:rgba(255,255,255,.03)} |
| .sliderTop{display:flex;justify-content:space-between;gap:8px;align-items:center;margin-bottom:8px} |
| .sliderTop strong{font-size:13px} |
| .val{font-variant-numeric:tabular-nums;color:#dbeafe;font-size:12px} |
| input[type=range]{width:100%;accent-color:#65b8ff} |
| .hint{font-size:12px;color:var(--muted);line-height:1.35;margin-top:6px} |
| .buttons{display:grid;grid-template-columns:1fr 1fr;gap:10px} |
| .metricGrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px} |
| .metric{background:rgba(255,255,255,.035);border:1px solid var(--line);border-radius:18px;padding:14px;min-height:104px} |
| .metric .name{font-size:12px;color:var(--muted)} |
| .metric .num{font-size:22px;font-weight:900;margin:4px 0;letter-spacing:-.03em;line-height:1.05} |
| .metric .desc{font-size:12px;color:var(--muted);line-height:1.35} |
| .output{display:grid;gap:14px} |
| .card{border:1px solid var(--line);border-radius:18px;background:rgba(255,255,255,.035);padding:14px} |
| .card h3{margin:0 0 8px;font-size:15px} |
| .card p{margin:0 0 10px;color:#dce8f7;line-height:1.48} |
| .card ul{margin:8px 0 0 20px;color:#dce8f7;line-height:1.45;padding:0} |
| .card li{margin:4px 0} |
| .small{font-size:12px;color:var(--muted);line-height:1.35} |
| .eq{ |
| font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;background:#080d15;border:1px solid var(--line);border-radius:18px; |
| padding:14px;color:#d8f3ff;margin-bottom:18px;line-height:1.55;overflow:auto; |
| } |
| .blue{color:var(--blue)}.green{color:var(--green)}.yellow{color:var(--yellow)}.orange{color:var(--orange)}.red{color:var(--red)}.violet{color:var(--violet)}.cyan{color:var(--cyan)} |
| #mathCanvas{width:100%;height:180px;border:1px solid var(--line);border-radius:16px;background:#0a0f19;display:block} |
| .log{max-height:560px;overflow:auto;display:flex;flex-direction:column;gap:9px;padding-right:4px} |
| .logItem{border:1px solid var(--line);border-radius:14px;padding:10px 11px;background:rgba(255,255,255,.035)} |
| .logItem .time{font-size:11px;color:#8190a8;margin-bottom:5px} |
| .logItem .msg{font-size:12px;line-height:1.35;color:#dce8f7} |
| .footerNote{margin:18px auto 0;color:var(--muted);line-height:1.45;font-size:13px;border:1px solid var(--line);background:rgba(255,255,255,.03);border-radius:18px;padding:14px} |
| .descBox{font-size:12px;color:var(--muted);line-height:1.35;border:1px solid var(--line);border-radius:14px;padding:10px;background:rgba(255,255,255,.03);min-height:54px;margin-top:8px} |
| .previewBox{border:1px solid var(--line);border-radius:16px;padding:12px;background:rgba(255,255,255,.03)} |
| hr{border:0;border-top:1px solid var(--line);margin:10px 0} |
| @media(max-width:1240px){.grid{grid-template-columns:1fr}header{position:static}.metricGrid{grid-template-columns:repeat(2,1fr)}} |
| @media(max-width:760px){.metricGrid{grid-template-columns:1fr}.buttons{grid-template-columns:1fr}} |
| </style> |
| </head> |
| <body> |
| <header> |
| <div class="wrap"> |
| <h1>Substrate Math Translation Simulator <span class="blue">v0.1</span></h1> |
| <div class="subtitle"> |
| A non-diagnostic learning translator that explains math concepts through different cognition styles. |
| Select a math topic, choose an explanation route, tune support preferences, and generate a dignity-preserving explanation. |
| <br><strong>Math stays math. The route changes so the learner can meet the structure.</strong> |
| </div> |
| <div class="tagrow"> |
| <span class="tag">Math translation, not replacement</span> |
| <span class="tag">Cognition-aware learning</span> |
| <span class="tag">No diagnosis</span> |
| <span class="tag">No forced closure</span> |
| <span class="tag">Substrate education layer</span> |
| </div> |
| </div> |
| </header> |
|
|
| <main> |
| <div class="wrap grid"> |
| <section class="panel"> |
| <h2>Learning Input</h2> |
| <div class="body controls"> |
| <div> |
| <label for="topic">Math topic</label> |
| <select id="topic"></select> |
| <div id="topicDesc" class="descBox"></div> |
| </div> |
|
|
| <div> |
| <label for="mode">Cognition / explanation mode</label> |
| <select id="mode"></select> |
| <div id="modeDesc" class="descBox"></div> |
| </div> |
|
|
| <div> |
| <label for="selfDesc">Optional learner note</label> |
| <textarea id="selfDesc" placeholder="Example: I need visual structure before symbols. I understand math through real examples. I need proof boundaries and misconception checks."></textarea> |
| <div class="hint">Self-described support only. This is not diagnosis or assessment.</div> |
| </div> |
|
|
| <div class="sliderRow"> |
| <div class="sliderTop"><strong>Abstraction Tolerance</strong><span class="val" id="vAbs"></span></div> |
| <input id="abstraction" type="range" min="0" max="1" step="0.01" value="0.50"> |
| <div class="hint">Lower = concrete first. Higher = structure/symbols first.</div> |
| </div> |
|
|
| <div class="sliderRow"> |
| <div class="sliderTop"><strong>Example Need</strong><span class="val" id="vEx"></span></div> |
| <input id="examples" type="range" min="0" max="1" step="0.01" value="0.78"> |
| <div class="hint">How much the explanation should lean on examples and worked cases.</div> |
| </div> |
|
|
| <div class="sliderRow"> |
| <div class="sliderTop"><strong>Symbol Density</strong><span class="val" id="vSym"></span></div> |
| <input id="symbols" type="range" min="0" max="1" step="0.01" value="0.46"> |
| <div class="hint">Controls how much equation/symbol language appears.</div> |
| </div> |
|
|
| <div class="sliderRow"> |
| <div class="sliderTop"><strong>Metaphor Density</strong><span class="val" id="vMet"></span></div> |
| <input id="metaphor" type="range" min="0" max="1" step="0.01" value="0.58"> |
| <div class="hint">Controls analogy, imagery, and story language.</div> |
| </div> |
|
|
| <div class="sliderRow"> |
| <div class="sliderTop"><strong>Pacing / Scaffold</strong><span class="val" id="vPace"></span></div> |
| <input id="pacing" type="range" min="0" max="1" step="0.01" value="0.74"> |
| <div class="hint">Higher = slower sequencing and more definitions.</div> |
| </div> |
|
|
| <div class="buttons"> |
| <button class="primary" id="generateBtn">Generate Math Translation</button> |
| <button id="randomBtn">Try Sample Learner</button> |
| </div> |
|
|
| <div class="buttons"> |
| <button class="good" id="exportJSON">Export JSON</button> |
| <button class="warn" id="copyBtn">Copy Output</button> |
| </div> |
| </div> |
| </section> |
|
|
| <section> |
| <div class="metricGrid"> |
| <div class="metric"> |
| <div class="name">Learning Accessibility</div> |
| <div class="num" id="accessScore">0.00</div> |
| <div class="desc">How well supports match the chosen cognition route.</div> |
| </div> |
| <div class="metric"> |
| <div class="name">Understanding Layer</div> |
| <div class="num" id="closureState">FIRST PASS</div> |
| <div class="desc">Whether the output targets intuition, working model, or formal layer.</div> |
| </div> |
| <div class="metric"> |
| <div class="name">Translation Route</div> |
| <div class="num" id="routeName">—</div> |
| <div class="desc">The cognitive route used for this explanation.</div> |
| </div> |
| </div> |
|
|
| <div class="eq"> |
| <div><strong>Math translation pressure form:</strong></div> |
| <div>S_learning,t = A_translation,t × B_math,t − P_mismatch,t</div> |
| <div><strong>Rule:</strong> preserve the mathematical structure, adapt the explanation route.</div> |
| <hr> |
| <div id="liveEq"></div> |
| <div id="formulaLine" style="margin-top:8px;color:#eef5ff"></div> |
| </div> |
|
|
| <div class="panel" style="margin-bottom:18px"> |
| <h2>Math Structure Field</h2> |
| <div class="body"> |
| <canvas id="mathCanvas" width="760" height="200"></canvas> |
| <div class="hint" style="text-align:center;margin-top:10px"> |
| Concept = structure · Symbols = compressed map · Translation = route into understanding. |
| </div> |
| </div> |
| </div> |
|
|
| <div class="panel"> |
| <h2>Generated Math Explanation</h2> |
| <div class="body output" id="output"></div> |
| </div> |
|
|
| <div class="footerNote"> |
| <strong>Boundary statement:</strong> This simulator is an educational translation prototype. It does not replace teachers, |
| textbooks, practice, formal proof, or mathematical rigor. It does not diagnose cognition or rank intelligence. |
| It adapts explanation format while preserving the math concept and its boundaries. |
| </div> |
| </section> |
|
|
| <aside class="panel"> |
| <h2>Learning Steward Log</h2> |
| <div class="body"> |
| <div class="previewBox" style="margin-bottom:12px"> |
| <div class="small"><strong>Steward function:</strong> preserve the concept, translate the route, mark misconceptions, and prevent confusion from being treated as failure.</div> |
| </div> |
| <div class="log" id="log"></div> |
| </div> |
| </aside> |
| </div> |
| </main> |
|
|
| <footer class="footerNote wrap"> |
| <strong>Substrate education principle:</strong> A learner should not be made to feel stupid because the explanation arrives in the wrong format. |
| The format should adapt while the mathematical structure remains honest. |
| </footer> |
|
|
| <script> |
| const modes = { |
| visual_map:{label:"Visual / map-based",route:"VISUAL_MAP",desc:"Prefers diagrams, number lines, shapes, graphs, arrows, and spatial relationships.",bias:{abstraction:.55,examples:.72,symbols:.36,metaphor:.70,pacing:.64}}, |
| concrete_examples:{label:"Concrete examples first",route:"CONCRETE_EXAMPLES",desc:"Prefers worked examples and ordinary-life situations before symbols.",bias:{abstraction:.26,examples:.95,symbols:.25,metaphor:.50,pacing:.82}}, |
| technical_symbolic:{label:"Technical / symbolic",route:"TECHNICAL_SYMBOLIC",desc:"Prefers notation, definitions, formulas, transformations, and formal relationships.",bias:{abstraction:.88,examples:.44,symbols:.94,metaphor:.18,pacing:.46}}, |
| story_metaphor:{label:"Story / metaphor",route:"STORY_METAPHOR",desc:"Prefers analogies, image-rich explanations, and narrative movement.",bias:{abstraction:.46,examples:.70,symbols:.22,metaphor:.94,pacing:.70}}, |
| stepwise_literal:{label:"Stepwise / literal",route:"STEPWISE_LITERAL",desc:"Prefers definitions, slow sequencing, one operation at a time, and low ambiguity.",bias:{abstraction:.32,examples:.84,symbols:.46,metaphor:.16,pacing:.96}}, |
| fast_associative:{label:"Fast associative / pattern-jump",route:"FAST_ASSOCIATIVE",desc:"Prefers pattern links across topics and seeing the full structure quickly.",bias:{abstraction:.78,examples:.60,symbols:.58,metaphor:.82,pacing:.28}}, |
| skeptical_redteam:{label:"Skeptical / red-team",route:"SKEPTICAL_REDTEAM",desc:"Prefers assumptions, edge cases, invalid moves, proof boundaries, and misconception checks.",bias:{abstraction:.66,examples:.64,symbols:.64,metaphor:.20,pacing:.60}}, |
| lived_context:{label:"Lived-context / practical stakes",route:"LIVED_CONTEXT",desc:"Prefers practical use, money/time/measurement examples, agency, and why the concept matters.",bias:{abstraction:.40,examples:.90,symbols:.30,metaphor:.68,pacing:.80}}, |
| teacher_scaffold:{label:"Teacher / scaffolded lesson",route:"TEACHER_SCAFFOLD",desc:"Prefers learning objective, definitions, examples, guided practice, and takeaway.",bias:{abstraction:.48,examples:.86,symbols:.48,metaphor:.42,pacing:.90}} |
| }; |
| |
| const topics = { |
| arithmetic:{ |
| label:"Arithmetic operations", |
| desc:"How addition, subtraction, multiplication, and division transform quantities.", |
| formula:"a + b, a − b, a × b, a ÷ b", |
| plain:"Arithmetic is the basic language of changing and comparing quantities.", |
| example:"If you have 3 groups of 4 apples, multiplication says 3 × 4 = 12 apples.", |
| misconception:"Multiplication is not always just 'making bigger' once negative numbers, fractions, and scaling enter." |
| }, |
| fractions:{ |
| label:"Fractions and ratios", |
| desc:"How parts, wholes, and comparisons are represented.", |
| formula:"a/b ; ratio a:b ; proportion a/b = c/d", |
| plain:"A fraction compares a part to a whole, and a ratio compares quantities to each other.", |
| example:"If 3 out of 8 slices are eaten, 3/8 of the pizza is gone.", |
| misconception:"A larger denominator does not always mean a larger value. 1/8 is smaller than 1/4." |
| }, |
| algebra:{ |
| label:"Algebra", |
| desc:"How symbols represent unknowns, relationships, and reusable patterns.", |
| formula:"ax + b = c", |
| plain:"Algebra uses symbols to hold places for numbers so relationships can be solved or reused.", |
| example:"If x + 3 = 10, then x = 7 because 7 plus 3 gives 10.", |
| misconception:"The letter is not the math. The letter is a placeholder for a value or variable relationship." |
| }, |
| functions:{ |
| label:"Functions", |
| desc:"How inputs map to outputs according to a rule.", |
| formula:"f(x) = y", |
| plain:"A function is a rule that takes an input and produces an output.", |
| example:"If f(x)=2x+1, then f(3)=7 because 2×3+1=7.", |
| misconception:"A function is not just an equation; it is a mapping rule from inputs to outputs." |
| }, |
| geometry:{ |
| label:"Geometry", |
| desc:"How shape, space, length, area, angle, and structure relate.", |
| formula:"A_rectangle = l × w ; a² + b² = c²", |
| plain:"Geometry studies spatial relationships: shapes, distances, areas, angles, and how they fit together.", |
| example:"A rectangle that is 5 units long and 3 units wide has area 15 square units.", |
| misconception:"Area and perimeter are not the same. Perimeter measures boundary length; area measures covered space." |
| }, |
| graphing:{ |
| label:"Graphing", |
| desc:"How visual coordinate maps show relationships between quantities.", |
| formula:"y = mx + b", |
| plain:"A graph turns a relationship into a visual map. The x-axis tracks input, and the y-axis tracks output.", |
| example:"In y=2x+1, every time x increases by 1, y increases by 2.", |
| misconception:"A graph is not decoration. It is a structured visual form of the relationship." |
| }, |
| probability:{ |
| label:"Probability", |
| desc:"How uncertainty, likelihood, and outcomes are measured.", |
| formula:"P(event) = favorable outcomes / total possible outcomes", |
| plain:"Probability measures how likely an event is under a defined set of possible outcomes.", |
| example:"A fair coin has probability 1/2 of landing heads on a single flip.", |
| misconception:"Unlikely does not mean impossible. Likely does not mean guaranteed." |
| }, |
| statistics:{ |
| label:"Statistics", |
| desc:"How data, variation, averages, spread, and inference are handled.", |
| formula:"mean = sum of values / number of values", |
| plain:"Statistics helps summarize data and reason about variation without pretending the variation vanished.", |
| example:"The average of 2, 4, and 9 is 5 because (2+4+9)/3 = 5.", |
| misconception:"An average can hide important spread. Two groups can have the same mean but very different distributions." |
| }, |
| calculus:{ |
| label:"Calculus basics", |
| desc:"How change and accumulation are modeled.", |
| formula:"derivative ≈ rate of change ; integral ≈ accumulated total", |
| plain:"Calculus studies how quantities change and how small pieces add up into totals.", |
| example:"Speed is a rate of change of position; distance traveled can be accumulated from speed over time.", |
| misconception:"Calculus is not just hard algebra. It is a language for change, accumulation, and limits." |
| }, |
| linear_algebra:{ |
| label:"Linear algebra basics", |
| desc:"How vectors, matrices, transformations, and systems are represented.", |
| formula:"A x = b", |
| plain:"Linear algebra studies structured relationships among many quantities at once using vectors and matrices.", |
| example:"A matrix can rotate, stretch, or combine coordinates in a controlled way.", |
| misconception:"A matrix is not just a grid of numbers. It can represent a transformation or a system of relationships." |
| } |
| }; |
| |
| const ids=["abstraction","examples","symbols","metaphor","pacing"]; |
| const els=Object.fromEntries(ids.map(id=>[id,document.getElementById(id)])); |
| let lastRecord=null, logRecords=[], phase=0; |
| |
| function fmt(n){return Number(n).toFixed(2)} |
| function iso(){return new Date().toISOString()} |
| function now(){return new Date().toLocaleTimeString([], {hour:"2-digit",minute:"2-digit",second:"2-digit"})} |
| |
| function initSelects(){ |
| const topicSel=document.getElementById("topic"); |
| Object.entries(topics).forEach(([k,t])=>{ |
| const opt=document.createElement("option"); opt.value=k; opt.textContent=t.label; opt.title=t.desc; topicSel.appendChild(opt); |
| }); |
| topicSel.value="algebra"; |
| const modeSel=document.getElementById("mode"); |
| Object.entries(modes).forEach(([k,m])=>{ |
| const opt=document.createElement("option"); opt.value=k; opt.textContent=m.label; opt.title=m.desc; modeSel.appendChild(opt); |
| }); |
| modeSel.value="visual_map"; |
| updateDescriptions(); |
| } |
| function updateDescriptions(){ |
| const t=topics[document.getElementById("topic").value]; |
| const m=modes[document.getElementById("mode").value]; |
| document.getElementById("topicDesc").textContent=t.desc; |
| document.getElementById("modeDesc").textContent=m.desc; |
| } |
| function updateLabels(){ |
| document.getElementById("vAbs").textContent=fmt(els.abstraction.value); |
| document.getElementById("vEx").textContent=fmt(els.examples.value); |
| document.getElementById("vSym").textContent=fmt(els.symbols.value); |
| document.getElementById("vMet").textContent=fmt(els.metaphor.value); |
| document.getElementById("vPace").textContent=fmt(els.pacing.value); |
| } |
| function getState(){ |
| const topic=document.getElementById("topic").value; |
| const mode=document.getElementById("mode").value; |
| return { |
| topic, topicLabel:topics[topic].label, |
| mode, modeLabel:modes[mode].label, |
| learnerNote:document.getElementById("selfDesc").value.trim(), |
| abstraction:parseFloat(els.abstraction.value), |
| examples:parseFloat(els.examples.value), |
| symbols:parseFloat(els.symbols.value), |
| metaphor:parseFloat(els.metaphor.value), |
| pacing:parseFloat(els.pacing.value) |
| }; |
| } |
| function score(s){ |
| const b=modes[s.mode].bias; |
| let dist=0; ids.forEach(k=>dist+=Math.abs(s[k]-b[k])); |
| const match=Math.max(0,1-dist/5); |
| const A_translation=match; |
| const B_math=.89; |
| const P_mismatch=(1-match)*.62; |
| const S=(A_translation*B_math)-P_mismatch; |
| return {match,A_translation,B_math,P_mismatch,S}; |
| } |
| function layer(S){ |
| if(S>.63)return ["FORMAL_READY","FORMAL + INTUITIVE"]; |
| if(S>.44)return ["WORKING_MODEL","WORKING MODEL"]; |
| if(S>.22)return ["FIRST_PASS","FIRST PASS"]; |
| return ["OPEN_LOOP","NEEDS RETRANSLATION"]; |
| } |
| function addLog(msg){ |
| const item=document.createElement("div"); item.className="logItem"; |
| const t=now(); |
| item.innerHTML=`<div class="time">${t}</div><div class="msg">${msg}</div>`; |
| document.getElementById("log").prepend(item); |
| logRecords.push({timestamp:iso(),displayTime:t,message:msg}); |
| } |
| function generate(){ |
| const s=getState(), t=topics[s.topic], m=modes[s.mode], sc=score(s), [closure, layerName]=layer(sc.S); |
| document.getElementById("accessScore").textContent=fmt(sc.match); |
| document.getElementById("accessScore").style.color=sc.match>.75?"var(--green)":sc.match>.55?"var(--yellow)":"var(--orange)"; |
| document.getElementById("closureState").textContent=layerName; |
| document.getElementById("closureState").style.color=layerName.includes("FORMAL")?"var(--green)":layerName==="WORKING MODEL"?"var(--yellow)":"var(--orange)"; |
| document.getElementById("routeName").textContent=m.route; |
| document.getElementById("routeName").style.color="var(--blue)"; |
| document.getElementById("liveEq").innerHTML=`S_learning,t = (${fmt(sc.A_translation)} × ${fmt(sc.B_math)}) − ${fmt(sc.P_mismatch)} ≈ <strong>${fmt(sc.S)}</strong>`; |
| document.getElementById("formulaLine").innerHTML=`Topic structure: <strong>${t.formula}</strong>`; |
| const out=buildOutput(s,t,m,sc,layerName); |
| renderOutput(out); |
| lastRecord={metadata:{title:"Substrate Math Translation Simulator",version:"v0.1",timestamp:iso(),boundary:"Educational translation prototype; not diagnosis or replacement for formal instruction."},state:s,metrics:sc,understandingLayer:layerName,output:out}; |
| addLog(`Generated ${t.label} through ${m.route}: ${layerName}. Math structure preserved; route adapted.`); |
| draw(); |
| } |
| function buildOutput(s,t,m,sc,layerName){ |
| return { |
| topic:t.label, mode:m.label, route:m.route, understandingLayer:layerName, |
| sections:[ |
| {title:"1. Main idea", text:modeIntro(s,t)}, |
| {title:"2. Mathematical structure", text:structureText(s,t)}, |
| {title:"3. How to picture it", text:pictureText(s,t)}, |
| {title:"4. Worked example / entry point", text:exampleText(s,t)}, |
| {title:"5. Misconception guardrail", text:guardrailText(s,t)}, |
| {title:"6. Check-for-understanding", text:checkText(s,t)}, |
| {title:"7. Closure boundary", text:closureText(layerName)} |
| ], |
| supports:supports(s,sc) |
| }; |
| } |
| function modeIntro(s,t){ |
| const map={ |
| visual_map:`Map it visually: the concept is the center node, the symbols are the compressed structure, the example is the path into the map, and the misconception is the boundary marker. For ${t.label}, the map starts here: ${t.plain}`, |
| concrete_examples:`Start with the example: ${t.example} From there, the math idea is: ${t.plain}`, |
| technical_symbolic:`Formal read: ${t.formula}. The concept is ${t.label}. Plain interpretation: ${t.plain}`, |
| story_metaphor:`Imagine the math as a machine that preserves relationships. For ${t.label}, the machine does this: ${t.plain}`, |
| stepwise_literal:`Step 1: the topic is ${t.label}. Step 2: the core structure is ${t.formula}. Step 3: the meaning is: ${t.plain}`, |
| fast_associative:`Pattern bridge: ${t.label} links structure, symbol, example, operation, graph, and proof boundary. Core: ${t.plain}`, |
| skeptical_redteam:`Bounded claim: this is a first-pass model of ${t.label}, not the entire field. The structure ${t.formula} is useful inside its assumptions. Core: ${t.plain}`, |
| lived_context:`Human-scale read: ${t.label} matters because it helps people measure, compare, plan, build, check claims, and avoid being fooled by bad numbers. Core: ${t.plain}`, |
| teacher_scaffold:`Learning objective: explain ${t.label} in plain language and connect it to ${t.formula}. Main idea: ${t.plain}` |
| }; |
| return map[s.mode]; |
| } |
| function structureText(s,t){ |
| let text=`The key structure is ${t.formula}. `; |
| if(s.symbols>.65) text+=`Read the symbols as compressed meaning: each symbol holds a role, and each operation changes the relationship according to rules. `; |
| else text+=`You do not have to start by manipulating symbols. First, treat the expression as a sentence about relationships. `; |
| if(s.pacing>.72) text+=`Name the parts, identify what is known, identify what is unknown, then apply one rule at a time.`; |
| return text; |
| } |
| function pictureText(s,t){ |
| if(s.mode==="visual_map") return `Draw ${t.label} as a map. Put the known quantities on one side, the unknown or target on the other, and the rule as the bridge between them.`; |
| if(s.mode==="story_metaphor") return `Picture ${t.label} as a transformation story: something enters, a rule acts on it, and a relationship is preserved or revealed.`; |
| if(s.mode==="technical_symbolic") return `Picture it as a rule-governed structure. The notation is not decoration; it encodes allowed moves and dependencies.`; |
| if(s.mode==="stepwise_literal") return `Picture one move at a time: define, substitute, simplify, check. Do not combine steps until the prior step is clear.`; |
| return `Picture the relationship first, then attach the symbols. The picture prevents the notation from floating without meaning.`; |
| } |
| function exampleText(s,t){ |
| let text=t.example; |
| if(s.examples>.72) text+=` Ask: what is given, what is being asked, what relationship connects them, and what would count as a correct answer?`; |
| if(s.metaphor>.72) text+=` The example is a bridge, not the whole territory: use it to enter the structure, then return to the math.`; |
| return text; |
| } |
| function guardrailText(s,t){ |
| let text=t.misconception; |
| if(s.mode==="skeptical_redteam") text+=` Red-team rule: every move must preserve equality, definition, or stated assumption.`; |
| if(s.pacing>.72) text+=` This is where the loop should stay open until the distinction is clear.`; |
| return text; |
| } |
| function checkText(s,t){ |
| const checks={ |
| arithmetic:"Can you explain why multiplication can mean repeated groups, scaling, or area depending on context?", |
| fractions:"Which is larger, 1/4 or 1/8, and how can you see it without only using rules?", |
| algebra:"In x + 3 = 10, what operation undoes +3 and why does it preserve the equation?", |
| functions:"If f(x)=2x+1, what input gives output 9?", |
| geometry:"How are perimeter and area different for the same rectangle?", |
| graphing:"In y=2x+1, what does the 2 do to the graph?", |
| probability:"Does a 1/6 chance mean an event must happen exactly once every six trials?", |
| statistics:"Why can an average hide important differences in a dataset?", |
| calculus:"What is the difference between rate of change and accumulated total?", |
| linear_algebra:"Why can a matrix be more than a table of numbers?" |
| }; |
| return checks[s.topic] || "Can you explain the concept without using the formal notation first?"; |
| } |
| function closureText(layerName){ |
| if(layerName.includes("FORMAL")) return "This translation can close at both the first-pass and working-model layers. Formal proof and practice still remain open for deeper validation."; |
| if(layerName==="WORKING MODEL") return "This translation can close as a working model. Keep formal proof, edge cases, and independent practice open."; |
| if(layerName==="FIRST PASS") return "This translation can close as a first-pass explanation. Keep examples, symbol manipulation, and proof boundaries open."; |
| return "This loop should remain open. The explanation route needs retranslation before claiming understanding."; |
| } |
| function supports(s,sc){ |
| const arr=[]; |
| if(s.examples>.65) arr.push("Use a worked example before symbolic manipulation."); |
| if(s.pacing>.70) arr.push("Define each symbol and operation before combining steps."); |
| if(s.symbols>.60) arr.push("Show notation, allowed moves, and assumptions."); |
| if(s.metaphor>.65) arr.push("Use analogy, but mark where the analogy stops."); |
| if(s.abstraction>.70) arr.push("Give the general structure before the example."); |
| if(sc.P_mismatch>.25) arr.push("Mismatch pressure remains: do not force closure; try another route."); |
| arr.push("Confusion is not failure. It is a signal that the route into the structure may need adjustment."); |
| return arr; |
| } |
| function renderOutput(o){ |
| const box=document.getElementById("output"); box.innerHTML=""; |
| const head=document.createElement("div"); head.className="card"; |
| head.innerHTML=`<h3>${o.topic} via <span class="blue">${o.route}</span></h3> |
| <p><strong>Selected mode:</strong> ${o.mode}</p> |
| <p><strong>Understanding layer:</strong> ${o.understandingLayer}. This is an explanation route, not a learner diagnosis.</p>`; |
| box.appendChild(head); |
| o.sections.forEach(sec=>{ |
| const div=document.createElement("div"); div.className="card"; |
| div.innerHTML=`<h3>${sec.title}</h3><p>${sec.text}</p>`; |
| box.appendChild(div); |
| }); |
| const sup=document.createElement("div"); sup.className="card"; |
| sup.innerHTML=`<h3>Recommended supports</h3><ul>${o.supports.map(x=>`<li>${x}</li>`).join("")}</ul>`; |
| box.appendChild(sup); |
| } |
| function copyOutput(){ |
| if(!lastRecord)generate(); |
| const lines=[]; |
| lines.push("Substrate Math Translation Simulator v0.1"); |
| lines.push(`Topic: ${lastRecord.output.topic}`); |
| lines.push(`Mode: ${lastRecord.output.mode}`); |
| lines.push(`Route: ${lastRecord.output.route}`); |
| lines.push(`Understanding layer: ${lastRecord.output.understandingLayer}`); |
| lines.push(""); |
| lastRecord.output.sections.forEach(s=>{lines.push(s.title);lines.push(s.text);lines.push("");}); |
| lines.push("Recommended supports:"); |
| lastRecord.output.supports.forEach(x=>lines.push("- "+x)); |
| navigator.clipboard.writeText(lines.join("\n")).then(()=>addLog("Copied generated math translation to clipboard.")); |
| } |
| function exportJSON(){ |
| if(!lastRecord)generate(); |
| const data={...lastRecord, steward_log:logRecords}; |
| const blob=new Blob([JSON.stringify(data,null,2)],{type:"application/json"}); |
| const url=URL.createObjectURL(blob); |
| const a=document.createElement("a"); a.href=url; a.download=`substrate-math-translation-${Date.now()}.json`; |
| document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); |
| } |
| function trySample(){ |
| const modeKeys=Object.keys(modes), topicKeys=Object.keys(topics); |
| const mk=modeKeys[Math.floor(Math.random()*modeKeys.length)]; |
| const tk=topicKeys[Math.floor(Math.random()*topicKeys.length)]; |
| document.getElementById("mode").value=mk; document.getElementById("topic").value=tk; |
| const b=modes[mk].bias; ids.forEach(id=>els[id].value=b[id]); |
| const samples=[ |
| "I need the picture before the symbols.", |
| "I trust the formula when I know what each symbol is allowed to do.", |
| "Examples first, then the rule.", |
| "I see patterns quickly and want the full map.", |
| "Please slow it down and define each move before combining them." |
| ]; |
| document.getElementById("selfDesc").value=samples[Math.floor(Math.random()*samples.length)]; |
| updateLabels(); updateDescriptions(); generate(); |
| } |
| function draw(){ |
| const c=document.getElementById("mathCanvas"), ctx=c.getContext("2d"), w=c.width,h=c.height; |
| const s=getState(), sc=score(s), t=topics[s.topic]; |
| phase+=.035; |
| ctx.clearRect(0,0,w,h); |
| const bg=ctx.createLinearGradient(0,0,w,h); bg.addColorStop(0,"#080d15"); bg.addColorStop(1,"#0f1420"); ctx.fillStyle=bg; ctx.fillRect(0,0,w,h); |
| const color=sc.S>.63?"#49d17c":sc.S>.44?"#ffd166":sc.S>.22?"#ff9f43":"#ff5c7a"; |
| const yMid=h*.56, amp=10+(1-sc.match)*42; |
| for(let layer=0;layer<4;layer++){ |
| ctx.beginPath(); |
| for(let x=0;x<=w;x+=5){ |
| const y=yMid+Math.sin((x+phase*90+layer*25)/(45-layer*4))*(amp*(1-layer*.14)); |
| if(x===0)ctx.moveTo(x,y); else ctx.lineTo(x,y); |
| } |
| ctx.strokeStyle=layer===0?color:`rgba(101,184,255,${.12+layer*.05})`; |
| ctx.lineWidth=layer===0?2.8:1.2; ctx.stroke(); |
| } |
| const nodes=["concept","symbols","example","rule","guardrail","check","closure"]; |
| nodes.forEach((n,i)=>{ |
| const x=58+i*(w-116)/(nodes.length-1); |
| const y=yMid+Math.sin((x+phase*90)/45)*amp; |
| ctx.beginPath(); ctx.arc(x,y,6+s.examples*3,0,Math.PI*2); |
| ctx.fillStyle=`rgba(88,230,217,${.28+s.pacing*.34})`; ctx.fill(); |
| ctx.strokeStyle=color; ctx.lineWidth=1.5; ctx.stroke(); |
| ctx.fillStyle="rgba(238,245,255,.72)"; ctx.font="11px ui-monospace,monospace"; ctx.textAlign="center"; ctx.fillText(n,x,y-14); |
| }); |
| ctx.fillStyle="rgba(238,245,255,.84)"; ctx.font="12px ui-monospace,monospace"; ctx.textAlign="center"; |
| ctx.fillText(`${t.label}: ${t.formula}`,w/2,32); |
| ctx.fillText(`S_learning ≈ ${fmt(sc.S)} · route match ${fmt(sc.match)}`,w/2,52); |
| } |
| function loop(){draw();requestAnimationFrame(loop);} |
| |
| ids.forEach(id=>els[id].addEventListener("input",()=>{updateLabels();generate();})); |
| document.getElementById("topic").addEventListener("change",()=>{updateDescriptions();generate();}); |
| document.getElementById("mode").addEventListener("change",()=>{updateDescriptions();generate();}); |
| document.getElementById("generateBtn").addEventListener("click",generate); |
| document.getElementById("randomBtn").addEventListener("click",trySample); |
| document.getElementById("copyBtn").addEventListener("click",copyOutput); |
| document.getElementById("exportJSON").addEventListener("click",exportJSON); |
| |
| initSelects(); updateLabels(); |
| addLog("Simulator initialized. Math structure preserved; cognition route adapted."); |
| generate(); loop(); |
| </script> |
| </body> |
| </html> |
|
|