solve2.fsp - Frink Server Pages highlighter
[Try solve2.fsp]
<!DOCTYPE html>
<HTML LANG="en">
<HEAD>
<TITLE>Frink System Solver</TITLE>
<META HTTP-EQUIV="Default-Style" CONTENT="Spaceship">
<LINK REL="StyleSheet" HREF="/frinkdocs/spaceship.css"
TYPE="text/css" TITLE="Spaceship">
<LINK REL="Alternate StyleSheet" HREF="/frinkdocs/apeairy.css"
TYPE="text/css" TITLE="APE Airy">
<LINK REL="Alternate StyleSheet" HREF="/frinkdocs/style.css" TYPE="text/css"
TITLE="APE Classic">
<LINK REL="Alternate StyleSheet" HREF="/frinkdocs/style2.css" TYPE="text/css"
TITLE="Compact">
<LINK REL="icon" HREF="/images/futureboyicon.png" TYPE="image/png">
<META NAME="viewport" CONTENT="width=device-width, initial-scale=1.0">
<LINK REL="canonical" HREF="https://frinklang.org/fsp/solve2.fsp">
</HEAD>
<%
use ../
systemSolver2.frink
use ../
HTMLUtils.frink
// showApproximations[false]
symbolicMode[true]
if !isVariableDefined["equations"]
ev = true
// equations = equations ? equations : "x^2 + 3x - 2 + 4y + 3y^2 = 3x - y + 10"
eqStr = HTMLEncode[equations]
solveFor = solveFor ? trim[solveFor] : undef
solveStr = HTMLEncode[solveFor]
wchecked = w ? "CHECKED" : ""
fchecked = f ? "CHECKED" : ""
evchecked = ev ? "CHECKED" : ""
conformalChecked = conformal ? "CHECKED" : ""
solvedChecked = solved ? "CHECKED" : ""
showorigChecked = showorig ? "CHECKED" : ""
if resultAs
resultAs = trim[resultAs]
resultAsQuoted = resultAs ? HTMLEncodeQuoted[resultAs] : ""
%>
<BODY onLoad="document.f1.equations.focus()">
<H1>Frink System Solver</H1>
<FORM ACTION="solve2.fsp" METHOD="GET" NAME="f1">
<DIV CLASS="back">
<TABLE BORDER="0" SUMMARY="Equation input">
<TR><TD CLASS="noborder" COLSPAN="2"><LABEL FOR="equation">Equations (one per line):</LABEL>
<TR><TD CLASS="noborder" COLSPAN="2"><TEXTAREA WRAP="off" ROWS="8" COLS="80" autocapitalize="none" autocorrect="none" spellcheck="false"
NAME="equations" ID="equations">$eqStr
</TEXTAREA>
<TR><TD CLASS="noborder"><LABEL FOR="solveFor">Solve for: </LABEL><INPUT TYPE="text" SIZE="5" autocapitalize="none" autocorrect="none" spellcheck="false"
NAME="solveFor" ID="solveFor" VALUE="$solveStr
"> (<I>leave blank for all</I>)
<!-- <TR><TD class="noborder" COLSPAN="2"><INPUT TYPE="CHECKBOX" NAME="w" ID="w" $wchecked
onChange="this.form.submit();"><LABEL FOR="w">Show work</LABEL> -->
<TR><TD CLASS="noborder" COLSPAN="2"><INPUT TYPE="CHECKBOX" NAME="f" ID="f" $fchecked
onChange="this.form.submit();"><LABEL FOR="f">Output in raw Frink notation</LABEL>
<TR><TD CLASS="noborder" COLSPAN="2"><INPUT TYPE="CHECKBOX" NAME="ev" ID="ev" $evchecked
onChange="this.form.submit();"><LABEL FOR="ev">Evaluate result numerically</LABEL>
<TR><TD CLASS="noborder" COLSPAN="2"><INPUT TYPE="Submit" VALUE="Solve">
</TABLE>
</DIV>
<%
if isVariableDefined[equations] and trim[equations] != ""
{
if (equations =~ %r/=/)
{
equations =~ %s/=/===/g
equations =~ %s/^\s*\/\/(.*)//mg // Skip commented-out lines
equations =~ %s/^[\r\n\s]+//s // Remove leading whitespace
equations =~ %s/[\r\n\s]+$//s // Remove trailing whitespace
equations =~ %s/[\r\n]+/,/sg
// println[equations]
str = "new System[[$equations
], []]"
// println[str]
system = unsafeEval[str]
// println[system]
eqs = system.solveAll[]
if solveFor
eqs = system.solveFor[solveFor]
println["<P><B>Solution:</B></P><P CLASS=\"code\"><CODE>"]
for eq = eqs
if f
println[HTMLEncode[inputFormUnicode[eq]] + "<BR>"]
else
println[formatExpressionSymbolic[inputFormUnicode[eq]] + "<BR>"]
println["</CODE></P>"]
} else
{
println["<P><I>No equals sign present. This is probably not a system of equations. </I></P>"]
}
}
/* All of the following code is to detect variable names in the
resulting solutions and create HTML forms to allow the user to
optionally plug in values for each variable (or leave them symbolic)
and evaluate the result symbolically and numerically. */
if isVariableDefined["equations"] and trim[equations] != "" and ev // Evaluate result?
{
println["""<DIV CLASS="back"><P><A NAME="Evaluated"><B>Evaluated result:</B></A></P>"""]
symbols = new set
for eq = eqs
symbols = union[symbols, getSymbols[eq]]
symbols.remove[solveFor]
repstr = ""
repls = new array
println["""<TABLE BORDER=1 STYLE="width: 100%"><TR><TH>Sym<TH>Symbolic?<TH>Value"""]
for sym = lexicalSort[symbols]
{
selvar = "sel_$sym
"
varname = "val_$sym
"
sch = eval[selvar] == "S" ? "checked" : ""
lch = eval[selvar] == "L" ? "checked" : ""
if (! sch AND ! lch)
sch = "checked"
if sch
repstr = repstr + "$sym
= noEval[$sym
]\n"
if lch
repls.push[ [constructExpression["Symbol",[sym]], eval[eval[varname]]]]
val = eval[varname] ? eval[varname] : (unit[sym] != undef ? eval[sym] : "")
valstr = HTMLEncodeQuoted[isString[val] ? val : inputFormUnicode[val]]
println[" <TR>"]
println[""" <TD>$sym
="""]
println[""" <TD><INPUT TYPE="RADIO" NAME="$selvar
" ID="${selvar}
_S" VALUE="S" $sch
><LABEL FOR="${selvar}
_S">$sym
</LABEL>"""]
println[""" <TD><INPUT TYPE="RADIO" NAME="$selvar
" ID="${selvar}
_L" VALUE="L" $lch
>"""]
print[""" <INPUT TYPE="TEXT" autocapitalize="none" autocorrect="none" spellcheck="false" NAME="$varname
" VALUE="$valstr
" STYLE="width: 90%; box-sizing: border-box" oninput="if (this.value.trim().length != 0) {document.getElementById('${selvar}
_L').checked=true} else {document.getElementById('${selvar}
_S').checked=true; this.value=' '}">"""]
}
println["</TABLE>"]
println["""<BR>(Optional) Show result in units: <INPUT TYPE="TEXT" NAME="resultAs" ID="resultAs" VALUE="$resultAsQuoted
" autocapitalize="none" autocorrect="none" spellcheck="false"><BR>"""]
println[""" <INPUT TYPE="CHECKBOX"
NAME="conformal" ID="conformal" $conformalChecked
onChange="this.form.submit();"><LABEL FOR="conformal">Conformal</LABEL><BR>"""]
println[""" <INPUT TYPE="CHECKBOX"
NAME="solved" ID="solved" $solvedChecked
onChange="this.form.submit();"><LABEL FOR="solved">Fully solved</LABEL><BR>"""]
println[""" <INPUT TYPE="CHECKBOX"
NAME="showorig" ID="showorig" $showorigChecked
onChange="this.form.submit();"><LABEL FOR="showorig">Show original equation</LABEL><BR>"""]
println["""<INPUT TYPE="Submit" VALUE="Solve">"""]
println["""<P CLASS="code"><CODE>"""]
resultAs = resultAs ? trim[resultAs] : ""
if isVariableDefined[resultAs] and resultAs != ""
{
// If resultAs has a comma like "ft, in" or "[ft, in]", or
// with quoted terms such as ["ft", "in"], then just canonify
// it to ["ft", "in"] or if it has a zero, leave that unquoted
// like ["ft", "in", 0]
// TODO: Turn this into a function
if resultAs =~ %r/,/
{
// Remove square brackets and quotes
resultAs =~ %s/[\[\]"]//g
resultAsArray = new array
for resa = split[",", resultAs] // Split on commas
{
resa = trim[resa]
if resa == "0" // Preserve literal 0 unquoted.
resultAsArray.push[0]
else
resultAsArray.push[resa]
}
resultAs = resultAsArray
}
}
//results = flatten[toArray[last]]
results = eqs
suppressed = 0
RESULT:
for eqn = rangeOf[results]
{
eq1 = results@eqn
varlen = 1
// Evaluate right-hand sides of solved equations
preamble = ""
// This matches a solved equation
if structureEquals[_a === _b, eq1]
{
preamble = preamble + getChild[eq1, 0] + " = "
part = getChild[eq1, 1]
varlen = length[inputFormUnicode[getChild[eq1,0]]]
if showorig
{
if f
preamble = preamble + HTMLEncode[inputFormUnicode[getChild[eq1,1]]] + "<BR>"
else
preamble = preamble + formatExpressionSymbolic[inputFormUnicode[getChild[eq1,1]]] + "<BR>"
preamble = preamble + repeat[" ", varlen] + " = "
}
} else
part = eq1
for [e1, e2] = repls
part = substituteExpression[part, e1, e2]
repstr2 = repstr + inputFormUnicode[part]
pe = eval[repstr2, false, true]
// println["pe=$pe
, type=" + type[pe] + ", resultAs=$resultAs
, eval=" + eval[eval[resultAs]]]
if ! structureEquals[pe, part]
if f
preamble = preamble + HTMLEncode[inputFormUnicode[part]] + "<BR>" + repeat[" ", varlen + 1] + "= "
else
preamble = preamble + formatExpressionSymbolic[inputFormUnicode[part]] + "<BR>" + repeat[" ", varlen + 1] + "= "
if solved && !isUnit[pe]
{
suppressed = suppressed + 1
next RESULT
}
if isVariableDefined[resultAs] and resultAs != "" and isUnit[pe]
{
if conformal
if ! (pe conforms eval[eval[resultAs]])
{
suppressed = suppressed + 1
next RESULT
}
if pe conforms eval[eval[resultAs]]
result = (pe -> resultAs)
else
result = inputFormUnicode[pe]
result = HTMLEncode[result]
result = formatExpression[result]
result =~ %s/\n/<BR>\n/mg
result =~ %s/\s/ /g
} else
{
if conformal && isVariableDefined[resultAs] and resultAs != ""
{
suppressed = suppressed + 1
next RESULT
}
if f
result = HTMLEncode[inputFormUnicode[pe]]
else
if solved
result = formatExpression[outputForm[pe]]
else
result = formatExpressionSymbolic[inputFormUnicode[pe]]
}
println[preamble]
println[result + "<BR>"]
if eqn < length[results]-1
println["<BR>"]
}
println["</CODE>"]
if (suppressed > 0)
println["<I>$suppressed
items suppressed because of above options.</I>"]
println["</P></DIV></FORM>"]
}
%>
<HR>
<P>
<A HREF="solve2.fsp" TARGET="_blank">Open new blank solver</A>
</P>
<P>
View source of <A HREF="highlight.fsp?f=solve2.fsp">this FSP page</A> or the <A HREF="colorize.fsp?f=allTransforms.frink">transformation rules</A> that solve these equations.
</P>
<P>
<I><A HREF="mailto:eliasen@mindspring.com">Alan Eliasen</A></I> was born
<%= round[now[] - #1969-08-19 04:54 PM Mountain#, minute] -> ["days", "hours", "minutes"] %>
ago.
</P>
<P>
Back to <A HREF="/frinkdocs/fspdocs.html">Frink Server Pages
documentation.</A>
</P>
</BODY>
</HTML>
[Try solve2.fsp]
Alan Eliasen was born
19527 days, 17 hours, 8 minutes ago.
Back to Frink Server Pages
documentation.