summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex')
-rw-r--r--macros/luatex/latex/luacas/doc/reference/ref_core/ref_core_classes/ref_core_classes.tex455
1 files changed, 455 insertions, 0 deletions
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