\section{Two Other CRDTs: Counter and Set}
\label{sect.simple.crdts}

To demonstrate that our proof framework provides reusable components that significantly simplify SEC proofs for new algorithms, we show proofs for two other well-known operation-based CRDTs: the Observed-Remove Set (ORSet) and the Increment-Decrement Counter as described by \citet{Shapiro:2011wy}.
These proofs build upon the abstract convergence theorem and the network model of Sections~\ref{sect.abstract.convergence} and~\ref{sect.network}, and reuse some of the proof techniques developed in the formalisation of RGA in Section~\ref{sect.rga}.

As these proofs leverage the framework's machinery and proof techniques, we were able to develop them very quickly: the counter was proved correct in a matter of minutes, and the specification and correctness proof of the ORSet was done in about four hours by one of the authors, an Isabelle novice who had never used any proof assistant software prior to the start of this project.
Although these anecdotes do not constitute a formal evaluation of ease of use, we take them as being an encouraging sign.

\subsection{Increment-Decrement Counter}
\label{subsect.increment-decrement.counter}

The Increment-Decrement Counter is perhaps the simplest CRDT, and a paradigmatic example of a replicated data structure with commutative operations.
As the name suggests, the data structure supports two operations: $\isa{increment}$ and $\isa{decrement}$ which respectively increment and decrement a shared integer counter:
\begin{isabelle}
\isacommand{datatype}\ operation {\isacharequal}\ Increment\ {\isacharbar}\ Decrement
\end{isabelle}
\noindent The interpretation function for these two operations is straightforward:
\begin{isabelle}
~~~~{\isachardoublequoteopen}counter{\isacharunderscore}op\ Decrement\ \=\kill
\isacommand{fun}\ counter{\isacharunderscore}op\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}operation\ {\isasymRightarrow}\ int\ {\isasymRightarrow}\ int\ option{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}counter{\isacharunderscore}op\ Increment\>x\ {\isacharequal}\ Some\ {\isacharparenleft}x\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}counter{\isacharunderscore}op\ Decrement\>x\ {\isacharequal}\ Some\ {\isacharparenleft}x\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
Note that the operations do not fail on under- or overflow, as they are defined on a type of unbounded (mathematical) integers.
We could also have implemented the counter using fixed-size integers---e.g. signed 32- or 64-bit machine words---with wrap-around on overflow, which would not have impacted the proofs.
Showing commutativity of the operations is an easy exercise in applying Isabelle's proof automation:
\begin{isabelle}
\isacommand{lemma}\ {\isachardoublequoteopen}counter{\isacharunderscore}op\ x\ {\isasymrhd}\ counter{\isacharunderscore}op\ y\ {\isacharequal}\ counter{\isacharunderscore}op\ y\ {\isasymrhd}\ counter{\isacharunderscore}op\ x{\isachardoublequoteclose}
\end{isabelle}
Unlike more complex CRDTs such as RGA, the operations of the increment-decrement counter commute unconditionally.
As a result, this CRDT converges in any asynchronous broadcast network, without requiring causally ordered delivery.
For simplicity, we define $\isa{counter}$ as a simple extension of our existing $\isa{network}{\isacharunderscore}\isa{with}{\isacharunderscore}\isa{ops}$ locale.
We need only specify the interpretation function and the initial state 0:
\begin{isabelle}
\isacommand{locale}\ counter\ {\isacharequal}\ network{\isacharunderscore}with{\isacharunderscore}ops\ {\isacharunderscore}\ counter{\isacharunderscore}op\ {\isadigit{0}}
\end{isabelle}
It is then straightforward to prove that $\isa{counter}$ is a sublocale of $\isa{strong-eventual-consistency}$ (see Section~\ref{sect.abstract.sec.spec}), from which we obtain concrete convergence and progress theorems for the counter CRDT.

\subsection{Observed-Remove Set}
\label{subsect.orset}

The Observed-Remove Set (ORSet) is a well-known CRDT for implementing replicated sets, supporting two operations: \emph{adding} and \emph{removing} arbitrary elements in the set.
It has mostly been studied in its state-based formulation \cite{Bieniusa:2012wu,Bieniusa:2012gt,Brown:2014hs,Zeller:2014fl}, but here we use the operation-based formulation as described by \citet{Shapiro:2011wy}.
The name derives from the fact that the algorithm ``observes'' the state of a node when removing an element from the set, as explained below.

We start by defining the two possible operations of the datatype:
\begin{isabelle}
\isacommand{datatype}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ operation\ {\isacharequal}\ Add\ {\isachardoublequoteopen}{\isacharprime}id{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}a{\isachardoublequoteclose}\ {\isacharbar}\ Rem\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id\ set{\isacharparenright}{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}a{\isachardoublequoteclose}
\end{isabelle}
\noindent Here, $\isacharprime\isa{id}$ is an abstract type of message identifiers, and the type variable $\isacharprime\isa{a}$ represents the type of values that the application wishes to add to the set.
When an element $\isa{e}$ is added to the set, the operation $\isa{Add}\ i\ e$ is tagged with a unique identifier $\isa{i}$ in order to distinguish it from other operations that may concurrently add the same element $\isa{e}$ to the set.
When an element $\isa{e}$ is removed from the set, the operation $\isa{Rem}\ is\ e$ contains a set of identifiers $\isa{is}$, identifying all of the additions of that element that causally happened-before the removal.

The state maintained at each node is a function that maps each element $\isacharprime\isa{a}$ to the set of identifiers of operations that have added that element:
\begin{isabelle}
\isacommand{type{\isacharunderscore}synonym}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ state\ {\isacharequal}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}id\ set{\isachardoublequoteclose}
\end{isabelle}
We consider an element $\isacharprime\isa{a}$ to be a member of the ORSet if the set of addition identifiers is non-empty.
The initial state of a node---the empty ORSet---is then simply $\isasymlambda\isa{x}\isachardot\ \isacharbraceleft\isacharbraceright$, i.e. the function that maps every possible element $\isacharprime\isa{a}$ to the empty set of identifiers $\isacharbraceleft\isacharbraceright$.

When interpreting an $\isa{Add}$ operation, we must add the identifier of that operation to the node state.
When interpreting a $\isa{Rem}$ operation, we must update the node state to remove all causally prior $\isa{Add}$ identifiers.
If there are no concurrent additions of the same element, this has the effect of making the set of identifiers for that element empty, and thus considering the element as no longer being in the set.
We express this as follows:
\begin{isabelle}
~~~~~~~~let\ \=before\ \={\isacharequal}\ case\ oper\ of\ \=Rem\ \=is\ \=e\kill
\isacommand{definition}\ op{\isacharunderscore}elem\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ operation\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}op{\isacharunderscore}elem\ oper\ {\isasymequiv}\ case\ oper\ of\ Add\ i\ e\ {\isasymRightarrow}\ e\ {\isacharbar}\ Rem\ is\ e\ {\isasymRightarrow}\ e{\isachardoublequoteclose}\\[4pt]
\isacommand{definition}\ interpret{\isacharunderscore}op\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ operation\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ state\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ state\ option{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}interpret{\isacharunderscore}op\ oper\ state\ {\isasymequiv}\\
~~~~~~~~let\>before\>{\isacharequal}\ state\ {\isacharparenleft}op{\isacharunderscore}elem\ oper{\isacharparenright}{\isacharsemicolon}\\
\>after\>{\isacharequal}\ case\ oper\ of \>Add\>i\>e\ {\isasymRightarrow}\ before\ {\isasymunion}\ {\isacharbraceleft}i{\isacharbraceright}\ {\isacharbar}\\
\>\>\>Rem\>is\>e\ {\isasymRightarrow}\ before\ {\isacharminus}\ is\\
~~~~~~~~in \>Some\ {\isacharparenleft}state\ {\isacharparenleft}{\isacharparenleft}op{\isacharunderscore}elem\ oper{\isacharparenright}\ {\isacharcolon}{\isacharequal}\ after{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
Here, $\isa{state}{\isacharparenleft}{\isacharparenleft}op{\isacharunderscore}elem\ oper{\isacharparenright}\ {\isacharcolon}{\isacharequal}\ \isa{after}{\isacharparenright}$ is Isabelle's syntax for pointwise function update.
A remove operation effectively undoes the prior additions of that element of the set, while leaving any concurrent or later additions of the same element unaffected.
When an element $e$ is concurrently added and removed, the identifier of the addition operation will not be in the identifier set of the removal operation.
As a result, the final state after interpreting these two operations will contain the element $e$.

As the last part of specifying ORSet, we must require that $\isa{Add}$ and $\isa{Rem}$ use identifiers correctly.
We require the identifier of $\isa{Add}$ operations to be globally unique, which we can express by making it equal to the unique ID of the message containing the operation (Section~\ref{sect.network.broadcast}).
A $\isa{Rem}$ operation must contain the set of addition identifiers in the node state at the moment when the $\isa{Rem}$ operation was issued.
We express these constraints using the following $\isa{valid-behaviours}$ predicate:
\begin{isabelle}
~~~~~~~~case\ msg\ of\ \={\isacharparenleft}i{\isacharcomma}\ Rem\ \=is\ \=e\kill
\isacommand{definition}\ valid{\isacharunderscore}behaviours\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ state\ {\isasymRightarrow}\ {\isacharprime}id\ {\isasymtimes}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}a{\isacharparenright}\ operation\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}valid{\isacharunderscore}behaviours\ state\ msg\ {\isasymequiv}\\
~~~~~~~~case\ msg\ of \>{\isacharparenleft}i{\isacharcomma}\ Add\>j\>e{\isacharparenright}\ {\isasymRightarrow}\ i\ {\isacharequal}\ j\ {\isacharbar}\\
\>{\isacharparenleft}i{\isacharcomma}\ Rem\>is\>e{\isacharparenright}\ {\isasymRightarrow}\ is\ {\isacharequal}\ state\ e{\isachardoublequoteclose}
\end{isabelle}
To prove that ORSet satisfies the specification of strong eventual consistency, we follow the same pattern as before.
We first define a locale $\isa{orset}$ that extends $\isa{network-with-constrained-ops}$:
\begin{isabelle}
\isacommand{locale}\ orset\ {\isacharequal}\ network{\isacharunderscore}with{\isacharunderscore}constrained{\isacharunderscore}ops\ {\isacharunderscore}\ interpret{\isacharunderscore}op\ {\isachardoublequoteopen}{\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isacharbraceleft}{\isacharbraceright}{\isacharparenright}{\isachardoublequoteclose}\ valid{\isacharunderscore}behaviours
\end{isabelle}

\noindent
Recall the requirements of the $\isa{strong-eventual-consistency}$ specification (Section~\ref{sect.abstract.sec.spec}).
Firstly, we must show that $\isa{apply-operations}$ never fails, which is easy in this case, since the interpretation function never returns $\isa{None}$:
\begin{isabelle}
\isacommand{theorem}\ apply{\isacharunderscore}operations{\isacharunderscore}never{\isacharunderscore}fails{\isacharcolon}\\
~~~~\isakeyword{shows}\ {\isachardoublequoteopen}hb.apply{\isacharunderscore}operations\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ i{\isacharparenright}{\isacharparenright}\ {\isasymnoteq}\ None{\isachardoublequoteclose}
\end{isabelle}
\noindent Secondly, we must show that concurrent operations commute.
Isabelle's proof automation can easily verify that two addition operations commute unconditionally, as do two removal operations:
\begin{isabelle}
\isacommand{lemma}\ add{\isacharunderscore}add{\isacharunderscore}commute{\isacharcolon}\\
~~~~\isakeyword{shows}\ {\isachardoublequoteopen}{\isasymlangle}Add\ i{\isadigit{1}}\ e{\isadigit{1}}{\isasymrangle}\ {\isasymrhd}\ {\isasymlangle}Add\ i{\isadigit{2}}\ e{\isadigit{2}}{\isasymrangle}\ {\isacharequal}\ {\isasymlangle}Add\ i{\isadigit{2}}\ e{\isadigit{2}}{\isasymrangle}\ {\isasymrhd}\ {\isasymlangle}Add\ i{\isadigit{1}}\ e{\isadigit{1}}{\isasymrangle}{\isachardoublequoteclose}\\[4pt]
\isacommand{lemma}\ rem{\isacharunderscore}rem{\isacharunderscore}commute{\isacharcolon}\\
~~~~\isakeyword{shows}\ {\isachardoublequoteopen}{\isasymlangle}Rem\ i{\isadigit{1}}\ e{\isadigit{1}}{\isasymrangle}\ {\isasymrhd}\ {\isasymlangle}Rem\ i{\isadigit{2}}\ e{\isadigit{2}}{\isasymrangle}\ {\isacharequal}\ {\isasymlangle}Rem\ i{\isadigit{2}}\ e{\isadigit{2}}{\isasymrangle}\ {\isasymrhd}\ {\isasymlangle}Rem\ i{\isadigit{1}}\ e{\isadigit{1}}{\isasymrangle}{\isachardoublequoteclose}
\end{isabelle}
\noindent However, add and remove operations commute only if the identifier of the addition is not one of the identifiers affected by the removal:
\begin{isabelle}
~~~~\isakeyword{assumes}\ \=\kill
\isacommand{lemma}\ add{\isacharunderscore}rem{\isacharunderscore}commute{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}i\ {\isasymnotin}\ is{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}{\isasymlangle}Add\ i\ e{\isadigit{1}}{\isasymrangle}\ {\isasymrhd}\ {\isasymlangle}Rem\ is\ e{\isadigit{2}}{\isasymrangle}\ {\isacharequal}\ {\isasymlangle}Rem\ is\ e{\isadigit{2}}{\isasymrangle}\ {\isasymrhd}\ {\isasymlangle}Add\ i\ e{\isadigit{1}}{\isasymrangle}{\isachardoublequoteclose}
\end{isabelle}

Proving that the assumption $\isa{i} \mathbin{\isasymnotin} \isa{is}$ holds for all concurrent $\isa{Add}$ and $\isa{Rem}$ operations is a bit more laborious.
We define \isa{added-ids} to be the identifiers of all $\isa{Add}$ operations in a list of delivery events, even if those elements are subsequently removed.
Then we prove that the set of identifiers in the node state is a subset of \isa{added-ids} (since $\isa{Add}$ operations only ever add identifiers to the node state, and $\isa{Rem}$ operations only ever remove identifiers):
\begin{isabelle}
~~~~\isakeyword{assumes}\ \=\kill
\isacommand{lemma}\ apply{\isacharunderscore}operations{\isacharunderscore}added{\isacharunderscore}ids{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}{\isasymexists}suf{\isachardot}\ pre\ {\isacharat}\ suf\ {\isacharequal}\ history\ i{\isachardoublequoteclose}\\
~~~~~~~~\isakeyword{and}\>{\isachardoublequoteopen}apply{\isacharunderscore}operations\ pre\ {\isacharequal}\ Some\ state{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}state\ e\ {\isasymsubseteq}\ set\ {\isacharparenleft}added{\isacharunderscore}ids\ pre\ e{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
\noindent From this lemma, we deduce that when an $\isa{Add}$ and a $\isa{Rem}$ operation are concurrent, the identifier of the $\isa{Add}$ cannot be in the set of identifiers removed by $\isa{Rem}$:
\begin{isabelle}
~~~~\isakeyword{assumes}\ \={\isachardoublequoteopen}Rem\ \=is\ \=e{\isadigit{2}}\ \={\isasymin}\kill
\isacommand{lemma}\ concurrent{\isacharunderscore}add{\isacharunderscore}remove{\isacharunderscore}independent{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}{\isacharparenleft}Add\ i\ e{\isadigit{1}}{\isacharparenright}\ $\|$ {\isacharparenleft}Rem\ is\ e{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\ \\
~~~~~~~~\isakeyword{and}\>{\isachardoublequoteopen}Add\>i\>e{\isadigit{1}}\>{\isasymin}\ set\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ j{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\\
~~~~~~~~\isakeyword{and}\>{\isachardoublequoteopen}Rem\>is\>e{\isadigit{2}}\>{\isasymin}\ set\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ j{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}i\ {\isasymnotin}\ is{\isachardoublequoteclose}
\end{isabelle}
\noindent Now that we have proved that the assumption of $\isa{add-rem-commute}$ holds for all concurrent operations, we can deduce that all concurrent operations commute:
\begin{isabelle}
\isacommand{theorem}\ concurrent{\isacharunderscore}operations{\isacharunderscore}commute{\isacharcolon}\\
~~~~\isakeyword{shows}\ \ {\isachardoublequoteopen}hb{\isachardot}concurrent{\isacharunderscore}ops{\isacharunderscore}commute\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ i{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}

Having proved $\isa{apply-operations-never-fails}$ and $\isa{concurrent-operations-commute}$, we can now immediately prove that $\isa{orset}$ is a sublocale of $\isa{strong-eventual-consistency}$, using the familiar proof pattern from the other CRDTs.
This proof produces concrete convergence and progress theorems for the ORSet.


\section{Problem Definition}
\subsection{Graph Problems}
\begin{frame}{The Problem Presented as Graphs}
\framesubtitle{How?}
	\begin{itemize}
		\item Nodes are devices
		\item Edges indicate which devices a device is in range of
	\end{itemize}
\end{frame}

\begin{frame}{The Problem Presented as Graphs}
\framesubtitle{How?}
\begin{figure}
\centering
\begin{tikzpicture}  [
        node distance = 1 cm,
        vertex/.style = {circle, draw, fill=blue!10},
        label/.style={fill=white},
        <->
    ]

    \node[draw=none](0){};
    \node[vertex, left  = 2cm of 0]   (1) {$v_1$};
    \node[vertex, above =     of 0]   (2) {$v_2$};
    \node[vertex, right = 2cm of 0]   (3) {$v_3$};
    \node[vertex, below =     of 0]   (4) {$v_4$};

    \draw (1) -- (2);
    \draw (1) -- (3);
    \draw (1) -- (4);
    \draw (2) -- (3);
    \draw (2) -- (4);
    \draw (3) -- (4);

\end{tikzpicture}
\end{figure}
Completely Connected Reliable Communication (CCRC)
\end{frame}

\begin{frame}{The Problem Presented as Graphs}
\framesubtitle{How?}
\begin{figure}
\centering
\begin{tikzpicture}  [
        node distance = 1 cm,
        vertex/.style = {circle, draw, fill=blue!10},
        label/.style={fill=white},
        <->
    ]

    \node[draw=none](0){};
    \node[vertex, left  = 2cm of 0]   (1) {$v_1$};
    \node[vertex, above =     of 0]   (2) {$v_2$};
    \node[vertex, right = 2cm of 0]   (3) {$v_3$};
    \node[vertex, below =     of 0]   (4) {$v_4$};

    \draw (1) -- (2);
    \draw (1) -- (4);
    \draw (2) -- (3);
    \draw (2) -- (4);
    \draw (3) -- (4);

\end{tikzpicture}
\end{figure}
Strongly Connected Reliable Communication (SCRC)
\end{frame}

\begin{frame}{The Problem Presented as Graphs}
\framesubtitle{How?}
    \begin{itemize}
        \item Nodes are devices
        \item Edges indicate which devices a device is in range of
        \item Weights indicate the chance of a transmission being received
    \end{itemize}
\end{frame}

\begin{frame}{The Problem Presented as Graphs}
\framesubtitle{How?}
\begin{figure}
\centering
\begin{tikzpicture} [
        node distance = 1 cm,
        vertex/.style = {circle, draw, fill=blue!10},
        edge/.style = {draw, -stealth, shorten >= 1pt},
        label/.style={fill=white}
    ]

    \node[draw=none](0){};
    \node[vertex, left =  3cm of 0]   (1) {$v_1$};
    \node[vertex, above=  2cm of 0]   (2) {$v_2$};
    \node[vertex, right=  3cm of 0]   (3) {$v_3$};
    \node[vertex, below=  2cm of 0]   (4) {$v_4$};

    \path[edge] (1) edge[bend left=15] node [label] {0.7} (2) edge[bend left=15] node [label] {0.5} (4);
    \path[edge] (1) edge[bend left=15] node [label] {0.7} (2) edge[bend left=15] node [label] {0.3} (3);
    \path[edge] (3) edge[bend left=15] node [label] {0.7} (2) edge[bend left=15] node [label] {0.3} (1);
    \path[edge] (2) edge[bend left=15] node [label] {0.7} (1) edge[bend left=15] node [label] {0.5} (4);
    \path[edge] (4) edge[bend left=15] node [label] {0.7} (1) edge[bend left=15] node [label] {0.5} (2);
    \path[edge] (2) edge[bend left=15] node [label] {0.8} (1) edge[bend left=15] node [label] {0.7} (3);
    \path[edge] (3) edge[bend left=15] node [label] {0.9} (2) edge[bend left=15] node [label] {0.8} (4);
    \path[edge] (4) edge[bend left=15] node [label] {0.4} (1) edge[bend left=15] node [label] {0.8} (3);

\end{tikzpicture}
\end{figure}
Completely Connected Unreliable Communication (CCUC)
\end{frame}

\begin{frame}{The Problem Presented as Graphs}
\framesubtitle{How?}
\begin{figure}
\centering
\begin{tikzpicture} [
        node distance = 1 cm,
        vertex/.style = {circle, draw, fill=blue!10},
        edge/.style = {draw, -stealth, shorten >= 1pt},
        label/.style={fill=white}
    ]

    \node[draw=none](0){};
    \node[vertex, left =  2cm of 0]   (1) {$v_1$};
    \node[vertex, above=      of 0]   (2) {$v_2$};
    \node[vertex, right=  2cm of 0]   (3) {$v_3$};
    \node[vertex, below=      of 0]   (4) {$v_4$};

    \path[edge] (1) edge[bend left=15] node [label] {0.7} (2) edge[bend left=15] node [label] {0.5} (4);
    \path[edge] (2) edge[bend left=15] node [label] {0.8} (1) edge[bend left=15] node [label] {0.7} (3);
    \path[edge] (3) edge[bend left=15] node [label] {0.9} (2) edge[bend left=15] node [label] {0.8} (4);
    \path[edge] (4) edge[bend left=15] node [label] {0.4} (1) edge[bend left=15] node [label] {0.8} (3);

\end{tikzpicture}
\end{figure}
Strongly Connected Unreliable Communication (SCUC)
\end{frame}

\begin{frame}{Time Division Multiple Access(TDMA)}
\subsection{TDMA Problem}
\framesubtitle{The generic method}
\begin{itemize}
	\item One frequency
	\item Using the frequency in turns
	\item Frame and time-slots
\end{itemize}
\vspace{-15pt}
\begin{figure}
\centering
\begin{tikzpicture}[thick,scale=0.6, every node/.style={scale=0.6}]
    \path[draw] (-5,0) -- (-5,1) -- (5,1) -- (5,0) -- (-5,0)
                (-3,1) -- (-3,0)
                (-1,1) -- (-1,0)
                (1,1) -- (1,0)
                (3,1) -- (3,0);

    \node at (-4,0.5) {Device A};
    \node at (-2,0.5) {Device B};
    \node at (0,0.5) {Device C};
    \node at (2,0.5) {Device D};
    \node at (4,0.5) {Device E};

    \path[draw, dashed] (-1,1) -- (-5,2)
                        (1,1) -- (5,2);

    \path[draw] (-5,2) -- (-5,3) -- (5,3) -- (5,2) -- (-5,2)
                (-3.8,2) -- (-3.8,3)
                (-2.6,2) -- (-2.6,3)
                (-1.2,2) -- (-1.2,3)
                (4,2) -- (4,3);

    \node[text width=1cm, align=center] at (-4.4,2.5) {Guard\\time};
    \node at (-3.2,2.5) {Sync};
    \node at (-1.9,2.5) {Control};
    \node at (1.5,2.5) {Transmission Data};
    \node[text width=1cm, align=center] at (4.5,2.5) {CRC\\check};

    \path (-5,4) -- node{\textbf{(b)} Typical time slot (some fields may not be used)} (5,3);

    \path (5,-1) -- node{\textbf{(a)} A frame with five time slots} (-5,0);
\end{tikzpicture}
\end{figure}
\vspace{-15pt}
For our project:
	\begin{itemize}
		\item Devices should be able to join
		\item The number of devices are not known in advance
	\end{itemize}
\end{frame}

\section{CCRC}
\begin{frame}{Design of CCRC}
\framesubtitle{Changes from generic TDMA}

\begin{itemize}
	\item The TDMA solution for CCRC
	\item Joining devices wait for Empty-Slot and then connects to the network
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}[thick,scale=0.6, every node/.style={scale=0.6}]
    \path[draw] (-5,0) -- (-5,1) -- (5,1) -- (5,0) -- (-5,0)
                (-3,1) -- (-3,0)
                (-1,1) -- (-1,0)
                (1,1) -- (1,0)
                (3,1) -- (3,0);

    \node at (-4,0.5) {Device A};
    \node at (-2,0.5) {Device B};
    \node at (0,0.5) {Device C};
    \node at (2,0.5) {Device D};
    \node at (4,0.5) {Empty-Slot};

    \path[draw, dashed] (-1,1) -- (-5,2)
                        (1,1) -- (6.7,2);

    \path[draw] (-5,2) -- (-5,3) -- (6.6,3) -- (6.6,2) -- (-5,2)
                (-1,2) -- (-1,3)
                (5,2) -- (5,3)
                (1,2) -- (1,3)
                (-3,2) -- (-3,3);

    \node at (-4,2.5) {Guard time};
    \node at (-2,2.5) {ASK Sync};
    \node at (0,2.5) {Control};
    \node at (3,2.5) {Transmission Data};
     \node[text width=1cm, align=center] at (5.8,2.5) {CRC\\check};

    \path[draw, dashed] (1,3) -- (-6,4)
                        (5,3) -- (7.5,4);

    \path[draw] (-6,4) -- (-6,5) -- (7.5,5) -- (7.5,4) -- (-6,4)
    			(-3.4,4) -- (-3.4,5)
    			(-1.2,4) -- (-1.2,5)
    			(0.8,4) -- (0.8,5);

    \node at (-4.7,4.5) {Current Slot};
    \node at (-2.3,4.5) {Slot Count};
    \node[text width=1cm, align=center] at (-0.35,4.5) {Address};
    \node[text width=1cm, align=center] at (4.0,4.5) {Data};

    \path (5,-1) -- node{Figure is not to scale} (-5,0);

\end{tikzpicture}
\end{figure}
\begin{itemize}
\item Presentation of CCRC in UPPAAL
\end{itemize}
\end{frame}


\subsection{Times Table} % (fold)
\label{sub:times_table_flow}

This program prints out the times table for a number entered by the user, displaying from 1 x n to 10 x n. The description of the program is in Table \ref{tbl:flow-times-table}, the pseudocode in Listing \ref{lst:flow-times-pseudo}, the C code in Listing \ref{lst:flow-times-c}, and the Pascal code in Listing \ref{lst:flow-times-pas}.

\begin{table}[h]
\centering
\begin{tabular}{l|p{10cm}}
  \hline
  \multicolumn{2}{c}{\textbf{Program Description}} \\
  \hline
  \textbf{Name} & \emph{Times Table} \\
  \\
  \textbf{Description} & Displays the Times Table from 1 x n to 10 x n. \\
  \hline
\end{tabular}
\caption{Description of the Times Table program}
\label{tbl:flow-times-table}
\end{table}

\pseudocode{lst:flow-times-pseudo}{Pseudocode for Times Table program.}{./topics/control-flow/examples/times-table.txt}

\mynote{
This is an updated version of the Seven Times Table Program. See \sref{sub:times_table} \nameref{sub:times_table}.
}

\clearpage

\csection{\ccode{lst:flow-times-c}{C Times Table}{topics/control-flow/examples/times_table.c}}

\passection{\pascode{lst:flow-times-pas}{Pascal Times Table}{topics/control-flow/examples/TimesTable.pas}}

% subsection times_table (end)

\clearpage
\subsection{Circle Area} % (fold)
\label{sub:circle_area_control_flow}

This program prints out the area of a circle. The description of the program is in Table \ref{tbl:flow-circle-area}, the pseudocode in Listing \ref{lst:flow-circle-areas-pseudo}, the C code in Listing \ref{lst:flow-circle-areas-c}, and the Pascal code in Listing \ref{lst:flow-circle-areas-pas}.

\begin{table}[h]
\centering
\begin{tabular}{l|p{10cm}}
  \hline
  \multicolumn{2}{c}{\textbf{Program Description}} \\
  \hline
  \textbf{Name} & \emph{Circle Areas} \\
  \\
  \textbf{Description} & Displays the Circle Areas for circles with radius from 1.0 to 5.0 with increments of 0.1. \\
  \hline
\end{tabular}
\caption{Description of the Circle Areas program}
\label{tbl:flow-circle-area}
\end{table}

\pseudocode{lst:flow-circle-areas-pseudo}{Pseudocode for Circle Areas program.}{./topics/control-flow/examples/circle_areas.txt}

\mynote{
This is an updated version of the Circle Areas Program. See Section \ref{sub:circle_area_data} \nameref{sub:circle_area_data}.
}

\clearpage

\csection{\ccode{lst:flow-circle-areas-c}{C Circle Areas}{topics/control-flow/examples/circle_areas.c}}

\passection{\pascode{lst:flow-circle-areas-pas}{Pascal Circle Areas}{topics/control-flow/examples/CircleAreas.pas}}

% subsection circle_area (end)

\clearpage
\subsection{Moving Rectangle} % (fold)
\label{sub:moving_rectangle}

This example SwinGame code will move a rectangle back and forth across the screen.

\begin{table}[h]
\centering
\begin{tabular}{l|p{10cm}}
  \hline
  \multicolumn{2}{c}{\textbf{Program Description}} \\
  \hline
  \textbf{Name} & \emph{Moving Rectangle} \\
  \\
  \textbf{Description} & Displays a rectangle that is moved back and forth across the screen. \\
  \hline
\end{tabular}
\caption{Description of the Moving Rectangle program}
\label{tbl:flow-moving-rect}
\end{table}

\begin{figure}[h]
   \centering
   \includegraphics[width=0.8\textwidth]{./topics/control-flow/examples/MovingRect.png}
   \caption{Example execution of the Moving Rectangle program}
   \label{fig:moving-rect-img}
\end{figure}

\clearpage

\cppsection{\ccode{clst:moving-rect}{C++ Moving Rect SwinGame code}{topics/control-flow/examples/moving-rect.cpp}}

\passection{\pascode{plst:moving-rect}{Pascal Moving Rect SwinGame code}{topics/control-flow/examples/MovingRect.pas}}

% subsection moving_rectangle (end)

\clearpage
\subsection{Button Click in SwinGame} % (fold)
\label{sub:button_click_in_swingame}

This example SwinGame code draws a rectangle that the user can `click'.

\begin{table}[h]
\centering
\begin{tabular}{l|p{10cm}}
  \hline
  \multicolumn{2}{c}{\textbf{Program Description}} \\
  \hline
  \textbf{Name} & \emph{Button Click} \\
  \\
  \textbf{Description} & Displays a rectangle the user can `click'. Having the mouse held down over the rectangle changes it to a filled rectangle. Clicking the rectangle shows the text `Clicked' in the top left corner. \\
  \hline
\end{tabular}
\caption{Description of the Button Click program}
\label{tbl:flow-button-click}
\end{table}

\begin{figure}[h]
   \centering
   \includegraphics[width=0.8\textwidth]{./topics/control-flow/examples/ButtonClick.png}
   \caption{Example execution of the Button Click program}
   \label{fig:button-click-img}
\end{figure}

\clearpage

\cppsection{\ccode{clst:swingame_button}{C++ Simple Button using SwinGame code}{topics/control-flow/examples/button-click.cpp}}

\passection{\pascode{plst:button-click}{Pascal Button Click code}{topics/control-flow/examples/ButtonClick.pas}}

% subsection button_click_in_swingame (end)

% \clearpage
% \subsection{Rocket Launch} % (fold)
% \label{sub:rocket_launch}
%
% \cppsection{\ccode{clst:rocket_launch}{C++ Rocket Launch using SwinGame code (Continues in \lref{clst:rocket_launch1}) }{topics/control-flow/examples/rocket_launch.cpp}}
%
% \begin{figure}[p]
%   \cppsection{\ccode{clst:rocket_launch1}{C++ Rocket Launch using SwinGame code (cont.) }{topics/control-flow/examples/rocket_launch1.cpp}}
% \end{figure}
%
% \begin{figure}[p]
%   \cppsection{\ccode{clst:rocket_launch2}{C++ Rocket Launch using SwinGame code (cont.) }{topics/control-flow/examples/rocket_launch2.cpp}}
% \end{figure}
%
%
% % subsection rocket_launch (end)


%% Introduction %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}
\label{sec:intro}

% What is essential to say?

In this paper, we present a decision procedure for solving systems of
integer linear constraints where each expression is subject
to both upper and lower bounds.  Such systems have the form:
%
\begin{equation}
    \label{eq:prob-inequalities}
    \begin{array}{ccccc}
        l_1    & \le & a_{11} x_1 + \cdots + a_{1n} x_n & \le & u_1 \\
        l_2    & \le & a_{21} x_1 + \cdots + a_{2n} x_n & \le & u_2 \\
        \vdots &     & \vdots                         &     & \vdots \\
        l_m    & \le & a_{m1} x_1 + \cdots + a_{mn} x_n & \le & u_m
    \end{array}
\end{equation}
%
where $l_i, u_i, a_{ij}$ are rational constants and the $x_i$ are unknown
integer variables.
%
As a more compact notation, we use $\v{l} \le \mat{A} \v{x} \le \v{u}$
to denote systems with this form.

% The problem is also
%known as \emph{integer linear programming} (ILP), though we are only concerned
%with the feasibility question here.

Our decision procedure is based on a variant of the Schnorr-Euchner
algorithm~\cite{Schnorr-Euchner} for computing the closest lattice
element to a target point, and is implemented in a tool which we call
\emph{BLT}.  The decision procedure reduces the constraint problem to
the problem of checking whether there is a common point $\v{y}$ in
both the lattice $\mathcal{L}_{\mat{A}}$ generated by the columns of $\mat{A}$
and the hyperrectangle containing the points between $\v{l}$ and
$\v{u}$.

%BLT does this by
%rescaling the coefficients in $\v{l}$, $\v{u}$ and $\mat{A}$
%attempting to find the lattice point closest (with respect to the $\linf{}$-norm) to
%the point $p$ in the center of the hyperrectangle.

%The main difference is the algorithm uses the $L^\infty$-norm to compute distances while %Schnorr-Euchner uses the $L^2$-norm.  BLT first
%rescales the
% preprocesing the formula with the form~\eqref{eq:prob-inequalities}, BLT computes the center %point $P$ of the hyperrectangle containing the points between $L$ and $U$.  To check %satisfiability, BLT attempts to find an assignment to $\v{x} \in \ZZ^n$ such that $A\v{x}$ is
%the closest point to $\v{P}$ in the lattice generated by the columns of $A$.
%If during the search BLT can find a point $A \v{x}$ inside the hyperrectangle defined
%by $L$ and $U$, then BLT returns SAT with the coefficients $\v{x}$.  If it can prove
%no such point exists, then it returns UNSAT.

We developed BLT while trying to apply constraint solving to signal
processing algorithms.  In particular, we were studying the problem of
\emph{reversing JPEG decompression}, that is finding JPEGs that decompress
into images that satisfy given constraints.  This could be used to encode
specific values on pixels in the image, perhaps for steganographic purposes.
As we will show, this problem can be expressed as an integer linear constraint
problem with the form~\eqref{eq:prob-inequalities} over $64$ variables.

Before developing BLT, we had generated various instances of this
problem, including both unsatisfiable and satisfiable cases.  We
applied several SMT solvers, including Yices~\cite{Dutertre:cav2014},
CVC4~\cite{DBLP:conf/cav/BarrettCDHJKRT11}, and
Z3~\cite{DeMoura:2008:ZES:1792734.1792766}, as well as an evaluation
version of Gurobi\footnote{Available
  at~\url{http://www.gurobi.com/}.}, an industrial linear programming
solver. The solvers we tried were incapable of solving
all but the most trivial instances of this problem without giving
additional hints. This was true even when after running some of the
problems for months on selected solvers.  In contrast, BLT is able to
solve the majority of the problems in under a second.

%For problems of this shape, we have found that our algorithm is able to solve problems in %seconds that are intractable to all other solvers that we have tried, including %
%  , but is non-trivial to solve; JPEG is a lossy compression algorithm.  Even if a set of %constraints is satisfiable on arbitrary images, it may not be accessible on images obtained %from decompressed images.

%The rest of the paper is organized as follows. First, we describe the lattice
%operations we use in Section~\ref{sec:preliminaries}. Then, we describe the
%algorithm in Section~\ref{sec:dp} and the JPEG preimage problem
%and performance of BLT on that problem in~\ref{sec:jpeg}.  Finally, we
%conclude with a brief discussion of related and future work in
%Section~\ref{sec:final}.


\section{Preliminaries and exploratory data analysis}

We start off by loading a useful support library, the \texttt{cluster} library.   We need to load the \texttt{flexclust} library to get hold of some interesting data.   Make that data available (the \texttt{milk} data) and start doing an exploratory data analysis.   The suggested code here includes star plots (quite interesting here) and faces (not very useful).   You may also consider parallel co-ordinates plots and scatterplots, but we will come back to them later.

\begin{Schunk}
\begin{Sinput}
> library(cluster)
> library(flexclust)
> library(MASS)
> library(TeachingDemos)
> data(milk)
> stars(milk, full = FALSE, draw.segments = TRUE, key.loc = c(10,
+     0.4), main = "Milk data")
> faces(milk, fill = TRUE, ncol = 4, scale = TRUE, nrow = 7)
\end{Sinput}
\end{Schunk}

\section{Calculating distances and performing hierarchical clustering}

The first piece of clustering will demonstrate the defaults, i.e. euclidean distance and complete linkage.   A good habit is to create a distance object, then create a \texttt{hclust} object and then extract whatever information we need from that \texttt{hclust} object.   For example, \texttt{plot()} will produce a dendrogram and \texttt{cutree()}, given an argument for \texttt{k} will ``cut'' the tree at the given number of clusters (you can also cut based on height if you prefer)

\begin{Schunk}
\begin{Sinput}
> milk.dist <- dist(milk)
> milk.hclust <- hclust(milk.dist)
> plot(milk.hclust)
> milk.cut <- cutree(milk.hclust, 3)
\end{Sinput}
\end{Schunk}

It is of interest investigating the stability of your cluster solution to different choices of distance measure, for example using the Manhattan distance:

\begin{Schunk}
\begin{Sinput}
> milk.dist.man <- dist(milk, method = "manhattan")
> milk.hclust.man <- hclust(milk.dist.man)
> plot(milk.hclust.man)
> milk.cut.man <- cutree(milk.hclust.man, 3)
> xtabs(~milk.cut + milk.cut.man)
\end{Sinput}
\end{Schunk}

or the Minkowski, with $\lambda=5$ (R calls this \texttt{p})

\begin{Schunk}
\begin{Sinput}
> milk.dist.min5 <- dist(milk, method = "minkowski", p = 5)
> milk.hclust.min5 <- hclust(milk.dist.min5)
> plot(milk.hclust.min5)
> milk.cut.min5 <- cutree(milk.hclust.min5, 3)
> xtabs(~milk.cut + milk.cut.min5)
\end{Sinput}
\end{Schunk}

Also, one may wish to consider different clustering strategies, in this case we consider Ward's method (based on the Euclidean distance):

\begin{Schunk}
\begin{Sinput}
> milk.hclust.ward <- hclust(milk.dist, method = "ward")
> plot(milk.hclust.ward)
> milk.cut.ward <- cutree(milk.hclust.ward, 3)
> xtabs(~milk.cut + milk.cut.ward)
\end{Sinput}
\end{Schunk}

You should actually find for these data, whatever you do yields quite a stable three cluster ``solution''.

\section{Visualising the solution in terms of the data}

We can use some standard exploratory data analysis techniques, only in this case it is possible to ``label'' the rows in terms of the cluster membership we have proposed:

\begin{Schunk}
\begin{Sinput}
> parcoord(milk, col = milk.cut, lty = milk.cut, main = "milk data, four group clustering")
> pairs(milk, lower.panel = function(x, y) {
+     points(x, y, pch = milk.cut, col = milk.cut)
+ }, main = "Scatterplot for milk data")
\end{Sinput}
\end{Schunk}

\section{k-means clustering}

k-means clustering assumes we have some idea of $k$ before we start.   In this example, we seem to be quite sure that $k=3$, that won't necessarily be the case with other problems.   The \texttt{kmeans} object contains other information about the solution, such as the centroids, but the cluster assignments are easily extracted and compared with the solutions we found earlier.

\begin{Schunk}
\begin{Sinput}
> milk.kmeans <- kmeans(milk, centers = 3)
> milk.kmeans$cluster
> xtabs(~milk.cut + milk.kmeans$cluster)
\end{Sinput}
\end{Schunk}

Do note that k-means clustering is applied to the \emph{data} and \emph{not} to the distance matrix!!!!!!

\section{Measures of fit}

This is a massive area.   We consider just one possibility amongst many based on the cophenetic distance, a measure of the distance between the level at which two points are merged.   Measuring the correlation between this distance and the original distance matrix tells us something about how well a given dendrogram represents a given distance matrix.

\begin{Schunk}
\begin{Sinput}
> d.retained <- cophenetic(milk.hclust)
> cor(milk.dist, d.retained)
\end{Sinput}
\end{Schunk}

(Too) many more possibilities are given in \texttt{cluster.stats()} in \texttt{library(fpc)}.   One of the more common ones is the Rand statistic, which can be used to compare two cluster solutions.   Again, we supply the original distance matrix, and then the cluster solution we have chosen and an alternative.   You should find with the milk data that the Rand statistic = 1, as these solutions agree perfectly.  The helpfile for this function gives you references to the literature if you want to know what all the other statsitics are measuring.

\begin{Schunk}
\begin{Sinput}
> library(fpc)
> cluster.stats(milk.dist, milk.cut, alt = milk.cut.man)
\end{Sinput}
\end{Schunk}

\section{Summary}

\fbox{\parbox[c]{0.9\textwidth}{\color{blue}
This week, we should have:

\begin{itemize}
\item Quickly carried out an e.d.a. using scripts saved from week 1 in order to look for similar subgroups within a dataset
\item Carried out cluster analysis using a variety of hierarchical schemes as well as k-means clustering
\item be able to describe the difference between hierarchical and k-means clustering; and to demonstrate this understanding by working simple examples by hand
\item be able to interpret the results of a cluster analysis; and  explain whether a particular hierarchical cluster analysis can be considered a ``good'' fit
\end{itemize}
}}


\documentclass{article}
\usepackage{amsmath,amssymb,amsfonts}
\begin{document}
\title{LIP-BFGS Theory}
\author{Jesse Lu}
\maketitle
\tableofcontents

\section{Introduction}
The acronym LIP-BFGS stands for
  Limited-memory Interior-Point Broyden-Fletcher-Goldfarb-Shanno.
It is simply an interior-point (IP) method which uses the
  limited-memory BFGS (L-BFGS) algorithm.
The main body of the algorithm is described in Chapter 19.3 of \cite{NW04}.

The purpose of this document is
  to allow the user to understand the accompanying \textsc{Matlab}
  implementation.

\part{Theory}
\section{Theory for the interior-point method}
Interior-point methods attempt to minimize $f(x)$
    subject to the equality and inequality constraints $c_E(x)$ and $c_I(x)$,
\begin{subequations}
\begin{align}
\text{minimize} \quad & f(x) \\
\text{subject to} \quad & c_E(x) = 0 \\
                        & c_I(x) \ge 0,
\end{align}
\end{subequations}
    by satisfying the Karush-Kuhn-Tucker (KKT) conditions
    (see Chapter 12.3 of \cite{NW04})
\begin{subequations}\begin{align}
    \nabla f(x) - A_E^T(x) y - A_I^T(x) z &= 0 \label{Lagrangian} \\
    z - \mu s^{-1} &= 0 \\
    c_E(x) &= 0 \\
    c_I(x) - s &= 0 \\
    s &\ge 0 \\
    z &\ge 0,
\end{align}\end{subequations}
    where
\begin{subequations}\begin{align}
    A_E(x) &= \nabla c_E(x), \quad\text{the Jacobian of $c_E(x)$} \\
    A_I(x) &= \nabla c_I(x), \quad\text{the Jacobian of $c_I(x)$}
\end{align}\end{subequations}
    $y$ and $z$ are the dual variables for $c_E(x)$ and $c_I(x)$ respectively,
    and $s$ is the slack variable.
Note that the expression $s^{-1}$
    refers to the element-wise inverse of the vector $s$.
Also, the expression in \eqref{Lagrangian} can also be written as
    $\nabla_x \mathcal{L} = 0$,
    where $\mathcal{L}$ is the Lagrangian of the problem.

As taken from Chapter 19.3 of \cite{NW04},
    the interior point method obtains step direction $p$ by solving
\begin{equation}
\begin{bmatrix}
    \nabla^2_{xx}\mathcal{L} & 0 & A_E^T(x) & A_I^T(x) \\
    0 & \Sigma & 0 & -I \\
    A_E(x) & 0 & 0 & 0 \\
    A_I(x) & -I & 0 & 0
\end{bmatrix}
\begin{bmatrix} p_x \\ p_s \\ -p_y \\ -p_z \end{bmatrix}
    = -
\begin{bmatrix}
    \nabla f(x) - A_E^T(x) y - A_I^T(x) z \\
    z - \mu s^{-1} \\
    c_E(x) \\
    c_I(x) - s
\end{bmatrix}.
\end{equation}
    where
\begin{equation} \Sigma = \text{diag}(z/s).\end{equation}
This equation can be simplified by
    first backsubstituting for $p_s$ and then for $p_z$.
The reduced system is then
\begin{multline}
\begin{bmatrix}
    \nabla^2_{xx}\mathcal{L} + A_I^T(x) \Sigma A_I^T(x) & A_E^T(x) \\
    A_E(x) & 0
\end{bmatrix}
\begin{bmatrix} p_x \\ -p_y \end{bmatrix}
    = -
\begin{bmatrix}
    \nabla f(x) - A_E^T(x) y - A_I(x) h \\
    c_E(x)
\end{bmatrix},
\end{multline}
    where
\begin{equation} h = z - \Sigma c_I(x) + \mu s^{-1} \end{equation}
    and
\begin{subequations}\begin{align}
    p_s &= A_I(x) p_x + c_I(x) - s \\
    p_z &= -\Sigma A_I(x) p_x - \Sigma c_I(x) + \mu s^{-1}.
\end{align}\end{subequations}

We now choose to consider only
    simple bound inequality constraints $l \le x \le u$, and
    affine equality constraints $A x - b = 0$.
Our problem can then be written down as
\begin{equation}
\begin{bmatrix}
    \nabla^2 f(x) + \Sigma_0 + \Sigma_1 & A^T \\
    A & 0
\end{bmatrix}
\begin{bmatrix} p_x \\ -p_y \end{bmatrix}
    = -
\begin{bmatrix}
    \nabla f(x) - A^T y + h_0 + h_1 \\ A x - b
\end{bmatrix},
\label{IP}
\end{equation}
    where
    \begin{subequations}\begin{align}
    \Sigma_0 &= \text{diag}(z_0 / s_0) \\
    \Sigma_1 &= \text{diag}(z_1 / s_1),
    \end{align}\end{subequations}
    and
    \begin{subequations}\begin{align}
    h_0 &= -z_0 + \Sigma_0 (x - l) - \mu s_0^{-1} \\
    h_1 &= z_1 - \Sigma_1 (u - x) + \mu s_1^{-1},
    \end{align}\end{subequations}
    and the other components of $p$ are
\begin{subequations}\begin{align}
    p_{s_0} &= p_x + (x - l) - s_0 \\
    p_{z_0} &= -\Sigma_0 p_x - \Sigma_0 (x - l) + \mu s_0^{-1} \\
    p_{s_1} &= -p_x + (u - x) - s_1 \\
    p_{z_1} &= \Sigma_1 p_x - \Sigma_1 (u - x) + \mu s_1^{-1}.
\end{align}\label{p_other}\end{subequations}

\section{Theory for the limited-memory BFGS algorithm}
Practically, computing and solving for $\nabla^2 f(x)$ in \eqref{IP},
    the \emph{Hessian} of $f(x)$, is often computationally challenging.
For this reason, we use the
    limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) algorithm
    to approximate $\nabla^2 f(x)$.
Specifically, we use the compact or outer-product representation of
    \begin{equation} B \sim \nabla^2 f(x), \end{equation}
    as described in chapter 7.2 of \cite{NW04},
    to efficiently solve for $p$ in \eqref{IP}.

The BFGS algorithm works by approximating the Hessian of function
    based on a list of the previous values of $x$ and $\nabla f(x)$.
The approximate Hessian, $B$, is recursively updated by the following formula,
    taken from chapter 6.1 of \cite{NW04},
    \begin{equation}
    B_{k+1} = B_k - \frac{B_k s_k s_k^T B_k}{s_k^T B_k s_k} +
            \frac{y_k y_k^T}{y_k^T s_k},
    \end{equation}
    where
    \begin{subequations}\begin{align}
    s_k &= x_{k+1} - x_k \\
    y_k &= \nabla f(x_{k+1}) - \nabla f(x_k).
    \end{align}\end{subequations}

The limited-memory BFGS algorithm simply truncates the list of $(s_k, y_k)$
    to the most recent $m$ values,
    which allows us to store $B$ efficiently
    in what is called the compact or outer-product representation
    (see chapter 7.2 of \cite{NW04}):
    \begin{equation}
    B_k = B_0 -
        \begin{bmatrix} B_0 S_k & Y_k \end{bmatrix}
        \begin{bmatrix}
            S_k^T B_0 S_k & L_k \\
            L_k^T & -D_k
        \end{bmatrix}^{-1}
        \begin{bmatrix} S_k^T B_0^T \\ Y_k^T \end{bmatrix},
    \end{equation}
    where $B_0$ is an initial guess for $B$,
    \begin{subequations}\begin{align}
        S_k &= [s_{k-m}, \ldots, s_{k-1}] \\
        Y_k &= [y_{k-m}, \ldots, y_{k-1}]
    \end{align}\end{subequations}
    and
    \begin{subequations}\begin{align}
        (L_k)_{i,j} &=
            \begin{cases}
                s_{i-1}^T y_{j-1} & \text{if $i > j$,} \\
                0 & \text{otherwise,}
            \end{cases} \\
        D_k &= \text{diag}([s_{k-m}^T y_{k-m}, \ldots, s_{k-1}^T y_{k-1}]).
    \end{align} \end{subequations}

Specifically, we choose
    \begin{equation} B_0 = \delta_k I, \end{equation}
    where $\delta_k$ is a scaling variable, given by
    \begin{equation}
        \delta_k = \frac{y_{k-1}^T y_{k-1}}{s_{k-1}^T y_{k-1}}.
    \end{equation}
This results in a computationally-efficient
    diagonal-plus-low-rank structure for $B_k$,
    \begin{equation}
    B_k = \delta_k I + W_k M_k W_k^T \label{lbfgs}
    \end{equation}
    where
    \begin{subequations}\begin{align}
        W_k &= \begin{bmatrix} \delta_k S_k & Y_k \end{bmatrix} \\
        M_k &=
            \begin{bmatrix}
                \delta_k S_k^T S_k & L_k \\
                L_k^T & -D_k
            \end{bmatrix}^{-1}.
    \end{align}\end{subequations}

Lastly, when $k = 0$ and there are no $(s_k, y_k)$ pairs
    with which to construct $B_k$,
    we simply choose $B_0 = I$.

\section{Efficiently solving an arrow-plus-low-rank system}
Substituting the expression for $B_k$ in \eqref{lbfgs} for
    $\nabla^2 f(x)$ in \eqref{IP} yields
    \begin{multline}
    \left(
    \begin{bmatrix}
        \delta_k I + \Sigma_0 + \Sigma_1 & A^T \\
        A & 0
    \end{bmatrix}
    +
    \begin{bmatrix} WM \\ 0 \end{bmatrix}
    \begin{bmatrix} W^T & 0 \end{bmatrix}
    \right)
    \begin{bmatrix} p_x \\ -p_y \end{bmatrix}
        \\ = -
    \begin{bmatrix}
        \nabla f(x) - A^T y + h_0 + h_1 \\ A x - b
    \end{bmatrix},\label{lipbfgs}
    \end{multline}
    which can be efficiently solved by taking advantage of the structure of
    the matrix
    \begin{equation}
    \begin{bmatrix}
        \delta_k I + \Sigma_0 + \Sigma_1 & A^T \\
        A & 0
    \end{bmatrix}
    +
    \begin{bmatrix} WM \\ 0 \end{bmatrix}
    \begin{bmatrix} W^T & 0 \end{bmatrix}. \label{aplr}
    \end{equation}

Such a matrix contains arrow-plus-low-rank structure;
    in the sense that the
    \begin{equation}
    \begin{bmatrix}
        \delta_k I + \Sigma_0 + \Sigma_1 & A^T \\
        A & 0
    \end{bmatrix} \label{arrow}
    \end{equation}
    term has ``arrow'' structure (pointing down and to the left)
    especially if $A$ is fat ($A \in \mathbb{R}^{m \times n}, m \ll n$),
    and that the
    \begin{equation}
    \begin{bmatrix} WM \\ 0 \end{bmatrix}
    \begin{bmatrix} W^T & 0 \end{bmatrix}.
    \end{equation}
    term is a low-rank matrix.

The arrow matrix can be efficiently solved via block substitution;
    meaning that we solve
    \begin{equation}
    \begin{bmatrix}
        \tilde{D} & A^T \\
        A & 0
    \end{bmatrix}
    \begin{bmatrix} x_1 \\ x_2 \end{bmatrix}
    =
    \begin{bmatrix} b_1 \\ b_2 \end{bmatrix}
    \end{equation}
    where
    \begin{equation} \tilde{D} = \delta_k I + \Sigma_0 + \Sigma_1 \end{equation}
    by computing, in order,
    \begin{subequations}\begin{align}
    A \tilde{D}^{-1} A^T x_2 &=
        A \tilde{D}^{-1} b_1 - b_2 \\
    x_1 &= \tilde{D}^{-1}
        (b_1 - A^T x_2).
    \end{align}\end{subequations}
This is computationally efficient because the term $A \tilde{D}^{-1} A^T$ is
    small, if the number of rows in $A$ is small,
    and therefore easy to invert.

Now that we can compute $\tilde{A}^{-1} b$,
    where $\tilde{A}$ is the arrow matrix in \eqref{arrow},
    we employ the matrix inversion lemma
    (also known as the Sherman-Woodbury-Morrison formula),
    which states
    \begin{equation}
    (A+UV^T)^{-1}b = A^{-1}b - A^{-1}U(I + V^T A^{-1}U)^{-1} V^T A^{-1}b,
    \end{equation}
    in order to solve the entire arrow-plus-low-rank system in \eqref{aplr},
    \begin{equation} \tilde{A} + \tilde{U}\tilde{V}^T \end{equation}
    where
    \begin{subequations}\begin{align}
    \tilde{U} &= \begin{bmatrix} WM \\ 0 \end{bmatrix} \\
    \tilde{V}^T &= \begin{bmatrix} W^T & 0 \end{bmatrix}.
    \end{align}\end{subequations}

\part{Implementation}
\section{Outline of LIP-BFGS algorithm}
LIP-BFGS requires the following input parameters:
\begin{itemize}
    \item $\nabla f(x)$,  function on $\mathbb{C}^n \to \mathbb{C}^n$
        to evaluate gradient at $x$,
    \item $x \in \mathbb{C}^n$,  initial value of optimization variable,
    \item $l, u \in \mathbb{R}^n$,  lower and upper bounds on $x$, and
    \item $A \in \mathbb{C}^{m \times n}, b \in \mathbb{C}^m$,
        equality constraint on $x$.
\end{itemize}

The basic outline of the LIP-BFGS algorithm is:
\begin{enumerate}
    \item Determine initial values of $s_{0,1}$, $y$, and $z_{0,1}$,
    \item Check termination condition; if needed,
        update $\mu$ and perform steps \ref{start}-\ref{stop},

    \item Form or update $B_k$ using \eqref{lbfgs}, \label{start}
    \item Compute step-direction $p$ by solving
        \eqref{lipbfgs} and \eqref{p_other},
    \item Perform a line-search to determine step-size along $p$,
        update $x$, $s_{0,1}$, $y$, and $z_{0,1}$. \label{stop}
\end{enumerate}

\section{Determining initial values of $s_{0,1}$, $y$, and $z_{0,1}$}
\section{Termination condition}
The suggested termination condition from chapter 19.2 of \cite{NW04}
    is used (with $\mu = 0$),
    \begin{equation}
    \text{if } E(x, s_0, s_1, y, z_0, z_1) \le \epsilon_\text{tol}
    \text{ then terminate,}
    \end{equation}
    where
    \begin{multline}
    E(x, s_0, s_1, y, z_0, z_1) = \text{max}\{
        \| \nabla f(x) - A^T y - z_0 + z_1 \|, \\
        \| s_0 z_0 \|,
        \| s_1 z_1 \|,
        \| A x - b \|,
        \|(x - l) - s_0 \|,
        \|(u - x) - s_1 \| \},
    \end{multline}
    and $s_0 z_0$, $s_1 z_1$ are element-wise vector products.

\section{L-BFGS update of $B_k$}
\section{Computing step direction $p$}
\section{Line-search and variable update}

Lastly, inspired from section 11.7.3 of \cite{BL04},
    we perform a backtracking line search (see section 9.2 or \cite{BL04})
    in order to guarantee decrease of the residual
    $r(x^+, s_0^+, s_1^+, y^+, z_0^+, z_1^+, \mu)$ where,
    \begin{subequations}\begin{align}
    x^+ &= x + t \alpha_p p_x \\
    s_0^+ &= s_0+t \alpha_p p_{s_0} \\
    s_1^+ &= s_1+t \alpha_p p_{s_1} \\
    y^+ &= y +\alpha_d p_y \\
    z_0^+ &= z_0 + \alpha_d p_{z_0} \\
    z_1^+ &= z_1+\alpha_d p_{z_1}
    \end{align}\end{subequations}
    and,
\begin{equation}
    r(x, s_0, s_1, y, z_0, z_1, \mu) =
\left\|
\begin{bmatrix}
    \nabla f(x) - A^T y + h_0 + h_1 \\ A x - b
\end{bmatrix}\right\|_2.
\end{equation}
The exit condition for the line search is
    \begin{equation} r(x^+, s_0^+, s_1^+, y^+, z_0^+, z_1^+, \mu) \le
    (1-\alpha t) r(x, s_0, s_1, y, z_0, z_1, \mu).
    \end{equation}
where $t$ is initially set to $t = \alpha_p$.

\begin{thebibliography}{99}
\bibitem{NW04} Nocedal and Wright,
    Numerical Optimization, Second Edition (Cambridge 2004)
\bibitem{BL04} Boyd and Vandenberghe,
    Convex Optimization (Cambridge 2004)
\end{thebibliography}
\end{document}


\section*{Problem 1 Solution}

\begin{enumerate}[a)]

\item Reactivity is defined as $\rho \equiv \frac{k - 1}{k}$. From the information provided in the problem, we can determine $k$ using the 6 factor formula.
$$ k = \varepsilon p f \eta P_{\textit{FNL}} P_{\textit{TNL}} $$
We are told that 13\% of neutrons are absorbed in resonances, so $p = 0.87$. We are told 10\% of neutrons leak from the reactor, so $P_{\textit{NL}} = 0.9$ and we will assume $P_{\textit{NL}} = P_{\textit{FNL}} P_{\textit{TNL}}$. We are also given the fraction of fissions that are fast fissions,
$$ \frac{\Sigma_f^F}{\Sigma_f^T + \Sigma_f^F} = 0.02 ,$$
from which we can calculate the fraction of fissions that are thermal:
$$ \frac{\Sigma_f^T}{\Sigma_f^T + \Sigma_f^F} = 0.98 .$$
Noting that the definition of the fast fission factor, $\varepsilon$, is just the inverse of the thermal fission fraction, we can find a value for $\varepsilon$:
\begin{align*}
\varepsilon	&\equiv \frac{\Sigma_f^T + \Sigma_f^F}{\Sigma_f^T} \\
			&= \left(\frac{\Sigma_f^T}{\Sigma_f^T + \Sigma_f^F}\right)^{-1} \\
			&= \left(0.98\right)^{-1} \\
			&= 1.02
\end{align*}
Finally, using the cross sections provided we determine $f$ and $\eta$. In general,
$$ \eta = \frac{\nu\Sigma_f}{\Sigma_a^{\text{fuel}}} ,$$
and for a homogeneous reactor,
$$ f = \frac{\Sigma_a^{\text{fuel}}}{\Sigma_a} .$$
When multiplied together,
\begin{align*}
f \eta	&= \frac{\nu\Sigma_f}{\Sigma_a} \\
		&= \frac{2.4\left(0.6\text{ cm}^{-1}\right)}{1\text{ cm}^{-1}} \\
		&= 1.44
\end{align*}
Altogether,
\begin{align*}
k	&= \varepsilon p f \eta P_{\textit{FNL}} P_{\textit{TNL}} \\
	&= \left(1.02\right)\left(0.87\right)\left(1.44\right)\left(0.9\right) \\
	&= 1.15
\end{align*}
and
$$ \rho = \frac{1.15-1}{1.15} $$
$$\boxed{ \rho = 0.13 }$$

\item Having calculated a value for the reactor's excess reactivity, we can use the provided plot to find the start of the xenon-induced deadtime and its duration. The plot gives 4 curves describing the negative reactivity created by xenon in a reactor over the first few days after shutdown. Each curve corresponds to an operating flux level in the reactor. While we are not given the flux in our reactor, we can approximate it from the information given.

We know that the reactor is producing 10,000 W/cm$^3$. This is equal to the energy produced per second, which is also equal to the product of the fission reaction rate and the energy produced per fission,
$$ P \approx E_f \Sigma_f \phi .$$
We solve this relationship for the flux (using the conversion from MeV to Joules),
\begin{align*}
\phi	&\approx \frac{P}{E_f \Sigma_f} \\
		&\approx \frac{\left(10,000\text{ W/cm}^3\right)}{\left(3.204\times10^{-11}\text{ J}\right)\left(0.6\text{ cm}^{-1}\right)} \\
		&\approx 5.2\times10^{14}\text{ cm}^{-2}\cdot\text{s}^{-1}
\end{align*}
At this flux level, we can use the top line as a reasonable approximation for our reactor's behavior. Our excess reactivity of 0.13 is shown as a dashed line on the plot, and we have added large points where our flux curve intersects our excess reactivity. When there is more negative reactivity than excess reactivity, there is no possible way to restart the reactor (even if all control rods, poisons, and absorbers are removed, the negative reactivity will surpass the excess reactivity and keep the reactor subcritical).

\includegraphics[width=12cm]{xenon-deadtime-marked}

The point the negative reactivity becomes greater than 0.13 and the deadtime begins is about 1 hour after shutdown. The deadtime then lasts for slightly more than 40 hours, and the reactor can be made critical again at the 42-43 hour mark.

\end{enumerate}