Pick an integrand below. For each one, a simplified version of the Risch machinery — comparing the shape of the derivative you'd need against the shape the function actually has — reports whether an elementary antiderivative exists, and shows it when it does.
<p class="hint">Pick an integrand and click <b>Decide</b>. A simplified version of the Risch machinery reports whether an elementary antiderivative exists — and produces it when it does, or explains why none can when it doesn’t.</p>
<div class="picker" id="picker"></div>
<div class="btns">
<button id="decide" type="button">Decide</button>
<button id="reset" type="button" class="ghost">Clear</button>
</div>
<div class="result" id="result">Pick an integrand above, then click Decide.</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .7rem; line-height: 1.45; }
.picker { display: flex; flex-direction: column; gap: .4rem; margin: .4rem 0 .8rem; }
.opt { display: flex; align-items: center; gap: .55rem; padding: .5rem .7rem; border: 1px solid #cdd9e3;
border-radius: 8px; background: #f4f7f9; cursor: pointer; transition: all .1s; }
.opt:hover { background: #e8eef3; }
.opt.sel { background: #1d3557; border-color: #1d3557; color: #fff; }
.opt .fn { font: 700 15px ui-monospace, monospace; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .6rem; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
.result { font-size: .95rem; font-weight: 600; margin: .5rem 0; min-height: 3.2em; line-height: 1.5; }
.result.yes { color: #0a7d33; }
.result.no { color: #c92f3c; }
.result .antideriv { font: 700 15px ui-monospace, monospace; display: block; margin-top: .25rem; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// Mini decision procedure: for each curated integrand, classify it as elementary (with an explicit antiderivative) or non-elementary (with a Liouville-style reason), mirroring what the real Risch algorithm decides in general.
// Catalog of integrands with their ground-truth classification (all are textbook results, not guesses).
const INTEGRANDS = [
{ id: 'x3', fn: 'x^3', elementary: true, antideriv: 'x^4 / 4',
why: 'why_x3' },
{ id: 'invx', fn: '1/x', elementary: true, antideriv: 'ln|x|',
why: 'why_invx' },
{ id: 'atan', fn: '1/(1+x^2)', elementary: true, antideriv: 'arctan(x)',
why: 'why_atan' },
{ id: 'xexp', fn: 'x * e^(x^2)', elementary: true, antideriv: '(1/2) e^(x^2)',
why: 'why_xexp' },
{ id: 'gauss', fn: 'e^(-x^2)', elementary: false, antideriv: null,
why: 'why_gauss' },
{ id: 'sinc', fn: 'sin(x) / x', elementary: false, antideriv: null,
why: 'why_sinc' },
{ id: 'logint', fn: '1 / ln(x)', elementary: false, antideriv: null,
why: 'why_logint' },
];
let selected = null;
// Render the list of selectable integrands, highlighting the current selection.
function renderPicker(){
const p = document.getElementById('picker'); p.innerHTML = '';
INTEGRANDS.forEach(item => {
const row = document.createElement('div');
row.className = 'opt' + (selected === item.id ? ' sel' : '');
row.innerHTML = '<span class="fn">∫ ' + item.fn + ' dx</span>';
row.addEventListener('click', () => { selected = item.id; renderPicker(); setResult('Pick an integrand above, then click Decide.', ''); });
p.appendChild(row);
});
}
function setResult(html, cls){
const r = document.getElementById('result');
r.innerHTML = html; r.className = 'result ' + cls;
}
// On Decide: look up the selected integrand and report yes/no plus the reason, exactly as the real algorithm would certify a result or a non-existence proof.
function decide(){
if (!selected){ setResult('Pick an integrand first.', 'no'); return; }
const item = INTEGRANDS.find(i => i.id === selected);
if (item.elementary){
setResult(fmt('✓ Yes — %fn% has an elementary antiderivative:', { fn: item.fn }) +
'<span class="antideriv">∫ ' + item.fn + ' dx = ' + item.antideriv + ' + C</span>' +
'<br>' + WHY[item.why], 'yes');
} else {
setResult(fmt('✗ No — %fn% provably has <b>no</b> elementary antiderivative.', { fn: item.fn }) + '<br>' + WHY[item.why], 'no');
}
console.log('Integrand:', item.fn, '->', item.elementary ? 'elementary antiderivative exists' : 'no elementary antiderivative (proved)');
}
// Map from reason keys to their explanatory text, shown alongside the verdict.
const WHY = {
why_x3: 'Plain power rule: raise the exponent and divide.',
why_invx: 'The one exception to the power rule; its antiderivative is a logarithm, not another power.',
why_atan: 'A standard elementary form — the derivative of arctan(x) is exactly 1/(1+x^2).',
why_xexp: 'The leading x is exactly (1/2) of the derivative of the exponent x^2, so the substitution u = x^2 closes the integral immediately.',
why_gauss: 'No polynomial factor multiplies e^(-x^2) here to match the derivative of -x^2 (which is -2x). Liouville’s theorem shows any antiderivative would need a brand-new logarithmic term that cannot exist — this is exactly why the error function erf(x) had to be invented.',
why_sinc: 'A classical case with no elementary closed form; its antiderivative is named the sine integral, Si(x), precisely because no elementary formula exists.',
why_logint: 'Another classical non-elementary integral; its antiderivative is named the logarithmic integral, li(x).',
};
document.getElementById('decide').addEventListener('click', decide);
document.getElementById('reset').addEventListener('click', () => { selected = null; renderPicker(); setResult('Pick an integrand above, then click Decide.', ''); });
renderPicker();
<p class="hint">Pick an integrand and click <b>Decide</b>. A simplified version of the Risch machinery reports whether an elementary antiderivative exists — and produces it when it does, or explains why none can when it doesn’t.</p>
<div class="picker" id="picker"></div>
<div class="btns">
<button id="decide" type="button">Decide</button>
<button id="reset" type="button" class="ghost">Clear</button>
</div>
<div class="result" id="result">Pick an integrand above, then click Decide.</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .7rem; line-height: 1.45; }
.picker { display: flex; flex-direction: column; gap: .4rem; margin: .4rem 0 .8rem; }
.opt { display: flex; align-items: center; gap: .55rem; padding: .5rem .7rem; border: 1px solid #cdd9e3;
border-radius: 8px; background: #f4f7f9; cursor: pointer; transition: all .1s; }
.opt:hover { background: #e8eef3; }
.opt.sel { background: #1d3557; border-color: #1d3557; color: #fff; }
.opt .fn { font: 700 15px ui-monospace, monospace; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .6rem; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
.result { font-size: .95rem; font-weight: 600; margin: .5rem 0; min-height: 3.2em; line-height: 1.5; }
.result.yes { color: #0a7d33; }
.result.no { color: #c92f3c; }
.result .antideriv { font: 700 15px ui-monospace, monospace; display: block; margin-top: .25rem; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// Mini decision procedure: for each curated integrand, classify it as elementary (with an explicit antiderivative) or non-elementary (with a Liouville-style reason), mirroring what the real Risch algorithm decides in general.
// Catalog of integrands with their ground-truth classification (all are textbook results, not guesses).
const INTEGRANDS = [
{ id: 'x3', fn: 'x^3', elementary: true, antideriv: 'x^4 / 4',
why: 'why_x3' },
{ id: 'invx', fn: '1/x', elementary: true, antideriv: 'ln|x|',
why: 'why_invx' },
{ id: 'atan', fn: '1/(1+x^2)', elementary: true, antideriv: 'arctan(x)',
why: 'why_atan' },
{ id: 'xexp', fn: 'x * e^(x^2)', elementary: true, antideriv: '(1/2) e^(x^2)',
why: 'why_xexp' },
{ id: 'gauss', fn: 'e^(-x^2)', elementary: false, antideriv: null,
why: 'why_gauss' },
{ id: 'sinc', fn: 'sin(x) / x', elementary: false, antideriv: null,
why: 'why_sinc' },
{ id: 'logint', fn: '1 / ln(x)', elementary: false, antideriv: null,
why: 'why_logint' },
];
let selected = null;
// Render the list of selectable integrands, highlighting the current selection.
function renderPicker(){
const p = document.getElementById('picker'); p.innerHTML = '';
INTEGRANDS.forEach(item => {
const row = document.createElement('div');
row.className = 'opt' + (selected === item.id ? ' sel' : '');
row.innerHTML = '<span class="fn">∫ ' + item.fn + ' dx</span>';
row.addEventListener('click', () => { selected = item.id; renderPicker(); setResult('Pick an integrand above, then click Decide.', ''); });
p.appendChild(row);
});
}
function setResult(html, cls){
const r = document.getElementById('result');
r.innerHTML = html; r.className = 'result ' + cls;
}
// On Decide: look up the selected integrand and report yes/no plus the reason, exactly as the real algorithm would certify a result or a non-existence proof.
function decide(){
if (!selected){ setResult('Pick an integrand first.', 'no'); return; }
const item = INTEGRANDS.find(i => i.id === selected);
if (item.elementary){
setResult(fmt('✓ Yes — %fn% has an elementary antiderivative:', { fn: item.fn }) +
'<span class="antideriv">∫ ' + item.fn + ' dx = ' + item.antideriv + ' + C</span>' +
'<br>' + WHY[item.why], 'yes');
} else {
setResult(fmt('✗ No — %fn% provably has <b>no</b> elementary antiderivative.', { fn: item.fn }) + '<br>' + WHY[item.why], 'no');
}
console.log('Integrand:', item.fn, '->', item.elementary ? 'elementary antiderivative exists' : 'no elementary antiderivative (proved)');
}
// Map from reason keys to their explanatory text, shown alongside the verdict.
const WHY = {
why_x3: 'Plain power rule: raise the exponent and divide.',
why_invx: 'The one exception to the power rule; its antiderivative is a logarithm, not another power.',
why_atan: 'A standard elementary form — the derivative of arctan(x) is exactly 1/(1+x^2).',
why_xexp: 'The leading x is exactly (1/2) of the derivative of the exponent x^2, so the substitution u = x^2 closes the integral immediately.',
why_gauss: 'No polynomial factor multiplies e^(-x^2) here to match the derivative of -x^2 (which is -2x). Liouville’s theorem shows any antiderivative would need a brand-new logarithmic term that cannot exist — this is exactly why the error function erf(x) had to be invented.',
why_sinc: 'A classical case with no elementary closed form; its antiderivative is named the sine integral, Si(x), precisely because no elementary formula exists.',
why_logint: 'Another classical non-elementary integral; its antiderivative is named the logarithmic integral, li(x).',
};
document.getElementById('decide').addEventListener('click', decide);
document.getElementById('reset').addEventListener('click', () => { selected = null; renderPicker(); setResult('Pick an integrand above, then click Decide.', ''); });
renderPicker();
Comments
Loading comments...