summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/luacas/doc
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-11-06 03:01:22 +0000
committerNorbert Preining <norbert@preining.info>2022-11-06 03:01:22 +0000
commit0a7c9b85de9aeaffafa0cf8944fa81ffe9652d09 (patch)
treea8a932b3f786cf3601808c4e352b3b6b07731742 /macros/luatex/latex/luacas/doc
parent5a47812f51f3d10a580db0c74aa20d73f5ed2ae4 (diff)
CTAN sync 202211060301
Diffstat (limited to 'macros/luatex/latex/luacas/doc')
-rw-r--r--macros/luatex/latex/luacas/doc/appendix/latexcode.tex140
-rw-r--r--macros/luatex/latex/luacas/doc/appendix/luacas.dat230
-rw-r--r--macros/luatex/latex/luacas/doc/intro/intro.tex143
-rw-r--r--macros/luatex/latex/luacas/doc/intro/intropart.tex202
-rw-r--r--macros/luatex/latex/luacas/doc/luacas.pdfbin0 -> 758211 bytes
-rw-r--r--macros/luatex/latex/luacas/doc/luacas.tex214
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref.tex236
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra.tex336
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_classes/ref_algebra_classes.tex977
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_methods/ref_algebra_methods.tex1305
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus.tex225
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_classes/ref_calculus_classes.tex277
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_methods/ref_calculus_methods.tex473
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_core/ref_core.tex249
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex455
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_methods/ref_core_methods.tex1155
-rw-r--r--macros/luatex/latex/luacas/doc/tutorial/tut.tex217
-rw-r--r--macros/luatex/latex/luacas/doc/tutorial/tut1/tut1.tex238
-rw-r--r--macros/luatex/latex/luacas/doc/tutorial/tut2/tut2.tex476
-rw-r--r--macros/luatex/latex/luacas/doc/tutorial/tut3/demotut3.dat46
-rw-r--r--macros/luatex/latex/luacas/doc/tutorial/tut3/tut3.tex575
21 files changed, 8169 insertions, 0 deletions
diff --git a/macros/luatex/latex/luacas/doc/appendix/latexcode.tex b/macros/luatex/latex/luacas/doc/appendix/latexcode.tex
new file mode 100644
index 0000000000..1f8ccd7471
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/appendix/latexcode.tex
@@ -0,0 +1,140 @@
+\documentclass{article}
+
+\usepackage{standalone}
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\begin{document}
+
+\section{The \LaTeX{} code}
+
+As noted above, this package is really a Lua program; the package {\ttfamily luacas.sty} is merely a shell to make accessing that Lua program easy and manageable from within \LaTeX{}.
+\inputminted[
+ firstline=12,
+ lastline=14,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+We check to make sure the user is compiling with Lua\LaTeX{}; if not, an error message is printed and compilation is aborted.
+
+\inputminted[
+ firstline=16,
+ lastline=24,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+The following packages are required for various macros:
+
+\inputminted[
+ firstline=27,
+ lastline=32,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+The files \verb|helper.lua| and \verb|parser.lua| help bridge the gap between the Lua program and \LaTeX{}.
+
+\inputminted[
+ firstline=35,
+ lastline=37,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+We now define the \mintinline{latex}{\begin{CAS}..\end{CAS}} environment:
+
+\inputminted[
+ firstline=39,
+ lastline=42,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+{\bf Note:} The contents are wrapped in the function \mintinline{lua}{CASparse()}. We now define the retrieving macros \mintinline{latex}{\get}, \mintinline{latex}{\fetch}, and \mintinline{latex}{\store}:
+
+\inputminted[
+ firstline=44,
+ lastline=67,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+And now we define the printing macros \mintinline{latex}{\print}, \mintinline{latex}{\vprint}, and \mintinline{latex}{\lprint}:
+
+\inputminted[
+ firstline=75,
+ lastline=128,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+And finally, we define the macros useful for printing expression trees:
+
+\inputminted[
+ firstline=130,
+ lastline=230,
+ breaklines,
+ linenos,
+ numbersep=5pt]
+ {latex}
+ {luacas.dat}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/appendix/luacas.dat b/macros/luatex/latex/luacas/doc/appendix/luacas.dat
new file mode 100644
index 0000000000..60866bae05
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/appendix/luacas.dat
@@ -0,0 +1,230 @@
+% Copyright (c) ???
+%
+% Permission is granted to copy, distribute and/or modify this
+% software under the terms of the LaTeX Project Public License
+% (LPPL), version 1.3c or any later version.
+%
+% This software is provided 'as is', without warranty of any kind,
+% either expressed or implied, including, but not limited to, the
+% implied warranties of merchantability and fitness for a
+% particular purpose.
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{luacas}
+ [2022/05/07 v1.0 CAS written in Lua for LaTeX]
+
+\RequirePackage{iftex}
+\ifluatex
+ \RequirePackage{luacode}
+\else
+ {\PackageError{luacas}
+ {Not running under LuaLaTeX}
+ {This package requires LuaLaTeX. Try compiling this document with\MessageBreak 'lualatex' instead of 'latex'. This is a fatal error; I'm aborting now.}%
+ }\stop
+\fi
+
+%Required Packages
+\RequirePackage{xparse}
+\RequirePackage{pgfkeys}
+\RequirePackage{verbatim}
+\RequirePackage{tikz}
+\RequirePackage{xcolor}
+\RequirePackage{mathtools}
+
+%These files contain Lua code for parsing luacas output; they also initialize the CAS itself
+\directlua{require('test.parser')
+ require('test.helper')
+}
+
+\NewDocumentEnvironment{CAS}%
+ {+b}%
+ {\luaexec{CASparse([[#1]])}}%
+ {}
+
+\newcommand{\get}%
+ [2][true]%
+ {\directlua{disp(#2, #1)}}
+
+\newcommand{\fetch}[1]{
+ \directlua{tex.print(tostring(#1))}
+}
+
+\NewDocumentCommand{\store}{m O{#1}}{
+ \expandafter\def\csname #2\endcsname{%
+ \directlua{
+ input = #1
+ if not input[1] then
+ tex.sprint{tostring(input)}
+ else
+ tex.sprint("{")
+ for _,entry in ipairs(input) do
+ tex.sprint(tostring(entry),",")
+ end
+ tex.sprint("}")
+ end
+ }%
+ }%
+}%
+
+%%%%%%%%%%
+%% Core %%
+%%%%%%%%%%
+
+%pretty print
+
+\NewDocumentCommand{\print}{s m}{%
+ \IfBooleanTF{#1}{%
+ \directlua{
+ local sym = #2
+ if sym then
+ tex.print(sym:autosimplify():tolatex())
+ else
+ tex.print('nil')
+ end
+ }%
+ }{%
+ \directlua{
+ local sym = #2
+ if sym then
+ tex.print(sym:tolatex())
+ else
+ tex.print('nil')
+ end
+ }%
+ }%
+}
+
+\NewDocumentCommand{\vprint}{s m}{%
+ \IfBooleanTF{#1}{%
+ \directlua{
+ local sym = #2
+ tex.sprint([[\unexpanded{\begin{verbatim}]] .. tostring(sym) .. [[\end{verbatim}}]])
+ }%
+ }{%
+ \directlua{
+ local sym = #2
+ tex.sprint([[\unexpanded{\begin{verbatim}]] .. tostring(sym:autosimplify()) .. [[\end{verbatim}}]])
+ }%
+ }%
+}
+
+\NewDocumentCommand{\lprint}{m O{nil,nil}}{%
+ \luaexec{
+ local tbl = #1
+ local low,upp = #2
+ local tmp =0
+ if tbl[0] == nil then
+ tmp = 1
+ end
+ upp = upp or \#tbl
+ low = low or tmp
+ for i=low,upp do
+ tex.print(tbl[i]:tolatex())
+ if tbl[i+1] then
+ tex.print(",")
+ end
+ end
+ }
+}
+
+%prints the first level of an expression tree; for use within a tikzpicture environment
+
+\NewDocumentCommand{\printshrub}{s m}{%
+ \IfBooleanTF{#1}{%
+ \directlua{
+ local sym = #2
+ sym = sym:autosimplify()
+ tex.print("\\node [label=90:", whatis(sym), "] {", nameof(sym), "}")
+ tex.print(sym:gettheshrub())
+ tex.print(";")
+ }%
+ }{%
+ \directlua{
+ local sym = #2
+ tex.print("\\node [label=90:", whatis(sym), "] {", nameof(sym), "}")
+ tex.print(sym:gettheshrub())
+ tex.print(";")
+ }%
+ }
+}
+
+%prints the full expression tree; for use within a tikzpicture environment
+
+\NewDocumentCommand{\printtree}{s m}{%
+ \IfBooleanTF{#1}{%
+ \luaexec{
+ local sym = #2
+ sym = sym:autosimplify()
+ tex.print("\\node {",nameof(sym),"}")
+ tex.print(sym:getthetree())
+ tex.print(";")
+ }%
+ }{%
+ \luaexec{
+ local sym = #2
+ tex.print("\\node {",nameof(sym),"}")
+ tex.print(sym:getthetree())
+ tex.print(";")
+ }%
+ }
+}
+
+%parses an expression tree for use within the forest environment; result is stored in \forestresult
+
+\NewDocumentCommand{\parseforest}{s m}{%
+ \IfBooleanTF{#1}{%
+ \luaexec{
+ local sym = #2
+ sym = sym:autosimplify()
+ tex.print("\\def\\forestresult{")
+ tex.print("[")
+ tex.print(nameof(sym))
+ tex.print(sym:gettheforest())
+ tex.print("]")
+ tex.print("}")
+ }%
+ }{%
+ \luaexec {
+ local sym = #2
+ tex.print("\\def\\forestresult{")
+ tex.print("[")
+ tex.print(nameof(sym))
+ tex.print(sym:gettheforest())
+ tex.print("]")
+ tex.print("}")
+ }%
+ }
+}
+
+\NewDocumentCommand{\parseshrub}{s m}{%
+ \IfBooleanTF{#1}{%
+ \luaexec{
+ local sym = #2
+ sym = sym:autosimplify()
+ tex.print("\\def\\shrubresult{")
+ tex.print("[")
+ tex.print(nameof(sym))
+ tex.print(", tikz+={\\node[anchor=south] at (.north) {test};}")
+ tex.print(sym:getthefancyshrub())
+ tex.print("]")
+ tex.print("}")
+ }%
+ }{%
+ \luaexec{
+ local sym = #2
+ tex.print("\\def\\shrubresult{")
+ tex.print("[")
+ tex.print(nameof(sym))
+ tex.print(", tikz+={\\node[anchor=south font=\\ttfamily\\footnotesize,gray] at (.north) {",longwhati (sym),"};}")
+ tex.print(sym:getthefancyshrub())
+ tex.print("]")
+ tex.print("}")
+ }%
+ }
+}
+
+\NewDocumentCommand{\whatis}{m}{%
+ \luaexec{
+ tex.sprint("{\\ttfamily",longwhatis(#1),"}")
+ }%
+} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/intro/intro.tex b/macros/luatex/latex/luacas/doc/intro/intro.tex
new file mode 100644
index 0000000000..bf77ffad04
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/intro/intro.tex
@@ -0,0 +1,143 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\begin{document}
+
+\section{What is \texttt{luacas}?}
+
+The package {\ttfamily luacas} allows for symbolic computation within \LaTeX{}. For example:
+\begin{CAS}
+ vars('x','y')
+ f = 3*x*y - x^2*y
+ fxy = diff(f,x,y)
+\end{CAS}
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','y')
+ f = 3*x*y - x^2*y
+ fxy = diff(f,x,y)
+\end{CAS}
+\end{minted}
+The above code will compute the mixed partial derivative $f_{xy}$ of the function $f$ defined by
+\[ f(x,y)=3xy-x^2y.\]
+There are various methods for fetching and/or printing results from the CAS within your \LaTeX{} document:
+
+\begin{codebox}
+\begin{minted}{latex}
+ \[ \print{fxy} = \print*{fxy} \]
+\end{minted}
+\tcblower
+\[ \print{fxy} = \print*{fxy} \]
+\end{codebox}
+
+\subsection{About}
+
+The core CAS program is written purely in Lua and integrated into \LaTeX{} via Lua\LaTeX{}. Currently, most existing computer algebra systems such as Maple and Mathematica allow for converting their stored expressions to \LaTeX{} code, but this still requires exporting code from \LaTeX{} to another program and importing it back, which can be tedious.
+
+The target audience for this package are mathematics students, instructors, and professionals who would like some ability to perform basic symbolic computations within \LaTeX{} without the need for laborious and technical setup. But truly, this package was born out of a desire from the authors to learn more about symbolic computation. What you're looking at here is the proverbial ``carrot at the end of the stick'' to keep our learning moving forward.
+
+Using a scripting language (like Lua) as opposed to a compiled language for the core CAS reduces performance dramatically, but the following considerations make it a good option for our intentions:
+
+\begin{itemize}
+ \item Compiled languages that can communicate with \LaTeX{} in some way (such as C through Lua) require compiling the code on each machine before running, reducing portability.
+ \item Our target usage would generally not involve computations that take longer than a second, such as factoring large primes or polynomials.
+ \item Lua is a fast scripting language, especially when compared to Python, and is designed to be compact and portable.
+ \item If C code could be used, we could tie into one of many open-source C symbolic calculators, but the point of this project was (and continues to be) to learn the mathematics of symbolic computation. The barebones but friendly nature of Lua made it an ideal language for those intents.
+\end{itemize}
+
+\subsection{Features}
+
+Currently, {\ttfamily luacas} includes the following functionality:
+
+\begin{itemize}
+ \item Arbitrary-precision integer and rational arithmetic
+ \item Number-theoretic algorithms for factoring integers and determining primality
+ \item Constructors for arbitrary polynomial rings and integer mod rings, and arithmetic algorithms for both
+ \item Factoring univariate polynomials over the rationals and over finite fields
+ \item Polynomial decomposition and some multivariate functionality, such as pseudodivision
+ \item Basic symbolic root finding and equation solving
+ \item Symbolic expression manipulations such as expansion, substitution, and simplification
+ \item Symbolic differentiation and integration
+\end{itemize}
+
+The CAS is written using object-oriented Lua, so it is modular and would be easy to extend its functionality.
+
+\subsection{Acknowledgements}
+
+We'd like to thank the faculty of the Department of Mathematics at Rose-Hulman Institute of Technology for offering constructive feedback as we worked on this project. A special thanks goes to Dr. Joseph Eichholz for his invaluable input and helpful suggestions.
+
+\section{Installation}
+
+\subsection{Requirements}
+
+The \texttt{luacas} package (naturally) requires you to compile with Lua\LaTeX{}. Lua 5.3 or higher is also required. Beyond that, the following packages are needed:
+\begin{multicols}{2}
+{\ttfamily
+\begin{itemize}
+ \item xparse
+ \item pgfkeys
+ \item verbatim
+ \item mathtools
+ \item luacode
+ \item iftex
+ \item tikz/forest
+ \item xcolor
+\end{itemize}}
+\end{multicols}
+The packages {\ttfamily tikz}, {\ttfamily forest}, and {\ttfamily xcolor} aren't strictly required, but they are needed for drawing expression trees.
+
+\subsection{Installing {\ttfamily luacas}}
+The package manager for your local TeX distribution ought to install the package fine on its own. But for those who like to take matters into their own hands: unpack \texttt{luacas.zip} in the current working directory (or in a directory visible to TeX, like your local texmf directory), and in the preamble of your document, put:
+\begin{minted}{latex}
+\usepackage{luacas}
+\end{minted}
+That's it, you're ready to go.
+
+\subsection{Todo}
+
+Beyond squashing bugs that inevitably exist in any new piece of software, future enhancements to \texttt{luacas} may include:
+\begin{itemize}
+ \item Improvements to existing functionality, e.g., a more powerful \texttt{simplify()} command and more powerful expression manipulation tools in general, particularly in relation to complex numbers, a designated class for multivariable polynomial rings, irreducible factorization over multivariable polynomial rings, and performance improvements;
+ \item New features in the existing packages, such as sum and product expressions \& symbolic evaluation of both, and symbolic differential equation solving;
+ \item New packages, such as for logic (boolean expressions), set theory (sets), and linear algebra (vectors and matrices), and autosimplification rules and algorithms for all of them;
+ \item Numeric functionality, such as numeric root-finding, linear algebra, integration, and differentiation;
+ \item A parser capable of evaluating arbitrary \LaTeX{} code and turning it into CAS expressions.
+\end{itemize}
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/intro/intropart.tex b/macros/luatex/latex/luacas/doc/intro/intropart.tex
new file mode 100644
index 0000000000..bfeb4a79b8
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/intro/intropart.tex
@@ -0,0 +1,202 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\def\currref{Core Methods}
+
+\newcommand{\coderef}[2]{%
+\index{\currref!\texttt{#1}}%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\index{\currref!\texttt{#1}}%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\begin{document}
+\thispagestyle{empty}
+\part{Introduction}
+
+\begin{multicols}{2}
+ \begin{minted}{latex}
+\begin{CAS}
+ vars('x')
+ f = x
+ for i in range(1,9) do
+ f = f*x
+ end
+ f = f-1
+\end{CAS}
+\parseforest{f}
+\bracketset{action character = @}
+\begin{center}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+
+\begin{CAS}
+ f = factor(f)
+\end{CAS}
+\parseforest{f}
+\begin{center}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+\end{minted}
+
+\columnbreak
+\phantom{}
+\vfill
+\begin{CAS}
+ vars('x')
+ f = x
+ for i in range(1,9) do
+ f = f*x
+ end
+ f = f-1
+\end{CAS}
+\parseforest{f}
+\bracketset{action character = @}
+\begin{center}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+\vfill
+\phantom{}
+\end{multicols}
+\vfill
+
+\begin{CAS}
+ f = factor(f)
+\end{CAS}
+\parseforest{f}
+\begin{center}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+\vfill
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/luacas.pdf b/macros/luatex/latex/luacas/doc/luacas.pdf
new file mode 100644
index 0000000000..d3ea07adf3
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/luacas.pdf
Binary files differ
diff --git a/macros/luatex/latex/luacas/doc/luacas.tex b/macros/luatex/latex/luacas/doc/luacas.tex
new file mode 100644
index 0000000000..b5aad9c9f9
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/luacas.tex
@@ -0,0 +1,214 @@
+\documentclass{article}
+
+\usepackage{standalone}
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage[edges]{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+%\usepackage[toc]{multitoc}
+
+\renewcommand{\comment}[1]{}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle,
+ %frame hidden
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\DeclareTotalTCBox{\lilcoderef}{O{} m m}{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ enhanced,
+ nobeforeafter,
+ tcbox raise base,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=1mm,
+ right=1mm,
+ top=1mm,
+ bottom=1mm,
+ oversize,
+ #1
+}{\mintinline{lua}{#2} \mintinline{lua}{#3}}
+
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+\usepackage{makeidx}
+\usepackage{fontawesome5}
+\usepackage{marginnote}
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\def\error{\color{red}}
+\def\self{\color{gray}}
+\def\call{}
+
+%\includeonly{
+% reference/ref_calculus/ref_calculus_methods/ref_calculus_methods_test.tex
+%}
+
+\begin{document}
+\title{The {\ttfamily luacas} package}
+\author{Evan Cochrane\thanks{\href{mailto:cochraef@rose-hulman.edu}{\ttfamily cochraef@rose-hulman.edu}} , Timothy All\thanks{\href{mailto:timothy.all@rose-hulman.edu}{\ttfamily timothy.all@rose-hulman.edu}}}
+\date{v1.0.0 \\ \today}
+
+\maketitle
+
+\begin{abstract}
+ The {\ttfamily luacas} package is a portable Computer Algebra System capable of symbolic computation, written entirely in Lua, designed for use in Lua\LaTeX{}.
+\end{abstract}
+
+\tableofcontents
+
+\include{intro/intropart.tex}
+
+\include{intro/intro.tex}
+
+\include{tutorial/tut.tex}
+
+\include{tutorial/tut1/tut1.tex}
+
+\include{tutorial/tut2/tut2.tex}
+
+\include{tutorial/tut3/tut3.tex}
+
+\include{reference/ref.tex}
+
+\include{reference/ref_core/ref_core.tex}
+
+\include{reference/ref_core/ref_core_classes/ref_core_classes.tex}
+
+\include{reference/ref_core/ref_core_methods/ref_core_methods.tex}
+
+\include{reference/ref_algebra/ref_algebra.tex}
+
+\include{reference/ref_algebra/ref_algebra_classes/ref_algebra_classes.tex}
+
+\include{reference/ref_algebra/ref_algebra_methods/ref_algebra_methods.tex}
+
+\include{reference/ref_calculus/ref_calculus.tex}
+
+\include{reference/ref_calculus/ref_calculus_classes/ref_calculus_classes.tex}
+
+\include{reference/ref_calculus/ref_calculus_methods/ref_calculus_methods.tex}
+
+\appendix
+
+\include{appendix/latexcode.tex}
+
+\newpage
+
+\printindex
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref.tex b/macros/luatex/latex/luacas/doc/reference/ref.tex
new file mode 100644
index 0000000000..426a1e17e5
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref.tex
@@ -0,0 +1,236 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage[edges]{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\begin{document}
+\thispagestyle{empty}
+\part{Reference}
+This part contains reference material for the classes and methods that incorporate the \texttt{luacas} package. Some classes are \emph{concrete} while others are \emph{abstract}. The concrete classes are essentially the objects that a user might reasonably interact with while using \texttt{luacas}. Thankfully, most of this interaction will be filtered through a rudimentary (but functional!) parser. Abstract classes exist for the purposes of inheritance.
+
+The classes in the diagram below are color-coded according to:
+\begin{itemize}
+ \item (\tikz[baseline=-0.5ex]\node[text=rosenavy,fill=roseblue!40]{\ttfamily\bfseries Class};) {\color{rosenavy}\ttfamily\bfseries Class}: a (concrete) class belonging to the core module;
+ \item (\tikz[baseline=-0.5ex]\node[text=rose,fill=rose!30]{\ttfamily\bfseries Class};) {\color{rose}\ttfamily\bfseries Class}: a (concrete) class belonging to the algebra module;
+ \item (\tikz[baseline=-0.5ex]\node[text=roseorange,fill=roseorange!30]{\ttfamily\bfseries Class};) {\color{roseorange}\ttfamily\bfseries Class}: a (concrete) class belonging to the calculus module.
+\end{itemize}
+Inheritance is indicated with an arrow:
+
+\forestset{multiple directions/.style={for tree={#1}, phantom, for relative level=1{no edge, delay={!c.content/.pgfmath=content("!u")}, before computing xy={l=0,s=0}}},
+ multiple directions/.default={},
+ grow subtree/.style={for tree={grow=#1}},
+ grow' subtree/.style={for tree={grow'=#1}}}
+
+\begin{center}
+ \begin{forest}
+ core/.style = {draw={rosenavy,thick},
+ font={\ttfamily\bfseries\color{rosenavy}},
+ fill = roseblue!#1},
+ algebra/.style = {draw={rose,thick},
+ font={\ttfamily\bfseries\color{rose}},
+ fill = rose!#1},
+ calculus/.style = {draw={roseorange,thick},
+ font={\ttfamily\bfseries\color{roseorange}},
+ fill = roseorange!#1},
+ multiple directions,
+ for tree = {font = \ttfamily\bfseries,
+ draw,
+ rounded corners=1pt,
+ edge = {-stealth},
+ s sep = 0.2cm}
+ [Expression
+ [, grow subtree = 90
+ [AtomicExpression,
+ core = {0},
+ for tree = {grow=east,
+ child anchor=west,
+ node options={anchor=west}},
+ forked edges,
+ calign=last,
+ l sep = 0.5cm,
+ s sep = 0.2cm
+ [SymbolExpression,
+ core={50}]
+ [ConstantExpression,
+ core ={0},
+ for tree = {grow = north,
+ node options = {anchor=north}
+ }
+ [Ring,
+ algebra ={0},
+ for tree = {grow = east}
+ [EuclideanDomain,
+ algebra={0}
+ [Field,
+ algebra = {0}
+ [IntegerModN,
+ algebra={30}]
+ [Rational,
+ algebra={30}]
+ ]
+ [Integer,
+ algebra={30}]
+ ]
+ [PolynomialRing,
+ algebra={30}]
+ ]
+ ]
+ ]]
+ [, grow subtree = -90
+ [CompoundExpression,
+ core = {0},
+ for tree = {grow=east,
+ child anchor=west,
+ node options={anchor=west}},forked edges,
+ calign=last,
+ l sep = 0.5cm,
+ s sep = 0.2cm
+ [FunctionExpression,
+ core = {40}
+ [TrigExpression,algebra={30}]
+ ]
+ [BinaryOperation,
+ core = {40}]
+ [Equation,
+ algebra = {30}]
+ [Logarithm,
+ algebra={30}]
+ [FactorialExpression,
+ algebra={30}]
+ [RootExpression,
+ algebra={30}]
+ [SqrtExpression,
+ algebra={30}]
+ [AbsExpression,
+ algebra={30}]
+ [DerivativeExpression,
+ calculus={20}]
+ [DiffExpression,
+ calculus={20}]
+ [IntegralExpression,
+ calculus={20}]
+ ]]
+ ]
+ \end{forest}
+\end{center}
+Every object in \texttt{luacas} is an expression, meaning it inherits from the {\ttfamily Expression} type (class). Since the {\ttfamily Expression} type itself has no constructor and cannot be instantiated, it it closer to an interface in Java OOP terms.\footnote{In reality, interfaces are unnecessary in Lua due to its weak typing - Lua doesn't check whether an object has a method at compile time. The {\ttfamily Expression} type is really an abstract class in Java terms.} {\ttfamily Expression}s can store any number of other expressions as sub-expressions, depending on type. This means that {\ttfamily Expression} objects are really trees. Types that inherit from {\ttfamily Expression} that can not store other expressions are called \emph{atomic expressions}, and correspond to the leaf nodes of the tree. Other expression types are \emph{compound expressions}. Thus, every {\ttfamily Expression} type inherits from one of {\ttfamily AtomicExpression} or {\ttfamily CompoundExpression}. The {\ttfamily ConstantExpresssion} interface is a subinterface to {\ttfamily AtomicExpression}. Types that inherit from {\ttfamily ConstantExpression} roughly correspond to numbers (interpreted broadly).
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra.tex b/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra.tex
new file mode 100644
index 0000000000..0e9bd011e8
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra.tex
@@ -0,0 +1,336 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,
+ size=small,
+ bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}
+ },
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\usetikzlibrary{shapes.multipart}
+\useforestlibrary{edges}
+
+\def\error{\color{red}}
+\def\self{\color{gray}}
+\def\call{$\star$ }
+
+\begin{document}
+\thispagestyle{empty}
+
+\section{Algebra}
+ This section contains reference materials for the algebra functionality of \texttt{luacas}. The classes in this module are diagramed below according to inheritance along with the methods/functions one can call upon them.
+ \begin{itemize}
+ \item {\error\ttfamily\itshape method}: an abstract method;
+ \item {\self\ttfamily\itshape method}: a method that returns the expression unchanged;
+ \item {\ttfamily\itshape method}: method that is either unique, implements an abstract method, or overrides an abstract
+method;
+ \item {\tikz[baseline=-0.5ex]\node[fill=rose!30] {\ttfamily\bfseries Class};}: a concrete class.
+ \end{itemize}
+Here is an inhertiance diagram of the classes in the algebra module that are derived from the \texttt{AtomicExpression} branch of classes. However, not all of them are proper {\ttfamily ConstantExpression}s, so some of them override the {\ttfamily isconstant()} method. Most methods are stated, but some were omitted (because they inherit in the obvious way, they are auxiliary and not likely to be interesting to the end-user, etc).
+ \vfill
+\forestset{
+rectcore/.style = {rectangle split,
+ rectangle split parts=2,
+ draw = {rosenavy,thick},
+ rounded corners = 1pt,
+ font = \ttfamily\bfseries,
+ fill = roseblue!#1
+ },
+rectalg/.style = {rectangle split,
+ rectangle split parts=2,
+ draw = {rose,thick},
+ rounded corners = 1pt,
+ font = \ttfamily\bfseries,
+ fill = rose!#1
+ }
+}
+\forestset{
+ multiple directions/.style={
+ for tree={#1},
+ phantom,
+ for relative level=1{
+ no edge,
+ delay={
+ !c.content/.pgfmath=content("!u")},
+ before computing xy={l=0,s=0}
+ }
+ },
+ multiple directions/.default={},
+ grow subtree/.style={for tree={grow=#1}},
+ grow' subtree/.style={for tree={grow'=#1}}}
+\tikzset{
+ every two node part/.style={font=\ttfamily\itshape\footnotesize}
+}
+\begin{center}
+ \begin{forest}
+ for tree = {node options={align=left},
+ edge = {-stealth}
+ },
+ forked edges
+ [Expression\nodepart{two}$\cdots$,rectcore={0}
+ [AtomicExpression\nodepart{two}$\cdots$,rectcore={0}
+ [SymbolExpression\nodepart{two}$\cdots$,rectcore={50}]
+ [ConstantExpression\nodepart{two}$\cdots$,rectcore={0}
+ [Ring\nodepart{two}\begin{minipage}{0.45\textwidth}\begin{multicols}{3}
+ {\error :getring}\\
+ {\error :inring(ring)}\\
+ {\error :iscommutative}\\
+ {\error :add(b)}\\
+ :sub(b)\\
+ {\error :neg(b)}\\
+ {\error :mul(b)}\\
+ :pow(n)\\
+ {\error :eq(b)}\\
+ {\error :lt(b)}\\
+ {\error :le(b)}\\
+ {\error :zero()}\\
+ {\error :one()}\\
+ {\error .makering}\\
+ .resultantring
+ \end{multicols}\end{minipage}
+ ,rectalg={0}
+ [PolynomialRing\nodepart{two}
+ .makering\\
+ .R\\
+ .gcd\\
+ .extendedgcd\\
+ .resultant\\
+ .resultantmulti\\
+ .monicgcdremainders\\
+ .partialfractions\\
+ %:isatomic\\
+ :new\\
+ .mul{\textunderscore}rec\\
+ :divremainder\\
+ :psuedodivide\\
+ :isconstant\\
+ :isatomic\\
+ :freeof\\
+ :tocompoundexpression\\
+ :evaluateat\\
+ :derivative\\
+ :squarefreefactorization\\
+ :factor\\
+ :rationalroots\\
+ :roots\\
+ $\cdots$
+ ,rectalg={30}]
+ [EuclideanDomain\nodepart{two}
+ {\error :divremainder}\\
+ :iscommutative
+ ,rectalg={0}
+ [Integer\nodepart{two}
+ .gcd\\
+ .extendedgcd\\
+ .max\\
+ .min\\
+ .ceillog\\
+ .powmod\\
+ :new\\
+ :divremainder\\
+ :asnumber\\
+ :divisors\\
+ :primefactorization\\
+ :findafactor\\
+ :isprime\\
+ :abs\\
+ $\cdots$
+ ,rectalg={30}]
+ [Field\nodepart{two}
+ :div
+ ,rectalg={0}
+ [Rational\nodepart{two}
+ :new\\
+ :reduce\\
+ :isconstant\\
+ :tocompoundexpression\\
+ :asnumber\\
+ :div
+ ,rectalg={30}]
+ [IntegerModN\nodepart{two}
+ :new
+ ,rectalg={30}]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ \end{forest}
+\end{center}
+\vfill
+
+\newpage
+
+Here is an inhertiance diagram of the classes in the algebra module that are derived from the \texttt{CompoundExpression} branch of classes. Again, most methods are stated, but some were omitted (because they inherit in the obvious way, they are auxiliary and not likely to be interesting to the end-user, etc).
+\vfill
+\begin{center}
+ \begin{forest}
+ for tree = {node options={align=left},
+ grow = south,
+ edge = {-stealth},
+ child anchor = west
+ },
+ forked edges
+ [Expression\nodepart{two}$\cdots$,
+ rectcore={0}
+ [CompoundExpression\nodepart{two}
+ $\cdots$,
+ rectcore={0},
+ calign = first,
+ for tree = {node options = {anchor = west},
+ grow' = east}
+ [BinaryOperation\nodepart{two}
+ $\cdots$,
+ rectcore={50}]
+ [FunctionExpression\nodepart{two}
+ $\cdots$,
+ rectcore={50}
+ [TrigExpression\nodepart{two}
+ :new
+ ,rectalg={30}]
+ ]
+ [AbsExpression\nodepart{two}
+ :new
+ ,rectalg={30}]
+ [SqrtExpression\nodepart{two}
+ :new\\
+ :topower
+ ,rectalg={30}]
+ [RootExpression\nodepart{two}
+ :new
+ ,rectalg={30}]
+ [FactorialExpression\nodepart{two}
+ :new
+ ,rectalg={30}]
+ [Logarithm\nodepart{two}
+ :new
+ ,rectalg={30}]
+ [Equation\nodepart{two}
+ :new\\
+ :solvefor()
+ ,rectalg={30}]
+ ]
+ ]
+ \end{forest}
+\end{center}
+\vfill
+\end{document}
+
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_classes/ref_algebra_classes.tex b/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_classes/ref_algebra_classes.tex
new file mode 100644
index 0000000000..58d9b69f84
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_classes/ref_algebra_classes.tex
@@ -0,0 +1,977 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+\usepackage{fontawesome}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\begin{document}
+\setdescription{style=multiline,
+ topsep=10pt,
+ leftmargin=5cm,
+ }
+
+\subsection{Algebra Classes}
+
+The algebra package contains functionality for arbitrary-precision arithmetic, polynomial arithmetic and factoring, symbolic root finding, and logarithm and trigonometric expression classes. It requires the core package to be loaded.
+
+The abstract classes in the algebra module all inherit from the \texttt{ConstantExpression} branch in the inheritance tree:
+
+\begin{itemize}
+ \item \texttt{Ring}
+ \item \texttt{EuclideanDomain}
+ \item \texttt{Field}
+\end{itemize}
+
+The {\ttfamily EuclideanDomain} class is a sub-class to the {\ttfamily Ring} class, and the {\ttfamily Field} class is a sub-class to the {\ttfamily EuclideanDomain} class.
+
+The following concrete classes inherit from the {\ttfamily Ring} class (or one of the sub-classes mentioned above). However, not all of them are proper {\ttfamily ConstantExpression}s, so some of them override the {\ttfamily isconstant()} method.
+
+\begin{itemize}
+ \item {\ttfamily Integer}
+ \item {\ttfamily IntegerModN}
+ \item {\ttfamily Rational}
+ \item {\ttfamily PolynomialRing}
+\end{itemize}
+
+The other concrete classes in the Algebra package do not inherit from the {\ttfamily Ring} interface, instead they inherit from the {\ttfamily CompoundExpression} interface:
+
+\begin{multicols}{2}
+\begin{itemize}
+ \item {\ttfamily AbsExpression}
+ \item {\ttfamily Logarithm}
+ \item {\ttfamily FactorialExpression}
+ \item {\ttfamily SqrtExpression}
+ \item {\ttfamily TrigExpression}
+ \item {\ttfamily RootExpression}
+ \item {\ttfamily Equation}
+\end{itemize}
+\end{multicols}
+
+\newcoderef{function Integer:new(n)}{return Integer}{n number|string|Integer}
+\index{Algebra!Classes!\texttt{SymbolExpression}}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer}
+
+Takes a \texttt{string}, \texttt{number}, or {\ttfamily Integer} input and constructs an \texttt{Integer} expression. The \texttt{Integer} class allows us to perform exact arithmetic on integers. Indeed, since Lua can only store integers exactly up to a certain point, it is recommended to use strings to build large integers.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+a = Integer(-12435)
+b = Integer('-12435')
+tex.print('\\[',a:tolatex(),
+ '=',
+ b:tolatex(),
+ '\\]')
+\end{minted}
+\tcblower
+\directlua{
+ a = Integer(-12435)
+ b = Integer('-12435')
+ tex.print('\\[',a:tolatex(),
+ '=',
+ b:tolatex(),
+ '\\]')
+}
+\end{codebox}
+An {\ttfamily Integer} is a table 1-indexed by Lua numbers consisting of Lua numbers. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+tex.print(tostring(b[1]))
+\end{minted}
+\tcblower
+\directlua{
+ tex.print(tostring(b[1]))
+}
+\end{codebox}
+Whereas:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+c = Integer('7240531360949381947528131508')
+tex.print('The first 14 digits of c:', tostring(c[1]),'. ')
+tex.print('The last 14 digits of c:', tostring([2]),'.')
+\end{minted}
+\tcblower
+\directlua{
+ c = Integer('7240531360949381947528131508')
+ tex.print('The first 14 digits of c:', tostring(c[1]),'. ')
+ tex.print('The last 14 digits of c:', tostring(c[2]),'.')
+}
+\end{codebox}
+
+The global field {\ttfamily DIGITSIZE} is set to \texttt{14} so that exact arithmetic on {\ttfamily Integer}s can be done as efficiently as possible while respecting Lua's limitations.
+
+\subsubsection*{Fields}
+{\ttfamily Integer}s have a {\ttfamily .sign} field which contains the Lua number {\ttfamily 1} or {\ttfamily -1} depending on whether \texttt{Integer} is positive or negative.
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+tex.print('The sign of',tostring(b),'is:',tostring(b.sign))
+\end{minted}
+\tcblower
+\directlua{
+ tex.print('The sign of',
+ tostring(b),
+ 'is:',
+ tostring(b.sign))
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The contents of the environment \mintinline{latex}{\begin{CAS}..\end{CAS}} are wrapped in the argument of a function \mintinline{lua}{CASparse()} which, among other things, seeks out digit strings intended to represent integers, and wraps those in \texttt{Integer('...')}.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ c = 7240531360949381947528131508
+\end{CAS}
+\directlua{
+ tex.print(tostring(c[1]))
+}
+\end{minted}
+\tcblower
+\begin{CAS}
+ c = 7240531360949381947528131508
+\end{CAS}
+\directlua{
+ tex.print(tostring(c[1]))
+}
+\end{codebox}
+
+\newcoderef{function IntegerModN:new(i,n)}{return IntegerModN}{i Integer, n Integer}
+\index{Algebra!Classes!\texttt{IntegerModN}}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegerModN}
+
+Takes an {\ttfamily Integer i} and {\ttfamily Integer n} and constructs an element in the ring $\mathbf{Z}/n\mathbf{Z}$, the integers modulo $n$.
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+i = Integer(143)
+n = Integer(57)
+a = IntegerModN(i,n)
+tex.print('\\[',i:tolatex(),'\\equiv',a:tolatex(true),'\\]')
+\end{minted}
+\tcblower
+\luaexec{
+ i = Integer(143)
+ n = Integer(57)
+ a = IntegerModN(i,n)
+ tex.print('\\[',i:tolatex(),'\\equiv',a:tolatex(true),'\\]')
+}
+\end{codebox}
+
+\subsubsection*{Fields}
+
+{\ttfamily IntegerModN}s have two fields: {\ttfamily .element} and {\ttfamily .modulus}. The reduced input \texttt{i} is stored in {\ttfamily .element} while the input \texttt{n} is stored in {\ttfamily .modulus}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+tex.print(a.element:tolatex(),'\\newline')
+tex.print(a.modulus:tolatex())
+\end{minted}
+\tcblower
+\luaexec{
+ tex.print(a.element:tolatex(),'\\newline')
+ tex.print(a.modulus:tolatex())
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \texttt{Mod(,)} is a shortcut for \texttt{IntegerModN(,)}:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ i = 143
+ n = 57
+ a = Mod(i,n)
+\end{CAS}
+\[\print{i}\equiv\print{a}\bmod{\print{n}}\]
+\end{minted}
+\tcblower
+\begin{CAS}
+ i = 143
+ n = 57
+ a = Mod(i,n)
+\end{CAS}
+\[ \print{i} \equiv \print{a} \bmod{\print{n}}\]
+\end{codebox}
+
+\newcoderef{function PolynomialRing:new(coefficients, symbol, degree)}{return PolynomialRing}{coefficients table<number,Ring>, symbol string|SymbolExpression, degree Integer}
+\index{Algebra!Classes!\texttt{PolynomialRing}}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing}
+
+Takes a table of {\ttfamily coefficients}, not all necessarily in the same ring, and a {\ttfamily symbol} to create a polynomial in $\mathtt{R[x]}$ where $\mathtt{x}$ is {\ttfamily symbol} and $\mathtt{R}$ is the smallest {\ttfamily Ring} possible given the coefficients. If {\ttfamily degree} is omitted, it will calculate the degree of the polynomial automatically. The list can either be one-indexed or zero-indexed, but if it is one-indexed, the internal list of coefficients will still be zero-indexed.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = PolynomialRing({0,1/3,-1/2,1/6},'t')
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = PolynomialRing({0,1/3,-1/2,1/6},'t')
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+The \texttt{PolynomialRing} class overwrites the \mintinline{lua}{isatomic()} and \mintinline{lua}{isconstant()} inheritances from the abstract class \texttt{ConstantExpression}.
+\subsubsection*{Fields}
+
+\begin{multicols}{2}
+{\ttfamily PolynomialRing}s have several fields:
+\begin{itemize}
+ \item {\ttfamily f.coefficients} stores the 0-indexed table of coefficients of {\ttfamily f};
+ \item {\ttfamily f.degree} stores the {\ttfamily Integer} that represents the degree of {\ttfamily f};
+ \item {\ttfamily f.symbol} stores the {\ttfamily string} representing the variable or {\ttfamily symbol} of {\ttfamily f}.
+ \item {\ttfamily f.ring} stores the \texttt{RingIdentifier} for the ring of coefficients.
+\end{itemize}
+
+\columnbreak
+
+\parseshrub{f}
+\bracketset{action character = @}
+\begin{center}
+\begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill=gray!20,
+ s sep = 1.5cm,
+ l sep = 2cm}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+for i=0,f.degree:asnumber() do
+ tex.print('\\[',
+ f.coefficients[i]:tolatex(),
+ f.symbol,
+ '^{',
+ tostring(i),
+ '}\\]')
+end
+if f.ring == Rational.getring() then
+ tex.print('Rational coefficients')
+end
+\end{minted}
+\tcblower
+\luaexec{
+for i=0,f.degree:asnumber() do
+ tex.print(
+ '\\[',
+ f.coefficients[i]:tolatex(),
+ f.symbol,
+ '^{',
+ tostring(i),
+ '}\\]'
+ )
+ end
+ if f.ring == Rational.getring() then
+ tex.print('Rational coefficients')
+ end
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{Poly()} is a shortcut for \mintinline{lua}{PolynomialRing:new()}. If the second argument \texttt{symbol} is omitted, then the default is \texttt{'x'}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({0,1/3,-1/2,1/6})
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({0,1/3,-1/2,1/6})
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+
+Alternatively, one could typeset the polynomial naturally and use the \texttt{topoly()} function. This is the same as the \texttt{topolynomial()} method except that the \texttt{autosimplify()} method is automatically called first:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = 1/3*x - 1/2*x^2 + 1/6*x^3
+ f = topoly(f)
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = 1/3*x - 1/2*x^2 + 1/6*x^3
+ f = topoly(f)
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+
+\newcoderef{function Rational:new(n,d,keep)}{return Rational}{n Ring, d Ring, keep bool}
+\index{Algebra!Classes!\texttt{Rational}}
+\addcontentsline{toc}{subsubsection}{\ttfamily Rational}
+
+Takes a numerator {\ttfamily n} and denominator {\ttfamily d} in the same {\ttfamily Ring} and constructs a rational expression in the field of fractions over that ring. For the integers, this is the ring of rational numbers. If the {\ttfamily keep} flag is omitted, the constructed object will be simplified to have smallest possible denominator, possibly returning an object in the original {\ttfamily Ring}. Typically, the {\ttfamily Ring} will be either {\ttfamily Integer} or {\ttfamily PolynomialRing}, so {\ttfamily Rational} can be viewed as a constructor for either a rational number or a rational function.
+
+For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+a = Integer(6)
+b = Integer(10)
+c = Rational(a,b)
+tex.print('\\[',c:tolatex(),'\\]')
+\end{minted}
+\tcblower
+\luaexec{
+ a = Integer(6)
+ b = Integer(10)
+ c = Rational(a,b)
+ tex.print('\\[',c:tolatex(),'\\]')
+}
+\end{codebox}
+But also:
+\begin{codebox}
+ \begin{minted}{lua}
+a = Poly({Integer(2),Integer(3)})
+b = Poly({Integer(4),Integer(1)})
+c = Rational(a,b)
+tex.print('\\[',c:tolatex(),'\\]')
+\end{minted}
+\tcblower
+\luaexec{
+a = Poly({Integer(2),Integer(3)})
+b = Poly({Integer(4),Integer(1)})
+c = Rational(a,b)
+tex.print('\\[',c:tolatex(),'\\]')
+}
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\texttt{Rational}s naturally have the two fields: \texttt{numerator}, \texttt{denominator}. These fields store precisely what you think. \texttt{Rational}s also have a \texttt{ring} field which stores the \texttt{RingIdentifier} to which the numerator and denominator belong. (This is $\mathbb{Z}$ for the rational numbers.)
+
+If \texttt{numerator} or \texttt{denominator} are \texttt{PolynomialRing}s, then the constructed \texttt{Rational} will have an additional field: \texttt{symbol}. This stores the symbol the polynomial rings are constructed over.
+
+\begin{codebox}[]
+ \begin{minted}{lua}
+if c.ring == PolynomialRing.getring() then
+ tex.print('$',c:tolatex(),'$ is a Rational Function in the variable',c.symbol)
+end
+\end{minted}
+\tcblower
+\luaexec{
+if c.ring == PolynomialRing.getring() then
+ tex.print('$',c:tolatex(),'$ is a Rational Function in the variable',c.symbol)
+end
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+\texttt{Raional}s are constructed naturally using the \texttt{/} operator:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = Poly({2,3})
+ b = Poly({4,1})
+ c = a/b
+\end{CAS}
+\[ \print{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = Poly({2,3})
+ b = Poly({4,1})
+ c = a/b
+\end{CAS}
+\[ \print{c} \]
+\end{codebox}
+
+\coderef{function AbsExpression:new(expression)}{return AbsExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily AbsExpression}
+
+Creates a new absolute value expression with the given expression.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({1,1})
+ g = Poly({-1,1})
+ h = AbsExpression(f/g)
+\end{CAS}
+\[ h = \print{h} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({1,1})
+ g = Poly({-1,1})
+ h = AbsExpression(f/g)
+\end{CAS}
+\[ h = \print{h} \]
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\texttt{AbsExpression}s have only one field: \texttt{.expression}. This field simply holds the \texttt{Expression} inside the absolute value:
+\begin{multicols}{2}
+\begin{codebox}[]
+\begin{minted}[fontsize=\small]{lua}
+tex.print('\\[',
+ h.expression:tolatex(),
+ '\\]')
+\end{minted}
+\tcblower
+\directlua{
+ tex.print('\\[',h.expression:tolatex(),'\\]')
+}
+\end{codebox}
+\parseshrub{h}
+\bracketset{action character = @}
+\begin{center}
+\begin{forest}
+ for tree = {font=\ttfamily,
+ draw,
+ rounded corners=1pt,
+ fill=gray!20,
+ l sep =1.5cm}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{abs()} is a shortcut to \mintinline{lua}{AbsExpression:new()}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({1,1})
+ g = Poly({-1,1})
+ h = abs(f/g)
+\end{CAS}
+\[ h = \print{h} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({1,1})
+ g = Poly({-1,1})
+ h = abs(f/g)
+\end{CAS}
+\[ h = \print{h} \]
+\end{codebox}
+
+\newcoderef{function Logarithm:new(base,arg)}{return Logarithm}{base Expression, arg Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily Logarithm}
+
+Creates a new \texttt{Logarithm} expression with the given \texttt{base} and \texttt{arg}ument. Some basic simplification rules are known to \texttt{autosimplify()}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('b','x','y')
+ f = Logarithm(b,x^y)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('b','x','y')
+ f = Logarithm(b,x^y)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\begin{multicols}{2}
+\texttt{Logarithm}s have two fields: \texttt{base} and \texttt{expression}; \texttt{base} naturally stores the base of the logarithm (i.e., the first argument of \texttt{Logarithm}) while \texttt{expression} stores the argument of the logarithm (i.e., the second argument of \texttt{Logarithm}).
+
+\begin{center}
+ \parseshrub{f}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners=1pt,
+ fill = gray!20,
+ s sep = 1.5cm}
+ @\shrubresult
+ \end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{log()} is a shortcut to \texttt{Logarithm}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('b')
+ f = log(b,b)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('b')
+ f = log(b,b)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{codebox}
+
+There is also a \mintinline{lua}{ln()} function to shortcut \texttt{Logarithm} where the base is \texttt{e}, the natural exponent.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = ln(e)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = ln(e)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{codebox}
+
+\newcoderef{function FactorialExpression:new(expression)}{return FactorialExpression}{expression Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily FactorialExpression}
+
+Creates a new \texttt{FactorialExpression} with the given \texttt{expression}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = FactorialExpression(5)
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = FactorialExpression(5)
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+The \texttt{evaluate()} method will compute factorials of nonnegative \texttt{Integer}s:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = FactorialExpression(5)
+\end{CAS}
+\[ \print{a} = \print{a:evaluate()} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = FactorialExpression(5)
+\end{CAS}
+\[ \print{a} = \print{a:evaluate()} \]
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\texttt{FactorialExpression}s have only one field: \texttt{expression}. This field stores the argument of \texttt{FactorialExpression()}.
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{factorial()} is a shortcut to \texttt{FactorialExpression()}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = factorial(5)
+\end{CAS}
+\[ \print{a} = \print{a:evaluate()} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = factorial(5)
+\end{CAS}
+\[ \print{a} = \print{a:evaluate()} \]
+\end{codebox}
+
+\newcoderef{function SqrtExpression:new(expression, root)}{return SqrtExpression}{expression Expression, root Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily SqrtExpression}
+
+Creates a new \texttt{SqrtExpression} with the given \texttt{expression} and \texttt{root}. Typically, \texttt{expression} is an \texttt{Integer} or \texttt{Rational}, and \texttt{SqrtExpression} is intended to represent a positive real number. If \texttt{root} is omitted, then \texttt{root} defaults to \mintinline{lua}{Integer(2)}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+a = SqrtExpression(Integer(8))
+b = SqrtExpression(Integer(8),Integer(3))
+c = a+b
+tex.print('\\[',c:tolatex(),'\\]')
+\end{minted}
+\tcblower
+\directlua{
+ a = SqrtExpression(Integer(8))
+b = SqrtExpression(Integer(8),Integer(3))
+c = a+b
+tex.print('\\[',c:tolatex(),'\\]')
+}
+\end{codebox}
+When \texttt{expression} and \texttt{root} are of the \texttt{Integer} or \texttt{Rational} types, then \texttt{autosimplify()} does a couple things. For example, with \texttt{a,b} as above, we get:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+c = c:autosimplify()
+tex.print('\\[',c:tolatex(),'\\]')
+\end{minted}
+\tcblower
+\directlua{
+c = c:autosimplify()
+tex.print('\\[',c:tolatex(),'\\]')
+}
+\end{codebox}
+On the other hand, if \texttt{root} or \texttt{expression} are not constants, then typically \mintinline{lua}{autosimplify()} will convert \texttt{SqrtExpression} to the appropriate \texttt{BinaryOperation}. For example:
+
+\directlua{
+ vars('x')
+ a = SqrtExpression(x,Integer(3))
+ b = a:autosimplify()
+}
+
+\begin{multicols}{2}
+ \begin{center}
+ \underline{Tree for \texttt{a}}
+
+\parseshrub{a}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {s sep=2cm,
+ font=\ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill=gray!20}
+ @\shrubresult
+\end{forest}
+
+ \underline{Tree for \texttt{a:autosimplify()}}
+
+\parseshrub{a:autosimplify()}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {s sep=2cm,
+ font=\ttfamily}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{sqrt()} shortcuts \texttt{SqrtExpression()}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = sqrt(1/9)
+ b = sqrt(27/16,3)
+ c = a+b
+\end{CAS}
+\[ \print{c} = \print*{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = sqrt(1/9)
+ b = sqrt(27/16,3)
+ c = a+b
+\end{CAS}
+\[ \print{c} = \print*{c} \]
+\end{codebox}
+
+\newcoderef{function TrigExpression:new(name,expression)}{return TrigExpression}{name string|SymbolExpression, expression Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily TrigExpression}
+
+Creates a new trig expression with the given \texttt{name} and \texttt{expression}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('x')
+f = TrigExpression('sin',x)
+tex.print('\\[',f:tolatex(),'\\]')
+\end{minted}
+\tcblower
+\directlua{
+ vars('x')
+ f = TrigExpression('sin',x)
+ tex.print('\\[',f:tolatex(),'\\]')
+}
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\begin{multicols}{2}
+
+\texttt{TrigExpression}s have many fields:
+\begin{itemize}
+ \item \mintinline{lua}{TrigExpression.name} stores the string \texttt{name}, i.e. the first argument of \mintinline{lua}{TrigExpression()};
+ \item \mintinline{lua}{TrigExpression.expression} stores the \texttt{Expression} \texttt{expression}, i.e. the second argument of \mintinline{lua}{TrigExpression()};
+ \item and all fields inherited from \texttt{FunctionExpression} (e.g. \mintinline{lua}{TrigExpression.derivatives} which defaults to \mintinline{lua}{Integer.zero()}).
+\end{itemize}
+
+\columnbreak
+
+\begin{center}
+\parseshrub{f}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill = gray!20,
+ l sep = 2cm}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+The usual trigonometric functions have the anticipated shortcut names. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = arctan(x^2)
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = arctan(x^2)
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+
+\newcoderef{function RootExpression:new(expression)}{return RootExpression}{expression Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily RootExpression}
+
+Creates a new \texttt{RootExpression} with the given \texttt{expression}. The method \mintinline{lua}{RootExpression:autosimplify()} attempts to return a list of zeros of \texttt{expression}. If no such set can be found, then
+
+\mintinline{lua}{RootExpression(expression:autosimplify())}
+
+is returned instead. At the moment, \texttt{expression} must be a univariate polynomial of degree $0,1,2$ or $3$ in order for the \texttt{autosimplify()} method to return anything interesting. Of course, \texttt{luacas} can find roots of higher degree polynomials, but this involves more machinery/methods within the \texttt{PolynomialRing} class.
+
+\subsubsection*{Fields}
+\texttt{RootExpression}s have only one field: \texttt{.expression}. For example:
+\begin{multicols}{2}
+ \begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({3,2,1})
+ r = RootExpression(f)
+\end{CAS}
+\[ \print{r} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({3,2,1})
+ r = RootExpression(f)
+\end{CAS}
+\[ \print{r} \]
+\end{codebox}
+
+\begin{center}
+\parseshrub{r}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners=1pt,
+ fill=gray!20,
+ l sep = 2cm}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{roots()} essentially shortcuts \texttt{RootExpression()}, but when \texttt{expression} is of the \texttt{PolynomialRing}-type, then \texttt{PolynomialRing:roots()} is returned.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ r = roots(f)
+\end{CAS}
+\[ \print{r[1]} \qquad \print{r[2]} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ r = roots(f)
+\end{CAS}
+\[ \print{r[1]} \qquad \print{r[2]} \]
+\end{codebox}
+
+
+\newcoderef{function Equation:new(lhs, rhs)}{return Equation}{lhs Expression, rhs Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily Equation}
+
+Creates a new \texttt{Equation} expression with the given \texttt{lhs} (left hand side) and \texttt{rhs} (right hand side). If both sides of the equation are constants, or structurally identical, \texttt{autosimplify()} will return a boolean:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','y')
+ f = Equation(sin(x-y),sin(x-y))
+ g = f:autosimplify()
+\end{CAS}
+\[ \print{f} \to \print{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y')
+ f = Equation(sin(x-y),sin(x-y))
+ g = f:autosimplify()
+\end{CAS}
+\[ \print{f} \to true \]
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\begin{multicols}{2}
+\texttt{Equation}s have two fields: \texttt{lhs} and \texttt{rhs}; which store the expressions on the left and right sides of the equation.
+
+\begin{center}
+ \parseshrub{f}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners=1pt,
+ fill = gray!20,
+ s sep = 1.5cm}
+ @\shrubresult
+ \end{forest}
+\end{center}
+\end{multicols}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_methods/ref_algebra_methods.tex b/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_methods/ref_algebra_methods.tex
new file mode 100644
index 0000000000..b576cdc1a3
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_algebra/ref_algebra_methods/ref_algebra_methods.tex
@@ -0,0 +1,1305 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+\usepackage{fontawesome5}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\DeclareTotalTCBox{\lilcoderef}{O{} m m}{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ enhanced,
+ nobeforeafter,
+ tcbox raise base,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=1mm,
+ right=1mm,
+ top=1mm,
+ bottom=1mm,
+ oversize,
+ #1
+}{\mintinline{lua}{#2} \mintinline{lua}{#3}}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+\usepackage{marginnote}
+
+\begin{document}
+\setdescription{style=multiline,
+ topsep=10pt,
+ leftmargin=6.5cm,
+ }
+
+\subsection{Algebra Methods}
+
+Many classes in the algebra package inherit from the {\ttfamily Ring} interface. The {\ttfamily Ring} interface requires the following arithmetic operations, which have corresponding abstract metamethods listed below. Of course, these abstract methods get passed to the appropriate concrete methods in the concrete classes that inherit from {\ttfamily Ring}.
+
+For {\ttfamily Ring} objects {\ttfamily a} and {\ttfamily b}:
+
+\SetLabelAlign{parright}{\parbox[t]{\labelwidth}{\raggedleft#1}}
+\begin{description}%[labelwidth = 6.5cm,align=parright]
+ \item[\lilcoderef{function a:add(b)}{return a + b}] Adds two ring elements.
+ \item[\lilcoderef{function a:sub(b)}{return a - b}] Subtracts one ring element from another. Subtraction has a default implementation in {\ttfamily Ring.lua} as adding the additive inverse, but this can be overwritten if a faster performance method is available.
+ \item[\lilcoderef{function a:neg()}{return -a}] Returns the additive inverse of a ring element.
+ \item[\lilcoderef{function a:mul(b)}{return a * b}] Multiplies two ring elements.
+ \item[\lilcoderef{function a:pow(n)}{return a ^ n}] Raises one ring element to the power of an integer. Exponentiation has a default implementation as repeated multiplication, but this can (and probably should) be overwritten for faster performance.
+ \item[\lilcoderef{function a:eq(b)}{return a == b}] Tests if two ring elements are the same.
+ \item[\lilcoderef{function a:lt(b)}{return a < b}] Tests if one ring element is less than another under some total order. If the ring does not have a natural total order, this method does not need to be implemented.
+ \item[\lilcoderef{function a:le(b)}{return a <= b}] Tests if one ring element is less than or equal to another under some total order. If the ring does not have a natural total order, this method does not need to be implemented.
+ \item[\lilcoderef{function a:zero()}{return Ring}] Returns the additive identity of the ring to which \texttt{a} belongs.
+ \item[\lilcoderef{function a:one()}{return Ring}] Returns the multiplicative identity of the ring to which \texttt{a} belongs.
+\end{description}
+
+\reversemarginpar
+Arithmetic\marginnote{\color{rose}\large\faHandPointRight} of {\ttfamily Ring} elements will (generally) not form a {\ttfamily BinaryOperation}. Instead, the appropriate \mintinline{lua}{__RingOperation} is called which then passes the arithmetic to a specific ring, if possible. For example:
+\begin{codebox}
+ \begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({2,1})
+ g = Poly({2,5})
+ h = f+g
+\end{CAS}
+\[ (\print{f}) + (\print{g}) = \print{h} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({2,1})
+ g = Poly({2,5})
+ h = f+g
+\end{CAS}
+\[ (\print{f}) + (\print{g}) = \print{h} \]
+\end{codebox}
+So why have the {\ttfamily Ring} class to begin with? Many of the rings in the algebra package are subsets of one another. For instance, integers are subsets of rationals, which are subsets of polynomial rings over the rationals, etc. To smoothly convert objects from one ring to another, it's good to have a class like {\ttfamily Ring} to handle all the ``traffic.''
+
+For example, the {\ttfamily RingIdentifier} object acts as a pseudo-class that stores information about the exact ring of an object, including the symbol the ring has if it's a polynomial ring. To perform operations on two elements of different rings, the CAS does the following:
+
+To get the generic {\ttfamily RingIdentifier} from a class, it uses the static method:
+\coderef{function Ring.makering()}{return RingIdentifier}
+
+To get the {\ttfamily RingIdentifier} from a specific instance (element) of a ring, it uses the method:
+
+\coderef{function Ring:getring()}{return RingIdentifier}
+
+So, for example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+a = Integer(2)/Integer(3)
+ring = a:getring()
+if ring == Integer.makering() then
+ tex.print('same rings')
+else
+ tex.print('different rings')
+end
+\end{minted}
+\tcblower
+\luaexec{
+a = Integer(2)/Integer(3)
+ring = a:getring()
+if ring == Integer.makering() then
+ tex.print('same rings')
+else
+ tex.print('different rings')
+end
+}
+\end{codebox}
+
+From there, the CAS computes the smallest {\ttfamily RingIdentifier} that contains the two {\ttfamily RingIdentifier}s as subsets using the static method:
+
+\newcoderef{function Ring.resultantring(ring1,ring2)}{return RingIdentifier}{ring1 RingIdentifier, ring2 RingIdentifier}
+
+So, for example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+a = Poly({Integer(2),Integer(1)})
+b = Integer(3)
+ring1 = a:getring()
+ring2 = b:getring()
+ring = Ring.resultantring(ring1,ring2)
+if ring == a:getring() then
+ tex.print('polynomial ring')
+end
+\end{minted}
+\tcblower
+\luaexec{
+ a = Poly({Integer(2),Integer(1)})
+ b = Integer(3)
+ ring1 = a:getring()
+ ring2 = b:getring()
+ ring = Ring.resultantring(ring1,ring2)
+ if ring == a:getring() then
+ tex.print('polynomial ring')
+ end
+}
+\end{codebox}
+
+Finally, the CAS converts both objects into the resultant {\ttfamily RingIdentifier}, if possible, using the method:
+
+\coderef{function Ring:inring(ring)}{return Ring}
+
+So, for example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+b = b:inring(ring)
+if b:type() == PolynomialRing then
+ tex.print('b is a polynomial now')
+end
+\end{minted}
+\tcblower
+\luaexec{
+ b = b:inring(ring)
+ if b:type() == PolynomialRing then
+ tex.print('b is a polynomial now')
+ end
+}
+\end{codebox}
+
+Finally, the CAS is able to perform the operation with the correct \mintinline{lua}{__RingOperation}. This all happens within the hierarchy of \texttt{Ring} classes automatically:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = Poly({1/2,3,1})
+ b = 1/2
+ c = a+b
+\end{CAS}
+\[ \print{a} + \print{b} = \print{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = Poly({1/2,3,1})
+ b = 2/3
+ c = a+b
+\end{CAS}
+\[ \print{a} + \print{b} = \print{c} \]
+\end{codebox}
+
+
+To add another class that implements {\ttfamily Ring} and has proper conversion abilities, the {\ttfamily resultantring} method needs to be updated to include all possible resultant rings constructed from the new ring and existing rings. The other three methods need to be implemented as well.
+
+\hrulefill
+
+We now discuss the more arithmetic methods included in the algebra package beginning with the \texttt{PolynomialRing} class.
+
+\coderef{function PolynomialRing:decompose()}{return table<number, PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:decompose}
+
+Returns a list of polynomials that form a complete decomposition of the given polynomial. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({5,-4,5,-2,1})
+ d = f:decompose()
+\end{CAS}
+\[ \left\{ \lprint{d} \right\} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({5,-4,5,-2,1})
+ d = f:decompose()
+\end{CAS}
+\[ \left\{ \lprint{d} \right\} \]
+\end{codebox}
+In particular, the code:
+\begin{minted}{lua}
+g = d[2]:evaluateat(d[1])
+tex.print('\\[', g:tolatex(), '\\]')
+\end{minted}
+recovers $f$:
+\luaexec{
+ g = d[2]:evaluateat(d[1])
+ tex.print('\\[', g:tolatex(), '\\]')
+}
+
+
+
+\coderef{function PolynomialRing:derivative()}{return PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:derivative}
+
+Returns the formal derivative of the given polynomial. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({1,1,1/2,1/6})
+ g = f:derivative()
+\end{CAS}
+\[ \print{f} \xrightarrow{d/dx}
+ \print{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({1,1,1/2,1/6})
+ g = f:derivative()
+\end{CAS}
+\[ \print{f} \xrightarrow{d/dx}
+ \print{g} \]
+\end{codebox}
+
+\coderef{function PolynomialRing:divisors()}{return table<number, PolynomialRing>}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:divisors}
+
+Returns a list of all monic divisors of positive degree of the polynomial, assuming the polynomial ring is a Euclidean Domain. For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = topoly(x^4 - 2*x^3 - x + 2)
+ d = f:divisors()
+\end{CAS}
+\[ \left\{ \lprint{d} \right\} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = topoly(x^4 - 2*x^3 - x + 2)
+ d = f:divisors()
+\end{CAS}
+\[ \left\{ \lprint{d} \right\} \]
+\end{codebox}
+
+\newcoderef{function PolynomialRing:divremainder(poly1)}{return poly2,poly3}{poly1 PolynomialRing,..., poly3 PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:divremainder}
+
+Uses synthetic division to return the quotient (\texttt{poly2}) and remainder (\texttt{poly3}) of \texttt{self/poly1}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({2,2,1})
+ g = Poly({1,1})
+ q,r = f:divremainder(g)
+\end{CAS}
+\[ \print{f} = (\print{g})(\print{q})
+ + \print{r} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({2,2,1})
+ g = Poly({1,1})
+ q,r = f:divremainder(g)
+\end{CAS}
+\[ \print{f} = (\print{g})(\print{q})
+ + \print{r} \]
+\end{codebox}
+
+\newcoderef{function PolynomialRing.extendedgcd(poly1,poly2)}{return poly3, poly4, poly5}{poly1 PolynomialRing, poly2 PolynomialRing, ..., poly5 PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:extendedgcd}
+
+Given two \texttt{PolynomialRing} elements \texttt{poly1,poly2} returns:
+\begin{itemize}
+ \item \texttt{poly3}: the gcd of \texttt{poly1,poly2};
+ \item \texttt{poly4,poly5}: the coefficients from Bezout's lemma via the extended gcd.
+\end{itemize}
+For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = topoly((x-1)*(x-2)*(x-3))
+ g = topoly((x-1)*(x+2)*(x+3))
+ h,a,b = PolynomialRing.extendedgcd(f,g)
+\end{CAS}
+\[ \print{f*a+g*b} = (\print{f})\left( \print{a} \right) +
+ (\print{g})\left(\print{b} \right)\]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = topoly((x-1)*(x-2)*(x-3))
+ g = topoly((x-1)*(x+2)*(x+3))
+ h,a,b = PolynomialRing.extendedgcd(f,g)
+\end{CAS}
+\[ \print{f*a+g*b} = (\print{f})\left( \print{a} \right) +
+ (\print{g})\left(\print{b} \right)\]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \texttt{gcdext()} is a shortcut to \texttt{Polynomial.extendedgcd()}:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly((x+2)*(x-3))
+ g = topoly((x+4)*(x-3))
+ h,a,b = gcdext(f,g)
+\end{CAS}
+\[ \print{h} = (\print{f}) \left( \print{a} \right) +
+ (\print{g})\left( \print{b} \right). \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly((x+2)*(x-3))
+ g = topoly((x+4)*(x-3))
+ h,a,b = gcdext(f,g)
+\end{CAS}
+\[ \print{h} = (\print{f}) \left( \print{a} \right) + (\print{g})\left( \print{b} \right). \]
+\end{codebox}
+
+\coderef{function PolynomialRing:evaluateat(Expression)}{return Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:evaluateat}
+
+Uses Horner's rule to evaluate a polynomial at \texttt{Expression}. Typically, the input \texttt{Expression} is an \texttt{Integer} or \texttt{Rational}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({2,2,1})
+ p = f:evaluateat(1/2)
+\end{CAS}
+\[ \left. \print{f} \right|_{x=1/2}
+ = \print{p} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({2,2,1})
+ p = f:evaluateat(1/2)
+\end{CAS}
+\[ \left. \print{f} \right|_{x=1/2}
+ = \print{p} \]
+\end{codebox}
+
+\coderef{function PolynomialRing:factor()}{return BinaryOperation}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:factor}
+
+Factors the given polynomial into irreducible terms over the polynomial ring to which the coefficients belong. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({8,24,32,24,10,2})
+ a = f:factor()
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({8,24,32,24,10,2})
+ a = f:factor()
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+
+On the other hand:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({Mod(1,5),Mod(0,5),Mod(1,5)})
+ a = f:factor()
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({Mod(1,5),Mod(0,5),Mod(1,5)})
+ a = f:factor()
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+
+The syntax \mintinline{lua}{f = Poly({Mod(1,5),Mod(0,5),Mod(1,5)})} is awkward. Alternatively, one can use the following instead:
+\begin{codebox}
+ \begin{minted}{latex}
+\begin{CAS}
+ f = Mod(Poly({1,0,1}),5)
+ a = f:factor()
+\end{CAS}
+\[ \print{f} = \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Mod(Poly({1,0,1}),5)
+ a = f:factor()
+\end{CAS}
+\[ \print{f} = \print{a} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{factor()} shortcuts \mintinline{lua}{PolynomialRing:factor()}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({8,24,32,24,10,2})
+ a = factor(f)
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({8,24,32,24,10,2})
+ a = factor(f)
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+
+\newcoderef{function PolynomialRing:freeof(symbol)}{return bool}{symbol SymbolExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:freeof}
+
+Checks the value of the field \mintinline{lua}{PolynomialRing.symbol} against \texttt{symbol}; returns \mintinline{lua}{true} if these symbols are not equal, and returns \mintinline{lua}{false} otherwise.
+
+Recall: the default symbol for \texttt{Poly} is \texttt{'x'}. So, for example:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = Poly({2,2,1})
+ vars('t')
+ if f:freeof(t) then
+ tex.print('$',f:tolatex(),'$ is free of $',t:tolatex(),'$')
+ else
+ tex.print('$',f:tolatex(),'$ is bound by $',t:tolatex(),'$')
+ end
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = Poly({2,2,1})
+ vars('t')
+ if f:freeof(t) then
+ tex.print('$',f:tolatex(),'$ is free of $',t:tolatex(),'$')
+ else
+ tex.print('$',f:tolatex(),'$ is bound by $',t:tolatex(),'$')
+ end
+\end{CAS}
+\end{codebox}
+
+\newcoderef{function PolynomialRing.gcd(poly1,poly2)}{return poly3}{poly1 PolynomialRing,..., poly3 PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing.gcd}
+
+Returns the greatest common divisor of two polynomials in a ring (assuming \texttt{poly1,poly2} belong to a Euclidean domain). For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = topoly((x^2+1)*(x-1))
+ g = topoly((x^2+1)*(x+2))
+ h = PolynomialRing.gcd(f,g)
+\end{CAS}
+\[ \gcd(\print{f},\print{g}) = \print{h} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = topoly((x^2+1)*(x-1))
+ g = topoly((x^2+1)*(x+2))
+ h = PolynomialRing.gcd(f,g)
+\end{CAS}
+\[ \gcd(\print{f},\print{g}) = \print{h} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{gcd()} shortcuts \mintinline{lua}{PolynomialRing.gcd()}. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = topoly(x^3 - x^2 + x - 1)
+ g = topoly(x^3 + 2*x^2 + x + 2)
+ h = gcd(f,g)
+\end{CAS}
+\[ \gcd(\print{f},\print{g}) = \print{h}.\]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = topoly(x^3 - x^2 + x - 1)
+ g = topoly(x^3 + 2*x^2 + x + 2)
+ h = gcd(f,g)
+\end{CAS}
+\[ \gcd(\print{f},\print{g}) = \print{h}.\]
+\end{codebox}
+
+\coderef{function PolynomialRing:isatomic()}{return false}
+\coderef{function PolynomialRing:isconstant()}{return false}
+
+The inheritances from \texttt{ConstantExpression} are overridden for the \texttt{PolynomialRing} class.
+
+\newcoderef{function PolynomialRing.monicgcdremainders(poly1,poly2)}{return table<number, Ring>}{poly1 PolynomialRing, poly2 PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing.monicgcdremainders}
+
+Given two polynomials \texttt{poly1} and \texttt{poly2}, returns a list of the remainders generated by the monic Euclidean algorithm.
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = topoly(x^13-1)
+ g = topoly(x^8-1)
+ r = PolynomialRing.monicgcdremainders(f,g)
+\end{CAS}
+\luaexec{
+ for i=1,\#r do
+ tex.print('\\[', r[i]:tolatex(), '\\]')
+ end
+}
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = topoly(x^13-1)
+ g = topoly(x^8-1)
+ r = PolynomialRing.monicgcdremainders(f,g)
+\end{CAS}
+\luaexec{
+ for i=1,\#r do
+ tex.print('\\[', r[i]:tolatex(), '\\]')
+ end
+}
+\end{codebox}
+
+\coderef{function PolynomialRing.mul_rec(poly1,poly2)}{return PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing.mul{\textunderscore}rec}
+
+Performs Karatsuba multiplication without constructing new polynomials recursively. But grade-school multiplication of polynomials is actually faster here up to a very large polynomial size due to Lua's overhead.
+
+\newcoderef{function PolynomialRing.partialfractions(g,f,ffactors)}{return BinaryOperation}{g PolynomialRing, f PolynomialRing, ffactors BinaryOperation}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing.partialfractions}
+
+Returns the partial fraction decomposition of the rational function \texttt{g/f} given \texttt{PolynomialRing}s \texttt{g, f}, and some (not necessarily irreducible) factorization \texttt{ffactors} of \texttt{f}. If the factorization is omitted, the irreducible factorization is used. The degree of \texttt{g} must be less than the degree of \texttt{f}.
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ g = topoly(4*x^2+2*x+2)
+ f = topoly((x^2+1)^2*(x+1))
+ a = PolynomialRing.partialfractions(g,f)
+\end{CAS}
+\[ \print{g/f} = \print*{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ g = topoly(4*x^2+2*x+2)
+ f = topoly((x^2+1)^2*(x+1))
+ a = PolynomialRing.partialfractions(g,f)
+\end{CAS}
+\[ \print{g/f} = \print*{a} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{parfrac()} shortcuts the more long winded \mintinline{lua}{PolynomialRing.partialfractions()}. Additionally, the \texttt{parfrac} function will automatically try to convert the first two arguments to the \texttt{PolynomialRing} type via \mintinline{lua}{topoly()}.
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ g = 4*x^2+2*x+2
+ f = (x^2+1)^2*(x+1)
+ a = parfrac(g,f)
+\end{CAS}
+\[ \print{g/f} = \print*{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ g = 4*x^2+2*x+2
+ f = (x^2+1)^2*(x+1)
+ a = parfrac(g,f)
+\end{CAS}
+\[ \print{g/f} = \print*{a} \]
+\end{codebox}
+
+\newcoderef{function PolynomialRing:rationalroots()}{return remaining, roots}{remaining PolynomialRing, roots table<number,PolynomialRing>}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:rationalroots}
+
+This method finds the factors of \texttt{PolynomialRing} (up to multiplicity) that correspond to rational roots; these factors are stored in a table \texttt{roots} and returned in the second output of the method. Those factors are then divided out of \texttt{Polynomialring}; the \texttt{PolynomialRing} that remains is returned in the first output of the method. For example:
+
+\begin{codebox}
+ \begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly((x-1)^2*(x+1)*(x^2+1))
+ g,r = f:rationalroots()
+\end{CAS}
+The factors of $f$ corresponding to rational roots are:
+\luaexec{
+ for i =1, \#r do
+ tex.print('\\[', r[i]:tolatex(), '\\]')
+ end
+}
+The part of $f$ that remains after dividing out these linear terms is:
+\[ \print{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly((x-1)^2*(x+1)*(x^2+1))
+ g,r = f:rationalroots()
+ \end{CAS}
+ The factors of $f$ corresponding to rational roots are:
+ \luaexec{
+ for i =1, \#r do
+ tex.print('\\[', r[i]:tolatex(), '\\]')
+ end
+ }
+ The part of $f$ that remains after dividing out these linear terms is:
+ \[ \print{g} \]
+\end{codebox}
+
+\coderef{function PolynomialRing:roots()}{return table<number, Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:roots}
+
+Returns a list of roots of \texttt{PolynomialRing}, simplified up to cubics. For example:
+
+\begin{codebox}[]
+ \begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly(x^6 + 3*x^5 + 6*x^4 + 7*x^3 + 6*x^2 + 3*x + 2)
+ r = f:roots()
+\end{CAS}
+$ \left\{ \lprint{r} \right\}$
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly(x^6 + 3*x^5 + 6*x^4 + 7*x^3 + 6*x^2 + 3*x + 2)
+ r = f:roots()
+\end{CAS}
+$ \left\{ \lprint{r} \right\}$
+\end{codebox}
+If the decomposition of \texttt{PolynomialRing} (or a factor thereof) is not a chain of cubics or lesser degree polynomials, then \texttt{RootExpression} is returned instead. For example:
+
+\begin{codebox}[]
+ \begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly(x^6 + x^5 - x^4 + 2*x^3 + 4*x^2 - 2)
+ r = f:roots()
+\end{CAS}
+\[ \left\{ \lprint{r} \right\} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly(x^6 + x^5 - x^4 + 2*x^3 + 4*x^2 - 2)
+ r = f:roots()
+\end{CAS}
+\[ \left\{ \lprint{r} \right\} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{roots()} shortcuts \mintinline{lua}{PolynomialRing:roots()}. Also, the function \texttt{roots} attempts to cast the argument as a polynomial automatically using \mintinline{lua}{topoly()}. For example:
+
+\begin{codebox}
+ \begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ f = x^6+x^5-x^4+2*x^3+4*x^2-2
+ r = roots(f)
+\end{CAS}
+$ \left\{ \lprint{r} \right\}$
+\end{minted}
+\tcblower
+ \begin{CAS}
+ f = x^6 + x^5 - x^4 + 2*x^3 + 4*x^2 - 2
+ r = roots(f)
+ \end{CAS}
+ $ \left\{ \lprint{r} \right\}$
+\end{codebox}
+
+\newcoderef{function PolynomialRing.resultant(a,b)}{return Field}{a PolynomialRing, b PolynomialRing}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing.resultant}
+
+Returns the resultant of two polynomials \texttt{a,b} in the same ring, whose coefficients are all part of a field. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly(x^2-2*x+1)
+ g = topoly(x^2+2*x-3)
+ r = PolynomialRing.resultant(f,g)
+\end{CAS}
+\[ \operatorname{res}(f,g) = \print{r} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly(x^2-2*x+1)
+ g = topoly(x^2+2*x-3)
+ r = PolynomialRing.resultant(f,g)
+\end{CAS}
+\[ \operatorname{res}(f,g) = \print{r} \]
+\end{codebox}
+
+\coderef{function PolynomialRing:squarefreefactorization()}{return BinaryOperation}
+\addcontentsline{toc}{subsubsection}{\ttfamily PolynomialRing:squarefreefactorization}
+
+Returns the square-free factorization of a polynomial defined over the rationals.
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = topoly(x^7 - 13*x^6 + 66*x^5 - 158*x^4 + 149*x^3 + 63*x^2 - 216*x + 108)
+ s = f:squarefreefactorization()
+\end{CAS}
+\[ \print{s} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = topoly(x^7 - 13*x^6 + 66*x^5 - 158*x^4 + 149*x^3 + 63*x^2 - 216*x + 108)
+ s = f:squarefreefactorization()
+\end{CAS}
+\[ \print{s} \]
+\end{codebox}
+
+If the polynomial is defined over $\mathbf{Z}/p\mathbf{Z}$ (where $p$ is prime), then the method \texttt{modularsquarefreefactorization()} should be used.
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{factor()} has an optional boolean argument that if set to \mintinline{lua}{true} returns \texttt{squarefreefactorization()} or \texttt{modularsquarefreefactorization()} (as appropriate). For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly(x^6 + 2*x^5 + 4*x^4 + 4*x^3 + 5*x^2 + 2*x + 2)
+ s = factor(f,true)
+\end{CAS}
+\[ \print{s} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly(x^6 + 2*x^5 + 4*x^4 + 4*x^3 + 5*x^2 + 2*x + 2)
+ s = factor(f,true)
+\end{CAS}
+\[ \print{s} \]
+\end{codebox}
+And also:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = topoly(x^6 + 2*x^5 + 4*x^4 + 4*x^3 + 5*x^2 + 2*x + 2)
+ f = Mod(f,5)
+ s = factor(f,true)
+\end{CAS}
+\[ \print{s} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = topoly(x^6 + 2*x^5 + 4*x^4 + 4*x^3 + 5*x^2 + 2*x + 2)
+ f = Mod(f,5)
+ s = factor(f,true)
+\end{CAS}
+\[ \print{s} \]
+\end{codebox}
+
+\newcoderef{function Integer.gcd(a,b)}{return Integer}{a Integer, b Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Ingeger.gcd}
+
+Returns the greatest common divisor of \texttt{a,b}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ b = 252
+ c = Integer.gcd(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ b = 252
+ c = Integer.gcd(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{gcd()} shortcuts \texttt{Integer.gcd()}. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ b = 252
+ c = gcd(a,b)
+\[ \gcd(a,b) = \print{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ b = 252
+ c = gcd(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} \]
+\end{codebox}
+
+
+\newcoderef{function Integer.extendedgcd(a,b)}{return Integer, Integer, Integer}{a Integer, b Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer.extendedgcd}
+
+Returns the greatest common divisor of \texttt{a,b} as well as Bezout's coefficients via extended gcd. For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ b = 252
+ c,x,y = Integer.extendedgcd(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} = \print{a}(\print{x}) + \print{b}(\print{y}) \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ b = 252
+ c,x,y = Integer.extendedgcd(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} = \print{a}(\print{x}) + \print{b}(\print{y}) \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{gcdext()} shortcuts \mintinline{lua}{Integer.extendedgcd()}. For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ b = 252
+ c,x,y = gcdext(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} = \print{a}(\print{x}) + \print{b}(\print{y}) \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ b = 252
+ c,x,y = gcdext(a,b)
+\end{CAS}
+\[ \gcd(a,b) = \print{c} = \print{a}(\print{x}) + \print{b}(\print{y}) \]
+\end{codebox}
+
+\newcoderef{function Integer.max(a,b)}{return Integer, Integer}{a Integer, b Integer}
+\newcoderef{function Integer.min(a,b)}{return Integer, Integer}{a Integer, b Integer}
+\addcontentsline{toc}{subsubsection}{{\ttfamily Integer.max} and {\ttfamily Integer.min}}
+
+Returns the max/min of \texttt{a,b}; the second output is the min/max (respectively).
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 8
+ b = 7
+ c = Integer.max(a,b)
+\end{CAS}
+\[ \max(\print{a},\print{b}) = \print{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 8
+ b = 7
+ c = Integer.max(a,b)
+\end{CAS}
+\[ \max(\print{a},\print{b}) = \print{c} \]
+\end{codebox}
+
+
+\newcoderef{function Integer.absmax(a,b)}{return Integer, Integer, number}{a Integer, b Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer.absmax}
+
+Methods for computing the larger magnitude of two integers. Also returns the other integer for sorting purposes, and the number -1 if the two values were swapped, 1 if not.
+
+
+\newcoderef{function Integer.ceillog(a,base)}{return Integer}{a Integer, base Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer.ceillog}
+
+Returns the ceiling of the log base (defaults to 10) of a. In other words, returns the least n such that $\mathtt{(base)^n > a}$.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 101
+ b = 10
+ c = Integer.ceillog(a,b)
+\end{CAS}
+\[ \print{c} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 101
+ b = 10
+ c = Integer.ceillog(a,b)
+\end{CAS}
+\[ \print{c} \]
+\end{codebox}
+
+\newcoderef{function Integer.powmod(a,b,n)}{return Integer}{a Integer,..., n Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer.powmod}
+
+Returns the \texttt{Integer} $c$ such that $c \equiv a^b \bmod{n}$. This should be used when $a^b$ is potentially large.
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 12341
+ b = 2^16+1
+ p = 62501
+ c = Integer.powmod(a,b,p)
+\end{CAS}
+\[ \print{c} \equiv \print{a}^{\print{b}} \bmod{\print{p}} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 12341
+ b = 2^16+1
+ p = 62501
+ c = Integer.powmod(a,b,p)
+\end{CAS}
+\[ \print{c} \equiv \print{a}^{\print{b}} \bmod{\print{p}} \]
+\end{codebox}
+
+\newcoderef{function Integer:divremainder(b)}{return Integer, Integer}{b Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer:divremainder}
+
+Returns the quotient and remainder over the integers. Uses the standard base 10 long division algorithm.
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ b = 252
+ q,r = Integer.divremainder(a,b)
+\end{CAS}
+\[ \print{a} = \print{b} \cdot \print{q} + \print{r} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ b = 252
+ q,r = Integer.divremainder(a,b)
+\end{CAS}
+\[ \print{a} = \print{b} \cdot \print{q} + \print{r} \]
+\end{codebox}
+
+\coderef{function Integer:asnumber()}{return number}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer:asnumber}
+
+Returns the integer as a floating point number. Can only approximate the value of large integers.
+
+\coderef{function Integer:divisors()}{return table<number, Integer>}
+
+Returns all positive divisors of the integer. Not guaranteed to be in any order.
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ d = a:divisors()
+\end{CAS}
+\[ \left\{ \lprint{d} \right\} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ d = a:divisors()
+\end{CAS}
+\[ \left\{ \lprint{d} \right\} \]
+\end{codebox}
+
+\coderef{function Integer:primefactorization()}{return BinaryOperation}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer:primefactorization}
+
+Returns the prime factorization of the integer as a \texttt{BinaryOperation}.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 408
+ pf = a:primefactorization()
+\end{CAS}
+\[ \print{pf} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 408
+ pf = a:primefactorization()
+\end{CAS}
+\[ \print{pf} \]
+\end{codebox}
+
+\coderef{function Integer:findafactor()}{return Integer}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer:findafactor}
+
+Return a non-trivial factor of {\ttfamily Integer} via Pollard Rho, or returns {\ttfamily Integer} if {\ttfamily Integer} is prime.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 4199
+ f = a:findafactor()
+\end{CAS}
+\[ \print{f} \mid \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 4199
+ f = a:findafactor()
+\end{CAS}
+\[ \print{f} \mid \print{a} \]
+\end{codebox}
+
+
+\coderef{function Integer:isprime()}{return bool}
+\addcontentsline{toc}{subsubsection}{\ttfamily Integer:isprime}
+
+Uses Miller-Rabin to determine whether {\ttfamily Integer} is prime up to a very large number.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ p = 7038304939
+ if p:isprime() then
+ tex.print(p:tolatex(), "is prime!")
+ end
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ p = 7038304939
+ if p:isprime() then
+ tex.print(p:tolatex(), "is prime!")
+ end
+\end{CAS}
+\end{codebox}
+
+\coderef{function Rational:reduce()}{return Rational}
+\addcontentsline{toc}{subsubsection}{\ttfamily Rational:reduce}
+
+Reduces a rational expression of integers to standard form. This method is called automatically when a new \texttt{Rational} expression is constructed:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = Rational(8,6)
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = Rational(8,6)
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+
+
+\coderef{function Rational:tocompoundexpression()}{return BinaryOperation}
+\addcontentsline{toc}{subsubsection}{\ttfamily Rational:tocompoundexpression}
+
+Converts a \texttt{Rational} expression into the corresponding \texttt{BinaryOperation} expression.
+
+\coderef{function Rational:asnumber()}{return number}
+\addcontentsline{toc}{subsubsection}{\ttfamily Rational:asnumber}
+
+Returns the given rational as an approximate floating point number. Going the other way, the parser in \mintinline{latex}{\begin{CAS}..\end{CAS}} will convert decimals (as written) to fractions. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ a = 0.375
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 0.375
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+
+\coderef{function SqrtExpression:topower()}{return BinaryOperation}
+\addcontentsline{toc}{subsubsection}{\ttfamily SqrtExpression:topower}
+
+Converts a \texttt{SqrtExpression} to the appropriate \texttt{BinaryOperation}. For example, consider:
+\begin{minted}{latex}
+\begin{CAS}
+ a = sqrt(3)
+ b = a:topower()
+\end{CAS}
+\end{minted}
+\begin{CAS}
+ a = sqrt(3)
+ b = a:topower()
+\end{CAS}
+Then:
+\begin{multicols}{2}
+ \begin{center}
+ \underline{Expression shrub for \texttt{a}:}
+
+ \parseshrub{a}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill = gray!20,
+ s sep = 1cm}
+ @\shrubresult
+ \end{forest}
+
+ \columnbreak
+
+ \underline{Expression shrub for \texttt{b}:}
+
+ \parseshrub{b}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill = gray!20,
+ s sep = 1.75cm}
+ @\shrubresult
+ \end{forest}
+ \end{center}
+\end{multicols}
+
+\newcoderef{function Equation:solvefor(var)}{return Equation}{var SymbolExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily Equation:solvefor}
+
+Attempts to solve the equation for a particular variable.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars("x", "y", "z")
+ lhs = e ^ (x^2 * y)
+ rhs = z + 1
+ eq = Equation(lhs, rhs):autosimplify()
+ eqx = eq:solvefor(x)
+\end{CAS}
+\[ \print{eq} \to \print{eqx} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars("x", "y", "z")
+ lhs = e ^ (x^2 * y)
+ rhs = z + 1
+ eq = Equation(lhs, rhs):autosimplify()
+ eqx = eq:solvefor(x)
+\end{CAS}
+\[ \print{eq} \to \print{eqx} \]
+\end{codebox}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus.tex b/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus.tex
new file mode 100644
index 0000000000..31d52ab868
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus.tex
@@ -0,0 +1,225 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,
+ size=small,
+ bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}
+ },
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\usetikzlibrary{shapes.multipart}
+\useforestlibrary{edges}
+
+\def\error{\color{red}}
+\def\self{\color{gray}}
+\def\call{$\star$ }
+
+\begin{document}
+\thispagestyle{empty}
+
+\section{Calculus}
+ This section contains reference materials for the calculus functionality of \texttt{luacas}. The classes in this module are diagramed below according to inheritance along with the methods/functions one can call upon them.
+ \begin{itemize}
+ \item {\error\ttfamily\itshape method}: an abstract method;
+ \item {\self\ttfamily\itshape method}: a method that returns the expression unchanged;
+ \item {\ttfamily\itshape method}: method that is either unique, implements an abstract method, or overrides an abstract
+method;
+ \item {\tikz[baseline=-0.5ex]\node[fill=roseorange!30] {\ttfamily\bfseries Class};}: a concrete class.
+ \end{itemize}
+Here is an inheritance diagram of the classes in the calculus module; all these classes inherit from the \texttt{CompoundExpression} branch of the inheritance tree. Most methods are stated, but some were omitted (because they inherit in the obvious way, they are auxiliary and not likely to be interesting to the end-user, etc).
+ \vfill
+\forestset{
+rectcore/.style = {rectangle split,
+ rectangle split parts=2,
+ draw = {rosenavy,thick},
+ rounded corners = 1pt,
+ font = \ttfamily\bfseries,
+ fill = roseblue!#1
+ },
+rectalg/.style = {rectangle split,
+ rectangle split parts=2,
+ draw = {rose,thick},
+ rounded corners = 1pt,
+ font = \ttfamily\bfseries,
+ fill = rose!#1
+ },
+rectcalc/.style = {rectangle split,
+ rectangle split parts=2,
+ draw = {roseorange,thick},
+ rounded corners = 1pt,
+ font = \ttfamily\bfseries,
+ fill = roseorange!#1
+ }
+}
+\forestset{
+ multiple directions/.style={
+ for tree={#1},
+ phantom,
+ for relative level=1{
+ no edge,
+ delay={
+ !c.content/.pgfmath=content("!u")},
+ before computing xy={l=0,s=0}
+ }
+ },
+ multiple directions/.default={},
+ grow subtree/.style={for tree={grow=#1}},
+ grow' subtree/.style={for tree={grow'=#1}}}
+\tikzset{
+ every two node part/.style={font=\ttfamily\itshape\footnotesize}
+}
+\begin{center}
+ \begin{forest}
+ for tree = {node options={align=left},
+ edge = {-stealth}
+ },
+ forked edges
+ [Expression\nodepart{two}$\cdots$,rectcore={0}
+ [CompoundExpressions\nodepart{two}$\cdots$,rectcore={0}
+ [DerivativeExpression\nodepart{two}
+ :new() \\
+ :evaluate()\\
+ :autosimplify()
+ ,rectcalc=30]
+ [DiffExpression\nodepart{two}
+ :new()\\
+ :evaluate()\\
+ :autosimplify()
+ ,rectcalc=30]
+ [IntegralExpression\nodepart{two}
+ :new()\\
+ :isdefinite()\\
+ .table()\\
+ .linearproperties()\\
+ .substitutionmethod()\\
+ .enhancedsubstitutionmethod()\\
+ .rationalfunction()\\
+ .partsmethod()\\
+ .eulersformula()\\
+ .integrate()
+ ,rectcalc=30]
+ ]
+ ]
+ \end{forest}
+\end{center}
+\vfill
+
+\end{document}
+
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_classes/ref_calculus_classes.tex b/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_classes/ref_calculus_classes.tex
new file mode 100644
index 0000000000..b08a190625
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_classes/ref_calculus_classes.tex
@@ -0,0 +1,277 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+\usepackage{fontawesome}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\begin{document}
+\setdescription{style=multiline,
+ topsep=10pt,
+ leftmargin=5cm,
+ }
+
+\subsection{Calculus Classes}
+
+There are only a few classes (currently) in the calculus module all of which are concrete:
+\begin{itemize}
+ \item {\ttfamily DerivativeExpression}
+ \item {\ttfamily DiffExpression}
+ \item {\ttfamily IntegralExpression}
+\end{itemize}
+
+\newcoderef{function DerivativeExpression:new(expression, symbol)}{return DerivativeExpression}{expression Expression, symbol SymbolExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily DerivativeExpression}
+
+Creates a new single-variable derivative operation of the given \texttt{expression} with respect to the given \texttt{symbol}. If \texttt{symbol} is omitted, then \texttt{symbol} takes the default value of \mintinline{lua}{SymbolExpression("x")}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('x')
+f = DerivativeExpression(sin(x)/x)
+tex.print('\\[', f:tolatex(), '\\]')
+\end{minted}
+\tcblower
+\luaexec{
+ vars('x')
+ f = DerivativeExpression(sin(x)/x)
+ tex.print('\\[', f:tolatex(), '\\]')
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{DD()} shortcuts \mintinline{lua}{DerivativeExpression()}.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = DD(sin(x)/x)
+\end{CAS}
+\[ \print{f} \]
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = DD(sin(x)/x)
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+Alternatively, one could also use \mintinline{lua}{diff()} (see below).
+
+\newcoderef{function DiffExpression:new(expression, symbols)}{return DiffExpression}{expression Expression, symbols table<number, Symbol>}
+\addcontentsline{toc}{subsubsection}{\ttfamily DiffExpression}
+
+Creates a new multi-variable higher-order derivative operation of the given \texttt{expression} with respect to the given \texttt{symbols}. As opposed to \texttt{DerivativeExpression}, the argument \texttt{symbols} cannot be omitted. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('x','y')
+f = DiffExpression(sin(x*y)/y,{x,y})
+tex.print('\\[', f:tolatex(), '\\]')
+\end{minted}
+\tcblower
+\luaexec{
+ vars('x','y')
+ f = DiffExpression(sin(x*y)/y,{x,y})
+ tex.print('\\[', f:tolatex(), '\\]')
+}
+\end{codebox}
+We can also use \texttt{DiffExpression} to create higher-order single variable derivatives:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('x')
+f = DiffExpression(sin(x)/x,{x,x})
+tex.print('\\[', f:tolatex(), '\\]')
+\end{minted}
+\tcblower
+\luaexec{
+ vars('x')
+ f = DiffExpression(sin(x)/x,{x,x})
+ tex.print('\\[', f:tolatex(), '\\]')
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{diff()} shortcuts \mintinline{lua}{DiffExpression()}. The arguments of \mintinline{lua}{diff()} can also be given in a more user-friendly, compact form. For example:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','y')
+ f = diff(sin(x)/x, {x,2})
+ g = diff(sin(x*y)/y,x,{y,2})
+\end{CAS}
+\[ \print{f} = \print*{f} \qquad \print{g} = \print*{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y')
+ f = diff(sin(x)/x, {x,2})
+ g = diff(sin(x*y)/y,x,{y,2})
+\end{CAS}
+\[ \print{f} = \print*{f} \qquad \print{g} = \print*{g} \]
+\end{codebox}
+
+\newcoderef{function IntegralExpression:new(expression,symbol,lower,upper)}{return IntegralExpression}{expression Expression, symbol SymbolExpression, lower Expression, upper Expression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression}
+
+Creates a new integral operation of the given \texttt{expression} with respect to the given \texttt{symbol} over the given \texttt{lower} and \texttt{upper} bounds. If \texttt{lower} and \texttt{upper} are omitted, then an \emph{indefinite} \texttt{IntegralExpression} is constructed. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small,breaklines]{lua}
+vars('x')
+f = IntegralExpression(sin(sqrt(x)), x)
+g = IntegralExpression(sin(sqrt(x)), x, Integer.zero(), pi)
+tex.print('\\[', f:tolatex(), '\\]')
+tex.print('\\[', g:tolatex(), '\\]')
+\end{minted}
+\tcblower
+\luaexec{
+ vars('x')
+ f = IntegralExpression(sin(sqrt(x)),x)
+ g = IntegralExpression(sin(sqrt(x)),x,Integer.zero(),pi)
+ tex.print('\\[', f:tolatex(), '\\]')
+ tex.print('\\[', g:tolatex(), '\\]')
+}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The function \mintinline{lua}{int()} shortcuts \mintinline{lua}{IntegralExpression()}. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ g = int(sin(sqrt(x)),x,0,pi)
+\end{CAS}
+\[ \print{g} = \print*{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ g = int(sin(sqrt(x)),x,0,pi)
+\end{CAS}
+\[ \print{g} = \print*{g} \]
+\end{codebox}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_methods/ref_calculus_methods.tex b/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_methods/ref_calculus_methods.tex
new file mode 100644
index 0000000000..c64baa5934
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_calculus/ref_calculus_methods/ref_calculus_methods.tex
@@ -0,0 +1,473 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+\usepackage{fontawesome5}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\DeclareTotalTCBox{\lilcoderef}{O{} m m}{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ enhanced,
+ nobeforeafter,
+ tcbox raise base,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=1mm,
+ right=1mm,
+ top=1mm,
+ bottom=1mm,
+ oversize,
+ #1
+}{\mintinline{lua}{#2} \mintinline{lua}{#3}}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+\usepackage{marginnote}
+
+\begin{document}
+\setdescription{style=multiline,
+ topsep=10pt,
+ leftmargin=6.5cm,
+ }
+
+\subsection{Calculus Methods}
+
+\newcoderef{function IntegralExpression.table(integral)}{return Expression|nil}{integral IntegralExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.table}
+
+Attempts to integrate \texttt{integral.expression} with respect to \texttt{integral.symbol} by checking a table of basic integrals; returns nil if the integrand isn't in the table. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = int(cos(x),x)
+ f = f:table()
+ g = int(x*cos(x),x)
+ g = g:table()
+\end{CAS}
+\[ f = \print{f} \qquad g = \print{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = int(cos(x),x)
+ f = f:table()
+ g = int(x*cos(x),x)
+ g = g:table()
+ \end{CAS}
+\[ f = \print{f} \qquad g = \print{g} \]
+\end{codebox}
+The table of integrals consists of power functions, exponentials, logarithms, trigonometric, and inverse trigonometric functions.
+
+\newcoderef{function IntegralExpression.linearproperties(integral)}{return Expression|nil}{integral IntegralExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.linearproperties}
+
+Attempts to integrate \texttt{integral.expression} with respect to \texttt{integral.symbol} by using linearity properties (e.g. the integral of a sum/difference is the sum/difference of integrals); returns nil if any individual component cannot be integrated using \mintinline{lua}{IntegralExpression:integrate()}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = int(sin(x) + e^x,x)
+ g = f:table()
+ f = f:linearproperties()
+\end{CAS}
+\[ f = \print*{f} \qquad g = \print*{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = int(sin(x) + e^x,x)
+ g = f:table()
+ f = f:linearproperties()
+\end{CAS}
+\[ f = \print*{f} \qquad g = \print*{g} \]
+\end{codebox}
+
+\newcoderef{function IntegralExpression.substitutionmethod(integral)}{return Expression|nil}{integral IntegralExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.substitutionmethod}
+
+Attempts to integrate \texttt{integral.expression} with respect to \texttt{integral.symbol} via $u$-substitution; returns nil if no suitable substitution is found to be successful.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = int(x*e^(x^2),x)
+ g = int(x*e^x,x)
+ f = f:substitutionmethod()
+ g = g:substitutionmethod()
+\end{CAS}
+\[ f = \print*{f} \qquad g = \print*{g}.\]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = int(x*e^(x^2),x)
+ g = int(x*e^x,x)
+ f = f:substitutionmethod()
+ g = g:substitutionmethod()
+\end{CAS}
+\[ f = \print*{f} \qquad g = \print*{g}.\]
+\end{codebox}
+
+\newcoderef{function IntegralExpression.enhancedsubstitutionmethod(integral)}{return Expression|nil}{integral IntegralExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.enhancedsubstitutionmethod}
+
+Attempts integrate \texttt{integral.expression} with respect to \texttt{integral.symbol} via $u$-substitutions. This method distinguishes itself from the \mintinline{lua}{.substitutionmethod} by attempted to solve $u= g(x)$ for the original variable and then substituting the result into the expression. This behavior is not included in \mintinline{lua}{.substitutionmethod} due to speed concerns. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = int(x^5*sqrt(x^3+1),x)
+ g = f:substitutionmethod()
+ h = f:enhancedsubstitutionmethod()
+\end{CAS}
+\[ g= \print*{g} \]
+\[ h= \print*{h} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = int(x^5*sqrt(x^3+1),x)
+ g = f:substitutionmethod()
+ h = f:enhancedsubstitutionmethod()
+\end{CAS}
+\[ g= \print*{g} \]
+\[ h= \print*{h} \]
+\end{codebox}
+
+
+\newcoderef{function IntegralExpression.trialsubstitutions(Expression)}{return table<number, Expression}{}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.trialsubstitutions}
+
+Generates a list of possible $u$-substitutions to attempt in \texttt{substitutionmethod()} and \texttt{enhancedsubstitutionmethod()}. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = cos(x)/(1+sin(x))
+ f = f:autosimplify()
+ l = IntegralExpression.trialsubstitutions(f)
+\end{CAS}
+$\left\{ \lprint{l} \right\}$.
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = cos(x)/(1+sin(x))
+ f = f:autosimplify()
+ l = IntegralExpression.trialsubstitutions(f)
+\end{CAS}
+$ \left\{ \lprint{l} \right\}$.
+\end{codebox}
+
+
+\newcoderef{function IntegralExpression.rationalfunction(IntegralExpression)}{return Expression|nil}{}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.rationalfunction}
+
+Integrates \texttt{integrand} with respect to \texttt{symbol} via Lazard, Rioboo, Rothstein, and Trager's method in the case when \texttt{expression} is a rational function in the variable \texttt{symbol}. If \texttt{integrand} is not a rational function, then nil is returned.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = (x^2+2*x+2)/(x^2+3*x+2)
+ f = f:autosimplify()
+ g = int(f,x):rationalfunction()
+\end{CAS}
+\[ \int \print{f}\ dx = \print*{g} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = (x^2+2*x+2)/(x^2+3*x+2)
+ f = f:autosimplify()
+ g = int(f,x):rationalfunction()
+\end{CAS}
+\[ \int \print{f}\ dx = \print*{g} \]
+\end{codebox}
+
+In some cases, the \mintinline{lua}{.rationalfunction} method returns non-standard results. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ num = x^2
+ den = ((x+1)*(x^2+2*x+2)):expand()
+ f = (num/den):autosimplify()
+ f = int(f,x):rationalfunction()
+\end{CAS}
+\[ \print{simplify(f)} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ num = x^2
+ den = ((x+1)*(x^2+2*x+2)):expand()
+ f = (num/den):autosimplify()
+ f = int(f,x):rationalfunction()
+\end{CAS}
+\[ \print{simplify(f)} \]
+\end{codebox}
+On the other hand:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ pfrac = parfrac(num,den)
+\end{CAS}
+\[ \print*{int(pfrac,x)} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ pfrac = parfrac(num,den)
+ \end{CAS}
+\[ \print*{int(pfrac,x)} \]
+\end{codebox}
+
+\newcoderef{function IntegralExpression.partsmethod(IntegralExpression)}{return Expression|nil}{}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.partsmethod}
+
+Attempts to integrate \texttt{integral.expression} with respect to \texttt{integral.symbol} via \emph{integration by parts}; returns nil if no suitable application of IBP is found. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ a = int(x*e^x,x)
+ b = a:partsmethod()
+ c = int(e^(x^2),x)
+ d = c:partsmethod()
+\end{CAS}
+\[ b=\print*{b} \]
+\[ d=\print*{d} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ a = int(x*e^x,x)
+ b = a:partsmethod()
+ c = int(e^(x^2),x)
+ d = c:partsmethod()
+\end{CAS}
+\[ b= \print*{b} \]
+\[ d= \print*{d} \]
+\end{codebox}
+
+
+\newcoderef{function IntegralExpression.eulersformula(integral)}{return Expression|nil}{integral IntegralExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.eulersformula}
+
+Attempts to integrate \texttt{integral.expression} with respect to \texttt{integral.symbol} by using the Euler formulas:
+\[ \cos x = \frac{e^{ix} + e^{-ix}}{2} \qquad \sin x = \frac{e^{ix} - e^{-ix}}{2i}.\]
+Per usual, this method returns nil if such a method is unsuccessful (or if the integrand is unchanged after applying the above substitutions). This can often be used as an alternative for integration by parts. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ a = int(e^x*sin(x),x)
+ b = int(x^2,x)
+ c = a:eulersformula()
+ d = b:eulersformula()
+\end{CAS}
+\[ c= \print*{c} \]
+\[ d= \print*{d} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ a = int(e^x*sin(x),x)
+ b = int(x^2,x)
+ c = a:eulersformula()
+ d = b:eulersformula()
+\end{CAS}
+\[ c= \print*{c} \]
+\[ d= \print*{d} \]
+\end{codebox}
+
+\newcoderef{function IntegralExpression.integrate(integral)}{return Expression|nil}{integral IntegralExpression}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.integrate}
+
+Recursive part of the indefinite integral operator; returns nil if the expression could not be integrated. The methods above get called (roughly) in the following order:
+\begin{enumerate}[(i)]
+ \item \mintinline{lua}{.table}
+ \item \mintinline{lua}{.linearproperties}
+ \item \mintinline{lua}{.substitutionmethod}
+ \item \mintinline{lua}{.rationalfunction}
+ \item \mintinline{lua}{.partsmethod}
+ \item \mintinline{lua}{.eulersformula}
+ \item \mintinline{lua}{.enhancedsubstitutionmethod}
+\end{enumerate}
+Between (vi) and (vii), the \mintinline{lua}{.integrate} method will attempt to expand the integrand and retry. The method is recursive in the sense that (most) of the methods listed above will call \mintinline{lua}{.integrate} at some point. For example, after a list of trial substitutions is created, the method \mintinline{lua}{.substitutionmethod} will call \mintinline{lua}{.integrate} to determine whether the new integrand can be integrated via the methods in the above list.
+
+\subsubsection*{Parsing}
+
+Recall the function \mintinline{lua}{int()} which acts as a shortcut for \mintinline{lua}{IntegralExpression:new()}. When \mintinline{lua}{:autosimplify()} is called upon an \texttt{IntegralExpression}, then \mintinline{lua}{IntegralExpression.integrate} is applied. If \mintinline{lua}{nil} is returned, then \mintinline{lua}{:autosimplify()} returns \mintinline{lua}{self}; otherwise the result of \mintinline{lua}{.integrate} is returned and evaluated over the bounds, if any are given. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = cos(x)*e^(sin(x))
+ f = int(f,x,0,pi/2)
+\end{CAS}
+\[ \print{f} = \print*{f}\]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = cos(x)*e^(sin(x))
+ f = int(f,x,0,pi/2)
+\end{CAS}
+\[ \print{f} = \print*{f}\]
+\end{codebox}
+
+On the other hand:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = e^(e^x)
+ f = int(f,x,0,1)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = e^(e^x)
+ f = int(f,x,0,1)
+\end{CAS}
+\[ \print{f} = \print*{f} \]
+\end{codebox}
+
+\coderef{function IntegralExpression:isdefinite()}{return bool}
+\addcontentsline{toc}{subsubsection}{\ttfamily IntegralExpression.isdefinite}
+
+Returns \mintinline{lua}{true} of \texttt{IntegralExpression} is definite (i.e. if \texttt{.upper} and \texttt{.lower} are defined fields), otherwise returns \mintinline{lua}{false}.
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core.tex b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core.tex
new file mode 100644
index 0000000000..668eda73a1
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core.tex
@@ -0,0 +1,249 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\index{\currref!\texttt{#1}}%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\index{\currref!\texttt{#1}}%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+\usetikzlibrary{shapes.multipart}
+\useforestlibrary{edges}
+
+\def\error{\color{red}}
+\def\self{\color{gray}}
+\def\call{}
+
+\begin{document}
+\thispagestyle{empty}
+
+\section{Core}
+ This section contains reference materials for the core functionality of \texttt{luacas}. The classes in this module are diagramed below according to inheritance along with the methods/functions one can call upon them.
+ \begin{itemize}
+ \item {\error\ttfamily\itshape method}: an abstract method (a method that must be implemented by a subclass to be called);
+ \item {\self\ttfamily\itshape method}: a method that returns the expression unchanged;
+ \item {\ttfamily\itshape method}: a method that is either unique, implements an abstract method, or overrides an abstract method;
+ \item {\tikz[baseline=-0.5ex]\node[fill=roseblue!50] {\ttfamily\bfseries Class};}: a concrete class.
+ \end{itemize}
+
+\forestset{
+rect/.style = {rectangle split,
+ rectangle split parts=2,
+ draw = {rosenavy,thick},
+ rounded corners = 1pt,
+ font = \ttfamily\bfseries,
+ }
+}
+\tikzset{
+ every two node part/.style={font=\ttfamily\itshape\footnotesize}
+}
+\begin{center}
+ \begin{forest}
+ for tree = {node options={align=left},
+ rect,
+ grow= south,
+ parent anchor=south,
+ child anchor=north,
+ edge = {-stealth}
+ },
+ forked edges
+ [Expression\nodepart{two}\begin{minipage}{0.5\textwidth}\vskip-0.2cm\begin{multicols}{2}
+ {\error :evaluate()} \\
+ {\error :autosimplify()} \\
+ :simplify() \\
+ :size() \\
+ {\error :subexpressions()} \\
+ {\error :setsubexpressions()} \\
+ {\error :freeof(symbol)} \\
+ {\error :substitute(map)} \\
+ {\self :expand()} \\
+ {\self :factor()} \\
+ {\self :combine()} \\
+ :getsubexpressionsrec() \\
+ {\error :isatomic()} \\
+ {\error :isconstant()} \\
+ :isrealconstant() \\
+ :iscomplexconstant() \\
+ {\error :order(other)} \\
+ {\self :topolynomial()} \\
+ {\error :tolatex()} \\
+ :type()\end{multicols}\end{minipage}
+ [AtomicExpression\nodepart{two}
+ {\self :tocompoundexpression()} \\
+ {\self :evaluate()} \\
+ {\self :autosimplify()} \\
+ :subexpressions() \\
+ {\self :setsubexpressions()} \\
+ :substitute(map) \\
+ :isatomic() \\
+ :tolatex()
+ [SymbolExpression\nodepart{two}
+ {\call :new(symbol)} \\
+ :freeof(symbol) \\
+ :isconstant() \\
+ :order(other) \\
+ :topolynomial()
+ ,fill = roseblue!50]
+ [ConstantExpression\nodepart{two}
+ :freeof(symbol)\\
+ :isconstant() \\
+ :order(other)
+ ]
+ ]
+ [CompoundExpression\nodepart{two}
+ :freeof(symbol) \\
+ :substitute(map) \\
+ :isatomic() \\
+ :isconstant()
+ [BinaryOperation\nodepart{two}
+ {\call :new(operation,expressions)} \\
+ :evaluate() \\
+ :autosimplify() (!)\\
+ :subexpressions() \\
+ :setsubexpressions() \\
+ :expand() \\
+ :factor() \\
+ :combine() \\
+ :order(other) \\
+ {:iscommutatitve()}\\
+ :topolynomial() \\
+ :tolatex()
+ , fill=roseblue!50]
+ [FunctionExpression\nodepart{two}
+ {\call :new(name,expressions)}\\
+ :evaluate()\\
+ :autosimplify()\\
+ :subexpressions()\\
+ :setsubexpressions()\\
+ :order(other)\\
+ :tolatex()
+ , fill=roseblue!50]
+ ]
+ ]
+ \end{forest}
+\end{center}
+The number of core methods should generally be kept small, since every new type of expression must implement all of these methods. The exception to this, of course, is core methods that call other core methods that provide a unified interface to expressions. For instance, {\ttfamily size()} calls {\ttfamily subexpressions()}, so it only needs to be implemented in the expression interface.
+
+All expressions should also implement the {\ttfamily \_\_tostring} and {\ttfamily \_\_eq} metamethods. Metamethods cannot be inherited using Lua, thus every expression object created by a constructor must assign a metatable to that object.
+
+\begin{itemize}
+ \item {\ttfamily \_\_tostring} provides a human-readable version of an expression for printing within Lua and exporting to external programs.
+
+ \item {\ttfamily \_\_eq} determines whether an expression is structurally identical to another expression.
+\end{itemize}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex
new file mode 100644
index 0000000000..77e80aa16f
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex
@@ -0,0 +1,455 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+\usepackage{fontawesome5}
+\usepackage{marginnote}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\begin{document}
+
+\subsection{Core Classes}
+
+There are several classes in the core module; but only some classes are concrete:
+
+\begin{multicols}{2}
+ \begin{center}
+ \underline{Abstract classes:}
+ \begin{itemize}
+ \item \texttt{Expression}
+ \item \texttt{AtomicExpression}
+ \item \texttt{CompoundExpression}
+ \item \texttt{ConstantExpression}
+ \end{itemize}
+
+ \underline{Concrete classes:}
+ \begin{itemize}
+ \item \texttt{SymbolExpression}
+ \item \texttt{BinaryOperation}
+ \item \texttt{FunctionExpression}
+ \end{itemize}
+\end{center}
+\end{multicols}
+
+The abstract classes provide a unified interface for the concrete classes (expressions) using inheritance. \emph{Every} expression in \texttt{luacas} inherits from either {\ttfamily AtomicExpression} or {\ttfamily CompoundExpression} which, in turn, inherit from {\ttfamily Expression}.
+
+\coderef{function SymbolExpression:new(string)}{return SymbolExpression}
+\index{Core!Classes!\texttt{SymbolExpression}}
+\addcontentsline{toc}{subsubsection}{\ttfamily SymbolExpression}
+
+Creates a new \texttt{SymbolExpression}. For example:
+\begin{codebox}[]
+\begin{minted}[breaklines,fontsize=\small]{lua}
+foo = SymbolExpression("bar")
+tex.sprint("The Lua variable ``foo'' is the SymbolExpression: ", foo:tolatex(),".")
+\end{minted}
+\tcblower
+\directlua{
+foo = SymbolExpression("bar")
+tex.sprint("The Lua variable 'foo' is the SymbolExpression: ", foo:tolatex(),".")
+}
+\end{codebox}
+
+\subsubsection*{Fields}
+
+\texttt{SymbolExpression}s have only one field: \texttt{symbol}. In the example above, the string \mintinline{lua}{"bar"} is stored in \mintinline{lua}{foo.symbol}.
+
+\subsubsection*{Parsing}
+
+The command \mintinline{lua}{vars()} in \texttt{test.parser} creates a new \texttt{SymbolExpression} for every string in the argument; each such \texttt{SymbolExpression} is assigned to a variable of the same name. For example:
+
+\begin{minted}{lua}
+vars('x','y')
+\end{minted}
+
+is equivalent to:
+
+\begin{minted}{lua}
+x = SymbolExpression("x")
+y = SymbolExpression("y")
+\end{minted}
+
+\newcoderef{function BinaryOperation:new(operation, expressions)}{return BinaryOperation}{operation function, expressions table<number,Expression>}
+\index{Core!Classes!\texttt{BinaryOperation}}
+\addcontentsline{toc}{subsubsection}{\ttfamily BinaryOperation}
+
+Creates a new \texttt{BinaryOperation} expression. For example:
+
+\begin{codebox}
+\begin{minted}[fontsize=\small]{lua}
+vars('x','y','z')
+w = BinaryOperation(
+ BinaryOperation.ADD,
+ {BinaryOperation(
+ BinaryOperation.MUL,
+ {x,y}
+ ),y,z}
+)
+tex.print("\\[w=",w:tolatex(),"\\]")
+\end{minted}
+\tcblower
+\directlua{
+vars('x','y','z')
+w = BinaryOperation(
+ BinaryOperation.ADD,
+ {BinaryOperation(
+ BinaryOperation.MUL,
+ {x,y}
+ ),y,z}
+)
+tex.print("\\[w=",w:tolatex(),"\\]")
+}
+\end{codebox}
+The variable \texttt{operation} must be a function \mintinline{lua}{function f(a,b)} assigned to one of the following types:
+\bgroup
+\setdescription{style=multiline,
+ topsep=10pt,
+ leftmargin=4.5cm,
+ font=\ttfamily
+ }
+\begin{description}
+ \item[BinaryOperation.ADD:] \mintinline{lua}{return a + b}
+ \item[BinaryOperation.SUB:] \mintinline{lua}{return a - b}
+ \item[BinaryOperation.MUL:] \mintinline{lua}{return a * b}
+ \item[BinaryOperation.DIV:] \mintinline{lua}{return a / b}
+ \item[BinaryOperation.IDIV:] \mintinline{lua}{return a // b}
+ \item[BinaryOperation.MOD:] \mintinline{lua}{return a % b}
+ \item[BinaryOperation.POW:] \mintinline{lua}{return a ^ b}
+\end{description}
+\egroup
+The variable \texttt{expressions} must be a table of \texttt{Expression}s index by Lua numbers.
+
+\subsubsection*{Fields}
+
+\texttt{BinaryOperation}s have the following fields: \texttt{name}, \texttt{operation}, and \texttt{expressions}. In the example above, we have:
+\begin{itemize}
+ \item the variable \texttt{expressions} is stored in \mintinline{lua}{w.expressions};
+ \item \mintinline{lua}{w.name} stores the string \mintinline{lua}{"+"}; and
+ \item \mintinline{lua}{w.operation} stores the function:
+ \begin{minted}{lua}
+BinaryOperation.ADD = function(a, b)
+ return a + b
+end
+ \end{minted}
+\end{itemize}
+
+\begin{multicols}{2}
+The entries of \texttt{w.expressions} can be used/fetched in a reasonable way:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+$\print{w.expressions[1]} \quad
+ \print{w.expressions[2]} \quad
+ \print{w.expressions[3]}$
+ \end{minted}
+ \tcblower
+$\print{w.expressions[1]} \quad
+ \print{w.expressions[2]} \quad
+ \print{w.expressions[3]}$
+\end{codebox}
+
+\begin{center}
+ \bracketset{action character = @}
+ \parseshrub{w}
+ \begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill = gray!20,
+ l sep = 1.5cm,
+ s sep = 2cm}
+ @\shrubresult
+ \end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+Thank goodness for this. Creating new \texttt{BinaryOperation}s isn't nearly as cumbersome as the above would indicate. Using Lua's powerful metamethods, we can parse expressions easily. For example, the construction of \texttt{w} given above can be done much more naturally using:
+\begin{codebox}
+\begin{minted}[fontsize=\small]{lua}
+vars('x','y','z')
+w = x*y+y+z
+tex.print("\\[w=", w:tolatex(), "\\]")
+\end{minted}
+\tcblower
+\directlua{
+ vars('x','y','z')
+ w = x*y+y+z
+ tex.print("\\[w=", w:tolatex(), "\\]")
+}
+\end{codebox}
+\reversemarginpar
+{\bf Warning:}\marginnote{\color{rose}\faExclamationTriangle} There are escape issues to be aware of with the operator \mintinline{latex}{%}. If you're writing custom \texttt{luacas} functions in a separate \texttt{.lua} file, then there are no issues; use \mintinline{latex}{%} with reckless abandon. But when using the operator \mintinline{latex}{%} within, say \mintinline{latex}{\begin{CAS}..\end{CAS}}, then one should write \mintinline{latex}{\%} in place of \mintinline{latex}{%}:
+
+\begin{codebox}
+\begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ a = 17
+ b = 5
+ c = a \% b
+\end{CAS}
+\[ \print{c} \equiv \print{a} \bmod{\print{b}} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 17
+ b = 5
+ c = a \% b
+\end{CAS}
+\[ \print{c} \equiv
+ \print{a} \bmod{\print{b}} \]
+\end{codebox}
+The above escape will {\bf not} work with \mintinline{latex}{\directlua}, but it will work for \mintinline{latex}{\luaexec} from the \texttt{luacode} package. Indeed, the \texttt{luacode} package was designed (in part) to make escapes like this more manageable. Here is the equivalent code using \mintinline{latex}{\luaexec}:
+\begin{codebox}[]
+\begin{minted}[fontsize=\small]{lua}
+a = Integer(17)
+b = Integer(5)
+c = a \% b
+tex.print("\\[",c:tolatex(),"\\equiv",a:tolatex(), "\\bmod{",b:tolatex(),"} \\]")
+\end{minted}
+\tcblower
+\luaexec{
+a = Integer(17)
+b = Integer(5)
+c = a \% b
+tex.print("\\[", c:tolatex(), "\\equiv", a:tolatex(), "\\bmod{", b:tolatex(), "} \\]")
+}
+\end{codebox}
+
+\newcoderef{function FunctionExpression:new(name,expressions)}{return FunctionExpression}{name string|SymbolExpression, expressions table<number,Expression>}
+\index{Core!Classes!\texttt{FunctionExpression}}
+\addcontentsline{toc}{subsubsection}{\ttfamily FunctionExpression}
+
+Creates a generic function. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('x','y')
+f = FunctionExpression('f',{x,y})
+tex.print("\\[",f:tolatex(),"\\]")
+ \end{minted}
+ \tcblower
+ \luaexec{
+ vars('x','y')
+ f = FunctionExpression('f',{x,y})
+ tex.print("\\[",f:tolatex(),"\\]")
+ }
+\end{codebox}
+The variable \texttt{name} can be a string (like above), or another \texttt{SymbolExpression}. But in this case, the variable \texttt{name} just takes the value of the string \mintinline{lua}{SymbolExpression.symbol}. The variable \texttt{expressions} must be a table of \texttt{Expression}s indexed by Lua numbers.
+
+\subsubsection*{Fields}
+\texttt{FunctionExpression}s have the following fields: \texttt{name}, \texttt{expressions}, \texttt{variables}, \texttt{derivatives}. In the example above, we have:
+\begin{itemize}
+ \item the variable \texttt{name}, i.e. the string \mintinline{lua}{'f'}, is stored in \mintinline{lua}{f.name}; and
+ \item the variable \texttt{expressions}, i.e. the table \mintinline{lua}{{x,y}} is stored in \mintinline{lua}{f.expressions}.
+\end{itemize}
+
+Wait a minute, what about \texttt{variables} and \texttt{derivatives}!? The field \texttt{variables} essentially stores a copy of the variable \texttt{expressions} \textit{as long as} the entries in that table are atomic. If they aren't, then \texttt{variables} will default to $x,y,z$, or $x_1,x_2,\ldots$ if the number of variables exceeds $3$. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('s','t')
+f = FunctionExpression('f',{s*s,s+t+t})
+tex.print("The variables of f are:")
+for _,symbol in ipairs(f.variables) do
+ tex.print(symbol:tolatex())
+end
+ \end{minted}
+ \tcblower
+\luaexec{
+ vars('s','t')
+ f = FunctionExpression('f',{s*s,s+t+t})
+ tex.print("The variables of f are:")
+ for _,symbol in ipairs(f.variables) do
+ tex.print(symbol:tolatex())
+ end
+}
+\end{codebox}
+The field \texttt{derivatives} is a table of \texttt{Integer}s indexed by Lua numbers whose length equals \mintinline{lua}{#o.variables}. The default value for this table is a table of (\texttt{Integer}) zeros. So for the example above, we have:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+for _,integer in ipairs(f.derivatives) do
+ if integer == Integer.zero() then
+ tex.print("I'm a zero.\\newline")
+ end
+end
+\end{minted}
+\tcblower
+\luaexec{
+ for _,integer in ipairs(f.derivatives) do
+ if integer == Integer.zero() then
+ tex.print("I'm a zero.\\newline")
+ end
+ end
+}
+\end{codebox}
+We can change the values of \texttt{variables} and \texttt{derivatives} manually (or more naturally by other gizmos found in \texttt{luacas}). For example, keeping the variables from above, we have:
+\begin{multicols}{2}
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+f.derivatives = {Integer.one(),
+ Integer.one()}
+tex.print("\\[",
+ f:simplify():tolatex(),
+ "\\]")
+\end{minted}
+\tcblower
+\luaexec{
+ f.derivatives = {Integer.one(),Integer.one()}
+ tex.print("\\[", f:simplify():tolatex(), "\\]")
+}
+\end{codebox}
+
+\begin{center}
+\parseshrub{f}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily,
+ draw,
+ rounded corners = 1pt,
+ fill = gray!20,
+ l sep = 1.5cm,
+ s sep = 0.75cm}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+Thank goodness for this too. The parser nested within the \LaTeX{} environment \mintinline{latex}{\begin{CAS}..\end{CAS}} allows for fairly natural function assignment; the name of the function must be declared in \mintinline{lua}{vars(...)} (or rather, as a \texttt{SymbolExpression}) beforehand:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('s','t','f')
+ f = f(s^2,s+2*t)
+ f.derivatives = {1,1}
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('s','t','f')
+ f = f(s^2,s+2*t)
+ f.derivatives = {1,1}
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_methods/ref_core_methods.tex b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_methods/ref_core_methods.tex
new file mode 100644
index 0000000000..a88b5a15d8
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_methods/ref_core_methods.tex
@@ -0,0 +1,1155 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse,documentation}
+\usepackage{microtype}
+\usepackage{makeidx}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\definecolor{codegreen}{HTML}{49BE25}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\newtcolorbox{codehead}[1][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1
+}
+
+\usepackage{varwidth}
+
+\newtcolorbox{newcodehead}[2][]{
+ enhanced,
+ frame hidden,
+ colback=rosegray!15,
+ boxrule=0mm,
+ leftrule=5mm,
+ rightrule=5mm,
+ boxsep=0mm,
+ arc=0mm,
+ outer arc=0mm,
+ left=3mm,
+ right=3mm,
+ top=1mm,
+ bottom=1mm,
+ toptitle=1mm,
+ bottomtitle=1mm,
+ oversize,
+ #1,
+ fonttitle=\bfseries\ttfamily\footnotesize,
+ coltitle=rosegray,
+ attach boxed title to top text right,
+ boxed title style={frame hidden,size=small,bottom=-1mm,
+ interior style={fill=none,
+ top color=white,
+ bottom color=white}},
+ title={#2}
+}
+
+
+\makeindex
+
+\newcommand{\coderef}[2]{%
+\begin{codehead}[sidebyside,segmentation hidden]%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{codehead}%
+}
+
+\newcommand{\newcoderef}[3]{%
+\begin{newcodehead}[sidebyside,segmentation hidden]{#3}%
+ \mintinline{lua}{#1}%
+ \tcblower%
+ \begin{flushright}%
+ \mintinline{lua}{#2}%
+ \end{flushright}%
+\end{newcodehead}%
+}
+
+\begin{document}
+
+\subsection{Core Methods}
+
+Any of the methods below can be used within \mintinline{latex}{\begin{CAS}..\end{CAS}}. There are times when the parser or \LaTeX{} front-end allows for simpler syntax or usability.
+
+\coderef{function Expression:autosimplify()}{return Expression|table<number, Expression>}
+\index{Core!Methods!\texttt{autosimplify}}
+\addcontentsline{toc}{subsubsection}{\ttfamily autosimplify}
+
+Performs fast simplification techniques on an expression. The return depends on the type of input \texttt{Expression}. Generally, one should call {\ttfamily autosimplify()} on expressions before applying other core methods to them.
+
+Consider the code:
+
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','y','z')
+ w = x/y + y/z + z/x
+\end{CAS}
+\[ \print{w} = \print{w:autosimplify()} \]
+\end{minted}
+\begin{CAS}
+ vars('x','y','z')
+ w = x/y + y/z + z/x
+\end{CAS}
+The output is as follows:
+\[ \print{w} = \print{w:autosimplify()} \]
+It seems that \texttt{autosimplify()} did nothing; but there are significant structural differences between \texttt{w} and \texttt{w:autosimplify()}:
+
+\begin{multicols}{2}
+ \begin{center}
+ \underline{Expression tree for \texttt{w}}
+
+ \parseforest{w}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+ \end{forest}
+
+ \underline{Expression tree for \texttt{w:autosimplify()}}
+
+ \parseforest{w:autosimplify()}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+ \end{forest}
+\end{center}
+\end{multicols}
+
+Ironically, the \emph{autosimplified} expression tree on the right looks more complicated than the one on the left! But one of the primary functions of \texttt{autosimplify()} is to take an expression (that truly could be input in a myriad of ways) and convert that expression into something \emph{anticipatable}.
+
+For example, suppose the user inputs:
+\begin{minted}{latex}
+\begin{CAS}
+ w = x/y + (z/x+y/z)
+\end{CAS}
+\end{minted}
+\begin{CAS}
+ w = x/y + (z/x+y/z)
+\end{CAS}
+In this case, the expression trees for \texttt{w} and \texttt{w:autosimplify()}, respectively, look as follows:
+
+\begin{multicols}{2}
+\begin{center}
+\parseforest{w}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+
+\parseforest{w:autosimplify()}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+\end{multicols}
+{\bf Note:} \texttt{w:autosimplify()} is exactly the same as it was before despite the different starting point. This is an essential function of \texttt{autosimplify()}.
+
+\subsubsection*{Parsing}
+
+The starred variant of the \LaTeX{} command \mintinline{latex}{\print} will automatically apply the method \texttt{autosimplify()} to its argument:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ a = x+x/2
+\end{CAS}
+\[ \print{a} = \print*{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ a = x+x/2
+\end{CAS}
+\[ \print{a} = \print*{a} \]
+\end{codebox}
+Alternatively, you can call \texttt{autosimplify()} directly within \mintinline{latex}{\begin{CAS}..\end{CAS}}:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ a = (x+x/2):autosimplify()
+\end{CAS}
+\[ \print{a} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ a = (x+x/2):autosimplify()
+\end{CAS}
+\[ \print{a} \]
+\end{codebox}
+
+\coderef{function Expression:evaluate()}{return Expression}
+\index{Core!Methods!\texttt{evaluate}}
+\addcontentsline{toc}{subsubsection}{\ttfamily evaluate}
+
+Attempts to apply operations found in the expression tree of \texttt{Expression}. For instance, evaluating a {\ttfamily DerivativeExpression} applies the derivative operator with respect to the {\ttfamily symbol} field to its {\ttfamily expression} field. Evaluating a {\ttfamily BinaryOperation} with its {\ttfamily operation} field set to {\ttfamily ADD} returns the sum of the numbers in the {\ttfamily expressions} field, if possible. If the expression does not represent an operation or is unable to be evaluated, calling {\ttfamily evaluate()} on an expression returns itself.
+
+For example, the code:
+\begin{minted}{latex}
+\directlua{
+ x = Integer(1)/Integer(2)
+ y = Integer(2)/Integer(3)
+ z = BinaryOperation(BinaryOperation.ADD,{x,y})
+}
+\[ \print{z} = \print{z:evaluate()}.\]
+\end{minted}
+produces:
+\directlua{
+ x = Integer(1)/Integer(2)
+ y = Integer(2)/Integer(3)
+ z = BinaryOperation(BinaryOperation.ADD,{x,y})
+}
+\[ \print{z} = \print{z:evaluate()}.\]
+
+\subsubsection*{Parsing}
+
+Arithmetic like above is actually done automatically (via the \texttt{Ring} interface):
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ x = 1/2
+ y = 2/3
+ z = x+y
+\end{CAS}
+\[ z = \print{z} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ x = 1/2
+ y = 2/3
+ z = x+y
+\end{CAS}
+\[ z = \print{z} \]
+\end{codebox}
+
+Otherwise, the \texttt{evaluate()} method will attempt to evaluate all subexpressions, and then stop there:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ y = diff(x^2+x,x)+diff(2*x,x)
+ y = y:evaluate()
+\end{CAS}
+\[ \print{y} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ y = diff(x^2+x,x)+diff(2*x,x)
+ y = y:evaluate()
+\end{CAS}
+\[ \print{y} \]
+\end{codebox}
+Whereas \texttt{autosimplify()} will return $3+2x$; indeed, the \texttt{autosimplify()} method (usually) begins by applying \texttt{evaluate()} first.
+
+\coderef{function Expression:expand()}{return Expression}
+\index{Core!Methods!\texttt{expand}}
+\addcontentsline{toc}{subsubsection}{\ttfamily expand}
+
+Expands an expression, turning products of sums into sums of products.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','y','z','w')
+ a = x+y
+ b = z+w
+ c = a*b
+\end{CAS}
+\[ \print{c} = \print{c:expand()} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y','z','w')
+ a = x+y
+ b = z+w
+ c = a*b
+\end{CAS}
+\[ \print{c} = \print{c:expand()} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+There is an \texttt{expand()} function in the parser; though it calls the \texttt{autosimplify()} method first. So, for example, \mintinline{lua}{expand(c)} is equivalent to \mintinline{lua}{c:autosimplify():expand()}.
+
+\coderef{function Expression:factor()}{return Expression}
+\index{Core!Methods!\texttt{factor}}
+\addcontentsline{toc}{subsubsection}{\ttfamily factor}
+
+Factors an expression, turning sums of products into products of sums. For general \texttt{Expressions} this functionality is somewhat limited. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ a = x-1
+ b = a*x+a
+\end{CAS}
+\[ \print{b} = \print{b:factor()} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y')
+ a = x-y
+ b = a*x+a*y
+\end{CAS}
+\[ \print{b} = \print{b:factor()} \]
+\end{codebox}
+On the other hand:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','y')
+ a = x^2-y^2
+\end{CAS}
+\[ \print{a} = \print{a:factor()} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y')
+ a = x^2-y^2
+\end{CAS}
+\[ \print{a} = \print{a:factor()} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+There is a \texttt{factor()} function in the parser that is more class-aware than the basic \texttt{:factor()} method mentioned here. For example:
+\begin{codebox}
+ \begin{minted}[fontsize = \small]{latex}
+\begin{CAS}
+ x = 12512
+\end{CAS}
+\[ \print{x:factor()} = \print{factor(x)} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ x = 12512
+\end{CAS}
+\[ \print{x:factor()} = \print{factor(x)} \]
+\end{codebox}
+
+\coderef{function Expression:freeof(symbol)}{return bool}
+\index{Core!Methods!\texttt{freeof}}
+\addcontentsline{toc}{subsubsection}{\ttfamily freeof}
+
+Determines whether or not {\ttfamily Expression} contains a particular {\ttfamily symbol} somewhere in its expression tree.
+
+The method \texttt{freeof()} is quite literal. For example:
+\begin{codebox}
+\begin{minted}[fontsize=\small]{lua}
+vars('foo','bar')
+baz = foo+bar
+if baz:freeof(foo) then
+ tex.sprint(baz:tolatex(), " is free of ",
+ foo:tolatex(),"!")
+else
+ tex.sprint(baz:tolatex(), " is bound by ",
+ foo:tolatex(),".")
+end
+\end{minted}
+\tcblower
+\directlua{
+vars('foo','bar')
+baz = foo+bar
+if baz:freeof(foo) then
+ tex.sprint(baz:tolatex(), " is free of ",
+ foo:tolatex(),"!")
+else
+ tex.sprint(baz:tolatex(), " is bound by ",
+ foo:tolatex(),".")
+end
+}
+\end{codebox}
+On the other hand, the expression tree for \mintinline{lua}{SymbolExpression("foo")} contains a single node with no edges. With nary a \mintinline{lua}{SymbolExpression("fo")} to find in such an expression tree, we have:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+vars('foo','fo')
+if foo:freeof(fo) then
+ tex.sprint(foo:tolatex()," is free of ",
+ fo:tolatex(),"!")
+else
+ tex.sprint(foo:tolatex()," is bound by ",
+ fo:tolatex(),'.')
+end
+ \end{minted}
+ \tcblower
+ \directlua{
+vars('foo','fo')
+if foo:freeof(fo) then
+ tex.sprint(foo:tolatex()," is free of ",
+ fo:tolatex(),"!")
+else
+ tex.sprint(foo:tolatex()," is bound by ",
+ fo:tolatex(),'.')
+end
+}
+ \end{codebox}
+
+\coderef{function Expression:isatomic()}{return bool}
+\index{Core!Methods!\texttt{isatomic}}
+\addcontentsline{toc}{subsubsection}{\ttfamily isatomic}
+
+Determines whether an expression is \emph{atomic}. Typically, atomicity is measured by whether the \texttt{Expression} has any subexpression fields. So, for example, \texttt{Integer(5)} and \texttt{Integer(15)} are atomic, and so is \texttt{Integer(20)}. But:
+\begin{minted}{lua}
+BinaryOperation(BinaryOperation.ADD,
+ {Integer(5),Integer(15)})
+\end{minted}
+is non-atomic.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+x = SymbolExpression("x")
+y = x*x+x
+if x:isatomic() then
+ tex.print(tostring(x),"is atomic;")
+end
+if not y:isatomic() then
+ tex.print(tostring(y),"is compound.")
+end
+\end{minted}
+\tcblower
+\directlua{
+x = SymbolExpression("x")
+y = x*x+x
+if x:isatomic() then
+ tex.print(tostring(x),"is atomic;")
+end
+if not y:isatomic() then
+ tex.print(tostring(y),"is compound.")
+end
+}
+\end{codebox}
+Since \texttt{SymbolExpression} inherits from \texttt{AtomicExpression}, we have that \texttt{isatomic()} is taken literally as well. For example:
+\begin{codebox}
+ \begin{minted}[fontsize=\small,breaklines]{lua}
+y = SymbolExpression("x*x+x")
+if not y:isatomic() then
+ tex.print(tostring(y),"is compound.")
+else
+ tex.print("But",tostring(y),"is atomic,
+ from a certain point of view.")
+end
+\end{minted}
+\tcblower
+\directlua{
+ y = SymbolExpression("x*x+x")
+if not y:isatomic() then
+ tex.print(tostring(y),"is compound.")
+else
+ tex.print("But",tostring(y),"is atomic,
+ from a certain point of view.")
+end
+}
+\end{codebox}
+\vskip 0.2cm
+
+\coderef{function Expression:iscomplexconstant()}{return bool}
+\index{Core!Methods!\texttt{iscomplexconstant}}
+\addcontentsline{toc}{subsubsection}{\ttfamily iscomplexconstant}
+
+Determines whether an expression is a complex number in the mathematical sense, such as $3 + \sqrt{2}i$. It's helpful to keep in mind that, oftentimes, content needs to be simplified/evaluated in order to obtain the intended results:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+a = (Integer.one() + I) ^ Integer(2)
+if a:iscomplexconstant() then
+ tex.print("$",a:tolatex(),"$ is a complex constant.")
+else
+ tex.print("$",a:tolatex(),"$ is not a complex constant.")
+end
+\end{minted}
+\tcblower
+\begin{center}
+\luaexec{
+ a = (Integer.one() + I) ^ Integer(2)
+ if a:iscomplexconstant() then
+ tex.print("$",a:tolatex(),"$ is a complex constant.")
+ else
+ tex.print("$",a:tolatex(),"$ is not a complex constant.")
+ end
+}
+\end{center}
+\end{codebox}
+While:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+a = (Integer.one()+I) ^ Integer(2)
+a = a:expand():simplify()
+if a:iscomplexconstant() then
+ tex.print("$",a:tolatex(),"$ is a complex constant.")
+else
+ tex.print("$",a:tolatex(),"$ is not a complex constant.")
+end
+\end{minted}
+\tcblower
+\begin{center}
+\luaexec{
+ a = (Integer.one()+I) ^ Integer(2)
+ a = a:expand():simplify()
+ if a:iscomplexconstant() then
+ tex.print("$",a:tolatex(),"$ is a complex constant.")
+ else
+ tex.print("$",a:tolatex(),"$ is not a complex constant.")
+ end
+}
+\end{center}
+\end{codebox}
+
+\coderef{function Expression:isconstant()}{return bool}
+\index{Core!Methods!\texttt{isconstant}}
+\addcontentsline{toc}{subsubsection}{\ttfamily isconstant}
+
+Determines whether an expression is atomic and contains no variables. This method is counterintuitive in some cases. For instance:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+if not pi:isconstant() then
+ tex.print("$\\pi$ is not constant.")
+end
+\end{minted}
+\tcblower
+\luaexec{
+if not pi:isconstant() then
+ tex.print("$\\pi$ is not constant.")
+end
+}
+\end{codebox}
+This is because {\ttfamily isconstant()} is meant to check for certain autosimplification transformations that can be performed on arbitrary {\ttfamily Ring} elements but not on those constants. Use {\ttfamily isrealconstant()} for what mathematicians think of as constants.
+
+\coderef{function Expression:isrealconstant()}{return bool}
+\index{Core!Methods!\texttt{isrealconstant}}
+\addcontentsline{toc}{subsubsection}{\ttfamily isrealconstant}
+
+Determines whether an expression is a real number in the mathematical sense, such as $2$, $\sqrt{5}$, or $\sin(3)$. For example:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{lua}
+if pi:isrealconstant() then
+ tex.print("$\\pi$ is a real constant.")
+end
+\end{minted}
+\tcblower
+\luaexec{
+ if pi:isrealconstant() then
+ tex.print("$\\pi$ is a real constant.")
+ end
+}
+\end{codebox}
+
+\coderef{function Expression:order(Expression)}{return boolean}
+\index{Core!Methods!\texttt{order}}
+\addcontentsline{toc}{subsubsection}{\ttfamily order}
+
+For the goals of autosimplification, \texttt{Expression}s must be ordered. \texttt{Expression:order(other)} method returns \mintinline{lua}{true} if \texttt{Expression} is ``less than'' \texttt{other} according to this ordering.
+
+\begin{multicols}{2}
+On certain classes, the ordering is intuitive:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+a = 4
+b = 3
+if a:order(2) then
+ tex.print(a:tolatex(),
+ "is less than",
+ b:tolatex())
+else
+ tex.print(b:tolatex(),
+ "is less than",
+ a:tolatex())
+end
+\end{minted}
+\tcblower
+\begin{CAS}
+ a = 4
+ b = 3
+ if a:order(2) then
+ tex.print(a:tolatex(),
+ "is less than",
+ b:tolatex())
+ else
+ tex.print(b:tolatex(),
+ "is less than",
+ a:tolatex())
+ end
+\end{CAS}
+\end{codebox}
+
+\columnbreak
+
+On \texttt{SymbolExpression}s, the ordering is lexigraphic:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{lua}
+vars('a')
+vars('b')
+if b:order(a) then
+ tex.print(b:tolatex(),
+ "is less than",
+ a:tolatex())
+else
+ tex.print(a:tolatex(),
+ "is less than",
+ b:tolatex())
+end
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('a','b')
+ if b:order(a) then
+ tex.print(b:tolatex(),
+ "is less than",
+ a:tolatex())
+ else
+ tex.print(a:tolatex(),
+ "is less than",
+ b:tolatex())
+ end
+\end{CAS}
+\end{codebox}
+\end{multicols}
+
+Of course, inter-class comparisons can be made as well -- but these are predominantly dictated by typesetting conventions.
+
+\coderef{function Expression:setsubexpressions(subexpressions)}{return Expression}
+\index{Core!Methods!\texttt{setsubexpressions}}
+\addcontentsline{toc}{subsubsection}{\ttfamily setsubexpressions}
+
+Creates a copy of an expression with the list of subexpressions as its new subexpressions. This can reduce code duplication in other methods.
+
+
+\coderef{function Expression:simplify()}{return Expression}
+\index{Core!Methods!\texttt{simplify}}
+\addcontentsline{toc}{subsubsection}{\ttfamily simplify}
+
+Performs more extensive simplification of an expression. This may be slow, so this function is separate from autosimplification and is not called unless the user specifically directs the CAS to do so. The method aims to find an expression tree equivalent to the one given that is ``smaller'' in size as measured by the number of nodes in the expression tree.
+
+The \texttt{simplify()} method does call the \texttt{autosimplify()} method first. Here's an example of where the results of \texttt{autosimplify()} and \texttt{simplify()} differ:
+
+\begin{minted}[breaklines]{latex}
+\begin{CAS}
+ vars('x')
+ a = 1-x+0*x
+ b = 1+1*x
+ c = a*b
+\end{CAS}
+\[ \print{c} = \print{c:autosimplify()} = \print{c:simplify()}. \]
+\end{minted}
+The code above produces:
+\begin{CAS}
+ vars('x')
+ a = 1-x+0*x
+ b = 1+1*x
+ c = a*b
+\end{CAS}
+\[ \print{c} = \print{c:autosimplify()} = \print{c:simplify()}. \]
+
+\subsubsection*{Parsing}
+
+There is a \texttt{simplify()} function for those unfamiliar with Lua methods. So, for example, \mintinline{lua}{c:simplify()} is equivalent to \mintinline{lua}{simplify(c)}.
+
+\coderef{function Expression:size()}{return Integer}
+\index{Core!Methods!\texttt{size}}
+\addcontentsline{toc}{subsubsection}{\ttfamily size}
+
+Returns the number of nodes of the tree that constitutes an expression, or roughly the total number of expression objects that make up the expression.
+
+For example, consider:
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x')
+ a = (1-x+0*x)
+ b = (1+1*x)
+ c = a*b
+\end{CAS}
+\end{minted}
+\begin{CAS}
+ vars('x')
+ a = (1-x+0*x)
+ b = (1+1*x)
+ c = a*b
+\end{CAS}
+Then the expression trees for \texttt{c}, \texttt{c:autosimplify()}, and \texttt{c:simplify()} are as follows:
+
+\begin{multicols}{3}
+ \begin{center}
+ \underline{Tree for \texttt{c}:}
+\parseforest{c}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+
+\columnbreak
+
+\underline{Tree for \texttt{c:autosimplify()}:}
+\parseforest{c:autosimplify()}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+
+\columnbreak
+
+\underline{Tree for \texttt{c:simplify()}:}
+\parseforest{c:simplify()}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {font = \ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+\end{multicols}
+Accordingly, we have:
+\begin{codebox}
+ \begin{minted}[breaklines,fontsize=\small]{lua}
+tex.print("The size of \\texttt{c} is",
+ tostring(c:size()),"\\newline")
+tex.print("The size of
+ \\texttt{c:autosimplify()} is",
+ tostring(c:autosimplify():size()), "\\newline")
+tex.print("The size of
+ \\texttt{c:simplify()} is",
+ tostring(c:simplify():size()))
+ \end{minted}
+ \tcblower
+ \luaexec{
+ tex.print("The size of \\texttt{c} is", tostring(c:size()),"\\newline")
+ tex.print("The size of \\texttt{c:autosimplify()} is", tostring(c:autosimplify():size()), "\\newline")
+ tex.print("The size of \\texttt{c:simplfy()} is", tostring(c:simplify():size()))
+}
+\end{codebox}
+\vskip 0.2cm
+
+\coderef{function Expression:subexpressions()}{return table<number, Expression>}
+\index{Core!Methods!\texttt{subexpressions}}
+\addcontentsline{toc}{subsubsection}{\ttfamily subexpressions}
+
+Returns a list of all subexpressions of an expression. This gives a unified interface to the instance variables for subexpressions, which have different names across classes. For example, consider:
+\begin{codebox}
+\begin{minted}[breaklines,fontsize=\footnotesize]{latex}
+\begin{CAS}
+ vars('x','y','z')
+ a = x*y+y*z
+ b = int(sin(x),x,0,pi/2)
+\end{CAS}
+\[ a = \print{a} \quad \text{and} \quad b=\print{b}.\]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y','z')
+ a = x*y+y*z
+ b = int(sin(x),x,0,pi/2)
+\end{CAS}
+\[ a = \print{a} \quad \text{and} \quad b=\print{b}.\]
+\end{codebox}
+Here are the expression shrubs for \texttt{a} and \texttt{b}:
+
+\begin{multicols}{2}
+\begin{center}
+ \underline{Expression shrub for \texttt{a}}
+
+ \parseshrub{a}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {draw,
+ rectangle,
+ rounded corners=1pt,
+ fill=gray!10,
+ s sep = 2cm,
+ font=\ttfamily}
+ @\shrubresult
+ \end{forest}
+
+ \underline{Expression shrub for \texttt{b}}
+
+\parseshrub{b}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {draw,
+ rectangle,
+ rounded corners=1pt,
+ fill=gray!10,
+ s sep = 1cm,
+ font=\ttfamily}
+ @\shrubresult
+\end{forest}
+\end{center}
+\end{multicols}
+On the other hand:
+\begin{codebox}
+\begin{minted}[breaklines,fontsize=\small]{lua}
+for _,expr in ipairs(a:subexpressions()) do
+ tex.print("$", expr:tolatex(), "$\\quad")
+end
+\end{minted}
+\tcblower
+\luaexec{
+ for _,expr in ipairs(a:subexpressions()) do
+ tex.print("$", expr:tolatex(), "$\\quad")
+ end
+}
+\end{codebox}
+while:
+\begin{codebox}
+\begin{minted}[breaklines,fontsize=\small]{lua}
+for _,expr in ipairs(b:subexpressions()) do
+ tex.print("$", expr:tolatex(), "$\\quad")
+end
+\end{minted}
+\tcblower
+\luaexec{
+ for _,expr in ipairs(b:subexpressions()) do
+ tex.print("$",expr:tolatex(),"$\\quad")
+ end
+}
+\end{codebox}
+\vskip 0.2cm
+
+\coderef{function Expression:substitute(map)}{return Expression}
+\index{Core!Methods!\texttt{substitute}}
+\addcontentsline{toc}{subsubsection}{\ttfamily substitute}
+
+The input \texttt{map} is a table that maps expressions to expressions; the method then recursively maps each instance of an expression with its corresponding table expression. One should take care when replacing multiple compound expressions in a single command, since there is no guarantee as to the order in which subexpressions in the table are replaced.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('foo','bar','baz')
+ qux = (foo/bar)
+ qux = qux:substitute({[foo]=bar,[bar]=baz})
+\end{CAS}
+\[ \print{qux} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('foo','bar','baz')
+ qux = (foo/bar)
+ qux = qux:substitute({[foo]=bar,[bar]=baz})
+ \end{CAS}
+ \[ \print{qux} \]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+There is a \texttt{substitute()} function with a slightly more user-friendly syntax. In particular,
+
+\mintinline{lua}{(foo/bar):substitute({[foo]=bar,[bar]=baz})}
+
+is equivalent to
+
+\mintinline{lua}{substitute({[foo]=bar,[bar]=baz}, foo/bar)}
+
+\coderef{function Expression:tolatex()}{return string}
+\index{Core!Methods!\texttt{tolatex}}
+\addcontentsline{toc}{subsubsection}{\ttfamily tolatex}
+
+Converts an expression to \LaTeX{} code. Some folks have strong feelings about how certain things are typeset. Case and point, which of these is your favorite:
+\[ \int \sin(\frac{y}{2})dy \qquad \int \sin\left( \frac{y}{2} \right)dy \qquad \int \sin\left( \frac{y}{2} \right)\, dy \qquad \int \sin\!\left( \frac{y}{2} \right)\, dy \qquad \int \sin\!\left( \frac{y}{2} \right) \mathop{\mathrm{d}y} \qquad \int \sin\mathopen{}\left( \frac{y}{2} \right) \mathop{dy} \quad ?\]
+We've tried to remain neutral:
+
+\begin{codebox}
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('y')
+ f = diff(int(sin(y/2),y),y)
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('y')
+ f = diff(int(sin(y/2),y),y)
+\end{CAS}
+\[ \print{f} \]
+\end{codebox}
+With any luck, we've pleased at least as many people as we've offended. In desperate times, one could rewrite the \texttt{tolatex()} method for any given class. Here, for example, is the \texttt{tolatex()} method as written for the \texttt{DerivativeExpression} class:
+\begin{minted}[breaklines]{lua}
+function DerivativeExpression:tolatex()
+ return '\\frac{d}{d' .. self.symbol:tolatex() .. '}\\left(' .. self.expression:tolatex() .. '\\right)'
+end
+\end{minted}
+But there are heathens that live among us who might prefer:
+\begin{minted}[breaklines]{lua}
+function DerivativeExpression:tolatex()
+ return '\\frac{\\mathrm{d}}{\\mathrm{d}' .. self.symbol:tolatex() .. '}\\left(' .. self.expression:tolatex() .. '\\right)'
+end
+\end{minted}
+If we include the above function in a separate file, say \texttt{mytex.lua}, and use:
+
+\mintinline{latex}{\directlua{dofile('mytex.lua')}}
+
+or include the above function directly into the document via \mintinline{latex}{\directlua} or \mintinline{latex}{\luaexec}, then we would get:
+\begin{codebox}
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = DerivativeExpression(y+sin(y),y)
+\end{CAS}
+\[ \print{f} \]
+\end{minted}
+\tcblower
+\[ \frac{\mathrm{d}}{\mathrm{d}y} \left( y + \sin\mathopen{}\left(y\right) \right).\]
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The \LaTeX{} command \mintinline{latex}{\print} calls the method \mintinline{lua}{tolatex()} unto its argument and uses \mintinline{lua}{tex.print()} to display the results. The starred variant \mintinline{latex}{\print*} applies the \texttt{autosimplify()} method before applying \mintinline{lua}{tolatex()}.
+
+Additionally, one can use the \texttt{disp()} function within \mintinline{latex}{\begin{CAS}..\end{CAS}}.
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ f = DerivativeExpression(y+sin(y),y)
+ disp(f)
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ f = DerivativeExpression(y+sin(y),y)
+ disp(f)
+\end{CAS}
+\end{codebox}
+
+The function \texttt{disp} takes two optional boolean arguments both are set to \texttt{false} by default. The first optional boolean controls \emph{inline} vs \emph{display} mode; the second optional boolean controls whether the method \texttt{autosimplify()} is called before printing:
+
+\begin{multicols}{3}
+ \begin{codebox}[]
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ disp(f,true)
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ disp(f,true)
+\end{CAS}
+\end{codebox}
+ \begin{codebox}[]
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ disp(f,true,true)
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ disp(f,true,true)
+\end{CAS}
+\end{codebox}
+ \begin{codebox}[]
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ disp(f,false,true)
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ disp(f,false,true)
+\end{CAS}
+\end{codebox}
+\end{multicols}
+
+
+\coderef{function Expression:topolynomial()}{return Expression | bool}
+\index{Core!Methods!\texttt{topolynomial}}
+\addcontentsline{toc}{subsubsection}{\ttfamily topolynomial}
+
+Attempts to cast \texttt{Expression} into a polynomial type ({\ttfamily PolynomialRing}); there are multiple outputs. The first output is \texttt{self} or \texttt{PolynomialRing}; the second output is \mintinline{lua}{false} or \mintinline{lua}{true}, respectively. \texttt{PolynomialRing} is the name of the class that codifies univariate polynomials proper.
+
+Polynomial computations tend to be significantly faster when those polynomials are stored as arrays of coefficients (as opposed to, say, when they are stored as generic \texttt{BinaryOperation}s). Hence the need for a method like \texttt{topolynomial()}.
+
+{\bf Warning:} the \texttt{topolynomial()} method expects the input to be autosimplified. For example:
+
+\begin{multicols}{2}
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = 3+2*x+x^2
+ f,b = f:topolynomial()
+ if b then
+ tex.print("\\[",f:tolatex(),"\\]")
+ else
+ tex.print("womp womp")
+ end
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = 3+2*x+x^2
+ f,b = f:topolynomial()
+ if b then
+ tex.print("\\[",f:tolatex(),"\\]")
+ else
+ tex.print("\\[ \\text{womp womp} \\]")
+ end
+\end{CAS}
+\end{codebox}
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = 3+2*x+x^2
+ f,b = f:autosimplify():topolynomial()
+ if b then
+ tex.print("\\[",f:tolatex(),"\\]")
+ else
+ tex.print("womp womp")
+ end
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = 3+2*x+x^2
+ f,b = f:autosimplify():topolynomial()
+ if b then
+ tex.print("\\[",f:tolatex(),"\\]")
+ else
+ tex.print("\\[ \\text{womp womp} \\]")
+ end
+\end{CAS}
+\end{codebox}
+\end{multicols}
+
+\subsubsection*{Parsing}
+
+There is a \mintinline{lua}{topoly()} function that applies \mintinline{lua}{:autosimplify()} automatically to the input. For example:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ f = 3+2*x+x^2
+ f = topoly(f)
+\end{CAS}
+The Lua variable \texttt{f} is the \whatis{f}: $\print{f}$.
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ f = 3+2*x+x^2
+ f = topoly(f)
+\end{CAS}
+The Lua variable \texttt{f} is the \whatis{f}: $\print{f}$.
+\end{codebox}
+
+
+\coderef{function Expression:type()}{return Expression | bool}
+\index{Core!Methods!\texttt{type}}
+\addcontentsline{toc}{subsubsection}{\ttfamily type}
+
+Returns the \mintinline{lua}{__index} field in the metatable for \texttt{Expression}. In other words, this function returns the type of \texttt{Expression}. Here's typical usage:
+
+\begin{codebox}
+ \begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ vars('x')
+ if x:type() == SymbolExpression then
+ tex.print(x:tolatex(), "is a SymbolExpression.")
+ end
+\end{CAS}
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x')
+ if x:type() == SymbolExpression then
+ tex.print(x:tolatex(), "is a SymbolExpression.")
+ end
+\end{CAS}
+\end{codebox}
+
+\subsubsection*{Parsing}
+
+The \LaTeX{} command \mintinline{latex}{\whatis} can be used to print the type of \texttt{Expression}:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+x is a \whatis{x}
+ \end{minted}
+ \tcblower
+ x is a \whatis{x}
+\end{codebox}
+
+Alternatively, there's a \mintinline{lua}{whatis()} function and a \mintinline{lua}{longwhatis()} function that can be called within a Lua environment (like \mintinline{latex}{\directlua} or \mintinline{latex}{\luaexec}):
+
+\begin{codebox}
+\begin{minted}[fontsize=\small]{lua}
+tex.print(whatis(x), '\\newline')
+tex.print(longwhatis(x))
+\end{minted}
+\tcblower
+\directlua{
+ tex.print(whatis(x), '\\newline')
+ tex.print(longwhatis(x))
+}
+\end{codebox}
+
+
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/tutorial/tut.tex b/macros/luatex/latex/luacas/doc/tutorial/tut.tex
new file mode 100644
index 0000000000..3e12ec919d
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/tutorial/tut.tex
@@ -0,0 +1,217 @@
+\documentclass{article}
+
+\usepackage{standalone}
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\begin{document}
+
+\section{Tutorials}
+
+Taking a cue from the phenomenal TikZ documentation, we introduce basic usage of the \texttt{luacas} package through a few informal tutorials. In the subsections that follow, we'll walk through how each of the outputs below are made using \texttt{luacas}. {\bf Crucially}, none of the computations below are ``hardcoded''; all computations are performed and printed using \texttt{luacas} to maximize portability and code reuse.
+
+\begin{tcolorbox}[colback=rose!10,
+ colframe=rose,
+ arc=1pt,
+ frame hidden]
+{\bf Tutorial 1:} {\itshape A limit definition of the derivative for Alice.}\vskip0.2cm
+\small
+\begin{CAS}
+ vars('x','h')
+ f = 2*x^3-x
+\end{CAS}
+Let $f(x) = \print{f}$. We wish to compute the derivative of $f(x)$ at $x$ using the limit definition of the derivative. Toward that end, we start with the appropriate difference quotient:
+\begin{CAS}
+ subs = {[x] = x+h}
+ q = (f:substitute(subs) - f)/h
+\end{CAS}
+\[ \begin{aligned}
+ \print{q} &=
+ \begin{CAS}
+ q = expand(q)
+ \end{CAS}
+ \print{q}& &\text{expand/simplify} \\
+ \begin{CAS}
+ subs = {[h]=0}
+ q = q:substitute(subs)
+ \end{CAS}
+ &\xrightarrow{h\to 0} \print{q}& &\text{take limit} \\
+ &=
+ \begin{CAS}
+ q = simplify(q)
+ \end{CAS}
+ \print{q}& &\text{simplify.}
+\end{aligned} \]
+%So $\print{diff(f,x)} = \print*{diff(f,x)}$.
+\end{tcolorbox}
+\vfill
+
+\begin{tcolorbox}[colback=rosenavy!10,
+ colframe=rosenavy,
+ arc=1pt,
+ frame hidden]
+ \small
+ {\bf Tutorial 2:} {\itshape A local max/min diagram for Bob}.
+ \vskip 0.2cm
+ Consider the function $f(x)$ defined by:
+ \begin{CAS}
+ vars('x')
+ f = x^2+2*x-2
+ g = x^2-1
+ subs = {[x] = f}
+ dh = expand(substitute(subs,g))
+ h = simplify(int(dh,x)+10)
+ \end{CAS}
+ $\displaystyle f(x) = \print{h}$.
+\begin{multicols}{2}
+ Note that:
+ \[ f'(x) = \print{dh}.\]
+ The roots to $f'(x)=0$ equation are:
+ \begin{CAS}
+ r = roots(dh)
+ \end{CAS}
+ \[ \print{r[1]}, \quad \print{r[2]}, \quad \print{r[3]}, \quad \print{r[4]}.\]
+ Recall: $f'(x_0)$ measures the slope of the tangent line to $y=f(x)$ at $x=x_0$. The values $r$ where $f'(r)=0$ correspond to places where the slope of the tangent line to $y=f(x)$ is horizontal (see the illustration). This gives us a method for identifying locations where the graph $y=f(x)$ attains a peak (local maximum) or a valley (local minimum).
+ \directlua{
+ v = {}
+ for i=1,4 do
+ table.insert(v,simplify(substitute({[x]=r[i]},h)))
+ end
+ }
+ \columnbreak
+ \store{h}\store{dh}
+ \begin{tikzpicture}[scale=0.95]
+ \begin{axis}[legend pos = north west]
+ \addplot
+ [domain=-3.5:1.5,samples=100] {\h};
+ \addlegendentry{$f$};
+ \addplot[densely dashed]
+ [domain=-3.25:1.25,samples=100] {\dh};
+ \addlegendentry{$df/dx$};
+ \addplot[gray,dashed,thick]
+ [domain=-3.5:1.5] {0};
+ \luaexec{for i=1,4 do
+ tex.print("\\draw[fill=purple,purple]",
+ "(axis cs:{", tostring(r[i]) ,"},0) circle (1.5pt)",
+ "(axis cs:{", tostring(r[i]) ,"},{", tostring(v[i]), "}) circle (1.5pt)",
+ "(axis cs:{", tostring(r[i]) ,"},{", tostring(v[i]), "}) edge[dashed] (axis cs:{", tostring(r[i]) ,"},0);")
+ end}
+ \end{axis}
+ \end{tikzpicture}
+\end{multicols}
+\end{tcolorbox}
+
+\vfill
+
+\begin{tcolorbox}[colback=roseorange!10,
+ colframe=roseorange,
+ arc=1pt,
+ frame hidden]
+ \small
+{\bf Tutorial 3:} {\itshape A limit definition of the derivative for Charlie.}\vskip 0.2cm
+
+\begin{CAS}
+ vars('x','h')
+ f = x/(x^2+1)
+\end{CAS}
+Let $f(x) = \print{f}$. We wish to compute the derivative of $f(x)$ at $x$ using the limit definition of the derivative. Toward that end, we start with the appropriate difference quotient:
+\begin{CAS}
+ subs = {[x] = x+h}
+ q = (f:substitute(subs) - f)/h
+\end{CAS}
+\directlua{
+ function Expression:mycombine()
+ local a = self.expressions[1].expressions[1].expressions[1]
+ local b = self.expressions[1].expressions[1].expressions[2]
+ local c = self.expressions[1].expressions[2].expressions[1]
+ local d = self.expressions[1].expressions[2].expressions[2]
+ local numerator = a*d-b*c
+ local denominator = self.expressions[2]*b*d
+ return numerator/denominator
+ end
+ function Expression:mysimplify()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = simplify(a)
+ return a/b
+ end
+ function Expression:myfactor()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = factor(a)
+ return a/b
+ end
+}
+\[ \begin{aligned}
+ \print{q} &=
+ \begin{CAS}
+ q = q:mycombine()
+ \end{CAS}
+ \print{q}& &\text{get a common denominator} \\
+ &=
+ \begin{CAS}
+ q = q:mysimplify()
+ \end{CAS}
+ \print{q}& &\text{simplify the numerator} \\
+ &=
+ \begin{CAS}
+ q = q:myfactor()
+ \end{CAS}
+ \print{q} & &\text{factor numerator} \\
+ &=
+ \begin{CAS}
+ q = simplify(q)
+ \end{CAS}
+ \print{q}& &\text{cancel the $h$s} \\
+ &\xrightarrow{h\to 0}
+ \begin{CAS}
+ subs = {[h] = 0}
+ q = substitute(subs,q):autosimplify()
+ \end{CAS}
+ \print{q}& &\text{take limit.}
+\end{aligned} \]
+\end{tcolorbox}
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/tutorial/tut1/tut1.tex b/macros/luatex/latex/luacas/doc/tutorial/tut1/tut1.tex
new file mode 100644
index 0000000000..1151d3e80b
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/tutorial/tut1/tut1.tex
@@ -0,0 +1,238 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\begin{document}
+
+\subsection{Tutorial 1: Limit Definition of the Derivative}
+
+Alice is teaching calculus, and she wants to give her students many examples of the dreaded \emph{limit definition of the derivative}. On the other hand, she'd like to avoid working out many examples by-hand. She decides to give \texttt{luacas} a try.
+
+Alice can access the \texttt{luacas} program using a custom environment: \mintinline{latex}{\begin{CAS}..\end{CAS}}. The first thing Alice must do is declare variables that will be used going forward:
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','h')
+\end{CAS}
+\end{minted}
+Alice decides that $f$, the function to be differentiated, should be $x^2$. So Alice makes this assignment with:
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+\end{CAS}
+\end{minted}
+Now, Alice wants to use the variable $q$ to store the appropriate \emph{difference quotient} of $f$. Alice could hardcode this into $q$, but that seems to defeat the oft sought after goal of reusable code. So Alice decides to use the \texttt{substitute} command of \texttt{luacas}:
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+ subs = {[x]=x+h}
+ q = (substitute(subs,f) - f)/h
+\end{CAS}
+\end{minted}
+Alice is curious to know if $q$ is what she thinks it is. So Alice decides to have \LaTeX{} print out the contents of $q$ within her document. For this, she uses the \mintinline{latex}{\print} command.
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)- f)/h
+\end{CAS}
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\[ \print{q} \]
+ \end{minted}
+ \tcblower
+ \[ \print{q} \]
+\end{codebox}
+So far so good! Alice wants to expand the numerator of $q$; she finds the aptly named \texttt{expand} method helpful in this regard. Alice redefines \mintinline{lua}{q} to be \mintinline{lua}{q=expand(q)}, and prints the result to see if things worked as expected:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+ q = expand(q)
+\end{CAS}
+\[ \print{q} \]
+ \end{minted}
+ \tcblower
+ \begin{CAS}
+ q = expand(q)
+ \end{CAS}
+ \[ \print*{q} \]
+\end{codebox}
+Alice is pleasantly surprised that the result of the expansion has been \emph{simplified}, i.e., the factors of $x^2$ and $-x^2$ cancelled each other out, and the resulting extra factor of $h$ has been cancelled out of the numerator and denominator.
+
+Finally, Alice wants to take the limit as $h\to 0$. Now that our difference quotient has been expanded and simplified, this amounts to another substitution:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+ q = expand(q)
+ subs = {[h] = 0}
+ q = substitute(subs,q)
+\end{CAS}
+\[ \print{q} \]
+ \end{minted}
+ \tcblower
+ \begin{CAS}
+ subs = {[h]=0}
+ q = q:substitute(subs)
+ \end{CAS}
+ \[ \print{q} \]
+\end{codebox}
+Alice is slightly disappointed that $0+2x$ is returned and not $2x$. Alice takes a guess that there's a \mintinline{lua}{simplify} command. This does the trick: adding the line \mintinline{lua}{q = simplify(q)} before leaving the \texttt{CAS} environment returns the expected $2x$:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+ q = expand(q)
+ subs = {[h] = 0}
+ q = substitute(subs,q)
+ q = simplify(q)
+\end{CAS}
+\[ \print{q} \]
+ \end{minted}
+ \tcblower
+ \begin{CAS}
+ q=simplify(q)
+ \end{CAS}
+ \[ \print{q} \]
+\end{codebox}
+
+Alternatively, Alice could have used the \mintinline{latex}{\print*} command instead of \mintinline{latex}{\print} -- the essential difference is that \mintinline{latex}{\print*}, unlike \mintinline{latex}{\print}, automatically simplifies the content of the argument.
+
+Alice is pretty happy with how everything is working, but she wants to be able to typeset the individual steps of this process. Alice is therefore thrilled to learn that the \mintinline{latex}{\begin{CAS}..\end{CAS}} environment is very robust -- it can:
+\begin{itemize}
+ \item Be entered into and exited out of essentially anywhere within her \LaTeX{} document, for example, within \mintinline{latex}{\begin{aligned}..\end{aligned}}; and
+ \item CAS variables persist -- if Alice assigns \mintinline{lua}{f = x^2} within \mintinline{latex}{\begin{CAS}..\end{CAS}}, then the CAS remembers that \mintinline{lua}{f = x^2} the next time Alice enters the CAS environment.
+\end{itemize}
+Here's Alice's completed code:
+\begin{codebox}[frame hidden,breakable]
+\begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x^2
+\end{CAS}
+Let $f(x) = \print{f}$. We wish to compute the derivative of $f(x)$ at $x$ using thelimit definition of the derivative. Toward that end, we start with the appopriatedifference quotient:
+\begin{CAS}
+ subs = {[x]=x+h}
+ q = (substitute(subs,f) - f)/h
+\end{CAS}
+\[ \begin{aligned}
+ \print{q} &=
+ \begin{CAS}
+ q = expand(q)
+ \end{CAS}
+ \print{q}& &\text{expand/simplify} \\
+ \begin{CAS}
+ subs = {[h]=0}
+ q = substitute(subs,q)
+ \end{CAS}
+ &\xrightarrow{h\to 0} \print{q}& &\text{take limit}\\
+ &=
+ \begin{CAS}
+ q = simplify(q)
+ \end{CAS}
+ \print{q} & &\text{simplify.}
+\end{aligned} \]
+So $\print{diff(f,x)} = \print*{diff(f,x)}$.
+\end{minted}
+\end{codebox}
+
+Alice can produce another example merely by changing the definition of $f$ on the third line to another polynomial:
+
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','h')
+ f = 2*x^3-x
+\end{CAS}
+\end{minted}
+And here is Alice's completed project:
+\begin{tcolorbox}[colback=rose!10,
+ colframe=rose,
+ arc=1pt,
+ frame hidden]
+{\bf Tutorial 1:} {\itshape A limit definition of the derivative for Alice.}\vskip0.2cm
+
+\begin{CAS}
+vars('x','h')
+f = 2*x^3-x
+\end{CAS}
+Let $f(x) = \print{f}$. We wish to compute the derivative of $f(x)$ at $x$ using the limit definition of the derivative. Toward that end, we start with the appropriate difference quotient:
+\begin{CAS}
+subs = {[x] = x+h}
+q = (f:substitute(subs) - f)/h
+\end{CAS}
+\[ \begin{aligned}
+\print{q} &=
+\begin{CAS}
+ q = expand(q)
+\end{CAS}
+\print{q}& &\text{expand/simplify} \\
+\begin{CAS}
+ subs = {[h]=0}
+ q = q:substitute(subs)
+\end{CAS}
+&\xrightarrow{h\to 0} \print{q}& &\text{take limit} \\
+&=
+\begin{CAS}
+ q = simplify(q)
+\end{CAS}
+\print{q}& &\text{simplify.}
+\end{aligned} \]
+%So $\print{diff(f,x)} = \print*{diff(f,x)}$.
+\end{tcolorbox}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/tutorial/tut2/tut2.tex b/macros/luatex/latex/luacas/doc/tutorial/tut2/tut2.tex
new file mode 100644
index 0000000000..a80e285782
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/tutorial/tut2/tut2.tex
@@ -0,0 +1,476 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\begin{document}
+
+\subsection{Tutorial 2: Finding Maxima/Minima}
+
+Bob is teaching calculus too, and he wants to give his students many examples of the process of \emph{finding the local max/min of a given function}. But, like Alice, Bob doesn't want to work out a bunch of examples by-hand. Bob decides to try his hand with \texttt{luacas} after having been taught the basics by Alice.
+
+Bob decides to stick with polynomials for these examples; if anything because those functions are in the wheel-house of \texttt{luacas}. In particular, Bob decides that the \emph{derivative} of the function he wants to use should be a composition of quadratics. This ought to ensure that the roots of that derivative are expressible in a nice way.
+
+Accordingly, Bob declares variables and chooses two quadratic polynomials to compose, say $f$ and $g$, and sets $dh = g \circ f$:
+
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x')
+ f = x^2+2*x-2
+ g = x^2-1
+ subs = {[x] = f}
+ dh = substitute(subs,g)
+\end{CAS}
+\end{minted}
+\begin{CAS}
+ vars('x')
+ f = x^2+2*x-2
+ g = x^2-1
+ subs = {[x] = f}
+ dh = substitute(subs,g)
+\end{CAS}
+
+Bob wants to compute $h$, the integral of $dh$. Bob could certainly compute this quantity by-hand, but why hardcode that information into the document when \texttt{luacas} can do this for you? So Bob uses the \texttt{int} command and shifts the result (with some malice aforethought):
+
+\begin{minted}{latex}
+\begin{CAS}
+ h = int(dh,x) + 10
+\end{CAS}
+\end{minted}
+\begin{CAS}
+ h = int(dh,x) + 10
+\end{CAS}
+
+Bob is curious to know the value of $h$. So he uses \mintinline{latex}{\print{h}} to produce:
+\begin{codebox}
+\begin{minted}[fontsize=\small]{latex}
+\[ \print{h} \]
+\end{minted}
+ \tcblower
+\[\print{h} \]
+\end{codebox}
+This isn't exactly what Bob had in mind. It occurs to Bob that he may need to simplify the expression $h$, so he tries:
+
+\begin{codebox}
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ h = simplify(int(dh,x)+10)
+\end{CAS}
+\[ \print{h} \]
+\end{minted}
+ \tcblower
+\begin{CAS}
+ h = simplify(h)
+\end{CAS}
+\[\print{h} \]
+\end{codebox}
+
+That's more like it! Now, Bob wants to find the roots to $dh$. Bob uses the \texttt{roots} command to do this:
+
+\begin{minted}{latex}
+\begin{CAS}
+ r = roots(dh)
+\end{CAS}
+\end{minted}
+\begin{CAS}
+ r = roots(dh)
+\end{CAS}
+
+But then Bob wonders to himself, ``How do I actually retrieve the roots of $dh$ from \texttt{luacas}?'' The assignment \mintinline{lua}{r = roots(dh)} stores the roots of the polynomial $dh$ in a table named \texttt{r}:
+
+\begin{codebox}[]
+\begin{minted}[fontsize=\small]{latex}
+\[ \print{r[1]}, \quad \print{r[2]}, \quad \print{r[3]}, \quad\print{r[4]} \]
+\end{minted}
+ \tcblower
+ \begin{CAS}
+ r = roots(dh)
+ \end{CAS}
+ \[ \print{r[1]}, \quad \print{r[2]}, \quad \print{r[3]}, \quad \print{r[4]} \]
+\end{codebox}
+If Bob truly wants to print the entire list \texttt{r}, Bob can use the \mintinline{latex}{\lprint} (\textbf{l}ist \textbf{print}) command:
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\[ \left\{ \lprint{r} \right\} \]
+ \end{minted}
+ \tcblower
+ \[ \left\{ \lprint{r} \right\} \]
+\end{codebox}
+Splendid! Bob would now like to evaluate the function $h$ at these roots (for these are the local max/min values of $h$). Here's Bob's first thought:
+
+\begin{codebox}
+\begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ v = simplify(substitute({[x]=r[1]},h))
+\end{CAS}
+\[ \print{v} \]
+\end{minted}
+ \tcblower
+ \begin{CAS}
+ v = simplify(substitute({[x]=r[1]},h))
+ \end{CAS}
+ \[ \print{v} \]
+\end{codebox}
+
+What the heck?! Bob is (understandably) confused. But here's where Bob learns a valuable lesson\dots
+
+\subsubsection{A brief interlude: Lua numbers vs \texttt{luacas Integers}}
+
+The \LaTeX{} environment \mintinline{latex}{\begin{CAS}..\end{CAS}} is really a glorified Lua environment. The ``glory'' comes in how the contents of the environment are parsed in a special manner to make interacting with the CAS (mostly) easy. Bob has encountered a situation where that interaction is not as easy as we'd like.
+
+For comparison, consider the following:
+\begin{multicols}{2}
+Here's some code using the \mintinline{latex}{\begin{CAS}..\end{CAS}}:
+\begin{codebox}\small
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('y')
+ a = 1
+ b = y+a
+\end{CAS}
+\[ \print{b} \]
+\end{minted}
+ \tcblower
+ \begin{CAS}
+ vars('y')
+ a = 1
+ b = y+a
+ \end{CAS}
+ \[ \print{b} \]
+\end{codebox}
+Here's that same code but using \mintinline{latex}{\directlua} instead:
+\begin{codebox}\small
+\begin{minted}[fontsize=\small]{latex}
+\directlua{
+ vars('y')
+ a = Integer(1)
+ b = y+a
+}
+\[ \print{b} \]
+\end{minted}
+ \tcblower
+ \directlua{
+ vars('y')
+ a = Integer(1)
+ b = y+a
+}
+\[ \print{b} \]
+\end{codebox}
+\end{multicols}
+The essential difference being:
+\begin{itemize}
+ \item Using \mintinline{latex}{\begin{CAS}..\end{CAS}}, a parser automatically interprets any digit strings as an \texttt{Integer}; this is a special class defined within the bowels of \texttt{luacas}. Ultimately, it allows for us to define things like the addition of an \texttt{Integer} and an \texttt{Expression} (in this case, the result is a new \texttt{Expression}) as well as arbitrary precision arithmetic.
+ \item Using \mintinline{latex}{\directlua}, there is no parsing, so the user (aka Bob) is responsible for telling \texttt{luacas} what to interpret as an \texttt{Integer} versus what to interpret as a normal Lua \texttt{number}.
+\end{itemize}
+Generally speaking, we like what the parser in \mintinline{latex}{\begin{CAS}..\end{CAS}} does: it keeps us from having to wrap all integers in \texttt{Integer(..)} (among other things). But the price we pay is that the parser indiscriminately wraps \emph{all} (or rather, most) digit strings in \texttt{Integer(..)}. This causes a problem in the following line in Bob's code:
+\begin{minted}{lua}
+v = simplify(substitute({[x]=r[1]},h))
+\end{minted}
+The parser sees \mintinline{lua}{r[1]} and interprets \texttt{1} as \texttt{Integer(1)} -- but \mintinline{lua}{r[Integer(1)]} is \texttt{nil}, so no substitution is performed.
+
+The good news is that, excluding the annoyance between \texttt{Integer} and Lua number, interacting with the CAS via \mintinline{latex}{\directlua} is not much different than interacting with it via \mintinline{latex}{\begin{CAS}..\end{CAS}}.
+
+\subsubsection*{Back to the tutorial...}
+
+After that enlightening interlude, Bob realizes that some care needs to be taken when constructing tables. Here's a solution from within \mintinline{latex}{\begin{CAS}..\end{CAS}}:
+
+\begin{codebox}[]
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ r = ZTable(r)
+ v = ZTable()
+ for i in range(1, 4) do
+ v[i] = simplify(substitute({[x]=r[i]},h))
+ end
+\end{CAS}
+\[ \left\{ \lprint{v} \right\} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ r = ZTable(r)
+ v = ZTable()
+ for i in range(1, 4) do
+ v[i] = simplify(substitute({[x]=r[i]},h))
+ end
+ \end{CAS}
+ \[ \left\{ \lprint{v} \right\} \]
+\end{codebox}
+
+The function \mintinline{lua}{ZTable()} sets indices appropriately for use within \mintinline{latex}{\begin{CAS}..\end{CAS}} while the function \mintinline{lua}{range()} protects the bounds of the for-loop. Alternatively, Bob can make tables directly within \mintinline{latex}{\directlua} (or \mintinline{latex}{\luaexec} from the \texttt{luacode} package) using whatever Lua syntax pleases him:
+
+\begin{codebox}[]
+\begin{minted}[fontsize=\small]{latex}
+\directlua{
+ v = {}
+ for i=1,4 do
+ table.insert(v,simplify(substitute({[x]=r[i]},h)))
+ end}
+\[ \left\{ \lprint{v} \right\} \]
+\end{minted}
+ \tcblower
+ \directlua{
+ v = {}
+ for i=1,4 do
+ table.insert(v,simplify(substitute({[x]=r[i]},h)))
+ end
+}
+\[ \left\{ \lprint{v} \right\} \]
+\end{codebox}
+Great! But still; Bob doesn't want to just pretty-print the roots of $dh$ (or the values that $h$ takes at those roots). Bob is determined to plot the results -- he wants to hammer home the point that the roots of $dh$ point to the local extrema of $h$.
+
+Luckily, Bob is familiar with some of the fantastic graphics tools in the \LaTeX{} ecosystem, like \texttt{pgfplots} and \texttt{asymptote}. But then Bob begins to wonder, ``How can I yoink results out of \texttt{luacas} so that I may yeet them into something like \texttt{pgfplots}?''
+Bob is delighted to find the following commands: \mintinline{latex}{\fetch} and \mintinline{latex}{\store}.
+
+Whereas the \mintinline{latex}{\print} command relies on the \texttt{luacas} method \mintinline{lua}{tolatex()}, the commands \mintinline{latex}{\fetch} and \mintinline{latex}{\store} rely on the \texttt{luacas} function \mintinline{lua}{tostring()}. Bob can view the output of \mintinline{lua}{tostring()} using the \mintinline{latex}{\vprint} command ({\bf v}erbatim {\bf print}). For example, \mintinline{latex}{\vprint{h}} produces:
+\vprint{h}
+This is more-or-less what Bob wants -- but he doesn't want the verbatim output printed to his document, Bob just wants the contents of \mintinline{lua}{tostring(h)}. Here's where \mintinline{latex}{\fetch} comes in. The command \mintinline{latex}{\fetch{h}} is equivalent to:
+\begin{minted}{latex}
+ \directlua{
+ tex.print(tostring(h))
+ }
+\end{minted}
+For comparison, the command \mintinline{latex}{\print{h}} is equivalent to:
+\begin{minted}{latex}
+ \directlua{
+ tex.print(h:tolatex())
+ }
+\end{minted}
+For Bob's purposes, \mintinline{latex}{\fetch{h}} is exactly what he needs:
+
+\begin{codebox}\small
+\begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{tikzpicture}[scale=0.9]
+ \begin{axis}[legend pos = north west]
+ \addplot [domain=-3.5:1.5,samples=100]
+ {\fetch{h}};
+ \addlegendentry{$f$};
+ \addplot[densely dashed]
+ [domain=-3.25:1.25,samples=100]
+ {\fetch{dh}};
+ \addlegendentry{$df/dx$};
+ \addplot[gray,dashed,thick]
+ [domain=-3.5:1.5] {0};
+ \end{axis}
+\end{tikzpicture}
+\end{minted}
+\tcblower
+\begin{tikzpicture}[scale=0.9]
+ \begin{axis}[legend pos = north west]
+ \addplot [domain=-3.5:1.5,samples=100] {\fetch{h}};
+ \addlegendentry{$f$};
+ \addplot[densely dashed]
+ [domain=-3.25:1.25,samples=100] {\fetch{dh}};
+ \addlegendentry{$df/dx$};
+ \addplot[gray,dashed,thick]
+ [domain=-3.5:1.5] {0};
+ \end{axis}
+\end{tikzpicture}
+\end{codebox}
+Alternatively, Bob could use \mintinline{latex}{\store}. The \mintinline{latex}{\store} command will \emph{fetch} the contents of its mandatory argument and store it in a macro of the same name.
+\begin{minted}{latex}
+\store{h}
+\store{dh}
+\end{minted}
+Now the macros \mintinline{latex}{\h} and \mintinline{latex}{\dh} can be used in place of \mintinline{latex}{\fetch{h}} and \mintinline{latex}{\fetch{dh}}, respectively. An optional argument can be used to store contents in a macro under a different name. This is useful for situations like the following:
+\begin{minted}{latex}
+\store{r[1]}[rootone]
+\end{minted}
+Now \mintinline{latex}{\rootone} can be used in place of \mintinline{latex}{\fetch{r[1]}}. But Bob wants to fetch all the values stored in \texttt{r} (and \texttt{v}, for that matter). In this case, Bob can use:
+\begin{minted}{latex}
+\store{r}
+\store{v}
+\end{minted}
+The command \mintinline{latex}{\store{r}} is equivalent to:
+\begin{minted}{latex}
+\def\r{{ \fetch{r[1]}, \fetch{r[2]}, \fetch{r[3]}, \fetch{r[4]} }}
+\end{minted}
+The contents of the \LaTeX{} macro \mintinline{latex}{\r} can be accessed with \mintinline{latex}{\pgfmathsetmacro}. For example:
+
+\begin{codebox}
+\begin{minted}[fontsize=\small,numbersep=6pt,linenos]{latex}
+\begin{tikzpicture}[scale=0.6]
+ \draw [dashed,latex-latex]
+ (-7,0) -- (4,0);
+ \foreach \k in {0,1,2,3}{
+ \pgfmathsetmacro\a{\r[\k]}
+ \draw (\a,0) circle (\a);
+ }
+ \foreach \x in {-6,...,3}{
+ \draw[fill,orange]
+ (\x,0) circle (2pt)
+ node[below] {\footnotesize$\x$};
+ }
+\end{tikzpicture}
+\end{minted}
+ \tcblower
+ \store{r}
+ \begin{center}
+ \begin{tikzpicture}[scale=0.65]
+ \draw [dashed,latex-latex] (-7,0) -- (4,0);
+ \foreach \k in {0,1,2,3}{
+ \pgfmathsetmacro\a{\r[\k]}
+ \draw (\a,0) circle (\a);
+ }
+ \foreach \x in {-6,...,3}{
+ \draw[fill,orange] (\x,0) circle (2pt)
+ node[below] {\footnotesize$\x$};
+ }
+ \end{tikzpicture}
+\end{center}
+\end{codebox}
+
+Alternatively, Bob could avoid the call to \mintinline{latex}{\pgfmathsetmacro} by replacing lines 5-6 in the above code with the slightly more verbose:
+
+\begin{minted}{latex}
+ \draw ({\fetch{r[\k]}},0) circle (\fetch{r[\k]});
+\end{minted}
+
+Alternatively still, Bob could appeal directly to the \mintinline{lua}{tostring()} function in \texttt{luacas} and iterate over tables like \texttt{r} using Lua itself. This can often be a simpler solution (particularly when working within \mintinline{latex}{\begin{axis}..\end{axis}}), and it is exactly what Bob does in his complete project shared below:
+\begin{codebox}[frame hidden,breakable]
+\begin{minted}[breaklines,fontsize=\small]{latex}
+Consider the function $f(x)$ defined by:
+\begin{CAS}
+ vars('x')
+ f = x^2+2*x-2
+ g = x^2-1
+ subs = {[x] = f}
+ dh = expand(substitute(subs,g))
+ h = simplify(int(dh,x)+10)
+\end{CAS}
+$\displaystyle f(x) = \print{h}$.
+\begin{multicols}{2}
+ Note that:
+ \[ f'(x) = \print{dh}.\]
+ The roots to $f'(x)=0$ equation are:
+ \begin{CAS}
+ r = roots(dh)
+ \end{CAS}
+ \[ \left\{ \lprint{r} \right\} \]
+ Recall: $f'(x_0)$ measures the slope of the tangent line to $y= (x)$ at $x=x_0$. The values $r$ where $f'(r)=0$ correspond to places where the slope of the tangent line to $y=f(x)$ is horizontal (see the illustration). This gives us a method for identifying locations where the graph $y=f(x)$ attains a peak (local maximum) or a valley (local minimum).
+ \begin{CAS}
+ r = ZTable(r)
+ v = ZTable()
+ for i in range(1, 4) do
+ v[i] = simplify(substitute({[x]=r[i]},h))
+ end
+ \end{CAS}
+ \columnbreak
+ \store{h}\store{dh}
+ \begin{tikzpicture}[scale=0.95]
+ \begin{axis}[legend pos = north west]
+ \addplot [domain=-3.5:1.5,samples=100] {\h};
+ \addlegendentry{$f$};
+ \addplot[densely dashed] [domain=-3.25:1.25,samples=100] {\dh};
+ \addlegendentry{$df/dx$};
+ \addplot[gray,dashed,thick] [domain=-3.5:1.5] {0};
+ \luaexec{for i=1,4 do
+ tex.print("\\draw[fill=purple,purple]",
+ "(axis cs:{",tostring(r[i]),"},0) circle (1.5pt)",
+ "(axis cs:{",tostring(r[i]),"},{",tostring(v[i]),"}) circle (1.5pt)",
+ "(axis cs:{",tostring(r[i]),"},{",tostring(v[i]),"}) edge[dashed] (axis cs:{",tostring(r[i]),"},0);")
+ end}
+ \end{axis}
+ \end{tikzpicture}
+\end{multicols}
+\end{minted}
+\end{codebox}
+And here is Bob's completed project:
+\begin{tcolorbox}[colback=rosenavy!10,
+ colframe=rosenavy,
+ arc=1pt,
+ frame hidden]
+ {\bf Tutorial 2:} {\itshape A local max/min diagram for Bob}.
+ \vskip 0.2cm
+ Consider the function $f(x)$ defined by:
+ \begin{CAS}
+ vars('x')
+ f = x^2+2*x-2
+ g = x^2-1
+ subs = {[x] = f}
+ dh = expand(substitute(subs,g))
+ h = simplify(int(dh,x)+10)
+ \end{CAS}
+ $\displaystyle f(x) = \print{h}$.
+\begin{multicols}{2}
+ Note that:
+ \[ f'(x) = \print{dh}.\]
+ The roots to $f'(x)=0$ equation are:
+ \begin{CAS}
+ r = roots(dh)
+ \end{CAS}
+ \[ \left\{ \lprint{r} \right\} \]
+ Recall: $f'(x_0)$ measures the slope of the tangent line to $y=f(x)$ at $x=x_0$. The values $r$ where $f'(r)=0$ correspond to places where the slope of the tangent line to $y=f(x)$ is horizontal (see the illustration). This gives us a method for identifying locations where the graph $y=f(x)$ attains a peak (local maximum) or a valley (local minimum).
+ \begin{CAS}
+ r = ZTable(r)
+ v = ZTable()
+ for i in range(1, 4) do
+ v[i] = simplify(substitute({[x]=r[i]},h))
+ end
+ \end{CAS}
+ \columnbreak
+ \store{h}\store{dh}
+ \begin{tikzpicture}[scale=0.95]
+ \begin{axis}[legend pos = north west]
+ \addplot
+ [domain=-3.5:1.5,samples=100] {\h};
+ \addlegendentry{$f$};
+ \addplot[densely dashed]
+ [domain=-3.25:1.25,samples=100] {\dh};
+ \addlegendentry{$df/dx$};
+ \addplot[gray,dashed,thick]
+ [domain=-3.5:1.5] {0};
+ \luaexec{for i=1,4 do
+ tex.print("\\draw[fill=purple,purple]",
+ "(axis cs:{", tostring(r[i]) ,"},0) circle (1.5pt)",
+ "(axis cs:{", tostring(r[i]) ,"},{", tostring(v[i]), "}) circle (1.5pt)",
+ "(axis cs:{", tostring(r[i]) ,"},{", tostring(v[i]), "}) edge[dashed] (axis cs:{", tostring(r[i]) ,"},0);")
+ end}
+ \end{axis}
+ \end{tikzpicture}
+\end{multicols}
+\end{tcolorbox}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/tutorial/tut3/demotut3.dat b/macros/luatex/latex/luacas/doc/tutorial/tut3/demotut3.dat
new file mode 100644
index 0000000000..95139afaf2
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/tutorial/tut3/demotut3.dat
@@ -0,0 +1,46 @@
+\parseforest{q}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {
+ font=\ttfamily,
+ rectangle,
+ rounded corners=1pt
+ },
+ where level=0{%
+ fill=orange!25
+ }{},
+ @\forestresult
+\end{forest}
+
+\begin{CAS}
+ r = diff(q,x,h)
+\end{CAS}
+\whatis{q} vs \whatis{r}
+
+\luaexec{if q.operation == BinaryOperation.ADD then
+ tex.print("I'm an \\texttt{ADD}")
+end}
+
+\luaexec{tex.print("I'm an order", r.degree, "derivative.")}
+
+\parseshrub{q}
+\begin{forest}
+ for tree = {draw,rectangle,rounded corners=1pt,fill=lightgray!20 font=\ttfamily}
+ @\shrubresult
+\end{forest}
+
+\parseshrub{q.expressions[1]}
+\begin{forest}
+ for tree = {draw,rectangle,
+ rounded corners=1pt,fill=lightgray!20,
+ font=\ttfamily, s sep=2cm}
+ @\shrubresult
+\end{forest}
+
+\parseshrub{r}
+\begin{forest}
+ for tree = {draw,rectangle,
+ rounded corners=1pt,fill=lightgray!20,
+ font=\ttfamily, s sep=1cm}
+ @\shrubresult
+\end{forest} \ No newline at end of file
diff --git a/macros/luatex/latex/luacas/doc/tutorial/tut3/tut3.tex b/macros/luatex/latex/luacas/doc/tutorial/tut3/tut3.tex
new file mode 100644
index 0000000000..1fda71a5a0
--- /dev/null
+++ b/macros/luatex/latex/luacas/doc/tutorial/tut3/tut3.tex
@@ -0,0 +1,575 @@
+\documentclass{article}
+
+\usepackage{luacas}
+\usepackage{amsmath}
+\usepackage{amssymb}
+
+\usepackage[margin=1in]{geometry}
+\usepackage[shortlabels]{enumitem}
+
+\usepackage{pgfplots}
+\pgfplotsset{compat=1.18}
+\usetikzlibrary{positioning,calc}
+\usepackage{forest}
+\usepackage{minted}
+\usemintedstyle{pastie}
+\usepackage[hidelinks]{hyperref}
+\usepackage{parskip}
+\usepackage{multicol}
+\usepackage[most]{tcolorbox}
+ \tcbuselibrary{xparse}
+\usepackage{microtype}
+
+\definecolor{rose}{RGB}{128,0,0}
+\definecolor{roseyellow}{RGB}{222,205,99}
+\definecolor{roseblue}{RGB}{167,188,214}
+\definecolor{rosenavy}{RGB}{79,117,139}
+\definecolor{roseorange}{RGB}{232,119,34}
+\definecolor{rosegreen}{RGB}{61,68,30}
+\definecolor{rosewhite}{RGB}{223,209,167}
+\definecolor{rosebrown}{RGB}{108,87,27}
+\definecolor{rosegray}{RGB}{84,88,90}
+
+\usepackage[
+backend=biber,
+style=numeric,
+]{biblatex}
+\addbibresource{sources.bib}
+
+\newtcolorbox{codebox}[1][sidebyside]{
+ enhanced,skin=bicolor,
+ #1,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle
+}
+
+\begin{document}
+
+\subsection{Tutorial 3: Adding Functionality}
+
+Charlie, like Alice and Bob, is also teaching calculus. Charlie likes Alice's examples and wants to try something similar. But Charlie would like to do more involved examples using rational functions. Accordingly, Charlie copy-and-pastes Alice's code:
+\begin{CAS}
+ vars('x','h')
+ f = 1/(x^2+1)
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+ q = expand(q)
+\end{CAS}
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','h')
+ f = 1/(x^2+1)
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+ q = expand(q)
+\end{CAS}
+\end{minted}
+Unfortunately, \mintinline{latex}{\[ q=\print{q} \]} produces:
+\[ q = \print{q} \]
+The \mintinline{lua}{simplify()} command doesn't seem to help either! What Charlie truly needs is to combine terms, i.e., Charlie needs to find a \emph{common denominator}. They're horrified to learn that no such functionality exists in this burgeoning package.
+
+So what's Charlie to do? They could put a feature request in, but they're concerned that the schlubs in charge of managing the package won't get around to it until who-knows-when. So Charlie decides to take matters into their own hands. Besides, looking for that silver lining, they'll learn a little bit about how \texttt{luacas} is structured.
+
+At the heart of any CAS is the idea of an \texttt{Expression}. Mathematically speaking, an \texttt{Expression} is a rooted tree. Luckily, this tree can be drawn using the (wonderful) \texttt{forest} package. In particular, the command \mintinline{latex}{\parseforest{q}} will scan the contents of the expression \texttt{q} and parse the results into a form compatible with the \texttt{forest} package; those results are saved in a macro named \mintinline{latex}{\forestresult}.
+
+\tcbsidebyside[
+ sidebyside adapt=right,
+ enhanced,skin=bicolor,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle,
+ frame hidden
+ ]{
+ \inputminted[
+ firstline = 1,
+ lastline = 13,
+ breaklines,
+ fontsize=\small
+ ]
+ {latex}
+ {demotut3.dat}}
+ {\parseforest{q}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {
+ font=\ttfamily,
+ rectangle,
+ rounded corners=1pt
+ },
+ where level=0{%
+ fill=orange!25
+ }{},
+ @\forestresult
+ \end{forest}}
+
+The root of the tree above is \texttt{ADD} since $q$ is, at its heart, the addition of two other expressions. Charlie wonders how they might check to see if a mystery \texttt{Expression} is an \texttt{ADD}? But this is putting the cart before the horse; Charlie should truly wonder how to check for the \emph{type} of \texttt{Expression} -- then they can worry about other attributes.
+
+Charlie can print the \texttt{Expression} type directly into their document using the \mintinline{latex}{\whatis} command:
+
+\begin{codebox}
+ \inputminted[
+ firstline = 15,
+ lastline = 18,
+ breaklines,
+ fontsize=\small
+ ]
+ {latex}
+ {demotut3.dat}
+ \tcblower
+ \begin{CAS}
+ r = diff(q,x,h)
+ \end{CAS}
+ \whatis{q} vs \whatis{r}
+\end{codebox}
+
+So \texttt{q} is a \texttt{BinaryOperation}? This strikes Charlie as a little strange. On the other hand, \texttt{q} is the result of a binary operation applied to two other expressions; so perhaps this makes a modicum of sense.
+
+At any rate, Charlie now knows, according to \texttt{luacas}, that \texttt{q} is of the \texttt{Expression}-type \whatis{q}. The actual operator that's used to form \texttt{q} is stored in the attribute \mintinline{lua}{q.operation}:
+
+\tcbsidebyside[
+ sidebyside adapt=right,
+ enhanced,skin=bicolor,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle,
+ frame hidden
+ ]{
+ \inputminted[
+ firstline = 20,
+ lastline = 22,
+ breaklines,
+ fontsize=\small
+ ]
+ {latex}
+ {demotut3.dat}}
+ {
+ \luaexec{
+ if q.operation == BinaryOperation.ADD then
+ tex.sprint("I'm an \\texttt{ADD}")
+ end
+ }}
+
+Of course, different \texttt{Expression} types have different attributes. For example, being a \texttt{DiffExpression}, \texttt{r} has the attribute \texttt{r.degree}:
+
+\tcbsidebyside[
+ sidebyside adapt=right,
+ enhanced,skin=bicolor,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle,
+ frame hidden
+ ]{
+ \inputminted[
+ firstline = 24,
+ lastline = 24,
+ breaklines,
+ fontsize=\small
+ ]
+ {latex}
+ {demotut3.dat}}
+ {
+ \luaexec{
+ tex.print("I'm an order", r.degree, "derivative.")
+ }}
+
+\texttt{BinaryOperation}s have several attributes, but the most important attribute for Charlie's purposes is \texttt{q.expressions}. In this case, \texttt{q.expressions} is a table with two entries; those two entries are precisely the \texttt{Expressions} whose sum forms \texttt{q}. In particular,
+
+\mintinline{latex}{\[ \print{q.expressions[1]} \qquad \text{and} \qquad \print{q.expressions[2]} \]}
+
+produces:
+\[ \print{q.expressions[1]} \qquad\text{and} \qquad \print{q.expressions[2]} \]
+
+The expression \texttt{q.expressions[1]} is another \texttt{BinaryOperation}. Instead of printing the entire expression tree (as we've done above), Charlie might be interested in the commands \mintinline{latex}{\parseshrub} and \mintinline{latex}{\shrubresult}:
+
+\tcbsidebyside[
+ sidebyside adapt=right,
+ enhanced,skin=bicolor,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle,
+ frame hidden
+ ]{\small
+ \inputminted[
+ firstline = 26,
+ lastline = 30,
+ breaklines
+ ]
+ {latex}
+ {demotut3.dat}}
+ {\parseshrub{q.expressions[1]}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {draw,rectangle,rounded corners=1pt,fill=lightgray!20,font=\ttfamily, s sep=1.5cm}
+ @\shrubresult
+ \end{forest}
+}
+
+The ``shrub'' is essentially the first level of the ``forest'', but with some extra information concerning attributes. For contrast, here's the result of \mintinline{latex}{\parseshrub} and \mintinline{latex}{\shrubresult} applied to \texttt{r}, the \texttt{DiffExpression} defined above.
+
+\tcbsidebyside[
+ sidebyside adapt=right,
+ enhanced,skin=bicolor,
+ arc=1pt,
+ colframe=brown,
+ colback=brown!15,colbacklower=white,
+ boxrule=1pt,
+ notitle,
+ frame hidden
+ ]{\small
+ \inputminted[
+ firstline = 40,
+ lastline = 46,
+ breaklines
+ ]
+ {latex}
+ {demotut3.dat}}
+ {\parseshrub{r}
+ \bracketset{action character = @}
+ \begin{forest}
+ for tree = {draw,rectangle,rounded corners=1pt,
+ fill=lightgray!20,font=\ttfamily, s sep=1.5cm}
+ @\shrubresult
+ \end{forest}
+}
+The attribute \mintinline{lua}{r.degree} returns the size of the table stored in \mintinline{lua}{r.symbols} which, in turn, records the variables (and order from left-to-right) with which to differentiate the expression stored in \mintinline{lua}{r.expression}.
+
+Now that Charlie knows the basics of how \texttt{luacas} is structured, they're ready to try their hand at adding some functionality.
+
+
+\begin{multicols}{2}
+First, Charlie decides to up the complexity of their expression {\ttfamily f} so that they have something more general to work with:
+\begin{CAS}
+ vars('x','h')
+ f = x/(x^2+1)
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+\end{CAS}
+\begin{minted}{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x/(x^2+1)
+ subs = {[x]=x+h}
+ q = (substitute(subs,f)-f)/h
+\end{CAS}
+\end{minted}
+Next, Charlie decides to print the un\texttt{expand}ed expression tree for $q$ to help give them a clear view (see right).
+
+\begin{center}
+\parseforest{q}
+\bracketset{action character = @}
+\begin{forest}
+ for tree = {
+ font=\ttfamily}
+ @\forestresult
+\end{forest}
+\end{center}
+\end{multicols}
+
+Charlie now wants to write their own function for combining expressions like this into a single denominator. It's probably best that Charlie writes this function in a separate file, say \texttt{myfile.lua}. Like most functions in \texttt{luacas}, Charlie defines this function as a \emph{method} applied to an \texttt{Expression}:
+
+\begin{minted}[linenos]{lua}
+function Expression:mycombine()
+\end{minted}
+
+Next, Charlie declares some local variables to identify appropriate numerators and denominators:
+\begin{minted}[linenos,firstnumber=2]{lua}
+ local a = self.expressions[1].expressions[1].expressions[1]
+ local b = self.expressions[1].expressions[1].expressions[2]
+ local c = self.expressions[1].expressions[2].expressions[1]
+ local d = self.expressions[1].expressions[2].expressions[2]
+\end{minted}
+
+So, for example, $a = x+h$, $b = (x+h)^2+1$, and so on. Charlie now forms the numerator and denominator, and returns the function:
+
+\begin{minted}[linenos,firstnumber=6]{lua}
+ local numerator = a*d-b*c
+ local denominator = self.expressions[2]*b*d
+ return numerator/denominator
+end
+\end{minted}
+
+\luaexec{
+ function Expression:mycombine()
+ local a = self.expressions[1].expressions[1].expressions[1]
+ local b = self.expressions[1].expressions[1].expressions[2]
+ local c = self.expressions[1].expressions[2].expressions[1]
+ local d = self.expressions[1].expressions[2].expressions[2]
+ local numerator = a*d-b*c
+ local denominator = self.expressions[2]*b*d
+ return numerator/denominator
+ end
+}
+Now Charlie only needs to ensure that \texttt{myfile.lua} is in a location visible to their TeX installation (e.g. in the current working folder). Charlie can then produce the following:
+
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\directlua{dofile('myfile.lua')}
+\begin{CAS}
+ q = q:mycombine()
+\end{CAS}
+\[ \print{q} \]
+ \end{minted}
+ \tcblower
+ \begin{CAS}
+ q = q:mycombine()
+ \end{CAS}
+ \[ \print{q}\]
+\end{codebox}
+
+Charlie wants to simplify the numerator (but not the denominator). So they decide to write another function in \texttt{myfile.lua} that does precisely this:
+
+\begin{minted}[linenos,firstnumber = 11]{lua}
+function Expression:mysimplify()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = simplify(a)
+ return a/b
+end
+\end{minted}
+\luaexec{
+function Expression:simplifynum()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = simplify(a)
+ return a/b
+end
+}
+Now Charlie has:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ q = q:mysimplify()
+\end{CAS}
+\[ \print{q} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ q = q:simplifynum()
+\end{CAS}
+\[ \print{q} \]
+\end{codebox}
+Finally, Charlie wants to factor the numerator. So Charlie writes the following final function to \texttt{myfile.lua}:
+\begin{minted}[linenos,firstnumber = 18]{lua}
+function Expression:myfactor()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = factor(a)
+ return a/b
+end
+\end{minted}
+
+\luaexec{
+function Expression:factornum()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = factor(a)
+ return a/b
+end
+}
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+After factoring the numerator:
+\begin{CAS}
+ q = q:myfactor()
+\end{CAS}
+\[ \print{q} \]
+And then simplifying:
+\begin{CAS}
+ q = simplify(q)
+\end{CAS}
+\[ \print{q} \]
+\end{minted}
+\tcblower
+After factoring the numerator:
+\begin{CAS}
+ q = q:factornum()
+\end{CAS}
+\[ \print{q} \]
+And then simplifying:
+\begin{CAS}
+ q = simplify(q)
+\end{CAS}
+\[ \print{q} \]
+\end{codebox}
+Armed with their custom functions \texttt{mycombine}, \texttt{mysimplify}, and \texttt{myfactor}, Charlie can write examples just like Alice's examples, but using rational functions instead.
+
+Of course, the schlubs that manage this package feel for Charlie, and recognize that there are other situations in which folks may want to combine a sum of rational expressions into a single rational expression. Accordingly, there is indeed a \texttt{combine} command included in \texttt{luacas} that performs this task:
+\begin{codebox}
+ \begin{minted}[fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','y','z')
+ a = y/z
+ b = z/x
+ c = x/y
+ d = combine(a+b+c)
+\end{CAS}
+\[ \print{a+b+c} = \print{d} \]
+\end{minted}
+\tcblower
+\begin{CAS}
+ vars('x','y','z')
+ a = y/z
+ b = z/x
+ c = x/y
+ d = combine(a+b+c)
+\end{CAS}
+\[ \print{a+b+c} = \print{d} \]
+\end{codebox}
+
+Here's Charlie's complete code (but using \mintinline{latex}{\directlua}) instead:
+
+\begin{codebox}[frame hidden,breakable]
+\begin{minted}[breaklines,fontsize=\small]{latex}
+\begin{CAS}
+ vars('x','h')
+ f = x/(x^2+1)
+\end{CAS}
+Let $f(x) = \print{f}$. We wish to compute the derivative of $f(x)$ at $x$ using the limit definition of the derivative. Toward that end, we start with the appropriate difference quotient:
+\begin{CAS}
+ subs = {[x] = x+h}
+ q = (f:substitute(subs) - f)/h
+\end{CAS}
+\directlua{
+\end{minted}
+\end{codebox}
+And now the Lua code:
+\begin{codebox}[frame hidden, breakable]
+\begin{minted}[breaklines,fontsize=\small]{lua}
+ function Expression:mycombine()
+ local a = self.expressions[1].expressions[1].expressions[1]
+ local b = self.expressions[1].expressions[1].expressions[2]
+ local c = self.expressions[1].expressions[2].expressions[1]
+ local d = self.expressions[1].expressions[2].expressions[2]
+ local numerator = a*d-b*c
+ local denominator = self.expressions[2]*b*d
+ return numerator/denominator
+ end
+ function Expression:mysimplify()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = simplify(a)
+ return a/b
+ end
+ function Expression:myfactor()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = factor(a)
+ return a/b
+ end
+\end{minted}
+\end{codebox}
+And now back to the \LaTeX{} code:
+\begin{codebox}[frame hidden,breakable]
+\begin{minted}[breaklines,fontsize=\small]{latex}
+}
+\[ \begin{aligned}
+ \print{q} &=
+ \begin{CAS}
+ q = q:mycombine()
+ \end{CAS}
+ \print{q}& &\text{get a common denominator} \\
+ &=
+ \begin{CAS}
+ q = q:mysimplify()
+ \end{CAS}
+ \print{q}& &\text{simplify the numerator} \\
+ &=
+ \begin{CAS}
+ q = q:myfactor()
+ \end{CAS}
+ \print{q} & &\text{factor numerator} \\
+ &=
+ \begin{CAS}
+ q = simplify(q)
+ \end{CAS}
+ \print{q}& &\text{cancel the $h$s} \\
+ &\xrightarrow{h\to 0}
+ \begin{CAS}
+ subs = {[h] = 0}
+ q = substitute(subs,q):autosimplify()
+ \end{CAS}
+ \print{q}& &\text{take limit.}
+\end{aligned} \]
+\end{minted}
+\end{codebox}
+And here is Charlie's completed project:
+\begin{tcolorbox}[colback=roseorange!10,
+ colframe=roseorange,
+ arc=1pt,
+ frame hidden]
+{\bf Tutorial 3:} {\itshape A limit definition of the derivative for Charlie.}\vskip 0.2cm
+
+\begin{CAS}
+ vars('x','h')
+ f = x/(x^2+1)
+\end{CAS}
+Let $f(x) = \print{f}$. We wish to compute the derivative of $f(x)$ at $x$ using the limit definition of the derivative. Toward that end, we start with the appropriate difference quotient:
+\begin{CAS}
+ subs = {[x] = x+h}
+ q = (f:substitute(subs) - f)/h
+\end{CAS}
+\directlua{
+ function Expression:mycombine()
+ local a = self.expressions[1].expressions[1].expressions[1]
+ local b = self.expressions[1].expressions[1].expressions[2]
+ local c = self.expressions[1].expressions[2].expressions[1]
+ local d = self.expressions[1].expressions[2].expressions[2]
+ local numerator = a*d-b*c
+ local denominator = self.expressions[2]*b*d
+ return numerator/denominator
+ end
+ function Expression:mysimplify()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = simplify(a)
+ return a/b
+ end
+ function Expression:myfactor()
+ local a = self.expressions[1]
+ local b = self.expressions[2]
+ a = factor(a)
+ return a/b
+ end
+}
+\[ \begin{aligned}
+ \print{q} &=
+ \begin{CAS}
+ q = q:mycombine()
+ \end{CAS}
+ \print{q}& &\text{get a common denominator} \\
+ &=
+ \begin{CAS}
+ q = q:mysimplify()
+ \end{CAS}
+ \print{q}& &\text{simplify the numerator} \\
+ &=
+ \begin{CAS}
+ q = q:myfactor()
+ \end{CAS}
+ \print{q} & &\text{factor numerator} \\
+ &=
+ \begin{CAS}
+ q = simplify(q)
+ \end{CAS}
+ \print{q}& &\text{cancel the $h$s} \\
+ &\xrightarrow{h\to 0}
+ \begin{CAS}
+ subs = {[h] = 0}
+ q = substitute(subs,q):autosimplify()
+ \end{CAS}
+ \print{q}& &\text{take limit.}
+\end{aligned} \]
+\end{tcolorbox}
+
+\end{document} \ No newline at end of file