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
    use ../MathML.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]
    rows = max[length[splitLines[equations]]+1, 8]
    solveFor = solveFor ? trim[solveFor] : undef
    solveStr = HTMLEncode[solveFor]
    wchecked = w ? "CHECKED" : ""
    f = f ? f : ""
    fchecked = (f=="f" or f=="on") ? "CHECKED" : ""
    mchecked = f=="m" ? "CHECKED" : ""
    nchecked = f==""  ? "CHECKED" : ""
    evchecked = ev ? "CHECKED" : ""
    conformalChecked = conformal ? "CHECKED" : ""
    solvedChecked = solved ? "CHECKED" : ""
    showorigChecked = showorig ? "CHECKED" : ""
    if resultAs
      resultAs = trim[resultAs]
    resultAsQuoted = resultAs ? HTMLEncodeQuoted[resultAs] : ""
    extra = """ class="big" """  // MathML format
%>

 <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="$rows" COLS="80" autocapitalize="none" autocorrect="none" spellcheck="false"
                             NAME="equations" ID="equations">$eqStr</TEXTAREA>
        <TR><TD CLASS="noborder"><LABEL FOR="solveFor">Solve&nbsp;for:&nbsp;</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">Show output as:
              <INPUT TYPE="RADIO" NAME="f" ID="fnone" VALUE="" $nchecked onChange="this.form.submit();"><LABEL FOR="fnone">Default</LABEL>
              <INPUT TYPE="RADIO" NAME="f" ID="f" VALUE="f" $fchecked onChange="this.form.submit();"><LABEL FOR="f">Raw Frink notation</LABEL>
              <INPUT TYPE="RADIO" NAME="f" ID="m" VALUE="m" $mchecked onChange="this.form.submit();"><LABEL FOR="m">MathML</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>"]
           if f=="m"
              println["<DIV CLASS=\"back\">"]
           else
              println["<P CLASS=\"code\"><CODE>"]
              
           for eq = eqs
              if f=="f"
                 println[HTMLEncode[inputFormUnicode[eq]] + "<BR>"]
              else
                 if f=="m"
                 {
                    if structureEquals[noEval[_a===_b], eq]
                        eq = substituteExpression[eq, noEval[_a===_b], noEval[_a=_b]]
                    println[MathML.format[eq, true, 0, extra]+ "<BR><BR>"]
                 } else   
                    println[formatExpressionSymbolic[inputFormUnicode[eq]] + "<BR>"]
           if f=="m"
              println["</DIV>"]
           else
              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["""<BR><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"></DIV>"""]
 
 
           if f=="m"
              println["<BR><DIV CLASS=\"back\">"]
           else
              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=="f"
                        preamble = preamble + HTMLEncode[inputFormUnicode[getChild[eq1,1]]] + "<BR>" 
                     else
                        if f=="m"
                           preamble = preamble + MathML.format[getChild[eq1,1], true, 0, extra] + "<BR>"
                        else
                           preamble = preamble + formatExpressionSymbolic[inputFormUnicode[getChild[eq1,1]]] + "<BR>"
                    preamble = preamble + repeat["&nbsp;", 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 == "f"
                     preamble = preamble + HTMLEncode[inputFormUnicode[part]] + "<BR>" + repeat["&nbsp;", varlen + 1]  + "= "
                 else
                   if f == "m"
                       preamble = preamble + MathML.format[part, true, 0, extra] + "<BR>" + repeat["&nbsp;", varlen + 1]  + "= "
                   else
                        preamble = preamble + formatExpressionSymbolic[inputFormUnicode[part]] + "<BR>" + repeat["&nbsp;", 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/&nbsp;/g
              } else
              {
                 if conformal && isVariableDefined[resultAs] and resultAs != ""
                 {
                    suppressed = suppressed + 1
                    next RESULT
                 }
                 if f == "f"
                    result = HTMLEncode[inputFormUnicode[pe]]
                 else
                    if f == "m"
                       result = MathML.format[pe, true, 0, extra]
                    else
                       if solved
                          result = formatExpression[outputForm[pe]]
                       else
                          result = formatExpressionSymbolic[inputFormUnicode[pe]]
              }

              println[preamble]
              println[result + "<BR>"]
              if eqn < length[results]-1
                 println["<BR>"]
           }
           if f=="m"
              println["</DIV>"]
           else
              println["</CODE></P>"]
           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 19963 days, 5 hours, 16 minutes ago.

Back to Frink Server Pages documentation.