---###!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width,initial-scale1.0 title数学解题器/title style :root{ --bg:#0a0f18; --fg:#c8d8e8; --accent:#00d4aa; --accent-hover:#00e5b5; --border:#1a2a3a; --inp:#0d1520; --card:#0e1728; --hover:#132038; --error:#ff5570; --warning:#ffd060; --info:#c0a0ff; --success:#00e5a0; } *{ margin:0; padding:0; box-sizing:border-box; transition: all 0.2s ease; } body{ background:var(--bg); color:var(--fg); font-family:JetBrains Mono,Consolas,Monaco,monospace; display:flex; justify-content:center; align-items:flex-start; min-height:100vh; padding:20px 16px; line-height:1.6; } .wrap{ width:100%; max-width:1100px; background:var(--card); border:1px solid var(--border); border-radius:16px; padding:28px 32px; box-shadow: 0 8px 32px rgba(0,0,0,0.3); } h2{ font-size:18px; letter-spacing:6px; color:var(--accent); text-align:center; margin-bottom:24px; font-weight:600; text-transform:uppercase; } .tabs{ display:flex; gap:4px; margin-bottom:20px; flex-wrap:wrap; border-bottom:1px solid var(--border); padding-bottom:1px; } .tab{ padding:12px 24px; background:#060c16; border:1px solid var(--border); border-bottom:none; color:#6888a8; cursor:pointer; border-radius:8px 8px 0 0; font-size:13px; font-weight:500; position:relative; top:1px; } .tab:hover{ color:var(--fg); background:var(--hover); transform:translateY(-1px); } .tab.active{ background:var(--card); border-bottom-color:var(--card); color:var(--accent); transform:translateY(0); box-shadow: 0 -2px 8px rgba(0,212,170,0.1); } .panel{ display:none; animation: fadeIn 0.3s ease; } .panel.active{ display:block; } keyframes fadeIn{ from{opacity:0;transform:translateY(10px)} to{opacity:1;transform:translateY(0)} } label{ font-size:12px; color:#5a7a9a; margin-bottom:8px; display:block; font-weight:500; text-transform:uppercase; letter-spacing:1px; } textarea{ width:100%; background:var(--inp); border:1px solid var(--border); color:var(--fg); padding:16px; border-radius:8px; font-family:inherit; font-size:14px; resize:vertical; min-height:120px; line-height:1.7; tab-size:4; } textarea:focus{ border-color:var(--accent); outline:none; box-shadow:0 0 0 3px rgba(0,212,170,0.1); } .btn-row{ display:flex; gap:10px; margin:16px 0; flex-wrap:wrap; } button{ background:var(--accent); border:none; color:#000; font-weight:700; padding:12px 24px; border-radius:8px; cursor:pointer; font-family:inherit; font-size:14px; letter-spacing:1px; display:flex; align-items:center; gap:8px; } button:hover{ background:var(--accent-hover); transform:translateY(-1px); box-shadow:0 4px 12px rgba(0,212,170,0.3); } button:active{ transform:translateY(0); } button.secondary{ background:var(--hover); color:var(--fg); } button.secondary:hover{ background:#182848; box-shadow:0 4px 12px rgba(0,0,0,0.2); } button.danger{ background:#2a1520; color:#ff5570; } button.danger:hover{ background:#3a1a28; box-shadow:0 4px 12px rgba(255,85,112,0.2); } button:disabled{ opacity:0.5; cursor:not-allowed; transform:none !important; box-shadow:none !important; } .res-wrap{ background:var(--inp); border:1px solid var(--border); border-radius:10px; margin-top:16px; overflow:hidden; box-shadow:inset 0 2px 8px rgba(0,0,0,0.2); } .res-head{ display:flex; justify-content:space-between; align-items:center; padding:10px 16px; background:#0a1018; border-bottom:1px solid var(--border); font-size:11px; color:#4a6a8a; font-weight:500; } .res-actions{ display:flex; gap:8px; } .res-actions button{ padding:6px 12px; font-size:11px; background:transparent; color:#6888a8; border:1px solid var(--border); } .res-actions button:hover{ color:var(--fg); background:var(--hover); } .res-body{ padding:20px; font-size:14px; overflow-x:auto; white-space:pre-wrap; max-height:550px; overflow-y:auto; font-family:inherit; line-height:1.8; } .res-body::-webkit-scrollbar{ width:8px; height:8px; } .res-body::-webkit-scrollbar-track{ background:var(--inp); } .res-body::-webkit-scrollbar-thumb{ background:var(--border); border-radius:4px; } .res-body::-webkit-scrollbar-thumb:hover{ background:#2a3a4a; } .g{color:var(--success)} .r{color:var(--error)} .v{color:var(--info)} .y{color:var(--warning)} .step{ margin-bottom:12px; padding-left:8px; border-left:2px solid var(--border); } .step-header{ font-weight:600; margin-bottom:4px; } .step-content{ padding-left:16px; color:#a8b8c8; } .loading{ display:inline-block; width:16px; height:16px; border:2px solid var(--border); border-top-color:var(--accent); border-radius:50%; animation: spin 1s linear infinite; } keyframes spin{ to{transform:rotate(360deg)} } media (max-width:768px){ .wrap{padding:20px 16px} h2{font-size:16px;letter-spacing:4px} .tab{padding:10px 16px;font-size:12px} button{padding:10px 16px;font-size:13px;flex:1;justify-content:center} .res-body{padding:16px;font-size:13px} } /style /head body div classwrap h2数学解题器/h2 div classtabs div classtab active data-panelsolver通用解题器/div div classtab data-panelexamples预设问题/div div classtab data-panelhelp使用说明/div /div div classpanel active idpanel-solver label初始变量值/label textarea idvarInput rows1 placeholder例如x2.0, y1.0, t0x2.0/textarea label推理规则每行条件,公式,优先级,结果变量,锁定/label textarea idruleInput rows12 placeholder每行一条规则格式条件,公式,优先级,结果变量,锁定fabs(x^3-2*x-5)1e-8, x-(x^3-2*x-5)/(3*x^2-2), 0, x, 0 fabs(x^3-2*x-5)1e-8, 收敛, 1, state, 1/textarea div classbtn-row button onclickrunSolver() idsolveBtnspan求解/span/button button onclickclearAll() classsecondary清空/button button onclickcheckConsistency() classsecondary检查一致性/button /div div classres-wrap div classres-head span推理过程与结果/span div classres-actions button onclickcopyResult()复制结果/button button onclickclearResult()清空/button /div /div div classres-body idsolverResultspan stylecolor:#5a7a9a点击求解按钮开始推理/span/div /div /div div classpanel idpanel-examples label预设问题/label div classbtn-row button onclickloadExample(newton) classsecondary牛顿法解方程/button button onclickloadExample(lorenz) classsecondary洛伦兹吸引子/button button onclickloadExample(heat) classsecondary热传导方程/button button onclickloadExample(integral) classsecondary积分方程/button button onclickloadExample(eigen) classsecondary特征值计算/button button onclickloadExample(conflict) classsecondary平级冲突演示/button /div textarea idexampleDesc rows6 readonly stylebackground:#050a12;color:#6888a8;margin-top:16px/textarea /div div classpanel idpanel-help div styleline-height:1.8;font-size:14px h3 stylecolor:var(--accent);margin-bottom:20px;font-size:18px使用说明/h3 h4 stylecolor:var(--info);margin:16px 0 8px基本概念/h4 p本工具通过规则匹配的方式求解数学问题。每条规则包含五个部分/p ul stylemargin:10px 0 20px 24px listrong stylecolor:var(--success)条件/strong一个数学表达式当计算结果不为零时视为条件成立/li listrong stylecolor:var(--success)公式/strong条件成立时执行的数学表达式计算结果将存入指定变量/li listrong stylecolor:var(--success)优先级/strong数字越小优先级越高当多条规则同时满足时只执行优先级最高的/li listrong stylecolor:var(--success)结果变量/strong公式计算结果的存储位置使用-表示不存储/li listrong stylecolor:var(--success)锁定/strong设置为1时规则执行后立即结束整个求解过程/li /ul h4 stylecolor:var(--info);margin:16px 0 8px规则格式/h4 p每行写一条规则用逗号分隔五个部分。支持以下运算符和函数/p ul stylemargin:10px 0 20px 24px li算术运算符 - * / ^幂/li li比较运算符 !/li li数学函数sin, cos, tan, log, ln, sqrt, abs, exp, fabs/li li常数piπ/li /ul h4 stylecolor:var(--info);margin:16px 0 8px求解过程/h4 p引擎反复扫描规则表每次执行一条条件成立且优先级最高的规则更新变量状态直至遇到锁定规则、无规则触发或达到最大迭代次数100次。/p h4 stylecolor:var(--info);margin:16px 0 8px键盘快捷键/h4 ul stylemargin:10px 0 20px 24px listrongCtrlEnter/strong开始求解/li listrongCtrlR/strong清空所有内容/li listrongTab/strong在文本区域中插入制表符/li /ul /div /div /div script const MF{sin:Math.sin,cos:Math.cos,tan:Math.tan,log:Math.log10,ln:Math.log,sqrt:Math.sqrt,abs:Math.abs,exp:Math.exp,fabs:Math.abs}; function evalExpr(input,varPool{}){ let sinput.replace(/\s/g,); for(let k in varPool) ss.replace(new RegExp(\\bk\\b,g),varPool[k]); ss.replace(/\b(sin|cos|tan|log|ln|sqrt|abs|exp|fabs)\b/gi,Math.$1).replace(/\bpi\b/gi,Math.PI).replace(/\^/g,**); try{return Function(use strict;return(s))();}catch(e){return NaN;} } function resolve(rules, pool){ if(rules.length3){ const matchesrules.map(r{const cevalExpr(r.cond,pool);return !isNaN(c)Math.abs(c)1e-12;}); const matchCountmatches.filter(mm).length; if(!matchCount) return {fired:false}; const prsrules.map((r,i)matches[i]?r.priority:31); const minPriMath.min(...prs); const cntmatches.filter((m,i)mrules[i].priorityminPri).length; if(cnt1) return {conflict:true}; const idxmatches.findIndex((m,i)mrules[i].priorityminPri); const rulerules[idx]; const resevalExpr(rule.formula,pool); if(isNaN(res)) return {error:公式错误: ${rule.formula}}; return {fired:true,rule,result:res}; } const grouped[]; for(let i0;irules.length;i3) grouped.push(rules.slice(i,i3)); const resultsgrouped.map(gresolve(g,pool)); const conflictresults.find(rr.conflict); if(conflict) return conflict; const errresults.find(rr.error); if(err) return err; const firedRulesresults.filter(rr.fired).map(rr.rule); if(!firedRules.length) return {fired:false}; return resolve(firedRules,pool); } function runSolver(){ const solveBtndocument.getElementById(solveBtn); const resultDivdocument.getElementById(solverResult); solveBtn.disabledtrue; solveBtn.innerHTMLspan classloading/spanspan计算中.../span; resultDiv.innerHTMLspan stylecolor:#6888a8正在进行推理.../span; setTimeout((){ try{ let varTextdocument.getElementById(varInput).value.trim(); let ruleTextdocument.getElementById(ruleInput).value.trim(); let pool{}; varText.split(,).map(ss.trim()).filter(ss).forEach(def{ let[n,v]def.split().map(ss.trim()); if(nv) pool[n]parseFloat(v); }); let rules[]; ruleText.split(\n).filter(ll.trim()).forEach(line{ let partsline.split(,).map(ss.trim()); if(parts.length5) return; rules.push({cond:parts[0],formula:parts[1],priority:parseInt(parts[2])||0,resultVar:parts[3]-?null:parts[3],lock:parseInt(parts[4])||0,line}); }); if(!rules.length){resultDiv.innerHTMLspan classr❌ 没有有效规则/span;return;} let lockThresholdMath.min(...rules.filter(rr.lock).map(rr.priority),31); let lockedfalse,iter0,maxIter100,out; if(lockThreshold31) outdiv classv stylemargin-bottom:12px 锁定优先级阈值: ${lockThreshold}/div\n; while(!lockeditermaxIter){ let filteredrules.filter(rr.prioritylockThreshold); let resresolve(filtered,pool); if(res.conflict){outdiv classstepdiv classstep-headerspan classr❌ [步骤${iter1}] 平级冲突无真推理终止/span/divdiv classstep-content多条相同优先级的规则同时匹配无法确定唯一解/div/div\n;break;} if(res.error){outdiv classstepdiv classstep-headerspan classr❌ [步骤${iter1}] 执行错误/span/divdiv classstep-content${res.error}/div/div\n;break;} if(!res.fired){outdiv classstepdiv classstep-headerspan classy⚠️ [步骤${iter1}] 无规则触发推理终止/span/divdiv classstep-content没有任何规则的条件满足/div/div\n;break;} const rres.rule; let stepContent公式结果: ${res.result}\n; if(r.resultVar){pool[r.resultVar]res.result;stepContent存入变量: ${r.resultVar}${res.result};} if(r.lock){stepContent\nspan classg✅ 规则锁定推理结束/span;lockedtrue;} outdiv classstepdiv classstep-headerspan classg✅ [步骤${iter1}] 触发规则/span: ${r.line}/divdiv classstep-content${stepContent}/div/div\n; iter; } if(!lockeditermaxIter) outdiv classstepdiv classstep-headerspan classy⚠️ 达到最大迭代次数(${maxIter})未锁定/span/divdiv classstep-content推理可能未完成请增加迭代次数或检查规则/div/div\n; let final[]; for(let k in pool) final.push(${k}${pool[k]}); outdiv stylemargin-top:20px;padding-top:12px;border-top:1px solid var(--border)span classv 最终变量状态:/span ${final.join( )}/div; resultDiv.innerHTMLout; resultDiv.scrollTopresultDiv.scrollHeight; }catch(e){resultDiv.innerHTMLspan classr❌ 发生错误: ${e.message}/span;} finally{solveBtn.disabledfalse; solveBtn.innerHTMLspan求解/span;} },50); } function checkConsistency(){ let ruleTextdocument.getElementById(ruleInput).value.trim(); let rules[]; ruleText.split(\n).filter(ll.trim()).forEach(line{ let partsline.split(,).map(ss.trim()); if(parts.length5) return; rules.push({cond:parts[0],formula:parts[1],priority:parseInt(parts[2])||0,resultVar:parts[3]-?null:parts[3],lock:parseInt(parts[4])||0,line}); }); if(!rules.length){document.getElementById(solverResult).innerHTMLspan classr❌ 没有有效规则/span;return;} let outdiv classv stylefont-size:16px;margin-bottom:16px 规则一致性检查报告/div\n\n; outdiv 总规则数: ${rules.length}/div\n\n; let priCount{}; rules.forEach(r{priCount[r.priority](priCount[r.priority]||0)1;}); let dupObject.keys(priCount).filter(ppriCount[p]1); if(dup.length){outdiv classy stylemargin-bottom:8px⚠️ 警告: 以下优先级有多个规则可能导致平级冲突:/div\n;dup.forEach(pout • 优先级 ${p}: ${priCount[p]} 条规则\n);out\n;} else outdiv classg stylemargin-bottom:16px✅ 所有规则优先级唯一无平级冲突风险/div\n\n; let lockRulesrules.filter(rr.lock); if(lockRules.length){outdiv classv stylemargin-bottom:8px 锁定规则:/div\n;lockRules.forEach(rout • ${r.line}\n);out\n 全局锁定阈值: ${Math.min(...lockRules.map(rr.priority))}\n\n;} else outdiv classy stylemargin-bottom:16px⚠️ 没有锁定规则推理将在达到最大迭代次数后终止/div\n\n; let minPriMath.min(...rules.map(rr.priority)); let unreachablerules.filter(rr.priorityminPrirules.some(r2r2.priorityr.priorityr2.condr.cond)); if(unreachable.length){outdiv classr stylemargin-bottom:8px❌ 错误: 以下规则永远不会被触发:/div\n;unreachable.forEach(rout • ${r.line}\n);} else outdiv classg✅ 所有规则都可能被触发/div\n; document.getElementById(solverResult).innerHTMLout; } function clearAll(){ document.getElementById(varInput).value; document.getElementById(ruleInput).value; document.getElementById(solverResult).innerHTMLspan stylecolor:#5a7a9a点击求解按钮开始推理/span; } function clearResult(){ document.getElementById(solverResult).innerHTMLspan stylecolor:#5a7a9a点击求解按钮开始推理/span; } function copyResult(){ const textdocument.getElementById(solverResult).innerText; navigator.clipboard.writeText(text).then((){ const btnevent.target; const origbtn.innerText; btn.innerText已复制!; setTimeout(()btn.innerTextorig,1500); }).catch(()alert(复制失败)); } function loadExample(type){ let vs,rs,ds; if(typenewton){vsx2.0;rsfabs(x^3-2*x-5)1e-8, x-(x^3-2*x-5)/(3*x^2-2), 0, x, 0\nfabs(x^3-2*x-5)1e-8, 收敛, 1, state, 1;ds牛顿迭代法解 x³-2x-50\n\n通过规则匹配实现迭代求解无需编写循环代码。;} else if(typelorenz){vsx1.0, y1.0, z1.0, t0, h0.01;rst10, xh*10*(y-x), 0, x, 0\nt10, yh*(x*(28-z)-y), 1, y, 0\nt10, zh*(x*y-8/3*z), 2, z, 0\nt10, th, 3, t, 0\nt10, 完成, 4, state, 1;ds洛伦兹吸引子离散化步进推理。;} else if(typeheat){vsiter0, u00.0, u10.5, u21.0, alpha1.0, dx0.1, dt0.001;rsiter100, (u2u0-2*u1)*alpha*dt/(dx^2)u1, 0, u1_new, 0\niter100, iter1, 1, iter, 0\niter100, 完成, 2, state, 1;ds一维热传导方程显式差分。;} else if(typeintegral){vsa0, b1, n20, lambda0.5, sum0, i0;rsin, sum(sin(ai*(b-a)/n)sin(a(i1)*(b-a)/n))*(b-a)/n/2, 0, sum, 0\nin, i1, 1, i, 0\nin, sum*lambda, 2, result, 0\nin, 完成, 3, state, 1;dsFredholm积分方程离散化求解。;} else if(typeeigen){vsv11.0, v20.0, lambda0, iter0;rsiter50, 2*v1v2, 0, v1_new, 0\niter50, v12*v2, 1, v2_new, 0\niter50, sqrt(v1_new^2v2_new^2), 2, lambda, 0\niter50, v1_new/lambda, 3, v1, 0\niter50, v2_new/lambda, 4, v2, 0\niter50, iter1, 5, iter, 0\niter50, 收敛, 6, state, 1;ds幂迭代法求特征值。;} else if(typeconflict){vsx5.0;rsx0, 规则1结果, 0, result, 0\nx0, 规则2结果, 0, result, 0\nx0, 规则3结果, 1, result, 1;ds平级冲突演示。;} document.getElementById(varInput).valuevs; document.getElementById(ruleInput).valuers; document.getElementById(exampleDesc).valueds; document.querySelectorAll(.tab).forEach(tt.classList.remove(active)); document.querySelector(.tab[data-panelsolver]).classList.add(active); document.querySelectorAll(.panel).forEach(pp.classList.remove(active)); document.getElementById(panel-solver).classList.add(active); document.getElementById(solverResult).innerHTMLspan stylecolor:#5a7a9a点击求解按钮开始推理/span; } document.querySelectorAll(.tab).forEach(tab{ tab.addEventListener(click,(){ document.querySelectorAll(.tab).forEach(tt.classList.remove(active)); document.querySelectorAll(.panel).forEach(pp.classList.remove(active)); tab.classList.add(active); document.getElementById(panel-tab.dataset.panel).classList.add(active); }); }); document.addEventListener(keydown,e{ if(e.ctrlKeye.keyEnter){e.preventDefault();runSolver();} else if(e.ctrlKeye.keyr){e.preventDefault();clearAll();} }); document.querySelectorAll(textarea).forEach(ta{ ta.addEventListener(keydown,e{ if(e.keyTab){e.preventDefault();const sta.selectionStart;ta.valueta.value.substring(0,s) ta.value.substring(ta.selectionEnd);ta.selectionStartta.selectionEnds4;} }); }); /script /body /html**一句话简介**本工具通过“规则匹配”的方式求解数学问题。你只需要告诉它“在什么条件下做什么计算”它就会自动反复扫描、执行直到得出最终结果。---### 一、界面概览工具包含三个标签页1. **通用解题器**输入变量和规则手动求解。2. **预设问题**内置了几个经典数学问题一键加载。3. **使用说明**就是这里的内容。---### 二、如何定义一个求解问题你需要填写两个区域**初始变量值**和**推理规则**。#### 1. 初始变量值用逗号分隔格式为 变量名数值。例如x2.0, y1.0, t0这些变量可以在规则中直接使用。#### 2. 推理规则每条规则占一行用逗号分隔为五个部分格式固定为条件, 公式, 优先级, 结果变量, 锁定每个部分的含义如下| 部分 | 说明 | 示例 ||------|------|------|| **条件** | 一个数学表达式结果不为0时视为“条件成立” | fabs(x^3-2*x-5)1e-8 || **公式** | 条件成立时要执行的计算 | x-(x^3-2*x-5)/(3*x^2-2) || **优先级** | 数字越小越优先执行0最高 | 0 || **结果变量** | 公式的计算结果存入哪个变量填 - 表示不存储 | x || **锁定** | 1 表示执行后立即结束求解0 表示继续 | 1 |---### 三、求解过程说明点击 **“求解”** 按钮后引擎会这样工作1. 扫描所有规则找出“条件成立”的规则。2. 如果多条规则同时成立只执行**优先级最高**的那条。3. 执行该规则的“公式”并把结果存入指定的“结果变量”。4. 如果该规则的“锁定”为 1则立即结束。5. 重复以上步骤直到锁定、无条件成立的规则、或达到100次上限。你可以点击 **“检查一致性”** 按钮让工具帮你分析规则是否有冲突、是否有永远不会被触发的规则。---### 四、运算符与函数支持规则中的条件和公式都支持以下写法- **算术** - * / ^幂- **比较** !- **函数**sin(x) cos(x) tan(x) log(x) ln(x) sqrt(x) abs(x) exp(x) fabs(x)- **常数**pi---### 五、可求解的数学问题类型通过编写不同的规则本工具可以求解- **非线性方程求根**如牛顿迭代- **常微分方程组**如洛伦兹吸引子- **偏微分方程**如热传导方程显式差分- **积分方程**如Fredholm方程离散化- **特征值问题**如幂迭代法- **任意自定义的迭代/递推算法**---### 六、预设问题说明在 **“预设问题”** 标签页中你可以一键加载以下经典案例| 预设名称 | 数学问题 ||----------|----------|| 牛顿法解方程 | 求解 x³−2x−50 || 洛伦兹吸引子 | 模拟混沌系统轨迹 || 热传导方程 | 一维显式差分解 || 积分方程 | Fredholm积分方程离散求解 || 特征值计算 | 幂迭代法求矩阵特征值 || 平级冲突演示 | 展示多条同优先级规则同时匹配时的处理方式 |---### 七、快捷键- **Ctrl Enter**开始求解- **Ctrl R**清空所有内容- **Tab**在文本编辑区域中插入4个空格---### 八、完整使用示例**问题**用牛顿法求解方程 x³−2x−50**步骤**1. 在“初始变量值”中输入x2.02. 在“推理规则”中输入fabs(x^3-2*x-5)1e-8, x-(x^3-2*x-5)/(3*x^2-2), 0, x, 0fabs(x^3-2*x-5)1e-8, 收敛, 1, state, 13. 点击 **“求解”**。4. 观察输出引擎会自动迭代更新 x直到残差小于 1e-8然后锁定并输出最终结果约 2.09455。---**注意事项**- 规则中的“条件”使用 fabs 判断浮点接近程度避免直接用 比较。- 如果推理在达到100步后仍未锁定工具会给出提示请检查规则或增加迭代次数修改代码中的 maxIter。- 请确保所有在规则中使用的变量都在“初始变量值”中定义过。---这份说明可以直接贴在工具旁边或单独保存为文本文件。任何有基本数学和编程常识的人读完就能上手使用。