-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.tex
2491 lines (1959 loc) · 136 KB
/
main.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass{article}
%\usepackage[utf8]{inputenc} %not needed for LuaLaTeX
\usepackage{tikz}
\usetikzlibrary{positioning,
shapes,
shadows,
arrows.meta,
fit}
\usepackage{longtable}
\usepackage{multirow}
\usepackage{multicol}
%\usepackage{listings}
\usepackage{minted} %minted has nicer syntax highlighting I think
%\usemintedstyle{vs}
\usepackage{graphicx}
\usepackage{amsthm,amssymb,amsmath}
\usepackage{cleveref}
\usepackage{xcolor}
\usepackage{subfig,caption}
\usepackage[section]{algorithm}
\usepackage{algpseudocode}
\usepackage[shortlabels]{enumitem}
\usepackage{geometry}
\geometry{margin=1.5in}
\theoremstyle{definition}
\newtheorem{thm}{Theorem}[section]
\newtheorem{corollary}[thm]{Corollary}
\newtheorem{lemma}[thm]{Lemma}
\newtheorem{prop}[thm]{Proposition}
\newtheorem{defin}[thm]{Definition}
\crefformat{defin}{\bfseries definition~#2#1#3}
\Crefformat{defin}{\bfseries Definition~#2#1#3}
\newtheorem{remark}[thm]{Remark}
\newtheorem{exa}[thm]{Example}
\algnewcommand{\algorithmicand}{\textbf{ and }}
\algnewcommand{\algorithmicor}{\textbf{ or }}
\algnewcommand{\algorithmicnot}{\textbf{ not }}
\algnewcommand{\OR}{\algorithmicor}
\algnewcommand{\AND}{\algorithmicand}
\algnewcommand{\NOT}{\algorithmicnot}
\usepackage{calc}
\DeclareMathOperator{\Autosimplify}{Autosimplify}
\DeclareMathOperator{\arules}{AutosimplifyRules}
\DeclareMathOperator{\spow}{PowerAS}
\DeclareMathOperator{\sprod}{ProductAS}
\DeclareMathOperator{\ssum}{SumAS}
\DeclareMathOperator{\squo}{QuotientAS}
\DeclareMathOperator{\sdiff}{DifferenceAS}
\DeclareMathOperator{\slog}{LogarithmAS}
\DeclareMathOperator{\pow}{\wedge}
\DeclareMathOperator{\NaN}{NaN}
\DeclareMathOperator{\construct}{Construct}
\DeclareMathOperator{\subs}{Substitute}
\DeclareMathOperator{\Root}{Root}
\DeclareMathOperator{\subtree}{Subtree}
\DeclareMathOperator{\dist}{Distance}
\DeclareMathOperator{\eval}{Evaluate}
\DeclareMathOperator{\args}{Args}
\DeclareMathOperator{\sort}{Sort}
\DeclareMathOperator{\lc}{lc}
\DeclareMathOperator{\cont}{cont}
\DeclareMathOperator{\zass}{ZassenhausFactor}
\DeclareMathOperator{\con}{c}
\DeclareMathOperator{\expand}{Expand}
\usepackage[
backend=biber,
style=numeric,
]{biblatex}
\addbibresource{sources.bib}
\makeatletter
\let\c@algorithm=\c@thm % :)
\makeatother
%\lstdefinestyle{lua}{
% language=[5.1]Lua,
% basicstyle=\ttfamily,
% keywordstyle=\color{magenta},
% stringstyle=\color{blue},
% commentstyle=\color{black!50}
%}
%lstset{style=lua}
\usepackage[textsize=scriptsize]{todonotes}
\usepackage{parskip}%kills indents in favor of spacing
\begin{document}
\begin{titlepage}
\begin{center}
\vspace*{1cm}
{\Huge \textbf{Building A Computer Algebra System in Lua For Use With Lua\LaTeX{}}}
\vspace{1.5cm}
\textbf{Evan Cochrane}
\vfill
\includegraphics[width=0.75\textwidth]{rose.png}
\vfill
2021-2022 Senior Project\\
\vspace{0.8cm}
Advised By Timothy All \& Joe Eichholz\\
Department Of Mathematics\\
Rose-Hulman Institute of Technology\\
\end{center}
\end{titlepage}
\topskip0pt
\vspace*{\fill}
\begin{center}
\textbf{Foreward}
\end{center}
This paper consists of four appendices, which are a description of the mathematics behind the core functionality of computer algebra systems (Appendix A), as well as several important algorithms, namely simplification (Appendix B), symbolic root-finding (Appendix C), and symbolic integration (Appendix D). Each appendix also details how these features were implemented in code. These appendices function as a supplement to the documentation for the CAS (currently a WIP), but also as a report for the mathematics behind the CAS.
\vspace*{\fill}
\newpage
\tableofcontents
\newpage
\section{Representing Expressions}
The representation and manipulation of arbitrary mathematical expressions is at the core of any computer algebra system. In general, an expression is any finite well-formed collection of symbols, but for our purposes, the following suffices \cite{casc1}:
\begin{defin} \label{def1}
An \emph{expression} is a structured combination of elements from the following:
\begin{itemize}
\item A set of \emph{symbols} or \emph{identifiers} $S$,
\item A set of \emph{constants} $A$ with $A \cap S = \emptyset$, and
\item A set of \emph{operations} or \emph{functions} $F$ with each $f \in F$ having $f: A^n \to A$ for some $n \in \mathbb{N}$.
\end{itemize}
The set of expressions that can be constructed from these sets is denoted $\mathcal{X}(S, A, F)$.
\end{defin}
\begin{exa} \label{exa0}
A simple example of integer expressions uses $S = \{x, y, z\}$, $A = \mathbb{Z}$, and $F = \{+, \times\}$, with $+$ and $\times$ defined in the usual way from $\mathbb{Z}^2 \to \mathbb{Z}$. We can construct expressions like $3$, $x$, $y + 4$, and $-3 \times (x + 1)$ from these sets.
\end{exa}
Even examples like Example \ref{exa0} allow for complex expressions to be constructed. However, the `structure' of expressions still needs to be formally defined. One way to represent this structure is with an expression tree (defined in Definition \ref{def2} below). First, we introduce some graph theoretic definitions needed to discuss trees:
\begin{defin}
Let $V$ be a finite non-empty set, and let $E \subseteq \mathcal{P}(V)$ such that $\forall e \in E$, $|e| = 2$. We call the ordered pair $(V,E)$ an \emph{undirected graph}, or just a \emph{graph}. We call $V$ the set of \emph{vertices} or \emph{nodes}, and we refer to the set $E$ as the set of \emph{edges}.
\end{defin}
For an in-depth discussion of graph theory and trees, we refer the reader to \cite{mgt}.
Given a graph $G = (V, E)$, a vertex $v \in V$ is \emph{incident} to an edge $e \in E$ if $v \in e$. Two vertices $v_1, v_2$ are \emph{adjacent} if $\{v_1, v_2\} \in E$. A \emph{path} is an ordered list of distinct edges $(e_1, e_2, \ldots, e_n)$ such that $\forall i \in \{1, 2, .. n-1\}$, $|e_1 \cap e_2| = 1$. The \emph{length} of the path is the number of items in the list. We say that the path $(e_1, e_2, \ldots, e_n)$ is a path from the vertex in $e_1 \setminus e_2$ to the vertex in $e_{n} \setminus e_{n-1}$, and that $G$ contains that path. A \emph{cycle} is a path from a vertex to itself. A graph is \emph{connected} if there is a path from any vertex to any other vertex, or if $|V| = 1$.
Let $G = (V, E)$ be a connected graph and $v_1, v_2 \in V$. Then, let $\dist(v_1,v_2)$ be defined as the length of the shortest path between $v_1, v_2$ if $v_1 \neq v_2$, or $0$ if $v_1 = v_2$. It can be shown that $\dist$ is a metric on $V$.
\begin{defin}
A \emph{tree} is a connected graph that contains no cycles.
\end{defin}
\begin{exa}
Naturally, graphs can be diagrammed by representing circles as vertices and lines between those circles as edges.
\begin{figure}[H]
\centering
\subfloat[Not a tree - contains a cycle \label{fig:1a}]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw] (1) at (0,0) {};
\node [circle,draw] (2) at (0,-1) {};
\node [circle,draw] (3) at (1,-1) {};
\node [circle,draw] (4) at (-1,-2) {};
\node [circle,draw] (5) at (1,-2) {};
\node [circle,draw] (6) at (-1,-3) {};
\node [circle,draw] (7) at (0,-3) {};
\draw (1) -- (2);
\draw (2) -- (3);
\draw (3) -- (5);
\draw (5) -- (7);
\draw (7) -- (6);
\draw (6) -- (4);
\draw (4) -- (2);
\draw (4) -- (7);
\draw (4) -- (5);
\end{tikzpicture}} \hspace{2cm}
\subfloat[Not a tree - not connected \label{fig:1b}]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw] (1) at (0,0) {};
\node [circle,draw] (2) at (0,-1) {};
\node [circle,draw] (3) at (1,-1) {};
\node [circle,draw] (4) at (-1,-2) {};
\node [circle,draw] (5) at (1,-2) {};
\node [circle,draw] (6) at (-1,-3) {};
\node [circle,draw] (7) at (0,-3) {};
\draw (1) -- (2);
\draw (1) -- (3);
\draw (3) -- (5);
\draw (7) -- (6);
\draw (6) -- (4);
\end{tikzpicture}} \hspace{2cm}
\subfloat[A tree \label{fig:1c}]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw] (1) at (0,0) {};
\node [circle,draw] (2) at (0,-1) {};
\node [circle,draw] (3) at (1,-1) {};
\node [circle,draw] (4) at (-1,-2) {};
\node [circle,draw] (5) at (1,-2) {};
\node [circle,draw] (6) at (-1,-3) {};
\node [circle,draw] (7) at (0,-3) {};
\draw (1) -- (2);
\draw (2) -- (3);
\draw (3) -- (5);
\draw (7) -- (4);
\draw (6) -- (4);
\draw (4) -- (2);
\end{tikzpicture}}
\caption{Examples of graphs.}
\end{figure}
\end{exa}
A \emph{subgraph} of a graph $G = (V,E)$ is a graph $G' = (V',E')$ with $V' \subseteq V$ and $E \subseteq E'$. If for every pair of vertices $v_1,v_2 \in G$ we have that $G'$ satisfies \[\{v_1,v_2\} \in E \text{ and } v_1,v_2 \in V' \implies \{v_1,v_2\} \in E',\]
then we say that $G'$ is the \emph{induced subgraph} of $G$ over $V'$. When $G$ is a tree, we typically use the terms \emph{subtree} and \emph{induced subtree} instead of subgraph and induced subgraph, respectively.
A vertex of a tree is called a \emph{leaf node} if it is incident to exactly one edge. Otherwise, it is called a \emph{branch node}. It can be useful to distinguish a single node of a tree $T$ as a \emph{root node}, which we denote $R = \Root(T)$. A tree with a root is called \emph{rooted tree}. A rooted tree imposes a partial order $\prec$ on the vertices of a tree, where
\[ v_1 \prec v_2 \iff \dist(R, v_1) + \dist(v_1, v_2) = \dist(R, v_2).\]
(The Hasse diagram for this partial order on a tree is the tree itself!) If $v_2 \succ v_1$ and $v_2 \neq v_1$, $v_2$ is a \emph{descendant} of $v_1$. Each of the adjacent vertices to $R$ are \emph{children} of the root.
\begin{defin}
Let $T$ be a rooted tree, and let $\{v_1, \ldots, v_n\}$ be the nodes adjacent to $\Root(T)$. A \emph{descendant subtree} of $T$ is a rooted, induced subtree of $T$ over the set containing vertex $v_i$ and its descendants with $v_i$ as its root. Since this is the only kind of subtree we discuss in the rest of these appendices, we refer to descendant subtrees as subtrees for simplicity.
\end{defin}
Note that this definition requires us to impose some order on the children of each node in a rooted tree.
\begin{exa}
If we distinguish the node labeled 1 as the root in Figure 2,
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=0.75]
\node [circle,draw] (1) at (0,0) {1};
\node [circle,draw] (2) at (0,-1) {2};
\node [circle,draw] (3) at (1,-1) {3};
\node [circle,draw] (4) at (-1,-2) {4};
\node [circle,draw] (5) at (1,-2) {5};
\node [circle,draw] (6) at (-1,-3) {6};
\node [circle,draw] (7) at (0,-3) {7};
\draw (1) -- (2);
\draw (2) -- (3);
\draw (3) -- (5);
\draw (7) -- (4);
\draw (6) -- (4);
\draw (4) -- (2);
\end{tikzpicture}
\caption{A labeled tree.}
\end{figure}
the graph corresponding to the figure has only one subtree, shown in Figure 3. The roots of each tree are shown in red.
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=0.75]
\node [circle,draw, fill=red!40] (2) at (0,-1) {2};
\node [circle,draw] (3) at (1,-1) {3};
\node [circle,draw] (4) at (-1,-2) {4};
\node [circle,draw] (5) at (1,-2) {5};
\node [circle,draw] (6) at (-1,-3) {6};
\node [circle,draw] (7) at (0,-3) {7};
\draw (2) -- (3);
\draw (3) -- (5);
\draw (7) -- (4);
\draw (6) -- (4);
\draw (4) -- (2);
\end{tikzpicture}
\caption{Subtree of Figure 2 with 1 as the root.}
\end{figure}
If instead, the node labeled 2 is chosen as the root, the tree has three subtrees, shown in Figure 4.
\begin{figure}[H]
\centering
\subfloat[]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw, fill=red!40] (4) at (-1,-2) {4};
\node [circle,draw] (6) at (-1,-3) {6};
\node [circle,draw] (7) at (0,-3) {7};
\draw (4) -- (6);
\draw (4) -- (7);
\end{tikzpicture}} \hspace{2cm}
\subfloat[]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw, fill=red!40] (1) at (0,0) {1};
\end{tikzpicture}} \hspace{2cm}
\subfloat[]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw, fill=red!40] (3) at (1,-1) {3};
\node [circle,draw] (5) at (1,-2) {5};
\draw (3) -- (5);
\end{tikzpicture}}
\caption{Subtrees of Figure 2 with 2 as the root.}
\end{figure}
Subtree (a) has the node labeled 4 as its root, subtree (b) has 1, and subtree (c) has 3.
\end{exa}
\begin{defin}
We \emph{construct} a new rooted tree $T' = (V', E')$ from rooted trees $T_1 = (V_1, E_1), \ldots ,T_n = (V_n, E_n)$, where every pair of vertex sets is disjoint, and a brand new node $v$ where $v \notin V_i$ for $i \in \{1, \ldots, n\}$ as follows:
\begin{equation*}
\construct(v, (T_1, \ldots T_n)) = T' = (V', E'),
\end{equation*}
where
\begin{align*}
V' &= \bigcup\limits_{i=1}^{n}V_i \cup\{v\},\\
E' &= \bigcup\limits_{i=1}^{n}(E_i \cup \{v, \Root(T_i)\}), \text{ and }\\
\Root(T') &= v.
\end{align*}
\end{defin}
The operations $\subtree$ and $\construct$ are, in some sense, inverses, since if $T$ is a rooted tree with $\Root(T)$ adjacent to $n$ other vertices,
\begin{equation*}
\construct(\Root(T), \{\subtree(T,1), \ldots, \subtree(T, n)\}) = T.
\end{equation*}
We can use trees to represent the structure of expressions by anchoring the node with the outermost operation as the root node of the tree, with each of its children as operands. Each of those children's children are then operands to that child, and so forth.
Expressions can, of course, contain multiple of the same symbol, but every element of a set is unique. To allow multiple instances of a symbol in the vertex set, we index each vertex with a unique natural number.
\begin{defin} \label{def2}
An \emph{expression tree} is a rooted tree $T = (V, E) \in \mathcal{X}(S, A, F)$ that satisfies the following:
\begin{itemize}
\item If $|V| = 1$, then the single vertex $v \in V$ must have $v = (v', i)$ for some $v' \in S \cup A, i \in \mathbb{N}$.
\item If $|V| > 1$, then any leaf node $v \in V$ that is not the root node must have $v = (v', i)$ for some $v' \in S \cup A, i \in \mathbb{N}$. Every other node must have $v = (v', i)$ for some $v' \in F, i \in \mathbb{N}$.
\item If $v \in V$ and $v = (f, i)$, for some $f \in F$ with $f$ having $n$ inputs, then $v$ must be incident with exactly $n+1$ edges.
\end{itemize}
\end{defin}
To reduce the notational burden, $v = (v', i) \in V$ is represented as $v'$, so we can write $v \in S$, $v \in A$, or $v \in F$ as shorthand, for instance. Furthermore, we represent a tree with one vertex as the vertex itself, so we can say $T \in S$ or $T \in A$ if $\Root(T) \in S$ or $\Root(T) \in A$. See Example \ref{exa1} and Example \ref{exa2} for an extended example of how these trees are represented.
\begin{exa}
Using the set $\mathcal{X}(S, A, F)$ from Example \ref{exa0}, we also write the symbol, constant, or function in a circle in the diagram of an expression tree to represent the element of $S$, $A$, or $F$ present at the vertex. Rather than coloring the root, from now on we use the convention that the root of the tree is the topmost node in the diagram.
\begin{figure}[H]
\centering
\subfloat[Not an expression tree - does not satisfy the third part of definition \ref{def2}. \label{fig:2a}]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw,minimum width=1cm] (1) at (0,0) {\Large $\times$};
\node [circle,draw,minimum width=1cm] (2) at (2,-2) {\Large $+$};
\node [circle,draw,minimum width=1cm] (3) at (-2,-2) {\large $-3$};
\node [circle,draw,minimum width=1cm] (4) at (2,-4) {\large $x$};
\draw (1) -- (2);
\draw (1) -- (3);
\draw (2) -- (4);
\end{tikzpicture}} \hspace{2cm}
\subfloat[An expression tree - corresponding to $-3 \times (x + 1)$ \label{fig:2b}]{
\begin{tikzpicture}[scale=0.75]
\node [circle,draw,minimum width=1cm] (1) at (0,0) {\Large $\times$};
\node [circle,draw,minimum width=1cm] (2) at (2,-2) {\Large $+$};
\node [circle,draw,minimum width=1cm] (3) at (-2,-2) {\large $-3$};
\node [circle,draw,minimum width=1cm] (4) at (0,-4) {\large $x$};
\node [circle,draw,minimum width=1cm] (5) at (4,-4) {\large $1$};
\draw (1) -- (2);
\draw (1) -- (3);
\draw (2) -- (4);
\draw (2) -- (5);
\end{tikzpicture}}
\caption{Graphs and Expression Graphs}
\end{figure}
\end{exa}
\begin{defin}
Expressions consisting of a single symbol or constant (so the corresponding expression tree has $|V| = 1$) are \emph{atomic expressions}, since they cannot be divided into \emph{subexpressions}, which are just subtrees of an expression tree. All other expressions are \emph{compound expressions}, consisting of one or more subexpressions. Also, if $X \in \mathcal{X}(S,A,F)$ is an expression, we let the function $\args(X)$ denote the number of subexpressions of $X$.
\end{defin}
\subsection{Ring Expressions}
While expression trees are versatile enough to represent structures of predicates from logic, sets from mathematics and vectors and matrices from linear algebra, the core functionality of a CAS is, unsurprisingly, algebra. The algebra of ring theory is a common choice, since it has a variety of operations to use without being too restrictive as to what constants we have available. Common algebraic structures such as integers, rational numbers, and polynomials are all rings, which is another bonus.
\begin{defin}
A \emph{ring} is a 3-tuple $(R, +, \times)$, where $R$ is a set, and $+$, $\times$, are functions from $R^2 \to R$ that satisfy the following properties:
\begin{description}[style=multiline,
topsep=5pt,
leftmargin=5.5cm]
\item[\emph{Additive associativity:}] $\forall x, y \in R$, $((x + y) + z) = (x + (y + z))$
\item[\emph{Additive identity:}] $\exists 0 \in R$ such that $\forall x \in R$, $x+0=0+x=0$
\item[\emph{Additive inverse:}] $\forall x \in R$, $\exists y \in R$ such that $x + y = y + x = 0$
\item[\emph{Additive commutativity:}] $\forall x, y \in R$, $x + y = y + x$
\item[\emph{Multiplicative associativity:}] $\forall x, y \in R$, $((x \times y) \times z) = (x \times (y \times z))$
\item[\emph{Multiplicative identity:}] $\exists 1 \in R$ such that $\forall x \in R$, $x\times 1 = 1 \times x=1$
\item[\emph{Distributive Property:}] $\forall x,y,z \in R$, $x \times (y + z) = x\times y + x\times z$ and $(y + z) \times x = y\times x + y\times x$
\end{description}
\end{defin}
Multiplication of two ring elements $x \times y$ is usually written as $xy$. For an in-depth introduction to ring theory and the theory of other algebraic structures, see \cite{aa}.
A ring $R$ is a \emph{commutative ring} if it satisfies
\begin{equation*}
\forall x,y \in R, x \times y = y \times x.
\end{equation*}
The commutativity of multiplication is not assumed in a general ring, but most common rings, including all rings in the algebra package, have this property.
An \emph{integral domain} is a commutative ring $R$ if it further satisfies
\begin{equation*}
\forall x,y \in R, x \neq 0 \text{ and } y \neq 0 \implies xy \neq 0.
\end{equation*}
Rings such as the integers are also Euclidean domains, which ensure the division with remainder and modulo operations are easily understood. Formally, $R$ is a \emph{Euclidean domain} if $R$ is an integral domain and there is some function $f: R \to \mathbb{N}$ that satisfies
\begin{equation*}
\forall a, b \in R, \exists q,r \in R \text{ such that } a = bq + r \text{ with } r = 0 \text{ or } f(r) < f(b).
\end{equation*}
Finally, rings such as the rationals have multiplicative inverses for every element except $0$. When combined with commutativity, this makes the standard division operation well-defined. Formally, $R$ is a \emph{field} if it is commutative and
\[ \forall x \in R, \text{ if } x \neq 0, \text{ then } \exists y \in R \text{ such that } xy=yx=1.\]
All rings also have an exponentiation operation that can be defined analogous to exponentiation as is commonly used. Exponentiation is a function from $R \times \mathbb{N}$ to $R$, and is denoted as $x \pow n$ or $x^n$ for $x \in R$, $n \in \mathbb{N}$. Exponentiation is defined as follows:
\begin{equation*}
x^n = \begin{cases} 1 & n = 0\\
(x)(x^{n-1}) & n > 0.
\end{cases}
\end{equation*}
If $R$ is also a field, the exponent domain can be extended to $\mathbb{Z}$ as follows, assuming $x$ is not the zero element of the field and $y$ is the multiplicative inverse of $x$:
\begin{equation*}
x^n = \begin{cases} 1 & n = 0\\
(x)(x^{n-1}) & n > 0\\
y^{-n} & n < 0.
\end{cases}
\end{equation*}
The following example illustrates how expression trees are constructed for the field of rational numbers. By the end of the example, it will be a close analog of the actual implementation of expression trees in the CAS.
\begin{exa} \label{exa1}
Let $S = \{a, b, c, \ldots, x, y, z, A, B, C, \ldots, X, Y, Z, \_\}^+$, $A = \mathbb{Q}$, and $F = \{+, - , \times, /, \pow\}$ as in Definition \ref{def1}. The operations $+$, $\times$, and $\pow$ are defined as usual for the field of rationals. The operations $-$ and $/$ are defined by taking the inverse of the second element of the first two operations: $x - y = x + (-y)$; $x / y = (x)(1/y)$.
Unfortunately, this is not a proper expression tree yet. Some operators are not defined over all rational numbers - in particular, division is undefined when the second operand is zero, and exponentiation is undefined when the second operand is not an integer.
Most computer algebra systems, including this one (eventually!), fix this by outputting a special `not a number' constant $\NaN$, so $A$ can be changed to $\mathbb{Q} \cup \{\NaN\}$. Then, we extend the input of each operator by outputing $\NaN$ if any of the inputs are $\NaN$:
\begin{equation*}
\forall f \in F, f(\ldots,\NaN,\ldots) = \NaN
\end{equation*}
This behavior holds for all of the functions we will add in $F$. There are more notational quirks of the typical way algebraic expressions are written that we need to consider. Since addition and multiplication are associative, for instance $(x+y)+z = x+(y+z)$, we write either expression as $x+y+z$ without ambiguity. Associative operations almost always have parentheses omitted when writing, so
\begin{equation*}
x + (y + 1/5)
\end{equation*}
would be written
\begin{equation*}
x + y + 1/5.
\end{equation*}
We can account for this notation mathematically by replacing $+$ and $\times$ with their $n$-operand equivalents in $F$. Zero-operand addition and multiplication return $0$ and $1$ respectively, while single-operand addition and multiplication are identity functions.
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=0.75]
\node [circle,draw,minimum width=1.25cm] (plus) at (0,0) {\Large $+$};
\node [circle,draw,minimum width=1.25cm] (x) at (-2, -2) {\Large $x$};
\node [circle,draw,minimum width=1.25cm] (plus2) at (2,-2) {\Large $+$};
\node [circle,draw,minimum width=1.25cm] (y) at (1, -4) {\Large $y$};
\node [circle,draw,minimum width=1.25cm] (1/3) at (3, -4) {\Large $\frac{1}{5}$};
\node [circle,draw,minimum width=1.25cm] (plus3) at (8,0) {\Large $+$};
\node [circle,draw,minimum width=1.25cm] (x2) at (6, -2) {\Large $x$};
\node [circle,draw,minimum width=1.25cm] (y2) at (8, -2) {\Large $y$};
\node [circle,draw,minimum width=1.25cm] (1/32) at (10, -2) {\Large $\frac{1}{5}$};
\draw (plus) -- (x);
\draw (plus) -- (plus2);
\draw (plus2) -- (y);
\draw (plus2) -- (1/3);
\draw (plus3) -- (x2);
\draw (plus3) -- (y2);
\draw (plus3) -- (1/32);
\end{tikzpicture}
\caption{Example expression trees corresponding to $x + (y + 1/3)$ and $x + y + 1/3$. \label{fig:1}}
\end{figure}
Finally, the exponentiation operation is typically not thought of as undefined for non-natural powers -- consider $2^{1/2} = \sqrt{2}$, for instance. The result just happens to be outside the set of rationals. Rather than augmenting $A$ again, it would be cleaner to amend our expression definition so the domain and codomain of operations in $F$ include expression trees.
\end{exa}
\begin{defin}
(Revised) An \emph{expression} $X$ is a an element of the set $\mathcal{T} = \mathcal{X}(S,A,F)$, such that
\begin{itemize}
\item $S$ is a set of symbols,
\item $A$ is a set of constants with $A \cap S = \emptyset$ and $\NaN \in A$, and
\item $F$ is a set of operations with each $f \in F$ having $f: \mathcal{T}^n \to \mathcal{T}$ for some $n \in \mathbb{N}$.
\end{itemize}
\end{defin}
This definition is more versatile, and allows us to define more complex operators like the derivative as being a part of an expression rather than just an operation on expressions, but it introduces the additional complexity of recursion.
\begin{exa} \label{exa2}
Continuing from Example \ref{exa1}, we can leave the sets $S$ and $A$ alone for the revised definition, but functions $f$ now need to be extended to work for all expressions. For $+$, for instance, we let $x + y$ be defined as before if $x,y \in A$, and $\construct(+, (x,y))$ otherwise. Other operations work much the same, and $+$ and $\times$ use an $n$-tuple in the second argument to $\construct$ instead of a 2-tuple if there are $n$ arguments.
One exception is exponentiation, where
\begin{equation*}
x \pow y = \begin{cases} x^y & x \in A, y \in \mathbb{Z}\\
\construct(\pow, (x,y)) & \text{otherwise}.
\end{cases}
\end{equation*}
Trigonometric functions, logarithms, and any other special functions we desire can also be included in $F$. We also add the derivative to $F$ which takes two arguments, the first of which is an expression $X$ and the second of which is a variable $s \in S$. Rather than having to define limits over expression trees, we use a \emph{differential algebra} to define our derivative operator over $\mathcal{X}(S,A,F)$. For a complete description of a differential algebra, see Definition \ref{def8}. The differential algebra we use is the \emph{formal derivative}, which uses the standard properties of a differential algebra with the additional rule that $\frac{\mathrm{d}}{\mathrm{d}x}(x)=1$ for any variable $x \in S$.
We can represent the expression $\frac{\mathrm{d}}{\mathrm{d}x} (\sin (x) + 3x+6)$, for instance, as below:
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=0.75]
\node [circle,draw,minimum width=1.25cm] (D) at (0,0) {\Large \ttfamily D};
\node [circle,draw,minimum width=1.25cm] (plus) at (-2,-2) {\Large $+$};
\node [circle,draw,minimum width=1.25cm] (x) at (2, -2) {\Large $x$};
\node [circle,draw,minimum width=1.25cm] (sin) at (-5, -4) {\Large \ttfamily sin};
\node [circle,draw,minimum width=1.25cm] (times) at (-2, -4) {\Large $\times$};
\node [circle,draw,minimum width=1.25cm] (6) at (1, -4) {\Large \ttfamily 6};
\node [circle,draw,minimum width=1.25cm] (x2) at (-5, -6) {\Large$x$};
\node [circle,draw,minimum width=1.25cm] (3) at (-3, -6) {\Large \ttfamily 3};
\node [circle,draw,minimum width=1.25cm] (x3) at (-1, -6) {\Large $x$};
\draw (D) -- (plus);
\draw (D) -- (x);
\draw (plus) -- (sin);
\draw (plus) -- (times);
\draw (plus) -- (6);
\draw (sin) -- (x2);
\draw (times) -- (3);
\draw (times) -- (x3);
\end{tikzpicture}
\caption{Example expression tree corresponding to $\frac{\mathrm{d}}{\mathrm{d}x}(\sin(x) + 3x + 6)$. \label{fig:2}}
\end{figure}
This expression tree illustrates a case where subtree order matters, since $\sin(x)+3x+6$ can only be the first subtree of the derivative.
\end{exa}
\subsection{Generic Expression Operations}
\begin{defin}
\emph{Structural equality} $(=)$ is equality on a set of expression trees $\mathcal{X}(S, A, F)$ defined in the usual way using set and tuple equality, including the underlying equalities on $S$ and $A$.
\end{defin}
While structural equality is useful, it does not align with the conventional notion of equality that a user of our CAS would want. It will not return the expressions $x + x$ and $2x$, or even $(x + x) + x$ and $x + x + x$ as equal. For this, we need to define various operations that act on trees. (These could even be added as part of the $F$ set, if the expression structure is defined properly.)
\begin{defin}
\emph{Evaluation} is a function that outputs the result of applying each function in a tree to its sub-tree recursively. Given an expression $X \in \mathcal{X} = \mathcal{X}(S, A, F)$,
\begin{equation*}
\eval(X) = \begin{cases}
X & X \in S \cup A \\
f(\eval(\subtree(X,1)), \ldots, \\ \eval(\subtree(X,m))) & \Root(X) = f \in F, f:\mathcal{X}^m\to\mathcal{X}
\end{cases}
\end{equation*}
If $\eval(X) \in A$, then $X$ is \emph{evaluatable}. If $\eval(X) = X$, then $X$ is an \emph{evaluated expression}.
\end{defin}
If for all $X \in \mathcal{X} = \mathcal{X}(S, A, F)$, there exists some natural number $n$ for which \[\eval^{n+1}(X) = \eval^n(X),\] then $\mathcal{X}$ is \emph{terminating}.
Evaluation is not a very useful procedure in actual CASs, but it is an important theoretical tool. To reduce the number of cases we need to consider in our algorithms, the set of evaluated expressions is typically the full subset of expressions we consider manipulating. This subset can further be reduced to autosimplified expressions (see Appendix B).
\begin{exa} Continuing from Example \ref{exa2}, expressions are evaluatable if and only if they do not contain symbols. For example,
\begin{align*}
\eval(((3 - 4)x) - y) &= \eval((3-4)x)-\eval(y)\\
&= \eval(3-4)\eval(x) - y \\
&= (\eval(3)-\eval(4))x-y\\
&= (-1)(x)-y.
\end{align*}
Here, the subexpression $(3-4)$ is evaluatable, but the whole expression is not. Also, $\mathcal{X}(S, A, F)$ is a terminating set of expressions. In fact,
\begin{thm}
Let $\mathcal{X}(S, A, F)$ be defined as in Example \ref{exa2}, except $F$ does not contain the derivative operator. Then,
\begin{equation*}
\forall X \in \mathcal{X}, \eval(\eval(X)) = \eval(X).
\end{equation*}
\end{thm}
\begin{proof}
Proof by structural induction. Let $X \in \mathcal{X}$. If $X \in S \cup A$, then $\eval(X) = X$, so $\eval(\eval(X)) = \eval(X)$.
Otherwise, assume each subtree of the $n$ subtrees of $X_i = \subtree(X, i)$ of $X$ has \[\eval(\eval(X_i)) = \eval(X_i).\] Let $f = \Root(X)$. If all subtrees have $X_i \in A$ (or $X_i \in \mathbb{N}$ if $f = \pow$), then $\eval(X) \in A$, so $\eval(\eval(X)) = \eval(X)$. Otherwise, every $f \in F$ has
\begin{equation*}
f(X_1, \ldots ,X_n) = \construct(f, (X_1, \ldots, X_n)) = X,
\end{equation*}
so again, $\eval(\eval(X)) = \eval(X)$.
\end{proof}
If the derivative operator is included in $F$, it is still true that $\mathcal{X}$ is terminating, since it can be shown that $\eval^3(X) = \eval^2(X)$ for every $X \in \mathcal{X}$.
\end{exa}
\begin{defin} \label{def3}
\emph{Substitution} is a function that replaces variables in an expression with other expressions. Given an expression $X \in \mathcal{X} = \mathcal{X}(S, A, F)$, and a set of tuples $\mathcal{S} = \{(s_1, X_1), \ldots , (s_n, X_n)\}$, where each $s_i$ is a unique element of $S$ and each $X_i \in \mathcal{X}$,
\begin{equation*}
\subs(X, \mathcal{S}) = \begin{cases}
X & X \in A \\
X & X \in S \text{ and } X \neq s_i \forall i \\
X_i & X \in S \text{ and } X = s_i\\
f(\subs(\subtree(X, 1)),\ldots, \\ \subs(\subtree(X, m))) & \Root(X) = f \in F, f:\mathcal{X}^m\to\mathcal{X}
\end{cases}
\end{equation*}
\end{defin}
Substitution is an important procedure in CASs in its own right. It is used when evaluating polynomials, for instance. Note also the relation to evaluation - in fact, $\subs(X, \emptyset) = \eval(X)$.
\begin{exa}
Continuing from Example \ref{exa2}, If $\mathcal{S} = \{(x, -2), (y, 2*y), (z, 4)\}$,
\begin{align*}
\subs(((3 - 4)x) - y, \mathcal{S}) &= \subs((3-4)x, \mathcal{S})-\subs(y, \mathcal{S})\\
&= \subs(3-4, \mathcal{S})\subs(x, \mathcal{S}) - 2y \\
&= (\subs(3, \mathcal{S})-\subs(4, \mathcal{S}))(-2)-2y\\
&= (-1)(-2)-2y\\
&= 2-2y.
\end{align*}
\end{exa}
\begin{defin} \label{def4}
Two expressions $X_1, X_2$ in a terminating set of expressions $\mathcal{X}(S, A, F)$ are \emph{semantically equal}, $X_1\overset{s}{=}X_2$, if, for all $\mathcal{S} \in \mathcal{P}(S \times A)$ with $|\mathcal{S}| = |S|$ and the set of all first elements of the tuples of $\mathcal{S}$ equal to $S$,
\begin{equation*}
\subs(\eval^n(X_1), \mathcal{S}) = \subs(\eval^m(X_2), \mathcal{S})
\end{equation*}
where $n$ and $m$ are natural numbers such that $\eval^{n+1}(X_1) = \eval^n(X_1)$ and $\eval^{m+1}(X_2) = \eval^m(X_2)$.
\end{defin}
This definition is not defined by any structure on the underlying set $A$, but instead by the notion that every possible substitution of variables in $S$ for two expressions results in the same element of $A$.
The termination requirement is due to the fact that both expressions must be evaluated expressions to ensure operations that act on trees and are part of $F$, such as the derivative, are semantically equal to their evaluations, so, for instance,
\begin{equation*}
\frac{\mathrm{d}}{\mathrm{d}x} (x^2) \overset{s}{=} x+x
\end{equation*}
would not work if the evaluation functions where not included.
Sets of operations that result in expression sets that are not terminating are somewhat contrived anyway. The most obvious example are including functions in $F$ that return a modified version of themselves:
\begin{equation*}
f(X) = \construct(+, (f(X), 1))
\end{equation*}
Semantic equality in the usual sense is ill-defined for these expressions anyway, since it would seem that
\begin{equation*}
f(X) \overset{s}{=} f(X) + 1 \overset{s}{=} (f(X) + 1) + 1\overset{s}{=} \ldots
\end{equation*}
\begin{thm}
If $\mathcal{X}(S,A,F)$ is a terminating set of expressions, $\overset{s}{=}$ is an equivalence relation on $\mathcal{X}(S,A,F)$.
\end{thm}
The proof largely follows from the fact that structural equality is an equivalence relationship on $\mathcal{X}(S,A,F)$ The details are left to the reader.
\subsection{Implementation Details}
While mathematically rigorous definitions of expression trees can be rather cumbersome, they are natural to implement as data structures in code. In Lua, this means using tables. Lua does not have built-in object-oriented functionality like Python or Java - instead, we use prototypes. \cite{pil} A prototype is a single table that acts like a class. It has a {\ttfamily new} method that can be used to construct tables, which correspond with objects. These objects have specific functions and variables as entries, which correspond to methods and instance variables, respectively. This is further streamlined by creating a metatable for the object and setting the {\ttfamily \_\_index} field to the class itself. The {\ttfamily \_\_index} field's entries, which are the class's entries, are accessed if no entry is found in the table the metatable is assigned to. Example code for creating an object in the ring of rationals is shown below:
\inputminted[
firstline=13,
lastline=52,
breaklines]
{lua}
{algebra/rational.lua}
Inheritance can also be implemented in Lua using the {\ttfamily \_\_index} metamethod, since it works recursively. If a class has an {\ttfamily \_\_index} metamethod then it can call methods from its superclass. The exception to this is other metamethods, which must be set in the metatable of the object itself. Interface implementation isn't necessary in Lua due to weak typing, but can still be implemented in spirit by adding superclasses with methods that throw errors for any methods that a subclass must implement.
Creating the prototypes for expression trees is as simple as creating a prototype for a general expression, and two prototypes for atomic and compound expressions that inherit their properties from general expressions. Compound expressions have one or more general expressions as instance variables, thus completing the recursive tree structure.
The various ring classes implemented in the algebra package - integers, integer mod rings, rationals, and polynomials - all inherit from atomic expressions. The various functions and operations, including binary operations ($+$, $\times$, $-$, $/$, and $\pow$), derivatives, integrals, and special functions all inherit from compound expressions. Each object created from a prototpye is an expression tree.
The code for substitution is split across different classes (compare with Definition \ref{def3}):
\inputminted[
firstline=44,
lastline=51,
breaklines]
{lua}
{core/atomicexpression.lua}
\inputminted[
firstline=23,
lastline=35,
breaklines]
{lua}
{core/compoundexpression.lua}
\newcommand{\iClass}{\tikz[baseline=-0.75ex]{\node[circle,draw,draw=violet!75!black,fill=violet!30,text=black,inner sep=1pt]{\bfseries\ttfamily I};}\,}
\newcommand{\cClass}{\tikz[baseline=-0.75ex]{\node[circle,draw,draw=red!75!black,fill=green!30,text=black,inner sep=1pt]{\bfseries\ttfamily C};}\,}
\tikzstyle{class}=[rectangle,
draw=violet!75!black,
rounded corners=1pt,
fill=yellow!30,
drop shadow,
align=left,
text=black,
font=\footnotesize\sffamily,
rectangle split,
rectangle split parts=3,
rectangle split part align={left,left,left}]
\tikzstyle{inherit}=[-{Triangle[open,scale=1.5]},red!75!black]
\tikzstyle{has}=[-{Triangle[scale=1.5]},red!75!black]
\tikzset{package/.style args={#1}{
draw,
thick,
inner sep=7pt,
rectangle,
rounded corners=1pt,
label={[draw,trapezium,thick,outer sep=0pt,inner sep =2pt]\footnotesize\sffamily\bfseries #1}
}
}
A simplified inheritance hierarchy is shown below:
\begin{figure}[H]
\centering
\begin{tikzpicture}[remember picture]
\node [class] (cexpression)
{\iClass\itshape CompoundExpression
};
\node[class,right=of cexpression] (expression)
{\iClass\itshape Expression
\nodepart{third} evaluate() \\
substitute(map)\\
autosimplify()
};
\node[class,right=of expression] (aexpression)
{\iClass\itshape AtomicExpression
};
\node[class,below=of aexpression] (constant)
{\raisebox{1.5ex}{\iClass}\itshape ConstantExpression
};
\node[class,left=of constant] (symbol)
{\cClass\itshape SymbolExpression
\nodepart{second} symbol
};
\node[class,left=of symbol] (function)
{\cClass\itshape Function
};
\node[class,left=of function] (binop)
{\cClass\itshape BinaryOp
\nodepart{second} operation
\nodepart{third} isassociative()\\
iscommutative()
};
\node[class,below=1.5cm of constant] (ring)
{\raisebox{1.5ex}{\iClass}\itshape Ring
\nodepart{third} $+$ $-$ $\times$ \\
zero() \\
one()
};
\node[class,below=of ring] (euclid)
{\raisebox{1.5ex}{\iClass}\itshape EuclideanDomain
\nodepart{third} $\mod$
};
\node[class,below=of euclid] (field)
{\raisebox{1.5ex}{\iClass}\itshape Field
\nodepart{third} $\div$
};
\node[class, left=of ring] (polynomial)
{\cClass\itshape PolynomialRing
};
\node[class, left=of euclid] (integer)
{\cClass\itshape Integer
\nodepart{two} digits[]
};
\node[class, left=of field] (rational)
{\cClass\itshape Rational
};
\node[class, left=of integer] (mod)
{\cClass\itshape IntegerModRing
};
\draw [inherit] (cexpression.one east) -- (expression.one west) ;
\draw [inherit] (aexpression.one west) -- (expression.one east);
\draw [has] (cexpression.two east) -- (expression.two west) node[below,midway] {0..*};
\draw [inherit] (symbol.one north) -- (aexpression.three south);
\draw [inherit] (constant.one north) -- (aexpression.three south);
\draw [inherit] (binop.one north) -- (cexpression.three south);
\draw [inherit] (function.one north) -- (cexpression.three south);
\draw [has] (function.two east) --
(symbol.one west) node[above,midway] {1};
\draw [inherit] (ring.one north) -- (constant.three south);
\draw [inherit] (euclid.one north) --(ring.three south);
\draw [inherit] (field.one north) -- (euclid.three south);
\draw [inherit] (polynomial.one east) -- (ring.one west);
\draw [inherit] (integer.one east) -- (euclid.one west);
\draw [inherit] (rational.one east) -- (field.one west);
\draw [inherit] (mod.one east) -- (ring.three west);
\draw [has] (mod.two east) -- (integer.one west) node[above,midway] {2};
\draw [has] (rational.one north) -- (integer.three south) node[above,midway] {2};
\draw [has] (polynomial.two east) -- (ring.two west) node[above,midway] {1..*};
\draw [has] (polynomial.one north) -- (symbol.three south) node[below left] {1};
\node[package={Core},
fit=(cexpression)(expression)(aexpression)(constant)(symbol)(binop)(function)] (exp) {};
\node[package={Algebra},
fit=(ring)(euclid)(field)(polynomial)(rational)(integer)(mod)] (exp) {};
\end{tikzpicture}
\caption{Simplified UML class diagram for expressions and the algebra package.}
\end{figure}
Note here the parallels between the mathematical and class structures: All fields are euclidean domains, which in turn are rings. Objects are thus elements of the structure (class) they are instantiated from. Polynomial rings are dynamically created as either rings or euclidean domains depending on whether the underlying ring is a field or not. Similarly, Integer Mod Rings are instantiated as fields if the modulus used to create them is prime. The seeming lack of respect for software engineering principles here is in part due to the nature of building a computer algebra system itself (a field is always going to be a ring, so we don't need to favor composition over inheritance) and partly due to the peculiar nature of OOP in Lua. (Just try doing conditional inheritance in Java!)
\newpage
\section{Autosimplification}
\textit{Simplification}, broadly speaking, is the conversion of expressions into other expressions that are less complicated or easier to read. \textit{Automatic simplification}, or \textit{autosimplification}, is a simplification algorithm done on all expressions input into the CAS and output to the user. \cite{casc2} An expression that is the output of an autosimplification algorithm is called an \textit{autosimplified expression}. The primary purpose of autosimplification is to reduce the set of expressions we have to consider in most functions that act on expressions to just autosimplified expressions, as well as to display output to the user in a reasonable-looking way.
We can also have more theoretical aims, though. Definition \ref{def4} does not give a viable procedure for determining whether two expressions are semantically equal, since we would need to perform infinitely many substitutions if either the $S$ set or $A$ set is infinitely large. Using autosimplification, we might hope that we can reduce the problem of determining semantic equality to determining structural equality. Specifically, given an expression set $\mathcal{X} = \mathcal{X}(S,A,F)$, we would like
\begin{equation*}
\forall X_1, X_2 \in \mathcal{X}, X_1 \overset{s}{=} X_2 \iff \Autosimplify(X_1) = \Autosimplify(X_2).
\end{equation*}
Unfortunately, this is not feasible to achieve. First, continuing with the expression set from the Appendix A examples, a user of our CAS would likely want
\begin{equation*}
\Autosimplify\left(\frac{x}{x}\right) = 1,
\end{equation*}
however, $\frac{x}{x} \overset{s}{\neq} 1$, since $\subs(\frac{x}{x}, \{(x, 0)\}) = \NaN$, but $\subs(1, \{(x, 0)\}) = 1$. This particular scenario can be remedied by relaxing strict semantic equality slightly:
\begin{defin}
Two expressions $X_1, X_2$ in a terminating set of expressions $\mathcal{X}(S, A, F)$ are \emph{definitely semantically equal}, $X_1\overset{s}{\approx}X_2$, if, for all $\mathcal{S} \in \mathcal{P}(S \times A)$ with $|\mathcal{S}| = |S|$ and the set of all first elements of the tuples of $\mathcal{S}$ equal to $S$,
\begin{equation*}
\subs(\eval^n(X_1), \mathcal{S}) = \subs(\eval^m(X_2), \mathcal{S}),
\end{equation*}
or
\begin{equation*}
\subs(\eval^n(X_1), \mathcal{S}) = \NaN, \text{ or } \subs(\eval^m(X_2), \mathcal{S}) = \NaN,
\end{equation*}
where $n$ and $m$ are natural numbers such that $\eval^{n+1}(X_1) = \eval^n(X_1)$ and $\eval^{m+1}(X_2) = \eval^m(X_2)$.
\end{defin}
Definite semantic equality, like semantic equality, is an equivalence relation on a terminating set of expressions. Furthermore, semantic equality implies definite semantic equality.
However, it is still infeasible to enforce
\begin{equation*}
\forall X_1, X_2 \in \mathcal{X}, X_1 \overset{s}{\approx} X_2 \iff \Autosimplify(X_1) = \Autosimplify(X_2)
\end{equation*}
for the functionality of our computer algebra system. For instance, consider the expression $(x+1)^{1000}$. Expanding the expression using the binomial theorem gives \[(x+1)^{1000} \overset{s}{=} x^{1000}+\binom{1000}{1} x^{999}+ \ldots + \binom{1000}{999} x+1.\] Clearly, the expression $(x+1)^{1000}$ is `simpler' (if we wanted an exact notion of simplicity, we could use the number of vertices in corresponding expression trees). However, autosimplifying the later expression into the former requires factoring a 1000-degree polynomial, which is slow. Since autosimplify is called by our CAS for every entered expression, sometimes multiple times, it needs to be fast, which factoring a large polynomial is generally not (see Appendix C).
The most we could hope for, then, from an autosimplification procedure is:
\begin{equation*}
\forall X_1, X_2 \in \mathcal{X}, \Autosimplify(X_1) = \Autosimplify(X_2) \implies X_1 \overset{s}{\approx} X_2.
\end{equation*}
(This does not mean we shouldn't try to reduce as many semantically equal expressions to structurally equal expressions as is reasonable!) We would also like all autosimplified expressions to always autosimplify to themselves, so if the user takes output from the CAS and inputs it back in, the new output is always the same as the old output (Looking at you, Maple!):
\begin{equation*}
\forall X \in \mathcal{X}, \Autosimplify(\Autosimplify(X)) = \Autosimplify(X).
\end{equation*}
\begin{defin} \label{def5}
\emph{Autosimplification} is a function that transforms expressions into simpler expressions. The following procedure defines generic autosimplification:
\begin{algorithm}\small
\caption{Generic Autosimplification Algorithm}
\begin{algorithmic}[1]
\Require $X \in \mathcal{X}(S, A, F)$
\Ensure $X$ is autosimplified
\If{$X \in S \cup A$}
\State \Return $X$
\Else
\For{$i \in \{1, \ldots, \args(X)\}$}
\State $X_i \gets \subtree(X, i)$
\State $X_i \gets \Autosimplify(X_i)$
\EndFor
\State $X \gets \construct(\Root(X), \{X_1, \ldots, X_{\args(X)}\})$
\State \Return $\arules(X)$
\EndIf
\end{algorithmic}
\end{algorithm}
\end{defin}
\emph{Autosimplification rules} are a set of transformations from expressions to expressions that depend on the set of functions in $F$, and may be complex functions themselves.
\begin{thm}
If, for all $ X \in \mathcal{X}(S, A, F)$, $\arules(X) \overset{s}{\approx} X$, then $\forall X_1, X_2 \in \mathcal{X}(S, A, F)$, $\Autosimplify(X_1) = \Autosimplify(X_2) \implies X_1 \overset{s}{\approx} X_2$.
\end{thm}
This theorem is straightforward, but it is useful because it allows us to use properties of the $S$ set to construct autosimplification rules.
Due to the autosimplification rules, the nature of autosimplification is heavily dependent on the structure underlying the set of expressions. Our discussion, then, is focused on the $\mathcal{X}(S, A, F)$ set developed in Example \ref{exa1}, as it mirrors the expression trees in the CAS. See Example \ref{exa3} for the autosimplification algorithm in practice.
\subsection{Autosimplification Over Fields}
Before we start defining our autosimplification rules, there is one caveat we need to address. The commutativity of multiplication and addition mean that we can rearrange $n$-ary sums and products in any order and still maintain semantic equality:
\begin{equation*}
x+2y+3z^2 \overset{s}{=} 2y+3z^2+x \overset{s}{=} 3z^2+2y+x \overset{s}{=} \ldots
\end{equation*}
Thus, for the autosimplifications of these expressions to be structurally equal, we need to maintain a total order $\lhd$ on all autosimplified expressions, and our simplification rules need to sort the subexpressions of sum expressions and product expressions by $\lhd$.
\begin{defin}
Let $\mathcal{X} = \mathcal{X}(S, A, F)$ be defined as in Example \ref{exa2}, and $\leq$ be the standard linear order on $\mathbb{Q}$ and the standard lexographic order on $A$. Let $\lhd$ be the binary relation on $\mathcal{X}$ defined by the Algorithm \ref{alg1}, which returns {\ttfamily true} if and only if $(U, V) \in \lhd$.
\begin{algorithm}\small