solve.fsp - Frink Server Pages highlighter

[Try solve.fsp]

<!DOCTYPE html>
<HTML LANG="en">
 <HEAD>
  <TITLE>Frink Solver</TITLE>
  <META NAME="viewport" CONTENT="width=device-width, initial-scale=1.0">
  <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">
  <LINK REL="canonical" HREF="https://frinklang.org/fsp/solve.fsp">
 </HEAD>
<% 
    use ../solvingTransformations.frink
    use ../powerTransformations.frink
    use ../derivatives.frink
    use ../integrals.frink
    use ../BooleanTransformations.frink
    use ../HTMLUtils.frink

    symbolicMode[true]

    if  ! isVariableDefined["equation"] && ! isVariableDefined["eq"]
        ev = "on"

    if ! isVariableDefined["equation"]
       if isVariableDefined["eq"]
          equation = eq  // Moving to use variable "eq" for shorter URLs.
 
    if (!equation)
    {
equation = "h = h0 + Integrate[v0, t] + Integrate[-gravity, t, 2]"
        solveFor = "h"
    }
    eqStr = HTMLEncodeQuoted[equation]
    solveFor = solveFor ? trim[solveFor] : ""
    solveStr = HTMLEncodeQuoted[solveFor]
    wchecked = w ? "CHECKED" : ""
    fchecked = f ? "CHECKED" : ""
    evchecked = ev ? "CHECKED" : ""
    resultAsQuoted = resultAs ? HTMLEncodeQuoted[resultAs] : ""
%>

 <BODY>
  <H1>Frink Solver</H1>
  <FORM ACTION="solve.fsp" METHOD="GET">
  <DIV CLASS="back">
      <TABLE BORDER="0" SUMMARY="Equation input">
        <TR><TD><LABEL FOR="eq">Equation:</LABEL>
        <INPUT TYPE="text" NAME="eq" 
         STYLE="width: 100%; box-sizing: border-box" SIZE="40" ID="eq"
         VALUE="$eqStr" autocapitalize="none" autocorrect="none" 
         oninput="document.getElementById('resultAs').value=''">
        <TR><TD><LABEL FOR="solveFor">Solve&nbsp;for:&nbsp;</LABEL><INPUT TYPE="text" SIZE="15" autocapitalize="none" autocorrect="none" NAME="solveFor"
        ID="solveFor" VALUE="$solveStr" oninput="document.getElementById('resultAs').value=''">
        <TR><TD COLSPAN="2"><INPUT TYPE="CHECKBOX" NAME="w" ID="w" $wchecked
        onChange="this.form.submit();"><LABEL FOR="w">Show work</LABEL>
        <TR><TD 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 COLSPAN="2"><INPUT TYPE="CHECKBOX" NAME="ev" ID="ev" $evchecked
    onChange="this.form.submit();"><LABEL FOR="ev">Evaluate result numerically</LABEL>
        <TR><TD COLSPAN="2"><INPUT TYPE="Submit" VALUE="Solve">
      </TABLE>
  </DIV>        
<%
    if (equation)
    {
        if (equation =~ %r/=/)
        {
           equation =~ %s/=/===/
           expr = parseToExpression["solve[$equation,$solveFor]"]
        } else
        {
           println["<P><I>No equals sign present.  Will not solve equation, but just evaluate the expression.</I></P>"]
           expr = parseToExpression[equation]
        }

        println["<P><B>Solution:</B></P><P CLASS=\"code\"><CODE>"]
        last = undef
        if w  // Show work?
        {
           res = array[transformExpressionTrace[expr]]
           if f
              println[removeApproximations[join["<BR><BR>",res]]]
           else
              println[formatExpressionSymbolic[join["<BR><BR>",res]]]

           last = res@(length[res]-1)
        } else
        {  // Don't show work
           res = array[transformExpression[expr]]
           if f
              println[removeApproximations[join["<BR>",res]]]
           else
              println[formatExpressionSymbolic[join["<BR>",res]]]

           last = res
        }
        println["</CODE></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 ev  // Evaluate result?
        {
           println["""<DIV CLASS="back"><P><B>Evaluated result:</B></P>"""]

           symbols = getSymbols[last]
           symbols.remove[solveFor]
           repstr = ""
           repls = new array
  
           println["""<TABLE BORDER=1 STYLE="width: 100%"><TR><TH>Sym<TH>Symbolic?<TH>Value"""]
           for sym = 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 : inputForm[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" NAME="$varname" VALUE="$valstr" STYLE="width: 100%; box-sizing: border-box" oninput="document.getElementById('${selvar}_L').checked=true">"""]
           }
           println["</TABLE>"]
           println["""<BR>(Optional) Show result in units: <INPUT TYPE="TEXT" NAME="resultAs" ID="resultAs" VALUE="$resultAsQuoted" autocapitalize="none" autocorrect="none">"""]
           println["""<BR><INPUT TYPE="Submit" VALUE="Solve">"""]
           println["""<P CLASS="code"><CODE>"""]
           for eq1 = toArray[last]
           {
              varlen = 1
              // Evaluate right-hand sides of solved equations
              if structureEquals[_a === _b, eq1]
              {
                 print[getChild[eq1, 0] + " = "]
                 part = getChild[eq1, 1]
                 varlen = length[inputForm[getChild[eq1,0]]]
              }  else
                 part = eq1

              for [e1, e2] = repls
                 part = substituteExpression[part, e1, e2]
  
              repstr2 = repstr + inputForm[part]
              pe = eval[repstr2, false, true]
              if ! structureEquals[pe, part]
                 print[inputForm[part] + "<BR>" + repeat["&nbsp;", varlen + 1]  + "= "]
              if isVariableDefined[resultAs] and trim[resultAs] != "" and isUnit[pe]
              {
                 result = pe -> resultAs
                 result = HTMLEncode[result]
                 result =~ %s/\n/<BR>\n/mg
                 result =~ %s/\s/&nbsp;/g
              } else
                 result = HTMLEncode[inputForm[pe]]

              println[result + "<BR><BR>"]
           }
           println["</CODE></P></DIV>"]
        }
     }
%>
  
  </FORM>
  <HR>
  <P>
   View source of <A HREF="highlight.fsp?f=solve.fsp">this FSP page</A>.  This
   is a program written in the programming language <A
   HREF="https://frinklang.org/">Frink</A>.
  </P>
  <P>
   <I>Contact <A HREF="mailto:eliasen@mindspring.com">Alan Eliasen</A></I>
  </P>

  <P>
   Back to <A HREF="/frinkdocs/fspdocs.html">Frink Server Pages
    documentation.</A>
  </P>  
 </BODY>
</HTML>

[Try solve.fsp]


Alan Eliasen was born 17840 days, 1 hours, 0 minutes ago.

Back to Frink Server Pages documentation.