\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{amsmath, amssymb}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{url}
\usepackage[margin=1in]{geometry}
\usepackage[ruled, linesnumbered]{algorithm2e}

\definecolor{vgreen}{RGB}{104,180,104}
\definecolor{vblue}{RGB}{49,49,255}
\definecolor{vorange}{RGB}{255,143,102}
\SetKw{Break}{break}
\SetKw{Continue}{continue}

\lstdefinestyle{verilog-style}
{
    language=Verilog,
    basicstyle=\small\ttfamily,
    keywordstyle=\color{vblue},
    identifierstyle=\color{black},
    commentstyle=\color{vgreen},
    numbers=left,
    numberstyle=\tiny\color{black},
    numbersep=10pt,
    tabsize=8,
    morekeywords={unique, logic, always_ff, typedef, enum, property, endproperty, cover}
    literate=*{:}{:}1
}

\title{FSM Extraction Algorithm}
\author{Keyi Zhang}
\begin{document}

\maketitle
\section{Graph Definition for the Circuit}\label{sec:1}
Let the entire circuit design to be represented as a graph, $G(V, E)$. We define $V$
as terminals of a net, and $E$ as relations between two net terminals.
For instance, in Listing~\ref{lst:1}, we have three variables, \texttt{a}, \texttt{b},
and \texttt{c}, hence we have three \textit{named} vertices in the graph: they are named
because they have direct correspondence to Verilog variables. Similar to synthesis,
we create a new vertex for every u-/bi-nary operator. These new vertices are not named
since they are created through expressions. For instance, \texttt{b + c} is represented
as a new vertex connected to both \texttt{b} and \texttt{c}.
For assignment, we introduce additional vertices as
``pass-through'' vertex, i.e. additional vertex that connects two vertices. For instance,
in Listing~\ref{lst:1}, the assignment vertex connects \texttt{a} and the new vertex
created by \texttt{b + c}, as showing in Figure~\ref{fig:1}. This new vertex will have
\texttt{assignment} type.
\begin{lstlisting}[style={verilog-style}, caption={Graph example from Verilog},
    label={lst:1}]
logic [15:0] a;
logic [15:0] b;
logic [15:0] c;

assign a = b + c;
\end{lstlisting}

\begin{figure}
    \centering
    \begin{tikzpicture}
    \input{figure1.tex}
    \end{tikzpicture}
    \caption{Graph representation for Listing~\ref{lst:1}.}
    \label{fig:1}
\end{figure}

To describe the behavior of conditional logic, e.g. \texttt{case} and \texttt{if}, and
clocking block, such as \texttt{always\_ff}. We introduce a new type of edge \texttt{control}
for conditional logic and \texttt{NonBlocking} for non-blocking assignment, as
shown in Listing~\ref{lst:2} and Figure~\ref{fig:2}. Notice that by introducing
control edge, we allow ``influence'' from one vertex to another vertex
even though there is no direct assignment. Mathematically speaking, that means
there is a path from the vertex used for conditional logic to the assigned vertex; in
this case, a path from \texttt{c} to \texttt{a}. We claim without proof that the graph
constructed by this method is a directed simple graph, which implies that any loop
in the graph has to go through at least two vertices.

We define the \texttt{source} of vertex is the function $source(v)$:
\[
    source(v) = \{x \mid x \in \mathcal{V} \cup {v}\quad\text{for all}\quad x \in \mathcal{E}(v) \} \cup \bigcup_{x \not \in \mathcal{V} \cup {v}}
                source(x)
\]
where $\mathcal{V}$ denotes the set of vertices that does not have any incoming edges,
i.e., constants and top-level IO ports, and $\mathcal{E}(v)$ is defined as the complete
set of $(x, v)$ such that $(x, v) \in E$ and $(x, v)$ is not a control edge.
Notice that this is a recursive definition to search the ``ultimate'' source of the
vertex, including itself.

\begin{lstlisting}[style={verilog-style}, caption={Control vertex and non-blocking
    assignment Verilog code},
    label={lst:2}]
input logic clk;
logic [15:0] a;
logic [15:0] b;
logic [15:0] c;

always_ff @(posedge clk) begin
    if (b == c) begin
      a <= c;
    end
end
\end{lstlisting}

\begin{figure}
    \centering
    \begin{tikzpicture}
    \input{figure2.tex}
    \end{tikzpicture}
    \caption{Graph representation for Listing~\ref{lst:2}. Dotted arrow represents edge with control
    type, and dashed arrow represents non-blocking assignment.}
    \label{fig:2}
\end{figure}

To avoid unnecessary edges and reduce graph complexity, the control edge only connects to ``one hierarchy''
inside the code block. Nested \texttt{if} statement traversal requires extra ``hops'' at the control nodes.
Notice that this is consistent with the structural RTL implementation, where \texttt{if} statement is
implemented as multiplexers, since the nested \texttt{if} is expressed as chained multiplexers.

\section{Finite State Machine (FSM)}\label{sec:fsm}
For the purpose of HDL-based design, we categorize FSM into two catagories:
\begin{itemize}
    \item \textbf{Explicit} FSM. This includes finite state machines where each state
    is assigned explicitly to an integer, such as local parameters or enums.
    \item \textbf{Implicit} FSM. This includes counter-based state machines where
    states are defined in a finite range of values and the state value can decrement
    or increment at any cycle.
\end{itemize}
Although mathematically these two types of FSMs are equivalent: one can always be
converted to another, logic designers may prefer one over another depends on the
problem and coding styles. As a result, when we extract FSM we should consider both
types of FSMs.
\subsection{FSM properties and Its Graph Equivalence}
We claim that there are three properties that holds for any FSM, either implicit
or explicit:
\begin{enumerate}
    \item The FSM state variable has to be a register.
    \item\label{item:1} All the sources to that FSM variable have to be either constant, ot itself,
    or combination of both with binary operators such as addition.
    \item The current value of the FSM state should be used to determined the next
    state.
\end{enumerate}

One caveat of last property is that it excludes the cases where a state machine
advances its state at every cycle regardless of the current state. This only happens
when the FSM is used as a counter and the maximum value of the counter is the maximum
value specified by its bit width. This, however, is trivial to detect, as shown
later.

Given the graph construction described in Section~\ref{sec:1}, we can show the
equivalent following properties in our graph:
\begin{enumerate}
    \item Given vertex $v$, for all its connected vertices $w \in V$ such that
    $(w, v) \in E$, Edge $(w, v)$ is non-blocking and $w$ is assignment.
    \item Given vertex $v$, each element in $source(v)$ has be to either a constant,
    or itself ($v$).
    \item Given vertex $v$, for all simple path $P$ from $v$ to $v$,
    $P = (v_0, v_1, \dots, v_i)$ such that $v_0 = v_i = v$ and $(v_{j-1}, v_{j}) \in E$,
    there exist an edge $e = (v_{j-1}, v_j)$ such that $e$ is a control edge.
\end{enumerate}

It is trivial to show the first properties are equivalent since we create an assignment
vertex for each blocking and non-blocking assignment, then connect that assignment vertex
to the sink vertex, which is the only source of incoming edges to a vertex.

To show that the second properties are equivalent, notice that the $source$ function
is recursive and the base case is the set $\mathcal{V} \cup v$ for a given vertex
$v$. Furthermore, Since $V$ is the set of all constants and IO ports, if $sources(v)$ are itself
or constant, it means that $v$ is not a data-path register.

To show the equivalence of the last properties, notice the introduction of \textit{control}
edge, which indicates the presence of a conditional logic. If a variable's current value
is used to determined the next value, there must be some conditional logic to use the
current value to mux out the next value, hence creating a control edge from that vertex
and form a loop.

For the corner case where the counter advances without comparing with the current
value, all its loop path will not have any control edge. However, the path length
must be 4: self $\rightarrow$ increment/decrement vertex $\rightarrow$ assignment vertex
$\rightarrow$ self.

\subsection{Relaxed FSM Properties}
In some cases where data path are mixed with control path, property~\ref{item:1} may not
hold anymore based on the coding style, as shown in Listing~\ref{lst:3} and Listing~\ref{lst:4}. Although these
two listings are logically equivalent, property~\ref{item:1} will fail on Listing~\ref{lst:4}.

\begin{lstlisting}[style={verilog-style}, caption={Conditional increment counter
    with constant source},
    label={lst:3}]
input logic clk;
input logic [15:0] a;
input logic [15:0] b;
logic [15:0] c;

always_ff @(posedge clk) begin
    if (a == b) begin
      c <= c + 1;
    end
end
\end{lstlisting}

\begin{lstlisting}[style={verilog-style}, caption={Conditional increment counter
    with constant source},
    label={lst:4}]
input logic clk;
input logic [15:0] a;
input logic [15:0] b;
logic [15:0] c;

always_ff @(posedge clk) begin
    c <= c + 16'(a == b);
end
\end{lstlisting}

To accommodate this use case, we can relax property~\ref{item:1} with some heuristics:
when the binary operator is addition or subtraction, one of the operand is itself and the
other operand is a single-bit value (before the bit-width conversion), we ican treat that
single-bit value as constant source.

\subsection{Implicit FSM Detection}
Based on the definition in Section~\ref{sec:fsm}, the only difference between implicit and
explicit FSM is that implicit has a source that combines itself with another constant with
a binary operation. We can use that property to distinguish these two FSMs. To put that
in the graphical terms, given a FSM vertex $v$, there exists a path,
$(v_0, v_1, \dots, v_i, v)$, where $v \in \{v_0, v_1, \dots, v_i\}$ and the path from $v$
to itself does not contain control edge.

\subsection{Coupled FSM Interaction}
When the value of one FSM machine affects another FSM, we call these two FSMs \textit{coupled}
and there are some logic that interacts with these two. For instance, in a controller,
the valid output FSM can only be in valid state if the main FSM is in transaction state.
Finding out these interactions between coupled FSM is very straight-forward given our graph setup.
Given two FSM vertices, $v$ and $w$, if there is a simple path from $v$ to $w$ that contains
a control edge, then $v$ and $w$ are coupled.

\section{Algorithms and Implementation Details}
This section describes algorithms used to extract FSM, the type of each FSM, and their interaction.
It also highlights some implementation details to speed up the computation.

\subsection{FSM Extraction}

The overall algorithm to extract FSMs from a given Verilog file is shown in Algorithm~\ref{alg:1}.

\begin{algorithm}[!tbh]\label{alg:1}
    \KwIn{Verilog file $V$}
    \KwResult{List of FSM variables and their states}
    $G \gets$ parse\_verilog ($V$)\;
    $Regs \gets$ identify\_registers (G)\;
    $result \gets$ $\{\}$\;
    \For{$r \gets$ Regs}{
        $\text{const\_sources} \gets$ get\_const\_sources ($r$)\;
        \If{$|\text{const\_sources}| > 0$ and $\text{has\_control\_loop} (r)$}{
            $result \gets result \cup \{(r, \text{const\_sources}\}$\;
        }
    }
    \Return{result}\;
 \caption{Overall algorithm to extract FSMs}
\end{algorithm}

In \textit{parse\_verilog}, to report all the hierarchical name (handle name) for the FSM variable,
we add a new type of vertex to represent Verilog module and in each vertex we store a
\texttt{parent} to point back to its hierarchical parent.

The algorithm for \texttt{identify\_registers} is shown in Algorithm~\ref{alg:2}, which examines
the incoming edges for each named vertex in the graph $G$. We only care about named vertex because
it is impossible to create a registers without an explicit name in Verilog. This will speed up
the search significantly.
\begin{algorithm}[!tbh]
    \label{alg:2}
    \KwIn{Graph $G$}
    \KwResult{Set of register vertices}
    $Regs \gets$ \{\}\;
    \For{$v \gets$ VertexNamed(G)} {
        $is\_reg \gets true$\;
        \For{$e \gets InComingEdges(v)$} {
            \If{$e.type \neq BlockingAssignment$} {
                $is\_reg \gets false$\;
                \Break\;
            }
        }
        \If{$is\_reg$} {
            $Regs \gets Regs \cup \{v\}$\;
        }
    }
    \Return{Regs}\;
 \caption{Algorithm for \texttt{identify\_registers}}
\end{algorithm}

The algorithm for \texttt{get\_const\_sources} is shown in Algorithm~\ref{alg:3}. We check the
connected vertices and if it is an external port, i.e. IO, we early out the recursion. Notice
that to avoid infinite loop and efficient search, in the actual implementation we need to
combine the algorithm with standard BFS with vertex coloring for visited/unvisited.
\begin{algorithm}[!tbh]
    \label{alg:3}
    \KwIn{Vertex $w$}
    \KwResult{A set of constant sources}
    $result \gets \{\}$\;
    \For{$v \gets ConnectedFrom(w)$} {
        \eIf{$v.type == Constant$} {
            $result \gets result \cup \{v\}$\;
        } {
            \If{$v.type == ExternalPort$} {
                \Return $\{\}$\;
            }
            $r \gets \text{get\_const\_sources}(v)$\;
            \If{$|r| == 0$} {
                \Return $\{\}$\;
            }
            $result \gets result \cup r$;
        }
    }
    \Return{result}\;
 \caption{Algorithm for \texttt{get\_const\_sources}}
\end{algorithm}

The algorithm for \texttt{has\_control\_loop()} is shown in Algorithm~\ref{alg:4}. Notice that
finding all the paths between two arbitrary vertices is hard and memory inefficient. Since the
goal is just to find one loop that contains a control vertex, we can significantly speed up
the search process by borrowing the idea from union-find, as shown between Line~\ref{line:1} and
Line~\ref{line:2}. We maintain a set that contains all the vertex connected by or \textit{indirectly}
connected by a control edge. This is done through two passes: the first pass collect all the
vertices directly connected by a control edge, and the second pass colors any vertex connected by
vertices in the control set. During the second pass, if a new vertex is colored and it has been
visited, we remove it from the visited set so that we can recompute any path from that vertex.
The coloring process ended when there is no vertex let to color or the target vertex has been
colored and we have reached a loop. The correctness of the algorithm can be proved by induction
on the graph, where the base case is the smallest loop with control loop and we add a vertex to
the loop during induction step. For completeness we show the BFS version of the algorithm.
\begin{algorithm}
    \label{alg:4}
    \KwIn{Vertex $r$}
    \KwResult{$true$ if it contains a control vertex connected to $r$}
    $control\_set \gets \{\}$\;
    $visited \gets \{\}$\;
    $working\_set \gets queue\{r\}$\;
    // first pass to get the control set\;
    \While{$|working\_set| > 0$} {
        $v \gets working\_set.pop()$\;
        \eIf{$v \in visited$} {
            \Continue\;
        } {
            $visited \gets visited \cup \{v\}$\;
        }
        \For{$e \in Edges(v)$} {
            $w \gets e.end()$\;
            \If{$e.type == Control$} {
                $control\_set \gets control\_set \cup \{w\}$\;
            }
            $working\_set \gets working\_set \cup \{w\}$\;
        }
    }

    // second pass compute the result\;
    $working\_set \gets = queue{r}$\;
    $visited \gets \{\}$\;
    \While{$|working\_set| > 0$} {
        $v \gets working\_set.pop()$\;
        \If{$v == r$ and $v \in control\_set$} {
            \Return $true$;
        }
        \eIf{$v \in visited$} {
            \Continue\;
        } {
            $visited \gets visited \cup \{v\}$\;
        }
        \For{$w \in EdgesVertex(v)$} {
            \label{line:1}\If{$v \in control\_set$ and $w \in control\_set$} {
                $control\_set \gets control\_set \cup \{w\}$\;
                \If{$w \in visited$} {
                    $visited \gets visited \setminus \{w\}$\;
                }
            \label{line:2}}
            $working\_set.add(w)$\;
        }
    }
    \Return{false}\;
 \caption{Algorithm for \texttt{has\_control\_loop()}}
\end{algorithm}

\subsection{Counter Identification}
The algorithm to detect counter is shown in Algorithm~\ref{alg:5}. We are looking for a pattern of
$v \gets v + constant$ for a given $v$. However, since values may get passed through multiple
vertices, we need to recursively check all the assignment patterns. Notice that for performance,
we can rewrite the algorithm using a while loop instead of a recursive call.

\begin{algorithm}[htb]
    \label{alg:5}
    \KwIn{Vertex $w$}
    \KwResult{$true$ if vertex is a counter}
    \For{$e \gets EdgesTo(w)$} {
        $v \gets e.start()$\;
        \If{$v.type == Assignment$ and $(x, w) \in E(G)$ and $x.type == Addition$} {
            \If{both a constant and $w$ connected to $x$} {
                \Return{true}\;
            }
        }
        $r \gets \text{detect\_counter(v)}$\;
        \If{$r$} {
            \Return{true};
        }
    }
    \Return{false}\;
 \caption{Algorithm for \texttt{is\_counter}}
\end{algorithm}

\subsection{Coupled FSM}
For given two FSM vertices $v_1$ and $v_2$, We can modify Algorithm~\ref{alg:4} where the
terminal condition is $v == v_2$ instead of $v == r$ and the algorithm will work out just
fine. Conceptually, if $v_1$ and $v_2$ are the same we will get a loop, which is what the
algorithm is designed for.

\subsection{FSM Transition Arc Extraction}
Because the comparison nodes connect the inner logic with control edges, we have traverse
the control edges to figure out the state transition logic. Because both explicit FSM and
implicit counters use explicit values to control the logic, such as \texttt{==} or \texttt{<},
we can use the comparison node to compute the state transition as indicated in the dataflow.
As shown in Algorithm~\ref{alg:6}, the main idea is to start from a comparator node where the
FSM register node is used to compare a constant state value, denoted as \texttt{state\_0},
and then traverse to an assignment where the state node is assigned to another constant state
value, denoted as \texttt{state\_1}. Since it is control logic, all the path has to be control
path and taken on the \texttt{true} path.

\begin{algorithm}[htb]
    \label{alg:6}
    \KwIn{State comparator node $v$}
    \KwIn{State assign node $w$}
    \KwResult{$true$ if under condition $v$, $w$ happens}
    \While{$e \gets Traverse(w)$} {
        \If{$e.type() != \texttt{control}$ \text{ or } $e.type() == \texttt{false}$} {
            \text{stop traverse from $e$}\;
        }

        $n \gets e.end()$\;
        \If{$n == w$} {
            \Return{true};
        }
    }
    \Return{false}\;
 \caption{Algorithm for detecting FSM transition arc}
\end{algorithm}

\subsection{Performance Optimization with Parallelism}
Notice that all the algorithms used in Algorithm~\ref{alg:1} are intentionally designed to not
share data during the iteration, nor do they modify the graph structure. As a result, we have
a list of embarrassingly parallel tasks each can be computed independently on each CPU core.
Given the nature of graph size as the design complexity grows, we can implement a thread-pool
and dispatch the tasks to available CPU cores.

\subsection{Parsing Verilog/SystemVerilog Files and Producing Graph}
There is an open-source SystemVerilog parser project called
slang~\footnote{\url{https://github.com/MikePopoloski/slang}}, and we have been contributing
to it by adding serialization ability on the symbol level (one compilation stage after syntax
tree parsing). The serialization dumps a JSON file and we can parse that efficiently using
simdjson~\footnote{\url{https://github.com/simdjson/simdjson}}.

When generating the graph, since we are not interested in the exact logic other than label
the vertex as binary operation, unary operation, etc, we lose lots of logical information
that could be useful for other tasks. However, at this stage the extra information are
unnecessary and waste of memory and thus shall not be kept inside the data structure.

\section{Interaction with Formal Verification Tools via SVA and its Applications}
Once we have obtained FSM information from the dataflow graph, we can generate FSM specification
based on the FSM states, types, interaction, and transition. Although there are many different
languages for specifying formal temporal logic, we choose SystemVerilog Assertions (SVA) for
several reasons:
\begin{itemize}
    \item SVA are widely supported in hardware formal verification tool chains.
    \item Designers can reuse existing input constraints when verifying FSM properties in design.
    \item Can be used for traditional constrained random coverage metric.
\end{itemize}

\subsection{SVA Code Generation Example}
The code generation for SVA from FSM properties are very mechanical and will not be the main
focus of this paper. Listing~\ref{lst:5} shows an example of checking whether a FSM \texttt{state}
is possible to transition from \texttt{STATE\_0} to \texttt{STATE\_1}. Notice that we use
\texttt{cover} so that formal tools can solve for possible transition given constraints.
The SVA files can either be a bind file, or inside top-level test-bench file where the
design under test is instantiated.

\begin{lstlisting}[style={verilog-style}, caption={SVA code example for state transition
    coverage},
    label={lst:5}]
    property fsm_state_0;
      @(posedge clk) state == STATE_0 |=> state == STATE_1;
    endproperty
    FSM_STATE_0: cover property (fsm_state_0);
\end{lstlisting}

After we collect results from formal tools, we can provide an API so that verification
engineers can check against their specification programmatically, for instances, number
of states, possible state transition and so on. Currently we support Cadence JapserGold
and we plan to support CosA2 via yosys.

\subsection{Dead code Detection}
One application for automatic state transition and reachability calculation with the help
of formal tools is dead code detection. If a state or a state transition is proven unreachable,
it usually implicates either dead code or bug in the FSM design. We will continue this section
with a case study on dead code since it is very common in generated code where the generator
parameters are used to produce the states and output logic associated with the state. We will
use RocketChip's DCache as an example here.

The main FSM in DCache is \texttt{release\_state}, where there are 8 pre-defined states. In
generated Verilog, these state values are represented as constants, $0, 1, \dots, 7$. If we
use the default configuration on RocketChip, Chisel will generate an FSM with all 8 states,
nested in a single \texttt{always} block.

Without much discerning, the FSM logic in generated Verilog looks like any other generated
code. However, once we use our FSM extraction algorithm and use JapserGold to verify the
state transition based on the graph analysis, we have discovered a unreachable state,
$4$. This is because given the default configuration, state $4$ is never going to be
assigned to \texttt{release\_state}. However, there are still some downstream logic that
expect \texttt{release\_state} to be $4$ and behave accordingly.

Does this dead state matter in the synthesis tools? Contrary to common belief, the answer
is yes. We compare two version of DCache: DCache-Original and DCache-Improved, where we
manually remove the dead state and its corresponding logic from the latter version. The
edits are formally verified to be functionally equivalent by JasperGold. We
use FreePDK-45 and Design Compiler for synthesis. To ensure a fair comparison, we target
both design at 100MHz clock speed, ultra-high effort, and flatten everything. We also
removed SRAM component to ensure that the comparison only focus the control logic.
Table~\ref{table:1}
shows the final synthesis result.

\begin{table}[!htb]\label{table:1}
    \centering
    \caption{Synthesis result comparison on RocketChip's DCache with and without dead code on
    FreePDK-45 with Design Compiler.}
    \begin{tabular}{|l|l|l|l|l|}
        \hline
        Design Name     & \# of Ports & \# of Nets & \# of Cells & \# of Combinational Cells \\ \hline
        DCache          & 2517        & 10476      & 8469        & 6213                      \\ \hline
        DCache-Improved & 2517        & 10435      & 8367        & 6112                      \\ \hline
    \end{tabular}
\end{table}

Although the difference is minimal, it shows that by properly incorporating dead logic
detection with our FSM extraction algorithm, we can reduce the size of synthesized netlist
without changing the circuit logic.

\end{document}


To complement and validate the results of the offline evaluation,  we ran a user study with 24 subjects to measure the performance of users with different clustering algorithms for an interactive visual interface.  In the following, we first describe the user study methodology followed by an evaluation of user performance.

\subsection{Methodology}
The main goal of this user study was to ask students to find the natural disasters in our collection of tweets. Before starting the experiment, each user was introduced to the goal of the survey with a video describing the interface and the different features. Then, each user was trained using two different search algorithms to find three different natural disasters using both a baseline interface showing all results as well as a clustering interface.

In brief, the user study interface allows users to enter a search query with results shown on an interactive Google Maps display used to browse the results.
The tweets that match a query were represented using circles with a grayscale color range corresponding to the probability of relevance -- light gray circles represented low probability relevance tweets, and dark gray circles represented high probability relevance tweets.
The user was able to interact with the map by panning, zooming and dragging and also by clicking on tweets and clusters to view their content (for clusters, we display a summary in terms of selected keywords).
The user could also use a time slider bar to restrict the results to tweets matching the query in a specific time window.
Once each user had familiarized themselves with the interface, they were asked to find three other natural disasters using a different display algorithm (baseline, K-means, EF1 relevance-driven clustering using the BPS greedy algorithm) for each of three trials containing three natural disasters each.

In each trial, the user was asked to enter information related to each natural disaster they identified, including the type of the natural disaster, its location (US state), and the date on which they think the disaster happened. We collected detailed interaction logs to record different behaviors and actions of the user. Moreover, each user was asked to answer NASA Task Load Index (NASA-TLX)~\cite{HART1988139} and System Usability Scale (SUS)~\cite{brooke1996sus} questionnaires after each trial. Finally, at the end of the experiment, each user was asked to fill out an exit survey, which included a ranking of the algorithms.

The three algorithms used to drive the interface in this user survey were:
\begin{enumerate}
\item A baseline method which displays all tweets that match the query (an example is shown in  Figure~\ref{Fig:GlobalDisplay}).
\item The BPS algorithm we proposed for relevance-driven clustering which displays the top 6 clusters for a query (an example is shown in Figure~\ref{Fig:FilteredDisplay}).
\item The K-Means algorithm discussed previously in the offline evaluation (using X-Means to automatically identify the best $K$), which also displays the top 6 clusters for a query (an example is shown in Figure~\ref{fig:ScreenShot}).
\end{enumerate}

Note that the probability relevance score of each tweet was derived using a language model to estimate $S(j)$~\cite{Zhai2001}.
Also, for each user the sequence of algorithms to evaluate was presented differently, such that to cover all possible six combinations uniformly four times (24 users).  Here, we wish to indicate that the user had no indication of what algorithm was used each time, especially between the BPS and the K-Means algorithms, which both present the results in a similar way using clusters (bounding boxes).
%Finally, we highlight the fact that during we have set up the task such that it wasn't too easy nor too difficult for the user.
A total of 24 users participated in our user study, for which the experiment took on average 50 minutes per user.

Figure \ref{fig:ScreenShot} shows the interface of the user study, with the results of the query ``tornado, blizzard, earthquake''  using K-Means. The results of the same query with the baseline and the BPS algorithms are shown in Figure \ref{Fig:UseCase}. At first glance, we clearly observe that the clusters of the BPS algorithm are more focused and more contextualized than those of the K-Means algorithm.  In the following, we analyze the main outcomes of this user study.

\begin{figure}[t]
\begin{centering}
{\includegraphics[width=8.5cm]{imgs/kmeans}}
\par\end{centering}
\caption{User survey Web page. The results of the query ``tornado, blizzard, earthquake''  are shown using clusters of X-Means, which can be hidden/shown using the buttons at the top. The sidebar was used to provide answers.}
\label{fig:ScreenShot}
\end{figure}

\begin{figure}[t]
\begin{centering}
\includegraphics[width=7.5cm]{imgs/legend3}
\par\end{centering}
\begin{centering}
{\includegraphics[width=8.5cm]{imgs/nd_recall}}
\par\end{centering}
\caption{The mean user performance and 95\% confidence intervals for each of the three search interfaces/algorithms are measured using cumulative recall for the type and location of the natural disasters and the absolute error for the first date of the natural disaster.  On average, users achieved higher recall and lower error faster using relevance-driven clustering (BPS) in comparison to K-means and the Baseline system.}
\label{fig:UserSurveyRecall}
\end{figure}

%However,
\begin{figure*}[t]
\begin{centering}
\includegraphics[width=7.5cm]{imgs/legend4}\\
\subfigure[Natural disasters.] {\includegraphics[width=5.7cm]{imgs/nd_recall_steps}}
\subfigure[Locations of the natural disasters.] {\includegraphics[width=5.7cm]{imgs/location_recall_steps}}
\subfigure[Errors in the dates of the natural disasters.] {\includegraphics[width=5.7cm]{imgs/nd_time_deviation_recall_steps}}
\par\end{centering}
\caption{Performance of the algorithms measured at different elapsed times for each trial.}
\label{fig:UserSurveyRecallStage}
\end{figure*}

\subsection{Performance analysis}

The performance of the users for each algorithm was measured using cumulative recall for the type and location of the natural disasters in each trial.  We remark that there were three distinct natural disasters per trial so perfect recall would require getting all three natural disaster types or locations correct.  Mean performance across all users for cumulative recall of disaster type and location are respectively shown in Figures~\ref{fig:UserSurveyRecall}(a) and Figure~\ref{fig:UserSurveyRecall}(b).  Users also had to enter their estimated starting date of each natural disaster, which we measure by absolute error assuming the maximum amount of error for any natural disasters that have not been submitted yet.  The mean performance of time estimation error across all users is reported in Figure~~\ref{fig:UserSurveyRecall}(c).  Moreover, in Figure~\ref{fig:UserSurveyRecallStage} we report the progression of these metrics for each algorithm using boxplots at different elapsed times into the experiment -- at 300, 600, 900 and 1200 seconds.

In brief, the main outcome of this performance analysis are fairly straightforward:
%(i)
From Figure~~\ref{fig:UserSurveyRecall}, we see that on average, users achieved higher task recall and lower error faster when using the BPS algorithm for relevance-driven clustering in comparison to K-Means and the baseline.
% The performance obtained for this user study confirms clearly the results obtained in the off-line evaluation since the BPS algorithm outperforms K-Means and the baseline in identifying the natural disasters, their locations, and their dates.
%(ii) In general, the clustering approach is clearly useful for this kind of task as both BPS and K-Means outperformed the baseline that show all matching elements.
%(iii) Clearly, the BPS algorithm required much fewer efforts and time to complete the task than for K-Means and the baseline and that to reach a bit higher level of recall.
%(iv)
Further considering the performance progression shown in Figure~\ref{fig:UserSurveyRecallStage}, we clearly notice that with the BPS algorithm, participants were able to achieve a higher performance at early stage of the experiment than using the two other algorithms.

% As a conclusion for this evaluation, we notice that there is a similar outcome between the two evaluation methods -- the offline evaluation and the user study. Both evaluations confirm that the BPS algorithm
% the significant contribution of the BPS algorithm for this specific relevance-driven clustering task. Even though the off-line evaluation showed that K-Means is inappropriate for this task, the performance obtained in this user study showed that it is effective to some extent.

\begin{figure}[t]
\begin{centering}
\includegraphics[width=7.5cm]{imgs/legend4}\\
\subfigure[Subscales rating. %``0'' means the user thinks that the workload for the considered dimension was ``Low'' and ``20'' means it was ``High''.
] {\includegraphics[width=4.6cm]{imgs/NASA_TLX}}
\subfigure[Overall rating.] {\includegraphics[width=3.8cm]{imgs/NASA_TLX_AVERAGE}}
\par\end{centering}
\caption{NASA Task Load Index (MD: Mental Demand, PD: Physical Demand, TD: Temporal Demand, OP: Own Performance, FR: Frustration, EF: Effort). }
\label{fig:NASA}
\end{figure}

\subsection{Surveys analysis}

With the previously discussed quantitative measures of user performance indicating the advantage of relevance-driven clustering, we next proceed to evaluate the users' own opinions of each interface/algorithm as collected in the user surveys discussed in the methodology.

During this user study, each participant had to answer 7 different questionnaires -- a NASA Task Load Index (NASA-TLX)~\cite{HART1988139} and a System Usability Scale (SUS)~\cite{brooke1996sus} questionnaires after having used each algorithm, plus a final questionnaire. We report below the main outcomes of each survey.

\subsubsection{NASA-TLX analysis}

The NASA-TLX questionnaire rates perceived workload in order to assess a task, system effectiveness or other aspects of performance.
The questionnaire includes questions on mental demand, physical demand, temporal demand, performance, frustration, and effort. NASA-TLX items are rated on a 20-point scale (1 = low workload, 20 = high workload, except for OP where 1 = perfect and 20 = failure).
We show the NASA-TLX results obtained  for each subscale and for the overall ratings  in Figure~\ref{fig:NASA}.
Briefly, the mean overall NASA-TLX rating was $45.91\pm 8.86$ for BPS, $54.75\pm 7.41$ for K-Means, and $70.41\pm 8.27$ for the baseline.
A Friedman's test revealed an overall significant difference ($\chi^2(3)= 16.113, p=0.003 < 0.05$).
Holm-Bonferroni corrected post-hoc analyses with Wilcoxon signed-rank tests
revealed that the difference between all pairs was significant ($p < 0.05$). %The difference between BPS and K-Means wasn't significant. Moreover, there were no significant differences in the sub-scales between BPS and K-Means.

According to these results, we note that participants overall perceived the BPS algorithm to be more effective at helping them complete their search task in comparison to using K-Means or the baseline.  Global median rates of frustration and mental effort were around 10, which indicates that the task was neither too difficult, nor too easy.  Also, as the median rates of these two factors were lower for the two clustering methods than the baseline, we conclude that participants overall felt that clustering-based search provided a less frustrating and less mentally demanding interface for this task in comparison to the baseline, which displayed all search results.
Finally, based on the task load rates where the BPS algorithm performed the best, we believe that relevance-driven clustering provided the most effective approach for carrying out this kind of geo-temporal search task.

\begin{figure}[t]
\begin{centering}
\includegraphics[width=7.5cm]{imgs/legend4}
{\includegraphics[width=7.5cm]{imgs/SUS_AVERAGE}}
\par\end{centering}
\caption{System Usability Scale overall rating.}
\label{fig:SUS}
\end{figure}

\subsubsection{SUS analysis}
The SUS questionnaire gives a global view of subjective assessments of usability. The questionnaire contains questions related to the global effectiveness, efficiency, and satisfaction. The SUS items are rated on a 5-point scale (0 = strong disagreement and 5 = strong agreement). In Figure~\ref{fig:SUS}, we show the results obtained over all SUS scores  with 95\% confidence interval . The mean SUS score was $72.39\pm 9.77$ for BPS, $70.83\pm 7.61$ for K-Means, and $51.77\pm 9.07$ for the baseline. A Friedman's test revealed an overall significant difference ($\chi^2(3)= 9.053, p=0.010 < 0.05$).
Holm-Bonferroni corrected post hoc analyses with Wilcoxon signed-rank tests
revealed that the difference between the two clustering methods and the baseline  was significant ($p < 0.05$). The difference between BPS and K-Means wasn't significant and hence we can only infer from the SUS survey that the users preferred the clustering interface (i.e., BPS and K-Means) over the baseline display of all search results.

\subsubsection{Final questionnaire analysis}
The final questionnaire that the participants had to answer included questions on the advantages and disadvantages of each algorithm, plus a global ranking of the three algorithms. %Due to space limitations, we briefly summarize the top disadvantages of the BPS algorithm and advantages of the baseline method in Table~\ref{tbl:SurveyComments}.

% Preview source code for paragraph 0

%\begin{table}
%\caption{User survey comments.}
%\label{tbl:SurveyComments}
%\begin{centering}
%\begin{tabular}{|>{\centering}p{4cm}|>{\centering}p{4cm}|}
%\hline
%\textbf{Disadvantages of BPS} & \textbf{Advantages of Baseline}\tabularnewline
%\hline
%\hline
%Clusters that have huge time-spend are most likely useless. & Simple, easy. Using %just the time sliders it was very easy to detect
%the disasters. \tabularnewline
%\hline
%Does not show up all the data points.  & Using the timeslider, I found it more %useful than the filters. \tabularnewline
%\cline{1-1}
%The interface takes more time to learn.  & \tabularnewline
%\hline
%\end{tabular}
%\par\end{centering}
%\end{table}

The ranking of the algorithms provided by participants is shown in Figure \ref{fig:UserSurveyRanking}.
We note that 18 participants out of 24 ranked  BPS as being the best algorithm, and 19 participants out of 24 ranked the baseline approach as being the least helpful for this task.  Hence there is strong evidence for user preference of BPS over K-means and for both BPS and K-means over the baseline system.
%However, we note that two users mentioned that they still prefer the baseline approach.
%This is probably due to the fact that they are used to work with a conventional search approach, and that they couldn't digest this new search clustering paradigm.
Finally, we mention that in the surveys, several participants reported the utility, the ease and the precision provided by the BPS algorithm to complete this search task.

\begin{figure}[t]
\begin{centering}
\includegraphics[width=7.5cm]{imgs/legend4}\\
{\includegraphics[width=8cm]{imgs/ranking}}
\par\end{centering}
\caption{Ranking of the algorithms by participants.}
\label{fig:UserSurveyRanking}
\end{figure}


\section{Sybil Resilience}
  One of the primary aims of this system is to mitigate the danger for Sybil attacks \cite{sybilattack} whilst maintaining
  fully decentralized autonomy \cite{dinoyziz}.

  Here we extend the definition of indirect trust to many players.
  \subimport{common/definitions/}{indirecttrustmultiplayer.tex}
  \noindent We now extend the Trust Flow theorem to many players.
  \subimport{common/theorems/}{multiplayertrustflowtheorem.tex}
  \subimport{common/proofs/}{multiplayertrustflowproof.tex}
  \noindent We now define several useful notions to tackle the problem of Sybil attacks. Let Eve be a possible attacker.
  \subimport{common/definitions/}{corrupted.tex}
  \subimport{common/definitions/}{sybil.tex}
  \subimport{common/definitions/}{collusion.tex}
  \subimport{common/figures/}{collusion.tikz}
  \subimport{thesis/theorems/}{sybilrestheorem.tex}
  \subimport{thesis/proofsketches/}{sybilresproofsketch.tex}
  We have proven that controlling $|\mathcal{C}|$ is irrelevant for Eve, thus Sybil attacks are meaningless. We note that
  this theorem does not deliver reassurances against attacks involving deception techniques. More specifically, a malicious
  player can create several identities, use them legitimately to inspire others to deposit direct trust to these identities
  and then switch to the evil strategy, thus defrauding everyone that trusted the fabricated identities. These identities
  correspond to the corrupted set of players and not to the Sybil set because they have direct incoming trust from outside
  the collusion.


\section{An Axiomatic Network Model}
\label{sect.network}

In this section we develop a formal definition of an \emph{asynchronous unreliable causal broadcast network}.
We choose this model because it satisfies the causal delivery requirements of many operation-based CRDTs \cite{Almeida:2015fc,Baquero:2014ed}.
Moreover, it is suitable for use in decentralised settings, as motivated in the introduction, since it does not require waiting for communication with a central server or a quorum of nodes.
Stronger consistency models do not have this property \cite{Attiya:2015dm,Davidson:1985hv}.

The \emph{causal} and \emph{broadcast} aspects of the model are explained in Sections~\ref{sect.network.broadcast} and~\ref{sect.network.causal}.
The \emph{asynchronous} aspect means that we make no timing assumptions: messages sent over the network may suffer unbounded delays before they are delivered, nodes may pause their execution for unbounded periods of time, and we require no clock synchronisation.
\emph{Unreliable} means that messages may never arrive at all, and nodes may fail permanently without warning.
Networks are known to exhibit these behaviours in practice \cite{Bailis:2014jx}, and replication algorithms must tolerate such failures.

This model provides a realistic setting in which we can embed various replication algorithms, and prove that they guarantee SEC in all possible behaviours of the network.
But it is also abstract enough to be able to model a wide range of scenarios: for example, if a user makes updates while offline, and the device re-synchronises when it is next online, we can simply model that interaction as very large network delay.
Our network model is defined using only six axioms, all of which are standard assumptions when modelling distributed systems, and which are satisfied by many systems in practice.
All theorems in this paper are derived from those axioms; in particular, we show that the causal delivery abstraction satisfies the strict partial ordering assumption of $\isa{hb-consistent}$ (Section~\ref{sect.happens.before}), allowing us to use the convergence theorem in any locales that extend the network.

\subsection{Modelling a Distributed System}

We model a distributed system as an unbounded number of communicating nodes.
We assume nothing about the communication pattern of nodes---we assume only that each node is uniquely identified by a natural number, and that the flow of execution at each node consists of a finite, totally ordered sequence of execution steps (events).
We call that sequence of events at node $i$ the \emph{history} of that node.
For convenience, we assume that every event or execution step is unique within a node's history; this assumption is standard when modelling distributed systems \cite{Cachin:2011wt} and can easily be implemented by attaching a sequence number, timestamp, or other unique identifier to each event.
This system model can be expressed in Isabelle as follows:
\begin{isabelle}
~~~~\isakeyword{assumes}\ \=\kill
\isacommand{locale} node{\isacharunderscore}histories\ {\isacharequal}\\
~~~~\isakeyword{fixes}\ \>history\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\ \\
~~~~\isakeyword{assumes}\ \>histories{\isacharunderscore}distinct{\isacharcolon}\ {\isachardoublequoteopen}distinct\ {\isacharparenleft}history\ i{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
Here, the history of a node $\isa{i}$ is obtained by using a function fixed by the locale, $\isa{history}$.
The history is simply a list of events, and each event is modelled as an abstract type variable---here we use $\isa{{\isacharprime}a}$.
The $\isa{distinct}$ predicate is an Isabelle/HOL library function that asserts that a list contains no duplicate elements.
Note that we make no assumption about the number of nodes in the system, which allows us to model systems in which nodes join and leave the network over time.
A node that does not exist is simply modelled as an empty list of events.

A node's history is finite, and at the end of a node's history we assume that a node has either failed or successfully terminated.
We treat node failure as permanent, and model it by the absence of any further events in its history.
This \emph{crash-stop} abstraction is commonly used by distributed algorithms \cite{Cachin:2011wt}.

In the $\isa{node{\isacharunderscore}histories}$ locale we may write $\isa{x} \sqsubset^\isa{i} \isa{y}$, which means that event $\isa{x}$ \emph{comes before} event $\isa{y}$ in the history of node $\isa{i}$.
More formally, $\isa{x} \sqsubset^\isa{i} \isa{y}$ if and only if there exist lists $\isa{xs}$, $\isa{ys}$, and $\isa{zs}$ such that $\isa{xs}\mathbin{@}[\isa{x}]\mathbin{@}\isa{ys}\mathbin{@}[\isa{y}]\mathbin{@}\isa{zs} = \isa{history\ i}$.

\subsection{An Asynchronous Broadcast Network}\label{sect.network.broadcast}

We now extend the $\isa{node-histories}$ locale by defining how nodes can communicate.
We specialise $\isacharprime\isa{a}$ to be one of two kinds of event: either \emph{broadcast} or \emph{deliver}.
(In the conventional distributed systems terminology, a \emph{deliver} event indicates that a message was received from the network and delivered to the application.)
Each event contains a message of some abstract type $\isacharprime\isa{msg}$:
\begin{isabelle}
\isacommand{datatype} {\isacharprime}msg\ event\ {\isacharequal}\ Broadcast\ {\isacharprime}msg\ {\isacharbar}\ Deliver\ {\isacharprime}msg
\end{isabelle}

Intuitively, a node can be regarded as a deterministic state machine where each state transition corresponds to a broadcast or deliver event.
We assume that users may query the state of any node at any time, and such queries need not be reflected as events, since they neither modify the node state nor send or receive any messages.

A broadcast abstraction is the standard network model for operation-based CRDTs because it best fits the replication pattern: any node can accept writes, and propagate them to the other nodes through broadcast.
In practical systems, broadcast abstractions are often implemented as overlay networks on top of unicast TCP links, for example as a fully connected graph (each node is connected to every other node), using a spanning tree protocol, a gossip protocol, or some other network topology.
Such protocols have already been studied extensively, for example by \citet{Leitao:2007gq}, so we leave the implementation of the overlay network out of the scope of this paper.

To formally specify the properties of a broadcast network, we define a new locale $\isa{network}$ containing three axioms that define how broadcast and deliver events may interact.
Since $\isa{network}$ is an extension of $\isa{node-histories}$, the aforementioned definitions of $\isa{history}$ and $\sqsubset^\isa{i}$ are available for use in the $\isa{network}$ axioms:
\begin{isabelle}
~~~~~~~~\isakeyword{and}\ \=msg{\isacharunderscore}id{\isacharunderscore}unique{\isacharcolon}\ \={\isasymrbrakk}\ \={\isachardoublequoteopen}Broadcast\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}\ \=\kill
\isacommand{locale}\ network\ {\isacharequal}\ node{\isacharunderscore}histories\ history\\
~~~~\isakeyword{for}\>history\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharprime}msg\ event\ list{\isachardoublequoteclose}\ {\isacharplus}\\
~~~~\isakeyword{fixes}\>msg{\isacharunderscore}id\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}msg\ {\isasymRightarrow}\ {\isacharprime}msgid{\isachardoublequoteclose}\\
~~~~\isakeyword{assumes}\ delivery{\isacharunderscore}has{\isacharunderscore}a{\isacharunderscore}cause{\isacharcolon}\\
\>\>{\isasymlbrakk}\ {\isachardoublequoteopen}Deliver\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}\ \>\>{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isasymexists}j{\isachardot}\ Broadcast\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ j{\isacharparenright}{\isachardoublequoteclose}\\
~~~~~~~~\isakeyword{and}\>deliver{\isacharunderscore}locally{\isacharcolon}\ \>{\isasymlbrakk}\ \>{\isachardoublequoteopen}Broadcast\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}\ \>{\isasymrbrakk}\ {\isasymLongrightarrow}\  Broadcast\ m\ {\isasymsqsubset}\isactrlsup i\ Deliver\ m{\isachardoublequoteclose}\\
~~~~~~~~\isakeyword{and}\>msg{\isacharunderscore}id{\isacharunderscore}unique{\isacharcolon}\ \>{\isasymlbrakk}\ \>{\isachardoublequoteopen}Broadcast\ m{\isadigit{1}}\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright};\\
\>\>\>Broadcast\ m{\isadigit{2}}\ {\isasymin}\ set\ {\isacharparenleft}history\ j{\isacharparenright};\\
\>\>\>msg{\isacharunderscore}id\ m{\isadigit{1}}\ {\isacharequal}\ msg{\isacharunderscore}id\ m{\isadigit{2}}\ \>{\isasymrbrakk}\ {\isasymLongrightarrow}\ i\ {\isacharequal}\ j\ {\isasymand}\ m{\isadigit{1}}\ {\isacharequal}\ m{\isadigit{2}}{\isachardoublequoteclose}
\end{isabelle}
The axioms can be understood as follows:
\begin{description}
    \item[delivery-has-a-cause:] If some message $\isa{m}$ was delivered at some node, then there exists some node on which $\isa{m}$ was broadcast.
        With this axiom, we assert that messages are not created ``out of thin air'' by the network itself, and that the only source of messages are the nodes.
    \item[deliver-locally:] If a node broadcasts some message $\isa{m}$, then the same node must subsequently also deliver $\isa{m}$ to itself.
        Since $\isa{m}$ does not actually travel over the network, this local delivery is always possible, even if the network is interrupted.
        Local delivery may seem redundant, since its effect could also occur in the broadcast event, but it is convenient for algorithms that use the broadcast abstraction \cite{Cachin:2011wt}.
    \item[msg-id-unique:] We do not require the message type $\isacharprime\isa{msg}$ to have any particular structure; we only assume the existence of a function $\isa{msg-id} \mathbin{\isacharcolon\isacharcolon} \isacharprime\isa{msg} \mathbin{\isasymRightarrow} \isacharprime\isa{msgid}$ that maps every message to some globally unique identifier of type $\isacharprime\isa{msgid}$.
        We assert this uniqueness by stating that if $\isa{m1}$ and $\isa{m2}$ are any two messages broadcast by any two nodes, and their $\isa{msg-id}$s are the same, then they were in fact broadcast by the same node and the two messages are identical.
        In practice, these globally unique IDs can by implemented using unique node identifiers, sequence numbers or timestamps.
\end{description}

The $\isa{network}$ locale also inherits the $\isa{histories-distinct}$ axiom from its parent locale $\isa{node-histories}$.
Many other properties that we require can be deduced as lemmas from these axioms.
For example, we can prove that for every message that is delivered by some node, there is exactly one broadcast event (on the same or some other node) that created the message.
Also, due to the $\isa{histories-distinct}$ axiom we know that the same message is not delivered more than once to each node---an aspect that can be implemented in practical systems by having each node keep track of message IDs it has received, and suppressing any duplicates.

Note that we make no assumptions about the reliability or the ordering of messages.
If one node broadcasts a message, it \emph{may} be delivered by other nodes, but we do not state if or when that will happen.
Messages may be arbitrarily delayed, reordered, or even lost entirely.
It is even acceptable for a node to never deliver any messages besides those it broadcasts itself, modelling a node that is permanently disconnected from the network.

\subsection{Causally Ordered Delivery}\label{sect.network.causal}

As discussed in Section~\ref{sect.happens.before}, some replication algorithms require that some operations be applied in a particular order because the later operation has a causal dependency on the earlier one.
We previously characterised these dependencies using the \emph{happens-before} relation $\prec$, which we required to be a strict partial order, but otherwise kept abstract.
In Section~\ref{sect.abstract.convergence} we reasoned about the order of \emph{operations}, but in a network we work with \emph{messages}.
We will connect operations and messages in Section~\ref{sect.network.ops}; for now we will define a particular instance of the ordering relation $\prec$ on messages, and prove that it satisfies the requirements of a strict partial order.

We do not use physical time (such as UTC) to define the order of messages, since reliance on physical time is often problematic in distributed systems \cite{Sheehy:2015jm}.
Instead, we say that a message $\isa{m1}$ happens before another message $\isa{m2}$ if the node that generated $\isa{m2}$ ``knew about'' $\isa{m1}$ at the time $\isa{m2}$ was generated.
More precisely, based on the well-known definition by \citet{Lamport:1978jq}, we say that $\isa{m1}\prec\isa{m2}$ if any of the following is true:
\begin{enumerate}
\item $\isa{m1}$ and $\isa{m2}$ were broadcast by the same node, and $\isa{m1}$ was broadcast before $\isa{m2}$.
\item The node that broadcast $\isa{m2}$ had delivered $\isa{m1}$ before it broadcast $\isa{m2}$.
\item There exists some operation $\isa{m3}$ such that $\isa{m1} \prec \isa{m3}$ and $\isa{m3} \prec \isa{m2}$.
\end{enumerate}

This verbal definition translates directly into Isabelle syntax:
\begin{isabelle}
~~~~{\isachardoublequoteopen}{\isasymlbrakk}\ Broadcast\ m{\isadigit{1}}\ \={\isasymsqsubset}\isactrlsup i\ Broadcast\ m{\isadigit{2}}\ \=\kill
\isacommand{inductive}\ hb\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}msg\ {\isasymRightarrow}\ {\isacharprime}msg\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}{\isasymlbrakk}\ Broadcast\ m{\isadigit{1}}\ \>{\isasymsqsubset}\isactrlsup i\ Broadcast\ m{\isadigit{2}}\ \>{\isasymrbrakk}\ {\isasymLongrightarrow}\ m{\isadigit{1}}\ $\prec$\ m{\isadigit{2}}{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}{\isasymlbrakk}\ Deliver\ m{\isadigit{1}}\ \>{\isasymsqsubset}\isactrlsup i\ Broadcast\ m{\isadigit{2}}\ \>{\isasymrbrakk}\ {\isasymLongrightarrow}\ m{\isadigit{1}}\ $\prec$\ m{\isadigit{2}}{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}{\isasymlbrakk}\ m{\isadigit{1}}\ $\prec$\  m{\isadigit{2}}{\isacharsemicolon}\ \ m{\isadigit{2}}\ $\prec$\ m{\isadigit{3}}\ \>\>{\isasymrbrakk}\ {\isasymLongrightarrow}\ m{\isadigit{1}}\ $\prec$\ m{\isadigit{3}}{\isachardoublequoteclose}
\end{isabelle}
Given this definition, we define a restricted variant of our broadcast network model by extending the $\isa{network}$ locale.
In addition to the existing $\isa{network}$ axioms, we require that if there are any happens-before dependencies between messages, they must be delivered in that order.
Concurrent messages may be delivered in any order.
\begin{isabelle}
\isacommand{locale} causal{\isacharunderscore}network\ {\isacharequal}\ network\ {\isacharplus}\\
~~~~\isakeyword{assumes}\ causal{\isacharunderscore}delivery{\isacharcolon}\\
~~~~~~~~{\isasymlbrakk}\ {\isachardoublequoteopen}Deliver\ m{\isadigit{2}}\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright};\ m{\isadigit{1}}\ $\prec$\ m{\isadigit{2}}\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ Deliver\ m{\isadigit{1}}\ {\isasymsqsubset}\isactrlsup i\ Deliver\ m{\isadigit{2}}{\isachardoublequoteclose}
\end{isabelle}
The $\isa{causal-delivery}$ axiom does not strengthen the reliability assumptions of the network: only in the case where some message $\isa{m2}$ is delivered, it requires that any causally preceding messages are delivered first.
It is still possible for some message never to be delivered.
Causal delivery is typically implemented in network protocols using vector timestamps \cite{Schwarz:1994gl,Fidge:1988tv,Raynal:1996jl}.
As these protocols are widely known and well understood, we elide any further discussion.

\subsection{Using Operations in the Network}\label{sect.network.ops}

We can now include the convergence theorem into our network model by further extending the $\isa{causal-network}$ locale.
In the new locale $\isa{network-with-ops}$ we do not assume any additional axioms; we only specialise the type variable of messages $\isacharprime\isa{msg}$ to be a pair of $\isacharprime\isa{msgid} \mathbin{\isasymtimes} \isacharprime\isa{oper}$, and we instantiate the $\isa{msg-id}$ function fixed by the $\isa{network}$ locale to be $\isa{fst}$, i.e., to return the first component $\isacharprime\isa{msgid}$ of the pair.
We also assume the existence of an interpretation function (see Section~\ref{sect.ops.interpretation}) and a fixed initial node state:
\begin{isabelle}
~~~~\isakeyword{fixes}\ \=history\ \=\kill
\isacommand{locale}\ network{\isacharunderscore}with{\isacharunderscore}ops\ {\isacharequal}\ causal{\isacharunderscore}network\ history\ fst\\
~~~~\isakeyword{for}\ \>history\ \>{\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}msgid\ {\isasymtimes}\ {\isacharprime}oper{\isacharparenright}\ event\ list{\isachardoublequoteclose}\ {\isacharplus}\\
~~~~\isakeyword{fixes}\ \>interp\ \>{\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}oper\ {\isasymRightarrow}\ {\isacharprime}state\ {\isasymRightarrow}\ {\isacharprime}state\ option{\isachardoublequoteclose}\\
~~~~\isakeyword{and}\ \>initial{\isacharunderscore}state\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}state{\isachardoublequoteclose}
\end{isabelle}
We have proved that the happens-before relation $\prec$ defined in the network is a strict partial order, so it meets the requirements of the $\isa{happens-before}$ locale.
The lemmas and definitions of this locale are therefore available to use with the happens-before relation $\prec$, and we indicate these specialised theorems and definitions by prefixing their names with $\isa{hb}$.
Moreover, we can prove that the sequence of message deliveries at any node is consistent with $\prec$, that is, it satisfies the definition of $\isa{hb-consistent}$ given in Section~\ref{sect.happens.before} (note $\isa{hb}{\isacharunderscore}\isa{consistent}$ is now prefixed):
\begin{isabelle}
\isacommand{theorem}\ \ {\isachardoublequoteopen}hb.hb{\isacharunderscore}consistent\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ i{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
\noindent
where $\isa{node-deliver-messages}$ is a function that filters the history of events at some node to return only messages that were delivered, in the order they were delivered.
Now, whenever a message is delivered at some node, we can take the operation $\isacharprime\isa{oper}$ from the message, and use its interpretation to update the state at that node.
Broadcast events do not change the state, but since every message must be delivered locally at the node where it was broadcast, the state change nevertheless takes effect locally.
We can then define the state of some node by using our definition of $\isa{apply-operations}$ from Section~\ref{sect.ops.interpretation}:
\begin{isabelle}
\isacommand{definition}\ apply{\isacharunderscore}operations\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}msgid\ {\isasymtimes}\ {\isacharprime}oper{\isacharparenright}\ event\ list\ {\isasymRightarrow}\ {\isacharprime}state\ option{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}apply{\isacharunderscore}operations\ es\ {\isasymequiv}\ hb{\isachardot}apply{\isacharunderscore}operations\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ es{\isacharparenright}\ initial{\isacharunderscore}state{\isachardoublequoteclose}
\end{isabelle}

So far we have no restriction on the operations that may be broadcast, except that they must be of some type $\isacharprime\isa{oper}$.
This suffices for some replication algorithms, but many have additional requirements regarding the contents of messages that cannot be expressed in Isabelle's type system.
As a general-purpose means of describing such requirements, the locale $\isa{network-with-constrained-ops}$ allows a replication algorithm to define a predicate $\isa{valid-msg}$ to specify whether a node is allowed to broadcast some message when in a particular state:
\begin{isabelle}
\hspace{6em}\=\kill
\isacommand{locale}\ network{\isacharunderscore}with{\isacharunderscore}constrained{\isacharunderscore}ops\ {\isacharequal}\ network{\isacharunderscore}with{\isacharunderscore}ops\ {\isacharplus}\\
~~~~\isakeyword{fixes}\ valid{\isacharunderscore}msg\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}state\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}msgid\ {\isasymtimes}\ {\isacharprime}oper{\isacharparenright}\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\\
~~~~\isakeyword{assumes}\ broadcast{\isacharunderscore}only{\isacharunderscore}valid{\isacharunderscore}msgs{\isacharcolon}\\
\>{\isachardoublequoteopen}{\isasymexists}suf{\isachardot}\ pre\ {\isacharat}\ {\isacharbrackleft}Broadcast\ m{\isacharbrackright}\ {\isacharat}\ suf\ {\isacharequal}\ history\ i\ {\isasymLongrightarrow}\\
\>{\isasymexists}state{\isachardot}\ apply{\isacharunderscore}operations\ pre\ {\isacharequal}\ Some\ state\ {\isasymand}\ valid{\isacharunderscore}msg\ state\ m{\isachardoublequoteclose}
\end{isabelle}

$\isa{broadcast-only-valid-msgs}$ is our final axiom, and it simply requires that if a node broadcasts some message, it must be valid according to the $\isa{valid-msg}$ predicate.
Since the choice of messages to broadcast is under the control of the replication algorithm, and the algorithm defines this predicate, this assumption is reasonable.

Although these six axioms are simple and uncontroversial, we believe that the set of axioms could be reduced further by defining some of the aforementioned algorithms (such as vector timestamps for causal delivery, or sequence numbers for message uniqueness) within Isabelle, and proving that the algorithms guarantee the required properties within some weaker network model.
However, doing so would lead us too far astray from the goal of proving the strong eventual consistency of CRDTs, so we leave it for future work.

The axioms of $\isa{network}{\isacharunderscore}\isa{with}{\isacharunderscore}\isa{constrained}{\isacharunderscore}\isa{ops}$ and its superlocales are consistent (in the sense that that we are unable to prove $\isa{False}$ by assuming the axioms).
We demonstrate this fact by building a trivial model of $\isa{network}{\isacharunderscore}\isa{with}{\isacharunderscore}\isa{constrained}{\isacharunderscore}\isa{ops}$ within Isabelle and showing that it satisfies all of the locale's axioms.
We elide these models here.

%To summarise, the six axioms that define our network model are as follows:
%\begin{isabelle}
%~~~~~~~~\isakeyword{and}\ \=initial{\isacharunderscore}state{\isacharcolon}\ \=~~~~~~\={\isasymrbrakk}\ \={\isachardoublequoteopen}Broadcast\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}\ \=\kill
%\isacommand{locale}\ network{\isacharunderscore}with{\isacharunderscore}constrained{\isacharunderscore}ops\ {\isacharequal}\\
%~~~~\isakeyword{fixes}\ \>history\ \>{\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}msgid\ {\isasymtimes}\ {\isacharprime}oper{\isacharparenright}\ event\ list{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\ \>interp\ \>{\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}oper\ {\isasymRightarrow}\ {\isacharprime}state\ {\isasymRightarrow}\ {\isacharprime}state\ option{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\ \>initial{\isacharunderscore}state\ \>{\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}state{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\ \>valid{\isacharunderscore}msg\ \>{\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}state\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}msgid\ {\isasymtimes}\ {\isacharprime}oper{\isacharparenright}\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\\
%~~~~\isakeyword{assumes}\ histories{\isacharunderscore}distinct{\isacharcolon}\ {\isachardoublequoteopen}distinct\ {\isacharparenleft}history\ i{\isacharparenright}{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\>delivery{\isacharunderscore}has{\isacharunderscore}a{\isacharunderscore}cause{\isacharcolon}\\
%\>\>\>{\isasymlbrakk}\ {\isachardoublequoteopen}Deliver\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}\ \>\>{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isasymexists}j{\isachardot}\ Broadcast\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ j{\isacharparenright}{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\>deliver{\isacharunderscore}locally{\isacharcolon}\ \>\>{\isasymlbrakk}\ \>{\isachardoublequoteopen}Broadcast\ m\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}\ \>{\isasymrbrakk}\ {\isasymLongrightarrow}\  Broadcast\ m\ {\isasymsqsubset}\isactrlsup i\ Deliver\ m{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\>msg{\isacharunderscore}id{\isacharunderscore}unique{\isacharcolon}\ \>\>{\isasymlbrakk}\ \>{\isachardoublequoteopen}Broadcast\ m{\isadigit{1}}\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright};\\
%\>\>\>\>Broadcast\ m{\isadigit{2}}\ {\isasymin}\ set\ {\isacharparenleft}history\ j{\isacharparenright};\\
%\>\>\>\>msg{\isacharunderscore}id\ m{\isadigit{1}}\ {\isacharequal}\ msg{\isacharunderscore}id\ m{\isadigit{2}}\ \>{\isasymrbrakk}\ {\isasymLongrightarrow}\ i\ {\isacharequal}\ j\ {\isasymand}\ m{\isadigit{1}}\ {\isacharequal}\ m{\isadigit{2}}{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\>causal{\isacharunderscore}delivery{\isacharcolon}\ \>\>{\isasymlbrakk}\ \>{\isachardoublequoteopen}Deliver\ m{\isadigit{2}}\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright};\\
%\>\>\>\>m{\isadigit{1}}\ $\prec$\ m{\isadigit{2}}\>{\isasymrbrakk}\ {\isasymLongrightarrow}\ Deliver\ m{\isadigit{1}}\ {\isasymsqsubset}\isactrlsup i\ Deliver\ m{\isadigit{2}}{\isachardoublequoteclose}\\
%~~~~~~~~\isakeyword{and}\>broadcast{\isacharunderscore}only{\isacharunderscore}valid{\isacharunderscore}ops{\isacharcolon}\\
%\>\>\>{\isasymlbrakk}\ \>{\isachardoublequoteopen}{\isasymexists}suf{\isachardot}\ pre\ {\isacharat}\ {\isacharbrackleft}Broadcast\ m{\isacharbrackright}\ {\isacharat}\ suf\ {\isacharequal}\ history\ i\ {\isasymrbrakk}\\
%\>\>\>\>{\isasymLongrightarrow}\ {\isasymexists}state{\isachardot}\ apply{\isacharunderscore}operations\ pre\ {\isacharequal}\ Some\ state\ {\isasymand}\ valid{\isacharunderscore}msg\ state\ m{\isachardoublequoteclose}
%\end{isabelle}


\RequirePackage[l2tabu, orthodox]{nag}
\documentclass{article}

\usepackage[letterpaper, margin=1.3cm]{geometry}
\usepackage{siunitx}
\usepackage{mathtools}
\usepackage{multicol}
\usepackage{pgfplots}
\usepackage{amssymb}
\usepackage{mathrsfs}
\usepackage[RPvoltages, american, betterproportions, siunitx]{circuitikz}

\pgfplotsset{compat=1.16}

\title{ECE 302 Problem Set 1}
\author{Michael Kwok}
\begin{document}

\maketitle
\begin{multicols}{2}
    \subsection*{1a}
    \begin{align*}
        r_D & = \frac{n V_T}{I_D}                                  \\
            & = \frac{1 \cdot 25\si{\milli\volt}}{0.1\si{\ampere}} \\
            & = 0.25 \si{\ohm}
    \end{align*}
    \subsection*{1b}
    \begin{align*}
        \frac{0.1}{10} & = \underline{0.01\si{\ampere}} \\
    \end{align*}
    \begin{align*}
        r_D & = \frac{n V_T}{I_D}                                   \\
            & = \frac{1 \cdot 25\si{\milli\volt}}{0.01\si{\ampere}} \\
            & = \underline{2.5 \si{\ohm}}
    \end{align*}
    \subsection*{1c}
    \[
        {\left( \frac{1}{2.5} \cdot 10 \right)}^{-1} = 0.25 \si{\ohm}
    \]
    \subsection*{1d}
    \[
        0.25 + 0.2 = 0.45\si{\ohm} \text{ in series}
    \]
    \[
        {\left( \frac{1}{2.7} \cdot 10 \right)}^{-1} = 0.27 \si{\ohm} \text{ in parallel}
    \]
    Parallel is preferable
    \subsection*{2a}

    Redraw circuit as dc:
    \begin{center}
        \begin{circuitikz}[american,]
            \draw(0,2) to[empty diode, -] (0,0) node[ground] (GND){};
            \draw(0,2) to[short, -] (1,2);
            \draw(1,0) node[ground] (GND){} to[american current source, -] (1,2);
        \end{circuitikz}
    \end{center}
    \vfill\null{}

    \columnbreak{}
    Redraw circuit as ac:
    \begin{center}
        \begin{circuitikz}[american,]
            \draw(0,0) node[ground] (GND){} to[american voltage source, -] (0,2);
            \draw(0,2) to[resistor] (2,2);
            \draw(2,2) to[empty diode, -] (2,0) node[ground] (GND){};
            \draw(2,2) to (3,2) node[ocirc]{};
        \end{circuitikz}
    \end{center}
    \vfill\null{}

    \begin{align*}
        \frac{v_o}{v_s} & = \frac{{\frac{n V_T}{I}}}{R_S \cdot \frac{n V_T}{I}} \\
                        & = \frac{nV_T}{IR_S+nV_T}
    \end{align*}
    \subsection*{2b}
    \begin{align*}
        v_o(t) & = \frac{2 \cdot 25\times 10^{-3}}{I\cdot 1000 + 2 \cdot 25\times 10^{-3}} \left(10 \cos \omega t \right) \\
               & = \frac{\frac{1}{20}}{1000I + \frac{1}{20}} \cdot 10 \cos \omega t                                       \\
               & = \frac{10}{20000I + 1} \cos\omega t
    \end{align*}
    \begin{itemize}
        \item I = \SI{1}{\micro\ampere}, \(9.8 \cos\omega t\)
        \item I = \SI{0.1}{\milli\ampere}, \(3.3 \cos\omega t\)
        \item I = \SI{1}{\milli\ampere}, \(0.48 \cos\omega t\)
    \end{itemize}
    \subsection*{2c}
    \begin{align*}
        \frac{1}{20000I + 1} & = \frac{1}{2}                       \\
        20000I + 1           & = 2                                 \\
        I                    & = \frac{1}{20000}                   \\
                             & = \underline{50 \si{\micro\ampere}}
    \end{align*}
    \subsection*{2d}
    \begin{align*}
        \text{let } v_o(t)            & = v_d(t)                        \\
        v_o(t)                        & \leq 0.1 \cdot n V_T            \\
        \frac{nV_T}{IR_S+nV_T} v_s(t) & \leq 0.1 \cdot n V_T            \\
        v_s(t)                        & \leq \underline{0.01\si{\volt}}
    \end{align*}
    \subsection*{3a}
    Redraw as dc to find combined \(r_D\):
    \begin{center}
        \begin{circuitikz}[american,]
            \draw(0,0) node[ground] (GND){} to[american current source] (0,2);
            \draw(0,2) to[short,-] (1,2);
            \draw(1,2) to[short,-] (1,1);
            \draw(1,2) to[short,-] (1,3);
            \draw(1,3) to[empty diode] (2,3) to[empty diode] (3,3);
            \draw(1,1) to[empty diode] (2,1) to[empty diode] (3,1);
            \draw(3,3) to[short,-] (3,2);
            \draw(3,1) to[short,-] (3,2);
            \draw(3,2) to[short,-] (4,2);
            \draw(4,2) to[american current source] node[ground] (GND){} (4,0);
        \end{circuitikz}
    \end{center}
    \[r_{D1} = r_{D2} =r_{D3} =r_{D4}\]
    \begin{align*}
        {\left({\left( \frac{V_T}{0.5 I} \cdot 2 \right)}^{-1} \cdot 2 \right)}^{-1} &                  \\
        {\left({\left( \frac{4V_T}{I}\right)}^{-1} \cdot 2 \right)}^{-1}             & = \frac{2V_T}{I}
    \end{align*}
    \begin{align*}
        \frac{v_o}{v_i} & = \frac{R}{R+\frac{2 V_T}{I}} \\
                        & =\frac{RI}{RI+2 V_T}
    \end{align*}
    \subsection*{3b}
    \begin{itemize}
        \item I = \SI{1}{\micro\ampere}, \(\frac{10000 \times 10^{-6}}{10000 \times10^{-6} + 2\cdot 25\times10^{-3}}\)
        \item I = \SI{10}{\micro\ampere}, \(\frac{10000 \cdot 10 \times 10^{-6}}{10000 \cdot 10\times10^{-6} + 2\cdot 25\times10^{-3}}\)
        \item I = \SI{100}{\micro\ampere}, \(\frac{10000 \cdot 100 \times 10^{-6}}{10000 \cdot 100 \times10^{-6} + 2\cdot 25\times10^{-3}}\)
    \end{itemize}
    \subsection*{3c}
    \[
        \frac{n V_T}{v_d} \geq 10
    \]
    \begin{align*}
        v_i - v_o & = 2 v_d               \\
        -v_o      & = 2v_d - v_i          \\
        v_d       & \leq 2.6\times10^{-3}
    \end{align*}
    \begin{align*}
        v_o \left( IR + 2V_T \right)    & = IR V_T \\
        v_o IR + v_o 2 V_T              & = IRV_T  \\
        IR(-2v_d) + (v_i - 2 v_d) 2 V_T & = 0
    \end{align*}
    \begin{align*}
        -20000Iv_d + (0.01 - 2 v_d) 0.05      & = 0 \\
        -20000Iv_d + 5\times10^{-4} - 0.1 v_d & = 0
    \end{align*}
    \[
        \frac{5\times 10^{-4}}{20000I + 0.1} = v_d
    \]
    \begin{align*}
        5\times 10^{-4} & \leq \left( 2.5\times10^{-3} \right)\left( 20000I + 0.1 \right) \\
        5\times10^{-4}  & = I                                                             \\
        I               & \geq \underline{5 \si{\micro\ampere}}
    \end{align*}
    \subsection*{4}
    Redraw circuit as dc:
    \begin{center}
        \begin{circuitikz}[american,]
            \draw(0,0) node[ground] (GND){} to[american current source, -] (0,2);
            \draw(0,2) to[short, -] (1,2);
            \draw(1,2) to[empty diode, -] (1,0) node[ground] (GND){};
        \end{circuitikz}
    \end{center}

    Redraw circuit as ac:
    \begin{center}
        \begin{circuitikz}[american,]
            \draw(0,0) node[ground] (GND){} to[american voltage source, -] (0,2);
            \draw(1,2) to[empty diode, -] (0,2);
            \draw(1,2) to[capacitor] (2,2) to (3,2) node[ocirc]{};
            \draw(2,2) to[resistor] (2,0) node[ground] (GND){};
        \end{circuitikz}
    \end{center}
    Do phasor analysis ala 203:

    \begin{align*}
        s      & = j \omega                       \\
        \omega & = 2\pi f                         \\
               & = 2\pi \cdot 100\si{\kilo\hertz}
    \end{align*}
    \begin{align*}
        \frac{\tilde{V_O}}{\tilde{V_I}} & = \frac{R}{R + r_D + \frac{1}{sC}}                                                                             \\
                                        & = \frac{RsC}{1 + (R + r_D) sC}                                                                                \\
                                        & \text{Rationalize complex fraction:}                                                                           \\
                                        & = \frac{RsC - RsC(R+r_D)sC}{1-{(R + r_D)}^2 +s^2 C^2}                                                          \\
                                        & = \frac{RsC + R(R+r_D)\omega^2C^2}{1+{(R + r_D)}^2 +\omega^2 C^2}                                              \\
                                        & = \frac{R(R+r_D)\omega^2C^2}{1+{(R + r_D)}^2 +\omega^2 C^2}+ \frac{R\omega C}{1+{(R + r_D)}^2 +\omega^2 C^2} j
    \end{align*}
    Find phase angle:
    \begin{align*}
        \tan^{-1} \left(\frac{R\omega C}{R(R+r_D)\omega^2C^2}\right) & = \tan^{-1} \left(\frac{1}{(R+r_D)\omega C}\right) \\
                                                                     & = \ang{45}                                         \\
        (R+r_D)\omega C                                              & =1                                                 \\
        \frac{1-R\omega C}{\omega C}                                 & = r_D
    \end{align*}
    \begin{align*}
        109.154 & = \frac{2.5\times 10^{-3}}{I}     \\
        I       & = 2.29\times 10^{-4} \si{\ampere} \\
                & = 229 \si{\micro\ampere}
    \end{align*}
\end{multicols}
\end{document}