\documentclass[notheorems]{beamer}

\usepackage[english]{babel}

\usepackage[latin1]{inputenc}

\input{abbrevs}

\usepackage[T1]{fontenc}

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{amsthm}

\theoremstyle{definition}
\newtheorem{definition}{Definition}

%\usepackage{tgtermes}
\usepackage{tgheros}
%\usepackage{cmbright}
\usepackage{qtxmath}
%\usepackage{kpfonts}
\renewcommand{\ttdefault}{txtt}

%\usepackage[amsmath,thmmarks]{ntheorem}

\usepackage{tikz}
\usetikzlibrary{arrows,positioning,chains}

\usepackage[color]{coqdoc}
\setlength{\coqdocbaseindent}{0.7em}

\usepackage{beamerthemesplit}

\setbeamertemplate{background canvas}[vertical shading][bottom=red!10,top=blue!10]
\setbeamertemplate{navigation symbols}{}
\setbeamertemplate{headline}{}
\usetheme{Warsaw}
\useinnertheme{rectangles}

\colorlet{darkred}{red!80!black}
\colorlet{darkblue}{blue!80!black}
\colorlet{darkgreen}{green!80!black}

\title{Infinitary Rewriting in \Coq}

\author{Martijn Vermaat}
\institute{VU University Amsterdam}
\date{August 2010}

\begin{document}

\frame{\titlepage}

\frame{

  \frametitle{Infinitary rewriting in \Coq}

  \tableofcontents

}

\section{Introduction}

\frame{

  \frametitle{Why?}

  Why formalize a mathematical theory mechanically?

  \pause

  \begin{itemize}
    \item Increases confidence in theorems
    \item Might catch oversights or errors in proofs
    \item Automation
    \item Gains insight and intuition
    \item Can form the basis of useful tools
  \end{itemize}

}

\frame{

  \frametitle{\Coq}

  \Coq is a \emph{proof assistant}

  \pause
  \begin{itemize}[<+->]
    \item (interactive) theorem prover
    \item proof checker
    \item programming language
    \item certified program extractor
  \end{itemize}

\pause

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdockw{Inductive} \coqdocinductive{nat}
:
\coqdockw{Set} :=\coqdoceol
\coqdocindent{0.3em}
\ensuremath{|} \coqdocconstructor{O}
:
\coqdocinductive{nat}\coqdoceol
\coqdocindent{0.3em}
\ensuremath{|} \coqdocconstructor{S}
:
\coqdocinductive{nat} \ensuremath{\rightarrow}
\coqdocinductive{nat}.
\coqdocindent{7.50em}
\coqdockw{Lemma}
\coqdoclemma{$+_0$}
: \ensuremath{\forall} \coqdocvar{n},
\coqdocvariable{n} = \coqdocvariable{n} + 0.\coqdoceol
\end{coqdoccode}

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Fixpoint}
+ (\coqdocvar{n} \coqdocvar{m} :
\coqdocinductive{nat}) :
\coqdocinductive{nat} :=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{n} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{O}
\ensuremath{\Rightarrow} \coqdocvariable{m}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{S}
\coqdocvar{n} \ensuremath{\Rightarrow}
\coqdocconstructor{S} (\coqdocvar{n} + \coqdocvar{m})\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Related work}

  \begin{block}{Rewriting in \Coq}
    \begin{description}
    \item[\CoLoR] focussed on termination
    \item[\Coccinelle] base of \CiME termination tool
    \end{description}
  \end{block}

  \begin{block}{Ordinals in \Coq}
    \begin{itemize}
    \item Cantor and Veblen normal forms (Cast\'eran)
    \item Set-theoretic surreal numbers (Mamane)
    \end{itemize}
  \end{block}

}

\section{Infinite terms}

\frame{

  \frametitle{Infinitary rewriting in \Coq}

  \tableofcontents[currentsection]

}

\frame{

  \frametitle{Coinductive terms}

  $\TerI(\X)$ defined in \Coq:\\[2em]

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{CoInductive}
\coqdocinductive{term} :
\coqdockw{Type} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Var} :
\coqdocvar{X}
\ensuremath{\rightarrow}
\coqdocinductive{term}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Fun} :
\ensuremath{\forall} \coqdocvar{f} : \coqdocvar{F},
\coqdocdefinition{vector}
\coqdocinductive{term}
(\coqdocprojection{arity} \coqdocvariable{f})
\ensuremath{\rightarrow}
\coqdocinductive{term}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

\pause

We use a recursive vector type instead of the standard inductive one.

}

\frame{

  \frametitle{Equalities on infinite terms}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{CoInductive}
$\sim$ :
\coqdocinductive{term} \ensuremath{\rightarrow}
\coqdocinductive{term} \ensuremath{\rightarrow}
\coqdockw{Prop} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{$\sim_\text{Var}$}
:
\ensuremath{\forall} \coqdocvar{x},
\coqdocconstructor{Var} \coqdocvariable{x}
$\sim$
\coqdocconstructor{Var}
\coqdocvariable{x}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{$\sim_\text{Fun}$}
:
\ensuremath{\forall} \coqdocvar{f} \coqdocvar{v} \coqdocvar{w},
(\ensuremath{\forall} \coqdocvar{i},
\coqdocvariable{v} \coqdocvariable{i}
$\sim$
\coqdocvariable{w} \coqdocvariable{i})
\ensuremath{\rightarrow}
\coqdocconstructor{Fun} \coqdocvariable{f}
\coqdocvariable{v}
$\sim$
\coqdocconstructor{Fun} \coqdocvariable{f}
\coqdocvariable{w}.\coqdoceol
\end{coqdoccode}

\pause

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Inductive}
\equpto{}
:
\coqdocinductive{nat}
\ensuremath{\rightarrow} \coqdocinductive{term}
\ensuremath{\rightarrow} \coqdocinductive{term}
\ensuremath{\rightarrow} \coqdockw{Prop} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{teut$_0$}   :
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{t},
\coqdocvariable{s} \equpto{0}
\coqdocvariable{t}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{teut$_\text{Var}$}
:
\ensuremath{\forall} \coqdocvar{d} \coqdocvar{x},
\coqdocconstructor{Var} \coqdocvariable{x}
\equpto{\coqdocvariable{d}}
\coqdocconstructor{Var}
\coqdocvariable{x}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{teut$_\text{Fun}$}
:
\ensuremath{\forall} \coqdocvar{d} \coqdocvar{f} \coqdocvar{v}
\coqdocvar{w},\coqdoceol
\coqdocindent{4em}
(\ensuremath{\forall} \coqdocvar{i},
\coqdocvariable{v} \coqdocvariable{i}
\equpto{\coqdocvariable{d}}
\coqdocvariable{w} \coqdocvariable{i}) \ensuremath{\rightarrow}
\coqdocconstructor{Fun}
\coqdocvariable{f} \coqdocvariable{v}
\equpto{\coqdocconstructor{S} \, \coqdocvariable{d}}
\coqdocconstructor{Fun} \coqdocvariable{f}
\coqdocvariable{w}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocvar{s}
$\equiv$
\coqdocvar{t} :=
\ensuremath{\forall} \coqdocvar{d},
\coqdocvariable{s}
\equpto{\coqdocvariable{d}}
\coqdocvariable{t}.\coqdoceol
\end{coqdoccode}

\pause

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Lemma}
\coqdoclemma{eq$_\equiv^\sim$}
: \ensuremath{\forall} \coqdocvar{s} \coqdocvar{t},
\coqdocvariable{s}
$\sim$
\coqdocvariable{t} \ensuremath{\leftrightarrow}
\coqdocvariable{s}
$\equiv$
\coqdocvariable{t}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Term rewriting systems}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Record} \coqdocrecord{rule} :
\coqdockw{Type} :=
\coqdocconstructor{Rule} \{\coqdoceol
\coqdocindent{1.00em}
\coqdocprojection{lhs}     :
\coqdocinductive{finite\_term};\coqdoceol
\coqdocindent{1.00em}
\coqdocprojection{rhs}     :
\coqdocinductive{finite\_term};\coqdoceol
\coqdocindent{1.00em}
\coqdocprojection{rule\_wf} :
\coqdocdefinition{is\_var}
\coqdocmethod{lhs} =
\coqdocconstructor{false}
\ensuremath{\land}
\coqdocdefinition{incl}
(\coqdocdefinition{vars}
\coqdocmethod{rhs})
(\coqdocdefinition{vars}
\coqdocmethod{lhs})\coqdoceol
\coqdocnoindent
\}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{left\_linear}
(\coqdocvar{r} : \coqdocrecord{rule}) :
\coqdockw{Prop} :=
\coqdocdefinition{linear}
(\coqdocprojection{lhs}
\coqdocvariable{r}).\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{trs} :=
\coqdocinductive{list}
\coqdocrecord{rule}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{trs\_left\_linear} (\coqdocvar{$\mathcal{R}$} : \coqdocdefinition{trs}) :
\coqdockw{Prop} :=\coqdoceol
\coqdocindent{1em}
\coqdocinductive{Forall} \coqdocdefinition{left\_linear}
\coqdocvar{$\mathcal{R}$}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Orthogonality}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{critical\_pair}
(\coqdocvar{$\mathcal{R}$} : \coqdocdefinition{trs})
(\coqdocvar{t$_1$} \coqdocvar{t$_2$} :
\coqdocinductive{term}) : \coqdockw{Prop}
:=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{\exists} \coqdocvar{$\rho_1$} :
\coqdocrecord{rule}, \ensuremath{\exists}
\coqdocvar{$\rho_2$} :
\coqdocrecord{rule},
\ensuremath{\exists} \coqdocvar{p} :
\coqdocabbreviation{position},
\ensuremath{\exists} \coqdocvar{$\sigma$},
\ensuremath{\exists} \coqdocvar{$\tau$},\coqdoceol
\coqdocindent{3.00em}
\coqdocvariable{$\rho_1$} \coqdocdefinition{$\in$}
\coqdocvariable{$\mathcal{R}$}
\ensuremath{\land}
\coqdocvariable{$\rho_2$} \coqdocdefinition{$\in$}
\coqdocvar{$\mathcal{R}$} \ensuremath{\land}
(\coqdocvariable{$\rho_1$} = \coqdocvariable{$\rho_2$} \ensuremath{\rightarrow}
\coqdocvariable{p} \ensuremath{\not=}
\coqdocconstructor{nil})
\ensuremath{\land}\coqdoceol
\coqdocindent{3.00em}
\coqdockw{match}
(\coqdocprojection{lhs}
\coqdocvariable{$\rho_1$})|$_{\coqdocvariable{p}}$,
(\coqdocprojection{lhs}
\coqdocvariable{$\rho_1$})$^{\coqdocvariable{$\sigma$}}$[$\Box$]$_{\coqdocvariable{p}}$ \coqdockw{with}\coqdoceol
\coqdocindent{3.00em}
\ensuremath{|}
\coqdocconstructor{Some}
\coqdocvar{s},
\coqdocconstructor{Some}
\coqdocvar{c} \ensuremath{\Rightarrow}\coqdoceol
\coqdocindent{5.00em}
\coqdocdefinition{is\_var} \coqdocvariable{s} =
\coqdocconstructor{false}
\ensuremath{\land}
\coqdocvariable{s}$^{\coqdocvariable{$\sigma$}}$ $\sim$
(\coqdocprojection{lhs}
\coqdocvariable{$\rho_2$})$^{\coqdocvariable{$\tau$}}$
\ensuremath{\land}\coqdoceol
\coqdocindent{5.00em}
\coqdocvariable{t$_1$} $\sim$
\coqdocvariable{c}[(\coqdocprojection{rhs}
\coqdocvariable{$\rho_2$})$^{\coqdocvariable{$\tau$}}$] \ensuremath{\land}
\coqdocvariable{t$_2$} $\sim$
(\coqdocprojection{rhs}
\coqdocvariable{$\rho_1$})$^{\coqdocvariable{$\sigma$}}$\coqdoceol
\coqdocindent{3.00em}
\ensuremath{|} \coqdocvar{\_}, \coqdocvar{\_}
\ensuremath{\Rightarrow}
\coqdocinductive{False}\coqdoceol
\coqdocindent{3.00em}
\coqdockw{end}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{orthogonal} (\coqdocvar{$\mathcal{R}$} :
\coqdocdefinition{trs})
: \coqdockw{Prop} :=\coqdoceol
\coqdocindent{1.00em}
\coqdocdefinition{trs\_left\_linear}
\coqdocvariable{$\mathcal{R}$} \ensuremath{\land}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{\forall} \coqdocvar{t$_1$} \coqdocvar{t$_2$}, \ensuremath{\lnot}
\coqdocdefinition{critical\_pair}
\coqdocvariable{t$_1$} \coqdocvariable{t$_2$}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{weakly\_orthogonal} (\coqdocvar{$\mathcal{R}$} :
\coqdocdefinition{trs})
: \coqdockw{Prop} :=\coqdoceol
\coqdocindent{1.00em}
\coqdocdefinition{trs\_left\_linear}
\coqdocvariable{$\mathcal{R}$} \ensuremath{\land}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{\forall} \coqdocvar{t$_1$} \coqdocvar{t$_2$},
\coqdocdefinition{critical\_pair}
\coqdocvariable{t$_1$} \coqdocvariable{t$_2$} \ensuremath{\rightarrow}
\coqdocvariable{t$_1$} $\sim$ \coqdocvariable{t$_2$}.\coqdoceol
\end{coqdoccode}

}

\section{Ordinal numbers}

\frame{

  \frametitle{Infinitary rewriting in \Coq}

  \tableofcontents[currentsection]

}

\frame{

  \frametitle{Brouwer ordinals}

\begin{definition}
The set of \emph{Brouwer ordinals} $\Ord$ is defined by induction:
\begin{itemize}
  \item
    $0 \in \Ord$
  \item
    If $\alpha \in \Ord$, then $\alpha^+ \in \Ord$
  \item
    If $\alpha_i \in \Ord$ for all $i \in \mathbb{N}$, then $\sqcup_i
    \alpha_i \in \Ord$
\end{itemize}
\end{definition}

\pause

\begin{itemize}
  \item We need an order on $\Ord$
  \item It should position $\sqcup_i i + 3$ and $\sqcup_i i \times 2$
    at the same rank
  \item And what to make of $\sqcup \{ 3, 3, 3, \ldots \}$?
\end{itemize}

}

\frame{

  \frametitle{Structural partial order on $\Ord$}

\begin{definition}
The set-valued function $\Phi$ defines the \emph{predecessor indices}
$\Phi(\alpha)$
\emph{for} $\alpha$ by recursion on $\alpha$:
\begin{align*}
  \Phi(0)                 &= \emptyset \\
  \Phi(\alpha^+)          &= \Phi(\alpha)^? \\
  \Phi(\sqcup_i \alpha_i) &= (\Sigma n \in \mathbb{N}) \;
  \Phi(\alpha_n)
\end{align*}
\end{definition}

\begin{definition}
The function $\_[\_] : (\prod \alpha : \Ord) \; \Phi(\alpha)
\rightarrow
\Ord$ defines the \emph{predecessor} $\alpha[\iota]$ \emph{of}
$\alpha$ \emph{indexed by} $\iota$ recursively on $\alpha$:
\begin{align*}
  \alpha^+[\textsc{none}]                     &= \alpha \\
  \alpha^+[\textsc{some $\iota$}]             &= \alpha[\iota] \\
  \sqcup_i \alpha_i[\langle n, \iota \rangle] &= \alpha_n[\iota]
\end{align*}
\end{definition}

}

\frame{

  \frametitle{Extensional order on $\Ord$}

\begin{definition}
We define the \emph{order} $\preceq$ as a binary relation on $\Ord$ by
induction:
\begin{itemize}
  \item
    $0 \preceq \beta$ for every ordinal $\beta \in \Ord$
  \item
    For all $\alpha, \beta \in \Ord$ and $\iota \in \Phi(\beta)$, if
    $\alpha \preceq \beta[\iota]$ then $\alpha^+ \preceq \beta$
  \item
    For all $\alpha_0, \alpha_1, \alpha_2, \ldots, \beta \in \Ord$, if
    $\alpha_n \preceq \beta$ for all $n \in \mathbb{N}$, then
    $\sqcup_i
    \alpha_i \preceq \beta$
\end{itemize}
\end{definition}

\begin{itemize}
  \item $\alpha \simeq \beta$ if $\alpha \preceq \beta$ and $\beta
    \preceq \alpha$
  \item $\alpha \prec \beta$ if $\alpha \preceq \beta[\iota]$ for some
    $\iota \in \Phi(\beta)$
\end{itemize}

}

\frame{

  \frametitle{Brouwer ordinals in \Coq}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Inductive} \coqdocinductive{ord}
:
\coqdockw{Set} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Zero}
:
\coqdocinductive{ord}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Succ}
:
\coqdocinductive{ord} \ensuremath{\rightarrow}
\coqdocinductive{ord}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{Limit} :
(\coqdocinductive{nat}
\ensuremath{\rightarrow} \coqdocinductive{ord})
\ensuremath{\rightarrow}
\coqdocinductive{ord}.\coqdoceol
\end{coqdoccode}

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Fixpoint} \coqdocdefinition{wf}
\coqdocvar{\ensuremath{\alpha}} : \coqdockw{Prop} :=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{\ensuremath{\alpha}}
\coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Zero}
\ensuremath{\Rightarrow}
\coqdocinductive{True}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Succ}
\coqdocvar{\ensuremath{\beta}} \ensuremath{\Rightarrow}
\coqdocdefinition{wf}
\coqdocvariable{\ensuremath{\beta}}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Limit}
\coqdocvar{f}
\ensuremath{\Rightarrow} \ensuremath{\forall} \coqdocvar{n},
\coqdocdefinition{wf} (\coqdocvariable{f}
\coqdocvariable{n}) \ensuremath{\land} \ensuremath{\forall}
\coqdocvar{m},
\coqdocvariable{n} < \coqdocvariable{m} \ensuremath{\rightarrow}
\coqdocvariable{f} \coqdocvariable{n} \ensuremath{\prec}
\coqdocvariable{f} \coqdocvariable{m}\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{ord$^\text{wf}$}
: \coqdockw{Set}
:=
\coqdocinductive{sig} \coqdocdefinition{wf}.\coqdoceol
\end{coqdoccode}

}

\section{Rewrite sequences of ordinal length}

\frame{

  \frametitle{Infinitary rewriting in \Coq}

  \tableofcontents[currentsection]

}

\frame{

  \frametitle{Rewrite steps}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Inductive}
$\rightarrow_\mathcal{R}$ :
\coqdocinductive{term} \ensuremath{\rightarrow}
\coqdocinductive{term} \ensuremath{\rightarrow}
\coqdockw{Type} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Step}
:
\ensuremath{\forall} (\coqdocvar{s} \coqdocvar{t} :
\coqdocinductive{term}) (\coqdocvar{$\rho$} :
\coqdocrecord{rule}) (\coqdocvar{c} :
\coqdocinductive{context}) (\coqdocvar{$\sigma$} :
\coqdocdefinition{substitution}),\coqdoceol
\coqdocindent{6.50em} \coqdocvariable{$\rho$}
\coqdocdefinition{$\in$}
\coqdocvar{$\mathcal{R}$} \ensuremath{\rightarrow}\coqdoceol
\coqdocindent{6.50em}
\coqdocvariable{c}[(\coqdocprojection{lhs}
\coqdocvariable{$\rho$})\coqdocvariable{$^\sigma$}] $\sim$
\coqdocvariable{s}
\ensuremath{\rightarrow}\coqdoceol
\coqdocindent{6.50em}
\coqdocvariable{c}[(\coqdocprojection{rhs}
\coqdocvariable{$\rho$})\coqdocvariable{$^\sigma$}] $\sim$
\coqdocvariable{t}
\ensuremath{\rightarrow}\coqdoceol
\coqdocindent{6.50em}
\coqdocvariable{s} $\rightarrow_\mathcal{R}$
\coqdocvariable{t}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Rewrite sequences}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Inductive}
$\twoheadrightarrow_\mathcal{R}$
:
\coqdocinductive{term} \ensuremath{\rightarrow}
\coqdocinductive{term} \ensuremath{\rightarrow}
\coqdockw{Type} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Nil} :
\ensuremath{\forall} \coqdocvar{t}, \coqdocvariable{t}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{t}\coqdoceol \coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Cons}
:
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{t} \coqdocvar{u},
\coqdocvar{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvar{t}
$\rightarrow$
\coqdocvariable{t} $\rightarrow_\mathcal{R}$
\coqdocvar{u} $\rightarrow$ \coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{u}\coqdoceol \coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Lim}   :
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{t},
(\coqdocinductive{nat}
\ensuremath{\rightarrow} \coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\textbf{?})
$\rightarrow$
\coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{t}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

\pause

Parameterize \coqdocconstructor{Lim} with target terms of
branches, they should converge to \coqdocvariable{t}.

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Lim} :
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{t}
(\coqdocvar{ts} :
\coqdocinductive{nat}
\ensuremath{\rightarrow} \coqdocinductive{term}),
\coqdocdefinition{converges}
\coqdocvariable{ts}
\coqdocvariable{t} $\rightarrow$\coqdoceol
\coqdocindent{5em}
(\ensuremath{\forall} \coqdocvar{n}, \coqdocvar{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvar{ts} \coqdocvariable{n}) $\rightarrow$
\coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{t}\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Predecessor indices for $\twoheadrightarrow_\mathcal{R}$}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Fixpoint}
\coqdocdefinition{pred\_type}
\coqdocvar{s} \coqdocvar{t}
(\coqdocvar{$\varphi$} : \coqdocvar{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvar{t}) :
\coqdockw{Type} :=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{$\varphi$} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Nil}
\coqdocvar{\_}
\ensuremath{\Rightarrow}
\coqdocinductive{False}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Cons}
\coqdocvar{\_} \coqdocvar{\_} \coqdocvar{\_} \coqdocvar{$\psi$}
\coqdocvar{\_}
\ensuremath{\Rightarrow}
\coqdocinductive{unit}
+ \coqdocdefinition{pred\_type}
\coqdocvariable{$\psi$}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Lim}
\coqdocvar{\_}
\coqdocvar{\_} \coqdocvar{\_} \coqdocvar{f} \coqdocvar{\_}
\ensuremath{\Rightarrow} \{ \coqdocvar{n} :
\coqdocinductive{nat}
\& \coqdocdefinition{pred\_type}
(\coqdocvariable{f} \coqdocvariable{n}) \}\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\end{coqdoccode}

\pause

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Fixpoint}
\coqdocdefinition{pred}
\coqdocvar{s} \coqdocvar{t} (\coqdocvar{$\varphi$} : \coqdocvar{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvar{t})
(\coqdocvar{$\iota$} :
\coqdocdefinition{pred\_type}
\coqdocvariable{$\varphi$})
:\coqdoceol \coqdocindent{2.00em}
\{ \coqdocvar{ts} :
\coqdocabbreviation{term} \ensuremath{\times}
\coqdocabbreviation{term} \&
(\coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocdefinition{fst}
\coqdocvariable{ts}) \ensuremath{\times}
(\coqdocdefinition{fst}
\coqdocvariable{ts} $\rightarrow_\mathcal{R}$
\coqdocdefinition{snd}
\coqdocvariable{ts}) \} :=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{$\varphi$} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Nil}
\coqdocvar{\_}
\ensuremath{\Rightarrow}
(\coqdocdefinition{False\_rect}
\coqdocvar{\_}) \coqdocvariable{$\iota$} \coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Cons}
\coqdocvar{\_}
\coqdocvar{u} \coqdocvar{t} \coqdocvar{$\psi$} \coqdocvar{$\pi$}
\ensuremath{\Rightarrow}
\coqdockw{match} \coqdocvariable{$\iota$} \coqdockw{with}\coqdoceol
\coqdocindent{10.00em}
\ensuremath{|}
\coqdocconstructor{inl}
\coqdocconstructor{tt}
\ensuremath{\Rightarrow}
\coqdocconstructor{existT}
\coqdocvar{\_} (\coqdocvariable{u}, \coqdocvariable{t})
(\coqdocvariable{$\psi$}, \coqdocvariable{$\pi$})\coqdoceol
\coqdocindent{10.00em}
\ensuremath{|}
\coqdocconstructor{inr}
\coqdocvar{$\kappa$}  \ensuremath{\Rightarrow}
\coqdocdefinition{pred}
\coqdocvariable{$\psi$}
\coqdocvariable{$\kappa$}\coqdoceol
\coqdocindent{10.00em}
\coqdockw{end}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Lim}
\coqdocvar{\_}
\coqdocvar{\_} \coqdocvar{\_} \coqdocvar{f} \coqdocvar{\_}
\ensuremath{\Rightarrow}
\coqdockw{match} \coqdocvariable{$\iota$} \coqdockw{with}\coqdoceol
\coqdocindent{10.00em}
\ensuremath{|}
\coqdocconstructor{existT}
\coqdocvar{n} \coqdocvar{$\kappa$} \ensuremath{\Rightarrow}
\coqdocdefinition{pred} (\coqdocvariable{f}
\coqdocvariable{n}) \coqdocvariable{$\kappa$}\coqdoceol
\coqdocindent{10.00em}
\coqdockw{end}
\coqdockw{end}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Notations for predecessor indexing}

{\renewcommand{\arraystretch}{1.1}
\renewcommand{\tabcolsep}{10pt}
\begin{tabular}{ll}
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}] & location of
\coqdocvariable{$\varphi$} indexed by \coqdocvariable{$\iota$}\\
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{seq}$ &
predecessor rewrite sequence of \coqdocvariable{$\varphi$} indexed by
\coqdocvariable{$\iota$}\\
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{stp}$ &
step of \coqdocvariable{$\varphi$} indexed by
\coqdocvariable{$\iota$}\\
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{l}$ &
source term of
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{stp}$
(also target term of
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{seq}$)\\
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{r}$ &
target term of
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{stp}$
\end{tabular}}\\[2em]

\begin{center}
\coqdocvariable{$\varphi$}[\coqdocvariable{$\iota$}]$^\textsc{stp}$
\ \ \ \ \ \ instead of \ \ \ \ \ \ \coqdocdefinition{snd}
(\coqdocdefinition{projT2} (\coqdocdefinition{pred}
\coqdocvariable{$\varphi$} \coqdocvariable{$\iota$}))
\end{center}

}

\frame{

  \frametitle{Example}

\begin{center}
\begin{tikzpicture}[scale=0.84]
\input{figures/predecessor.tikz}
\end{tikzpicture}
\end{center}

\footnotesize{Rewrite sequence of length $\omega + 2$ with predecessor index
$\coqdocconstructor{inr} \; (\coqdocconstructor{inr} \; \langle 4,
\coqdocconstructor{inl}\rangle)$}

}

\frame{

  \frametitle{Embeddings of rewrite sequences}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Inductive} $\sqsubseteq$
: \ensuremath{\forall} \coqdocvar{s} \coqdocvar{t} \coqdocvar{u}
\coqdocvar{v}, \coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{t}
$\rightarrow$ \coqdocvariable{u}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{v}
$\rightarrow$ \coqdockw{Prop} :=\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{$\sqsubseteq_\text{Nil}$}
:
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{u} \coqdocvar{v}
(\coqdocvar{$\psi$}
: \coqdocvariable{u}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{v}),\coqdoceol
\coqdocindent{9.50em}
\coqdocconstructor{Nil} \coqdocvariable{s}
$\sqsubseteq$
\coqdocvariable{$\psi$}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{$\sqsubseteq_\text{Cons}$}
:
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{t} \coqdocvar{u}
\coqdocvar{v}
(\coqdocvar{$\psi$}
: \coqdocvariable{u}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{v}) (\coqdocvar{$\iota$} :
\coqdocdefinition{pred\_type}
\coqdocvariable{$\psi$})\coqdoceol
\coqdocindent{5.00em}
(\coqdocvar{$\varphi$} : \coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{$\psi$}[\coqdocvariable{$\iota$}]$^\textsc{l}$)
(\coqdocvar{$\pi$} :
\coqdocvariable{$\psi$}[\coqdocvariable{$\iota$}]$^\textsc{l}$
$\rightarrow_\mathcal{R}$
\coqdocvariable{t}),\coqdoceol
\coqdocindent{9.50em}
\coqdocvariable{$\varphi$} $\sqsubseteq$
\coqdocvariable{$\psi$}[\coqdocvariable{$\iota$}]$^\textsc{seq}$
\ensuremath{\rightarrow}\coqdoceol
\coqdocindent{9.50em}
\coqdocvariable{$\pi$} $\approx$
\coqdocvariable{$\psi$}[\coqdocvariable{$\iota$}]$^\textsc{stp}$
\ensuremath{\rightarrow}\coqdoceol
\coqdocindent{9.50em}
\coqdocconstructor{Cons}
\coqdocvariable{$\varphi$} \coqdocvariable{$\pi$}
$\sqsubseteq$
\coqdocvariable{$\psi$}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{$\sqsubseteq_\text{Lim}$}
:
\ensuremath{\forall} \coqdocvar{s} \coqdocvar{t} \coqdocvar{u}
\coqdocvar{v}
(\coqdocvar{ts} :
\coqdocinductive{nat}
\ensuremath{\rightarrow} \coqdocinductive{term})
(\coqdocvar{f} : \ensuremath{\forall} \coqdocvar{n},
\coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{ts} \coqdocvariable{n})\coqdoceol
\coqdocindent{5.00em}
(\coqdocvar{c} :
\coqdocdefinition{converges}
\coqdocvariable{ts}
\coqdocvar{t}) (\coqdocvar{$\psi$} : \coqdocvar{u}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvar{v}),\coqdoceol
\coqdocindent{9.50em}
(\ensuremath{\forall} \coqdocvar{n}, \coqdocvariable{f}
\coqdocvariable{n}
$\sqsubseteq$ \coqdocvariable{$\psi$})
\ensuremath{\rightarrow}\coqdoceol
\coqdocindent{9.50em}
\coqdocconstructor{Lim} \coqdocvariable{f}
\coqdocvariable{c} $\sqsubseteq$
\coqdocvariable{$\psi$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Definition}
$\sqsubset$
\coqdocvar{s} \coqdocvar{t} \coqdocvar{u} \coqdocvar{v}
(\coqdocvar{$\varphi$} : \coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{t},
\coqdocvar{$\psi$} :
\coqdocvariable{u}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{v}) :=\coqdoceol
\coqdocindent{1em}
\ensuremath{\exists} \coqdocvar{$\iota$},
\coqdocvariable{$\varphi$} $\sqsubseteq$
\coqdocvariable{$\psi$}[\coqdocvariable{$\iota$}]$^\textsc{seq}$.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Well-formed rewrite sequences}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Fixpoint} \coqdocdefinition{wf}
\coqdocvar{s} \coqdocvar{t}
(\coqdocvar{$\varphi$} : \coqdocvariable{s}
$\twoheadrightarrow_\mathcal{R}$
\coqdocvariable{t}) : \coqdockw{Prop}
:=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{$\varphi$} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Nil}
\coqdocvar{\_} \ensuremath{\Rightarrow}
\coqdocinductive{True}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Cons}
\coqdocvar{\_} \coqdocvar{\_} \coqdocvar{$\psi$} \coqdocvar{\_}
\coqdocvar{\_} \ensuremath{\Rightarrow}
\coqdocdefinition{wf}
\coqdocvariable{\coqdocvariable{$\psi$}}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocconstructor{Lim}
\coqdocvar{\_} \coqdocvar{\_} \coqdocvar{f} \coqdocvar{\_}
\coqdocvar{\_}  \ensuremath{\Rightarrow}
(\ensuremath{\forall} \coqdocvar{n},
\coqdocdefinition{wf} (\coqdocvariable{f}
\coqdocvariable{n})) \ensuremath{\land}
\ensuremath{\forall} \coqdocvar{n} \coqdocvar{m}, \coqdocvariable{n}
< \coqdocvariable{m} \ensuremath{\rightarrow} \coqdocvariable{f}
\coqdocvariable{n}
$\sqsubset$
\coqdocvariable{f} \coqdocvariable{m}\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\end{coqdoccode}

}

\section{\texorpdfstring{UN$^\infty$}{UN} and weak orthogonality}

\frame{

  \frametitle{Infinitary rewriting in \Coq}

  \tableofcontents[currentsection]

}

\frame{

  \frametitle{UN$^\infty$ and weak orthogonality}

  Orthogonality implies UN$^\infty$; what about weak orthogonality?\\[2em]

  \pause

  The TRS
  \begin{align*}
    \rho_1 \, &: \, PSx \to x\\
    \rho_2 \, &: \, SPx \to x
  \end{align*}
  is weakly orthogonal and
  \begin{align*}
    \psi = P \, SS \, PPP \, SSSS \, PPPPP \, SSSSSS \ldots
  \end{align*}
  has two normal forms:
  \begin{align*}
    S^\omega \quad \twoheadleftarrow_{\rho_1} \quad \psi \quad
    \twoheadrightarrow_{\rho_2} \quad P^\omega
  \end{align*}

}

\frame{

  \frametitle{S$^\omega$, P$^\omega$ and $\psi$ in \Coq}

  We define finite repetitions by recursion

\begin{coqdoccode}
\coqdocemptyline
\coqdocnoindent
\coqdockw{Fixpoint}
\coqdocdefinition{Pnt} (\coqdocvar{n} :
\coqdocinductive{nat})
\coqdocvar{t} :=
\coqdockw{match} \coqdocvariable{n} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{O}
\ensuremath{\Rightarrow} \coqdocvariable{t}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{S}
\coqdocvar{n} \ensuremath{\Rightarrow}
\coqdocconstructor{P} @
(\coqdocdefinition{Pnt} \coqdocvariable{n}
\coqdocvariable{t})\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\coqdocemptyline
\end{coqdoccode}

and infinite repetitions by corecursion

\begin{coqdoccode}
\coqdocemptyline
\coqdocnoindent
\coqdockw{CoFixpoint}
\coqdocdefinition{S$^\omega$}
: \coqdocinductive{term} :=
\coqdocconstructor{S} @ \coqdocdefinition{S$^\omega$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

\pause

We would like to define $\psi$ as

\begin{coqdoccode}
\coqdocemptyline
\coqdocnoindent
\coqdockw{CoFixpoint}
\coqdocdefinition{$\psi'$} \coqdocvar{n}
: \coqdocinductive{term} :=\coqdoceol
\coqdocindent{1.00em}
\coqdocdefinition{Snt} \coqdocvariable{n} (\coqdocdefinition{Pnt}
(\coqdocconstructor{S} \coqdocvariable{n}) (\coqdocdefinition{$\psi'$}
(\coqdocconstructor{S} (\coqdocconstructor{S}
\coqdocvariable{n})))).\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\psi$} :=
\coqdocdefinition{$\psi'$} 0.\coqdoceol
\coqdocemptyline
\end{coqdoccode}

but this definition is not guarded.

}

\frame{

  \frametitle{$\psi$ in \Coq}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{CoFixpoint}
\coqdocdefinition{$\psi'$} \coqdocvar{n}
: \coqdocinductive{term} :=\coqdoceol
\coqdocindent{1.00em}
(\coqdocvar{cofix} \coqdocvar{P2nPt} (\coqdocvar{p} :
\coqdocinductive{nat})
:=\coqdoceol
\coqdocindent{2.00em}
\coqdockw{match} \coqdocvariable{p} \coqdockw{with}\coqdoceol
\coqdocindent{2.00em}
\ensuremath{|}
\coqdocconstructor{O}
\ensuremath{\Rightarrow} \coqdocconstructor{P}
@ (\coqdocvar{cofix} \coqdocvar{S2nt} (\coqdocvar{s} :
\coqdocinductive{nat})
:=\coqdoceol
\coqdocindent{7.50em}
\coqdockw{match} \coqdocvariable{s} \coqdockw{with}\coqdoceol
\coqdocindent{7.50em}
\ensuremath{|}
\coqdocconstructor{O}
\ensuremath{\Rightarrow}
\coqdocdefinition{$\psi'$}
(\coqdocconstructor{S}
\coqdocvariable{n})\coqdoceol
\coqdocindent{7.50em}
\ensuremath{|}
\coqdocconstructor{S}
\coqdocvar{s} \ensuremath{\Rightarrow}
\coqdocconstructor{S} @
\coqdocconstructor{S} @ (\coqdocvariable{S2nt}
\coqdocvariable{s})\coqdoceol
\coqdocindent{7.50em}
\coqdockw{end})
(\coqdocconstructor{S}
\coqdocvariable{n})\coqdoceol
\coqdocindent{2.00em}
\ensuremath{|}
\coqdocconstructor{S}
\coqdocvar{p} \ensuremath{\Rightarrow}
\coqdocconstructor{P} @
\coqdocconstructor{P} @
(\coqdocvariable{P2nPt} \coqdocvariable{p})\coqdoceol
\coqdocindent{2.00em}
\coqdockw{end}) \coqdocvariable{n}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\psi$} :=
\coqdocdefinition{$\psi'$} 0.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{The TRS in \Coq}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\mathcal{R}$} :=
\coqdocdefinition{$\rho_1$} ::
\coqdocdefinition{$\rho_2$} ::
\coqdocconstructor{nil}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Lemma}
\coqdoclemma{wo$_\mathcal{R}$} :
\coqdocdefinition{weakly\_orthogonal} \coqdocdefinition{$\mathcal{R}$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Lemma} \coqdoclemma{nf$_{\text{S}^\omega}$} :
\coqdocdefinition{normal\_form}
(\coqdocvar{system} :=
\coqdocdefinition{$\mathcal{R}$}) \coqdocdefinition{S$^\omega$}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Lemma} \coqdoclemma{nf$_{\text{P}^\omega}$} :
\coqdocdefinition{normal\_form}
(\coqdocvar{system} :=
\coqdocdefinition{$\mathcal{R}$}) \coqdocdefinition{P$^\omega$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Lemma}
\coqdoclemma{neq$^{\text{S}^\omega}_{\text{P}^\omega}$} :
\ensuremath{\lnot}
\coqdocdefinition{S$^\omega$} $\sim$
\coqdocdefinition{P$^\omega$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

Now we construct rewrite sequences from $\psi$ to $S^\omega$ and
$P^\omega$.

}

\frame{

  \frametitle{Example rewrite sequences from $\psi$ to $\ldots$}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\phi_0$}
: \coqdocdefinition{$\psi$} $\twoheadrightarrow_\mathcal{R}$
\coqdocdefinition{$\psi$} :=
\coqdocconstructor{Nil}
\coqdocdefinition{$\psi$}.\coqdoceol
\end{coqdoccode}

\pause

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\sigma_1$}
(\coqdocvar{x} : \coqdocdefinition{X}) :
\coqdocinductive{term} :=
\coqdockw{match} \coqdocvariable{x} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
1 \ensuremath{\Rightarrow}
\coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} 1
$\quad$ \ensuremath{|} $\quad$ \coqdocvar{\_} \ensuremath{\Rightarrow}
\coqdocconstructor{Var}
\coqdocvariable{x}
$\quad$ \coqdockw{end}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\pi_1$}
: \coqdocdefinition{$\psi$} $\rightarrow_\mathcal{R}$
(\coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} 1) :=
\coqdocconstructor{Step}
\coqdocdefinition{$\rho_1$}
$\Box$
\coqdocdefinition{$\sigma_1$}
\coqdoclemma{\_}
\coqdoclemma{\_}
\coqdoclemma{\_}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\phi_1$}
: \coqdocdefinition{$\psi$} $\twoheadrightarrow_\mathcal{R}$
(\coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} 1) :=
\coqdocconstructor{Cons}
\coqdocdefinition{$\phi_0$}
\coqdocdefinition{$\pi_1$}.\coqdoceol
\end{coqdoccode}

\pause

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\sigma_2$}
(\coqdocvar{x} : \coqdocdefinition{X}) :
\coqdocinductive{term} :=
\coqdockw{match} \coqdocvariable{x} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} 1 \ensuremath{\Rightarrow}
\coqdocconstructor{S} @
\coqdocconstructor{S} @
\coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} 2\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|} \coqdocvar{\_} \ensuremath{\Rightarrow}
\coqdocconstructor{Var}
\coqdocvariable{x}\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\pi_2$}
: \coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} 1) $\rightarrow_\mathcal{R}$
(\coqdocconstructor{S} @
\coqdocconstructor{P} @
\coqdocconstructor{P} @
\coqdocconstructor{S} @
\coqdocconstructor{S} @
\coqdocconstructor{S}\coqdoceol
\coqdocindent{1.00em} @
\coqdocdefinition{$\psi'$} 2) :=
\coqdocconstructor{Step}
\coqdocdefinition{$\rho_1$}
(\coqdocconstructor{S} @
\coqdocconstructor{P} @
\coqdocconstructor{P} @
$\Box$)
\coqdocdefinition{$\sigma_2$}
\coqdoclemma{\_}
\coqdoclemma{\_}
\coqdoclemma{\_}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\phi_2$}
: \coqdocdefinition{$\psi$} $\twoheadrightarrow_\mathcal{R}$
(\coqdocconstructor{S} @
\coqdocconstructor{P} @
\coqdocconstructor{P} @
\coqdocconstructor{S} @
\coqdocconstructor{S} @
\coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} 2) :=\coqdoceol
\coqdocindent{1.00em}
\coqdocconstructor{Cons}
\coqdocdefinition{$\phi_1$}
\coqdocdefinition{$\pi_2$}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{Constructing $\psi \twoheadrightarrow S^n (\psi' n)$}

\begin{coqdoccode}
%\coqdocnoindent
%\coqdockw{Definition}
%\coqdocdefinition{$\sigma$}
%\coqdocvar{n} \coqdocvar{t} (\coqdocvar{x} :
%\coqdocdefinition{X}) :
%\coqdocinductive{term} :=\coqdoceol
%\coqdocindent{1.00em}
%\coqdockw{match} \coqdocvariable{x} \coqdockw{with}\coqdoceol
%\coqdocindent{1.00em}
%\ensuremath{|} 1 \ensuremath{\Rightarrow}
%\coqdocdefinition{Snt} \coqdocvariable{n}
%\coqdocvariable{t}\coqdoceol
%\coqdocindent{1.00em}
%\ensuremath{|} \coqdocvar{\_} \ensuremath{\Rightarrow}
%\coqdocconstructor{Var}
%\coqdocvariable{x}\coqdoceol
%\coqdocindent{1.00em}
%\coqdockw{end}.\coqdoceol
%\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\pi$}
\coqdocvar{m} \coqdocvar{n} \coqdocvar{t} :\coqdoceol
\coqdocindent{1.00em}\coqdocdefinition{Snt} \coqdocvariable{m}
(\coqdocdefinition{PnSnt}
(\coqdocconstructor{S}
\coqdocvariable{n}) \coqdocvariable{t}) $\rightarrow_\mathcal{R}$
\coqdocdefinition{Snt} \coqdocvariable{m}
(\coqdocdefinition{PnSnt}
\coqdocvariable{n} \coqdocvariable{t}) :=\coqdoceol
\coqdocindent{2.00em}
\coqdocinductive{Step}
\coqdocdefinition{$\rho_1$}
(\coqdocdefinition{Snc} \coqdocvariable{m}
(\coqdocdefinition{Pnc} \coqdocvariable{n}
$\Box$))
(\coqdocdefinition{$\sigma$}
\coqdocvariable{n} \coqdocvariable{t})
\coqdoclemma{\_}
\coqdoclemma{\_}
\coqdoclemma{\_}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Fixpoint}
\coqdocdefinition{$\phi_a$}
\coqdocvar{m} \coqdocvar{n} \coqdocvar{t} :
\coqdocdefinition{Snt} \coqdocvariable{m}
(\coqdocdefinition{PnSnt}
\coqdocvariable{n} \coqdocvariable{t}) $\twoheadrightarrow_\mathcal{R}$
\coqdocdefinition{Snt} \coqdocvariable{m}
\coqdocvariable{t} :=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{n} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{O}
\ensuremath{\Rightarrow}
\coqdocconstructor{Nil}
(\coqdocdefinition{Snt} \coqdocvariable{m}
\coqdocvariable{t})\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{S}
\coqdocvar{n} \ensuremath{\Rightarrow}
\coqdocdefinition{snoc}
(\coqdocdefinition{$\pi$}
\coqdocvariable{m} \coqdocvariable{n} \coqdocvariable{t})
(\coqdocdefinition{$\phi_a$}
\coqdocvariable{m} \coqdocvariable{n} \coqdocvariable{t})\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\phi_b$} % TODO: here the S(2 n) is not correct
\coqdocvar{n} : \coqdocdefinition{Snt}
\coqdocvariable{n} (\coqdocdefinition{$\psi'$}
\coqdocvariable{n}) $\twoheadrightarrow_\mathcal{R}$
\coqdocdefinition{Snt}
(\coqdocconstructor{S}
\coqdocvariable{n})
(\coqdocdefinition{$\psi'$}
(\coqdocconstructor{S}
\coqdocvariable{n})) :=\coqdoceol
\coqdocindent{1.00em}
\coqdocdefinition{$\phi_a$} \coqdocvariable{n} (\coqdocconstructor{S} (2
$\times$ \coqdocvariable{n})) (\coqdocconstructor{S} @
\coqdocdefinition{$\psi'$} (\coqdocconstructor{S}
\coqdocvariable{n})).\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Fixpoint}
\coqdocdefinition{$\phi_c$}
\coqdocvar{n} : \coqdocdefinition{$\psi$} $\twoheadrightarrow_\mathcal{R}$
\coqdocdefinition{Snt} \coqdocvariable{n}
(\coqdocdefinition{$\psi'$}
\coqdocvariable{n}) :=\coqdoceol
\coqdocindent{1.00em}
\coqdockw{match} \coqdocvariable{n} \coqdockw{with}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{O}
\ensuremath{\Rightarrow}
\coqdocconstructor{Nil}
\coqdocdefinition{$\psi$}\coqdoceol
\coqdocindent{1.00em}
\ensuremath{|}
\coqdocconstructor{S}
\coqdocvar{n} \ensuremath{\Rightarrow}
\coqdocdefinition{append}
(\coqdocdefinition{$\phi_c$}
\coqdocvariable{n})
(\coqdocdefinition{$\phi_b$}
\coqdocvariable{n})\coqdoceol
\coqdocindent{1.00em}
\coqdockw{end}.\coqdoceol
\end{coqdoccode}

}

\frame{

  \frametitle{$\omega$-step rewrite sequence from $\psi$ to $S^\omega$}

\begin{coqdoccode}
\coqdocnoindent
\coqdockw{Lemma}
\coqdoclemma{conv}
: \coqdocdefinition{converges}
(\coqdockw{fun} \coqdocvar{n} \ensuremath{\Rightarrow}
\coqdocdefinition{Snt} \coqdocvariable{n}
(\coqdocdefinition{$\psi'$}
\coqdocvariable{n}))
\coqdocdefinition{S$^\omega$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Definition}
\coqdocdefinition{$\phi$}
: \coqdocdefinition{$\psi$} $\twoheadrightarrow_\mathcal{R}$
\coqdocdefinition{S$^\omega$} :=
\coqdocconstructor{Lim}
\coqdocdefinition{$\phi_c$}
\coqdoclemma{conv}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Lemma}
\coqdoclemma{wf$_\phi$}
: \coqdocdefinition{wf}
\coqdocdefinition{$\phi$}.\coqdoceol
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\end{coqdoccode}

We can now prove our lemma.

\begin{coqdoccode}
\coqdocemptyline
\coqdocemptyline
\coqdocemptyline
\coqdocnoindent
\coqdockw{Lemma}
\coqdoclemma{no\_un$_\mathcal{R}$}
: \ensuremath{\lnot}
\coqdocdefinition{unique\_normal\_forms}
\coqdocdefinition{$\mathcal{R}$}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Lemma} \coqdoclemma{no\_un\_wo}
: \ensuremath{\lnot} \ensuremath{\forall} \coqdocvar{F} \coqdocvar{X}
\coqdocvar{$\mathcal{R}$},\coqdoceol
\coqdocindent{1.00em}
\coqdocdefinition{weakly\_orthogonal}
(\coqdocvar{F} := \coqdocvariable{F}) (\coqdocvar{X} :=
\coqdocvariable{X}) \coqdocvariable{$\mathcal{R}$}
\ensuremath{\rightarrow}\coqdoceol
\coqdocindent{1.00em}
\coqdocdefinition{unique\_normal\_forms}
\coqdocvariable{$\mathcal{R}$}.\coqdoceol
\end{coqdoccode}

}

\section{Conclusion}

\frame{

  \frametitle{Infinitary rewriting in \Coq}

  \tableofcontents[currentsection]

}

\frame{

  \frametitle{Our \Coq-development}

  Joint work with Dimitri Hendriks\\[1em]

  Some 7500 physical lines of code
  \begin{itemize}
    \item 1250 for terms
    \item 900 for ordinals
    \item 1500 for rewriting
    \item 3000 for UN$^\infty$ and weak orthogonality\\[1em]
  \end{itemize}

  Acknowledgements
  \begin{itemize}
    \item J\"org Endrullis
    \item Vincent van Oostrom for ideas on embedding relation
    \item Peter Hancock for the order on ordinals
    \item Adam Chlipala for recursive vector type and more
    \item Matthieu Sozeau for help on dependent destruction tactic
  \end{itemize}

}

\frame{

  \frametitle{Conclusions}

  State of \Coq
  \begin{itemize}
    \item Formalizing takes too much time and working with it is tedious
    \item Guardedness restriction is too restrictive
    \item Writing \Coq code can be fun and frustrating\\[1em]
  \end{itemize}

  \pause

  Our formalization
  \begin{itemize}
    \item Representation of rewrite sequences not close to paper
    \item Convergence notions are not translated easily
    \item Compression Lemma was too high a goal
  \end{itemize}

}

\frame{

  \frametitle{The End}

  Questions?\\[3em]

  \begin{block}{Selected references}
    \begin{itemize}
    \item Peter Hancock, (Ordinal-theoretic) Proof Theory
    \item J\"org Endrullis et al, Unique Normal Forms in Infinitary
      Weakly Orthogonal Term Rewriting
    \item Terese, Term Rewriting Systems
    \item Jan Willem Klop and Roel de Vrijer, Infinitary Normalization
    \item Adam Chlipala, Certified Programming with Dependent Types
    \end{itemize}
  \end{block}

}

\end{document}


%!TEX root = main.tex

% =============================================================================
\section{Background on LSM Trees}
\label{sec:background}
% =============================================================================

\Paragraph{Basics}
LSM trees use the \textit{out-of-place} ingestion paradigm to store key-value
pairs. Writes, updates, or deletes are buffered in a memory buffer, and once
full, its contents are sorted based on the key, forming an
\textit{immutable sorted run}. This run is then flushed to the first level on
secondary storage. Each level of sorted runs has a maximum permitted size, which
is tunable. Overall, for an LSM tree with $L$ disk-resident levels, we denote the
memory buffer as Level $0$, and the remaining
levels in storage, level $1$ to $L$. The disk-resident sorted runs have exponentially increasing
sizes following a tunable size ratio $\sizeratio$.
Figure \ref{fig:lsm-overview} shows an overview of an LSM tree.

\begin{figure}[h]
    \centering
    \includegraphics[scale=0.75]{figures/lsm_overview.pdf}
    \caption{Overview of the structure of an LSM tree}
    \label{fig:lsm-overview}
\end{figure}

We denote the number of bits of main memory allocated to the buffer as $\mbuf$,
which holds a number of entries with fixed entry size $E$. For example, in
RocksDB the default buffer size is $\mbuf=64$MB, and depending on the
application, the entry size typically varies between 64B and 1KB.

Level 0 can be updated in-place since it is in memory, however, the runs in
levels 1 and beyond are immutable. Each Level $i$ has a capacity threshold of
$(\sizeratio - 1) T^{i-1} \cdot \frac{\mbuf}{E}$ entries , thus, levels have
exponentially increasing capacities by a factor of $\sizeratio$.  The total
number of levels $L$ for a given {\sizeratio} is

\begin{equation}
L(T) = \Bigg\lceil \log_T \left( {\frac{N \cdot E}{\mbuf}} + 1 \right) \Bigg\rceil ,
\label{eq:levels}
\end{equation}

where $N$ is the total number of physical entries across all levels including
updates and deletions \cite{Dayan2018a, Luo2020, Sarkar2020}.

\Paragraph{Compaction Policies: Leveling and Tiering}
Classically, LSM trees support two merging policies: leveling and tiering.
In leveling, each level may have at most one run, and every time a run in Level
    $i - 1$ ($i \geq 1$) is moved to Level $i$, it is greedily sort-merged
    (compaction) with the run from Level $i$, if it exists.
With tiering, every level must accumulate $\sizeratio$ runs before they trigger
    a compaction.
During a compaction, entries with a matching key are consolidated and only the
    most recent valid entry is retained~\cite{Dong2017, ONeil1996}.
Recently hybrid compaction policies fuse leveling and tiering in a single tree
    to strike a balance between the read and write throughput~\cite{Dayan2018,
    Dayan2019}.

\Paragraph{LSM tree Operations}
An LSM tree supports: (a) writes of new key-value pairs, (b) point queries, or
(c) range queries.

\emph{Writes:} A write operation is handled by a buffer append, and if the
buffer gets full, it triggers a compaction as discussed above. Any write may
include either a new key-value pair, a key-value pair that invalidates an
existing one (an \emph{update}), or a special key-value pair that deletes an
existing one (a \emph{delete}).

\emph{Point Queries:}
A point query searches for the value of a specific unique key. It begins by
looking at the memory buffer, then traverses the tree from the smallest level to
the largest one. For tiering, within a level, a lookup moves from the most to
the least recent tier. The lookup terminates when it finds the first matching
entry. Note that a point query might return an \emph{empty} result or a
\emph{non-empty} result. We differentiate the two because, in general, workloads
with empty point queries can be further optimized \cite{Dayan2017,Dayan2018a}.

\emph{Range Queries:}
A range lookup returns the most recent versions of the target keys
by sort-merging the qualifying key ranges across all runs in the tree.

\Paragraph{Optimizing Lookups}
Read performance is optimized using Bloom filters and fence pointers.
In the worst case, a lookup
needs to probe every run. To reduce this cost,
LSM engines use one Bloom filter per run in main memory~\cite{Dayan2017, FacebookRocksDB}.
Bloom filters \cite{Bloom1970} are probabilistic membership test data structures
    that exhibit a false positive $f$ as a function of the ratio between the
    memory allocated $\mfilt$ to them and the elements it indexes.
In LSM trees, Bloom filters allow a lookup to skip probing a run altogether if
    the filter-lookup returns negative.
In practice, for efficient storage, Bloom filters are maintained at the
    granularity of files~\cite{Dong2017}.
Fence pointers store the smallest key per disk page in memory~\cite{Dayan2017},
    to quickly identify which page(s) to read for a lookup, and perform up to
    one I/O per run for point lookups.

\Paragraph{Tuning LSM Trees}
Prior to this work, efforts to systematically tune LSM trees assume that the
    workload information and the environmental setup is accurately known.
Under that assumption, the main focus on LSM tuning has been on deciding how to
allocate the available main memory between Bloom filters and buffering
\cite{Dayan2017,Kim2020,Luo2020a}, while often the size ratio and the merging
strategy was also co-tuned \cite{Dayan2018a}.  In addition, recent work has
introduced new hybrid merging strategies \cite{Dayan2018,Dayan2019,Sarkar2021c},
and optimizations for faster data ingestion \cite{Luo2019b} and performance
stability
\cite{Luo2019a}.


% Template file for TeXShop by Michael Sharpe, LPPL
\documentclass[11pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage[parfill]{parskip}% Begin paragraphs with an empty line rather than an indent
\usepackage{graphicx}
\usepackage{amsmath,amsthm}
\usepackage{natbib}

\title{MIT 6.862 Applied Machine Learning Project Proposal}
\author{Matthew West, Fall 2019}
\begin{document}
\date{}
\maketitle

\subsection*{Question}
This is a supervised learning project where the questions of interest relate to medical diagnostics, investigating how supervised learning can be used in classification and particularly in determining the presence of breast cancer from a dataset derived from mammogram images. The first part of the project will involve looking at both traditional machine learning (Naive Bayes, SVM, etc) and more contemporary deep neural networks for classification, and to determine which approach performs best using a naive metric such as accuracy, thus providing some basic insight into which approach might be favourable for the nature and size of dataset available. Given the relatively small size of the dataset, it is anticipated that deep networks won't confer a significant benefit in classification, though it is possible that more data will become available, ideally including the original images from which the chosen dataset is derived.

Following this, it will be of interest to extend the use of accuracy, bringing in alternative metrics related to precision and recall, and performing a comparison between the different algorithms as before, but with a set of new potential metrics. This will also involve an exploration of which types of metric are preferable for medical diagnostics, where we often care much more about minimizing false, giving comparatively little weight to false positives.

\subsection*{Data}
The dataset for the first part of this project at least will be the Wisconsin Breast Cancer Dataset \cite{Dua:2019}. This was collected by a group at the University of Wisconsin in the early 1990's, and is a structured dataset with 10 features computed from a set of digitized images of breast tissue. There are 569 instances, with 357 labelled as malignant (M), and 212 as benign (B). This dataset thus presents a binary classification problem, making it amenable to many metrics of success that incorporate precision and recall.

Beyond this, there are a number of other candidate datasets that could be incorporated into the project, but each presents a challenge in comparing to the Wisconsin dataset. Most of them are raw images only and typically labelled in terms of regions of interest, thus presenting both an image segmentation and classification problem simultaneously. While it would be fruitful to compare Convolutional Neural Networks to traditional machine learning classifiers on data of this variety, there is another layer of complexity inherent in extracting appropriate features to optimize classifier performance, such that they would provide a fair comparison to CNN's.

Among these potential datasets are DDSM, the Digital Database for Screening Mammography, and its curated sub-dataset with expert mammographer ground truth validation, Curated Breast Imaging Subset (CBIS-DDSM). \cite{lee2017curated} These present an image segmentation problem, so there would be a considerable amount of additional work in processing the data before it can be used purely for investigation of classification. Another promising candidate dataset is the CAMELYON dataset, which was made public for a grand challenge in pathology posed by the Department of Pathology at Radboud University Medical Center. \cite{litjens20181399}

\subsection*{Motivation and Previous Work}
Machine and deep learning methods have already received significant attention within medical imaging diagnostics, a well publicised example of which was DeepMind's use of deep learning in diagnosing retinal disease. \cite{de2018clinically} More specifically, similar methods have been used in breast and prostate cancer imaging diagnostics. \cite{wang2016deep, goldenberg2019new}

The motivation for this kind of work is clear, as medical diagnostics is becoming increasingly automated and incorporating the use of statistical and machine learning methods. There are a number of practical and ethical issues in using machine learning in a clinical setting, even when being utilized in tandem with a trained clinician, so it is important to give proper treatment to classification problems specific to the medical domain. Another desirable feature of models used in this way is interpretability, which some sophisticated models struggle with, so it may be the case that for a diagnostic tool it becomes worth trading performance in some metric for an increased degree of interpretability.

\subsubsection*{Computational Resources}
I will be running and evaluating the models for this project primarily on my local machine, and perhaps using external cloud GPU services (AWS, etc) if the models become sufficiently complex. My computer has an Intel i7 with 32GB of RAM and an Nvidia GTX 1650 GPU, with 4GB of GDDR5 memory, and I anticipate that this will be sufficient for training most of the models within a reasonable time frame, given the size of the dataset. I will use the programming language Python 3 and a selection of machine learning libraries and frameworks such as scikit-learn and TensorFlow.

\subsection*{Project Plan}
\begin{itemize}
\item \textbf{Exploratory Data Analysis:}
Get to know the dataset and demonstrate that classification is even a reasonable thing to attempt given the problem statement. Set up data pipeline to make classification possible. Identify useful features and reduce to the most useful ones if necessary. (By 10/14)
\item \textbf{Comparison of traditional ML on selected feature set:}
Compare different algorithms using cross-validation to determine accuracy on validation data. (By 10/24)
\item \textbf{Beyond Accuracy: Precision and Recall}
Explore alternative metrics of success and determine which metric captures the desired behaviour of a tool used in medical diagnostics. Re-evaluate previous algorithms using selected metrics. (By 11/10)
\item \textbf{Beyond Wisconsin (time allowing): } Incorporating alternative datasets with raw images allowing for comparison between CNN's and traditional ML on structured data. (By 11/30)
\end{itemize}

\nocite{*}
\bibliographystyle{plain}
\bibliography{MIT}

\end{document}


\chapter{Implementation IV:  \alphakanren}\label{akimplchapter}

\enlargethispage{1em}

In this chapter we present two implementations of \alphakanrensp based
on two implementations of nominal unification: one using idempotent
substitutions, and one using triangular substitutions.  The idempotent
implementation mirrors the mathematical description of nominal
unification given by \citet{Urban-Pitts-Gabbay/04}, while the
triangular implementation is more efficient.

This chapter is organized as follows. In section~\ref{nominalunif} we
present our implementation of nominal unification using idempotent
substitutions. In section~\ref{akgoalconstructorimplsection} we
implement \alphakanren's goal constructors, using the unifier of
section~\ref{nominalunif}, and in section~\ref{akreifysection} we
implement reification.  In section~\ref{triangularsection} we present
a second implementation of nominal unification, using triangular
substitutions.

% In section~\ref{akperfsection} we compare the performance of the two
% \alphakanrensp implementations, using the relational theorem prover of
% \ref{alphatapchapter}.

\section{Nominal Unification with Idempotent Substitutions}\label{nominalunif}

Nominal unification occurs in two distinct phases: the first processes
equations, while the second processes constraints.  The first phase
takes a set of equations \scheme{eqns} and transforms it into a
substitution \scheme{sigma} and a set of unresolved constraints
\scheme{delta}.  The second phase combines the unresolved constraints
with the previously resolved constraints, which have both been brought
up to date using \scheme{apply-subst}.  Then, the unifier transforms
these combined constraints into a set of resolved constraints
$\nabla$, and returns the list \mbox{\scheme|`(,sigma ,nabla)|} as a
package.

Nominal unification uses several data structures.  A set of
equations \scheme{eqns} is represented as a list of pairs of terms.
A substitution \scheme{sigma} is represented as an association list of variables to terms.
A set of constraints \scheme{delta} is represented as a list of pairs associating
noms to terms; a \scheme{nabla} is a \scheme{delta} in which all terms are unbound variables.
In a substitution, a variable may have at most one association.
In a \scheme{delta} (and therefore in a \scheme{nabla}) a nom may have multiple associations.

We represent a variable as a suspension containing an empty
list of swaps.  Several functions reconstruct suspensions that represent
variables.  However, our implementation of nominal unification assumes
that variables can be compared using \scheme{eq?}.

In order to ensure that a variable is always \scheme{eq?} to itself,
regardless of how many times it is reconstructed, we use a
\scheme{letrec} trick: a suspension representing a variable
contains a procedure of zero arguments (a \emph{thunk})
that, when invoked, returns the suspension,
thus maintaining the desired \scheme{eq?}-ness property.
(In the text we conflate variables with their associated thunks.)

\schemedisplayspace
\begin{schemedisplay}
(define ak-var
  (lambda (ignore)
    (letrec ((s (list 'susp-tag '() (lambda () s))))
      s)))
\end{schemedisplay}

\scheme{unify} attempts to solve a set of equations \scheme{eqns}
in the context of a package \mbox{\scheme|`(,sigma ,nabla)|}.
\scheme{unify} applies \scheme{sigma} to \scheme{eqns},
and then calls \scheme{apply-sigma-rules} on the resulting
set of equations.
\scheme{apply-sigma-rules} either successfully completes the first
phase of nominal unification by returning a new \scheme{sigma} and
\scheme{delta}, or invokes the failure continuation \scheme{fk},
a jump-out continuation similar to Lisp's
\scheme{catch} \cite{Steele:1990:CLL}.

\schemedisplayspace
\begin{schemedisplay}
(define unify
  (lambda (eqns sigma nabla fk)
    (let ((eqns (apply-subst sigma eqns)))
      (mv-let ((sigma^ delta) (apply-sigma-rules eqns fk))
        (unifyhash delta (compose-subst sigma sigma^) nabla fk)))))
\end{schemedisplay}
\noindent \scheme{mv-let}, defined in Appendix~\ref{pmatch}, deconstructs a list of values.

In the second phase of nominal unification, \scheme{unifyhash} calls \scheme{apply-subst}
to bring \scheme{nabla} and \scheme{delta} up to date, then
passes their union to \scheme{apply-nabla-rules}.

\schemedisplayspace
\begin{schemedisplay}
(define unifyhash
  (lambda (delta sigma nabla fk)
    (let ((delta (apply-subst sigma delta))
          (nabla (apply-subst sigma nabla)))
      (let ((delta (delta-union nabla delta)))
        (list sigma (apply-nabla-rules delta fk))))))
\end{schemedisplay}

\scheme{apply-sigma-rules} is a recursive function whose only task is
to combine results returned by \scheme{sigma-rules}.
\scheme{sigma-rules} takes two arguments: a single equation and the
rest of the equations.  If \scheme{sigma-rules} fails, then
\scheme{apply-sigma-rules} invokes \scheme{fk}, and the result of
\scheme{unify} is \scheme{#f}.  Each successful call to
\scheme{sigma-rules} returns a new set of equations \scheme{eqns}, a
new \scheme{sigma}, and a set of (unresolved) constraints
\scheme{delta}.  Successive calls to \scheme{sigma-rules} resolve the
equations in \scheme{eqns} until there are no equations left.

\newpage

\schemedisplayspace
\begin{schemedisplay}
(define apply-sigma-rules
  (lambda (eqns fk)
    (cond
      ((null? eqns) `(,empty-sigma ,empty-delta))
      (else
       (let ((eqn (car eqns)) (eqns (cdr eqns)))
         (mv-let ((eqns sigma delta) (or (sigma-rules eqn eqns) (fk)))
           (mv-let ((sigma^ delta^) (apply-sigma-rules eqns fk))
             (list (compose-subst sigma sigma^) (delta-union delta^ delta)))))))))
\end{schemedisplay}

\scheme{apply-nabla-rules} is similar to \scheme{apply-sigma-rules},
but takes constraints instead of equations, and combines the results
returned by \scheme{nabla-rules}.

\schemedisplayspace
\begin{schemedisplay}
(define apply-nabla-rules
  (lambda (delta fk)
    (cond
      ((null? delta) empty-nabla)
      (else
       (let ((c (car delta)) (delta (cdr delta)))
         (mv-let ((delta nabla) (or (nabla-rules c delta) (fk)))
           (delta-union nabla (apply-nabla-rules delta fk))))))))
\end{schemedisplay}

\noindent \scheme{empty-sigma}, \scheme{empty-delta}, and
\scheme{empty-nabla} are defined in section~\ref{akgoalconstructorimplsection}.

In both \scheme{sigma-rules} and \scheme{nabla-rules}
we use \scheme{untagged?}
to distinguish untagged pairs from specially tagged pairs that
represent binders, noms, and suspensions.

\schemedisplayspace
\begin{schemedisplay}
(define untagged?
  (lambda (x)
    (not (memv x '(tie-tag nom-tag susp-tag)))))
\end{schemedisplay}

Here are the transformation rules of the nominal unification
algorithm, derived from the rules in \citet{Urban-Pitts-Gabbay/04}.
(\scheme{sigma-rules} relies on \scheme{pmatch}, which is defined in
Appendix~\ref{pmatch}.)

\newpage

\schemedisplayspace
\begin{schemedisplay}
(define sigma-rules
  (lambda (eqn eqns)
    (pmatch eqn
      (`(,c . ,c^)
       (guard (not (pair? c)) (equal? c c^))
       `(,eqns ,empty-sigma ,empty-delta))
      (`((tie-tag ,a ,t) . (tie-tag ,a^ ,t^))
       (guard (eq? a a^))
       `(((,t . ,t^) . ,eqns) ,empty-sigma ,empty-delta))
      (`((tie-tag ,a ,t) . (tie-tag ,a^ ,t^))
       (guard (not (eq? a a^)))
       (let ((u^ (apply-pi `((,a ,a^)) t^)))
         `(((,t . ,u^) . ,eqns) ,empty-sigma ((,a . ,t^)))))
      (`((nom-tag __) . (nom-tag __))
       (guard (eq? (car eqn) (cdr eqn)))
       `(,eqns ,empty-sigma ,empty-delta))
      (`((susp-tag ,pi ,x) . (susp-tag ,pi^ ,x^))
       (guard (eq? (x) (x^)))
       (let ((delta (map (lambda (a) (cons a (x)))
                         (disagreement-set pi pi^))))
         `(,eqns ,empty-sigma ,delta)))
      (`((susp-tag ,pi ,x) . ,t)
       (guard (not (occurs-check (x) t)))
       (let ((x (x)) (t (apply-pi (reverse pi) t)))
         (let ((sigma `((,x . ,t))))
           (list (apply-subst sigma eqns) sigma empty-delta))))
      (`(,t . (susp-tag ,pi ,x))
       (guard (not (occurs-check (x) t)))
       (let ((x (x)) (t (apply-pi (reverse pi) t)))
         (let ((sigma `((,x . ,t))))
           (list (apply-subst sigma eqns) sigma empty-delta))))
      (`((,t1 . ,t2) . (,t1^ . ,t2^))
       (guard (untagged? t1) (untagged? t1^))
       `(((,t1 . ,t1^) (,t2 . ,t2^) . ,eqns) ,empty-sigma ,empty-delta))
      (else #f))))
\end{schemedisplay}

Clauses two and three in \scheme{sigma-rules}
implement $\alpha$-equivalence of binders, as defined
in section~\ref{akintro} of Chapter~\ref{akchapter}.
Clause five unifies two suspensions that have the same variable;
in this case, \scheme{sigma-rules} creates as many new freshness constraints
as there are noms in the \emph{disagreement set} (defined below) of the
suspensions' swaps.
Clauses six and seven are similar: each clause unifies a
suspension containing a variable \scheme{x} and a list of swaps \scheme{pi}
with a term \scheme{t}.
\scheme{sigma-rules} creates a substitution associating
\scheme{x} with the result of applying the swaps in \scheme{pi} to \scheme{t} in
\emph{reverse order}, with the newest swap in \scheme{pi} applied first.
This substitution is applied to the context \scheme{eqns}.

\newpage

\scheme{apply-pi}, below, applies a list of swaps \scheme{pi} to a term \scheme{v}.

\schemedisplayspace
\begin{schemedisplay}
(define apply-pi
  (lambda (pi v)
    (pmatch v
      (`,c (guard (not (pair? c))) c)
      (`(tie-tag ,a ,t)
       (let ((a (apply-pi pi a))
             (t (apply-pi pi t)))
         `(tie-tag ,a ,t)))
      (`(nom-tag __)
       (let loop ((v v) (pi pi))
         (if (null? pi)
             v
             (apply-swap (car pi) (loop v (cdr pi))))))
      (`(susp-tag ,pi^ ,x)
       (let ((pi (append pi pi^)))
         (if (null? pi)
             (x)
             `(susp-tag ,pi ,x))))
      (`(,a . ,d) (cons (apply-pi pi a) (apply-pi pi d))))))
\end{schemedisplay}

\noindent If \scheme{v} is a nom, then  \scheme{pi}'s swaps are applied,
with the oldest swap applied first.  If \scheme{v} is a suspension
with a list of swaps \scheme{pi^} and variable \scheme{x}, then
the swaps in \scheme{pi} are added to the swaps in \scheme{pi^}.
If this list is empty, then \scheme{x}'s suspension is
returned; otherwise, a new suspension is created with those swaps.

\schemedisplayspace
\begin{schemedisplay}
(define apply-swap
  (lambda (swap a)
    (pmatch swap
      (`(,a1 ,a2)
       (cond
         ((eq? a a2) a1)
         ((eq? a a1) a2)
         (else a))))))
\end{schemedisplay}

The \scheme{nabla-rules} are much simpler than the \scheme{sigma-rules}.
In the second clause, the nom \scheme{a^} in the binding position of the binder
is the same as \scheme{a}, so \scheme{a} can never appear free in \scheme{t}.
In the fifth clause, the list of swaps \scheme{pi} in the suspension are
applied, in reverse order, to the nom \scheme{a}, yielding another nom.
\scheme{nabla-rules} then adds a new constraint associating this nom with
the suspension's variable.

\newpage

\schemedisplayspace
\begin{schemedisplay}
(define nabla-rules
  (lambda (d delta)
    (pmatch d
      (`(,a . ,c)
       (guard (not (pair? c)))
       `(,delta ,empty-nabla))
      (`(,a . (tie-tag ,a^ ,t))
       (guard (eq? a^ a))
       `(,delta ,empty-nabla))
      (`(,a . (tie-tag ,a^ ,t))
       (guard (not (eq? a^ a)))
       `(((,a . ,t) . ,delta) ,empty-nabla))
      (`(,a . (nom-tag __))
       (guard (not (eq? a (cdr d))))
       `(,delta ,empty-nabla))
      (`(,a . (susp-tag ,pi ,x))
       (let ((a (apply-pi (reverse pi) a)) (x (x)))
         `(,delta ((,a . ,x)))))
      (`(,a . (,t1 . ,t2))
       (guard (untagged? t1))
       `(((,a . ,t1) (,a . ,t2) . ,delta) ,empty-nabla))
      (else #f))))
\end{schemedisplay}

Finding the disagreement set of two lists of swaps
\scheme{pi} and \scheme{pi^} requires
forming a set of all the noms in those lists, then applying both \scheme{pi}
and \scheme{pi^} to each nom \scheme{a} in this set.
If \mbox{\scheme|(apply-pi pi a)|} and \mbox{\scheme|(apply-pi pi^ a)|}
produce different noms, then \scheme{a} is in the \emph{dis}agreement set.
(\scheme{filter} and \scheme{remove-duplicates} are defined
in Appendix~\ref{helpers}.)

\schemedisplayspace
\begin{schemedisplay}
(define disagreement-set
  (lambda (pi pi^)
    (filter
      (lambda (a) (not (eq? (apply-pi pi a) (apply-pi pi^ a))))
      (remove-duplicates
        (append (apply append pi) (apply append pi^))))))
\end{schemedisplay}

The \scheme{occurs-check} is what one might expect.

\schemedisplayspace
\begin{schemedisplay}
(define occurs-check
  (lambda (x v)
    (pmatch v
      (`,c (guard (not (pair? c))) #f)
      (`(tie-tag __ ,t) (occurs-check x t))
      (`(nom-tag __) #f)
      (`(susp-tag __ x^) (eq? (x^) x))
      (`(,x^ . ,y^) (or (occurs-check x x^) (occurs-check x y^)))
      (else #f))))
\end{schemedisplay}

\subsection{Idempotent Substitutions}\label{applysubst}

\scheme{compose-subst}'s definition is taken from \citet{lloyd:lp}.  It
takes two substitutions \scheme{sigma} and \scheme{tau}, and constructs a new
substitution \scheme{sigma^} in which each association \mbox{\scheme|`(,x . ,v)|}
in \scheme{sigma} is replaced by \mbox{\scheme|`(,x . v^)|}, where \scheme{v^} is the result
of applying \scheme{tau} to \scheme{v}.
Any association in \scheme{tau} whose
variable has an association in \scheme{sigma^} is then filtered from \scheme{tau}.
Also, any association of the form \mbox{\scheme|`(,x . ,x)|} is filtered from \scheme{sigma^}.
These filtered substitutions are then appended.

\schemedisplayspace
\begin{schemedisplay}
(define compose-subst
  (lambda (sigma tau)
    (let ((sigma^ (map
                    (lambda (a) (cons (car a) (apply-subst tau (cdr a))))
                    sigma)))
      (append
        (filter (lambda (a) (not (assq (car a) sigma^))) tau)
        (filter (lambda (a) (not (eq? (car a) (cdr a)))) sigma^)))))
\end{schemedisplay}

Next we define \scheme{apply-subst}.  In the suspension case,
\scheme{apply-subst} applies the list of swaps \scheme{pi} to a variable,
or to its binding.

\schemedisplayspace
\begin{schemedisplay}
(define apply-subst
  (lambda (sigma v)
    (pmatch v
      (`,c (guard (not (pair? c))) c)
      (`(tie-tag ,a ,t)
       (let ((t (apply-subst sigma t)))
         `(tie-tag ,a ,t)))
      (`(nom-tag __) v)
      (`(susp-tag ,pi ,x) (apply-pi pi (get (x) sigma)))
      (`(,x . ,y) (cons (apply-subst sigma x) (apply-subst sigma y))))))
\end{schemedisplay}

\noindent \scheme{get}, which is defined in Appendix~\ref{helpers},
finds the binding of a variable in a substitution or returns the
variable if no binding exists.

\subsection{{\it \deltaunionsymbol}}

Finally we define \scheme{delta-union}, which forms the union of
two \scheme{delta}'s.

\schemedisplayspace
\begin{schemedisplay}
(define delta-union
  (lambda (delta delta^)
    (pmatch delta
      (`() delta^)
      (`(,d . ,delta)
       (if (term-member? d delta^)
           (delta-union delta delta^)
           (cons d (delta-union delta delta^)))))))
\end{schemedisplay}
\newpage
\begin{schemedisplay}
(define term-member?
  (lambda (v v*)
    (pmatch v*
      (`() #f)
      (`(,v^ . ,v*)
       (or (term-equal? v^ v) (term-member? v v*))))))

(define term-equal?
  (lambda (u v)
    (pmatch `(,u ,v)
      (`(,c ,c^) (guard (not (pair? c)) (not (pair? c^)))
       (equal? c c^))
      (`((tie-tag ,a ,t) (tie-tag ,a^ ,t^))
       (and (eq? a a^) (term-equal? t t^)))
      (`((nom-tag __) (nom-tag __)) (eq? u v))
      (`((susp-tag ,pi ,x) (susp-tag ,pi^ ,x^))
       (and (eq? (x) (x^)) (null? (disagreement-set pi pi^))))
      (`((,x . ,y) (,x^ . ,y^))
       (and (term-equal? x x^) (term-equal? y y^)))
      (else #f))))
\end{schemedisplay}

Recall that \scheme{delta} denotes a set of unresolved
constraints, where a constraint is a pair of a nom \scheme{a} and a
term \scheme{t}.  \scheme{delta-union} uses \scheme{term-member?},
which uses \scheme{term-equal?} when comparing two constraints.  The
definition of \scheme{term-equal?} is straightforward except when
comparing two suspensions, in which case their variables must be the
same, and the disagreement set of their lists of swaps must be empty.

%\section{Goals and Packages}\label{akpackagerepsection}

% Our \alphakanren\ implementation comprises three kinds of operators: the interface
% operator \scheme{run}; goal constructors \scheme{==}, \scheme{hash},
% \scheme{conde}, \scheme{exist}, and \scheme{fresh}, which take a package
% \emph{implicitly}; and functions such as \scheme{reify},
% and the already defined \scheme{unify} and \scheme{unify#}, which take a
% package \emph{explicitly}.

% (As in Chapter~\ref{mkimplchapter}, we notate \scheme{lambda} as
% \scheme{lambdag@} when creating such a function~\scheme{g}.)

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax lambdag@
%   (syntax-rules () ((__ (p) e) (lambda (p) e))))
% \end{schemedisplay}

% Because a sequence of packages may be infinite, we represent it
% not as a list but as a \mbox{\scheme|p-inf|}, a special kind of
% stream that can contain either zero, one, or more packages
% \cite{hinze2000,Wadler85}.
% We use \mbox{\scheme|#f|} to represent the empty stream of
% packages. If \scheme{p} is a package, then \scheme{p} itself
% represents the stream containing
% just~\scheme{p}.  To represent a stream containing multiple
% packages, we use \mbox{\scheme|(choice p f)|}, where \scheme{p}
% is the first package in the stream, and where \scheme{f} is a
% thunk that, when invoked, produces the remainder of the stream.
% (For clarity, we notate \scheme{lambda}
% as \scheme{lambdaf@} when creating such a function~\scheme{f}.)
% To represent an incomplete stream, we use \mbox{\scheme|(inc e)|},
% where \scheme{e} is an \emph{expression} that evaluates to
% a \mbox{\scheme|p-inf|}---thus \scheme{inc} creates an \scheme{f}.

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax lambdaf@
%   (syntax-rules () ((__ () e) (lambda () e))))

% (define-syntax choice
%   (syntax-rules () ((__ a f) (cons a f))))

% (define-syntax inc
%   (syntax-rules () ((__ e) (lambdaf@ () e))))
% \end{schemedisplay}

% \noindent A singleton stream \scheme{p} is the same as
% \begin{schemebox}(choice p (lambdaf@ () #f))\end{schemebox}.  However,
% for the goals that return only a single package, using this special
% representation of a singleton stream
% avoids the cost of unnecessarily building and taking apart pairs,
% and creating and invoking thunks.

% To ensure that the values produced by these four kinds of
% \mbox{\scheme|p-inf|}'s can be distinguished, we assume that a package
% is never \schemeresult{#f}, a function, or a pair whose \scheme{cdr}
% is a function.  To discriminate among these four cases, we define
% \mbox{\scheme|case-inf|}.

% \newpage
% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax case-inf
%   (syntax-rules ()
%     ((_ a-inf (() e0) ((f^) e1) ((a^) e2) ((a f) e3))
%      (pmatch a-inf
%        (#f e0)
%        (`,f^ (guard (procedure? f^)) e1)
%        (`,a^ (guard (not
%                      (and (pair? a^)
%                           (procedure? (cdr a^)))))
%             e2)
%        (`(,a . ,f) e3)))))
% \end{schemedisplay}

% The interface operator \scheme{run}
% uses \scheme{take} (defined below) to convert an \scheme{f} to an
% \emph{even} stream \cite{Lazysml98}.
% The definition of \scheme{run} places an artificial goal at the tail
% of \mbox{\scheme|g0 g ...|}; this artificial goal reifies the variable
%  \scheme{x} using the final package \scheme{p}
% produced by running the goals \mbox{\scheme|g0 g ...|}
% in the empty package \mbox{\scheme|`(,empty-sigma ,empty-nabla)|}.

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax run
%   (syntax-rules ()
%     ((_ n (x) g0 g ...)
%      (take n (lambdaf@ ()
%                ((exist (x) g0 g ...
%                   (lambdag@ (p) (cons (reify x p) '())))
%                 `(,empty-sigma ,empty-nabla)))))))
% \end{schemedisplay}

% \noindent Wrapping the reified value
% in a list allows \scheme{#f} to appear as a value.

% If the first argument to \scheme{take} is \scheme{#f},
% then \scheme{take} returns the entire stream of reified values as a list,
% thereby providing the behavior of \scheme{run*}.
% The \scheme{and} expressions within \scheme{take}
% detect this \scheme{#f} case.

% \newpage
% \schemedisplayspace
% \begin{schemedisplay}
% (define take
%   (lambda (n f)
%     (if (and n (zero? n))
%       '()
%       (case-inf (f)
%         (() '())
%         ((f) (take n f))
%         ((a) a)
%         ((a f) (cons (car a)
%                  (take (and n (- n 1)) f)))))))
% \end{schemedisplay}

% \scheme{run*} is trivially defined in terms of \scheme{run}.

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax run*
%   (syntax-rules ()
%     ((_ (x) g0 g ...)
%      (run #f (x) g0 g ...))))
% \end{schemedisplay}

\section{Goal Constructors}\label{akgoalconstructorimplsection}

In the core miniKanren implementation of Chapter~\ref{mkimplchapter},
a goal is a function that maps a substitution \scheme{s} to an ordered
sequence of zero or more substitutions (see
section~\ref{goalconstructors}).  In \alphakanren, a goal \scheme{g}
is a function that maps a package \scheme{p} to an ordered
sequence \scheme|p-inf| of zero or more packages.

We represent the empty substitution,
along with the empty unresolved and resolved
constraint sets, as the empty list.

\wspace

\noindent \scheme|(define empty-sigma '()) $~~~~~$ (define empty-delta '()) $~~~~~$ (define empty-nabla '())|

\wspace

\scheme{==} and \scheme{hash} construct goals that return either a
singleton stream or an empty stream.

\schemedisplayspace
\begin{schemedisplay}
(define-syntax ==
  (syntax-rules ()
    ((_ u v)
     (unifier unify `((,u . ,v))))))
\end{schemedisplay}
\newpage
\begin{schemedisplay}
(define-syntax hash
  (syntax-rules ()
    ((_ a t)
     (unifier unifyhash `((,a . ,t))))))

(define unifier
  (lambda (fn set)
    (lambdag@ (p)
      (mv-let ((sigma nabla) p)
        (call/cc (lambda (fk) (fn set sigma nabla (lambda () (fk #f)))))))))
\end{schemedisplay}

% To take the conjunction of goals, we define \scheme{exist}, a goal
% constructor that first lexically binds variables built by
% \scheme{var}, and then combines successive goals using \scheme{bind*}.
The goal constructor \scheme{fresh} is identical to \scheme{exist},
except that it lexically binds noms instead of variables.

% (define-syntax exist
%   (syntax-rules ()
%     ((_ (x ...) g0 g ...)
%      (lambdag@ (p)
%        (inc
%          (let ((x (var)) ...)
%            (bind* (g0 p) g ...)))))))

\schemedisplayspace
\begin{schemedisplay}
(define-syntax fresh
  (syntax-rules ()
    ((_ (a ...) g0 g ...)
     (lambdag@ (p)
       (inc
         (let ((a (nom 'a)) ...)
           (bind* (g0 p) g ...)))))))

(define nom
  (lambda (a)
    (list 'nom-tag (symbol->string a))))
\end{schemedisplay}

% \scheme{bind*} is short-circuiting: since the empty stream is
% represented by \mbox{\scheme|#f|}, any failed goal causes
% \scheme{bind*} to immediately return \scheme{#f}.  \scheme{bind*}
% relies on \scheme{bind} \cite{moggi91notions,Wadler92}, which applies the
% goal \scheme{g} to each element in the stream \scheme{p-inf}.  The
% resulting \scheme{p-inf}'s are then merged using \scheme{mplus}, which
% combines a \scheme{p-inf} and an \scheme{f} to yield a single
% \scheme{p-inf}.  (\scheme{bind} is similar to Lisp's \scheme{mapcan}
% but uses \scheme{mplus} (not \scheme{append}) to interleave the values
% of streams.)

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax bind*
%   (syntax-rules ()
%     ((_ e) e)
%     ((_ e g0 g ...)
%      (let ((a-inf e))
%        (and a-inf (bind* (bind a-inf g0) g ...))))))

% (define bind
%   (lambda (a-inf g)
%     (case-inf a-inf
%       (() #f)
%       ((f) (inc (bind (f) g)))
%       ((a) (g a))
%       ((a f) (mplus (g a) (lambdaf@ () (bind (f) g)))))))

% (define mplus
%   (lambda (a-inf f)
%     (case-inf a-inf
%       (() (f))
%       ((f^) (inc (mplus (f) f^)))
%       ((a) (choice a f))
%       ((a f^) (choice a (lambdaf@ () (mplus (f) f^)))))))
% \end{schemedisplay}

% To take the disjunction of goals we define \scheme{conde}, a goal
% constructor that combines successive \scheme{conde}-lines using
% \scheme{mplus*}, which in turn relies on \scheme{mplus}.
% We use the same implicit package \scheme{p} for each \scheme{conde}-line.
% To avoid unwanted divergence, we treat the
% \scheme{conde}-lines as a single \scheme{inc} stream.

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax conde
%   (syntax-rules ()
%     ((_ (g0 g ...) (g1 g^ ...) ...)
%      (lambdag@ (p)
%        (inc (mplus* (bind* (g0 p) g ...)
%                     (bind* (g1 p) g^ ...)
%                     ...))))))
% \end{schemedisplay}

% \begin{schemedisplay}
% (define-syntax mplus*
%   (syntax-rules ()
%     ((_ e) e)
%     ((_ e0 e ...) (mplus e0 (lambdaf@ () (mplus* e ...))))))
% \end{schemedisplay}

\section{Reification}\label{akreifysection}

\enlargethispage{2em}

As described in section~\ref{mkreification}, \emph{reification} is the
process of turning a miniKanren (or \alphakanren) value into a Scheme
value.

\alphakanren's version of \scheme{reify} takes a variable \scheme{x}
and a package \scheme{p}, and returns the value associated with
\scheme{x} in \scheme{p} (along with any relevant constraints), first
replacing all variables and noms with symbols representing those
entities.  A constraint \scheme{`(,a . ,y)} is \emph{relevant} if both
\scheme{a} and \scheme{y} appear in the value associated with
\scheme{x}.

The first \scheme{cond} clause in the definition of \scheme{reify}
below returns only the reified value associated with \scheme{x}, when
there are no relevant constraints.  The \scheme{else} clause returns
both the reified value of \scheme{x} and the reified set of relevant
constraints; we have arbitrarily chosen the colon `:' to separate the
reified value from the list of reified constraints.

\schemedisplayspace
\begin{schemedisplay}
(define reify
  (lambda (x p)
    (mv-let ((sigma nabla) p)
      (let* ((v (get x sigma)) (s (reify-s v)) (v (walk* v s)))
        (let ((nabla (filter (lambda (a) (and (symbol? (car a)) (symbol? (cdr a))))
                       (walk* nabla s))))
          (cond
            ((null? nabla) v)
            (else `(,v : ,nabla))))))))
\end{schemedisplay}

\scheme{reify-s} is the heart of the reifier.  \scheme{reify-s} takes
an arbitrary value \scheme{v}, and returns a substitution that maps
every distinct nom and variable in \scheme{v} to a unique symbol.  The
trick to maintaining left-to-right ordering of the subscripts on these
symbols is to process \scheme{v} from left to right, as can be seen in
the last \scheme{pmatch} clause.  When \scheme{reify-s} encounters a
nom or variable, it determines if we already have a mapping for that
entity.  If not, \scheme{reify-s} extends the substitution with an
association between the nom or variable and a new, appropriately
subscripted symbol.

\schemedisplayspace
\begin{schemedisplay}
(define reify-s
  (letrec
    ((r-s (lambda (v s)
            (pmatch v
              (`,c (guard (not (pair? c))) s)
              (`(tie-tag ,a ,t) (r-s t (r-s a s)))
              (`(nom-tag ,n)
               (cond
                 ((assq v s) s)
                 ((assp nom? s)
                  => (lambda (p)
                       (let ((n (reify-n (cdr p))))
                         (cons `(,v . ,n) s))))
                 (else (cons `(,v . a.0) s))))
              (`(susp-tag () __)
               (cond
                 ((assq v s) s)
                 ((assp ak-var? s)
                  => (lambda (p)
                       (let ((n (reify-n (cdr p))))
                         (cons `(,v . ,n) s))))
                 (else (cons `(,v . __.0) s))))
              (`(susp-tag ,pi ,x)
               (r-s (x) (r-s pi s)))
              (`(,a . ,d) (r-s d (r-s a s)))))))
      (lambda (v)
        (r-s v '()))))
\end{schemedisplay}

\scheme{walk*} applies a special substitution \scheme{s}, which
maps noms and variables to symbols, to an arbitrary value \scheme{v}.

\schemedisplayspace
\begin{schemedisplay}
(define walk*
  (lambda (v s)
    (pmatch v
      (,c (guard (not (pair? c))) c)
      (`(tie-tag ,a ,t) (list 'tie-tag (get a s) (walk* t s)))
      (`(nom-tag __) (get v s))
      (`(susp-tag () __) (get v s))
      (`(susp-tag ,pi ,x) (list 'susp-tag (walk* pi s) (get (x) s)))
      (`(,a . ,d) (cons (walk* a s) (walk* d s))))))
\end{schemedisplay}

\begin{schemedisplay}
(define ak-var?
  (lambda (x)
    (pmatch x
      (`(susp-tag () __) #t)
      (else #f))))

(define nom?
  (lambda (x)
    (pmatch x
      (`(nom-tag __) #t)
      (else #f))))
\end{schemedisplay}

\scheme{reify-n} returns a symbol representing an individual
variable or nom; this symbol always ends with a period
followed by a non-negative integer.

\schemedisplayspace
\begin{schemedisplay}
(define reify-n
  (lambda (a)
    (let ((str* (string->list (symbol->string a))))
      (let ((c* (memv #\. str*)))
        (let ((rn (string->number (list->string (cdr c*)))))
          (let ((n-str (number->string (+ rn 1))))
            (string->symbol
              (string-append
                (string (car str*)) "." n-str))))))))
\end{schemedisplay}

% \subsection{Impure Control Operators:}

% For completeness, we define three additional \alphakanren\ goal constructors
% not used in this paper: \scheme{project}, which can be used to
% access the values of variables, and
% \scheme{conda} and \scheme{condu}, which can be used to prune
% the search tree of a program.
% The examples from chapter 10 of \emph{The Reasoned Schemer}~\cite{reasoned}
% demonstrate how \scheme{conda} and
% \scheme{condu} can be useful, and the pitfalls that await the
% unsuspecting reader.
% %\newpage

% \schemedisplayspace
% \begin{schemedisplay}
% (define-syntax project
%   (syntax-rules ()
%     ((_ (x ...) g0 g ...)
%      (lambdag@ (p)
%        (mv-let ((sigma nabla) p)
%          (let ((x (get x sigma)) ...)
%            (bind* (g0 p) g ...)))))))
% \end{schemedisplay}

% \begin{schemedisplay}
% (define-syntax conda
%   (syntax-rules ()
%     ((_ (g0 g ...) (g1 g^ ...) ...)
%      (lambdag@ (p)
%        (inc (ifa ((g0 p) g ...) ((g1 p) g^ ...) ...))))))

% (define-syntax ifa
%   (syntax-rules ()
%     ((_) #f)
%     ((_ (e g ...) b ...)
%      (let loop ((a-inf e))
%        (case-inf a-inf
%          (() (ifa b ...))
%          ((f) (inc (loop (f))))
%          ((a) (bind* a-inf g ...))
%          ((a f) (bind* a-inf g ...)))))))
% \end{schemedisplay}

% \begin{schemedisplay}
% (define-syntax condu
%   (syntax-rules ()
%     ((_ (g0 g ...) (g1 g^ ...) ...)
%      (lambdag@ (p)
%        (inc (ifu ((g0 p) g ...) ((g1 p) g^ ...) ...))))))
% \end{schemedisplay}
% \newpage
% \begin{schemedisplay}
% (define-syntax ifu
%   (syntax-rules ()
%     ((_) #f)
%     ((_ (e g ...) b ...)
%      (let loop ((a-inf e))
%        (case-inf a-inf
%          (() (ifu b ...))
%          ((f) (inc (loop (f))))
%          ((a) (bind* a-inf g ...))
%          ((a f) (bind* a g ...)))))))
% \end{schemedisplay}

\section{Nominal Unification with Triangular Substitutions}\label{triangularsection}

\enlargethispage{1em}

In this section we modify the idempotent nominal unification
implementation to work with triangular substitutions, significantly
improving the performance of \alphakanren\footnote{This implementation
  of triangular nominal unification is due to Joseph Near.  Ramana
  Kumar has implemented a somewhat faster triangular unifier; however,
  the resulting code bears little resemblance to the idempotent
  algorithm of~\cite{Urban-Pitts-Gabbay/04}.}.  We present only the
definitions that differ from those already presented.

Like the core miniKanren implementation of
Chapter~\ref{mkimplchapter}, our triangular unifier relies on a
\scheme|walk| function for looking up values in a triangular
substitution.  The nominal \scheme|walk| function is complicated by
the need to handle suspensions and permutations.

\schemedisplayspace
\begin{schemedisplay}
(define walk
  (lambda (x s)
    (let loop ((x x) (pi '()))
      (pmatch x
        (`(susp-tag ,pi^ ,v)
         (let ((v (assq (v) s)))
           (cond
             (v (loop (cdr v) (append pi^ pi)))
             (else (apply-pi pi x)))))
        (else (apply-pi pi x))))))
\end{schemedisplay}

We can now redefine \scheme|walk*| in terms of \scheme|walk|.

\schemedisplayspace
\begin{schemedisplay}
(define walk*
  (lambda (v s)
    (let ([v (walk v s)])
      (pmatch v
        (`(tie-tag ,a ,t) (list 'tie-tag a (walk* t s)))
        (`(,a . ,d) (guard (untagged? a))
         (cons (walk* a s) (walk* d s)))
        (else v)))))
\end{schemedisplay}

\scheme|unify| no longer uses \scheme|compose-subst| or
\scheme|apply-subst|.

\schemedisplayspace
\begin{schemedisplay}
(define unify
  (lambda (eqns sigma nabla fk)
    (mv-let ((sigma^ delta) (apply-sigma-rules eqns sigma fk))
      (unifyhash delta sigma^ nabla fk))))
\end{schemedisplay}

Similarly, \scheme|unifyhash| no longer uses \scheme|apply-subst|.

\schemedisplayspace
\begin{schemedisplay}
(define unifyhash
  (lambda (delta sigma nabla fk)
    (let ((delta (delta-union nabla delta)))
      (list sigma (apply-nabla-rules delta sigma fk)))))
\end{schemedisplay}

\scheme|apply-sigma-rules| now takes \scheme|sigma| as an additional
argument, which it passes to \scheme|sigma-rules|; also,
\scheme|apply-sigma-rules| no longer uses \scheme|compose-subst|.

\schemedisplayspace
\begin{schemedisplay}
(define apply-sigma-rules
  (lambda (eqns sigma fk)
    (cond
      ((null? eqns) `(,sigma ,empty-delta))
      (else
       (let ((eqn (car eqns)) (eqns (cdr eqns)))
         (mv-let ((eqns sigma delta) (or (sigma-rules eqn sigma eqns) (fk)))
           (mv-let ((sigma^ delta^) (apply-sigma-rules eqns sigma fk))
             (list sigma^ (delta-union delta^ delta)))))))))
\end{schemedisplay}

\scheme|apply-nabla-rules| also takes \scheme|sigma| as an additional
argument, which it passes to \scheme|nabla-rules|.

\schemedisplayspace
\begin{schemedisplay}
(define apply-nabla-rules
  (lambda (delta sigma fk)
    (cond
      ((null? delta) empty-nabla)
      (else
       (let ((c (car delta)) (delta (cdr delta)))
         (mv-let ((delta nabla) (or (nabla-rules c sigma delta) (fk)))
           (delta-union nabla (apply-nabla-rules delta sigma fk))))))))
\end{schemedisplay}

\scheme|sigma-rules| no longer uses \scheme|apply-subst|, but now
walks \scheme|eqns| in \scheme|sigma|, which is passed in as an
additional argument.

\schemedisplayspace
\begin{schemedisplay}
(define sigma-rules
  (lambda (eqn sigma eqns)
    (let ((eqn (cons (walk (car eqn) sigma) (walk (cdr eqn) sigma))))
      (pmatch eqn
        (`(,c . ,c^)
         (guard (not (pair? c)) (equal? c c^))
         `(,eqns ,sigma ,empty-delta))
        (`((tie-tag ,a ,t) . (tie-tag ,a^ ,t^))
         (guard (eq? a a^))
         `(((,t . ,t^) . ,eqns) ,sigma ,empty-delta))
        (`((tie-tag ,a ,t) . (tie-tag ,a^ ,t^))
         (guard (not (eq? a a^)))
         (let ((u^ (apply-pi `((,a ,a^)) t^)))
           `(((,t . ,u^) . ,eqns) ,sigma ((,a . ,t^)))))
        (`((nom-tag __) . (nom-tag __))
         (guard (eq? (car eqn) (cdr eqn)))
         `(,eqns ,sigma ,empty-delta))
        (`((susp-tag ,pi ,x) . (susp-tag ,pi^ ,x^))
         (guard (eq? (x) (x^)))
         (let ((delta (map (lambda (a) (cons a (x)))
                           (disagreement-set pi pi^))))
           `(,eqns ,sigma ,delta)))
        (`((susp-tag ,pi ,x) . ,t)
         (guard (not (occurs-check (x) t)))
         (let ((sigma (ext-s (x) (apply-pi (reverse pi) t) sigma)))
           `(,eqns ,sigma ,empty-delta)))
        (`(,t . (susp-tag ,pi ,x))
         (guard (not (occurs-check (x) t)))
         (let ((sigma (ext-s (x) (apply-pi (reverse pi) t) sigma)))
           `(,eqns ,sigma ,empty-delta)))
        (`((,t1 . ,t2) . (,t1^ . ,t2^))
         (guard (untagged? t1) (untagged? t1^))
         `(((,t1 . ,t1^) (,t2 . ,t2^) . ,eqns) ,sigma ,empty-delta))
        (else #f)))))
\end{schemedisplay}

\newpage

\scheme|nabla-rules| also takes \scheme|sigma| as an additional
argument, which it uses to walk \scheme|d|.

\schemedisplayspace
\begin{schemedisplay}
(define nabla-rules
  (lambda (d sigma delta)
    (let ((d (cons (walk (car d) sigma) (walk (cdr d) sigma))))
      (pmatch d
        (`(,a . ,c)
         (guard (not (pair? c)))
         `(,delta ,empty-nabla))
        (`(,a . (tie-tag ,a^ ,t))
         (guard (eq? a^ a))
         `(,delta ,empty-nabla))
        (`(,a . (tie-tag ,a^ ,t))
         (guard (not (eq? a^ a)))
         `(((,a . ,t) . ,delta) ,empty-nabla))
        (`(,a . (nom-tag __))
         (guard (not (eq? a (cdr d))))
         `(,delta ,empty-nabla))
        (`(,a . (susp-tag ,pi ,x))
         (let ((a (apply-pi (reverse pi) a)) (x (x)))
           `(,delta ((,a . ,x)))))
        (`(,a . (,t1 . ,t2))
         (guard (untagged? t1))
         `(((,a . ,t1) (,a . ,t2) . ,delta) ,empty-nabla))
        (else #f)))))
\end{schemedisplay}

The redefinition of \scheme|reify| uses the new \scheme|apply-reify-s|
function in place of some uses of \scheme|walk*|.

\schemedisplayspace
\begin{schemedisplay}
(define reify
  (lambda (x p)
    (mv-let ((sigma nabla) p)
      (let* ((v (walk* x sigma)) (s (reify-s v)) (v (apply-reify-s v s)))
        (let ((nabla (filter (lambda (a) (and (symbol? (car a)) (symbol? (cdr a))))
                       (apply-reify-s nabla s))))
          (cond
            ((null? nabla) v)
            (else `(,v : ,nabla))))))))
\end{schemedisplay}

\newpage

\scheme|apply-reify-s| is new, but is almost identical to the old
definition of \scheme|walk*| in section~\ref{akreifysection}.

\schemedisplayspace
\begin{schemedisplay}
(define apply-reify-s
  (lambda (v s)
    (pmatch v
      (`,c (guard (not (pair? c))) c)
      (`(tie-tag ,a ,t) (list 'tie-tag (get a s) (apply-reify-s t s)))
      (`(nom-tag __) (get v s))
      (`(susp-tag () __) (get v s))
      (`(susp-tag ,pi ,x)
       (list 'susp-tag
         (map (lambda (swap)
                (pmatch swap
                  (`(,a ,b) (list (get a s) (get b s)))))
              pi)
         (get (x) s)))
      (`(,a . ,d) (cons (apply-reify-s a s) (apply-reify-s d s))))))
\end{schemedisplay}

By using triangular rather than idempotent substitutions, unification
is as much as ten times faster and is more memory efficient.

An important limitation of both the triangular and idempotent
implementations is that neither currently supports disequality
constraints.

% \section{Performance Comparison: Idempotent vs. Triangular Substitutions}\label{akperfsection}

% I'm not using anything fancy. The occurs-check is easy to turn off, but I've left it on here. I tried to keep this file as close to alphamk.scm as possible. I wrote a simple test that should take time linear in the length of the list. Even without any other optimizations, it's a huge improvement:

% Idempotent:
% > (time (run* (q) (exist (x) (testo (make-list 400) x))))
% running stats for (run* (q) (exist (x) (testo (make-list 400) x))):
%     1373 collections
%     36043 ms elapsed cpu time, including 4156 ms collecting
%     38922 ms elapsed real time, including 4609 ms collecting
%     5745917976 bytes allocated
% (_.0)

% Triangular:
% > (time (run* (q) (exist (x) (testo (make-list 400) x))))
% running stats for (run* (q) (exist (x) (testo (make-list 400) x))):
%     8 collections
%     396 ms elapsed cpu time, including 12 ms collecting
%     411 ms elapsed real time, including 14 ms collecting
%     35858608 bytes allocated
% (_.0)

% The difference in allocation was something of a surprise to me, but it makes sense. Of course, Ramana's version with unsound unification is still faster, but it's not nearly as big an improvement over the "naive" triangular version as that version is over the original:
% > (time (run #f (q) (exist (x) (testo (make-list 400) x))))
% running stats for (run #f (q) (exist (x) (testo (make-list 400) x))):
%     1 collection
%     176 ms elapsed cpu time, including 52 ms collecting
%     187 ms elapsed real time, including 55 ms collecting
%     3028096 bytes allocated
% (*0)

% This version runs most of the Pelletier problems using alphaTAP. There are a few that it can't solve without the proof (like 34). I don't *think* this is due to errors in the implementation, but I could be wrong. The aim is to make it fast while staying as close to the paper version as possible, right?

% Joe


\subsection{SARIMA}