\chapter{File System}

\section{Size of file cache}
In this part, we try to determine the file cache size.

\paragraph{Methodology}
If the file the fit into cache totally, then it would be very fast to read. If the file is too big that can not be put into cache totally, then read would be slower then that fir into cache totally.

So I prepared 40 files with different sizes ranging from 1GB to 4GB. We read each file 10 times and calculate  read cycles/MB.

\paragraph{Predictions}
Our computer main memory is 8GB. So the cache must be less than 8GB; Besides, the project web page says it is a notable fraction of main memory and can be several GBs. So we predict it is 2GBs.

\paragraph{Results}
We present our measure results. By the way, we did not show the results of files that are less than 3GB, we have run them and narrow down
narrow the range from 3GB to 4GB. So we only include result from 3GB to 4GB here.

\begin{center}
\begin{tabular}{l*{6}{c}r}
File Size             &  Cycles/MB\\
\hline
3000MB & 610 \\
3100MB & 614 \\
3200MB & 598 \\
3300MB & 622 \\
3400MB & 1965 \\
3500MB & 5498 \\
3600MB & 5572 \\
3700MB & 5503 \\
3800MB & 5673 \\
3900MB & 5657 \\
4000MB & 5598 \\

\end{tabular}
\end{center}

\begin{figure}[htbp] %  figure placement: here, top, bottom, or page
   \centering
   \includegraphics[width=5in]{./pics/41.jpg}
   \caption{read cycles}
   \label{fig:read cycles}
\end{figure}

\paragraph{Discussion}
The graph shows that the file cache size is between 3300MB and 3500MB. Before this experiment, I did not realize that OS will use so many spaces for file cache. This optimization speed up file reading time significantly. I do this measurement when my computer is free. If my computer are running many applications that consume many memory, then I think OS could not provide so much memory for file caching.

\section{File read time}
In this part, we report for both sequential and random access as a function of file size.

\paragraph{Methodology}
First, in order not to measure cached data, we want to set O\_DIRECT flag when opening a file, which could minimize cache effects of the I/O from this file. But Mac OS does not support O\_DIRECT. So we looked through Apple document and find we can set F\_NOCACHE flag in fcntl().

Besides, we use read() for sequential access, because read() will modify file pointer that fit the situation; However for random access it is bad to use read(), because we have to use lseek() to move the file pointer to target position which will significantly cost time. So we use pread() instead of read() for random access. Pread() works just like read() but reads from the specified position in the file without modifying the file pointer.

We provide several files with different sizes and iterate 100 times, then calculate  the average per-block read time.

\paragraph{Predictions}
In previous measurement, we can see it is very cheap to read file with cache. I can not find any related data about file reading time without cache on the web. It is hard to make predictions.

Because we are using SSD, the speed of sequential and random access shoule be close to each other. Considering that we did not use file cache, we will fetch each block of data from disk. Besides, read is a system call, without cache I think it will block which may introduce context switch. So I predict the time is about twice of context switch : 280000 software overheads and 20000 hardware overheads.

\paragraph{Results}
We present our measure results. The base file is 4KB, and we define log(4KB) = 2.

\begin{figure}[htbp] %  figure placement: here, top, bottom, or page
   \centering
   \includegraphics[width=5in]{./pics/42.jpg}
   \caption{read cycles per block}
   \label{fig:read cycles per block}
\end{figure}

\begin{center}
\begin{tabular}{| p{2cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{3cm}}
File Size &  Base Hardware Performance  & Estimated Software Overhead  & Predicted Time  & Measured Time & Std  \\

\hline
4KB & 20000 cycles& 280000 cycles& 300000 cycles& 401481 cycles & 10665 cycles \\
8KB & 20000 cycles& 280000 cycles& 300000 cycles& 475677 cycles & 13289 cycles \\
16KB & 20000 cycles& 280000 cycles& 300000 cycles& 501356 cycles & 10032 cycles \\
32KB & 20000 cycles& 280000 cycles& 300000 cycles& 670260 cycles & 15723 cycles \\
64KB & 20000 cycles& 280000 cycles& 300000 cycles& 489722 cycles & 12875 cycles \\
128KB & 20000 cycles& 280000 cycles& 300000 cycles& 397495 cycles & 12200 cycles \\
256KB & 20000 cycles& 280000 cycles& 300000 cycles& 293712 cycles & 9200 cycles \\
512KB & 20000 cycles& 280000 cycles& 300000 cycles& 300106 cycles &  10085 cycles \\
1024KB & 20000 cycles& 280000 cycles& 300000 cycles& 281106 cycles & 5602 cycles \\
2048KB & 20000 cycles& 280000 cycles& 300000 cycles& 287629 cycles & 6001 cycles \\

\end{tabular}
\end{center}

Above is the result of sequential access. We can see on average it takes about 300000-600000 cycles to read each file block, close to what we predicted previously.

\begin{center}
\begin{tabular}{| p{2cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{3cm} }
File Size   & Base Hardware Performance  & Estimated Software Overhead  & Predicted Time  & Measured Time  & Std \\
\hline
4KB & 20000 cycles& 280000 cycles& 300000 cycles& 420067 cycles & 17352 cycles\\
8KB & 20000 cycles& 280000 cycles& 300000 cycles& 393597 cycles & 13847 cycles\\
16KB & 20000 cycles& 280000 cycles& 300000 cycles& 502322 cycles & 15555 cycles\\
32KB & 20000 cycles& 280000 cycles& 300000 cycles& 405538 cycles & 14200 cycles\\
64KB & 20000 cycles& 280000 cycles& 300000 cycles& 425528 cycles & 12222 cycles\\
128KB & 20000 cycles& 280000 cycles& 300000 cycles& 426442 cycles & 13902 cycles \\
256KB & 20000 cycles& 280000 cycles& 300000 cycles& 504624 cycles & 10002 cycles\\
512KB & 20000 cycles& 280000 cycles& 300000 cycles& 492654 cycles & 12320 cycles \\
1024KB & 20000 cycles& 280000 cycles& 300000 cycles& 430804 cycles & 10800 cycles\\
2048KB & 20000 cycles& 280000 cycles& 300000 cycles& 426658 cycles & 9602 cycles \\

\end{tabular}
\end{center}

Above is the result of random access. We can see on average it takes about 400000-500000 cycles to read each file block, also close to what we predicted previously.

\paragraph{Discussion}
As we have predicted, random access is almost as fast as sequential access due to SSD. We also can see, without file cache, it would be very expensive to do file reading. Each block would cost almost 300000-600000 cycles on average.

Then I remove F\_NOCACHE flag to do file reading, finding that it only takes about 1000-2000 cycles per block, which is so cheap compared with no cache. It speeds up over 100 times. So, in most situations open file with cache is good for program performance.

As for "sequential" access might not be sequential, we have to seek the next right position for sequential read without cache. Because contents in a file may not be consecutive.

\section{Remote file read time}
In this section, we conduct the previous experiment for a remote file system.

\paragraph{Methodology}
We use the same method described in previous section. The only difference is that we now read a remote file.

\paragraph{Predictions}
Based on previous result, plus RTT time, we predict hardware overhead equals  20000 cycles  plus 450000 RTT cycles, 470000 cycles totally. As for software overhead, we predict about 450000 cycles due to local file reading.

As before, we think sequential access time is close to random access time.

\paragraph{Results}

We present our measure results. The base file is 4KB, and we define log(4KB) = 2.

\begin{figure}[htbp] %  figure placement: here, top, bottom, or page
   \centering
   \includegraphics[width=4in]{./pics/43.jpg}
   \caption{remote read cycles per block}
   \label{fig:remote read cycles per block}
\end{figure}

\begin{center}
\begin{tabular}{| p{2cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{3cm} }
File Size  & Base Hardware Performance  & Estimated Software Overhead  & Predicted Time  & Measured Time  & Std \\
\hline
8KB & 450000 cycles& 450000 cycles& 900000 cycles& 1060023 cycles & 12040 cycles \\
16KB & 450000 cycles& 450000 cycles& 900000 cycles& 1037613 cycles & 11025 cycles\\
32KB & 450000 cycles& 450000 cycles& 900000 cycles& 1155908 cycles & 20301 cycles\\
64KB & 450000 cycles& 450000 cycles& 900000 cycles& 1127454 cycles & 18750 cycles\\
128KB & 450000 cycles& 450000 cycles& 900000 cycles& 1134455 cycles & 23004 cycle \\
256KB & 450000 cycles& 450000 cycles& 900000 cycles& 1105819 cycles & 13334 cycle \\
512KB & 450000 cycles& 450000 cycles& 900000 cycles& 1085479 cycles & 17648 cycles\\
1024KB & 450000 cycles& 450000 cycles& 900000 cycles& 1089600 cycles & 20334 cycles\\
2048KB & 450000 cycles& 450000 cycles& 900000 cycles& 1074542 cycles & 17778 cycles \\

\end{tabular}
\end{center}

Above is the result of sequential access.

\begin{center}
\begin{tabular}{| p{2cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{3cm} }
File Size  & Base Hardware Performance  & Estimated Software Overhead  & Predicted Time  & Measured Time  & Std \\
\hline
8KB & 450000 cycles& 450000 cycles& 900000 cycles& 1043427 cycles & 9400 cycles\\
16KB & 450000 cycles& 450000 cycles& 900000 cycles& 1065662 cycles & 13298 cycles\\
32KB & 450000 cycles& 450000 cycles& 900000 cycles& 1058558 cycles & 12201 cycles\\
64KB & 450000 cycles& 450000 cycles& 900000 cycles& 1073499 cycles & 16652 cycles\\
128KB & 450000 cycles& 450000 cycles& 900000 cycles& 1073262 cycles & 8553 cycles\\
256KB & 450000 cycles& 450000 cycles& 900000 cycles& 1077349 cycles & 8890 cycles\\
512KB & 450000 cycles& 450000 cycles& 900000 cycles& 1074041 cycles & 13009 cycles\\
1024KB & 450000 cycles& 450000 cycles& 900000 cycles& 1074543 cycles & 10004 cycles\\
2048KB & 450000 cycles& 450000 cycles& 900000 cycles& 1044684 cycles & 9330 cycles\\

\end{tabular}
\end{center}

Above is the result of random access.

\paragraph{Discussion}
Due to previous experience, this time our estimation is very close to the measured results. Remote file access time is about twice higher than local file access. In my environment, RTT is close to reading a block data without file cache.

If one machine is in China, another one is in US,  network will be the most important overhead compared to other factors.

SSDs also make random access as fast as sequential access.

\paragraph{Question} What is the "network penalty" of accessing files over the network?  Remote file access time is about twice higher than local file access. In my environment, RTT is close to reading a block data without file cache. So RTT is the "network penalty". We have include TCP/IP penalty in RTT.

\section{Contention}
In this section, we report the average time to read one file system block of data as a function of the number of processes simultaneously performing the same operation on different files on the same disk (and not in the file buffer cache).

\paragraph{Methodology}
As previous experiment, we continue using F\_NOCACHE flag to disable file cache. In this experiment, we create several processes. Each process read different file which is of the same size : 1MB. And we iterate 100 times to get average data.

\paragraph{Predictions}
We are sure that the more process number, the more cycles it spend on reading file. We think each read will result in a context switch to another process. We present predictions with results in the following table. We use 1MB file, including 256 blocks. Based on previous experiment on sequential reading 1MB file, when there is only 1 process, the reading cycles are 281106. When increasing a process, we add about 15000 cycles for software and 1000 for hardware.

\paragraph{Results}
We present our measure results.

\begin{center}
\begin{tabular}{| p{2cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} | p{2.5cm} |  p{3cm}}
nprocesses   & Base Hardware Performance  & Estimated Software Overhead  & Predicted Time  & Measured Time  & Std \\
\hline
1 & 1000 cycles& 280000 cycles& 281000cycles & 229003 cycles & 8572 cycles \\
2 & 2000 cycles& 295000 cycles& 297000 cycles& 253880 cycles & 9400 cycles \\
3 & 3000 cycles& 310000 cycles& 313000 cycles& 209028 cycles & 9210 cycles \\
4 & 4000 cycles& 325000 cycles& 329000 cycles& 240578 cycles & 10450 cycles \\
5 & 5000 cycles& 340000 cycles& 345000 cycles& 432147 cycles & 8322 cycles \\
6 & 6000 cycles& 355000 cycles& 371000 cycles& 438801 cycles & 9726 cycles \\
7 & 7000 cycles& 370000 cycles& 377000 cycles& 459831 cycles & 8625 cycles \\
8 & 8000 cycles& 385000 cycles& 393000 cycles& 415745 cycles & 13392 cycles \\
9 & 9000 cycles& 400000 cycles& 409000 cycles& 474147 cycles & 12209 cycles \\
10 & 10000 cycles& 415000 cycles& 425000 cycles& 491004 cycles & 7490 cycles \\
11 & 11000 cycles& 430000 cycles& 441000 cycles& 515341 cycles & 15526 cycles \\
12 & 12000 cycles& 445000 cycles& 457000 cycles& 515871 cycles & 10024 cycles\\
13 & 13000 cycles& 460000 cycles& 473000 cycles& 536629 cycles & 20047 cycles \\
14 & 14000 cycles& 475000 cycles& 489000 cycles& 568728 cycles & 14478 cycles \\
15 & 15000 cycles& 490000 cycles& 505000 cycles& 590147 cycles & 25980 cycles \\

\end{tabular}
\end{center}

\begin{figure}[htbp] %  figure placement: here, top, bottom, or page
   \centering
   \includegraphics[width=4.5in]{./pics/44.jpg}
   \caption{average cycles per process}
   \label{fig:average cycles per process}
\end{figure}

\paragraph{Discussion}
We can see that generally, with the increasing of process, the average cycle increase too.

Our prediction is so close to the measured results. I am very surprised, I had thought that the measured results may exceed millions of cycles due to context switch between processes.

When I set the file cache flag, the cycles reduce to about 6000-8000 per block.

If we use HDD, each read will take many seek time. Now we use SSD, the cost is very small. That's the big difference between SSD and HDD.


\section{Method}

\subsection{ECG-DualNet}
\begin{frame}{Method}
\framesubtitle{ECG-DualNet(++)}
    \begin{figure}[!ht]
        \centering
        \input{artwork/ecg_dual_net}
        \caption{ECG-DualNet++ architecture with signal and spectrogram encoder}
        \label{fig:ecg_dual_net}
    \end{figure}
    \begin{textblock*}{3cm}(11.8cm, 3cm)
        \raggedright
        \cite{Vaswani2017}
        \cite{Wang2020}
        \cite{Dosovitskiy2020}
        \cite{De2017}
    \end{textblock*}
\end{frame}

\subsection{Augmentation Pipeline}
\begin{frame}{Method}
\framesubtitle{Augmentation Pipeline}
    \vspace{-0.251cm}
    \begin{figure}[!ht]
        \setlength{\figH}{4.5cm}
        \setlength{\figW}{0.33\textwidth}
        \centering
        \input{artwork/scale}\input{artwork/shift}\input{artwork/band_pass_filter}
        \caption{Different augmentations applied to ECG signal of the 2017 PhysioNet/CinC Challenge dataset \cite{Clifford2017}.}
        \label{fig:ecg_aug_1}
    \end{figure}
\end{frame}

\begin{frame}{Method}
\framesubtitle{Augmentation Pipeline}
    \vspace{-0.24cm}
    \begin{figure}[!ht]
        \setlength{\figH}{4.5cm}
        \setlength{\figW}{0.33\textwidth}
        \centering
        \input{artwork/drop}\input{artwork/cutout}\input{artwork/sine}
        \caption{Different augmentations applied to ECG signal of the 2017 PhysioNet/CinC Challenge dataset \cite{Clifford2017}.}
        \label{fig:ecg_aug_2}
    \end{figure}
\end{frame}

\begin{frame}{Method}
\framesubtitle{Augmentation Pipeline}
    \vspace{-0.25cm}
    \begin{figure}[!ht]
        \setlength{\figH}{4.5cm}
        \setlength{\figW}{0.33\textwidth}
        \centering
        \input{artwork/resample}\input{artwork/random_resample}
        \caption{Different augmentations applied to ECG signal of the 2017 PhysioNet/CinC Challenge dataset \cite{Clifford2017}. Random reasmple aug. inspired by 2D random elastic aug. \cite{Simard2003}.}
        \label{fig:ecg_aug_3}
    \end{figure}
\end{frame}

\subsection{Training \& Validation}
\begin{frame}{Method}
\framesubtitle{Training \& Validation}
    \begin{block}{Training loss (weighted cross entropy loss)}
        $$\mathcal{L} = -\frac{1}{N}\sum_{j=1}^{N}\sum_{i=1}^{4}\alpha_{i}\,y_{ji}\,\log(\hat{y}_{ji})$$
    \end{block}
    \pause
    \begin{block}{Validation metrics (accuracy \& F1)}
        $$\operatorname{ACC}=\frac{1}{n}\sum_{j=1}^{n}\delta\left(\arg\max(\mathbf{y}_{j}), \arg\max(\hat{\mathbf{y}}_{j})\right),\quad \operatorname{F1}=\frac{1}{4}\sum_{i=1}^{4}\frac{2\text{TP}_{i}}{2\text{TP}_{i} + \text{FP}_{i} + \text{FN}_{i}}$$
    \end{block}
\end{frame}


\subsection{Generalization to Arrows}

\begin{frame}[fragile]{The ArrowParallel typeclass}
Now, let's generalize:
\begin{lstlisting}[frame=htrbl]
parEvalN :: [a -> b] -> [a] -> [b]
\end{lstlisting}
\pause
\begin{lstlisting}[frame=htrbl]
parEvalN :: (Arrow arr) => [arr a b] -> arr [a] [b]
\end{lstlisting}
\pause
\begin{lstlisting}[frame=htrbl]
class Arrow arr => ArrowParallel arr a b where
	parEvalN :: [arr a b] -> arr [a] [b]
\end{lstlisting}
\pause
\begin{lstlisting}[frame=htrbl]
class Arrow arr => ArrowParallel arr a b conf where
	parEvalN :: conf -> [arr a b] -> arr [a] [b]
\end{lstlisting}

\end{frame}


\documentclass{documentation}

\title{TensorSpace Package}

\author{Joshua Maglione}
\address{Universit\"at Bielefeld}
\email{jmaglione@math.uni-bielefeld.de}

\author{James B. Wilson}
\address{Colorado State University}
\email{james.wilson@colostate.edu}

\version{2.3}
\date{\today}
\copyrightyear{2016--2020}

\input{preamble.tex}

%-----------------------------------------------------------------------------
\begin{document}

\frontmatter

\dominitoc
\maketitle
\tableofcontents

\mainmatter

\chapter{Introduction}

This documentation describes Magma operations with multilinear algebra. Our
notation follows \cite{FMW:densors} closely and can be viewed as companion
literature. Wherever possible we follow the conventions in use in physics
\cite{Weyl}*{Chapter V}, differential geometry \cite{Lee:geom}*{Chapter 10}, and
algebra \cite{Landsberg:tensors}. Necessary categorical formalism is drawn
largely from \cite{Wilson:division}. The package covers:
\begin{enumerate}
\item Tensors and multilinear functions and their associated groups and algebras.
\item Spaces of tensors.
\item Categories of tensors and tensor spaces.
\item Exceptional tensors of octonions and Jordan algebras.
\end{enumerate}
We follow the types described in \cite{FMW:densors}*{Section~7} to the degree
feasible within the Magma type-system.
\bigskip

\subsection*{Citing TensorSpace}
To cite the TensorSpace package, please use the following\\
\\
Joshua Maglione and James B. Wilson, \emph{TensorSpace}, version 2.3, GitHub,
2020. Contributions from Peter A. Brooksbank,
\url{https://github.com/thetensor-space/TensorSpace}. \\
\\
For AMSRefs:
\begin{verbatim}
\bib{TensorSpace}{misc}{
   author={Maglione, Joshua},
   author={Wilson, James B.},
   title={TensorSpace},
   publisher={GitHub},
   year={2020},
   edition={version 2.3},
   note={Contributions from Peter A. Brooksbank,
    \texttt{https://github.com/thetensor-space/TensorSpace}},
}
\end{verbatim}

\section{Overview}
We set up some notation used throughout. Define $K$ to be a commutative ring
(typically a field), $\vav$ to be a nonnegative integer (in some literature this
is denoted by the Hebrew letter $\vavv$), and a sequence of right $K$-modules
$U_0,\dots,U_{\vav}$. Set $\zrange{\vav}=\{0,\dots,\vav\}$, resp.
$\range{\vav}=\{1,\ldots,\vav\}$. For a set $R$ and $A\subset R$, $\comp{A}=R-A$,
assuming $R$ is fixed in the context.

Abbreviate
\begin{align*}
   U_0\oslash U_1 & = \hom_K(U_1,U_0)
   &
   U_0\oslash\cdots \oslash U_{\vav} & = (U_0\oslash\cdots\oslash U_{\vav-1})\oslash U_{\vav}.
\end{align*}
Also write $\rversor_{a\in[\vav]} U_a=U_0\oslash\cdots\oslash
U_{\vav}$.  So $U_0\oslash U_1$ denotes the space of \emph{linear maps} $U_1\to U_0$,
which we evaluate with the the notation $\la t|u_1\ra$ fpr $u_1\in U_1$.
Likewise, $U_0\oslash U_1\oslash U_2$ denotes the space of \emph{bilinear maps}
$\bar{t}:U_2\to (U_1\to U_0)$ evaluated  on inputs $u_2\in U_2$ as
\[
   \la t|u_2\ra \in U_0\oslash U_1.
\]
Often the intent is to then evaluate that result on some $u_1\in U_1$ for which we may
write
\[
   \la t|u_2,u_1\ra := \la t| u_2\ra |u_1\ra.
\]
So we may treat $\bra{t}$ as function $U_2\times U_1\bmto U_0$ --- the symbol $\bmto$
replaces $\to$ to distinguish \emph{bi-}linear from simply linear.  More generally,
$\bra{t}\in U_0\oslash\cdots\oslash U_{\vav}$ is a $\vav$-multilinear map
(of valence $\vav+1$) and can be evaluated  on $u:(a\in \range{\vav})\to (u_a\in U_a)$
as
\[
   \la t|u_{\vav},\ldots,u_1\ra = \la t|u_{\vav}\ra\cdots |u_1\ra.
\]
We also write $\bra{t}:U_{\vav}\times\cdots\times U_1\bmto U_0$, where $\bmto$ denotes
\emph{multilinear maps}.

A \emph{tensor space} $T$ is a $K$-module equipped with a monomorphism
\[
   \bra{\cdot} : T \hookrightarrow U_0\oslash \cdots\oslash U_{\vav}.
\]
\emph{Tensors}
are elements of $T$, $(U_{\vav},\dots,U_0)$ is the \emph{frame}, and $\vav+1$ is
the valence. In Dirac styled $\bra{t}$ ``bra t'' and $\ket{u}$ ``ket u''
notation, we evaluate $\bra{t}\in U_0\oslash \cdots\oslash U_{\vav}$ on inputs
$\ket{u}=\ket{u_{\vav},\dots, u_1}\in U_{\vav}\times\cdots\times U_1$ denote
$\bra{t}u\rangle$ or $\bra{t} u_{\vav},\dots,u_1\rangle$.  When regarding $\bar{t}$
as a function on $U_{\vav}\times\cdots\times U_1$ into $U_0$ we use $\bmto$ for the
arrow emphasize $\bar{t}:U_{\vav}\times\cdots\times U_1\bmto U_0$ is \emph{multilinear}.

Every tensor in Magma is treated as an element
of a tensor space. By default a universal tensor space:
\begin{align*}
   \rversor_{a\in[\vav]} U_a = U_0\oslash \cdots\oslash U_{\vav}
   = \hom_K(U_{\vav},\dots,\hom_K(U_1,U_0)\cdots).
\end{align*}
In Magma, the tensor space is what determines the associated
multilinear function of a given tensor $T$.
Evaluation of $T$ mimics a map
$U_{\vav}\times \cdots \times U_1\to U_0$, for instance
\begin{code}
> <u_v, ..., u_1> @ T;
\end{code}
Special attention is given to bilinear maps
$*:U_2\times U_1\rightarrowtail U_0$
including the ability to use infix notation ${\tt u_2*u_1}$.
Tensor spaces have type {\tt TenSpc} and behave like modules
in that they have subspaces and quotient spaces.  Tensors have type
{\tt TenSpcElt} and behave similar to Magma matrices.

A library of commonly used exceptional tensors is provided.
These include octonion algebras and exceptional Jordan algebras.

Tensor categories, type {\tt TenCat}, tell Magma how to interpret the
contents of a tensor space.  For example, one tensor category treats a
$(d\times d)$-matrix $F$ over a field $K$ as a linear map $K^d\to K^d$,
another assigns the same matrix to a bilinear form
$K^d\times K^d\rightarrowtail K$.  Functors are provided to change
tensor categories and to define standard categories.

\section{Printing and Version}

We have included intrinsics to allow for verbose printing and printing to strings.
Currently, there is only one level of printing, so either verbose printing is on or off.

\index{SetVerbose}
\begin{intrinsics}
SetVerbose(MonStgElt, RngIntElt) : ->
\end{intrinsics}

{\tt SetVerbose} is a built in Magma function, but with this package, this
intrinsic accepts the string \texttt{"TensorSpace"} and an integer in $\{0,1\}$.

We have included an intrinsic to check which version of TensorSpace you have attached in Magma.

\begin{example}[VerbosePrinting]
We demonstrate the verbose printing available for TensorSpace.
Currently, we only have verbose printing when we solve linear systems.
To turn on all the printing statements, set \texttt{"TensorSpace"} to {\tt 1}.

\begin{code}
> SetVerbose("TensorSpace", 1);
>
> t := RandomTensor(GF(2), [32, 32, 32]);
> D := DerivationAlgebra(t);
Setting up linear system: 3072 by 32768
Solving up linear system: 3072 by 32768
\end{code}
\end{example}

\index{Sprint}
\begin{intrinsics}
Sprint(t) : TenSpcElt -> MonStgElt
Sprint(T) : TenSpc -> MonStgElt
Sprint(C) : TenCat -> MonStgElt
\end{intrinsics}

Returns strings that can be executed in Magma to construct the given object. If
$t$ is a black-box tensor where structure constants cannot be computed, then the
returned string is equivalent to \texttt{print t}, which cannot be executed to
construct $t$.

\begin{example}[PrintToString]

We first construct a tensor category, tensor space, and a tensor contained in the tensor space.
\begin{code}
> C := TensorCategory([1, 1, 0], {{0}, {1,2}});
> C;
Tensor category of valence 3 (->,->,==) ({ 0 },{ 1, 2 })
>
> T := KTensorSpace(GF(2), [10, 10, 2], C);
> T;
Tensor space of dimension 200 over GF(2) with valence 3
U2 : Full Vector space of degree 10 over GF(2)
U1 : Full Vector space of degree 10 over GF(2)
U0 : Full Vector space of degree 2 over GF(2)
>
> t := T![1..200];
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 10 over GF(2)
U1 : Full Vector space of degree 10 over GF(2)
U0 : Full Vector space of degree 2 over GF(2)
\end{code}

Now we will print to string each of the objects we created.
\begin{code}
> Sprint(C);
TensorCategory(\[ 1, 1, 0 ], { PowerSet(IntegerRing()) |
{ IntegerRing() | 0 },
{ IntegerRing() | 1, 2 }
})
>
> Sprint(T);
TensorSpace([*VectorSpace(GF(2), 10), VectorSpace(GF(2), 10),
VectorSpace(GF(2),2)*], TensorCategory(\[ 1, 1, 0 ], {
PowerSet(IntegerRing()) |
{ IntegerRing() | 0 },
{ IntegerRing() | 1, 2 }
}))
>
> Sprint(t);
Tensor(GF(2), \[ 10, 10, 2 ], [ GF(2) | 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0 ], TensorCategory(\[ 1, 1, 0 ], { PowerSet(IntegerRing()) |
{ IntegerRing() | 0 },
{ IntegerRing() | 1, 2 }
}))
\end{code}
\end{example}

\index{TensorSpaceVersion}
\begin{intrinsics}
TensorSpaceVersion() : -> MonStgElt
\end{intrinsics}

Returns the version number for the TensorSpace package attached in Magma.

\begin{example}[Version]
We verify that we have attached the current version of the TensorSpace package.
Even though \texttt{TensorSpaceVersion} has no arguments, \texttt{()} is still required.

\begin{code}
> TensorSpaceVersion();
2.3
\end{code}
\end{example}

\chapter{Tensors}\label{ch:tensors}

\input{tensors.tex}
\input{alg-invariants.tex}

\chapter{Tensor spaces}\label{ch:tensor-spaces}

\input{tensor-spc-cat.tex}

\chapter{Some examples}\label{ch:examples}

\input{longer-exs.tex}

\appendix

\chapter{Cyclic algebras and their modules}\label{append:cyclic}

\input{cyclic.tex}

\backmatter

\begin{bibdiv}
\begin{biblist}

\bib{Albert:Fundamentals}{article}{
   author={Albert, A. A.},
   title={Non-associative algebras. I. Fundamental concepts and isotopy},
   journal={Ann. of Math. (2)},
   volume={43},
   date={1942},
   pages={685--707},
   review={\MR{0007747}},
}

\bib{Magma}{article}{
   author={Bosma, Wieb},
   author={Cannon, John},
   author={Playoust, Catherine},
   title={The Magma algebra system. I. The user language},
   note={Computational algebra and number theory (London, 1993)},
   journal={J. Symbolic Comput.},
   volume={24},
   date={1997},
   number={3-4},
   pages={235--265},
   review={\MR{1484478}},
}

\bib{BMW:genus2}{article}{
   author={Brooksbank, Peter A.},
   author={Maglione, Joshua},
   author={Wilson, James B.},
   title={A fast isomorphism test for groups whose Lie algebra has genus 2},
   journal={J. Algebra},
   volume={473},
   date={2017},
   pages={545--590},
   review={\MR{3591162}},
}

\bib{BW:isometry}{article}{
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={Computing isometry groups of Hermitian maps},
   journal={Trans. Amer. Math. Soc.},
   volume={364},
   date={2012},
   number={4},
   pages={1975--1996},
   review={\MR{2869196}},
}

\bib{BW:grps-tensor}{article}{
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={Groups acting on tensor products},
   journal={J. Pure Appl. Algebra},
   volume={218},
   date={2014},
   number={3},
   pages={405--416},
   review={\MR{3124207}},
}

\bib{BW:Module-iso}{article}{
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={The module isomorphism problem reconsidered},
   journal={J. Algebra},
   volume={421},
   date={2015},
   pages={541--559},
   review={\MR{3272396}},
}

\bib{BW:StarAlge}{unpublished}{
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={StarAlge Package},
   status={\url{https://github.com/algeboy/StarAlge}},
}

\bib{FMW:densors}{article}{
   author={First, Uriya},
   author={Maglione, Joshua},
   author={Wilson, James B.},
   title={Polynomial identity tensors and their invariants},
   note={in preparation},
}

\bib{Landsberg:tensors}{book}{
   author={Landsberg, J. M.},
   title={Tensors: geometry and applications},
   series={Graduate Studies in Mathematics},
   volume={128},
   publisher={American Mathematical Society, Providence, RI},
   date={2012},
   pages={xx+439},
   review={\MR{2865915}},
}

\bib{Lee:geom}{book}{
   author={Lee, John M.},
   title={Introduction to smooth manifolds},
   series={Graduate Texts in Mathematics},
   volume={218},
   edition={2},
   publisher={Springer, New York},
   date={2013},
   pages={xvi+708},
   review={\MR{2954043}},
}

\bib{Payne:elation-grps}{article}{
   author={Payne, Stanley E.},
   title={Finite groups that admit Kantor families},
   conference={
      title={Finite geometries, groups, and computation},
   },
   book={
      publisher={Walter de Gruyter GmbH \& Co. KG, Berlin},
   },
   date={2006},
   pages={191--202},
   review={\MR{2258010}},
}

\bib{Malcev}{book}{
   author={Mal{\cprime}cev, A. I.},
   title={Foundations of linear algebra},
   series={Translated from the Russian by Thomas Craig Brown; edited by J.
   B. Roberts},
   publisher={W. H. Freeman \& Co., San Francisco, Calif.-London},
   date={1963},
   pages={xi+304},
   review={\MR{0166200}},
}

\bib{Schafer}{book}{
   author={Schafer, Richard D.},
   title={An introduction to nonassociative algebras},
   series={Pure and Applied Mathematics, Vol. 22},
   publisher={Academic Press, New York-London},
   date={1966},
   pages={x+166},
   review={\MR{0210757}},
}

\bib{Weyl}{book}{
	author={Weyl, Herman},
	title={The theory of groups and quantum mechanics},
	publisher={Dover, New York},
	year={1950},
}

\bib{Wilson:division}{article}{
   author={Wilson, James B.},
   title={Division, adjoints, and dualities of bilinear maps},
   journal={Comm. Algebra},
   volume={41},
   date={2013},
   number={11},
   pages={3989--4008},
   review={\MR{3169502}},
}

\bib{Wilson:LMR}{article}{
   author={Wilson, James B.},
   title={On automorphisms of groups, rings, and algebras},
   journal={Comm. Algebra},
   volume={45},
   date={2017},
   number={4},
   pages={1452--1478},
   review={\MR{3576669}},
}

\end{biblist}
\end{bibdiv}

\printindex

\end{document}


\documentclass{beamer}

\usetheme{JuanLesPins}
%\usetheme{Darmstadt}

\usepackage{beamerthemesplit}
\usepackage{pxfonts}
\usepackage{proof}
\usepackage{graphicx}

\input{../../papers/implicit/macros}

\newenvironment{code}{
\begin{block}{}\(\begin{array}{l}
}{
\end{array}\)\end{block}
}

\setlength\parskip{2mm}

\renewcommand\Bar{~~|~~}

\newcommand\CheckType[4]{{#1} \vdash {#2} \uparrow {#3} \leadsto {#4}}
\newcommand\InferType[4]{{#1} \vdash {#2} \downarrow {#3} \leadsto {#4}}
\newcommand\FreshMeta[3]{\mathsf{FreshMeta({#2} \vdash {#1} : {#3})}}
\newcommand\Instantiate[2]{\mathsf{Instantiate}({#1} := {#2})}
\newcommand\Encapsulate[2]{\mathsf{Box}({#1} \Bar {#2})}
\newcommand\MV[1]{\mathsf{MV}({#1})}

\newcommand\False{\mathit{false}}
\newcommand\True{\mathit{true}}
\newcommand\Zero{\mathit{zero}}
\newcommand\Suc{\mathit{suc}}
\newcommand\Set{\mathit{Set}}
\newcommand\Nat{\mathit{Nat}}
\newcommand\Bool{\mathit{Bool}}
\newcommand\Not{\mathit{not}}

\begin{document}

\title{A type-safe treatment of meta variables}
\author{Ulf Norell}
\institute{(joint work with Catarina Coquand)}
\date{\today}

\frame{\titlepage}

\section{Introduction}

\frame{
    \frametitle{Abstract}

    Type checking with meta variables is trickier than we have previously
    believed.

    In particular it is easy to violate the invariant that we only compute with
    well-typed terms, thus losing normalisation.

    We show how to maintain well-typedness by encapsulating possibly ill-typed
    terms in boxes that can only be opened if the contents is known to be well-typed.

    \vspace*{-8mm}
    \begin{flushright}
    \includegraphics[width=35mm]{danger_do_not_open_until.pdf}
    \end{flushright}
}

\frame{
    \frametitle{The Logical Framework}

\[\begin{array}{lclr}
    A	   & ::= & \SET \Or \EL M \Or \PI xAA		& \mathit{types} \\
    M	   & ::= & x \Or c \Or f \Or M\,M \Or \LAM xM	& \mathit{terms} \\
    \Gamma & ::= & () \Or \Gamma,x:A			& \mathit{contexts} \\
\end{array}\]

\[\begin{array}{ll}
    \IsTypeC\Gamma A & \mbox{$A$ is a valid type in $\Gamma$} \\
    \HasTypeC\Gamma MA & \mbox{$M$ has type $A$ in $\Gamma$} \\
    \EqualTypeC\Gamma AB & \mbox{$A$ and $B$ are convertible types in $\Gamma$}\\
    \EqualC\Gamma MNA & \mbox{$M$ and $N$ are convertible terms of type $A$ in $\Gamma$} \\
\end{array}\]

\[
    \infer[\mbox{the conversion rule}]{\HasTypeC\Gamma MB}{
      \HasTypeC\Gamma MA
    & \EqualTypeC\Gamma AB
    }
\]

}

\frame{
    \frametitle{Checking conversion}

    One option (which scales to meta variables) is to interleave weak-head
    normalisation and comparison of heads.

\[\begin{array}{c}
    \infer{\EqualC \Gamma {x~\vec M} {x~\vec N} A}{
	x : \Delta \to B \in \Gamma
    &	\EqualC \Gamma {\vec M} {\vec N} \Delta
    }
    \\{}\\
    \infer{\EqualC \Gamma {M,\vec M} {N,\vec N} {(x : A)\Delta}}{
	\EqualC \Gamma M N A
    &	\EqualC \Gamma {\vec M} {\vec N} {\Subst \Delta x M}
    }
\end{array}\]
    {\small (Weak-head normalisation is left implicit.)}
}

\frame{
    \frametitle{Meta variables}

    Meta variables can be used for several things. For instance, to represent
    \begin{itemize}
	\item incomplete parts of a program (instantiated by the user)
	\item implicit parts of a program (instantiated by the type checker)
    \end{itemize}

    In this work we are mostly concerned with the latter use.
}

\frame{
    \frametitle{Typing rules for meta variables}
We change the type checker to produce new terms:
\[\begin{array}{lcl}
    \CheckType \Gamma e A M && \mbox{type checking} \\
    \InferType \Gamma e A M && \mbox{type inference}
\end{array}\]

and add a rule for meta variables (written $?$ in the input language)
\[\infer{\CheckType \Gamma ? A \alpha}{
    \FreshMeta \alpha \Gamma A
}\]
}

\section{The Problem}

\frame{
    \frametitle{Convertibility with meta variables}
    In the presence of meta variables, checking convertibility becomes unification:
\[
    \infer{\EqualC \Gamma \alpha M A}{
	\alpha \notin \MV M
    &	\Instantiate \alpha M
    }
\]
    Functions defined by pattern matching are troublesome.
\[
    \EqualC \Gamma {\mathit{isZero}~\alpha} {\mathit{false}} {\mathit{Bool}}
\]
    In this case unification gives up, and the constraint is postponed until
    more information is available about $\alpha$.
}

\frame{
    \frametitle{The conversion rule}
A possible conversion rule (used by previous implementations of Agda):
\[
    \infer{\CheckType \Gamma e A M}{
	\InferType \Gamma e B M
    &	\EqualTypeC \Gamma A B
    }
\]
This rule makes no distinction between successful unification and postponed constraints.
}

\frame{
    \frametitle{What could possibly go wrong?}
    Consider the example
\[
    \infer{\CheckType \Gamma \Zero {F~\alpha} \Zero}{
	\InferType \Gamma \Zero \Nat \Zero
    &	\EqualTypeC \Gamma {F~\alpha} \Nat
    }
\]
    where
\[\begin{array}{lcl}
    \multicolumn3l{F : \Bool \to \Set} \\
    F~\False & = & \Nat \\
    F~\True  & = & \Bool \\
\end{array}\]
    The type checker will accept $\Zero : F~\alpha$ which doesn't seem that
    harmful. The problem is that the same rule will accept something of type
    $F~\alpha$ whenever a $\Bool$ is required and we can end up with $\Zero :
    \Bool$.
}

\frame{
    \frametitle{A concrete example}

\[\begin{array}{l}
F : \Bool \to \Set \\
F~\False = \Nat \\
F~\True  = \Bool \\
{}\\
h : ((x : F~\alpha) \to F~(\Not~x)) \to \Nat \\
h~g = g~\Zero
\end{array}\]

We get the constraints
\[\begin{array}{lclcl}
    \Bool & = & F~\alpha && \mbox{from $x \uparrow \Bool$} \\
    F~\alpha & = & \Nat && \mbox{from $\Zero \uparrow {F~\alpha}$} \\
    F~(\Not~\Zero) & = & \Nat && \mbox{from ${g~\Zero} \uparrow \Nat$} \\
\end{array}\]

When checking the last constraint the type checker fails with an ``incomplete
pattern matching'' error.

}

\section{The Solution}

\frame{
    \frametitle{The Solution}

    Our solution is to encapsulate potentially ill-typed terms inside boxes
    which can only be opened if the corresponding constraint has been solved.
\[
    \infer{\CheckType \Gamma e A c}{
	\InferType \Gamma e B M
    &	\Encapsulate {c : A = M} {\EqualTypeC \Gamma A B}
    }
\]
    As long as $A = B$ remains unsolved $c$ will not reduce, but as soon as we
    solve the constraint it reduces to $M$.
}

\frame{
    \frametitle{Type safety}

    With this approach we can guarantee type-safety.
    \[\CheckType \Gamma e A M \Longrightarrow \HasTypeC \Gamma M A
    \]
    This holds independent of any postponed constraints.
}

\frame{
    \frametitle{Live Demo}
    \begin{center}{\Huge Live Demo}
    \end{center}
}

\frame{
    \frametitle{Bonus Slide}

    Remember this rule?
\[
    \infer{\EqualC \Gamma {M,\vec M} {N,\vec N} {(x : A)\Delta}}{
	\EqualC \Gamma M N A
    &	\EqualC \Gamma {\vec M} {\vec N} {\Subst \Delta x M}
    }
\]
    If $M = N$ is postponed we can't guarantee $\vec N : \Subst \Delta x M$.

    Options
    \begin{itemize}
	\item postpone the whole constraint if $M = N$ is postponed
	\item allow boxing of constraints
    \end{itemize}
\[
    \infer{\EqualTypeC \Gamma {M,\vec M : (x : A_1)\Delta_1} {N,\vec N : (x : A_2)\Delta_2}}{
    \begin{array}{l}
	\Encapsulate {\EqualC \Gamma M N A_1} {\EqualTypeC \Gamma {A_1} {A_2}} \\
	\EqualTypeC \Gamma {\vec M : \Subst {\Delta_1} x M} {\vec N : \Subst {\Delta_2} x N}
    \end{array}
    }
\]
}

\end{document}


\subsubsection{\tt Kronecker Product}
\label{benchmarkkroneckerproduct}

FIXME

{\tt ipbb} is a synthetic AKS benchmark that performs
a Boolean-Boolean ({\apl M\qor\qdot\qand\qtran\0M}) matrix product on
arrays of shape {\tt [400, 400]}.


\subsection{Combining instance graphs}
\label{subsec:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs}

The structure of \cref{fig:transformation_framework:instance_models_and_instance_graphs:structure_instance_models_graphs} shows that the instance graphs $IG_A$ and $IG_B$ are combined into one instance graph $IG_{AB}$. This section provides the definition of this combination and its corresponding theorems. Please note that the definitions presented here, just like the previous section, are as generic as possible, and do not actively take into account that $IG_{A}$ and $IG_{B}$ are mostly distinct. This bit of information is added later as part of a theorem and proof.

\begin{defin}[Combination function on instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine}
$\mathrm{combine}$ is a binary function on two instance graphs which combines two instance graphs into one instance graph. Assume $IG_A$ is an instance graph typed by type graph $TG_A$ and $IG_B$ is an instance graph typed by type graph $TG_B$, then $\mathrm{combine}(IG_A, IG_B)$ is typed by $\mathrm{combine}(TG_A, TG_B)$ and is defined as follows:
\begin{align*}
\mathrm{combine}(IG_A, IG_B) = \langle&
N = N_{IG_A} \cup N_{IG_B} \\&
E = E_{IG_A} \cup E_{IG_B} \\&
\mathrm{ident} = \mathrm{ident\_\!combine}(IG_A, IG_B) \rangle
\end{align*}

In which $\mathrm{ident\_\!combine}$ is given as part of \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ident_combine}.
\isabellelref{ig_combine}{GROOVE.Instance_Graph_Combination}
\end{defin}

The definition of the combination of instance graphs is the easiest combination function to understand. Essentially, it does nothing more than combining the nodes and edges of the graph. The only thing that is done extra is the combination of the identification function, of which the definition is presented within the next definition.

\begin{defin}[Combination function for identities of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ident_combine}
$\mathrm{ident\_\!combine}(IG_A, IG_B)$ is a partial function on two type graphs which returns a new function \\$Id \Rightarrow (N_{IG_{AB}} \cap Node_t)$. It is defined as follows:
\begin{multline*}
    \mathrm{ident\_\!combine}(IG_{A}, IG_{B}, i) = \\
    \begin{cases}
        \mathrm{ident}_{IG_A}(i) & \mathrm{if }\ i \in \mathrm{dom}\ \mathrm{ident}_{IG_A} \cap \mathrm{dom}\ \mathrm{ident}_{IG_B} \land \mathrm{ident}_{IG_A}(i) = \mathrm{ident}_{IG_B}(i) \\
        \mathrm{ident}_{IG_A}(i) & \mathrm{if }\ i \in \mathrm{dom}\ \mathrm{ident}_{IG_A} \setminus \mathrm{dom}\ \mathrm{ident}_{IG_B} \\
        \mathrm{ident}_{IG_B}(i) & \mathrm{if }\ i \in \mathrm{dom}\ \mathrm{ident}_{IG_B} \setminus \mathrm{dom}\ \mathrm{ident}_{IG_A}
    \end{cases}
\end{multline*}
\isabellelref{ig_combine_ident}{GROOVE.Instance_Graph_Combination}
\end{defin}

The combination function for identifiers of the instance graphs is not very difficult either. If an identifier is only valid in one of the instance graphs, the identifier value is copied from that graph. Furthermore, if an identifier is valid in both instance graphs, it should be the case that the identifiers project on the same node. If this is the case, then the identifier is set for the combination.

Like the combination function of object identifiers of instance models (\cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:objectid_combine}), the behaviour of this function might seem strange. Theoretically, it might give rise to nodes with two identities, which is undesired. As will be shown later, the combination function and theorems assume that the identities of the graphs are already distinct. This assumption is fair, as it is possible to redefine two instance graphs to have distinct identities, without loss of significance.

\begin{figure}
    \centering
    \begin{subfigure}{0.3\textwidth}
        \centering
        \input{images/04_transformation_framework/instance_graphs_combination/contact_instance_partial1.tikz}
        \caption{Contacts model $IG_{Contact}$}
        \label{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example_ig1}
    \end{subfigure}
    \begin{subfigure}{0.3\textwidth}
        \centering
        \input{images/04_transformation_framework/instance_graphs_combination/contact_instance_partial2.tikz}
        \caption{Address extension $IG_{Ext}$}
        \label{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example_ig2}
    \end{subfigure}
    \begin{subfigure}{0.35\textwidth}
        \centering
        \input{images/04_transformation_framework/instance_graphs_combination/contact_instance_combined.tikz}
        \caption{Combined model $IG_{ContactExt}$}
        \label{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example_ig12}
    \end{subfigure}
    \caption{Example of the combination of instance graphs}
    \label{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example}
\end{figure}

With all definitions in place, it is possible to provide an example. Let us return to the contacts list example introduced in \cref{fig:transformation_framework:type_models_and_type_graphs:combining_type_graphs:combine_example} of \cref{subsec:transformation_framework:type_models_and_type_graphs:combining_type_graphs}. Suppose a simple instance of $TG_{Contact}$, which has one instance with a name and e-mail address. This could be formally defined as follows:

\begin{align*}
IG_{Contact} =\ &\langle&
N =\ &\{ Contact_1, \text{``Netwerkprofessort''}, \text{``networks@example.com''} \} \\&&
\mathrm{type_{n}} =\ &\{
( Contact_1, \type{Contact} ),
( \text{``networks@example.com''}, \type{string} ),\\&&&
( \text{``Netwerkprofessort''}, \type{string} )
\} \\&&
E =\ &\big\{
\big( Contact_1, ( \type{Contact}, \type{email}, \type{string} ), \text{``networks@example.com''} \big),\\&&&
\big( Contact_1, ( \type{Contact}, \type{firstName}, \type{string} ), \text{``Netwerkprofessort''} \big)
\big\} \\&&
\mathrm{ident} =\ &\{
( Example, Contact_1 )
\}
\\&\rangle
\end{align*}

A visual representation of this model is included in \cref{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example_ig1}. Now suppose that we want to extent this contact with an address. An instance of $Tm_{Ext}$ represents this address, and is defined as follows:

\begin{align*}
IG_{Ext} =\ &\langle&
N =\ &\{ Contact_1, Address_1, \text{``November Str. 15''}, \text{``NL''} \} \\&&
\mathrm{type_{n}} =\ &\{
( Contact_1, \type{Contact} ),
( Address_1, \type{Address} ),\\&&&
( \text{``November Str. 15''}, \type{string} ),
( \text{``NL''} , \type{string} )
\} \\&&
E =\ &\big\{
\big( Contact_1, ( \type{Contact}, \type{fav}, \type{Contact} ), Contact_1 \big),\\&&&
\big( Contact_1, ( \type{Contact}, \type{addresses}, \type{Address} ), Address_1 \big),\\&&&
\big( Address_1, ( \type{Address}, \type{addressLine}, \type{string} ), \text{``November Str. 15''} \big),\\&&&
\big( Address_1, ( \type{Address}, \type{country}, \type{string} ), \text{``NL''} \big)
\big\} \\&&
\mathrm{ident} =\ &\{
( Example, Contact_1 )
\}
\\&\rangle
\end{align*}

The visual representation of $IG_{Ext}$ is included in \cref{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example_ig2}. With these instance models formally defined, it is possible to combine them using \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine}. This will yield the following model:

\begin{align*}
IG_{ChatExt} =\ &\langle&
N =\ &\{ Contact_1, Address_1, \text{``November Str. 15''}, \text{``NL''} \} \\&&
\mathrm{type_{n}} =\ &\{
( Contact_1, \type{Contact} ),
( Address_1, \type{Address} ),\\&&&
( \text{``networks@example.com''}, \type{string} ),
( \text{``Netwerkprofessort''}, \type{string} ),\\&&&
( \text{``November Str. 15''}, \type{string} ),
( \text{``NL''} , \type{string} )
\} \\&&
E =\ &\big\{
\big( Contact_1, ( \type{Contact}, \type{email}, \type{string} ), \text{``networks@example.com''} \big),\\&&&
\big( Contact_1, ( \type{Contact}, \type{firstName}, \type{string} ), \text{``Netwerkprofessort''} \big),\\&&&
\big( Contact_1, ( \type{Contact}, \type{fav}, \type{Contact} ), Contact_1 \big),\\&&&
\big( Contact_1, ( \type{Contact}, \type{addresses}, \type{Address} ), Address_1 \big),\\&&&
\big( Address_1, ( \type{Address}, \type{addressLine}, \type{string} ), \text{``November Str. 15''} \big),\\&&&
\big( Address_1, ( \type{Address}, \type{country}, \type{string} ), \text{``NL''} \big)
\big\} \\&&
\mathrm{ident} =\ &\{
( Example, Contact_1 )
\}
\\&\rangle
\end{align*}

A visual representation of this combined model is included as \cref{fig:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine_example_ig12}. Like the example for the combination of type graphs, this example shows that the definition of the combination of instance graphs is useful. It allows to build larger graphs out of smaller building blocks. Furthermore, the example shows that the combination of the two instance graphs is typed by the combination of its corresponding type graphs.

Although the definitions of the combination of instance graphs are given, no mathematical properties or theorems are defined yet. Some mathematical properties hold for the combination of instance graphs, that will be presented in the following theorems.

\begin{thm}[Commutativity of the combination of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_commute}
Assume that $IG_A$ and $IG_B$ are instance graphs, then the $\mathrm{combine}$ function is commutative:
\begin{equation*}
    \mathrm{combine}(IG_A, IG_B) = \mathrm{combine}(IG_B, IG_A)
\end{equation*}
\isabellelref{ig_combine_commute}{GROOVE.Instance_Graph_Combination}
\end{thm}

\begin{thm}[Associativity of the combination of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_assoc}
Assume that $IG_A$, $IG_B$ and $IG_C$ are instance graphs, then the $\mathrm{combine}$ function is associative:
\begin{equation*}
    \mathrm{combine}(\mathrm{combine}(IG_A, IG_B), IG_C) = \mathrm{combine}(IG_A, \mathrm{combine}(IG_B, IG_C))
\end{equation*}
\isabellelref{ig_combine_assoc}{GROOVE.Instance_Graph_Combination}
\end{thm}

\begin{thm}[Idempotence of the combination of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_idemp}
Assume that $IG_A$ is an instance graph and that it is valid in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}. Then the following property holds:
\begin{equation*}
    \mathrm{combine}(IG_A, IG_A) = IG_A
\end{equation*}
\isabellelref{ig_combine_idemp_alt}{GROOVE.Instance_Graph_Combination}
\end{thm}

These properties follow directly from \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:combine}, but the corresponding proofs will not be included here. It should be noted that these properties are indeed proven correct as part of this thesis, and the corresponding proofs are validated within Isabelle.

Besides these properties, the combination of instance graphs also has an identity element. The empty instance graph represents this identity element, but it needs to be defined first:

\begin{defin}[Empty instance graph]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:empty_instance_graph}
Let $IG_{\epsilon}$ be the empty instance graph. It is typed by the empty type graph $TG_{\epsilon}$. $IG_{\epsilon}$ is defined as:
\begin{align*}
IG_{\epsilon} = \langle&
N = \{\} \\&
E = \{\} \\&
\mathrm{ident} = undefined\rangle
\end{align*}
\end{defin}

\begin{thm}[Correctness of the empty type model]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_empty_correct}
The empty instance graph, $IG_{\epsilon}$, is valid with respect to
\cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}.
\isabellelref{ig_empty_correct}{GROOVE.Instance_Graph}
\end{thm}

The proof for the correctness of the empty instance graph is trivial. Still, a validated version of this proof can be found within the Isabelle theories of this thesis.

As mentioned earlier, the empty instance graph acts as an identity element when combining two instance graphs. The following theorem specifies this behaviour.

\begin{thm}[Identity of the combination of instance models]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_identity}
Assume that $IG_A$ is an instance graph and that it is valid in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}. Then $IG_{\epsilon}$ acts as an identity element in the combination function:
\begin{equation*}
    \mathrm{combine}(IG_{\epsilon}, IG_A) = IG_A
\end{equation*}
\isabellelref{ig_combine_identity_alt}{GROOVE.Instance_Graph_Combination}
\end{thm}

Once more, the proof of this theorem follows directly from the definition. Therefore, the corresponding proof will not be included here, but a validated version can be found within the Isabelle theories of this thesis.

A final desired property for the combination of instance models is a correctness property. \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:imod_combine_correct} defines the theorem under which the combination of instance models is a valid instance model. Please note that this theorem is a generic theorem, which does not take into account that the instance models are mostly distinct.

\begin{thm}[Validity of the combination of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_correct}
Assume that $IG_A$ and $IG_B$ are valid instance graphs in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}. Assume that $IG_A$ is typed by type model $TG_A$. Furthermore, assume that $IG_B$ is typed by type model $TG_B$. $TG_A$ and $TG_B$ are valid by definition. Also assume that $TG_{AB} = \mathrm{combine}(TG_A, TG_B)$ is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}. Finally, assume the following properties:
\begin{itemize}
    \item For all shared identities, the nodes belonging to the identities must be equal in both instance graphs: $\forall i \in \mathrm{dom}\ \mathrm{ident}_{IG_A} \cap \mathrm{dom}\ \mathrm{ident}_{IG_B}\!: \mathrm{ident}_{IG_A}(i) = \mathrm{ident}_{IG_B}(i)$.
    \item The outgoing multiplicity for edges must be valid: $\forall et \in ET_{TG_A} \cup ET_{TG_B} \land n \in N_{IG_A} \cup N_{IG_B}\!: (\mathrm{type_n}(n), \mathrm{src}(et)) \in\ \sqsubseteq_{TG_{AB}} \implies$\\$|\{e \mid e \in E_{IG_A} \cup E_{IG_B} \land \mathrm{src}(e) = n \land \mathrm{type_e}(e) = et \}| \in \mathrm{out}(\mathrm{mult}_{TG_{AB}}(et))$.
    \item The incoming multiplicity for edges must be valid: $\forall et \in ET_{TG_A} \cup ET_{TG_B} \land n \in N_{IG_A} \cup N_{IG_B}\!: (\mathrm{type_n}(n), \mathrm{tgt}(et)) \in\ \sqsubseteq_{TG_{AB}} \implies$\\$|\{e \mid e \in E_{IG_A} \cup E_{IG_B} \land \mathrm{tgt}(e) = n \land \mathrm{type_e}(e) = et \}| \in \mathrm{in}(\mathrm{mult}_{TG_{AB}}(et))$.
    \item Each node may only be contained by one other node: $\forall n \in N_{IG_A} \cup N_{IG_B}\!: |\{e \mid e \in E_{IG_A} \cup E_{IG_B} \land \mathrm{tgt}(e) = n \land \mathrm{type_e}(e) \in contains_{TG_{AB}} \}| \leq 1$.
    \item There may be no cycle in the containment edges of the combined instance graph: $\{( \mathrm{src}(e), \mathrm{tgt}(e) ) \mid e \in E_{IG_A} \cup E_{IG_B} \land \mathrm{type_e}(e) \in contains_{TG_{AB}} \}$ is acyclic.
\end{itemize}

Then $\mathrm{combine}(IG_A, IG_B)$ is a valid instance graph in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}.
\isabellelref{ig_combine_correct}{GROOVE.Instance_Graph_Combination}
\end{thm}

\begin{proof}
To proof that $\mathrm{combine}(IG_A, IG_B)$ is a valid instance graph, it needs to be shown that\\ $\mathrm{combine}(IG_A, IG_B)$ gives rise to a valid structure for an instance graph and that \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity} holds. For readability, define $IG_{AB}$ to be $\mathrm{combine}(IG_A, IG_B)$.

\emph{Structural properties}
\begin{itemize}
    \item All elements of $N_{IG_{AB}}$ are elements of $Node_t \cup Node_v$.

    Follows from $N_{IG_{A}} \subseteq Node_t \cup Node_v$ and $N_{IG_{B}} \subseteq Node_t \cup Node_v$.

    \item All elements of $E_{IG_{AB}}$ are elements of $N_{IG_{AB}} \times ET_{TG_{AB}} \times N_{IG_{AB}}$.

    Follows from $E_{IG_{A}} \subseteq (N_{IG_{A}} \times ET_{TG_{A}} \times N_{IG_{A}})$ and $E_{IG_{B}} \subseteq (N_{IG_{B}} \times ET_{TG_{B}} \times N_{IG_{B}})$. To complete the proof, use that $ET_{TG_{AB}} = ET_{TG_{A}} \cup ET_{TG_{B}}$ and $N_{IG_{AB}} = N_{IG_{A}} \cup N_{IG_{B}}$.

    \item For each identity $i \in \mathrm{dom}\ \mathrm{ident}_{IG_{AB}}$, $\mathrm{ident}_{IG_{AB}}(i)$ is an element of $N_{IG_{AB}} \cap Node_t$.

    First note that $\mathrm{ident}_{IG_{AB}}(i) = \mathrm{ident}_{IG_{A}}(i)$ or $\mathrm{ident}_{IG_{AB}}(i) = \mathrm{ident}_{IG_{B}}(i)$.

    If $\mathrm{ident}_{IG_{AB}}(i) = \mathrm{ident}_{IG_{A}}(i)$, then have $\mathrm{ident}_{IG_{A}}(i) \in N_{IG_{A}} \cap Node_t$. Then use $N_{IG_{AB}} = N_{IG_{A}} \cup N_{IG_{B}}$ to have $\mathrm{ident}_{IG_{AB}}(i) \in N_{IG_{AB}} \cap Node_t$.

    Similarly, if $\mathrm{ident}_{IG_{AB}}(i) = \mathrm{ident}_{IG_{B}}(i)$, then have $\mathrm{ident}_{IG_{B}}(i) \in N_{IG_{B}} \cap Node_t$. Then use $N_{IG_{AB}} = N_{IG_{A}} \cup N_{IG_{B}}$ to have $\mathrm{ident}_{IG_{AB}}(i) \in N_{IG_{AB}} \cap Node_t$.
\end{itemize}

\emph{Validity properties}
\begin{itemize}
    \item $\forall n \in N_{IG_{AB}}\!: \mathrm{type}_n(n) \in NT_{TG_{AB}}$.

    Have that $\mathrm{type}_n(n) \in NT_{TG_{A}}$ or $\mathrm{type}_n(n) \in NT_{TG_{B}}$. Then have that $\mathrm{type}_n(n) \in NT_{TG_{AB}}$ because $N_{IG_{AB}} = N_{IG_{A}} \cup N_{IG_{B}}$.

    \item $\forall e \in E_{IG_{AB}}\!: \mathrm{type}_n \big(\mathrm{src}(e)\big) \sqsubseteq_{TG_{AB}} \mathrm{src} \big(\mathrm{type}_e(e)\big)$.

    Since types of nodes and edges are preserved while merging, $\sqsubseteq_{TG_{A}}\ \subseteq\ \sqsubseteq_{TG_{AB}}$ and $\sqsubseteq_{TG_{B}}\ \subseteq\ \sqsubseteq_{TG_{AB}}$, it follows that $\mathrm{type}_n \big(\mathrm{src}(e)\big) \sqsubseteq_{TG_{AB}} \mathrm{src} \big(\mathrm{type}_e(e)\big)$.

    \item $\forall e \in E_{IG_{AB}}\!: \mathrm{type}_n \big(\mathrm{tgt}(e)\big) \sqsubseteq_{TG_{AB}} \mathrm{tgt} \big(\mathrm{type}_e(e)\big)$.

    Since types of nodes and edges are preserved while merging, $\sqsubseteq_{TG_{A}}\ \subseteq\ \sqsubseteq_{TG_{AB}}$ and $\sqsubseteq_{TG_{B}}\ \subseteq\ \sqsubseteq_{TG_{AB}}$, it follows that $\mathrm{type}_n \big(\mathrm{tgt}(e)\big) \sqsubseteq_{TG_{AB}} \mathrm{tgt} \big(\mathrm{type}_e(e)\big)$.

    \item $\forall n \in N_{IG_{AB}}\!: \mathrm{type}_n(n) \not\in abs_{TG_{AB}}$.

    Use that $N_{IG_{AB}} = N_{IG_{A}} \cup N_{IG_{B}}$. Then make a case distinction.

    If $n \in N_{IG_{A}}$, then $\mathrm{type}_n(n) \not\in abs_{TG_{A}}$. Furthermore, $\mathrm{type}_n(n) \not\in abs_{TG_{B}} \setminus NT_{TG_{A}}$. Then we have that $\mathrm{type}_n(n) \not\in abs_{TG_{AB}}$.

    Similarly, if $n \in N_{IG_{B}}$, then $\mathrm{type}_n(n) \not\in abs_{TG_{B}}$. Furthermore, $\mathrm{type}_n(n) \not\in abs_{TG_{A}} \setminus NT_{TG_{B}}$. Then we have that $\mathrm{type}_n(n) \not\in abs_{TG_{AB}}$.

    \item $\forall et \in ET_{TG_{AB}}\!: \forall n \in N_{IG_{AB}}\!: \mathrm{type}_n(n) \sqsubseteq_{TG_{AB}} \mathrm{src}(et) \Longrightarrow |\{e \in E_{IG_{AB}} \mid \mathrm{src}(e) = n \land \mathrm{type}_e(e) = et\}| \in \mathrm{out}(\mathrm{mult}_{TG_{AB}}(et))$.

    This can be solved directly by expanding some definitions and using the assumption for outgoing multiplicities.

    \item $\forall et \in ET_{TG_{AB}}\!: \forall n \in N_{IG_{AB}}\!: \mathrm{type}_n(n) \sqsubseteq_{TG_{AB}} \mathrm{tgt}(et) \Longrightarrow |\{e \in E_{IG_{AB}} \mid \mathrm{tgt}(e) = n \land \mathrm{type}_e(e) = et\}| \in \mathrm{in}(\mathrm{mult}_{TG_{AB}}(et))$.

    This can be solved directly by expanding some definitions and using the assumption for incoming multiplicities.

    \item $\forall n \in N_{IG_{AB}}\!: |\{e \in E_{IG_{AB}} \mid \mathrm{tgt}(e) = n\,\land\,\mathrm{type}_e(e) \in contains_{TG_{AB}}\}| \leq 1$.

    This can be solved directly by expanding some definitions and using the assumption for the containment of nodes.

    \item There may be no cycle between the containment edges in $E_{IG_{AB}}$.

    This is solved by assumption.
\end{itemize}

The proofs of all these individual properties complete the entire proof.
\end{proof}

As explained before, \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_correct} does not take into account that the instance graphs are supposed to be distinct except for a set of nodes. Furthermore, it does not take into account that the corresponding type graphs are supposed to be distinct except for a set of node types. The following lemma is an alternation of the previous theorem, which takes these properties into account.

\begin{lem}[Consistency of the combination (mostly) distinct of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_merge_correct}
Assume that $IG_A$ and $IG_B$ are valid instance graphs in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}. Assume that $IG_A$ is typed by type model $TG_A$. Furthermore, assume that $IG_B$ is typed by type model $TG_B$. $TG_A$ and $TG_B$ are consistent by definition. Also assume that $TG_{AB} = \mathrm{combine}(TG_A, TG_B)$ is consistent in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}. Moreover, assume that $TG_{A}$ and $TG_{B}$ are entirely distinct except for a set of node types $NT$. Also assume that $IG_{A}$ and $IG_{B}$ are entirely distinct except for a set of nodes $N$. Finally, assume the following properties:
\begin{itemize}
    \item For all shared identities, the nodes belonging to the identities must be equal in both instance graphs: $\forall i \in \mathrm{dom}\ \mathrm{ident}_{IG_A} \cap \mathrm{dom}\ \mathrm{ident}_{IG_B}\!: \mathrm{ident}_{IG_A}(i) = \mathrm{ident}_{IG_B}(i)$.
    \item The outgoing multiplicity for edges in $IG_A$ must be valid: $\forall et \in ET_{TG_A} \land n \in N_{IG_A} \cup N_{IG_B}\!: (\mathrm{type_n}(n), \mathrm{src}(et)) \in\ \sqsubseteq_{TG_{AB}} \implies$\\$|\{e \mid e \in E_{IG_A} \land \mathrm{src}(e) = n \land \mathrm{type_e}(e) = et \}| \in \mathrm{out}(\mathrm{mult}_{TG_{A}}(et))$.
    \item The incoming multiplicity for edges in $IG_A$ must be valid: $\forall et \in ET_{TG_A} \land n \in N_{IG_A} \cup N_{IG_B}\!: (\mathrm{type_n}(n), \mathrm{tgt}(et)) \in\ \sqsubseteq_{TG_{AB}} \implies$\\$|\{e \mid e \in E_{IG_A} \land \mathrm{tgt}(e) = n \land \mathrm{type_e}(e) = et \}| \in \mathrm{in}(\mathrm{mult}_{TG_{A}}(et))$.
    \item The outgoing multiplicity for edges in $IG_B$ must be valid: $\forall et \in ET_{TG_B} \land n \in N_{IG_A} \cup N_{IG_B}\!: (\mathrm{type_n}(n), \mathrm{src}(et)) \in\ \sqsubseteq_{TG_{AB}} \implies$\\$|\{e \mid e \in E_{IG_B} \land \mathrm{src}(e) = n \land \mathrm{type_e}(e) = et \}| \in \mathrm{out}(\mathrm{mult}_{TG_{B}}(et))$.
    \item The incoming multiplicity for edges in $IG_B$ must be valid: $\forall et \in ET_{TG_B} \land n \in N_{IG_A} \cup N_{IG_B}\!: (\mathrm{type_n}(n), \mathrm{tgt}(et)) \in\ \sqsubseteq_{TG_{AB}} \implies$\\$|\{e \mid e \in E_{IG_B} \land \mathrm{tgt}(e) = n \land \mathrm{type_e}(e) = et \}| \in \mathrm{in}(\mathrm{mult}_{TG_{B}}(et))$.
    \item Each node that is present in both instance graphs may only be contained by one other node: $\forall n \in N_{IG_A} \cap N_{IG_B}\!: |\{e \mid e \in E_{IG_A} \cup E_{IG_B} \land \mathrm{tgt}(e) = n \land \mathrm{type_e}(e) \in contains_{TG_{AB}} \}| \leq 1$.
    \item There may be no cycle in the containment edges of the combined instance graph: $\{( \mathrm{src}(e), \mathrm{tgt}(e) ) \mid e \in E_{IG_A} \cup E_{IG_B} \land \mathrm{type_e}(e) \in contains_{TG_{AB}} \}$ is acyclic.
\end{itemize}

Then $\mathrm{combine}(IG_A, IG_B)$ is a valid instance graph in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}.
\isabellelref{ig_combine_merge_correct}{GROOVE.Instance_Graph_Combination}
\end{lem}

\begin{proof}
Use \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_correct} to show that $\mathrm{combine}(IG_A, IG_B)$ is a consistent type model. Use the assumptions given. Some assumptions of \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:imod_combine_correct} are solved using multiple assumptions because part of the assumption became irrelevant.
\end{proof}

Finally, the concept of compatibility between two instance graphs is defined.

\begin{defin}[Compatibility of instance graphs]
\label{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:compatibility}
Assume instance graphs $IG_A$ and $IG_B$. We say that $IG_A$ is compatible with $IG_B$ if  $\mathrm{combine}(IG_A, IG_B)$ is a valid instance graph in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}.
\end{defin}

The notion of compatibility will be used later as a way to denote instance graphs that can be combined with other instance graphs without loss of validity.


\section{The \removecopy algorithm (basic contract)}
\Label{sec:removecopy}

The \removecopy algorithm of the \cxx Standard Library \cite[\S 28.6.8]{cxx-17-draft}
copies all elements of a sequence other than a given value.
Here, the general implementation has been altered to process \valuetype ranges.
The new signature reads:

\begin{lstlisting}[style=acsl-block]

  size_type
  remove_copy(const value_type* a, size_type n, value_type* b, value_type v);
\end{lstlisting}

The requirements of \removecopy are:

\begin{table}[hbt]
  \begin{center}
    \begin{tabular}{|l|p{0.6\textwidth}|}
\hline
\textbf{Requirements} & \textbf{Description}
\\\hline
\hline
\namedlabel{itm:remove-size}
{\textbf{Remove Copy Size}} &
The output range has to fit in all the elements of
the input range, except the ones that equal the value~\inl{v}
        by \removecopy.
\\\hline
        \namedlabel{itm:remove-separation}{\textbf{Remove Copy Separated}} &
        The input range and the output range do not overlap
\\\hline
        \namedlabel{itm:remove-elements}{\textbf{Remove Copy Elements}} &
        The \removecopy algorithm copies elements that
        are not equal to \inl{v}
        from range
        \inl{a[0..n-1]} to the range {\inl{b[0..\\result-1]}}.
\\\hline
        \namedlabel{itm:remove-order}{\textbf{Remove Copy Stability}} &
        The algorithm is stable, that is, the
        relative order of the elements in \inl{b} is the same as in \inl{a}.
\\\hline
        \namedlabel{itm:remove-return}{\textbf{Remove Copy Return}} &
        The return value is the length of the resulting range.
\\\hline
        \namedlabel{itm:remove-complexity}{\textbf{Remove Copy Complexity}} &
        The algorithm takes $n$ comparisons in every case.
\\\hline
      \end{tabular}
    \end{center}
  \caption{\label{tbl:remove_copy_props}Properties of \removecopy}
\end{table}
\FloatBarrier

Figure~\ref{fig:removecopy} shows an example of how \removecopy is supposed
to copy elements that differ from~\inl{4} from the input range to the output range.

\begin{figure}[hbt]
\centering
\includegraphics[width=0.75\textwidth]{Figures/remove_copy.pdf}
\caption{\Label{fig:removecopy}Effects of \removecopy}
\end{figure}

\FloatBarrier

\subsection{Formal specification of \removecopy}

The following listing shows our first attempt to specify \removecopy.
In postcondition~\inl{discard} we use of the predicate \logicref{NoneEqual}
to show that the value \inl{v} does not occur in the range \inl{b[0..\\result]}.

\input{Listings/remove_copy.h.tex}

One shortcoming of this specification is that the postcondition \inl{bound}
only makes very general and not very precise statements about the number of copied elements.
We will address this problem in the contract of \specref{removecopyii}.
A more serious shortcoming is, however, that we haven't specified what
the relationship between the elements of the input range \inl{a[0..n-1]}
and the output range \inl{b[0..\\result-1]} looks like.
This problem will be tackled in the contract of \specref{removecopyiii}.

%\clearpage

\subsection{Implementation of \removecopy}

An implementation of \removecopy is shown in the following listing.

\input{Listings/remove_copy.c.tex}

Here we also need to add another loop invariant~\inl{discard} which basically
checks if \inl{v} occurs in \inl{b[0..k]} for each iteration of the loop.

%\clearpage


e% Created 2018-01-30 Tue 14:39
\documentclass[11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{fixltx2e}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{float}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{marvosym}
\usepackage{wasysym}
\usepackage{amssymb}
\tolerance=1000
\usepackage[pdftex]{hyperref}
\usepackage[pdftex]{insdljs}
\newcommand{\aDE}[4]{\begin{center}\begin{equation}\label{#4}\frac{{dy(t)}}{{dt}} -#1y(t) = #2u(t),y(0) = #3 \end{equation}\end{center}}
\newcommand\tugHello{Hello World!}
\begin{insDLJS}{mydljs}{My Private DLJS}
function HelloWorld() { app.alert("\tugHello", 3); }
\end{insDLJS}
\author{Changyuan Lin}
\date{\today}
\title{Test}
\hypersetup{
  pdfkeywords={},
  pdfsubject={},
  pdfcreator={Emacs 25.3.1 (Org mode 8.2.10)}}
\begin{document}

\maketitle
\tableofcontents

\section{Chapter 1}
\label{sec-1}
\subsection{Equation Generated by Python}
\label{sec-1-1}
Consider the differential equation given below.
\aDE{1.5}{1.5}{3.6}{eq1}
\subsection{Table}
\label{sec-1-2}
Consider the singal given below.

\begin{figure}[!htpb]
\centering
\includegraphics[width=0.5in]{plot.png}
\caption{\label{FIG:fig2}Reconstruct signal \(y(t)\).}
\end{figure}

\subsection{Inline Equation}
\label{sec-1-3}
Consider the differential equation given below.
\aDE{1.5}{1.5}{3.6}{eq2}
\begin{itemize}
\item Find an integral form solution for Eq.\ref{eq2}.
\item Find an analytic solution for Eq.\ref{eq2} when the input \(u(t)\) is  given as , for \(t\ge 0\). Is this input able to stabilize state \(y(t)\) when \( t\rightarrow  \infty\)?
\item Find the difference equation when sampleo time is \(\triangle t=0.3\) by exact discretization.
\item Find the difference equation with time derivative approximated at \(\triangle t=0.3\) by finite difference method.
\item Find a solution of difference equation and exact diference equation using  MATLAB or any other software for \(k=20\).  Plot the sequence of numbers obtained by the exact difference equation and by finite difference method and applied piecewise constant input given as follows
\[ \begin{array}{c} u(0) = -2 \\u(1\triangle t) = -2e^{-2*1\triangle t} \\ u(2\triangle t) = -2e^{-2*2\triangle t} \\ \cdots=\cdots \\ u(k\triangle t)= -2e^{-2*k\triangle t}\end{array} \]

with k=20

Solution:
\end{itemize}

\begin{itemize}
\item \[y(t)=5e^{2t}+1.5e^{2t}\int_0^t (-2) e^{-2s}e^{-2s}ds= 5e^{2t}-3e^{2t} \int_0^t e^{-4s}ds=5e^{2t}-3\int_0^t e^{-4s}\frac{d(-4s)}{-4} \]
       \[y(t)=5e^{2t}+\frac{3}{4}\left[e^{-4t}-1\right]\]
\item Exact discretization \(\Delta t = 0.3\):
\[\begin{array}{rcl}
       y_{k+1} &=& e^{a\Delta t}y_{k} + a^{-1}(e^{a\Delta t}-1)bu_{k} \\[0.25cm]
       &=& 1.822y_{k} + 0.6166u_{k}
       \end{array}\]

\item Finite difference method \(\Delta t=0.3\):
\[\begin{array}{rcl}  \frac{dy}{dt} \approx \frac{y_{k+1}-y_{k}}{\Delta t} &=& 2y_{k} + 1.5u_{k} \\[0.25cm]
         y_{k+1} &=& (1+2\Delta t)y_{k} + 1.5(\Delta t )u_{k} \\[0.25cm]
         &=& 1.6y_{k} + 0.45u_{k}
         \end{array}\]
\end{itemize}

\begin{figure}[!htpb]
\centering
\includegraphics[width=4in]{plot1.png}
\caption{\label{FIG:fig3}Finite difference and exact discretization \(y(k)\).}
\end{figure}

\subsection{ditaa \& \LaTeX{} Graph}
\label{sec-1-4}
For the physical process of tank dynamics given in the Figure below:

\vspace{0.2in}
\setlength{\unitlength}{1cm}
\begin{picture}(1, 1)
  \put(5, 0.9){\vector(1, 0){1.8}}
  \put(6.8, 0.9){\vector(0,-1){0.7}}
  \put(5.5,1.1){{$f_{in}(t)$}}
  \put(6.3, 0.25){\line(0,-1){1.9}}
  \put(8.2, 0.25){\line(0,-1){1.9}}
  \put(6.3,-1.95){\framebox(1.9,1.9)}
  \put(8., -1.95){\vector(1,0){2.5}}
  \put(9.6, -2.1){\line(0,0){0.4}}
  \put(9.3, -2.1){\line(0,0){0.4}}
  \put(9.3, -2.1){\line(3,4){0.3}}
  \put(9.3, -1.75){\line(3,-4){0.3}}
  \put(9.45,-2.){\line(0,1){0.5}}
  \put(9.15,-1.5){\line(1,0){0.5}}
   \put(10.7,-2){{$f_{out}(t)$}}
   \put(9.3,-1.25){{$K$}}
    \put(5.5,-1.25){{$h(t)$}}
\end{picture}
\vspace{0.7in}

Solution:
\begin{itemize}
\item \( \frac{dh}{dt} = -\frac{1}{K\overline{A}}h + \frac{1}{\overline{A}}f_{in}\)
\item Assume that the tank height is measured, \(y(t) = h(t)\)
       \[\Sigma(A,B,C,D) = \Sigma\left(-\frac{1}{K\overline{A}}, \frac{1}{\overline{A}}, 1, 0\right)\]
\item The state-space realization is given as:
\end{itemize}

\begin{figure}[!htpb]
\centering
\includegraphics[width=3in,height=1.5in]{hello.png}
{\caption{Block diagram elements.}}
\end{figure}

\begin{itemize}
\item \[\begin{array}{c}
        \Phi = e^{-\frac{0.2}{K\overline{A}}}, \quad \Gamma = -K\left(e^{-\frac{0.2}{K\overline{A}}} - 1\right), \quad \theta = 1 \\[0.5cm]
        \Sigma(A_{d},B_{d},C_{d},D_{d}) = \Sigma\left( e^{-\frac{0.2}{K\overline{A}}}, -K\left(e^{-\frac{0.2}{K\overline{A}}} - 1\right), 1, 0\right)
        \end{array}\]
\item Assume that \(h(0) = 0\). Laplace transform:
\[ \frac{Y(s)}{U(s)} = \frac{5}{s+1}\]
\[\boxed{ \nonumber  \tau = 1, \quad \tau_{d} = 0\Rightarrow \Delta t = (0.1\sim0.2)1\tau = 0.1\sim 0.2}\]
\end{itemize}

\section{Chapter 2}
\label{sec-2}
\subsection{JavaScript}
\label{sec-2-1}
\begin{Form} % a hyperref environment, needed for \PushButton
% use built in form button of hyperref
Push \PushButton[name=myButton,onclick={HelloWorld();}]{Button}
\end{Form}
% Emacs 25.3.1 (Org mode 8.2.10)
\end{document}


\section{Conclusion and Future Work}

In this paper we have shown how to mechanise an algorithmic subtyping relation
for higher-order polymorphism, together with its proofs of soundness,
completeness and decidability, in the Abella proof assistant.
In ongoing work we are extending our mechanisation with a bidirectional type
inference algorithm. The main difficulty there is communicating the
instantiations of existential variables from the subtyping algorithm to the
type inference. To make this possible we are exploring a continuation passing
style formulation, which generalises the worklist approach.
Another possible extension is to have the algorithm return an explicit witness
for the subtyping as part of type-directed elaboration into System F.


\chapter{Double Implementation}\label{a:oldDouble}
This appendix contains a complete version of Double as described in \autoref{teExample}.
\begin{tcolorbox}[breakable, toprule at break=0pt, bottomrule at break=0pt]
\begin{minted}{haskell}
module Main(main) where
import Language.Drasil (
  -- Primitive types
  Contents(LlC), Document, Expr(Int), LabelledContent,
  Sentence(S, E, EmptyS), Space(Integer), Symbol(Atomic),
  -- Chunks
  AssumpChunk, Change, CI, ConstrainedChunk, QDefinition,
  QuantityDict, ReqChunk, UnitaryConceptDict, UnitDefn,
  -- Smart constructors
  assump, commonIdeaWithDict, cn''', frc, fromEqn', lc,
  nounPhraseSent, pn, nw, qw, person, shortname, vc,
  -- Sentence functions
  atStart, short, phrase,
  -- Expr combinators
  ($^), sy)

import Database.Drasil (Block, ChunkDB, RefbyMap,
  SystemInformation(SI), TraceMap, cdb, collectUnits, rdb,
  refdb, _authors, _concepts, _constants, _constraints,
  _datadefs, _definitions, _defSequence, _inputs, _kind,
  _outputs, _quants, _sys, _sysinfodb, _usedinfodb)
import Theory.Drasil (DataDefinition, ddNoRefs)
import Utils.Drasil (chgsStart, foldlSent, foldlSent_, for)

import Data.Drasil.Concepts.Documentation (doccon, doccon',
  input_, output_, software, srs, system, value)
import Data.Drasil.IdeaDicts (mathematics)
import Data.Drasil.SI_Units (derived, fundamentals, siUnits)

import Drasil.DocLang (
  DocDesc, DocSection(RefSec, IntroSec, SSDSec, ReqrmntSec,
    LCsSec, TraceabilitySec),
  DerivationDisplay(HideDerivation), Field(DefiningEquation,
    Description, Label, Symbol, Units),
  InclUnits(IncludeUnits), IntroSec(IntroProg),
  RefSec(RefProg), ReqrmntSec(ReqsProg), ReqsSub(FReqsSub),
  SCSSub(Assumptions, DDs), SolChSpec(SCSProg),
  SSDSec(SSDProg), SSDSub(SSDSolChSpec), TSIntro(TSPurpose),
  TraceabilitySec(TraceabilityProg), Verbosity(Verbose),
  generateRefbyMap, generateTraceMap, generateTraceTable,
  getSCSSub, getTraceMapFromChgs, getTraceMapFromDD,
  getTraceMapFromReqs, intro, mkDoc, tsymb)

import Language.Drasil.Code (Choices(..), CodeSpec,
  Comments(CommentNone), ConstraintBehaviour(Warning),
  ImplementationType(Program), Lang(Cpp, CSharp, Java,
    Python), Logging(LogNone), Structure(Bundled), codeSpec)
import Language.Drasil.Printers (DocSpec(DocSpec),
  DocType(SRS, Website), PrintingInformation(PI),
  defaultConfiguration)
import Language.Drasil.Generate (gen, genCode)

symbols :: [QuantityDict]
symbols = [x, y]

pname :: String
pname = "Double"

double :: CI
double = commonIdeaWithDict "double" (pn pname) pname
  [mathematics]

assumpNum :: AssumpChunk
assumpNum = assump "assumpNum" (foldlSent [S "This",
  phrase system, S "only considers", phrase input_,
  S "integers between", E $ (-2) $^ 29, S "and",
  E (2 $^ 29)]) "assumpNum" $
  shortname "reasonableNumber"

reqMul :: ReqChunk
reqMul = frc "reqMul" (foldlSent [S "The", phrase output_,
  S "shall be twice the", phrase input_, phrase value])
  "reqMul" $ shortname "mulNum"

chg :: Change
chg = lc "chg" (foldlSent [chgsStart assumpNum (S "The"),
  phrase software, S "may be changed to remove the range",
  S "restriction on the", phrase input_, S "to support",
  S "doubling any integer"]) "chg" $
  shortname "removeRestriction"

x :: QuantityDict
x = vc "x" (cn''' "input value") (Atomic "x") Integer

y :: QDefinition
y = fromEqn' "y" (nounPhraseSent $ foldlSent_ [phrase input_,
  phrase value, S "doubled"]) EmptyS (Atomic "y") Integer $
  (Int 2) * sy x

doubleDD :: DataDefinition
doubleDD = ddNoRefs y [{-Derivation-}] "doubleDD" [{-Notes-}]

thisSI :: SystemInformation
thisSI = SI {
  _sys = double,
  _kind = srs,
  _authors = [person "Gabriel" "Dalimonte"],
  _quants = symbols,
  _datadefs = [doubleDD],
  _inputs = [x],
  _outputs = [y],
  _sysinfodb = allSymbols,
  _usedinfodb = allSymbols,
  _defSequence = [] :: [Block QDefinition],
  _constraints = [] :: [ConstrainedChunk],
  _constants = [],
  _concepts = [] :: [UnitaryConceptDict],
  _definitions = [] :: [QDefinition],
  refdb = rdb [] []
}

allSymbols :: ChunkDB
allSymbols = cdb symbols (nw double : map nw symbols ++
  map nw doccon ++ map nw fundamentals ++ map nw derived ++
  map nw doccon') srsDomains (siUnits ++ checkSI) label refBy
  dataDefn [] [] [] [assumpNum] reqs chgs [] []

thisSRS :: DocDesc
thisSRS = [
  RefSec $ RefProg intro [tsymb [TSPurpose]],
    IntroSec $ IntroProg (foldlSent [atStart double,
      S "is a trivial example for demonstrating Drasil's",
      S "capabilities"]) (short double) [],
    SSDSec $ SSDProg [
      SSDSolChSpec $ SCSProg [
        Assumptions,
        DDs [] [Label, Symbol, Units, DefiningEquation,
        Description Verbose IncludeUnits] [doubleDD]
        HideDerivation
      ]],
  ReqrmntSec $ ReqsProg [
    FReqsSub [reqMul] []
  ],
  LCsSec $ LCsProg [chg],
  TraceabilitySec $
    TraceabilityProg [traceTable] [foldlSent
      [S "items with each other"]] [LlC traceTable] []
  ]

traceTable :: LabelledContent
traceTable = generateTraceTable thisSI

checkSi :: [UnitDefn]
checkSi = collectUnits allSymbols symbols

label :: TraceMap
label = generateTraceMap thisSRS

refBy :: RefbyMap
refBy = generateRefbyMap label

scs :: SCSSub
scs = getSCSSub thisSRS

dataDefn :: [DataDefinition]
dataDefn = getTraceMapFromDD scs

reqs :: [ReqChunk]
reqs = getTraceMapFromReqs scs

chgs :: [Change]
chgs = getTraceMapFromChgs scs

srsBody :: Document
srsBody = mkDoc thisSRS for thisSI

pS :: PrintingInformation
pS = PI allSymbols defaultConfiguration

thisCode :: CodeSpec
thisCode = codeSpec thisSI thisChoices []

thisChoices :: Choices
thisChoices = Choices {
  lang             = [Python, Cpp, CSharp, Java],
  impType          = Program,
  logFile          = "log.txt",
  logging          = LogNone,
  comments         = CommentNone,
  onSfwrConstraint = Warning,
  onPhysConstraint = Warning,
  inputStructure   = Bundled
}

main :: IO ()
main = do
  gen (DocSpec Website $ pname ++ "_SRS") srsBody pS
  gen (DocSpec SRS $ pname ++ "_SRS")     srsBody pS
  genCode thisChoices thisCode

\end{minted}
\end{tcolorbox}


\chapter{Package MARSS:  Warnings and errors}
\label{app:warnings}
\index{troubleshooting}The following are brief descriptions of the warning and error message you may see and what they mean (or might mean).  More warning information can be found by typing \verb@MARSSinfo()@ at the commmand line.

\section*{B update is outside the unit circle}
\index{troubleshooting!B outside unit circle}If you are estimating $\BB$, then if the absolute value of all the eigenvalues of $\BB$ are less than 1, the system is stationary (meaning the $\XX$'s have some multivariate distribution that does not change over time).  In this case, we say that $\BB$ is within the unit circle.  A pure univariate random walk for example would have $\BB$=1 and it is not stationary.  The distribution of $\XX$ for the pure random walk has a variance that increases with time.  If on the other hand $|\BB|<1$, you have an Ornstein-Uhlenbeck process and is stationary, with a stationary variance of $\QQ/(1-\BB^2)$ (note $\BB$ is a scalar here because in this example $\XX$ is univariate).  If any of the eigenvalues (real part) are greater than 1, then the system will ``explode''---it rapidly diverges.

In the EM algorithm, there is nothing to force $\BB$ to be on or within the unit circle (real part of the eigenvalues less than or equal to 1).  It is possible at one of the EM iterations the $\BB$ update will be outside the unit circle.  The problem is that if you get too far outside the unit circle, the algorithm becomes numerically unstable since small errors are magnified by the ``explosive'' $\BB$ term.  If you see the `B outside the unit circle' warning, it is fine as long as it is temporary and the log-likelihood does not start decreasing (you will see a separate warning if that happens).

If you do see $\BB$ outside the unit circle and the log-likelihood decreases, then it probably means that you have poorly specified the model somehow.  An easy way to do this is to poorly specify the initial conditions, $\pipi$ and $\LAM$.  If, say, you try to specify a vague prior on $\xx_0$ (or $\xx_1$) with $\pipi$ equal to zero and $\LAM$ equal to a diagonal matrix with a large variance on the diagonal, you will likely run into trouble if $\BB$ has off-diagonal terms.  The reason is that by specifying that $\LAM$ is diagonal, you specified that the individual $X$'s in $\XX_0$ are independent, yet if $\BB$ has off-diagonal terms, the stationary distribution of $\XX_1$ is NOT independent.  If you force the diagonal terms on $\LAM$ to be big enough, you can force the maximum-likelihood estimate of $\BB$ to be outside the unit circle since this is the only way to account for $\XX_0$ independent and $\XX_1$ highly correlated\index{prior!troubleshooting}.

The problem is that you will not know the stationary distribution of the $\XX$'s (from which $\XX_0$ was presumably drawn) without knowing the parameters you are trying to estimate.  One approach is the estimate both $\pipi$ and $\LAM$ by setting \verb@x0="unconstrained"@ and \verb@V0="unconstrained"@ in the model specification.  Estimating both $\pipi$ and $\LAM$ cannot be done robustly for all MARSS models, and in general, one probably wants to specify the model in such a way as to fix one or both of these.   Another, more robust approach, is to treat $\xx_1$ as fixed but unknown (instead of $\xx_0$).  You do this by setting \verb@model$tinitx=1@, so that $\pipi$ refers to $t=1$ not $t=0$.  Then estimate $\pipi$ and fix $\LAM=0$. This eliminates $\LAM$ from the model and often eliminates the problems with prior specification---as the expense of $m$ more parameters.  Note, when you set $\LAM=0$, $\LAM$ is truly eliminated from the model by MARSS; the likelihood function is different, so do not expect $\LAM=0$ and $\LAM \sim 0$ to have the same likelihood under all conditions.

\section*{Warning! Reached maxit before parameters converged}
\index{troubleshooting!non-convergence}The maximum number of EM iterations is set by \verb@control$maxit@.  If you get this warning, it means that one of the parameters or log-likelihood had not yet reached the convergence stopping criteria before \verb@maxit@ was reached.  There are many situations where you might want to set \verb@control$maxit@ lower than the value needed to reach convergence.  For example, if you are using the EM algorithm to produce initial values for a different algorithm (like a Bayesian MCMC algorithm or a Newton method) then you can set \verb@maxit@ low, say 20 or 50.

\section*{Stopped at iter=xx in MARSSkem() because numerical errors were generated in MARSSkf}
\index{troubleshooting!numerical instability}This means the Kalman filter/smoother algorithm became unstable and most likely one of the variances became ill-conditioned.  When that happens the inverses of those matrices are poor, and you will start to get negative values on the diagonals of your variance-covariance matrices.  Once that happens, the inverse of that var-covariance matrix produces an error.  If you get this error, turn on tracing with \verb@control$trace=1@. This will store the error messages so you can see what is going on.  It may be that you have specified the model in such a way that some of the variances are being forced very close to 0, which makes the var-covariance matrix ill-conditioned.  The output from the MARSS call will be the parameter values just before the error occurred.

\section*{Warning: the  xyz  parameter value has not converged}
\index{troubleshooting!non-convergence}The algorithm checks whether the log-likelihood and each individual parameter has converged.  If a parameter has not converged, you can try upping \verb@control$maxit@ and see if it converges.  If you set, \verb@maxit@ high, but the parameter is still not converging, then it suggests that one of the variance parameters is so small that the EM update steps for that parameter are tiny.  For example, as $\QQ$ goes to zero, the update steps for $\uu$ go to zero.  As $\LAM$ goes to zero, the update steps for $\pipi$ go to zero.  The first thing to do is to reflect on whether you are inadvertently specifying the model in such a way that one of the variances is forced to zero.  For example, if the total variance in $\XX$ is 0.1 and you fix $\RR=0.2$ then $\QQ$ must go to zero.  The second thing to do is to try using a Newton algorithm, using your last EM values as the initial conditions for the Newton algorithm.  The initial values are set using the \verb@inits@ argument for the \verb@MARSS()@ function.

\section*{MARSSkem: The solution became unstable and logLik DROPPED}
\index{troubleshooting!numerical instability}\index{troubleshooting!logLik dropped}This is a more serious error as in the EM algorithm, the log-likelihood should never drop.  The first thing to do is check if you have specified a bizarre model or data, inadvertently.  Plot the data you are trying to fit.  Often, this error arises when a user has inadvertently scrambled their data order during a demeaning or variance-standardization step.  Second, check the model you are trying to fit.  Use \verb@test=MARSS(data, model=xyz, fit=FALSE)@ and then \verb@summary(test$model)@.  This shows you what \verb@MARSS()@ thinks your model is.  You may be trying to fit an illogical model.

If those checks looks good, then pass \verb@control$trace=1@ into the \verb@MARSS()@ call.  This will report a fuller set of warnings.  Look if the error ``B is outside the unit circle'' appears.  If so, you are probably specifying a strange $\BB$ matrix.  Are you forcing the $\BB$ matrix to be outside the unit circle (eigenvalues > 1)? If so, you need to rethink your $\BB$ matrix contraints.  If you do not see that error, look at \verb@test$iter.record$logLik@.  If the log-likelihood is steadily dropping (at each iteration) or drops by large amounts (much larger than the machine precision), that is bad and means that the EM algorithm did not work.  If however the log-likelihood is just fluctuating by small amounts about some steady value, that is ok as it means that the values converged but the parameters are such that there are slight numerical fluctuations.  Try passing \verb@control$safe=TRUE@ in the \verb@MARSS()@ call. This can sometimes help as it inserts a call to the Kalman filter after each individual parameter update.

\section*{Stopped at iter=xx in MARSSkem: solution became unstable. R (or Q) update is not positive definite}
\index{troubleshooting!matrix not positive definite}First check if you have specified an illegally constrained variance-covariance matrix.  For example, if the variances (diagonal) are constrained to be equal, you cannot specify the covariances (off-diagonals) as unequal. Or if you specify that some of the covariances are equal, you cannot specify the variances as all unequal.  These are illegal constraints on a variance-covariance matrix from a statistical perspective (nothing to do with MARSS specifically).

This could also be due to numerical instability as $\BB$ leaves the unit circle or one of the variance matrix becomes ill-conditioned.  Try turning on tracing with \verb@control$trace=1@ and turn on safe with \verb@control$safe=TRUE@.  This will print out the error warnings at each parameter update step.  Then consider whether you have inadvertently specified the model in such a way as to force this behavior in the $\BB$ parameter.

You might also get this error if you inadvertantly specified an improper structure for $\RR$ or $\QQ$.  For example, if you used \verb@R=diag(c(1,1,"r"))@ with the intent of specifying a diagonal matrix with fixed variance 1 at $\RR[1,1]$ and $\RR[2,2]$ and an estimated $\RR[3,3]$, you would have actually specified a character matrix with \verb@"0"@ on the off-diagonals and \verb@c("1","1","r")@ on the diagonal.  \verb@MARSS()@ interprets all elements in quotes as names of parameters to be estimated.  Thus it will estimate one off-diagonal covariance and two diagonal variances.  That happens to put illegal constraints on estimation of a variance-covariance matrix having nothing to do with the \verb@MARSS()@ function but with estimation of variance-covariance matrices in general.

\section*{iter=xx MARSSkf: logLik computation is becoming unstable.  Condition num. of Sigma[t=1] = Inf and of R = Inf.}
\index{troubleshooting!sigma condition number}This means, generally, that V0 is very small, say 0, and R is very small and very close to zero.

\section*{ Warning: setting diagonal to 0 blocked at iter=X. logLik was lower in attempt to set 0 diagonals on X }
\index{troubleshooting!setting diagonal to 0 blocked}This is a warning not an error.  What is happening is that one of the variances (in $\QQ$ or $\RR$) is getting small and the EM algorithm is attempting to set the value to 0 (because \verb@control$degen.allow=TRUE@).  But when it tried to do this, the new likelihood with the variance equal to 0 was lower and the variance was not set to 0.

A model with a variance minuscule and a model with the same variance equal to 0 are not the same model\index{prior!troubleshooting}.  In the first, a stochastic process with small variance exists but in the second, the analogous process is deterministic.  And in the first case, you can get a situation where the likelihood term L(x|mean=mu,sigma=0) appears.  That term will be infinite when x=mu. So in the model with variance minuscule, you will get very large likelihood values as the variance term gets smaller and smaller.  In the analogous model with that variance set to 0, that likelihood term does not appear so the likelihood does not go to infinity.

This is not an error nor pathological behavior; the models are fundamentally different.  Nonetheless, this will pose a dilemma when you want to chose the best model based on maximum likelihood.  The model with minuscule variance will have infinite likelihood but the same behavior as the one with variance 0.   In our experience, this dilemma arises when one has a lot of missing data near the beginning of the time series and is affected by how you specify the prior on the initial state.  Try setting the prior at $t=0$ versus $t=1$.  Try using a diffuse prior.  You absolutely want to compare estimates using the BFGS and EM algorithms in this case, because the different algorithms differ in their ability to find the maximum in this strange case.  Neither is uniformly better or worse.  It seems to depend on which variance ($\QQ$ or $\RR$) is going to zero.

\section*{Warning: kf returned error at iter=X in attempt to set 0 diagonals for X}
\index{troubleshooting!Kalman filter errors}This is a warning that the EM algorithm tried to set one of the diagonals of element X to 0 because \verb@allow.degen@ is TRUE and element X is going to zero.  However when this was tried, the Kalman filter returned an error.  Typically, this happens when both $\RR$ and $\QQ$ elements are both trying to be set to 0.  If the maximum-likelihood estimate is that both $\RR$ and $\QQ$ are zero, it probably means that your MARSS model is not a very good description of the data.

\section*{Warning: At iter=X attempt to set 0 diagonals for R blocked for elements where corresponding rows of A or Z are not fixed. }
\index{troubleshooting!setting diagonal to 0 blocked}You have \verb@control$degen.allow=TRUE@ and one of the $\RR$ diagonal elements is getting very small.  MARSS attempts to set these $\RR$ elements to 0, but if row $i$ of $\RR$ is 0, then the corresponding $i$ rows of $\aa$ and $\ZZ$ must be fixed.  This is for the EM algorithm.  It might work with the BFGS algorithm, or might spit out garbage without telling you.  Always be a suspect, when the EM and BFGS behavior is different.  That is a good sign that something is wrong with how your model describes the data.  It's not a problem with the algorithms per se; rather for certain pathological models, the algorithms behave differently from each other.

\section*{Stopped at iter=X in MARSSkem. XYZ is not invertible.  }
\index{troubleshooting!matrix not invertible}There are a series of checks in MARSS that check if matrix inversions are possible before doing the inversion.   These errors crop up most often when $\QQ$ or $\RR$ are getting very small.  At some point, they can get so small that inversions become unstable.  If this error is given, then the output will be the last parameter estimates before the error.  Try setting \verb@control$allow.degen=FALSE@.  Sometimes the error occurs when a diagonal element of $\QQ$ or $\RR$ is being set to 0.  You will also have to set \verb@control$maxit@ to something smaller because the EM algorithm will not stop since the problematic diagonal element will walk slowly and inexorably to 0.