\section{Algorithmic Verification}\label{sec:algorithmic}

Next, we describe \smtlan, a conservative approximation
of \corelan where the undecidable type subsumption rule
is replaced with a decidable one, yielding an SMT-based
algorithmic type system that enjoys the same soundness
guarantees.

\subsection{The SMT logic \smtlan}

\input{text/refinementreflection/smtsyntax}

\mypara{Syntax: Terms \& Sorts}
%
Figure~\ref{fig:smtsyntax} summarizes the syntax
of \smtlan, the \emph{sorted} (SMT-)
decidable logic of quantifier-free equality,
uninterpreted functions and linear
arithmetic (QF-EUFLIA) ~\citep{Nelson81,SMTLIB2}.
%
The \emph{terms} of \smtlan include
integers $n$,
booleans $b$,
variables $x$,
data constructors $\dc$ (encoded as constants),
fully applied unary \unop and binary \binop operators,
and application $x\ \overline{\pred}$ of an uninterpreted function $x$.
%
The \emph{sorts} of \smtlan include built-in
integer \tint and \tbool for representing
integers and booleans.
%
%% NV reflected functions and measures are first order
%% NV because
%% NV 1. they can be partially applied
%% NV 2. they can be passed as arguments
The interpreted functions of \smtlan, \eg
the logical constants $=$ and $<$,
%% NV and the uninterpreted functions app and lam
%% NV but we have not introduced these yet
have the function sort $\sort \rightarrow \sort$.
%
Other functional values in \corelan, \eg
reflected \corelan functions and
$\lambda$-expressions, are represented as
first-order values with
uninterpreted sort \tsmtfun{\sort}{\sort}.
%
%%The uninterpreted functions of \smtlan, which
%%correspond to reflected \corelan functions,
%%have the function sort $\sort \rightarrow \sort$.
%%%
%%Other functional values in \corelan, \eg
%%$\lambda$-expressions, are represented as
%%first-order values in \smtlan with
%%uninterpreted sort \tsmtfun{\sort}{\sort}.
%%%
The universal sort \tuniv represents all other values.

\mypara{Semantics: Satisfaction \& Validity}
%
An assignment $\sigma$ is a mapping from
variables to terms
%
${\sigma \defeq \{ \assignto{x_1}{\pred_1}, \ldots, \assignto{x_n}{\pred_n} \}}$.
%
We write
%
${\sigma \models \pred}$
%
if the assignment $\sigma$ is a
\emph{model of} $\pred$, intuitively
if $\sigma\ \pred$ ``is true''~\cite{Nelson81}.
%
A predicate $\pred$ \emph{is satisfiable} if
there exists ${\sigma\models\pred}$.
%
A predicate $\pred$ \emph{is valid} if
for all assignments ${\sigma\models\pred}$.

\subsection{Transforming \corelan into \smtlan}
%
\label{subsec:embedding}

\input{text/refinementreflection/defuncrules}
%
The judgment
\tologicshort{\env}{e}{\typ}{\pred}{\sort}{\smtenv}{\axioms}
states that a $\corelan$ term $e$ is transformed,
under an environment $\env$, into a
$\smtlan$ term $\pred$.
%
The transformation rules are summarized in Figure~\ref{fig:defunc}.

\mypara{Embedding Types}
%
We embed \corelan types into \smtlan sorts as:
%
$$
\begin{array}{rclcrcl}
\embed{\tint}                       & \defeq &  \tint &  &
\embed{T}                           & \defeq &  \tuniv \\
\embed{\tbool}                      & \defeq &  \tbool & &
\embed{\tfun{x}{\typ_x}{\typ}} & \defeq & \tsmtfun{\embed{\typ_x}}{\embed{\typ}}
\end{array}
$$
%%%The embedding extends to typing environments:
%%%% by embedding the types of the environment
%%%$$
%%%\embedsort{\{\tbind{x_1}{\typ_1}, \dots, \tbind{x_n}{\typ_n}\}}
%%%  \defeq
%%%  \{\tbind{x_1}{\embed{\typ_1}}, \dots, \tbind{x_n}{\embed{\typ_n}}
%%%  \}
%%%$$

\mypara{Embedding Constants}
%
Elements shared on both \corelan and \smtlan
translate to themselves.
%
These elements include
booleans (\lgbool),
integers (\lgint),
variables (\lgvar),
binary (\lgbinGEN)
and unary (\lgun)
operators.
%
SMT solvers do not support currying,
and so in \smtlan, all function symbols
must be fully applied.
%
Thus, we assume that all applications
to primitive constants and data
constructors are \emph{saturated},
%% NV eta converted
\ie fully applied, \eg by converting
source level terms like @(+ 1)@ to
@(\z -> z + 1)@.
%

%%% Thus, to translate \corelan's partially applied operators,
%%% we define an uninterpreted function
%%% $$
%%% \tbind{\smtvar{c}}{\embed{\constty{c}}}
%%% $$
%%% for every functional constant $c$ in \corelan.
%%% %
%%% For example, $+ 1$ will be translated to application of $\smtvar{+}$ to $1$, while
%%% $1+2$ will be translated to the identical $1+2$.

%%\spara{Lambda Lifting}
%%%
%%Since \smtlan does not support $\lambda$-functions.
%%the translation lifts function to axiomatized variables.
%%%
%%Rule~\lgfun
%%translates the term $\efun{x}{\typ}{e}$ to
%%a fresh variable $f$ that satisfies two axioms:
%%(1). $\beta$-reduction,
%%that is $f$ applied to $x$ is equal to $e$, and
%%(2). extentionality,
%%that is for every other function $g$ and argument $x$,
%%if $f$ applied to $x$ is equal to $g$ applied to $x$,
%%then $f = g$.

\mypara{Embedding Functions}
%
As \smtlan is a first-order logic, we
embed $\lambda$-abstraction and application
using the uninterpreted functions
\smtlamname{}{} and \smtappname{}{}.
%
We embed $\lambda$-abstractions
using $\smtlamname{}{}$ as shown in rule~\lgfun.
%
The term $\efun{x}{}{e}$ of type
${\typ_x \rightarrow \typ}$ is transformed
to
${\smtlamname{\sort_x}{\sort}\ x\ \pred}$
of sort
${\tsmtfun{\sort_x}{\sort}}$, where
%
$\sort_x$ and $\sort$ are respectively
$\embed{\typ_x}$ and $\embed{\typ}$,
%
${\smtlamname{\sort_x}{\sort}}$
is a special uninterpreted function
of sort
${\sort_x \rightarrow \sort\rightarrow\tsmtfun{\sort_x}{\sort}}$,
and
$x$ of sort $\sort_x$ and $r$ of sort $\sort$ are
the embedding of the binder and body, respectively.
%
As $\smtlamname{}{}$ is just an SMT-function,
it \emph{does not} create a binding for $x$.
%
Instead, the binder $x$ is renamed to
a \emph{fresh} name pre-declared in
the SMT environment.

\mypara{Embedding Applications}
%
Dually, we embed applications via
defunctionalization~\citep{Reynolds72}
using an uninterpreted \emph{apply}
function
$\smtappname{}{}$ as shown in rule~\lgapp.
%
The term ${e\ e'}$, where $e$ and $e'$ have
types ${\typ_x \rightarrow \typ}$ and $\typ_x$,
is transformed to
${\tbind{\smtappname{\sort_x}{\sort}\ \pred\ \pred'}{\sort}}$
where
%
$\sort$ and $\sort_x$ are respectively $\embed{\typ}$ and $\embed{\typ_x}$,
the
${\smtappname{\sort_x}{\sort}}$
is a special uninterpreted function of sort
${\tsmtfun{\sort_x}{\sort} \rightarrow \sort_x \rightarrow \sort}$,
and
$\pred$ and $\pred'$ are the respective translations of $e$ and $e'$.

\mypara{Embedding Data Types}
%
Rule~\lgdc translates each data constructor to a
predefined \smtlan constant ${\smtvar{\dc}}$ of
sort ${\embed{\constty{\dc}}}$.
%
Let $\dc_i$ be a non-boolean data constructor such that
$$
\constty{\dc_i} \defeq \typ_{i,1} \rightarrow \dots \rightarrow \typ_{i,n} \rightarrow \typ
$$
Then the \emph{check function}
${\checkdc{{\dc_i}}}$ has the sort
$\tsmtfun{\embed{\typ}}{\tbool}$,
and the \emph{select function}
${\selector{\dc}{i,j}}$ has the sort
$\tsmtfun{\embed{\typ}}{\embed{\typ_{i,j}}}$.
%
Rule~\lgcase translates case-expressions
of \corelan into nested $\mathtt{if}$
terms in \smtlan, by using the check
functions in the guards, and the
select functions for the binders
of each case.
%
%\mypara{Reflecting DataTypes}
%
% The above approach  makes it straightforward
% to reflect functions over datatypes into \smtlan.
%
For example, following the above, the body of the list append function
%
%%% reflect (++) :: xs:[Int] -> ys:[Int] -> [Int]
\begin{code}
  []     ++ ys = ys
  (x:xs) ++ ys = x : (xs ++ ys)
\end{code}
%
is reflected into the \smtlan refinement:
%
$$
\ite{\mathtt{isNil}\ \mathit{xs}}
    {\mathit{ys}}
    {\mathtt{sel1}\ \mathit{xs}\
       \dcons\
       (\mathtt{sel2}\ \mathit{xs} \ \mathtt{++}\  \mathit{ys})}
$$
%
We favor selectors to the axiomatic translation of
HALO~\citep{halo} and \fstar~\cite{fstar} to avoid
universally quantified formulas and the resulting
instantiation unpredictability.

%% $$
%% \tbind{\checkdc{\dc}}{\embed{\typ \rightarrow \tbool}}
%% \ \text{with}\ \constty{\dc} = \typ_1 \rightarrow \dots \rightarrow \typ_n\rightarrow\typ
%% $$
%% and the field selector is used to substitute the data constructor quantified variables $\overline{y_i}$:
%% eg. if \dc is [] then i == 0
%%     if \dc is (:) :: a -> [a] -> [a] then
%%         \dc_1 = head :: [a] -> a
%%         \dc_2 = tail :: [a] -> [a]
%% $$
%% \tbind
      %% {\embed{\typ \rightarrow \typ_i}}
%% \ \text{with}\ \constty{\dc} = \typ_1 \rightarrow \dots \rightarrow \typ_n\rightarrow\typ, i \leq n
%% $$
%% %
%% For example, the body of the @length@ function from~\S~\ref{sec:examples}
%% translates to the condition $\eif{\isN\ xs}{0}{1+\texttt{length} (\etail\ xs)}$,
%% as $\etail \defeq \selector{\dcons}{2}$.

\subsection{Correctness of Translation}

Informally, the translation relation $\tologicshort{\env}{e}{}{\pred}{}{}{}$
is correct in the sense that if $e$ is a terminating boolean expression
then $e$ reduces to \etrue \textit{iff} $\pred$ is SMT-satisfiable
by a model that respects $\beta$-equivalence.

%%\mypara{Type Preservation}
%%%
%%The \emph{initial environment} \smtenvinit
%%maps the uninterpreted symbols used
%%by the translation, namely
%%%
%%$\smtlamname{}{}$,
%%$\smtappname{}{}$,
%%$\smtvar{\dc}$,
%%$\checkdc{{\dc_i}}$,
%%$\selector{\dc}{{i,j}}$
%%and fresh binder names $x$ used  in $\smtlamname{}{}$
%%to their respective sorts.
%%%
%%The judgment $\smthastype{\smtenv}{\pred}{\sort}$ states
%%that the term $\pred$ has sort $\sort$ in environment
%%$\smtenv$. (We omit the standard derivation rules
%%for brevity.)
%%%
%%The translation is type (sort) preserving.
%%
%%\begin{lemma}
%%%  [Type Transformation]
%%If \tologicshort{\env}{e}{\typ}{p}{\sort}{\smtenv}{\axioms},
%%and \hastype{\env}{e}{\typ}, then
%%\smthastype{\smtenvinit, \embedsort{\env}}{p}{\embed{\typ}}.
%%\end{lemma}
%%
%%% are defined in the
%%% %
%%% Thus, \smtenvinit includes
%%% $$
%%% \begin{array}{rcll}
%%% \smtvar{c}  &\colon &\embed{\constty{c}}
  %%% &\forall c\in \corelan\\
%%% \smtlamname{\sort_x}{\sort}&\colon&\sort_x \rightarrow \sort\rightarrow\tsmtfun{\sort_x}{\sort}
  %%% &\forall \sort_x, \sort\in \smtlan\\
%%% \smtappname{\sort_x}{\sort}&\colon&\tsmtfun{\sort_x}{\sort} \rightarrow \sort_x \rightarrow \sort
  %%% &\forall \sort_x, \sort\in \smtlan\\
%%% \smtvar{\dc}&\colon&\embed{\constty{\dc}}
  %%% &\forall\dc\in\corelan\\
%%% \checkdc{\dc}&\colon&\embed{T \rightarrow \tbool}
  %%% &\forall \dc\in \corelan\ \text{of data type}\ T \\
%%% \selector{\dc}{i}&\colon&\embed{T \rightarrow \typ_i}
  %%% &\forall \dc\in \corelan\ \text{of data type}\ T \\
  %%% &&&\text{and}\ i\text{-th argument}\ \typ_i \\
%%% {x} & \colon&{\sort}&\text{for each lambda argument} \\
%%% \end{array}
%%% $$

% \mypara{Lifted Substitutions}

%
%% as defined
%% in~\citep{Vazou15} remove bottoms from expressions
%% in substitutions and translate via
%% \tologic{\emptyset}{\star}{}{\star}{}{}{}
%% to a set of models $\sigma \in \theta^\perp$
%% where each bottom maps to
%% %
%%
%% Such models $\sigma \in \theta^\perp$
%% map variables in $\theta$ to values
%% in the logic, without providing
%% interpretations for the
%% $\smtlamname{}{}$ and $\smtappname{}{}$.

\NV{below we use substitution in lambda s which is not formally defined}
%
\begin{definition}[$\beta$-Model]\label{def:beta-model}
A $\beta-$model $\bmodel$ is an extension of a model $\sigma$
where $\smtlamname{}{}$ and $\smtappname{}{}$
satisfy the axioms of $\beta$-equivalence:
$$
\begin{array}{rcl}
\forall x\ y\ e. \smtlamname{}{}\ x\ e
  & = & \smtlamname{}{}\ y\ (e\subst{x}{y}) \\
\forall x\ e_x\ e. (\smtappname{}{}\ (\smtlamname{}{}\ x\ e)\ e_x
  & = &  e\subst{x}{e_x}
\end{array}
$$
\end{definition}

\mypara{Semantics Preservation}
%
We define the translation of a \corelan term
into \smtlan under the empty environment as
${\embed{e} \defeq \pred}$
if ${\tologicshort{\emptyset}{\refa}{}{\pred}{}{}{}}$.
%
A \emph{lifted substitution}
$\theta^\perp$ is a set of models $\sigma$
where each ``bottom'' in the substitution
$\theta$ is mapped to an arbitrary logical
value of the respective sort~\citep{Vazou14}.
%
We connect the semantics of \corelan and translated
\smtlan via the following theorems:
% terms can connect evaluation of boolean
% \corelan expression to \smtlan predicates.

\begin{theorem}\label{thm:embedding-general}
If ${\tologicshort{\env}{\refa}{}{\pred}{}{}{}}$,
then for every ${\sub\in\interp{\env}}$
and every ${\sigma\in {\sub^\perp}}$,
if $\evalsto{\applysub{\sub^\perp}{\refa}}{v}$
then $\sigma^\beta \models \pred = \embed{v}$.
\end{theorem}

% For Boolean expressions we specialize the above to

\begin{corollary}\label{thm:embedding}
If ${\hastype{\env}{\refa}{\tbool}}$, $e$ reduces to a value and
${\tologicshort{\env}{\refa}{\tbool}{\pred}{\tbool}{\smtenv}{\axioms}}$,
then for every ${\sub\in\interp{\env}}$
and every ${\sigma\in {\sub^\perp}}$,
$\evalsto{\applysub{\sub^\perp}{\refa}}{\etrue}$ iff
$\sigma^\beta \models \pred$.
\end{corollary}

\subsection{Decidable Type Checking}
\begin{figure}[t!]
\centering
$$
\begin{array}{rrcl}
\emphbf{Refined Types} \quad
  & \typ
  & ::=   & \tref{v}{\btyp^{[\tlabel]}}{\reft} \spmid \tfun{x}{\typ}{\typ}
\\[0.10in]
\end{array}
$$
\emphbf{Well Formedness}\hfill{\fbox{\aiswellformed{\env}{\typ}}}\\
$$
\inference{
  \ahastype{\env,\tbind{v}{\btyp}}{\refa}{\tbool^{\tlabel}}
}{
  \aiswellformed{\env}{\tref{v}{\btyp}{\refa}}
}[\rwbase]
$$
\emphbf{Subtyping}\hfill{\fbox{\aissubtype{\env}{\typ}{\typ'}}}\\
$$
\inference{
\env' \defeq \env,\tbind{v}{\{\btyp^\tlabel | \refa\}} &
\tologicshort{\env'}{\refa'}{\tbool}{\pred'}{}{}{} &
\smtvalid{\vcond{\env'}{\pred'}}
%
}{
 \aissubtype{\env}{\tref{v}{\btyp}{\refa}}{\tref{v}{\btyp}{\refa'}}
}[\rsubbase]
$$
%%%% %\NV{REVERT TO OLD DEFINITIONS, what is e'?}
%%%% $$
%%%% \inference{
%%%% \tologicshort{\env'}{\refa_1}{\tbool}{\pred_1}{\tbool}{\smtenv_1}{\axioms_1} &
%%%% \tologicshort{\env'}{\refa_2}{\tbool}{\pred_2}{\tbool}{\smtenv_1}{\axioms_1} \\
%%%% % \isvalid{\env,\tbind{v}{\btyp}}{\refa_1}{\refa_2}
%%%% \env' \defeq \env,\tbind{v}{\btyp^\tlabel} &
%%%% % \tologicshort{\env'}{\refa'}{\tbool}{\pred'}{\tbool}{\smtenv'}{\axioms'} &
%%%% \smtvalid{\vcond{\env'}{\pred_1 \Rightarrow \pred_2}}
%%%% %
%%%% }{
  %%%% \aissubtype{\env}{\tref{v}{\btyp}{\refa_1}}{\tref{v}{\btyp}{\refa_2}}
%%%% }[\rsubbase]
%%%% $$
%%% \emphbf{Implication}\hfill{\isvalid{\env}{\refa_1}{\refa_2}}\\
%%% $$
%%% \inference{
  %%% \tologicshort{\env}{\refa_1}{\tbool}{\pred_1}{\tbool}{\smtenv_1}{\axioms_1} &
  %%% \tologicshort{\env}{\refa_2}{\tbool}{\pred_2}{\tbool}{\smtenv_2}{\axioms_i} \\
  %%% \text{is SMT-valid}\ (\embedexpr{\env} \Rightarrow \pred_1 \Rightarrow \pred_2)
%%% }{
  %%% \isvalid{\env}{\refa_1}{\refa_2}
%%% }
%%% $$
%%% \emphbf{Typing}\hfill{\ahastype{\env}{\prog}{\typ}}\\
\caption{\textbf{Algorithmic Typing (other rules in Figs~\ref{fig:syntax} and \ref{fig:typing}.)}}
\label{fig:modifications}
\end{figure}

Figure~\ref{fig:modifications} summarizes the modifications required
to obtain decidable type checking.
%
Namely, basic types are extended with labels that track termination
and subtyping is checked via an SMT solver.

\mypara{Termination}
%
Under arbitrary beta-reduction semantics
(which includes lazy evaluation), soundness
of refinement type checking requires checking
termination, for two reasons:
%
(1)~to ensure that refinements cannot diverge, and
(2)~to account for the environment during subtyping~\citep{Vazou14}.
%
We use \tlabel to mark provably terminating
computations, and extend the rules to use
refinements to ensure that if
${\ahastype{\env}{e}{\tref{v}{\btyp^\tlabel}{r}}}$,
then $e$ terminates~\citep{Vazou14}.
%
%% Here we assume termination is checked by an oracle,
%% but we can use refinement types themselves to prove
%% correctness of the termination labeling

\mypara{Verification Conditions}
The \emph{verification condition} (VC)
${\vcond{\env}{\pred}}$
is \emph{valid} only if the set of values
described by $\env$, is subsumed by
the set of values described by $\pred$.
%
$\env$ is embedded into logic by conjoining
(the embeddings of) the refinements of
provably terminating binders~\cite{Vazou14}:
%
%% We only trust refinements of terminating
%% expressions, as every diverging expression
%% can be unsoundly refined \efalse.
%% $$
%% \embed{\env} \defeq
  %% \bigwedge\{ p \mid \tbind{x}{\tref{v}{\btyp^{\tlabel}}{e}} \in \env
   %% \land \tologicshort{\env}{e\subst{v}{x}}{\btyp}{p}{\embed{\btyp}}{\smtenv}{\axioms}
   %% \}
%% $$
\begin{align*}
\embed{\env} \defeq & \bigwedge_{x \in \env} \embed{\env, x} \\
\intertext{where we embed each binder as}
\embed{\env, x} \defeq & \begin{cases}
                           \pred  & \text{if } \env(x)=\tref{v}{\btyp^{\tlabel}}{e},\
                                    \tologicshort{\env}{e\subst{v}{x}}{\btyp}{\pred}{\embed{\btyp}}{\smtenv}{\axioms} \\
                           \etrue & \text{otherwise}.
                         \end{cases}
\end{align*}

%We use the embedding of environment to decidably check subtyping.
%As defined in Figure~\ref{fig:modifications},
%\tref{v}{\btyp}{\refa_1} is subtype of \tref{v}{\btyp}{\refa_1}
%under the environment \env, when
%$\refa_i$ transforms to $\pred_i$ with axioms $\axioms_i$
%and assuming $\embedexpr{\env}$ and the axioms $\axioms_i$
%$\pred_i$ implies $\pred_2$.

\mypara{Subtyping via SMT Validity}
%
We make subtyping, and hence, typing decidable,
by replacing the denotational base subtyping
rule $\rsubbase$ with a conservative,
algorithmic version that uses an SMT
solver to check the validity of the subtyping VC.
%
We use Corollary~\ref{thm:embedding} to prove
soundness of subtyping.
%
\begin{lemma}\label{lem:subtyping} %[Conservative Subtyping]
If {\aissubtype{\env}{\tref{v}{\btyp}{e_1}}{\tref{v}{\btyp}{e_2}}}
then {\issubtype{\env}{\tref{v}{\btyp}{e_1}}{\tref{v}{\btyp}{e_2}}}.
\end{lemma}

%
\mypara{Soundness of \smtlan}
%
Lemma~\ref{lem:subtyping} directly implies the soundness of \smtlan.
%
\begin{theorem}[Soundness of \smtlan]\label{thm:soundness-smt}
If \ahastype{\env}{e}{\typ} then \hastype{\env}{e}{\typ}.
\end{theorem}

\begin{comment}
\begin{proof}
By rule \rsubbase, we need to show that
$\forall \sub\in\interp{\env}.
  \interp{\applysub{\sub}{\tref{v}{\btyp}{\refa_1}}}
  \subseteq
  \interp{\applysub{\sub}{\tref{v}{\btyp}{\refa_2}}}$.
%
We fix a $\sub\in\interp{\env}$.
and get that forall bindings
$(\tbind{x_i}{\tref{v}{\btyp^{\downarrow}}{\refa_i}}) \in \env$,
$\evalsto{\applysub{\sub}{e_i\subst{v}{x_i}}}{\etrue}$.

Then need to show that for each $e$,
if $e \in \interp{\applysub{\sub}{\tref{v}{\btyp}{\refa_1}}}$,
then $e \in \interp{\applysub{\sub}{\tref{v}{\btyp}{\refa_2}}}$.

If $e$ diverges then the statement trivially holds.
Assume $\evalsto{e}{w}$.
We need to show that
if $\evalsto{\applysub{\sub}{e_1\subst{v}{w}}}{\etrue}$
then $\evalsto{\applysub{\sub}{e_2\subst{v}{w}}}{\etrue}$.

Let \vsub the lifted substitution that satisfies the above.
Then  by Lemma~\ref{thm:embedding}
for each model $\bmodel \in \interp{\vsub}$,
$\bmodel\models\pred_i$, and $\bmodel\models q_1$
for
$\tologicshort{\env}{e_i\subst{v}{x_i}}{\btyp}{\pred_i}{\embed{\btyp}}{\smtenv_i}{\axioms_i}$
$\tologicshort{\env}{e_i\subst{v}{w}}{\btyp}{q_i}{\embed{\btyp}}{\smtenv_i}{\beta_i}$.
%
Since \aissubtype{\env}{\tref{v}{\btyp}{e_1}}{\tref{v}{\btyp}{e_2}} we get
$$
\bigwedge_i \pred_i
\Rightarrow q_1 \Rightarrow q_2
$$
thus $\bmodel\models q_2$.
%
By Theorem~\ref{thm:embedding} we get $\evalsto{\applysub{\sub}{\refa_2\subst{v}{w}}}{\etrue}$.
\end{proof}
\end{comment}


\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{mathpartir}

\newcommand{\Addr}{a}

\newcommand{\KVAR}{\kappa}
\newcommand{\ONE}{\circ}
\newcommand{\MANY}{\ast}

\newcommand{\KINDU}{\textbf{U}}
\newcommand{\KINDA}{\textbf{A}}

\newcommand{\BORROW}[1][\iota]{\&^{#1}\,}

\newcommand{\TASS}[1]{#1\colon\!}

\newcommand{\TVAR}{\alpha}
\newcommand{\TALL}[2]{\forall\TASS{#1}#2.}
\newcommand{\KALL}[1]{\forall#1.}

\newcommand{\LAM}[3][{}]{\lambda^{#1}\TASS{#2}#3.}
\newcommand{\APP}[1]{#1\,}
\newcommand{\TLAM}[3][{}]{\Lambda^{#1}\TASS{#2}#3.}
\newcommand{\TAPP}[2]{#1\,[#2]}
\newcommand{\KLAM}[2][{}]{\Lambda^{#1}#2.}
\newcommand{\KAPP}[2]{#1\,\{#2\}}

\newcommand{\KENV}{\Delta}
\newcommand{\KENVEMPTY}{\Diamond}
\newcommand{\TENV}{\Gamma}
\newcommand{\TENVEMPTY}{\Diamond}

\newcommand{\SPLIT}[3]{#1 \ltimes #2 = #3} % used to be \bowtie

\newcommand\stepsto{\longrightarrow}

\newtheorem{lemma}{Lemma}

\title{$F^{\ONE}$ with subkinding}
\author{Peter Thiemann}

\begin{document}
\maketitle
Syntax and rules updated --- possibly inconsistent

Syntax (perhaps more expressions are needed)
\begin{align*}
  k &::= \KVAR \mid \ONE \mid \MANY & \text{kinds, where }  \MANY \sqsubseteq \ONE \\
    &\mid k \to k & \text{constructor kinds}\\
    &\mid k \le k \Rightarrow k & \text{constrained kinds}\\
    &\mid \KALL\KVAR k & \text{universal kinds}\\
    % &\mid k \le k \Rightarrow k & \text{constrained kinds}\\
  t &::= \TVAR \mid t \stackrel{k}{\to} t \mid \TALL\TVAR k t \mid \KALL\KVAR t \mid k \le k \Rightarrow t & \text{types} \\
    & \mid \LAM\TVAR k t \mid \APP tt \mid \KLAM\KVAR t \mid \KAPP t k  & \text{constructors} \\
  e &::= x \mid \LAM[k] x t e \mid \APP ee \mid \TLAM[k] \TVAR k v \mid \TAPP et \mid \KLAM[k] \KVAR v \mid \KAPP ek & \text{expressions} \\
  v &::=  \LAM[k] x t e \mid  \TLAM[k] \TVAR k v \mid \KLAM[k]\KVAR v & \text{values}
  \\
  \TENV &::=
          \TENVEMPTY
          \mid \TENV, \TASS x t
                                    & \text{type environments}
  \\
  \KENV &::= \KENVEMPTY
          \mid \TENV, \TASS \TVAR k
          \mid \TENV, k \le k
          \mid \TENV, \KVAR
                                    & \text{kind environments}
\end{align*}
%
Kind environment formation
\begin{mathpar}
  \inferrule{}{\KENVEMPTY \models }

  \inferrule{\KENV \models \\ \KENV \vdash k \\ \TVAR\notin\KENV }{\KENV, \TASS\TVAR{k} \models}

  \inferrule{\KENV \models  \\ \KENV \vdash k_1, k_2}{\KENV, k_1 \le k_2 \models}

  \inferrule{\KENV \models \\ \KVAR\notin \TENV}{\KENV, \KVAR \models }
\end{mathpar}
Kind formation
\begin{mathpar}
  \inferrule{\KENV, \KVAR, \KENV' \models}{\KENV, \KVAR, \KENV' \vdash \KVAR }

  \inferrule{\KENV \models}{\KENV \vdash \ONE}

  \inferrule{\KENV \models}{\KENV \vdash \MANY}

  \inferrule{\KENV \vdash k_1, k_2}{\KENV \vdash k_1 \to k_2}

  \inferrule{\KENV, \KVAR \vdash k}{\KENV \vdash \KALL\KVAR k}
  %
  % \inferrule{\KENV, k_1 \le k_2 \vdash k_3}{\KENV \vdash k_1 \le k_2 \Rightarrow k_3}
\end{mathpar}
Subkinding
\begin{mathpar}
  \inferrule{\KENV \models\\k_1 \sqsubseteq k_2}{\KENV \vdash k_1 \le k_2}

  \inferrule{\KENV \vdash \KVAR}{\KENV \vdash \KVAR \le \KVAR}

  \inferrule{\KENV, k_1 \le k_2, \KENV' \models}{\KENV, k_1 \le k_2, \KENV' \vdash k_1 \le k_2}

  \inferrule{\KENV \vdash k_2 \le k_1 \\ \KENV \vdash k_1' \le k_2'}{\KENV \vdash k_1 \to k_1' \le k_2 \to k_2'}

  \inferrule{\KENV, \KVAR \vdash k_1 \le k_2}{\KENV \vdash \KALL\KVAR k_1 \le \KALL\KVAR k_2}

  % \inferrule[HOW?]{}{\KENV \vdash (k_1 \le k_2 \Rightarrow k_3) \le (k_1' \le k_2' \Rightarrow k_3')}
  %
  \inferrule{\KENV \vdash k_1 \le k_2 \\\KENV \vdash k_2 \le k_3}{\KENV \vdash k_1 \le k_3}
\end{mathpar}
Kinding
\begin{mathpar}
  \inferrule[KSub]{\KENV \vdash t : k \\ \KENV \vdash k \le k' }{\KENV \vdash t : k'}

  \inferrule[KFun]{\KENV \vdash t_1 : \ONE \\ \KENV \vdash t_2 : \ONE}{ \KENV \vdash t_1 \stackrel{k}{\to} t_2 : k}

  \inferrule[KVar]{}{\KENV, \TVAR:k, \KENV' \vdash \TVAR:k}

  \inferrule[KTAll]{\KENV \vdash k\\ \KENV, \TVAR:k \vdash t:k' \\ \TVAR \notin \KENV}{\KENV \vdash \TALL\TVAR k t : k'}

  \inferrule[KKAll]{\KENV, \KVAR \vdash t: k \\ \KVAR \notin \KENV}{\KENV \vdash \KALL\KVAR t : k}

  \inferrule[KConst]{\KENV \vdash k_1, k_2 \\
    \KENV, k_1 \le k_2 \vdash t : k}{\KENV \vdash k_1 \le k_2 \Rightarrow t : k}

  \inferrule[KTLam]{\KENV, \TVAR:k \vdash t : k'}{\KENV \vdash \LAM\TVAR k t : k \to k'}

  \inferrule[KTApp]{\KENV \vdash t_1 : k_2 \to k_1 \\ \KENV \vdash t_2 : k_2}{\KENV \vdash \APP{t_1}{t_2} : k_1}

  \inferrule[KKAll]{\KENV,\KVAR \vdash t : k}{\KENV \vdash \KLAM\KVAR t : \KALL\KVAR k}

  \inferrule[KKApp]{\KENV \vdash t : \KALL\KVAR k' \\ \KENV \vdash k}{\KENV \vdash \KAPP t k : k'[\KVAR\mapsto k]}
\end{mathpar}
Type environment formation
\begin{mathpar}
  \inferrule[TEStart]{\KENV \models \\ \KENV \vdash k \le \ONE }{\KENV; \TENVEMPTY \models k}

  \inferrule[TEAssume]{\KENV; \TENV \models k \\  \KENV \vdash t : k' \\ \KENV \vdash k' \le k \\ x \notin \TENV }{
    \KENV; \TENV, \TASS x t \models k}
\end{mathpar}
Type conversion (congruence rules omitted)
\begin{mathpar}
  \inferrule[Conv-Beta]{\KENV, \TASS\TVAR k' \vdash t:k \\ \KENV \vdash t' : k' }{
    \KENV \vdash \APP{(\LAM\TVAR {k'} t)}{t'} = t[\TVAR \mapsto t'] : k}

  \inferrule[Conv-KSubst]{
    \KENV, \KVAR \vdash t : k \\ \KENV \vdash k'
  }{
    \KENV \vdash \KAPP{(\KLAM\KVAR t)}{k'} = t[\KVAR \mapsto k'] : k[\KVAR \mapsto k']}
\end{mathpar}
Type environment splitting (sequential)
\begin{mathpar}
  \inferrule{}{
    \KENV \vdash \SPLIT{\TENVEMPTY}{\TENVEMPTY}{\TENVEMPTY}}

  \inferrule{
    \KENV \vdash \SPLIT{\TENV_1}{\TENV_2}{\TENV} \\
    \KENV \vdash \SPLIT{t_1}{t_2}{t} \\
  }{
    \KENV \vdash \SPLIT{(\TENV_1, \TASS x t_1)}{(\TENV_2, \TASS x t_1)}{(\TENV, \TASS x t)}}

  \inferrule{
    \KENV \vdash \SPLIT{\TENV_1}{\TENV_2}{\TENV}
  }{
    \KENV \vdash \SPLIT{(\TENV_1, \TASS x t)}{\TENV_2}{(\TENV, \TASS x t)}}

  \inferrule{
    \KENV \vdash \SPLIT{\TENV_1}{\TENV_2}{\TENV}
  }{
    \KENV \vdash \SPLIT{\TENV_1}{(\TENV_2, \TASS x t)}{(\TENV, \TASS x t)}}
\end{mathpar}
Type splitting
\begin{mathpar}
  \inferrule{
    \KENV \vdash t : k \\
    \KENV \vdash k \le \KINDU_\infty
  }{
    \KENV \vdash \SPLIT{t}{t}{t}
  }

  \inferrule{
    \KENV \vdash t : k \\
    \KENV \vdash k \le \KINDA
  }{
    \KENV \vdash \SPLIT{\BORROW t}{t}{t}
  }

  \inferrule{
    \KENV \vdash t : k \\
    \KENV \vdash k \le \KINDA
  }{
    \KENV \vdash \SPLIT{\BORROW[i] t}{\BORROW[!]t}{\BORROW[!]t}
  }
\end{mathpar}
Typing rules
\begin{mathpar}
  \inferrule[Conv]{
    \KENV; \TENV \vdash e:t:k \\ \KENV \vdash t = t' : k
  }{\KENV; \TENV \vdash e : t': k}

  \inferrule[Var]{ \KENV; \TENV, \TENV' \models \MANY \\ \KENV \vdash t : k \\ \KENV \vdash k \le \ONE }{\KENV; \TENV, x:t, \TENV' \vdash x:t:k }

  \inferrule[Lam]
  {\KENV; \TENV \models k \\ \KENV; \TENV, x:t \vdash e : t':k'}
  {\KENV;\TENV \vdash \LAM[k] xte : t \stackrel{k}\to t':k}

  \inferrule[App]
  { \KENV \vdash \SPLIT{\TENV_1}{\TENV_2}{\TENV} \\
    \KENV;\TENV_1 \vdash e : t' \stackrel{k}\to t:k \\
    \KENV; \TENV_2 \vdash e' : t':k' \\
    \KENV \vdash t:k''
  }
  { \KENV; \TENV \vdash \APP ee' : t : k''}

  \inferrule[TLam]
  {\KENV, \TASS\TVAR k; \TENV \vdash v : t : k' \\ \TVAR \notin \KENV}
  {\KENV; \TENV \vdash (\TLAM[k']\TVAR k v) : (\TALL \TVAR k t) : k'}

  \inferrule[TApp]
  {
    \KENV; \TENV \vdash e : (\TALL \TVAR k t') : k' \\
    \KENV \vdash t : k
  }
  { \KENV; \TENV \vdash \TAPP e t : t'[\TVAR \mapsto t] : k' }

  \inferrule[KLam]
  { \KENV, \KVAR; \TENV \vdash e : t : k \\ \KVAR \notin \KENV}
  { \KENV; \TENV \vdash \KLAM[k]\KVAR e : \KALL\KVAR t : k}

  \inferrule[KApp]
  { \KENV; \TENV \vdash e : \KALL\KVAR t : k' \\ \KENV \vdash k}
  { \KENV; \TENV \vdash \KAPP e k : t[\KVAR \mapsto k] : k'[\KVAR \mapsto k]}

  \inferrule[CIntro]
  { \KENV,   k_1 \le k_2; \TENV \vdash e : t}
  { \KENV; \TENV \vdash e :  k_1 \le k_2 \Rightarrow t}

  \inferrule[CElim]
  { \KENV; \TENV \vdash e :  k_1 \le k_2 \Rightarrow t \\ \KENV \vdash k_1 \le k_2}
  { \KENV; \TENV \vdash e : t}
\end{mathpar}

Simple small-step semantics (for type preservation) with
$e[x \mapsto v]$ standing for capture-avoiding substitution of $v$ for
$x$ in $e$. Call-by-value as in $F^{\ONE}$.
\begin{mathpar}
  \inferrule[V-Beta]{}{\APP{(\LAM[k] x t e)}v \stepsto e[x \mapsto v]}

  \inferrule[T-Beta]{}{\TAPP{(\TLAM[k'] \TVAR k v)}t \stepsto v[\TVAR \mapsto t]}

  \inferrule[K-Beta]{}{\KAPP{(\KLAM \KVAR v)}k \stepsto v[\KVAR \mapsto k]}
  \\
  \inferrule[App-Left]{e_1 \stepsto e_1'
  }{\APP{e_1}{e_2} \stepsto \APP{e_1'}{e_2}}

  \inferrule[App-Right]{e \stepsto e'}{\APP v e \stepsto \APP v e'}

  \inferrule[TApp-Left]{e \stepsto e'}{\TAPP{e} t \stepsto \TAPP{e'} t}

  \inferrule[KApp-Left]{e \stepsto e'}{\KAPP{e} k \stepsto \KAPP{e'} k}
\end{mathpar}

\clearpage
\begin{lemma}[Weakening]
  Let $\mathcal{A}$ range over assumptions in kind environments.
  Let $\mathcal{J}$ range over judgments in the context of a kind environment.

  If $\KENV \vdash \mathcal{J}$ and $\KENV, \mathcal{A} \models$, then $\KENV, \mathcal{A} \vdash \mathcal{J}$.
\end{lemma}
\begin{lemma}[Unrestricted Weakening]
  Suppose that $\KENV; \TENV \vdash e : t$, $x\notin \TENV$, and $\KENV \vdash t_x : \MANY$.
  Then  $\KENV; \TENV, x : t_x \vdash e : t$.
\end{lemma}
\begin{lemma}[Value Substitution]\label{lemma:value-substitution}
  Suppose that $\KENV; \TENV, x:t_x \vdash e : t$
  and $\KENV; \TENVEMPTY \vdash v : t'$
  and $\KENV \vdash t_x = t' : k'$.
  Then $\KENV; \TENV \vdash e[x \mapsto v] : t$.
\end{lemma}
\begin{proof}
  As the conversion assumes the empty environment, it cannot be
  affected by adding further assumptions.

  The proof proceeds by induction on the derivation of  $\KENV; \TENV, x:t_x
  \vdash e : t$ and produces a derivation for the term after
  substitution. The only interesting case is the one for the
  \TirName{Var} rule when the variable is $x$:
  \begin{mathpar}
    \inferrule[Var]{ \KENV;\TENV \models \MANY \\ \KENV \models t_x : k' \\ \KENV \vdash k' \le \ONE }{\TENV, x:t_x \vdash x:t_x }
  \end{mathpar}
  By unrestricted weakening we have that
  \begin{gather*}
    \KENV; \TENV \vdash v : t' \\
    \KENV \vdash t_x = t' : k'
  \end{gather*}
  and hence by \TirName{Conv} and symmetry of $=$, we have the desired outcome
  \begin{gather*}
    \KENV; \TENV \vdash v : t_x
  \end{gather*}
\end{proof}
\begin{lemma}[Type Substitution]\label{lemma:type-substitution}
  Suppose that $\KENV \vdash t' : k'$.
  \begin{enumerate}
  \item\label{item:1} If $\KENV, \TASS\TVAR {k'} \vdash t : k$, then
    $\KENV \vdash t[\TVAR \mapsto t'] : k$.
  \item\label{item:3} If $\KENV, \TASS\TVAR {k'}; \TENV \models k$,
    then $\KENV; \TENV[\TVAR \mapsto t'] \models k$.
  \item\label{item:5} If $\KENV, \TASS\TVAR {k'} \vdash t_1 = t_2 : k$,
    then $\KENV \vdash t_1[\TVAR \mapsto t'] = t_2[\TVAR \mapsto t'] : k$.
  \item\label{item:4} If
    $\KENV, \TASS\TVAR {k'} \vdash \SPLIT{\TENV_1}{\TENV_2}{\TENV}$,
    then $\KENV \vdash \SPLIT{\TENV_1[\TVAR \mapsto t']}{\TENV_2[\TVAR \mapsto t']}{\TENV[\TVAR \mapsto t']}$.
  \item\label{item:2} If $\KENV, \TASS\TVAR {k'}; \TENV \vdash e : t$, then
    $\KENV; \TENV[\TVAR \mapsto t'] \vdash e[\TVAR \mapsto t'] : t[\TVAR \mapsto t']$.
  \end{enumerate}
\end{lemma}
\begin{proof}
  \textbf{Item}~\ref{item:1} is proved by induction on the derivation of
  $\KENV, \TASS\TVAR {k'} \vdash t : k$.

  The only interesting rule is \TirName{KVar}:
  $\KENV, \TASS\TVAR {k'} \vdash \TVAR : k'$. As
  $\TVAR[\TVAR \mapsto t'] = t'$, we have $\KENV \vdash t' : k'$ by
  assumption.

  All remaining cases are immediate by appeal to the inductive hypothesis.

  \textbf{Item}~\ref{item:3} is proved by induction on the derivation of
  $\KENV, \TASS\TVAR {k'}; \TENV \models k$.

  \textbf{Case} \TirName{TEStart}. Immediate.

  \textbf{Case} \TirName{TEAssume}. From $\KENV, \TASS\TVAR {k'}; \TENV, \TASS x t \models k$ inversion yields
  \begin{gather}
    \label{eq:4}
    \KENV, \TASS\TVAR {k'}; \TENV \models k \\
    \KENV, \TASS\TVAR {k'} \vdash t : k'' \\
    \KENV, \TASS\TVAR {k'} \vdash k'' \le k \\
    x \notin \TENV
  \end{gather}
  By induction from~\eqref{eq:4}
  \begin{gather}
    \KENV; \TENV[\TVAR \mapsto t'] \models k
  \end{gather}
  By Item~\ref{item:1}
  \begin{gather}
    \KENV \vdash t[\TVAR\mapsto t'] : k''
  \end{gather}
  As $\TVAR\notin k'', k$
  \begin{gather}
    \KENV \vdash k'' \le k
  \end{gather}
  By \TirName{TEAssume}
  \begin{gather}
    \KENV; (\TENV, \TASS x t)[\TVAR \mapsto t'] \models k
  \end{gather}

  \textbf{Item}~\ref{item:5} is proved by induction on the derivation of
  $\KENV, \TASS\TVAR{ k'} \vdash t_1 = t_2 : k$.

  \textbf{Item}~\ref{item:4} is proved by induction on the derivation of splitting.

  \textbf{Item}~\ref{item:2} is proved by induction on the derivation of
  $\KENV, \TASS\TVAR k; \TENV \vdash e : t$.

  \textbf{Case} \TirName{Conv}: immediate by Item~\ref{item:5}.

  \textbf{Case} \TirName{Var}: immediate by Item~\ref{item:1} and Item~\ref{item:3}.

  \textbf{Case} \TirName{Lam}: by Item~\ref{item:3} and induction.

  \textbf{Case} \TirName{App}: by Item~\ref{item:4} and induction.

  The remaining cases present no new problems.
\end{proof}
Kind substitution can lead to unsatisfiable constraints. That does not
mean that kind substitution is bad, but that a value with a bad kind
substitution cannot be used as the unsatisfiable sonstraint cannot be
eliminated by \TirName{CElim}!
\begin{lemma}[Kind Substitution]\label{lemma:kind-substitution}
  Suppose that $\KENV \vdash k$.
  \begin{enumerate}
  \item If $\KENV, \KVAR \vdash t : k'$,
    then $\KENV \vdash t[\KVAR \mapsto k] : k'[\KVAR \mapsto k]$.
  \item If $\KENV, \KVAR \vdash t = t' : k'$,
    then $\KENV \vdash t[\KVAR \mapsto k] = t'[\KVAR \mapsto k] : k'[\KVAR \mapsto k]$.
  \item If $\KENV, \KVAR ; \TENV \models k'$,
    then $\KENV; \TENV[\KVAR \mapsto k] \models k'[\KVAR \mapsto k]$.
  \item If $\KENV,\KVAR \vdash k_1 \le k_2$,
    then $\KENV \vdash k_1[\KVAR \mapsto k] \le k_2[\KVAR \mapsto k]$.
  \item If $\KENV, \KVAR \vdash \SPLIT{\TENV_1}{\TENV_2}{\TENV}$,
    then $\KENV \vdash \SPLIT{\TENV_1[\KVAR \mapsto k]}{\TENV_2[\KVAR \mapsto k]}{\TENV[\KVAR \mapsto k]}$.
  \item If $\KENV, \KVAR; \TENV \vdash e : t$,
    then $\KENV; \TENV[\KVAR \mapsto k] \vdash e[\KVAR \mapsto k] : t[\KVAR \mapsto k]$.
  \end{enumerate}
\end{lemma}
\begin{proof}
  \textbf{!!! TODO !!!}
\end{proof}
\begin{lemma}[Inversion for Function Type]\label{lemma:inversion-function}
  If $\KENV; \TENVEMPTY \vdash \LAM x {t_x} e : t_f$,
  then there is some $n\ge0$ and $k_{i1}$, $k_{i2}$ (for $1\le i\le n$) such that
  \begin{gather}
    \KENV \vdash t_f = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow t_x \stackrel{k}\to t : k'
    \\
    \KENV; \TASS x{t_x} \vdash e : t
    \\
    \KENV \vdash k' \le \ONE
    \\
    \KENV \vdash k \le \ONE
    \mathrm{.}
  \end{gather}
\end{lemma}
\begin{proof}
  Induction on the derivation of
  $\KENV; \TENVEMPTY \vdash \LAM x {t_x} e : t_f$.

  \textbf{Case} \TirName{Lam}. Rule inversion yields $\KENV \models$,
  $\KENV \vdash k \le \ONE$, $t_f = t_x \stackrel{k}\to t$, and
  $\KENV; \TASS x{t_x} \vdash e : t$. By reflexivity of conversion
  $\KENV \vdash t_f = t_x \stackrel{k}\to t : k'$, for some
  $\KENV \vdash k' \le \ONE$, and the claim holds for $n=0$.

  \textbf{Case} \TirName{Conv}. Rule inversion yields
  $\KENV; \TENVEMPTY \vdash \LAM x {t_x} e : t_1$ and
  $\KENV \vdash t_1 = t_f : k'$ with $\KENV \vdash k' \le
  \ONE$. Conclude by induction and by transitivity of conversion.

  \textbf{Case} \TirName{CIntro}. Rule inversion yields that
  $t_f = k_1 \le k_2 \Rightarrow t_1$ and
  $\KENV, k_1 \le k_2; \TENVEMPTY \vdash e : t_1$. By induction,
  $\KENV \vdash t_1 = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le
  k_{n2} \Rightarrow t_x \stackrel{k}\to t : k'$ so by congruence
  $\KENV \vdash t_f = k_1 \le k_2 \Rightarrow k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le
  k_{n2} \Rightarrow t_x \stackrel{k}\to t : k'$, which proves the claim.

  \textbf{Case} \TirName{CElim}. Rule inversion yields that
  $\KENV; \TENVEMPTY \vdash \LAM x {t_x} e : t_1$ with
  $t_1 = k_1 \le k_2 \Rightarrow t_f$ and $\KENV \vdash k_1 \le
  k_2$. By induction
  $\KENV \vdash t_1 = k_1 \le k_2 \Rightarrow k_{11}\le
  k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow t_x
  \stackrel{k}\to t : k'$ so that by congruence
  $\KENV \vdash t_f = k_{11}\le
  k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow t_x
  \stackrel{k}\to t : k'$, which proves the claim.
\end{proof}
\begin{lemma}[Inversion for Type Abstraction]\label{lemma:inversion-universal}
  Suppose that $\KENV; \TENVEMPTY \vdash \TLAM\TVAR k v : t_a$.
  Then there is some $n\ge0$ and $k_{i1}$, $k_{i2}$ (for $1\le i\le n$) such that
  \begin{gather}
    \KENV \vdash t_a = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow \TALL \TVAR k t' : k'
    \\
    \KENV, \TASS \TVAR{k}; \TENVEMPTY \vdash v : t'
    \\
    \KENV \vdash k' \le \ONE
    \mathrm{.}
  \end{gather}
\end{lemma}
\begin{proof}
  Analogous to Lemma~\ref{lemma:inversion-function}.
\end{proof}
\begin{lemma}[Inversion for Kind Abstraction]\label{lemma:inversion-kind-abstraction}
  Suppose that $\KENV; \TENVEMPTY \vdash \KLAM\KVAR v : t_a$.
  Then there is some $n\ge0$ and $k_{i1}$, $k_{i2}$ (for $1\le i\le n$) such that
  \begin{gather}
    \KENV \vdash t_a = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow \KALL \KVAR t' : k'
    \\
    \KENV, \KVAR; \TENVEMPTY \vdash v : t'
    \\
    \KENV \vdash k' \le \ONE
    \mathrm{.}
  \end{gather}
\end{lemma}
\begin{proof}
  Analogous to Lemma~\ref{lemma:inversion-function}.
\end{proof}
\begin{lemma}[Type Preservation]~\\
  Suppose that $\KENV; \TENVEMPTY \vdash e : t$ and $e \stepsto e'$.
  Then $\KENV;\TENVEMPTY \vdash e' : t$.
\end{lemma}
\begin{proof}
  In each case we proceed by induction on the derivation of the
  assumed judgment.  If the top-level rule is \TirName{Conv},
  \TirName{CIntro}, or \TirName{CElim}, then the claim holds by
  induction.

  \textbf{Case} ${\APP{(\LAM x {t_x} e)}v \stepsto e[x \mapsto v]}$.

  By assumption $\KENV;\TENVEMPTY \vdash \APP{(\LAM x {t_x} e)}v : t$.

  If the top-level rule is \TirName{App} rule, we can apply inversion to find
  \begin{gather}
    \label{eq:1}
    \KENV; \TENVEMPTY \vdash \LAM x {t_x} e : t' \stackrel{k}\to t
    \\
    \label{eq:2}
    \KENV; \TENVEMPTY \vdash v : t'
  \end{gather}
  By Lemma~\ref{lemma:inversion-function}, there exists an $n\ge0$ and $k_{i1}$, $k_{i2}$ (for $1\le i\le n$) such that
  \begin{gather}
    \KENV \vdash t' \stackrel{k}\to t = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow t_x \stackrel{k}\to t : k'
    \\
    \KENV; \TASS x{t_x} \vdash e : t
  \end{gather}
  Hence, $n=0$ and
  \begin{gather}
    \KENV \vdash t' \stackrel{k}\to t = t_x \stackrel{k}\to t : k'
  \end{gather}
  from which we can follow
  \begin{gather}
    \label{eq:3}
    \KENV \vdash t_x = t' : k' \text{ where } \KENV \vdash k' \le \ONE
  \end{gather}
  With these assumptions, we apply value substitution
  (Lemma~\ref{lemma:value-substitution}) to obtain the result.

  \textbf{Case} $\TAPP{(\TLAM \TVAR k v)}{t'} \stepsto v[\TVAR \mapsto t']$.

  By assumption
  $\KENV;\TENVEMPTY \vdash \TAPP{(\TLAM \TVAR k v)}{t'} :
  t$. Inversion of the \TirName{TApp} rule yields
  \begin{gather}
    \KENV; \TENVEMPTY \vdash \TLAM \TVAR k v : \TALL\TVAR k t_0 \\
    \KENV \vdash t' : k \\
    t = t_0 [\TVAR\mapsto t']
  \end{gather}
  By Lemma~\ref{lemma:inversion-universal}, there exists an $n\ge0$ and $k_{i1}$, $k_{i2}$ (for $1\le i\le n$) such that
  \begin{gather}
    \KENV \vdash \TALL\TVAR k t_0 = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow \TALL\TVAR k t_1 : k_1
    \\
    \label{eq:5}
    \KENV, \TASS \TVAR{k}; \TENVEMPTY \vdash v : t_1
  \end{gather}
  Hence, $n=0$ and
  \begin{gather}
    \KENV \vdash \TALL\TVAR k t_0 = \TALL\TVAR k t_1 : k_1
  \end{gather}
  from which we can follow
  \begin{gather}
    \label{eq:6}
    \KENV, \TASS\TVAR k \vdash t_0 = t_1 : k_1
  \end{gather}
  By Lemma~\ref{lemma:type-substitution} (type substitution) applied to~\eqref{eq:5}
  \begin{gather}
    \label{eq:7}
    \KENV; \TENVEMPTY \vdash v[\TVAR \mapsto t'] : t_1[\TVAR \mapsto t']
  \end{gather}
  By Lemma~\ref{lemma:type-substitution} (type substitution) applied to~\eqref{eq:6}
  \begin{gather}
    \label{eq:8}
    \KENV \vdash t_0[\TVAR \mapsto t'] = t_1[\TVAR \mapsto t'] : k_1
  \end{gather}
  By \TirName{Conv} applied to~\eqref{eq:7} and~\eqref{eq:8}
  \begin{gather}
    \KENV; \TENVEMPTY \vdash v[\TVAR \mapsto t'] : t
  \end{gather}
  as required.

  \textbf{Case} $\KAPP{(\KLAM \KVAR v)}k \stepsto v[\KVAR \mapsto k]$.

  By inversion of rule \TirName{KApp}, we obtain from
  $\KENV; \TENVEMPTY \vdash \KAPP{(\KLAM \KVAR v)}k : t_e$ that
  \begin{gather}
    t_e =  t[\KVAR \mapsto k] \\
    \label{eq:9}
    \KENV; \TENVEMPTY \vdash \KLAM \KVAR v : \KALL\KVAR t \\
    \KENV \vdash k
  \end{gather}
  By Lemma~\ref{lemma:inversion-kind-abstraction} applied to~\eqref{eq:9} we find that
  \begin{gather}
    \KENV \vdash
    \KALL\KVAR t
    = k_{11}\le k_{12}\Rightarrow \dots k_{n1}\le k_{n2} \Rightarrow
    \KALL \KVAR t' : k'     \\
    \label{eq:10}
    \KENV, \KVAR; \TENVEMPTY \vdash v : t'
  \end{gather}
  so that $n=0$ and
  \begin{gather}
    \KENV \vdash
    \KALL\KVAR t
    =
    \KALL \KVAR t' : k'
  \end{gather}
  and thus
  \begin{gather}\label{eq:11}
    \KENV, \KVAR \vdash
    t
    =
    t' : k'
  \end{gather}
  Applying kind substitution to~\eqref{eq:10} and~\eqref{eq:11} yields
  \begin{gather}
    \KENV; \TENVEMPTY \vdash v[\KVAR \mapsto k] : t'[\KVAR \mapsto k]
    \\
    \KENV \vdash
    t[\KVAR \mapsto k]
    =
    t'[\KVAR \mapsto k] : k'[\KVAR \mapsto k]
  \end{gather}
  and thus by \TirName{Conv} the desired
  \begin{gather}
    \KENV; \TENVEMPTY \vdash v[\KVAR \mapsto k] : t_e
  \end{gather}

  \textbf{Case} reduction in context by rules \TirName{App-Left},
  \TirName{App-Right}, \TirName{TApp-Left}, and \TirName{KApp-Left}. The result is
  immediate by inversion of the respective rule and then by appeal to the inductive hypothesis.
\end{proof}

TODO:
Templates in $F^{\ONE}$, work by Morris, Bernardi, and others.

\section{Allocating Semantics}

A more elaborate big-step semantics that allocates all values on the
heap and removes linear values after they are used.  The evaluation
judgement is thus $H, e \Downarrow H, \Addr$ where $H$ is a heap that
binds addresses $\Addr$ to values, which are abstractions that may
contain addresses themselves, but no free variables.

\begin{mathpar}
  \inferrule{}{H, \LAM[k] x t e \Downarrow H+ (\Addr \mapsto \LAM[k] x t e), \Addr}

  \inferrule{
    H_1, e_1 \Downarrow H_2, \Addr_1 \\
    H_2 (\Addr_1) = \LAM[k]x t e \\
    H_2' = H_2 \text{ if $k=\MANY$ else } H_2 \setminus \Addr_1
    \\\\
    H_2', e_2 \Downarrow H_3, \Addr_2 \\
    H_3, e[x \mapsto \Addr_2] \Downarrow H_4, \Addr
  }{H_1, \APP{e_1}{e_2} \Downarrow H_4, \Addr}

  \inferrule{}{
    H, \TLAM[k']\TVAR k v \Downarrow H+ (\Addr \mapsto \TLAM[k']\TVAR k v), \Addr
  }

  \inferrule{
    H, e \Downarrow H', \Addr' \\
    H' (\Addr') = \TLAM[k']\TVAR k v \\
    H'' = H' \text{ if $k'=\MANY$ else } H' \setminus \Addr'
  }{
    H, \TAPP e t \Downarrow H''+ (\Addr \mapsto v[\TVAR \mapsto t]), \Addr
  }

  \inferrule{}{
    H, \KLAM[k]\KVAR v \Downarrow H+ (\Addr \mapsto \KLAM[k]\KVAR v), \Addr
  }

  \inferrule{
    H, e \Downarrow H', \Addr' \\
    H' (\Addr') = \KLAM[k']\KVAR v \\
    H'' = H' \text{ if $k'=\MANY$ else } H' \setminus \Addr'
  }{
    H, \KAPP e k \Downarrow H''+ (\Addr\mapsto v[\KVAR\mapsto k]),
    \Addr
  }
\end{mathpar}

\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:


\chapter{The source code}

\section{Introduction}

\section{Data types}

There are several new types, the two most important ones are
\begin{itemize}
\item{REAL}\\
REAL is a floating point number. It is defined in `src/constants.h' as
\begin{verbatim}
     #define REAL double
\end{verbatim}
but if one needs higher precision one could use
\begin{verbatim}
     #define REAL long double
\end{verbatim}
and using the `qd' library it is even possible to use arbitrary precision.
\item{VECTOR}\\
An structure with three elements `x', `y', and `z'.
\begin{verbatim}
     typedef struct point
     {
       REAL x;
       REAL y;
       REAL z;
     } POINT,VECTOR;
\end{verbatim}
\item{REAL\_MATRIX3x3}\\
A $3\times3$ matrix, used as transformations on vectors (like `strain') and for the three cell-vectors making up the cell matrix. It is defined in `src/matrix.h'.
\begin{verbatim}
     typedef struct real_matrix3x3
     {
       REAL ax;
       REAL ay;
       REAL az;

       REAL bx;
       REAL by;
       REAL bz;

       REAL cx;
       REAL cy;
       REAL cz;
     } REAL_MATRIX3x3;
\end{verbatim}
\end{itemize}

\section{Datastructures}

\subsection*{Box properties and periodic boundaries}

For each system, a cell box and other properties are defined in `src/simulation.h'
\begin{footnotesize}
\begin{verbatim}
     REAL_MATRIX3x3 *Box;                   // the cell matrix
     REAL_MATRIX3x3 *InverseBox;            // the inverse of the cell matrix
     REAL_MATRIX3x3 *ReplicaBox;            // the cell matrix of the replica system
     REAL_MATRIX3x3 *InverseReplicaBox;     // the inverse of the the cell matrix of the replica system
     INT_VECTOR3 *NumberOfReplicaCells;     // the integere number of replicas in each direction a,b,c
     int *TotalNumberOfReplicaCells;        // the total number of replica cells
     VECTOR *ReplicaShift;                  // the shift in a,b,c for each replica cell
     int *UseReplicas;                      // whether or not to use replicas
     REAL_MATRIX3x3 *BoxProperties;         // properties of the cell matrix (i.e. perpendicular lengths)
     REAL_MATRIX3x3 *InverseBoxProperties;  // properties of the inverse cell matrix
     REAL *Volume;                          // the volume
     REAL *AlphaAngle;                      // the alpha-angle of the cell
     REAL *BetaAngle;                       // the beta-angle of the cell
     REAL *GammaAngle;                      // the gamma-angle of the cell
     int *BoundaryCondition;                // the boundary condition (i.e. `RECTANGULAR' or `TRICLINIC')
\end{verbatim}
\end{footnotesize}
These are dynamically allocated arrays and have the same length as the amount of systems present. For example, in a Gibbs simulation two systems are needed,
one for the gas-phase and one for the liquid phase. `Volume[0]' would give the volume of the first cell, and `Volume[1]' would give the volume of the second cell.

Periodic boundaries are applied after each distance computation calling the function `ApplyBoundaryCondition' (defined in `src/potentials.h')
It operates on a `VECTOR' and give the corrected vector back. The system is specified with the global variable `CurrentSystem'.
\begin{footnotesize}
\begin{verbatim}
     VECTOR ApplyBoundaryCondition(VECTOR dr)
     {
       VECTOR s,t;

       switch(BoundaryCondition[CurrentSystem])
       {
         case FINITE:
           break;
         case RECTANGULAR:
         case CUBIC:
           dr.x-=Box[CurrentSystem].ax*(REAL)NINT(dr.x*InverseBox[CurrentSystem].ax);
           dr.y-=Box[CurrentSystem].by*(REAL)NINT(dr.y*InverseBox[CurrentSystem].by);
           dr.z-=Box[CurrentSystem].cz*(REAL)NINT(dr.z*InverseBox[CurrentSystem].cz);
           break;
         case TRICLINIC:
           // convert from xyz to abc
           s.x=InverseBox[CurrentSystem].ax*dr.x+InverseBox[CurrentSystem].bx*dr.y+InverseBox[CurrentSystem].cx*dr.z;
           s.y=InverseBox[CurrentSystem].ay*dr.x+InverseBox[CurrentSystem].by*dr.y+InverseBox[CurrentSystem].cy*dr.z;
           s.z=InverseBox[CurrentSystem].az*dr.x+InverseBox[CurrentSystem].bz*dr.y+InverseBox[CurrentSystem].cz*dr.z;

           // apply boundary condition
           t.x=s.x-(REAL)NINT(s.x);
           t.y=s.y-(REAL)NINT(s.y);
           t.z=s.z-(REAL)NINT(s.z);

           // convert from abc to xyz
           dr.x=Box[CurrentSystem].ax*t.x+Box[CurrentSystem].bx*t.y+Box[CurrentSystem].cx*t.z;
           dr.y=Box[CurrentSystem].ay*t.x+Box[CurrentSystem].by*t.y+Box[CurrentSystem].cy*t.z;
           dr.z=Box[CurrentSystem].az*t.x+Box[CurrentSystem].bz*t.y+Box[CurrentSystem].cz*t.z;
           break;
         default:
           fprintf(stderr,"Error: Unkown boundary condition....\n");
           exit(0);
           break;
       }
       return dr;
     }
\end{verbatim}
\end{footnotesize}
The function `NINT' is faster version of `rint' (or `floor').
\begin{footnotesize}
\begin{verbatim}
     #define NINT(x) ((int)((x)>=0.0?((x)+0.5):((x)-0.5)) )
\end{verbatim}
\end{footnotesize}
A common occurrence of the boundary conditions application is for two positions of atoms `posA' and `posB' (of type `VECTOR')
\begin{footnotesize}
\begin{verbatim}
     dr.x=posA.x-posB.x;
     dr.y=posA.y-posB.y;
     dr.z=posA.z-posB.z;
     dr=ApplyBoundaryCondition(dr);
     rr=SQR(dr.x)+SQR(dr.y)+SQR(dr.z);
     r=sqrt(rr);
\end{verbatim}
\end{footnotesize}

\noindent
There are functions you can use to transform from Cartesian to fractional coordinates (defined in `src/potentials.h')
\begin{footnotesize}
\begin{verbatim}
     VECTOR ConvertFromXYZtoABC(VECTOR t)
     {
       VECTOR s;

       s.x=InverseBox[CurrentSystem].ax*t.x+InverseBox[CurrentSystem].bx*t.y+InverseBox[CurrentSystem].cx*t.z;
       s.y=InverseBox[CurrentSystem].ay*t.x+InverseBox[CurrentSystem].by*t.y+InverseBox[CurrentSystem].cy*t.z;
       s.z=InverseBox[CurrentSystem].az*t.x+InverseBox[CurrentSystem].bz*t.y+InverseBox[CurrentSystem].cz*t.z;
       return s;
     }
\end{verbatim}
\end{footnotesize}
and from fractional coordinates to Cartesian
\begin{footnotesize}
\begin{verbatim}
     VECTOR ConvertFromABCtoXYZ(VECTOR t)
     {
       VECTOR dr;

       dr.x=Box[CurrentSystem].ax*t.x+Box[CurrentSystem].bx*t.y+Box[CurrentSystem].cx*t.z;
       dr.y=Box[CurrentSystem].ay*t.x+Box[CurrentSystem].by*t.y+Box[CurrentSystem].cy*t.z;
       dr.z=Box[CurrentSystem].az*t.x+Box[CurrentSystem].bz*t.y+Box[CurrentSystem].cz*t.z;
       return dr;
     }
\end{verbatim}
\end{footnotesize}

\subsection*{(Pseudo-)atoms}

The data structure `PSEUDO\_ATOM' contains information on atoms, either real atoms or united atoms where several atoms are lumped together (for example: CH3).

\begin{footnotesize}
\begin{verbatim}
     // Pseudoatoms
     typedef struct PseudoAtom
     {
       char Name[256];              // the Name of the pseudo-atom (`CH3',`H',`O' etc).
       char PrintToPDBName[256];    // the string to print to a pdb-file as name
       int  PrintToPDB;             // whether to write this atom to the pdf-file or not
       char ChemicalElement[256];   // the chemical element (`O', `H', etc)
       int ScatteringType;          // the scattering type (powder diffraction)
       int AnomalousScatteringType; // the anmalous scattering type (powder diffraction)
       REAL TemperatureFactor;      // the temperature factor (powder diffraction)
       REAL Mass;                   // the mass of the pseudo-atom
       REAL Charge;                 // the charge of the pseudo-atom
       REAL Polarization;           // the polarization of the atom
       int HasCharges;              // whether or not the atom has atoms with charges
       int IsPolarizable;           // whether or not the atom has a induced point dipole
       int Interaction;             // whether or not the atom has interactions
       REAL Radius;                 // the radius (used for calculating Bonds in the zeolite)
       int Connectivity;            // the connectivity (used for calculating Bonds/Bends/Torsion in the framework)
     } PSEUDO_ATOM;
\end{verbatim}
\end{footnotesize}

\noindent
A typical use is, once the type is known, to retrieve the charge for a pseudo-atoms:
\begin{verbatim}
     REAL q;
     q=PseudoAtom[type].Charge;
\end{verbatim}
Use the following to find out to what pseudoatom a string corresponds to
\begin{verbatim}
     int type;
     type=ReturnPseudoAtomNumber("CH4");
\end{verbatim}
However, usually the type is a property of each of the atoms of a molecule.
\begin{verbatim}
     int type;
     type=Framework[1].Atoms[0][10].Type;
\end{verbatim}
and `type' can then be used to get the mass, charge, polarization, etc. Here, the type is retrieve for atom number 11 (c is starting from 0, unlike Fortran)
of the first framework of the second system.

\subsection*{Framework}

Atoms make up a framework, several frameworks can make up 1 system. The definition of a framework atom `FRAMEWORK\_ATOM' is
\begin{footnotesize}
\begin{verbatim}
     typedef struct framework_atom
     {
       int Type;                      // the pseudo-atom type of the atom
       int AssymetricType;            // the `asymmetric' type

       // MC/MD properties
       POINT Position;                // the position of the atom
       POINT ReferencePosition;       // the `reference' position of the atom

       // MD properties
       VECTOR Velocity;               // the velocity of the atom
       VECTOR ReferenceVelocity;      // the `reference' velocity of the atom
       VECTOR Force;                  // the force acting on the atom

       VECTOR ElectricField;          // the electricfield vector
       VECTOR ReferenceElectricField; // the `reference' electricfield vector
       VECTOR InducedElectricField;   // the induced electric field
       VECTOR InducedDipole;          // the induced dipole moment on this atom
       int HessianIndex;              // the index in the Hessian matrix for this atom
     } FRAMEWORK_ATOM;
\end{verbatim}
\end{footnotesize}
It contains the properties you'd expect, like type, position, velocity, and force. For polarization, also electric field, induced electric field,
and induced dipole are needed. For many applications, one needs to backup the positions and/or velocities. The field `ReferencePosition' and `ReferenceVelocity'
are useful for that. Also they can be used for some algorithms which need the `old' values to. An example is the numerical computation of stress. First all
positions are copied  to the `ReferencePosition', then the positions `Position' are generated from the strain at infinite small strain difference and the
finite difference scheme is applied.

\noindent
A framework-structure `FRAMEWORK\_COMPONENT' is defined per system
\begin{verbatim}
     FRAMEWORK_COMPONENT *Framework;
\end{verbatim}
with
\begin{footnotesize}
\begin{verbatim}
     typedef struct FrameworkComponent
     {
       char (*Name)[256];                        // the name of the frameworks

       int TotalNumberOfAtoms;                   // the total number of atoms of the frameworks
       int TotalNumberOfUnitCellAtoms;           // the total number of atoms of the unit cell
       REAL FrameworkDensity;                    // the total density of the frameworks
       REAL FrameworkMass;                       // the total mass of the frameworks

       int NumberOfFrameworks;                   // the number of frameworks
       REAL *FrameworkDensityPerComponent;       // the density per framework
       REAL *FrameworkMassPerComponent;          // the mass per framework

       int *NumberOfAtoms;                       // the number of atoms per framework
       int *NumberOfUnitCellAtoms;               // the number of unit cell atoms per framework
       FRAMEWORK_ATOM **Atoms;                   // list of framework-atoms per framework
       ..................
       ..................
} FRAMEWORK_COMPONENT;
\end{verbatim}
\end{footnotesize}
The structure had the element `Atoms' which is a list of framework-atoms per framework.
So, to get the type of the 11 atom of the first framework of the second system, use
\begin{verbatim}
     int type;
     type=Framework[1].Atoms[0][10].Type;
\end{verbatim}

\noindent
Finally, a small example where we print out the positions of all the framework atoms for all frameworks and systems
\begin{verbatim}
      int i,j,f1;
      for(i=0;i<NumberOfSystem;i++)
      {
        for(f1=0;f1<Framework[i].NumberOfSystems;f1++)
        {
          for(j=0;j<Framework[i].NumberOfAtoms[f1];j++)
            printf("system: %d framework: %d atom: %d -> position: %g %g %g\n",
            i,f1,j,
            Framework[i].Atoms[f1][j].Position.x,
            Framework[i].Atoms[f1][j].Position.y,
            Framework[i].Atoms[f1][j].Position.z);
        }
      }
\end{verbatim}

\subsection*{Components}

Everything that is independent of a molecule's positions but still a property of molecules is stored in the structure `COMPONENT'.
Here you find the number of atoms for this type of molecule per system, the mass for the component etc.
Also computed values for densities of the bulk fluid, compressibility, and the amount of excess molecules are stored. These are computed
from the mol fraction, pressure, and critical pressure/temperature and acentric factor.
After these properties there are data on the potentials defined for the component: bond, Urey-Bradley, bends, torsions, cross-terms, intra Van der Waals etc.
For Monte Carlo the structure contains the probability of all the moves.

\begin{footnotesize}
\begin{verbatim}
     typedef struct Component
     {
       char Name[256];                 // the name of the component ("methane","C12","propane" etc).
       int NumberOfAtoms;              // the number of atoms in the component
       int StartingBead;               // the bead of the molecule used for starting the growing process in CBMC
       REAL Mass;                      // the mass of the component
       int *NumberOfMolecules;         // the number of molecules of the component for each system
       int *Type;                      // the pseudo-atom Type of each atom
       int *Connectivity;              // the connectivity of each atom
       int HasCharges;                 // whether the molecule contains charges or not
       int IsPolarizable;              // whether the molecule has point dipoles or not
       int ExtraFrameworkMolecule;     // TRUE: Cation, FALSE: Adsorbate
       int Swapable;                   // whether or not the number of molecules is fluctuating (i.e. GCMC)
       int Widom;                      // whether this component is used for Widom insertions

       REAL *IdealGasRosenbluthWeight; // the Rosenbluth weight of an ideal-chain per system
       REAL *IdealGasTotalEnergy;      // the total energy of an ideal-chain per system

       REAL *PartialPressure;          // the partial pressure of the component per system
       REAL *FugacityCoefficient;      // the fugacity coefficient of the component per system
       REAL *BulkFluidDensity;         // the bulkfluid-density of the component per system
       REAL *Compressibility;          // the compresibility of the fluid-fase per system
       REAL *MolFraction;              // the mol-fraction of the component per system
       REAL *AmountOfExcessMolecules;  // the amount of excess molecules per syste,

       REAL CriticalTemperature;       // the critical temperature of the component
       REAL CriticalPressure;          // the critical pressure of the component
       REAL AcentricFactor;            // the acentric factor of the component

       int NumberOfGroups;             // the number of groups
       GROUP_DEFINITION *Groups;       // the definition of the groups
       int *group;                     // to which group an atom belongs
       VECTOR *Positions;              // the positions in the body-fixed frame
          ..................
          ..................
       int NumberOfBonds;                                    // the number of bonds of the component
       PAIR *Bonds;                                          // the list of bond-pairs
       int *BondType;                                        // the type of the bond for each bond-pair
       REAL (*BondArguments)[MAX_BOND_POTENTIAL_ARGUMENTS];  // the arguments needed for this bond-pair
          ..................
          ..................
       REAL ProbabilityTranslationMove;  // the probability of the translation MC-move for the component
       REAL ProbabilityRotationMove;     // the probability of the rotation MC-move for the component
       REAL ProbabilityCBMCMove;         // the probability of the partial-regrow MC-move for the component
       REAL ProbabilityReinsertionMove;  // the probability of the reinsertion MC-move for the component
          ..................
          ..................
     } COMPONENT;
\end{verbatim}
\end{footnotesize}

A component consists of `groups', which is a collection of atoms that are either treated as rigid or as flexible. The component has
elements that lists how many of these groups there are, the definition of the group, and the positions of all the atoms in the body-fixed frame.
The definition of the group is the structure `GROUP\_DEFINITION'. Important elements are whether or not the group is rigid, the
number of atoms in the group, and the list of atom number present in the groups.

\begin{footnotesize}
\begin{verbatim}
     typedef struct group_definitions
     {
       int Rigid;                        // whether or not the group is rigid
       int Type;                         // the type, NONLINEAR_MOLECULE, LINEAR_MOLECULE, or POINT_PARTICLE

       REAL Mass;                        // the mass of the group

       int NumberOfGroupAtoms;           // the numer of atoms in the group
       int *Atoms;                       // the atoms in the group

       REAL_MATRIX3x3 InertiaTensor;     // the inertia tensor
       VECTOR InertiaVector;             // the inertia vector
       VECTOR InverseInertiaVector;      // the inverse of inertia vector

       REAL_MATRIX3x3 RotationalMatrix;  // the rotational matrix
       TRIPLE orientation;               // three atoms A,B,C to compute quaternions
       REAL rot_min;

       int RotationalDegreesOfFreedom;   // the rotational degrees of freedom
     } GROUP_DEFINITION;
\end{verbatim}
\end{footnotesize}
The inertia tensor, vector and rotational matrix etc. are the same for a certain type of molecule. Together with the actually atom positions, the orientations
can be computed for all the rigid units (i.e. the quaternions are computed).

\subsection*{Adsorbate and cations}
The definition of an adsorbate atom `ADSORBATE\_ATOM' is very similar to a framework atom
\begin{footnotesize}
\begin{verbatim}
     typedef struct adsorbate_atom
     {
       int Type;                       // the pseudo-atom type of the atom

       // MC/MD properties
       POINT Position;                 // the position of the atom
       POINT ReferencePosition;        // the `reference' position of the atom

       // MD properties
       VECTOR Velocity;                // the velocity of the atom
       VECTOR ReferenceVelocity;       // the `reference' velocity of the atom
       VECTOR Force;                   // the force acting on the atom

       VECTOR ElectricField;           // the electricfield vector
       VECTOR ReferenceElectricField;  // the `reference' electricfield vector
       VECTOR InducedElectricField;    // the induced electric field
       VECTOR InducedDipole;           // the induced dipole moment on this atom
       int HessianIndex;               // the index in the Hessian matrix for this atom
     } ADSORBATE_ATOM;
\end{verbatim}
\end{footnotesize}
The definition for cations is identical except it is called `CATION\_ATOM'.
The definition of an adsorbate molecule is
\begin{footnotesize}
\begin{verbatim}
     typedef struct adsorbate
     {
       int Type;               // the component type of the molecule
       int NumberOfAtoms;      // the number of atoms in the molecule
       GROUP *Groups;          // data of the rigid groups
       ADSORBATE_ATOM *Atoms;  // list of atoms
     } ADSORBATE_MOLECULE;
\end{verbatim}
\end{footnotesize}
The definition of a cation is called `CATION\_MOLECULE'.
Note that a molecule can consists of atoms, but also can contain rigid units. The atoms are accessible through the `Atoms' field, and rigid units
are accessible through the `Groups' field. A `GROUP' consists of
\begin{footnotesize}
\begin{verbatim}
     typedef struct group
     {
       REAL Mass;                             // mass of the rigid unit
       QUATERNION Quaternion;                 // orientation of the unit
       QUATERNION QuaternionMomentum;         // quaternion momentum
       QUATERNION QuaternionForce;            // quaternion force
       VECTOR Torque;                         // torque vector
       VECTOR CenterOfMassPosition;           // the center of mass position
       VECTOR CenterOfMassReferencePosition;  // the reference position for the center of mass
       VECTOR CenterOfMassVelocity;           // the center of mass velocity
       VECTOR CenterOfMassForce;              // the center of mass force
       VECTOR AngularVelocity;                // the angular velocity of the rigid unit
     } GROUP;
\end{verbatim}
\end{footnotesize}
which contains elements like position and orientation, and fields for the integration of rigid units, i.e. QuaternionMomentum etc.

\noindent
Molecules are stored as a list of molecules for each system
\begin{footnotesize}
\begin{verbatim}
     ADSORBATE_MOLECULE **Adsorbates;
\end{verbatim}
\end{footnotesize}
To get the type of the 5th atom of the 11th adsorbate of the first system, use
\begin{verbatim}
     int type;
     type=Adsorbates[0][10].Atoms[4].Type;
\end{verbatim}
As an example, here a function to measure the velocity drift of all the adsorbates in the current system
\begin{footnotesize}
\begin{verbatim}
     VECTOR MeasureVelocityDrift(void)
     {
       int i,k,l,Type,A,f;
       REAL Mass,TotalMass;
       VECTOR com;

       TotalMass=0.0;
       com.x=com.y=com.z=0.0;
       for(i=0;i<NumberOfAdsorbateMolecules[CurrentSystem];i++)
       {
         Type=Adsorbates[CurrentSystem][i].Type;
         for(l=0;l<Components[Type].NumberOfGroups;l++)
         {
           if(Components[Type].Groups[l].Rigid)
           {
             Mass=Components[Type].Groups[l].Mass;
             TotalMass+=Mass;
             com.x+=Mass*Adsorbates[CurrentSystem][i].Groups[l].CenterOfMassVelocity.x;
             com.y+=Mass*Adsorbates[CurrentSystem][i].Groups[l].CenterOfMassVelocity.y;
             com.z+=Mass*Adsorbates[CurrentSystem][i].Groups[l].CenterOfMassVelocity.z;
           }
           else
           {
             for(k=0;k<Components[Type].Groups[l].NumberOfGroupAtoms;k++)
             {
               A=Components[Type].Groups[l].Atoms[k];
               Mass=PseudoAtoms[Adsorbates[CurrentSystem][i].Atoms[A].Type].Mass;
               TotalMass+=Mass;
               com.x+=Mass*Adsorbates[CurrentSystem][i].Atoms[A].Velocity.x;
               com.y+=Mass*Adsorbates[CurrentSystem][i].Atoms[A].Velocity.y;
               com.z+=Mass*Adsorbates[CurrentSystem][i].Atoms[A].Velocity.z;
             }
           }
         }
       }
       com.x/=TotalMass;
       com.y/=TotalMass;
       com.z/=TotalMass;
       return com;
     }
\end{verbatim}
\end{footnotesize}
It loops over all the adsorbate molecules, and asks for the type. The component-type is important to get the number of groups for the current molecule.
Then, there is a inner loop over all of the groups of the current molecule. If the group is rigid, then the center of mass velocity is used, otherwise
it is flexible and it loops over all the atoms of the flexible group.
In general, if something is the same for a type of molecule then it is a property of the component. If it is different for each molecule, it is a property
of a molecule.
\section{Modifying}

\subsection{Monte Carlo}

\subsubsection*{Selecting MC moves}
The file `src/monte\_carlo.c' is the main Monte Carlo simulation routine. The bulk of the code deals with how to select a particular Monte carlo move.
Some requirements and conveniences:
\begin{itemize}
  \item{The moves should be chosen in random order}
  \item{System move should be chosen much less frequent than particle moves. The particles need to be able to adapt to the new system.}
  \item{For $n$ systems, the amount of steps should be $n$ times larger.}
  \item{For $n$ times as many molecules, the amount of steps should be $n$ times larger.}
  \item{For multi-component systems one needs more steps.}
  \item{For systems at low loadings, the sampling lengths should be increase a bit (i.e. set a minimum amount of inner steps).}
  \item{The relative probabilities of particle moves should be taken into account.}
\end{itemize}

\noindent A code which achieves all the above is listed here (there are many other ways of doing this). For each MC `cycle'
\begin{footnotesize}
\begin{verbatim}
      for(i=0;i<NumberOfSystems;i++)
      {
        // choose system at random
        CurrentSystem=(int)(RandomNumber()*(REAL)NumberOfSystems);

        NumberOfSystemMoves=9;
        NumberOfMolecules=NumberOfAdsorbateMolecules[CurrentSystem]+NumberOfCationMolecules[CurrentSystem];
        NumberOfParticleMoves=MAX(MinimumInnerCycles,NumberOfMolecules);
        NumberOfSteps=(NumberOfSystemMoves+NumberOfParticleMoves)*NumberOfComponents;

        // loop over the MC `steps' per MC `cycle'
        for(j=0;j<NumberOfSteps;j++)
        {
          // choose any of the MC moves randomly
          ran_int=(int)(RandomNumber()*NumberOfSteps);
          switch(ran_int)
          {
            case 0: if(RandomNumber()<ProbabilityParallelTemperingMove) ParallelTemperingMove(); break;
            case 1: if(RandomNumber()<ProbabilityHybridNVEMove) HybridNVEMove(); break;
            case 2: if(RandomNumber()<ProbabilityHybridNPHMove) HybridNPHMove(); break;
            case 3: if(RandomNumber()<ProbabilityHybridNPHPRMove) HybridNPHPRMove(); break;
            case 4: if(RandomNumber()<ProbabilityVolumeChangeMove) VolumeMove(); break;
            case 5: if(RandomNumber()<ProbabilityBoxShapeChangeMove) BoxShapeChangeMove(); break;
            case 6: if(RandomNumber()<ProbabilityGibbsVolumeChangeMove) GibbsVolumeMove(); break;
            case 7: if(RandomNumber()<ProbabilityFrameworkChangeMove) FrameworkChangeMove(); break;
            case 8: if(RandomNumber()<ProbabilityFrameworkShiftMove) FrameworkShiftMove(); break;
            default:
              // choose component at random
              CurrentComponent=(int)(RandomNumber()*(REAL)NumberOfComponents);

              // choose the Monte Carlo move at random
              ran=RandomNumber();
              if(ran<Components[CurrentComponent].ProbabilityTranslationMove) TranslationMove();
              else if(ran<Components[CurrentComponent].ProbabilityRandomTranslationMove) RandomTranslationMove();
              else if(ran<Components[CurrentComponent].ProbabilityRotationMove) RotationMove();
              else if(ran<Components[CurrentComponent].ProbabilityCBMCMove) CBMCMove();
              else if(ran<Components[CurrentComponent].ProbabilityReinsertionMove) ReinsertionMove();
              else if(ran<Components[CurrentComponent].ProbabilityReinsertionInPlaceMove) ReinsertionInPlaceMove();
              else if(ran<Components[CurrentComponent].ProbabilityReinsertionInPlaneMove) ReinsertionInPlaneMove();
              else if(ran<Components[CurrentComponent].ProbabilityIdentityChangeMove) IdentityChangeMove();
              else if(ran<Components[CurrentComponent].ProbabilitySwapMove)
              {
                if(RandomNumber()<0.5) SwapAddMove();
                else SwapRemoveMove();
              }
              else if(ran<Components[CurrentComponent].ProbabilityWidomMove) WidomMove();
              else if(ran<Components[CurrentComponent].ProbabilitySurfaceAreaMove) SurfaceAreaMove();
              else if(ran<Components[CurrentComponent].ProbabilityGibbsSwapChangeMove) GibbsParticleTransferMove();
              else if(ran<Components[CurrentComponent].ProbabilityGibbsIdentityChangeMove) GibbsIdentityChangeMove();
              break;
          }
        }
      }
\end{verbatim}
\end{footnotesize}
First is a loop over the amount of systems, and a random system is chosen. Suppose we have 200 single component molecules in this system, then each of the system move is chosen
with 1/209 probability (case 0-8), and there is a 200/209 chance to select a particle move (case 9-209). The probability of the particle moves are scaled in such a way that
the proper relative occurrence is obeyed (as specified in the input). Note that the swap-move has 50\% to be swap insertion and 50\% to be swap remove. This is necessary
to obey detailed balance. For multi-components more moves are performed.

\subsubsection*{Sampling properties during Monte Carlo}
The Monte Carlo routine has two parts:
\begin{itemize}
  \item{The initialization part. Here, no properties are computed and MC moves are performed just to reach equilibrium.}
  \item{The production run, where properties are computed.}
\end{itemize}
The basic outline of the production run is
\begin{footnotesize}
\begin{verbatim}
     // initialize sampling-routines at the start of the production run
     SampleInfraRedSpectra(INITIALIZE);
     SampleMeanSquareDisplacementOrderN(INITIALIZE);
     SampleOnsagerMeanSquareDisplacementOrderN(INITIALIZE);
     SampleRadialDistributionFunction(INITIALIZE);
     SampleFrameworkSpacingHistogram(INITIALIZE);
     SamplePositionHistogram(INITIALIZE);
     SampleNumberOfMoleculesHistogram(INITIALIZE);
     SampleEnergyHistogram(INITIALIZE);
     SampleDensityProfile3DVTKGrid(INITIALIZE);
     SampleEndToEndDistanceHistogram(INITIALIZE);
     SampleMoleculePropertyHistogram(INITIALIZE);
     SamplePDBMovies(INITIALIZE);
     SampleDcTSTConfigurationFiles(INITIALIZE);
     SampleFreeEnergyProfile(INITIALIZE);
     SampleCationAndAdsorptionSites(INITIALIZE);

     for(CurrentCycle=0;CurrentCycle<NumberOfCycles;CurrentCycle++)
     {
       // sample energy average and system/particle properties
       for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
       {
         UpdateEnergyAveragesCurrentSystem();

         SampleRadialDistributionFunction(SAMPLE);
         SampleFrameworkSpacingHistogram(SAMPLE);
         SamplePositionHistogram(SAMPLE);
         SampleNumberOfMoleculesHistogram(SAMPLE);
         SampleEnergyHistogram(SAMPLE);
         SampleDensityProfile3DVTKGrid(SAMPLE);
         SampleEndToEndDistanceHistogram(SAMPLE);
         SampleMoleculePropertyHistogram(SAMPLE);
         SampleFreeEnergyProfile(SAMPLE);
         SampleCationAndAdsorptionSites(SAMPLE);
       }

       // SELECTION OF MC-MOVES (SEE CODE OF THE PREVIOUS SECTION)

       for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
       {
         SampleRadialDistributionFunction(PRINT);
         SampleFrameworkSpacingHistogram(PRINT);
         SamplePositionHistogram(PRINT);
         SampleNumberOfMoleculesHistogram(PRINT);
         SampleEnergyHistogram(PRINT);
         SampleDensityProfile3DVTKGrid(PRINT);
         SampleEndToEndDistanceHistogram(PRINT);
         SampleMoleculePropertyHistogram(PRINT);
         SamplePDBMovies(PRINT);
         SampleDcTSTConfigurationFiles(PRINT);
         SampleFreeEnergyProfile(PRINT);
         SampleCationAndAdsorptionSites(PRINT);
       }
     }

     // finalize output
     SampleRadialDistributionFunction(FINALIZE);
     SampleFrameworkSpacingHistogram(FINALIZE);
     SamplePositionHistogram(FINALIZE);
     SampleNumberOfMoleculesHistogram(FINALIZE);
     SampleEnergyHistogram(FINALIZE);
     SampleDensityProfile3DVTKGrid(FINALIZE);
     SampleEndToEndDistanceHistogram(FINALIZE);
     SampleMoleculePropertyHistogram(FINALIZE);
     SamplePDBMovies(FINALIZE);
     SampleDcTSTConfigurationFiles(FINALIZE);
     SampleFreeEnergyProfile(FINALIZE);
     SampleCationAndAdsorptionSites(FINALIZE);
\end{verbatim}
\end{footnotesize}
Each of the sampling routine (in `src/sample.c') has 5 scaling options:
\begin{itemize}
 \item{ALLOCATE} to allocate memory needed for the sampling.
 \item{INITIALIZE} to initialized the routine if needed.
 \item{SAMPLE} to sample the properties.
 \item{PRINT} to periodically write the output to file.
 \item{FINALIZE} to free the requested memory and clean up.
\end{itemize}
Adding your own sampling routines requires an additional routine in `src/sample.c', the definition in `src/sample.h' and addition to
calls to `src/monte\_carlo.c'.

\subsection{Molecular Dynamics}

A molecular dynamics simulation is performed in several steps:
\begin{itemize}
  \item{The proper amount of molecules are created and they are inserted as as no overlaps occurred with the framework or other particles.}
  \item{Initialization: during the initialization period an NVT Monte-Carlo (MC) simulation is performed to rapidly achieve
        an equilibrium molecular arrangement.}
  \item{After the initialization period, velocities are assigned, drawn from the Maxwell-Boltzmann
        distribution at the desired average temperature to all the atoms. The total momentum of the system can be set to zero.}
  \item{Equilibration: Next, the system is further equilibrated by performing an NVT MD simulation using a specified ensemble.}
  \item{Production run: the simulation is performed in the requested ensemble and properties are measured.}
\end{itemize}
The amount of cycles for each of these steps can be specified. For example, when starting from a restart-file there is no need for the Monte Carlo initialization,
and if also the velocities are used from the restart-file then also the MD equilibration could be skipped. Moreover, the equilibration can be done in a different
ensemble as the production run. This is most useful for NVE simulations, where the equilibration could be done using NVT. The final temperature of the
NVE production run is then quite close the desired temperature (in NVE the temperature is not imposed).

The initialization part is not shown here, as it is very similar to regular Monte Carlo. The basic outline for the equilibration and production run are listed below.
The most important lines are the `Integration();' ones, which evolve the system a single time step. This routine is implemented in `src/integration.c' and makes use
of `src/thermo\_baro\_stats.c' for temperature and pressure control.

\begin{footnotesize}
\begin{verbatim}
     // initialize
     InitializesEnergiesAllSystems();
     InitializeSmallMCStatisticsAllSystems();
     InitializeMCMovesStatisticsAllSystems();

     // compute initial energy
     InitializeNoseHooverAllSystems();
     InitializeForcesAllSystems();

     // set the current ensemble to the initialization ensemble
     for(i=0;i<NumberOfSystems;i++)
       Ensemble[i]=InitEnsemble[i];

     InitializesEnergyAveragesAllSystems();

     for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
     {
       ReferenceEnergy[CurrentSystem]=ConservedEnergy[CurrentSystem];
       Drift[CurrentSystem]=0.0;
     }

     // Molecular-Dynamics initializing period to achieve a rapid equilibration of the velocities
     for(CurrentCycle=0;CurrentCycle<NumberOfEquilibrationCycles;CurrentCycle++)
     {
       for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
       {
         // regularly output system status and restart files
         if(CurrentCycle%PrintEvery==0)
         {
           PrintIntervalStatusEquilibration(CurrentCycle,NumberOfEquilibrationCycles,OutputFilePtr[CurrentSystem]);
           PrintRestartFile();
         }

         // evolve the system a full time-step
         Integration();

         // update the current energy-drift
         Drift[CurrentSystem]+=fabs((ConservedEnergy[CurrentSystem]-ReferenceEnergy[CurrentSystem])/
               ReferenceEnergy[CurrentSystem]);
       }
     }

     // initialize sampling-routines at the start of the production run
     for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
     {
       Ensemble[CurrentSystem]=RunEnsemble[CurrentSystem];

       ReferenceEnergy[CurrentSystem]=ConservedEnergy[CurrentSystem];
       Drift[CurrentSystem]=0.0;
     }
     SampleInfraRedSpectra(INITIALIZE);
     SampleEndToEndDistanceHistogram(INITIALIZE);
     SampleMeanSquareDisplacementOrderN(INITIALIZE);
     SampleOnsagerMeanSquareDisplacementOrderN(INITIALIZE);
     SampleEnergyHistogram(INITIALIZE);
     SamplePositionHistogram(INITIALIZE);
     SampleRadialDistributionFunction(INITIALIZE);
     SamplePositionHistogram(INITIALIZE);
     SampleMoleculePropertyHistogram(INITIALIZE);
     SamplePDBMovies(INITIALIZE);
     SampleCationAndAdsorptionSites(INITIALIZE);

     // Molecular-Dynamics production run
     // loop over the amount of production cycles (MD integration steps)
     for(CurrentCycle=0;CurrentCycle<NumberOfCycles;CurrentCycle++)
     {
       // loop over all the systems and handle one by one
       for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
       {
         SampleInfraRedSpectra(SAMPLE);
         SampleEndToEndDistanceHistogram(SAMPLE);
         SampleMeanSquareDisplacementOrderN(SAMPLE);
         SampleOnsagerMeanSquareDisplacementOrderN(SAMPLE);
         SampleEnergyHistogram(SAMPLE);
         SamplePositionHistogram(SAMPLE);
         SampleRadialDistributionFunction(SAMPLE);
         SamplePositionHistogram(SAMPLE);
         SampleMoleculePropertyHistogram(SAMPLE);
         SampleCationAndAdsorptionSites(SAMPLE);

         // update all the average energies
         UpdateEnergyAveragesCurrentSystem();

         if(CurrentCycle%PrintPropertiesEvery==0)
           PrintPropertyStatus(CurrentCycle,NumberOfCycles,OutputFilePtr[CurrentSystem]);

         if(CurrentCycle%PrintEvery==0)
         {
           PrintIntervalStatus(CurrentCycle,NumberOfCycles,OutputFilePtr[CurrentSystem]);
           PrintRestartFile();
         }

         // regulary output radial distribution function
         SampleInfraRedSpectra(PRINT);
         SampleEndToEndDistanceHistogram(PRINT);
         SampleMeanSquareDisplacementOrderN(PRINT);
         SampleOnsagerMeanSquareDisplacementOrderN(PRINT);
         SampleEnergyHistogram(PRINT);
         SamplePositionHistogram(PRINT);
         SampleRadialDistributionFunction(PRINT);
         SamplePositionHistogram(PRINT);
         SampleMoleculePropertyHistogram(PRINT);
         SamplePDBMovies(PRINT);
         SampleCationAndAdsorptionSites(PRINT);

         // evolve the current system a full time step
         Integration();

         // update the current energy-drift
         Drift[CurrentSystem]+=fabs((ConservedEnergy[CurrentSystem]-ReferenceEnergy[CurrentSystem])/
               ReferenceEnergy[CurrentSystem]);
       }
     }

     // finalize and clean up
     for(CurrentSystem=0;CurrentSystem<NumberOfSystems;CurrentSystem++)
     {
       SampleInfraRedSpectra(FINALIZE);
       SampleEndToEndDistanceHistogram(FINALIZE);
       SampleMeanSquareDisplacementOrderN(FINALIZE);
       SampleOnsagerMeanSquareDisplacementOrderN(FINALIZE);
       SampleEnergyHistogram(FINALIZE);
       SamplePositionHistogram(FINALIZE);
       SampleRadialDistributionFunction(FINALIZE);
       SamplePositionHistogram(FINALIZE);
       SampleMoleculePropertyHistogram(FINALIZE);
       SamplePDBMovies(FINALIZE);
       SampleCationAndAdsorptionSites(FINALIZE);
     }
\end{verbatim}
\end{footnotesize}
Adding your own sampling routines requires an additional routine in `src/sample.c', the definition in `src/sample.h' and addition to
calls to `src/molecular\_dynamics.c'.

\section{Debugging}

\subsection{Linux}

There are several debuggers like `gdb', and memory check utilities available, i.e. valgrind.

\subsection{Mac OSX}

Debugging memory error under Max OsX is easy. One can replace the standard library to allocate memory by different ones that check memory allocation and use.
It can catch a lot of array out-of-bound error, even for dynamically allocated memory. See

\begin{verbatim}
     man libgmalloc
\end{verbatim}

An example, export `RASPA\_DIR' to the installation directory, start the debugger, load the debugging libraries and start running the code.
\begin{verbatim}
     export RASPA_DIR=${HOME}/RASPA/simulations/
     gdb ~/RASPA/simulations/bin/simulate

     GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct  2 04:07:49 UTC 2007)
     Copyright 2004 Free Software Foundation, Inc.
     GDB is free software, covered by the GNU General Public License, and you are
     welcome to change it and/or distribute copies of it under certain conditions.
     Type "show copying" to see the conditions.
     There is absolutely no warranty for GDB.  Type "show warranty" for details.
     This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries ... done

     (gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib
     (gdb) r
\end{verbatim}


\documentclass[10pt, oneside, letterpaper]{article}
\usepackage[margin=1in]{geometry}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage{color}
\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}
\usepackage{listings}
\lstset{
  backgroundcolor=\color{white}, % choose the background color
  basicstyle=\footnotesize\ttfamily, % size of fonts used for the code
  breaklines=true, % automatic line breaking only at whitespace
  frame=single, % add a frame
  captionpos=b, % sets the caption-position to bottom
  commentstyle=\color{mygreen}, % comment style
  escapeinside={\%*}{*)}, % if you want to add LaTeX within your code
  keywordstyle=\color{blue}, % keyword style
  stringstyle=\color{mymauve}, % string literal style
}
\usepackage{enumitem}
\usepackage{blindtext}
\usepackage{datetime2}
\usepackage{fancyhdr}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{float}
\usepackage{pgf}
% \usepackage{layouts}
% \printinunitsof{in}\prntlen{\textwidth}
\title{Basic Circuit Discretization}
\author{Assignment 1a}
\date{Due: 2021/01/22}

\pagestyle{fancy}
\setlength{\headheight}{23pt}
\setlength{\parskip}{1em}
\fancyhf{}
\chead{Assignment 1a \\ Basic Circuit Discretization}
\rhead{Michel Kakulphimp \\ Student \#63542880}
\lhead{EECE560 \\ UBC MEng}
\cfoot{\thepage}

\begin{document}
\maketitle
\thispagestyle{fancy}

\section{Introduction}
In this first assignment, we are analyzing the transient behaviour of a series RL circuit as we close its main switch. Since this circuit and its constituent components can be modeled as an easy-to-solve first order differential equation, this allows us to simultaneously solve for its continuous time solution as well as apply some discretization techniques to enable solving the circuit in a step-by-step manner. Comparing the two allows us to analyze how well each discretization technique is able to approximate the true solution.

The following sections will discuss the derivation of the continuous time function as well as the derivation of the discretized functions. The trapezoidal and backward Euler approximations of a differential equation will be employed for this assignment. Following the derivations, we will plot different the approximations and compare their performance with respect to different time steps as well to each other. The continuous solutions will be overlayed to understand how well the approximations come to solving the circuit's solution.

Finally, a discussion of the results as well as improvements will be proposed. A full code listing of the code used in this project is provided as well for review.
\section{Setup}
The following sections go through the derivation of the different solutions used to produce the final plots for this assignment.
\subsection{Homogeneous Plus Steady-State Solutions}
In this section, we will derive the homogeneous plus steady-state solutions for $i(t)$ and $v_L(t)$. These solutions will plot the continuous time value for each of the quantities, and will be used as a baseline comparison to see how well the approximations match the ground truth. Using KVL, the circuit can be represented by the following equation:
\begin{alignat}{2}
10 - Ri(t) & = L\frac{di(t)}{d(t)}
\intertext{Solving this first order differential equation will provide the continuous time system solution for $i(t)$ and $v_L(t)$. First, we will derive the continuous time system solution for $i(t)$in terms of homogeneous plus steady-state equations:}
\frac{10 - Ri(t)}{L} & = \frac{di(t)}{dt} \\
\frac{dt}{L} & = \frac{di(t)}{10-Ri(t)} \\
\frac{1}{L}\int{}\,dt & = \int{}\frac{1}{10-R\,i(t)}di(t) \\
\frac{1}{L}t + K & = -\frac{1}{R}\ln{|10-R\,i(t)|} \\
e^{-\frac{R}{L}-RK} & = 10 - R\,i(t) \\
i(t) & = \frac{10}{R} - A\,e^{-\frac{R}{L}t} & A = e^{-RK} \\
\Aboxed{i(t) & = \frac{10}{R} - A\,e^{-\frac{R}{L}t}}
\intertext{We know from our initial conditions that $i(0) = 0$; this allows us to solve for the steady-state solution by solving for the constant $A$.}
0 & = \frac{10}{R} - A\,e^{-\frac{R}{L}(0)} \\
A & = \frac{10}{R}
\intertext{This gives us our final, continuous time solution for $i(t)$ as follows:}
i(t) & =\frac{10}{R} - \frac{10}{R}\,e^{-\frac{R}{L}t} & i(t)=0 \\
\Aboxed{i(t) & =\frac{10}{R} - \frac{10}{R}\,e^{-\frac{R}{L}t} & i(t)=0}
\intertext{Obtaining our continuous time $v_L(t)$ relies on the formula for the voltage across an inductor. Since we have obtained our $i(t)$, we can take its derivative with respect to time to obtain the equation's $\frac{di(t)}{dt}$ term.}
\frac{di(t)}{dt} & = A\,\frac{R}{L}\,e^{-\frac{R}{L}t}
\intertext{This derivative can then be substituted into the equation for the voltage across our inductor:}
v_L(t) & = L\,\frac{di(t)}{dt} \\
\Aboxed{v_L(t) & = A\,R\,e^{-\frac{R}{L}t}}
\intertext{Knowing our initial conditions, we obtain the following steady-state equation for $v_L(t)$}
\Aboxed{v_L(t) & = 10\,e^{-\frac{R}{L}t}}
\end{alignat}
\subsection{Isolating Components for Discretization}
In order to apply the trapezoidal and backward Euler discretizations used by the step-by-step solution, we must isolate the integration of $i(t)dt$. This is the component that will be approximated by the following discretization techniques:
\begin{alignat}{2}
\intertext{Trapezoidal:}
\int_{t-\Delta{}t}^{t}i(t)dt & \simeq \frac{i(t)+i(t-\Delta{}t)}{2}\Delta{}t
\intertext{Backward Euler:}
\int_{t-\Delta{}t}^{t}i(t)dt & \simeq i(t)\Delta{}t
\end{alignat}
The following steps will manipulate our original KVL relationship into a differential equation that can be discretized, isolating the integration of $i(t)dt$.
\begin{alignat}{2}
10 - Ri(t) & = L\frac{di(t)}{d(t)} \\
\frac{10}{L} - \frac{R}{L}i(t) & = \frac{di(t)}{dt} \\
\frac{10}{L}dt - \frac{R}{L}i(t)dt & = di(t) \\
\frac{10}{L}\int_{t-\Delta{}t}^{t}dt - \frac{R}{L}\int_{t-\Delta{}t}^{t}i(t)dt & = i(t) - i(t-\Delta{}t) \\
\frac{10}{L}[t - (t-\Delta{}t)] - \frac{R}{L}\int_{t-\Delta{}t}^{t}i(t)dt & = i(t) - i(t-\Delta{}t) \\
- \frac{R}{L}\int_{t-\Delta{}t}^{t}i(t)dt & = i(t) - i(t-\Delta{}t) - \frac{10}{L}\Delta{}t \\
\Aboxed{\int_{t-\Delta{}t}^{t}i(t)dt & = -\frac{L}{R}i(t) + \frac{L}{R}i(t-\Delta{}t) + \frac{10}{R}\Delta{}t}
\end{alignat}
With $\int_{t-\Delta{}t}^{t}i(t)dt$ isolated, we can now apply our discretization techniques to obtain our step-by-step solution for the current. Similarly, discretizing $v_L(t)$ can be performed by manipulating the fundamental equation for the voltage across an inductor:
\begin{alignat}{2}
v_L(t) & = L\frac{di(t)}{dt} \\
\int_{t-\Delta{}t}^{t}v_L(t) & = Ldi(t) \\
\Aboxed{\int_{t-\Delta{}t}^{t}v_L(t) & = L[i(t) - i(t-\Delta{}t)]}
\end{alignat}
\subsection{Trapezoidal Discretization}
The following is the derivation of the step-by-step solution for $i(t)$ and $v_L(t)$ using the trapezoidal discretization technique.
\begin{alignat}{2}
\intertext{Current $i(t)$:}
\frac{i(t)+i(t-\Delta{}t)}{2}\Delta{}t & \simeq -\frac{L}{R}i(t) + \frac{L}{R}i(t-\Delta{}t) + \frac{10}{R}\Delta{}t \\
i(t)\Delta{}t + i(t-\Delta{}t)\Delta{}t & \simeq \frac{2L}{R}i(t-\Delta{}t)-\frac{2L}{R}i(t) + \frac{20}{R}\Delta{}t \\
i(t)\Delta{}t + \frac{2L}{R}i(t) & \simeq \frac{2L}{R}i(t-\Delta{}t) - i(t-\Delta{}t)\Delta{}t+20\Delta{}t \\
\Aboxed{i(t) & \simeq \frac{i(t-\Delta{}t)[2L-R\Delta{}t] + 20\Delta{}t}{R\Delta{}t + 2L}}
\intertext{Voltage $v_L(t)$:}
\frac{v_L(t)+v_L(t-\Delta{}t)}{2}\Delta{}t & \simeq L[i(t) - i(t-\Delta{}t)] \\
\Aboxed{v_L(t) & \simeq \frac{2L}{\Delta{}t}[i(t) - i(t-\Delta{}t)] - v_L(t-\Delta{}t)}
\end{alignat}
\subsection{Backward Euler Discretization}
The following is the derivation of the step-by-step solution for $i(t)$ and $v_L(t)$ using the backward Euler discretization technique.
\begin{alignat}{2}
\intertext{Current $i(t)$:}
i(t)\Delta{}t & \simeq -\frac{L}{R}i(t) + \frac{L}{R}i(t-\Delta{}t) + \frac{10}{R}\Delta{}t \\
i(t)R\Delta{}t + Li(t) & \simeq  Li(t - \Delta{t}) + 10\Delta{}t \\
i(t)[R\Delta{}t + L] & \simeq Li(t - \Delta{}t) + 10\Delta{}t \\
\Aboxed{i(t) & \simeq \frac{Li(t - \Delta{}t) + 10\Delta{}t}{R\Delta{}t + L}}
\intertext{Voltage $v_L(t)$:}
v_L(t)\Delta{}t & \simeq L[i(t) - i(t-\Delta{}t)] \\
\Aboxed{v_L(t) & \simeq \frac{L[i(t) - i(t-\Delta{}t)]}{\Delta{}t}}
\end{alignat}
\section{Simulation}
With the equations derived, we can now plot our results to see how they perform with different parameters. The assignment requests the following solutions to be generated using a computer program:
\begin{enumerate}[label=\alph*)]
  \item Using the trapezoidal rule with $\Delta{}t_1 = 0.1ms$
  \item Using the backward Euler rule with $\Delta{}t_1 = 0.1ms$
  \item Using the trapezoidal rule with $\Delta{}t_2 = 0.8ms$
  \item Using the backward Euler rule with $\Delta{}t_2 = 0.8ms$
\end{enumerate}
In all plots, the continuous solution is plotted as a dotted line to show what the exact solution should be. This provides a baseline to compare the performance of the different approximations. Figure \ref{trap_approx}. shows the performance of the Trapezoidal approximation using time steps of $0.1ms$ and $0.8ms$. Figure \ref{back_approx}. shows the performance of the backward Euler approximation using time steps of $\Delta{}t_1 = 0.1ms$ and $\Delta{}t_2 = 0.8ms$. Finally, Figure \ref{approx_comp}. compares both approximation techniques using the time step of $\Delta{}t_2 = 0.8ms$.

As expected, the smaller the time step, the closer the step-by-step solutions approximate the real solution. This makes sense because as the $\Delta{}t$ becomes smaller, the closer it becomes to approximating the integration. What was unexpected, however, is the backward Euler solution more closely approximating the solution numerically versus the trapezoidal one. Intuitively, the trapezoidal solution should approximate the solution better due to its inclusion of a triangle area above the square below. The trapezoidal approximation does seem to follow the shape better than the backward Euler one, however. The backward Euler approximation can be seen to cross the true solution towards the end of the simulation in Figure \ref{approx_comp}. whereas the trapezoidal solution asymptotically approaches the true solution. At small time steps the trapezoidal solution is likely the better one.
\begin{figure}[H]
    \begin{center}
        \input{trapezoidal_plots.pgf}
    \end{center}
    \caption{Trapezoidal Approximations at $\Delta{}t_1 = 0.1 ms, \Delta{}t_2 = 0.8 ms$}
    \label{trap_approx}
\end{figure}

\begin{figure}[H]
    \begin{center}
        \input{backeuler_plots.pgf}
    \end{center}
    \caption{Backward Euler Approximations at $\Delta{}t_1 = 0.1 ms, \Delta{}t_2 = 0.8 ms$}
    \label{back_approx}
\end{figure}

\begin{figure}[H]
    \begin{center}
        \input{compare_plot_0p0008.pgf}
    \end{center}
    \caption{Comparison of Approximations at $\Delta{}t_2 = 0.8 ms$}
    \label{approx_comp}
\end{figure}
\section{Conclusion}
Overall this was a good refresher on transient circuit analysis as well as a productive introduction to discretization techniques. Further optimizations and improvements are proposed below:
\begin{itemize}
    \item In order to perform more efficient calculation steps, the program could decide to dynamically modify its solution's step size if it detects the output to be stable. This would allow it to more effectively make use of its compute cycles. A threshold could be implemented to determine the range of change for which it should attempt to modify its step size.
    \item In a similar vein, the program could also attempt changing its discretization rules on the fly to better approximate the transient solution. Perhaps in some scenarios, a circuit exhibits several different stages where certain approximations work better than others.
    \item Using a programming language that supports special compiler hints, a program could be written to make use of special processing units that accelerate an approximation's iteration. Perhaps a program could also run multiple discretization rules in parallel, and through some kind of analysis, dynamically switch between the more accurate solution.
\end{itemize}
\newpage
\section{Code Listing}
The following is the code written in Python to perform the calculations derived for this homework assignment as well as generate the plots used in this report.
\lstinputlisting[language=Python]{assignment1a.py}

\end{document}