% This file contains the content for a main section
\regularsectionformat
%% Modify below this line %%
\chapter{Discussion}
\label{chap:discussion}

\section{Comparison of the ACES white point and CIE \texorpdfstring{D\textsubscript{60}}{D60}}
\label{sec:comp}
Frequently, the white point associated with various ACES encodings is said to be `D\textsubscript{60}' \cite{autodesk,bmforum,acescentralD60}. This shorthand notation has sometimes led to confusion for those familiar with the details of how the chromaticity coordinates of the CIE D series illuminants are calculated \cite{notD60}.  The chromaticity coordinates of any CIE D series illuminant can be calculated using the equations found in Section 3 of CIE 15:2004 and reproduced in Equation~\ref{eq:xyeq} \cite{CIE152004}.

\begin{floatequ}[!ht]
    \begin{alignat*}{2}
    & y_{D} && = -3.000x_{D}^{2}+2.870x_{D}-0.275 \\
    & x_{D} && =
        \begin{dcases}
            0.244063+0.09911{\frac {10^{3}}{T}}+2.9678{\frac {10^{6}}{T^{2}}}-4.6070{\frac {10^{9}}{T^{3}}} \qquad & 4,000\ \mathrm {K} \leq T\leq 7,000\ \mathrm {K} \\
            0.237040+0.24748{\frac {10^{3}}{T}}+1.9018{\frac {10^{6}}{T^{2}}}-2.0064{\frac {10^{9}}{T^{3}}} \qquad & 7,000\ \mathrm {K} < T\leq 25,000\ \mathrm {K}
        \end{dcases}
    \end{alignat*}

    \captionsetup{width=.75\textwidth}
    \caption{Calculation of CIE xy from CCT for CIE Daylight}
    \label{eq:xyeq}
\end{floatequ}

The CIE has specified four canonical daylight illuminants (D\textsubscript{50}, D\textsubscript{55}, D\textsubscript{65} and D\textsubscript{75}) \cite{CIE152004}.  Contrary to what the names might imply, the correlated color temperature (CCT) values of these four canonical illuminants are not the nominal CCT values of \SI[mode=text]{5000}{\kelvin}, \SI[mode=text]{5500}{\kelvin}, \SI[mode=text]{6500}{\kelvin}, and \SI[mode=text]{7500}{\kelvin}.  For instance, CIE D\textsubscript{65} does not have a CCT of \SI[mode=text]{6500}{\kelvin} but rather a CCT temperature of approximately \SI[mode=text]{6504}{\kelvin} \cite{wyszecki1982color}.
The exact CCT values differ from the nominal CCT values due to a 1968 revision to $c_2$, the second radiation constant in Planck's blackbody radiation formula \cite{Durieux1970}.  When the value of $c_2$ was changed from 0.014380 to 0.014388, it altered the CIE xy location of the Planckian locus for a blackbody. This small change to the Planckian locus' position relative to the chromaticity coordinates of the established CIE daylight locus had the effect of changing the correlated color temperature of the CIE D series illuminants ever so slightly.  The precise CCT values for the established canonical CIE D series illuminants can be determined by applying the equation in Equation~\ref{eq:ccteq} to the nominal CCT values implied by the illuminant name.  The exact CCT values of the canonical daylight illuminants are not whole numbers after the correction factor is applied, but it is common to round their values to the nearest Kelvin.  The CCT values of the CIE canonical daylight illuminants before the 1968 change to $c_2$, after the 1968 change, and rounded to the nearest Kelvin can be found in Table~\ref{tab:d_cct}.

\begin{floatequ}[!ht]
\begin{equation}
    CCT_{new} = CCT\times \frac{1.4388}{1.4380}
\end{equation}
    \captionsetup{width=.75\textwidth}
    \caption{Conversion of nominal pre-1968 CCT to post-1968 CCT}
    \label{eq:ccteq}
\end{floatequ}

\begin{table}[!ht]
    \centering
    \begin{tabularx}{.97\linewidth}{|Y|Y|Y|Y|}
    \hline
    \textbf{CIE D} & \textbf{CCT} & \textbf{CCT current} & \textbf{CCT current} \\ [-1.3ex]
    \textbf{Illuminant} & \textbf{before 1968} & \footnotesize{\textbf{(round to 3 decimal places)}} & \footnotesize{\textbf{(round to 0 decimal places)}} \\ \hline
    D\textsubscript{50} & \SI[mode=text]{5000}{\kelvin} & \SI[mode=text]{5002.782}{\kelvin} & \SI[mode=text]{5003}{\kelvin} \\ \hline
    D\textsubscript{55} & \SI[mode=text]{5500}{\kelvin} & \SI[mode=text]{5503.060}{\kelvin} & \SI[mode=text]{5503}{\kelvin} \\ \hline
    D\textsubscript{65} & \SI[mode=text]{6500}{\kelvin} & \SI[mode=text]{6503.616}{\kelvin} & \SI[mode=text]{6504}{\kelvin} \\ \hline
	D\textsubscript{75} & \SI[mode=text]{7500}{\kelvin} & \SI[mode=text]{7504.172}{\kelvin} & \SI[mode=text]{7504}{\kelvin} \\ \hline
    \end{tabularx}
    \captionsetup{width=.75\textwidth}
    \caption{CCT of canonical CIE daylight illuminants \cite{tableValsPython}}
    \label{tab:d_cct}
\end{table}

D\textsubscript{60} is not one of the four CIE canonical daylight illuminants so the exact CCT of such a daylight illuminant could be interpreted to be either approximately \SI[mode=text]{6003}{\kelvin} ($6000 \times \frac{1.4388}{1.4380}$) or \SI[mode=text]{6000}{\kelvin}.  Regardless, the ACES white point chromaticity coordinates derived using the method specified in Section~\ref{chap:dervation} differs from both the chromaticity coordinates of CIE daylight with a CCT of \SI[mode=text]{6003}{\kelvin} and CIE daylight with a CCT of \SI[mode=text]{6000}{\kelvin}.  The chromaticity coordinates of each, rounded to 5 decimal places, can be found in Table~\ref{tab:ciexy}.  As illustrated in Figure~\ref{fig:cieuv}, the chromaticity coordinates of the ACES white point do not fall on the daylight locus nor do they match those of any CIE daylight spectral power distribution.  The positions of the chromaticity coordinates in CIE Uniform Color Space (u$^\prime$v$^\prime$) and the differences from the ACES chromaticity coordinates in $\Delta$u$^\prime$v$^\prime$ can be found in Table~\ref{tab:cieuv}.

\begin{table}[!ht]
    \centering
    \begin{tabularx}{.75\linewidth}{|l|Y|Y|}
    \hline
     & \textbf{CIE $\boldsymbol{x}$} & \textbf{CIE $\boldsymbol{y}$} \\ \hline
    ACES White Point & 0.32168 & 0.33767 \\ \hline
    CIE Daylight 6000K & 0.32169  & 0.33780 \\ \hline
	CIE Daylight 6003K & 0.32163  & 0.33774 \\ \hline
    \end{tabularx}
    \captionsetup{width=.75\textwidth}
    \caption{CIE xy chromaticity coordinates rounded to 5 decimal places \cite{tableValsPython}}
    \label{tab:ciexy}
\end{table}

\begin{table}[!ht]
    \centering
    \begin{tabularx}{.75\linewidth}{|l|Y|Y|Y|}
    \hline
     & \textbf{CIE $\boldsymbol{u^\prime}$} & \textbf{CIE $\boldsymbol{v^\prime}$} & $\boldsymbol{\Delta u^\prime v^\prime}$ \\ \hline
    ACES White Point & 0.20078 & 0.47421 & 0\\ \hline
    CIE Daylight 6000K & 0.20074 & 0.47427 & 0.00008 \\ \hline
	CIE Daylight 6003K & 0.20072 & 0.47423 & 0.00007 \\ \hline
    \end{tabularx}
    \captionsetup{width=.75\textwidth}
    \caption{CIE u$^\prime$v$^\prime$ chromaticity coordinates and $\Delta$u$^\prime$v$^\prime$ from the ACES white point rounded to 5 decimal places \cite{tableValsPython}}
    \label{tab:cieuv}
\end{table}

\begin{figure}[!ht]
    \centering
    \includegraphics[width=0.5\textwidth]{cieuv.png}
    \caption{CIE UCS diagram with chromaticity coordinates}
    \label{fig:cieuv}
\end{figure}

Although the ACES white point chromaticity is not on either the Planckian locus or the daylight locus, the CCT of its chromaticity can still be estimated.  There are a number of methods for estimating the CCT of any particular set of chromaticity coordinates \cite{robertson1968computation,mccamy1992correlated,hernandez1999calculating,Ohno2014}.  The results of four popular methods can be found in Table~\ref{tab:aceswpcct}.  Each of the methods estimates the CCT of the ACES white point to be very close to \SI[mode=text]{6000}{\kelvin}.

\begin{table}[!ht]
    \centering
    \begin{tabularx}{.9\linewidth}{|Y|Y|}
    \hline
    \textbf{CCT Estimation Method} & \textbf{ACES white point CCT} \\ \hline
    Robertson & \SI[mode=text]{5998.98}{\kelvin} \\ \hline
    Hernandez-Andres & \SI[mode=text]{5997.26}{\kelvin} \\ \hline
    Ohno & \SI[mode=text]{6000.04}{\kelvin} \\ \hline
	McCamy & \SI[mode=text]{6000.41}{\kelvin} \\ \hline
    \end{tabularx}
    \captionsetup{width=.9\textwidth}
    \caption{Estimation of the CCT of the ACES white point rounded to 2 decimal places \cite{tableValsPython}}
    \label{tab:aceswpcct}
\end{table}

\section{Reasons for the ``\texorpdfstring{D\textsubscript{60}}{D60}-like'' white point}
\label{sec:reasonForD60}
The ACES white point was first specified by the Academy's ACES Project Committee in 2008 in Academy Specification S-2008-001.  The details in S-2008-001 were later standardized in SMPTE ST 2065-1:2012.  Prior to the release of the Academy specification the Project Committee debated various aspects of the ACES2065-1 encoding, including the exact white point, for many months.  The choice of the ``D\textsubscript{60}-like'' white point was influenced heavily by discussions centered around viewer adaptation, dark surround viewing conditions, ``cinematic look'', and preference.  In the end, the Committee decided to go with a white point that was close to that of a daylight illuminant but also familiar to those with a film heritage. The white point would later be adopted for use in other encodings used in the ACES system. It is important to note that the ACES white point does not dictate the chromaticity of the reproduction neutral axis.  Using various techniques beyond the scope of this document the chromaticity of the equal red, green and blue (ACES2065-1 \rgbequal) may match the ACES white point, the display calibration white point, or any other white point preferred for technical or aesthetic reasons.

The Committee felt that a white point with a chromaticity similar to that of daylight was appropriate for ACES2065-1.  However, the exact CCT of the daylight was in question.  Some felt D\textsubscript{55} was a reasonable choice given its historical use as the design illuminant for daylight color negative films.  Others felt D\textsubscript{65} would be good choice given its use in television and computer graphics as a display calibration white point.  Because the exact white point chromaticity would not prohibit users from achieving any reproduction white point, the Committee ultimately decided to use the less common CCT of \SI[mode=text]{6000}{\kelvin}.  This choice was based on an experiment to determine the reproduction chromaticity of projected color print film, the relative location of the white point compared to other white points commonly used in digital systems, and the general belief that imagery reproduced with the white point felt aesthetically ``cinematic''.

The projected color print film experiment involved simulating the exposure of a spectrally non-selective (neutral) gray scale onto color negative film, printing that negative onto a color print film, then projecting the color film onto a motion picture screen with a xenon-based film projector and measuring the colorimetry off the screen. The result of the experiment found that the CIE xy chromaticity coordinates of a projected LAD patch \cite{pytlak1976simplified,kodakLad} through a film system were approximately $x=0.32170$ $y=0.33568$. Figure~\ref{fig:filmprintthrough} shows a plot of the CIE $u^\prime v^\prime$ chromaticity coordinates of a scene neutral as reproduced by a film system compared to the CIE daylight locus and the ACES white point.  The chromaticity of the film system LAD reproduction was determined to be closest to CIE daylight with the CCT of \SI[mode=text]{6000}{\kelvin} when the differences were calculated in CIE $u^\prime v^\prime$.  A summary of the CIE $u^\prime v^\prime$ differences between CIE daylight at various CCTs and the LAD patch chromaticity are summarized in Table~\ref{tab:lad}.

\begin{figure}[!ht]
    \centering
    \includegraphics[width=0.85\textwidth]{images/PrintThroughChromaticities.png}
    \caption{Film system print-through color reproduction of original scene neutral scale}
    \label{fig:filmprintthrough}
\end{figure}

\begin{table}[!ht]
    \centering
    \begin{tabularx}{.75\linewidth}{|Y|Y|}
    \hline
    \textbf{Daylight CCT} & $\boldsymbol{\Delta u^\prime v^\prime}$ \textbf{from LAD chromaticity}\\ \hline
		\SI[mode=text]{5500}{\kelvin} & 0.008183 \\ \hline
		\SI[mode=text]{5600}{\kelvin} & 0.006619 \\ \hline
		\SI[mode=text]{5700}{\kelvin} & 0.005112 \\ \hline
		\SI[mode=text]{5800}{\kelvin} & 0.003676 \\ \hline
		\SI[mode=text]{5900}{\kelvin} & 0.002354 \\ \hline
		\SI[mode=text]{6000}{\kelvin} & 0.001360 \\ \hline
		\SI[mode=text]{6100}{\kelvin} & 0.001448 \\ \hline
		\SI[mode=text]{6200}{\kelvin} & 0.002442 \\ \hline
		\SI[mode=text]{6300}{\kelvin} & 0.003627 \\ \hline
		\SI[mode=text]{6400}{\kelvin} & 0.004836 \\ \hline
		\SI[mode=text]{6500}{\kelvin} & 0.006035 \\ \hline
    \end{tabularx}
    \captionsetup{width=.75\textwidth}
    \caption{CIE $\Delta$u$^\prime$v$^\prime$ difference between projected LAD patch and CIE Daylight CCT chromaticity coordinates round to 6 decimal places \cite{tableValsPython}}
    \label{tab:lad}
\end{table}

\section{Reasons why the ACES white point doesn't match the CIE \texorpdfstring{D\textsubscript{60}}{D60} chromaticity coordinates}
\label{sec:reasonsForDifference}
As discussed in Section~\ref{sec:reasonForD60}, the ACES white point was chosen to be very close to that of CIE Daylight with a CCT of \SI[mode=text]{6000}{\kelvin}.  This raises the question why the CIE chromaticity coordinates of $x=0.32169$ $y=0.33780$ were not used.  The reasoning is somewhat precautionary; at the time, the exact chromaticity coordinates for the ACES white point were being debated, the ACES Project Committee was concerned about the implications the choice of any particular set of chromaticity coordinates could suggest.

Those new to ACES can often misinterpret the specification of a set of ACES encoding white point chromaticity coordinates as a requirement that the final reproduction neutral axis chromaticity is limited to only that white point chromaticity.  However, as pointed out in Section~\ref{sec:reasonForD60}, the ACES encoding white point does not dictate the chromaticity of the reproduction neutral axis, and regardless of the ACES white point chromaticity, the reproduction neutral axis may match the ACES white point, the display calibration white point, or any other white point preferred for technical or aesthetic reasons.  The ACES white point chromaticity coordinates serve to aid in the understanding and, if desired, conversion of the colorimetry of ACES encoded images to any other encoding including those with a different white point.

Just as the implication of the ACES encoding white point on reproduction can be misunderstood, the ACES Project Committee was also concerned that the ACES encoding white point might have unintended implications for image creators. Specifically, the Committee was concerned that the choice of a set of chromaticity coordinates that corresponded to a source with a defined spectral power distribution might be misunderstood to suggest that only that source could be used to illuminate the scene.  For example, the Committee was concerned if the ACES white point chromaticity was chosen to match that of CIE Daylight with a CCT of \SI[mode=text]{6000}{\kelvin} then \textit{only} scenes photographed under CIE Daylight with a CCT of \SI[mode=text]{6000}{\kelvin} would be compatible with the ACES system.  In reality, ACES does not dictate the source under which movies or television shows can be photographed.  ACES Input Transforms handle the re-encoding of camera images to ACES2065-1 and preserve all the technical and artistic intent behind on-set lighting choices.

For these reasons as well as an abundance of caution, the ACES Project Committee decided it would be best to use a set of chromaticity coordinates very near those of CIE Daylight with a CCT of \SI[mode=text]{6000}{\kelvin} but not exactly those of any easily calculated spectral power distribution.


\chapter{Design of a Multi-Trajectory Simulation Algorithm}
\label{ch:Multi-Trajectory Simulation Algorithm}
This chapter introduces a design for a multi-trajectory simulation algorithm and provides explanations and examples of its main steps. The strength of this algorithm lies in its ability to run simulations within complex models, either with or without the presence of rare-events, and its adaptability to reach a wide coverage of the state space with efficiency in different types of models...

\section{Introduction to Multi-Trajectory}
\label{sec:Introduction to Multi-Trajectory}
Multi-trajectory simulation algorithm is based on particles, where a particle represents one possible trajectory of the simulation, and carries a weight that indicates the probability of that trajectory to happen. At any given time there is a collection of particles ready to be executed. Each particle is associated with one state of the model, and the execution of it implies a change in that state by following one or more of its possible transitions.

The core idea of the algorithm can be described as a loop of three steps:
\begin{enumerate}
  \item Selection of the next particle...
  \item Execution of the particle, which consists in choosing between:
  \begin{enumerate}
    \item Move: Randomly select...
    \item Split: Create one new...
  \end{enumerate}
  \item Insertion of the particle...
\end{enumerate}

\begin{figure}[htb]
\begin{multicols}{3}
\centering
\includegraphics[width=.33\textwidth]{Model_Markov_Chain_Init.pdf}\\
Initial\\
\includegraphics[width=.33\textwidth]{Model_Markov_Chain_Move.pdf}\\
Move, with probability $\alpha/(\alpha+\beta+\gamma)$\\
\includegraphics[width=.33\textwidth]{Model_Markov_Chain_Split.pdf}\\
Split\\
\end{multicols}
\caption{Move or Split Example}
\label{fig:Move or Split Example}
\end{figure}

Against expectations, after the implementation of these strategies the results obtained by the executions were incorrect. Different attempts were made to overcome this error without success. An analysis of it with a numerical example is presented in Section~\ref{sub:Markov Chain}. Due to this limitation a solution with a fair execution over the particles is chosen, using the definition of a cycle as the execution of all particles in the pool and the restriction of not execute a particle twice in a cycle.

\subsection*{Only Exponential Transitions Enabled}
If there are only exponential transitions enabled, ...  and the average time spent in the state is equal to the inverse of the sum of all those weighting factors.

\begin{flalign*}
\begin{array}{ccl}
Time\ Spent &=&\displaystyle\frac{\displaystyle 1}{\displaystyle\sum\limits_{i=0}^n (\frac{enabled_i}{delay_i})}\\
\\
Weighting\ Factor[i] &=&\left\lbrace
	\begin{array}{ccl}
	Immediate\ Transition &=&0\\
	Exponential\ Transition &=&\displaystyle\frac{enabled_i}{delay_i}\\
	Deterministic\ Transition &=&0
	\end{array}
\right.
\end{array}
\end{flalign*}


\documentclass[11pt,oneside]{article}	%use"amsart"insteadof"article"forAMSLaTeXformat
\usepackage{geometry}		%Seegeometry.pdftolearnthelayoutoptions.Therearelots.
\geometry{letterpaper}		%...ora4paperora5paperor...
%\geometry{landscape}		%Activateforforrotatedpagegeometry
%\usepackage[parfill]{parskip}		%Activatetobeginparagraphswithanemptylineratherthananindent
\usepackage{graphicx}				%Usepdf,png,jpg,orepswithpdflatex;useepsinDVImode
								%TeXwillautomaticallyconverteps-->pdfinpdflatex
\usepackage{amssymb}
\usepackage[colorlinks]{hyperref}

%----macros begin---------------------------------------------------------------
\usepackage{color}
\usepackage{amsthm}

\def\conv{\mbox{\textrm{conv}\,}}
\def\aff{\mbox{\textrm{aff}\,}}
\def\E{\mathbb{E}}
\def\R{\mathbb{R}}
\def\Z{\mathbb{Z}}
\def\tex{\TeX}
\def\latex{\LaTeX}
\def\v#1{{\bf #1}}
\def\p#1{{\bf #1}}
\def\T#1{{\bf #1}}

\def\vet#1{{\left(\begin{array}{cccccccccccccccccccc}#1\end{array}\right)}}
\def\mat#1{{\left(\begin{array}{cccccccccccccccccccc}#1\end{array}\right)}}

\def\lin{\mbox{\rm lin}\,}
\def\aff{\mbox{\rm aff}\,}
\def\pos{\mbox{\rm pos}\,}
\def\cone{\mbox{\rm cone}\,}
\def\conv{\mbox{\rm conv}\,}
\newcommand{\homog}[0]{\mbox{\rm homog}\,}
\newcommand{\relint}[0]{\mbox{\rm relint}\,}

%----macros end-----------------------------------------------------------------

\title{Curves, surfaces and splines with LAR
\footnote{This document is part of the \emph{Linear Algebraic Representation with CoChains} (LAR-CC) framework~\cite{cclar-proj:2013:00}. \today}
}
\author{Alberto Paoluzzi}
%\date{}							%Activatetodisplayagivendateornodate

\begin{document}
\maketitle
\nonstopmode

\begin{abstract}
In this module we implement above LAR most of the parametric methods for polynomial and rational curves, surfaces and splines discussed in the book~\cite{Paoluzzi2003a}, and implemented in the PLaSM language and in the python package pyplasm.
\end{abstract}

\tableofcontents

%===============================================================================
\section{Introduction}
%===============================================================================

%===============================================================================
\section{Tensor product surfaces}
%===============================================================================

The tensor product form of surfaces will be primarily used, in the remainder of this module, to support the LAR implementation of polynomial (rational) surfaces. For this purpose, we start by defining some basic operators on function tensors.
In particular, a toolbox of basic tensor operations is given in Script 12.3.1. The ConstFunTensor operator produces a tensor of constant functions starting from a tensor of numbers; the recursive FlatTensor may be used to ?flatten? a tensor with any number of indices by producing a corresponding one index tensor; the InnerProd and TensorProd are used to compute the inner product and the tensor product of conforming tensors of functions, respectively.

\paragraph{Toolbox of tensor operations}

%-------------------------------------------------------------------------------
@D Multidimensional transfinite Bernstein-Bezier Basis
@{""" Toolbox of tensor operations """
def larBernsteinBasis (U):
	def BERNSTEIN0 (N):
		def BERNSTEIN1 (I):
			def map_fn(point):
				t = U(point)
				out = CHOOSE([N,I])*math.pow(1-t,N-I)*math.pow(t,I)
				return out
			return map_fn
		return [BERNSTEIN1(I) for I in range(0,N+1)]
	return BERNSTEIN0
@}
%-------------------------------------------------------------------------------

\subsection{Tensor product surface patch}

%-------------------------------------------------------------------------------
@D Tensor product surface patch
@{""" Tensor product surface patch """
def larTensorProdSurface (args):
	ubasis , vbasis = args
	def TENSORPRODSURFACE0 (controlpoints_fn):
		def map_fn(point):
			u,v=point
			U=[f([u]) for f in ubasis]
			V=[f([v]) for f in vbasis]
			controlpoints=[f(point) if callable(f) else f
				for f in controlpoints_fn]
			target_dim = len(controlpoints[0][0])
			ret=[0 for x in range(target_dim)]
			for i in range(len(ubasis)):
				for j in range(len(vbasis)):
					for M in range(len(ret)):
						for M in range(target_dim):
							ret[M] += U[i]*V[j] * controlpoints[i][j][M]
			return ret
		return map_fn
	return TENSORPRODSURFACE0
@}
%-------------------------------------------------------------------------------

\paragraph{Bilinear tensor product surface patch}

%-------------------------------------------------------------------------------
@D Bilinear surface patch
@{""" Bilinear tensor product surface patch """
def larBilinearSurface(controlpoints):
	basis = larBernsteinBasis(S1)(1)
	return larTensorProdSurface([basis,basis])(controlpoints)
@}
%-------------------------------------------------------------------------------

\paragraph{Biquadratic tensor product surface patch}

%-------------------------------------------------------------------------------
@D Biquadratic surface patch
@{""" Biquadratic tensor product surface patch """
def larBiquadraticSurface(controlpoints):
	basis1 = larBernsteinBasis(S1)(2)
	basis2 = larBernsteinBasis(S1)(2)
	return larTensorProdSurface([basis1,basis2])(controlpoints)
@}
%-------------------------------------------------------------------------------

\paragraph{Bicubic tensor product surface patch}

%-------------------------------------------------------------------------------
@D Bicubic surface patch
@{""" Bicubic tensor product surface patch """
def larBicubicSurface(controlpoints):
	basis1 = larBernsteinBasis(S1)(3)
	basis2 = larBernsteinBasis(S1)(3)
	return larTensorProdSurface([basis1,basis2])(controlpoints)
@}
%-------------------------------------------------------------------------------

%===============================================================================
\section{Transfinite B\'ezier}
%===============================================================================
%-------------------------------------------------------------------------------
@D Multidimensional transfinite B\'ezier
@{""" Multidimensional transfinite Bezier """
def larBezier(U):
	def BEZIER0(controldata_fn):
		N = len(controldata_fn)-1
		def map_fn(point):
			t = U(point)
			controldata = [fun(point) if callable(fun) else fun
				for fun in controldata_fn]
			out = [0.0 for i in range(len(controldata[0]))]
			for I in range(N+1):
				weight = CHOOSE([N,I])*math.pow(1-t,N-I)*math.pow(t,I)
				for K in range(len(out)):  out[K] += weight*(controldata[I][K])
			return out
		return map_fn
	return BEZIER0

def larBezierCurve(controlpoints):
	return larBezier(S1)(controlpoints)
@}
%-------------------------------------------------------------------------------

%===============================================================================
\section{Coons patches}
%===============================================================================

%-------------------------------------------------------------------------------
@D Transfinite Coons patches
@{""" Transfinite Coons patches """
def larCoonsPatch (args):
	su0_fn , su1_fn , s0v_fn , s1v_fn = args
	def map_fn(point):
		u,v=point
		su0 = su0_fn(point) if callable(su0_fn) else su0_fn
		su1 = su1_fn(point) if callable(su1_fn) else su1_fn
		s0v = s0v_fn(point) if callable(s0v_fn) else s0v_fn
		s1v = s1v_fn(point) if callable(s1v_fn) else s1v_fn
		ret=[0.0 for i in range(len(su0))]
		for K in range(len(ret)):
			ret[K] = ((1-u)*s0v[K] + u*s1v[K]+(1-v)*su0[K] + v*su1[K] +
			(1-u)*(1-v)*s0v[K] + (1-u)*v*s0v[K] + u*(1-v)*s1v[K] + u*v*s1v[K])
		return ret
	return map_fn
@}
%-------------------------------------------------------------------------------

%===============================================================================
\section{Bsplines}
%===============================================================================
The B-splines discussed in this section are called \emph{non-uniform}
because different spline segments may correspond to different
intervals in parameter space, unlike uniform B-splines.
The basis polynomials, and consequently the spline shape and the other
properties, are defined by a non-decreasing sequence of real
numbers
\[
t_0 \leq t_1 \leq\cdots\leq t_n,
\]
called the {\it knot sequence}.  Splines of this kind are also named
\emph{NUB-splines} in the remainder of this book,\footnote{Some authors
call them non-uniform non-rational B-splines.  We prefer to emphasize
that they are polynomial splines.} where the name stands for
Non-Uniform B-splines.

The knot sequence is used to define the basis polynomials which blend
the control points.  In particular, each subset of $k+2$ adjacent knot
values is used to compute a basis polynomial of degree $k$.  Notice
that some subsequent knots may coincide.  In this case we speak of
\emph{multiplicity} of the knots.

\paragraph{Note}\index{Splines!number of points and joints}

In non-uniform B-splines the number $n+1$ of {\em knot values} is
greater than the number $m+1$ of control points $\p{p}_0, \ldots,
\p{p}_m$.  In particular, the relation
\begin{equation}
	n = m+k+1,
	\label{eq:knotsNumber}
\end{equation}
where $k$ is the \emph{degree} of spline segments, must hold between
the number of knots and the number of control points.  The quantity $h
= k+1$ is called the \emph{order} of the spline.  It will be useful
when giving recursive formulas to compute the B-basis polynomials.
Let us remember, e.g., that a spline of order four is made of cubic
segments.

\paragraph{Non-uniform B-spline flexibility}
\index{Non-uniform B-splines!flexibility}

Such splines have a much greater flexibility than the uniform ones.
The basis polynomial associated with each control point may vary
depending on the subset of knots it depends on.  Spline segments may
be parametrized over intervals of different size, and even reduced to
a single point.  Therefore, the continuity at a joint may be reduced,
e.g.~from $C^{2}$ to $C^{1}$ to $C^{0}$ and even to none by suitably increasing the multiplicity
of a knot.

%-------------------------------------------------------------------------------
\subsection{Definitions}
%-------------------------------------------------------------------------------

\subsubsection{Geometric entities}

In order to fully understand the construction of a non-uniform B-spline, it may
be useful to recall the main inter-relationships among the 5 geometric
entities that enter the definition.

\paragraph{Control points} \hspace{-2mm}are denoted as $\p{p}_{i}$,
with $0\leq i\leq m$.  A non-uniform B-spline usually approximates the control
points.

\paragraph{Knot values} \hspace{-2mm}are denoted as $t_{i}$, with $0\leq i\leq
n$.  It must be $n = m+k+1$, where $k$ is the spline degree.
Knot values are used to define the B-spline polynomials. They also
define the join points (or joints) between adjacent spline segments.
When two consecutive knots coincide, the spline segment associated with
their interval reduces to a point.

\paragraph{Spline degree} \hspace{-2mm}is defined as the degree of the
B-basis functions which are combined with the control points.  The
degree is denoted as $k$.  It is connected to the spline order $h =
k+1$.  The most used non-uniform B-splines are either cubic or quadratic.  The
image of a linear non-uniform B-spline is a polygonal line.  The image of a
non-uniform B-spline of degree $0$ coincides with the sequence of control
points.

\paragraph{B-basis polynomials} \hspace{-2mm}are denoted as $B_{i,h}(t)$.  They are
univariate polynomials in the $t$ indeterminate, computed by using the
recursive formulas of Cox and de Boor.  The $i$ index is associated with
the first one of values in the knot subsequence
$(t_{i},t_{i+1},\ldots,t_{i+h})$ used to compute $B_{i,h}(t)$.  The
second index is called \emph{order} of the polynomial.

\paragraph{Spline segments} \hspace{-2mm}are defined as polynomial vector functions
of a single parameter.  Such functions are denoted as $\p{Q}_{i}(t)$,
with $k\leq i\leq m$.  A $\p{Q}_{i}(t)$ spline segment is obtained by a
combination of the $i$-th control point and the $k$ previous points
with the basis polynomials of order $h$ associated to the same
indices.  It is easy to see that the number of spline segments is
$m-K+1$.

%-------------------------------------------------------------------------------
\subsection{Computation of a B-spline mapping}
%-------------------------------------------------------------------------------

The B-spline mapping, i.e. the vector-valued polynomial to be mapped over a 1D domain
discretisation by the \texttt{larMap} operator, is computed by making reference to the
\texttt{pyplasm} implementation given by the \texttt{BSPLINE} contained in the
\texttt{fenvs.py} library in the \texttt{pyplasm} package.

\texttt{BSPLINE} is a third-order function, that must be ordinately applied to
\texttt{degree}, \texttt{knots}, and \texttt{controlpoints}.

%-------------------------------------------------------------------------------
\subsection{Domain computation}
%-------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
@D Domain decomposition for 1D bspline maps
@{""" Domain decomposition for 1D bspline maps """
def larDom(knots,tics=32):
	domain = knots[-1]-knots[0]
	return larIntervals([tics*int(domain)])([domain])
@}
%-------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
\subsection{Examples}
%-------------------------------------------------------------------------------

\paragraph{Two examples of B-spline curves using lar-cc}

%-------------------------------------------------------------------------------
@O test/py/splines/test08.py
@{""" Two examples of B-spline curves using lar-cc """
from larlib import *

controls = [[0,0],[-1,2],[1,4],[2,3],[1,1],[1,2],[2.5,1],[2.5,3],[4,4],[5,0]];
knots = [0,0,0,0,1,2,3,4,5,6,7,7,7,7]
bspline = BSPLINE(3)(knots)(controls)
obj = larMap(bspline)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))

controls = [[0,1],[1,1],[2,0],[3,0],[4,0],[5,-1],[6,-1]]
knots = [0,0,0,1,2,3,4,5,5,5]
bspline = BSPLINE(2)(knots)(controls)
obj = larMap(bspline)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))
@}
%-------------------------------------------------------------------------------

\paragraph{Bezier curve as a B-spline curve}

%-------------------------------------------------------------------------------
@O test/py/splines/test09.py
@{""" Bezier curve as a B-spline curve """
from larlib import *

controls = [[0,1],[0,0],[1,1],[1,0]]
bezier = larBezierCurve(controls)
dom = larIntervals([32])([1])
obj = larMap(bezier)(dom)
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))

knots = [0,0,0,0,1,1,1,1]
bspline = BSPLINE(3)(knots)(controls)
dom = larIntervals([100])([knots[-1]-knots[0]])
obj = larMap(bspline)(dom)
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))
@}
%-------------------------------------------------------------------------------

\paragraph{B-spline curve: effect of double or triple control points}

%-------------------------------------------------------------------------------
@O test/py/splines/test10.py
@{""" B-spline curve: effect of double or triple control points """
from larlib import *

controls1 = [[0,0],[2.5,5],[6,1],[9,3]]
controls2 = [[0,0],[2.5,5],[2.5,5],[6,1],[9,3]]
controls3 = [[0,0],[2.5,5],[2.5,5],[2.5,5],[6,1],[9,3]]
knots = [0,0,0,0,1,1,1,1]
bspline1 = larMap( BSPLINE(3)(knots)(controls1) )(larDom(knots))
knots = [0,0,0,0,1,2,2,2,2]
bspline2 = larMap( BSPLINE(3)(knots)(controls2) )(larDom(knots))
knots = [0,0,0,0,1,2,3,3,3,3]
bspline3 = larMap( BSPLINE(3)(knots)(controls3) )(larDom(knots))

VIEW(STRUCT( CAT(AA(MKPOLS)([bspline1,bspline2,bspline3])) +
	[POLYLINE(controls1)]) )
@}
%-------------------------------------------------------------------------------

\paragraph{Periodic B-spline curve}

%-------------------------------------------------------------------------------
@O test/py/splines/test11.py
@{""" Periodic B-spline curve """
from larlib import *

controls = [[0,1],[0,0],[1,0],[1,1],[0,1]]
knots = [0,0,0,1,2,3,3,3]				# non-periodic B-spline
bspline = BSPLINE(2)(knots)(controls)
obj = larMap(bspline)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))

knots = [0,1,2,3,4,5,6,7]				# periodic B-spline
bspline = BSPLINE(2)(knots)(controls)
obj = larMap(bspline)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))
@}
%-------------------------------------------------------------------------------

\paragraph{Effect of knot multiplicity on B-spline curve}

%-------------------------------------------------------------------------------
@O test/py/splines/test12.py
@{""" Effect of knot multiplicity on B-spline curve """
from larlib import *

points = [[0,0],[-1,2],[1,4],[2,3],[1,1],[1,2],[2.5,1]]
b1 = BSPLINE(2)([0,0,0,1,2,3,4,5,5,5])(points)
VIEW(STRUCT(MKPOLS( larMap(b1)(larDom([0,5])) ) + [POLYLINE(points)]))
b2 = BSPLINE(2)([0,0,0,1,1,2,3,4,4,4])(points)
VIEW(STRUCT(MKPOLS( larMap(b2)(larDom([0,5])) ) + [POLYLINE(points)]))
b3 = BSPLINE(2)([0,0,0,1,1,1,2,3,3,3])(points)
VIEW(STRUCT(MKPOLS( larMap(b3)(larDom([0,5])) ) + [POLYLINE(points)]))
b4 = BSPLINE(2)([0,0,0,1,1,1,1,2,2,2])(points)
VIEW(STRUCT(MKPOLS( larMap(b4)(larDom([0,5])) ) + [POLYLINE(points)]))
@}
%-------------------------------------------------------------------------------

TODO: extend biplane mapping to unconnected domain ... (remove BUG above)

%-------------------------------------------------------------------------------
\subsection{B-spline basis functions}
%-------------------------------------------------------------------------------

In mathematics, the support of a function is the set of points where the function is not zero-valued.
A spline is a sufficiently smooth polynomial function that is piecewise-defined, and possesses a high degree of smoothness at the places where the polynomial pieces connect (which are known as knots).

A B-spline, or Basis spline, is a spline function that has minimal support with respect to a given degree, smoothness, and domain partition. Any spline function of given degree can be expressed as a linear combination of B-splines of that degree. Cardinal B-splines have knots that are equidistant from each other. B-splines can be used for curve-fitting and numerical differentiation of experimental data.

In CAD and computer graphics, spline functions are constructed as linear combinations of B-splines with a set of control points.

\paragraph{Sampling of a set of B-splines}
Here we provide the code  for  the sampling of a set of B-splines of given degree, knot vector and number of control points.

%-------------------------------------------------------------------------------
@D Sampling of a set of B-splines
@{""" Sampling of a set of B-splines of given degree, knots and controls """
def BSPLINEBASIS(degree):
	def BSPLINE0(knots):
		def BSPLINE1(ncontrols):
			n = ncontrols-1
			m=len(knots)-1
			k=degree+1
			T=knots
			tmin,tmax=T[k-1],T[n+1]
			if len(knots)!=(n+k+1):
				raise Exception("Invalid point/knots/degree for bspline!")

			# de Boor coefficients
			def N(i,k,t):
				# Ni1(t)
				if k==1:
					if(t>=T[i] and t<T[i+1]) or(t==tmax and t>=T[i] and t<=T[i+1]):
						# i use strict inclusion for the max value
						return 1
					else:
						return 0
				# Nik(t)
				ret=0

				num1,div1= t-T[i], T[i+k-1]-T[i]
				if div1!=0: ret+=(num1/div1) * N(i,k-1,t)
				num2,div2=T[i+k]-t, T[i+k]-T[i+1]
				if div2!=0:  ret+=(num2/div2) * N(i+1,k-1,t)

				return ret

			# map function
			def map_fn(point):
				t=point[0]
				return [N(i,k,t) for i in range(n+1)]

			return map_fn
		return BSPLINE1
	return BSPLINE0
@}
%-------------------------------------------------------------------------------

\paragraph{Example}

The script below is used to display the graph of the whole set of basis splines
for a given degree, knot vector and number of control points. It may be interesting to note that
the value stored in \texttt{obj} is the LAR 2-model of a curve (look at \texttt{obj[1]}) embedded in
$n$-dimensional space, with $n=9$ (the number of contral points), where every coordinate provides the
discretised values of one of the blending functions, i.e.~the values of one B-spline basis function.

%-------------------------------------------------------------------------------
@D Drawing the graph of a set of B-splines
@{""" Drawing the graph of a set of B-splines """
if __name__=="__main__":

	knots = [0,0,0,1,1,2,2,3,3,4,4,4]
	ncontrols = 9
	degree = 2
	obj = larMap(BSPLINEBASIS(degree)(knots)(ncontrols))(larDom(knots))

	funs = TRANS(obj[0])
	var = AA(CAT)(larDom(knots)[0])
	cells = larDom(knots)[1]

	graphs =  [[TRANS([var,fun]),cells] for fun in funs]
	graph = STRUCT(CAT(AA(MKPOLS)(graphs)))
	VIEW(graph)
	VIEW(STRUCT(MKPOLS(graphs[0]) + MKPOLS(graphs[-1])))
@}
%-------------------------------------------------------------------------------

%===============================================================================
\section{Transfinite B-splines}
%===============================================================================

%-------------------------------------------------------------------------------
@D Transfinite B-splines
@{
def TBSPLINE(U):
	def TBSPLINE0(degree):
		def TBSPLINE1(knots):
			def TBSPLINE2(points_fn):

				n=len(points_fn)-1
				m=len(knots)-1
				k=degree+1
				T=knots
				tmin,tmax=T[k-1],T[n+1]

				# see http://www.na.iac.cnr.it/~bdv/cagd/spline/B-spline/bspline-curve.html
				if len(knots)!=(n+k+1):
					raise Exception("Invalid point/knots/degree for bspline!")

				# de boord coefficients
				def N(i,k,t):

					# Ni1(t)
					if k==1:
						if(t>=T[i] and t<T[i+1]) or (t==tmax and t>=T[i] and t<=T[i+1]):
							# i use strict inclusion for the max value
							return 1
						else:
							return 0

					# Nik(t)
					ret=0

					num1,div1= t-T[i], T[i+k-1]-T[i]
					if div1!=0: ret+=(num1/div1) * N(i,k-1,t)
					# elif num1!=0: ret+=N(i,k-1,t)

					num2,div2=T[i+k]-t, T[i+k]-T[i+1]
					if div2!=0:  ret+=(num2/div2) * N(i+1,k-1,t)
					# elif num2!=0: ret+=N(i,k-1,t)

					return ret

				# map function
				def map_fn(point):
					t=U(point)

					# if control points are functions
					points=[f(point) if callable(f) else f for f in points_fn]

					target_dim=len(points[0])
					ret=[0 for i in range(target_dim)];
					for i in range(n+1):
						coeff=N(i,k,t)
						for M in range(target_dim):
							ret[M]+=points[i][M]*coeff
					return ret

				return map_fn

			return TBSPLINE2
		return TBSPLINE1
	return TBSPLINE0
@}
%-------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
@O test/py/splines/test13.py
@{""" Periodic B-spline curve """
from larlib import *

controls = [[0,1],[0,0],[1,0],[1,1],[0,1]]
knots = [0,0,0,1,2,3,3,3]				# non-periodic B-spline
tbspline = TBSPLINE(S1)(2)(knots)(controls)
obj = larMap(tbspline)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))

knots = [0,1,2,3,4,5,6,7]				# periodic B-spline
tbspline = TBSPLINE(S1)(2)(knots)(controls)
obj = larMap(tbspline)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))
@}
%-------------------------------------------------------------------------------

\paragraph{Transfinite surface from Bezier control curves and periodic B-spline curve}

In the script below a simple example of Transfinite surface is generated, using 5
Bezier control curves and a periodic B-spline curve.

%-------------------------------------------------------------------------------
@O test/py/splines/test14.py
@{""" Transfinite surface from Bezier control curves and periodic B-spline curve """
from larlib import *

b1 = BEZIER(S1)([[0,1,0],[0,1,5]])
b2 = BEZIER(S1)([[0,0,0],[0,0,5]])
b3 = BEZIER(S1)([[1,0,0],[2,-1,2.5],[1,0,5]])
b4 = BEZIER(S1)([[1,1,0],[1,1,5]])
b5 = BEZIER(S1)([[0,1,0],[0,1,5]])
controls = [b1,b2,b3,b4,b5]
knots = [0,1,2,3,4,5,6,7]				# periodic B-spline
knots = [0,0,0,1,2,3,3,3]				# non-periodic B-spline
tbspline = TBSPLINE(S2)(2)(knots)(controls)
dom = larModelProduct([larDomain([10]),larDom(knots)])
dom = larIntervals([32,48],'simplex')([1,3])
obj = larMap(tbspline)(dom)
VIEW(STRUCT( MKPOLS(obj) ))
VIEW(SKEL_1(STRUCT( MKPOLS(dom) )))
@}
%-------------------------------------------------------------------------------

%===============================================================================
\section{NURBS}
%===============================================================================

Rational non-uniform B-splines are normally denoted as NURB splines or
simply as NURBS. These splines are very important for both graphics
and CAD applications. In particular:

\begin{enumerate}

\item
Rational curves and splines are invariant with respect to affine and
projective transformations.  Consequently, to transform or
project a NURBS it is sufficient to transform or project its
control points, leaving to the graphics hardware the task of sampling
or rasterizing the transformed curve.

\item
NURBS represent exactly the conic sections, i.e.~circles, ellipses,
parabol\ae, iperbol\ae. Such curves are very frequent in mechanical
CAD, where several shapes and geometric constructions are based on
such geometric primitives.

\item
Rational B-splines are very flexible, since (a) the available degrees
of freedom concern both degree, control points, knot values and
weights; (b) can be locally interpolant or approximant; (c) can
alternate spline segments with different degree; and (d)
different continuity at join points.

\item
They also allow for local variation of ``parametrization velocity", or
better, allow for modification of the norm of velocity vector along
the spline, defined as the derivative of the curve with respect to the
arc length.  For this purpose it is sufficient to properly modify the
knot sequence.  This fact allows easy modification of the sampling density
of spline points along segments with higher or lower curvature, while
maintaining the desired appearance of smoothness.

\end{enumerate}

As a consequence of their usefulness for applications, NURBS are
largely available when using geometric libraries or CAD kernels.

%-------------------------------------------------------------------------------
\subsection{Rational B-splines of arbitrary degree}
%-------------------------------------------------------------------------------

A rational B-spline segment $\v{R}_{i}(t)$ is defined as the
projection from the origin on the hyperplane $x_{d+1}=1$ of a
polynomial B-spline segment $\v{P}_{i}(u)$ in $\E^{d+1}$ homogeneous
space.

Using the same approach adopted when discussing rational B\'ezier
curves, where $\p{q}_{i} = (w_{i}\p{p}_{i}, w_{i})\in\E^{d+1}$ are the
$m+1$ homogeneous control points, the equation of the rational
B-spline segment of degree $k$ with $n+1$ knots, may be therefore
written as
\begin{equation}
    \p{R}_i(t) =
    \sum_{\ell=0}^k
    w_{i-\ell}\,\p{p}_{i-\ell}
    {B_{i-\ell,k+1}(t) \over w(t)}
 =
    \sum_{\ell=0}^k
    \p{p}_{i-\ell}
    N_{i-\ell,k+1}(t)
    \label{eq:NUBgeneriche1}
\end{equation}
with $ k\leq i\leq m$,  $t\in [t_{i}, t_{i+1})$, and
\[
w(t) = \sum_{\ell=0}^k
w_{i-\ell} B_{i-\ell,k+1}(t),
\]
where $N_{i,h}(t)$ is the non-uniform rational
B-basis function of initial value $t_{i}$ and order $h$.
A global representation of the NURB spline can be given, due to the
local support of the $N_{i,h}(t)$ functions, i.e.~to the fact that
they are zero outside the interval $[t_{i},t_{i+h})$. So:
\[
\p{R}(t) =  \bigcup_{i=k}^{m} \p{R}_i(t) =
\sum_{i=0}^{m}\p{p}_{i}\,N_{i,h}(t), \qquad t\in [t_{k},t_{m+1}).
\]

NURB splines can be computed as non-uniform B-splines by using homogeneous
control points, and finally by dividing the Cartesian coordinate
maps times the homogeneous one.  This approach will be used in
the NURBS implementation given later in this chapter.  A more
efficient and numerically stable variation of the Cox and de Boor
formula for the rational case is given by
Farin~\cite{Farin:88}, p.~196.

%-------------------------------------------------------------------------------
\subsection{Computation of a NURBS mapping}
%-------------------------------------------------------------------------------

The NURBS mapping, i.e. the vector-valued polynomial to be mapped over a 1D domain
discretisation by the \texttt{larMap} operator, is computed by making reference to the
\texttt{pyplasm} implementation given by the \texttt{RATIONALBSPLINE} contained in the
\texttt{fenvs.py} library in the \texttt{pyplasm} package.

\texttt{RATIONALBSPLINE} is a third-order function, that must be ordinately applied to
\texttt{degree}, \texttt{knots}, and \texttt{controlpoints}.

%-------------------------------------------------------------------------------
@D NURBS and TNURBS mapping definition
@{""" Alias for the pyplasm definition (too long :o) """
NURBS = RATIONALBSPLINE     # in pyplasm
TNURBS = TRATIONALBSPLINE	 # in lar-cc (only)
@}
%-------------------------------------------------------------------------------

\paragraph{Transfinite NURBS interface}

The \texttt{TNURBS} function, that is by definite an alias to \texttt{TRATIONALBSPLINE},
is used to define a NURBS surface by blending 1D curves, or a NURBS solid by blending 2D surfaces,
and so on. For an example of use, just look at the test example \texttt{test05.py},
where a cylinder surface with unit radius and height is generated by blending 9 vertical unit segments
via the unit 1D circle as NURBS curve.

%-------------------------------------------------------------------------------
@D Transfinite NURBS interface
@{""" Transfinite NURBS """
def TRATIONALBSPLINE(U):
	def TRATIONALBSPLINE0(degree):
		def TRATIONALBSPLINE1(knots):
			def TRATIONALBSPLINE2(points):
				bspline=TBSPLINE(U)(degree)(knots)(points)
				def map_fn(point):
					ret=bspline(point)
					last=ret[-1]
					if last!=0: ret=[value/last for value in ret]
					ret=ret[:-1]
					return ret
				return map_fn
			return TRATIONALBSPLINE2
		return TRATIONALBSPLINE1
	return TRATIONALBSPLINE0
@}
%-------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
\subsection{Examples}
%-------------------------------------------------------------------------------

\begin{figure}[htbp] %  figure placement: here, top, bottom, or page
   \centering
   \includegraphics[width=0.33\linewidth]{images/nurbs-circle}
   \caption{Circle 2D \emph{exactly} implemented as a 9-point NURBS curve.}
   \label{fig:example}
\end{figure}

\paragraph{Circle implemented as 9-point NURBS curve}

%-------------------------------------------------------------------------------
@O test/py/splines/test13.py
@{""" Circle implemented as 9-point NURBS curve """
from larlib import *

knots = [0,0,0,1,1,2,2,3,3,4,4,4]
_p=math.sqrt(2)/2.0
controls = [[-1,0,1], [-_p,_p,_p], [0,1,1], [_p,_p,_p],[1,0,1], [_p,-_p,_p],
			[0,-1,1], [-_p,-_p,_p], [-1,0,1]]
nurbs = NURBS(2)(knots)(controls)
obj = larMap(nurbs)(larDom(knots))
VIEW(STRUCT( MKPOLS(obj) + [POLYLINE(controls)] ))
@}
%-------------------------------------------------------------------------------

\paragraph{Cylinder implemented as transfinite NURBS surface (with Bezier control curves)}

The transfinite cylinder surface generated below has both radius and height equal to 1.

%-------------------------------------------------------------------------------
@O test/py/splines/test15.py
@{""" Cylinder implemented as 9-point NURBS curve """
from larlib import *

knots = [0,0,0,1,1,2,2,3,3,4,4,4]
_p=math.sqrt(2)/2.0
controls = [[-1,0,1], [-_p,_p,_p], [0,1,1], [_p,_p,_p],[1,0,1], [_p,-_p,_p],
			[0,-1,1], [-_p,-_p,_p], [-1,0,1]]
c1 = BEZIER(S1)([[-1,0,0,1],[-1,0,1,1]])
c2 = BEZIER(S1)([[-_p,_p,0,_p],[-_p,_p,_p,_p]])
c3 = BEZIER(S1)([[0,1,0,1],[0,1,1,1]])
c4 = BEZIER(S1)([[_p,_p,0,_p],[_p,_p,_p,_p]])
c5 = BEZIER(S1)([[1,0,0,1],[1,0,1,1]])
c6 = BEZIER(S1)([[_p,-_p,0,_p],[_p,-_p,_p,_p]])
c7 = BEZIER(S1)([[0,-1,0,1],[0,-1,1,1]])
c8 = BEZIER(S1)([[-_p,-_p,0,_p],[-_p,-_p,_p,_p]])
c9 = BEZIER(S1)([[-1,0,0,1],[-1,0,1,1]])
controls = [c1,c2,c3,c4,c5,c6,c7,c8,c9]

tnurbs = TNURBS(S2)(2)(knots)(controls)
dom = larModelProduct([larDomain([10]),larDom(knots)])
dom = larIntervals([10,36],'simplex')([1,4])
obj = larMap(tnurbs)(dom)
VIEW(STRUCT( MKPOLS(obj) ))
@}
%-------------------------------------------------------------------------------

%===============================================================================
\section{Computational framework}
%===============================================================================
\subsection{Exporting the library}
%-------------------------------------------------------------------------------
@O larlib/larlib/splines.py
@{""" Mapping functions and primitive objects """
from larlib import *

@< Tensor product surface patch @>
@< Bilinear surface patch @>
@< Biquadratic surface patch @>
@< Bicubic surface patch @>
@< Multidimensional transfinite Bernstein-Bezier Basis @>
@< Multidimensional transfinite B\'ezier @>
@< Transfinite Coons patches @>
@< Domain decomposition for 1D bspline maps @>
@< Sampling of a set of B-splines @>
@< Drawing the graph of a set of B-splines @>
@< Transfinite B-splines @>
@< Transfinite NURBS interface @>
@< NURBS and TNURBS mapping definition @>
@}

%===============================================================================
\section{Examples}
%===============================================================================

\paragraph{Examples of larBernsteinBasis generation}

%-------------------------------------------------------------------------------
@d Examples of larBernsteinBasis
@{larBernsteinBasis(S1)(3)
""" [<function __main__.map_fn>,
	<function __main__.map_fn>,
	<function __main__.map_fn>,
	<function __main__.map_fn>] """
larBernsteinBasis(S1)(3)[0]
""" <function __main__.map_fn> """
larBernsteinBasis(S1)(3)[0]([0.0])
""" 1.0 """
@}
%-------------------------------------------------------------------------------

\paragraph{Graph of Bernstein-Bezier basis}

%-------------------------------------------------------------------------------
@O  test/py/splines/test04.py
@{""" Graph of Bernstein-Bezier basis """
from larlib import *

def larBezierBasisGraph(degree):
	basis = larBernsteinBasis(S1)(degree)
	dom = larDomain([32])
	graphs = CONS(AA(larMap)(DISTL([S1, basis])))(dom)
	return graphs

graphs = larBezierBasisGraph(4)
VIEW(STRUCT( CAT(AA(MKPOLS)( graphs )) ))
@}
%-------------------------------------------------------------------------------

\paragraph{Some examples of curves}

%-------------------------------------------------------------------------------
@O test/py/splines/test01.py
@{""" Example of Bezier curve """
from larlib import *

controlpoints = [[-0,0],[1,0],[1,1],[2,1],[3,1]]
dom = larDomain([32])
obj = larMap(larBezierCurve(controlpoints))(dom)
VIEW(STRUCT(MKPOLS(obj)))

obj = larMap(larBezier(S1)(controlpoints))(dom)
VIEW(STRUCT(MKPOLS(obj)))
@}
%-------------------------------------------------------------------------------

\paragraph{Transfinite cubic surface}

%-------------------------------------------------------------------------------
@O test/py/splines/test02.py
@{""" Example of transfinite surface """
from larlib import *

dom = larDomain([20],'simplex')
C0 = larBezier(S1)([[0,0,0],[10,0,0]])
C1 = larBezier(S1)([[0,2,0],[8,3,0],[9,2,0]])
C2 = larBezier(S1)([[0,4,1],[7,5,-1],[8,5,1],[12,4,0]])
C3 = larBezier(S1)([[0,6,0],[9,6,3],[10,6,-1]])
dom2D = larExtrude1(dom,20*[1./20])
obj = larMap(larBezier(S2)([C0,C1,C2,C3]))(dom2D)
VIEW(STRUCT(MKPOLS(obj)))
@}
%-------------------------------------------------------------------------------

\paragraph{Coons patch interpolating 4 boundary curves}

%-------------------------------------------------------------------------------
@O test/py/splines/test03.py
@{""" Example of transfinite Coons surface """
from larlib import *

Su0 = larBezier(S1)([[0,0,0],[10,0,0]])
Su1 = larBezier(S1)([[0,10,0],[2.5,10,3],[5,10,-3],[7.5,10,3],[10,10,0]])
Sv0 = larBezier(S2)([[0,0,0],[0,0,3],[0,10,3],[0,10,0]])
Sv1 = larBezier(S2)([[10,0,0],[10,5,3],[10,10,0]])
dom = larDomain([20])
dom2D = larExtrude1(dom, 20*[1./20])
out = larMap(larCoonsPatch([Su0,Su1,Sv0,Sv1]))(dom2D)
VIEW(STRUCT(MKPOLS(out)))
@}
%-------------------------------------------------------------------------------

\paragraph{Bilinear tensor product patch}

%-------------------------------------------------------------------------------
@O test/py/splines/test05.py
@{""" Example of bilinear tensor product surface patch """
from larlib import *

controlpoints = [
	[[0,0,0],[2,-4,2]],
	[[0,3,1],[4,0,0]]]
dom = larDomain([20])
dom2D = larExtrude1(dom, 20*[1./20])
mapping = larBilinearSurface(controlpoints)
patch = larMap(mapping)(dom2D)
VIEW(STRUCT(MKPOLS(patch)))
@}
%-------------------------------------------------------------------------------

\paragraph{Biquadratic tensor product patch}

%-------------------------------------------------------------------------------
@O test/py/splines/test06.py
@{""" Example of bilinear tensor product surface patch """
from larlib import *

controlpoints=[
	[[0,0,0],[2,0,1],[3,1,1]],
	[[1,3,-1],[2,2,0],[3,2,0]],
	[[-2,4,0],[2,5,1],[1,3,2]]]
dom = larDomain([20])
dom2D = larExtrude1(dom, 20*[1./20])
mapping = larBiquadraticSurface(controlpoints)
patch = larMap(mapping)(dom2D)
VIEW(STRUCT(MKPOLS(patch)))
@}
%-------------------------------------------------------------------------------

\paragraph{Bicubic tensor product patch}

%-------------------------------------------------------------------------------
@O test/py/splines/test07.py
@{""" Example of bilinear tensor product surface patch """
from larlib import *

controlpoints=[
	[[ 0,0,0],[0 ,3  ,4],[0,6,3],[0,10,0]],
	[[ 3,0,2],[2 ,2.5,5],[3,6,5],[4,8,2]],
	[[ 6,0,2],[8 ,3 , 5],[7,6,4.5],[6,10,2.5]],
	[[10,0,0],[11,3  ,4],[11,6,3],[10,9,0]]]
dom = larDomain([20])
dom2D = larExtrude1(dom, 20*[1./20])
mapping = larBicubicSurface(controlpoints)
patch = larMap(mapping)(dom2D)
VIEW(STRUCT(MKPOLS(patch)))
@}
%-------------------------------------------------------------------------------

%===============================================================================
\appendix
\section{Utility functions}
%===============================================================================

\bibliographystyle{amsalpha}
\bibliography{splines}

\end{document}


\subsection{Nonlinear Invariant Cryptanalysis}

\renewcommand{\TITLE}{\it Nonlinear Invariant Cryptanalysis}

\begin{frame}[t]
\vspace{1.25cm}
\CurTitle{}

\Center{
    \textcolor{blue}{Properties} of messages that are \textcolor{green!70!black}{preserved} through encryption
}

\vspace{-0.5cm}

\only<2>{\Center{\includegraphics[height=3cm]{invariant1.pdf}}}
\only<3>{\Center{\includegraphics[height=3cm]{invariant2.pdf}}}
\only<4>{\Center{\includegraphics[height=3cm]{invariant3.pdf}}}
\only<5>{\Center{\includegraphics[height=3cm]{invariant4.pdf}}}
\only<6>{\Center{\includegraphics[height=3cm]{invariant5.pdf}}}
\end{frame}

\begin{frame}[t]
\CreditsTikz{}
\CurTitle{}

\Center{
\hspace*{1.75cm}\includegraphics[width=0.85\linewidth]{norx_sponge_serial_v3.pdf}
}

\Block{4cm,4cm}{5cm}{
    \includegraphics[width=2.5cm]{norx_G_col.pdf}
}
\Block{8cm,4cm}{5cm}{
    \includegraphics[width=4.5cm]{norx_G_diag.pdf}
}

\vspace{3.75cm}

\Center{
    \Large Analysis of the NORX Authenticated Encryption
}
\end{frame}

\begin{frame}[t]
\CurTitle{}

\vspace{1cm}

$$
\begin{bmatrix}
0 & 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1 & 1 & 1 \\
0 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 1 & 1 & 1 \\
1 & 0 & 1 & 1 & 0 & 1 & 1 & 0 & 0 & 1 & 1 \\
1 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\
1 & 1 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 1 \\
\end{bmatrix}
$$

\vspace{0.5cm}

\Center{
    \Large Theoretical study of linear layers \\
    preserving degree-$d$ invariants
}
\end{frame}

\begin{frame}[t]
    \CurTitle{}

    \nocitepartii{mybibNORX}
    \nocitepartii{mybibNLI}
    \bibliographystylepartii{unsrt}
    \Block{3cm,2.5cm}{10cm}{
        \bibliographypartii{mybiblio.bib}
    }
\end{frame}


% $RCSfile: timestepping.tex,v $
% $Revision: 1.5 $
% $Author: langer $
% $Date: 2008-06-17 15:26:24 $

\documentclass[onecolumn,prl,floatfix,12pt]{revtex4}

\newcommand{\M}{\textbf{M}}
\newcommand{\C}{\textbf{C}}
\newcommand{\K}{\textbf{K}}
\newcommand{\D}{\textbf{D}}
\newcommand{\f}{\textbf{f}}
\newcommand{\fbarstar}{\textbf{$\bar{\textbf{f}}$*}}
\newcommand{\half}{{1\over2}}

\begin{document}

\title{Notes on Time Stepping for OOF2}

\author{OOF Team}

\maketitle

\section{Zienkiewicz \& Taylor's SS22 Algorithm}

The equation to be solved is
\begin{equation}
  \label{eq:ode}
  \M \ddot a + \C \dot a + \K a + \f = 0
\end{equation}
where $a$ is a vector of values and \M, \C, and \K\ are constants.

Assume we know $a$ and $\dot a$ at $t=t_n$ and we want to find them at
$t=t_{n+1} = t_n + \Delta t$.  Expand in a Taylor series in $\tau =
t-t_n$:
\begin{equation}
  \label{eq:taylor}
  a = a_n + \tau\dot a_n + \half\tau^2\alpha_n
\end{equation}
$\alpha_n$ is a vector of unknown values.
Multiply (\ref{eq:ode}) by a weighting function $W(\tau)$ and integrate
over the interval:
\begin{equation}
  \label{eq:weighted}
  0=\int_0^{\Delta t}d\tau\, \left[\M \ddot a + \C \dot a + \K a + \f\right]
\end{equation}
Insert (\ref{eq:taylor})
\begin{equation}
  \label{eq:w1}
0 = \left[\int W(\tau)d\tau\right]^{-1}\int W(\tau)\left(\M \alpha_n + \C
  (\dot a_n + \tau \alpha_n) + \K(a_n + \tau\dot a_n + \half
  \tau^2\alpha_n)+ \f
 \right) d\tau
\end{equation}

Since the matrices are constant, we can pull them out of the
integral, so if we define
\begin{equation}
  \label{eq:theta}
  \Delta t^k \theta_k = {\int_0^{\Delta t}W(\tau)\tau^k\,d\tau\over
    \int_0^{\Delta t}W(\tau)\,d\tau}
\end{equation}
then (\ref{eq:w1}) becomes
\begin{eqnarray}
  0 &=& \M\alpha_n + \C(\dot a_n + \theta_1\Delta t\alpha_n) + \K (a_n +
  \theta_1 \Delta t\dot a_n + \half\Delta t^2 \theta_2\alpha_n) +
  \bar \f \label{eq:w2} \\
&=& \left(\M + \theta_1\Delta t\C + \half\theta_2\Delta t^2\K\right) \alpha_n
 + \left(\C + \theta_1\Delta t\K\right)\dot a_n + \K a_n  + \bar \f \label{eq:w3}
\end{eqnarray}
where
\begin{equation}
  \label{eq:fbar}
  \bar \f = {\int_0^{\Delta t} W(\tau)f(t_n+\tau)\,d\tau \over
    \int_0^{\Delta t}W(\tau)\,d\tau}
\end{equation}
(\ref{eq:w3}) is a matrix equation which can be solved for $\alpha_n$.
Then
\begin{eqnarray}
  \label{eq:anp1}
  a_{n+1} &=& a_n + \Delta t\dot a_n + \half\Delta t^2\alpha_n \\
  \label{eq:adnp1}
  \dot a_{n+1} &=& \dot a_n + \Delta t\alpha_n
\end{eqnarray}

Z\&T give no guidance on how to compute $\bar\f$ in (\ref{eq:w3})
except to mention that if we assume $\f(t)$ to be linear in $t$ over
the (short) interval $\Delta t$ (see below) then
\begin{equation}
  \label{eq:fbar2}
  \bar \f = (1-\theta_1)\f(t_n) + \theta_1\f(t_{n+1})
\end{equation}
which is probably a reasonable approximation.

If $\M=0$, the equation is a first order ODE in disguise.  The method
still works as long as we choose the right initial value for $\dot
a_0$.  Just set $\Delta t=0$ and $\M=0$ in (\ref{eq:w3}) to get
\begin{equation}
  \label{eq:a0}
  \dot a_0 = -\C^{-1}(\K a_0 + \bar\f).
\end{equation}

\section{Nonlinear generalization of SS22}

If \M, \C, or \K\ are functions of the variables $a$ or $t$, we can
make progress by assuming that they vary linearly over the interval
$\Delta t$, like this:
\begin{equation}
  \label{eq:Mexp}
  \M(\tau) = \M_n + {\tau\over\Delta t}(\M_{n+1} - \M_n)
\end{equation}
where $\M_n$ means $\M(t_n, a_n)$.  The \M\ terms in (\ref{eq:w1})
become
\begin{equation}
  \label{eq:m1}
  \left[\int W(\tau)d\tau\right]^{-1}\int W(\tau)\M\alpha_n\,d\tau =
  (1-\theta_1)\M_n\alpha_n + \theta_1\M_{n+1}\alpha_n
\end{equation}
In the linear system, where $\M_n = \M_{n+1} = \M$, this reduces to
$\M\alpha_n$, in agreement with (\ref{eq:w3}).

The numerator of the \C\ terms in (\ref{eq:w1}) becomes
\begin{eqnarray}
  \lefteqn{\int W(\tau)\C(\dot a_n + \tau\alpha_n)\,d\tau}\nonumber \\
  &&= \int W(\tau)\left(\C_n + {\tau\over\Delta t}(\C_{n+1} - \C_n)\right)
  (\dot a_n + \tau\alpha_n)\,dt \\
&&= \int W(\tau)\left[\C_n\dot a_n +
  {\tau\over\Delta t}(\C_{n+1}-\C_n)\dot a_n
  + \C_n\tau\alpha_n + {\tau^2\over\Delta t}(\C_{n+1}-\C_n)\alpha_n\right]\, dt
\end{eqnarray}
Use (\ref{eq:theta}) and restore the denominator to get
\begin{eqnarray}
  &=& \C_n\dot a_n + \theta_1(\C_{n+1}-\C_n)\dot a_n +
  \Delta t\theta_1\C_n\alpha_n + \Delta t\theta_2(\C_{n+1}-\C_n)\alpha_n \\
  &=&
  \label{eq:Cexp}
  \Delta t\left[(\theta_1-\theta_2)\C_n + \theta_2\C_{n+1}\right]\alpha_n
  + \left[(1-\theta_1)\C_n+ \theta_1\C_{n+1}\right]\dot a_n
\end{eqnarray}
In the linear case where $\C_{n+1} = \C_n = \C$, this reduces to
$\Delta t\theta_1\C\alpha_n + \C\dot a_n$, also in agreement with
(\ref{eq:w3}).

The numerator of the \K\ terms in (\ref{eq:w1}) becomes
\begin{eqnarray}
  \lefteqn{\int W(\tau)\K(a_n + \tau\dot a_n + \half\tau^2\alpha_n)}\nonumber \\
  &&= \int W(\tau)
  \left[\K_n + {\tau\over\Delta t} (\K_{n+1} - \K_n)\right]
    (a_n + \tau\dot a_n + \half\tau^2\alpha_n)
\end{eqnarray}
Including the denominator gives
\begin{eqnarray}
  \label{eq:Kexp}
  &=& \left[(1-\theta_1)\K_n + \theta_1\K_{n+1}\right]a_n
  + \left[(\theta_1-\theta_2)\K_n + \theta_2\K_{n+1}\right]\Delta t\dot a_n\\
  &&\qquad +\half \left[(\theta_2-\theta_3)\K_n + \theta_3\K_{n+1}\right]
  \Delta t^2\alpha_n \nonumber
\end{eqnarray}
When $\K_n = \K_{n+1}=\K$, this reduces to $\K a_n + \theta_1\Delta
t\K\dot a_n + \half\theta_2\Delta t^2\K\alpha_n$, in agreement with
(\ref{eq:w3}).

Combining (\ref{eq:Kexp}), (\ref{eq:Cexp}), and (\ref{eq:Mexp}), we
get
\begin{equation}
  \label{eq:nlsummary}
  0 = \textbf{M*}\alpha_n + \textbf{C*}\dot a_n + \textbf{K*}a_n + \fbarstar
\end{equation}
where
\begin{eqnarray}
  \textbf{M*} &=&
    (1-\theta_1)\M_n + \theta_1\M_{n+1}
    + \Delta t\left[(\theta_1-\theta_2)\C_n + \theta_2\C_{n+1}\right]
    \label{eq:Mstar} \\
    && \nonumber\qquad + \half\Delta t^2 \left[
      (\theta_2-\theta_3)\K_n + \theta_3\K_{n+1} \right]\\
    \textbf{C*} &=& (1-\theta_1)\C_n + \theta_1\C_{n+1}
    + \Delta t\left[(\theta_1-\theta_2)\K_n + \theta_2\K_{n+1}\right]
    \label{eq:Cstar}\\
    \textbf{K*} &=& (1-\theta_1)\K_n + \theta_1\K_{n+1}
    \label{eq:Kstar} \\
    \fbarstar &=& (1-\theta_1)\f_n + \theta_1\f_{n+1} \label{eq:fstar}
\end{eqnarray}
(\ref{eq:nlsummary}) is a matrix equation which may be solved for
$\alpha_n$, which then determines $a_{n+1}$ and $\dot a_{n+1}$ via
(\ref{eq:anp1}) and (\ref{eq:adnp1}).  Since $\M_{n+1}$, $\C_{n+1}$,
$\K_{n+1}$, and $\f_{n+1}$ may depend on $a_{n+1}$,
(\ref{eq:nlsummary}) is non-linear and must be solved iteratively,
probably with Picard iteration.

It's likely that stability requires that $\theta_i\ge\half$ for
$i=1,2,3$.

\section{The Numerical Recipes Method}

I'm calling this the Numerical Recipes Method because it's basically
the only way that NR suggests handling second order time derivatives.
It's not meant to imply that NR invented it.  Surprisingly, Z\&T
\textit{don't} mention this method.

In (\ref{eq:ode}), let
\begin{equation}
  \label{eq:y}
  y \equiv \D^{-1} \dot a
\end{equation}
where $\D$ is an arbitrary nonsingular matrix.  Then we have two
\textit{first} order ODEs:
\begin{eqnarray}
  \label{eq:ode2a}
  \M\D\dot y + \C\D y + \K a + \f &=& 0 \\
  \label{eq:ode2b}
  \dot a - \D y &=& 0
\end{eqnarray}
If we define a new vector that includes the degrees of freedom ($a$)
and their derivatives ($y$)
\begin{equation}
  \label{eq:u}
  u = \left[\begin{array}{c} a\\y \end{array} \right]
\end{equation}
then the equations can be written as
\begin{equation}
  \label{eq:ode3}
  \tilde\M \dot u + \tilde\K u + \tilde f = 0
\end{equation}
where
\begin{equation}
  \label{eq:tildeM}
  \tilde\M = \left[\begin{array}{cc}
      0 & \M\D \\
      \mathcal{I} & 0
 \end{array}\right],
\end{equation}
\begin{equation}
  \label{eq:tildeK}
  \tilde\K = \left[\begin{array}{cc}
      \K & \C\D \\
      0 & -\D
    \end{array}\right],
\end{equation}
and
\begin{equation}
  \label{eq:tildef}
  \tilde f =  \left[\begin{array}{c} \f \\ 0 \end{array}\right]
\end{equation}
If we choose $\D\approx\M^{-1}$, then $\tilde\M$ should be well
behaved. (\ref{eq:ode3}) can be solved with a number of different
methods, such as forward and backward Euler, Runge-Kutta,
\textit{etc.}

\end{document}


\documentclass[preprint, 11pt]{sigplanconf}

\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{float}
\newcommand{\cL}{{\cal L}}
\newcommand{\concat}{\ensuremath{+\!\!\!\!+\,}}
\begin{document}

\special{papersize=8.5in,11in}
\setlength{\pdfpageheight}{\paperheight}
\setlength{\pdfpagewidth}{\paperwidth}

\titlebanner{McGill University COMP527 Winter2016 final project}
\preprintfooter{Review and Test Cases for \textsc{Myth} by \citet{osera2015type}}

\title{Example-directed Program Synthesis}
\subtitle{Review and Test Cases}

\authorinfo{Qi Nan Jin - 260531346}
           {McGill University}
           {qi.jin@mail.mcgill.ca}

\maketitle

\begin{abstract}
This project closely reviews the concept of example-directed program synthesis with a main focus on the new synthesis language $\lambda_{syn}$ developed by \citet{osera2015type}, as well as the associated artifact: \textsc{Myth}. It provides a theoretical review of the underlying concepts, a reproducibility test to the results and a sensitivity test of the synthesis language with respect to example specifications. It also proposes some improvements and additions to the existing \textsc{Myth} artifact.\end{abstract}\\

\terms
$\lambda_{syn}$, \textsc{Myth}\\

\keywords
Program synthesis, Example-directed\\

\section{Introduction}\label{sec-intr}

For decades, program synthesis has been an active and interesting area of research for its promising potential applications \cite{Basin2004}. Since the early works of \citet{green1969application}, as well as \citet{manna1971toward}, a close link has been established between program synthesis and formal deduction systems with heuristics. The underlying relationship between logical frameworks and programs makes program synthesis a particularly interesting topic in both computer science and logics. \\

In the recent years, more attentions have been attributed to the development of example-directed program synthesis. The ideal of example specifications can be related back to early works include \citet{freeman1991refinement}, which introduces the concept of refinement types. A recent paper by \citet{osera2015type} introduces a new method for type-and-example-directed program synthesis that claims to match or outperform existing “gold-standard” methods. \\

In this project, a theoretical review of the concept of program synthesis will be provided, leading to a detailed examination of the new method by \citet{osera2015type}, as well as the emerging artifact, \textsc{Myth}. \\

\section{Theory}\label{sec-theo}

\subsection{Program Synthesis in General}\label{sec-prog}

Works in constructive mathematics from as early as the 1930s \cite{kolmogorov1932theory}\cite{kreitz1998program} laid foundation in the field of program synthesis, by suggesting the parallel between programs as proofs. With the appearance of automatic theorem provers, program synthesizers emerged shortly thereafter\cite{kreitz1998program}. \\

In its early stage, program synthesis focuses mainly on proof search, based on early works of \citet{green1969application}, as well as \citet{manna1971toward}. The method builds upon the idea that corresponding proof of the specification statement is constructive, for which the steps can be directly associated to methods to construct the program. This method mainly relies on the construction of an extended $\lambda$-calculus, following the Curry-Howard Isomorphism between proofs and terms \cite{curry1972combinatory} \cite{tait1967intensional}.\\

A second branch of program synthesis quickly emerged in the late 1970s based on program transformation \cite{burstall1977transformation}, which usually proceeds by translating the output-condition step-by-step, into logically equivalent or stronger formula \cite{kreitz1998program}. Different branches of possible optimizations methods for transformational synthesis include Partial evaluation \cite{bjorner1988partial}, Finite differencing \cite{paige1982finite}, etc.\\

\subsection{Example-directed program synthesis}\label{sec-exam}

Example-directed program synthesis aims to provide concrete input-output examples as extra information in the specification in a proof-search based program synthesis. Based on recent work from \citet{frankle2016example}, examples can be interpreted as refinement types, first studies by Freeman and Pfenning \cite{freeman1991refinement}\cite{pfenning1993refinement}. A parallel can be drown between the three fundamental types in the refinement-type system and the input-output specifications. More specifically, the input/output pairs can be identified as singleton types. The functions mapping the input type to the output type can be identified as function/arrow types. Finally, multiple input-output examples used in conjunction can, obviously, identified as the conjunction type in the refinement-type system.\\

The work of \citet{osera2015type}, builds on this idea and formalizes a synthesis languague: $\lambda_{syn}$, as shown in Figure \ref{fig-lambdasyn}. \\

\begin{figure}[!ht]
  \begin{center}
    \begin{tabular}{lrl}
            $\tau$    & ::=    & $\tau$ $\mid$ $\tau_{1} \rightarrow \tau_{2}$ \\
            $e$       & ::=    & $x$ $\mid$ $C(e_{1},..,e_{k})$ $\mid$ $e_{1}$ $e_{2}$ \\
                      & $\mid$ & $\mathrm{fix} \, f(x:\tau_{1}):\tau_{2}=e$ $\mid$ $pf$ \\
                      & $\mid$ & $\mathrm{match}\, e \, \mathrm{ with } \, p_{1} \rightarrow e_{1}$ $\mid$ .. $\mid$ $p_{m} \rightarrow e_{m}$ \\
            $p$       & ::=    & $C(x_{1},..,x_{k})$ \\
            $u,v$     & ::=    & $C(v_{1},..,v_{k})$ $\mid$ $\mathrm{fix} \, f(x:\tau_{1}):\tau_{2}=e$ $\mid$ $pf$ \\
            $ex$      & ::=    & $C(ex_{1},..,ex_{k})$ $\mid$ $pf$ \\
            $pf$      & ::=    & $v_{1} \Rightarrow ex_{1}$ $\mid$ .. $\mid$ $v_{m} \Rightarrow ex_{m}$ \\
            $E$       & ::=    & $x$ $\mid$ $E\,I$ \\
            $I$       & ::=    & $E$ $\mid$ $C(I_{1},..,I_{k})$ $\mid$ $\mathrm{fix} \, f(x:\tau_{1}):\tau_{2}=I$ \\
                      & $\mid$ & $\mathrm{match}\, E \, \mathrm{ with } \, p_{1} \rightarrow I_{1}$ $\mid$ .. $\mid$ $p_{m} \rightarrow I_{m}$ \\
            $\Gamma$  & ::= & $\cdot$ $\mid$ $x$ : $\tau,\Gamma$ \\
            $\Sigma$  & ::= & $\cdot$ $\mid$ $C$ : $\tau_{1} * .. * \tau_{n} \rightarrow T,\Sigma$ \\

            $\sigma$  & ::= & $\cdot$ $\mid$ $[v/x]\sigma$ \\
            $X$       & ::= & $\cdot$ $\mid$ $\sigma \mapsto ex \concat X$
    \end{tabular} \\
  \end{center}
  \caption{$\lambda_{syn}$ syntax as formalized by \citet{osera2015type}.}
  \label{fig-lambdasyn}
\end{figure}

This language also includes full sets of typechecking rules, synthesis rules, auxiliary synthesis functions as well as evaluation and compatibility rules to form a complete framework. The details are exhaustively presented in the original paper \cite{osera2015type}.\\

The formalized synthesis language $\lambda_{syn}$ operates in two modes: generating type in elimiation form ($E$-guessing) and checking type in introduction form ($I$-refinement). This is achieved with the help of an new data structure named \em{refinement tree}. A \em{refinement tree} includes both goal nodes at which $E$-guessing happen, and refinement nodes at which the type-checking of $I$-refinement is performed. An iterative-deepening search is then applied to this structure to find a matching function that satisfies the input-output specifications \cite{osera2015type}.\\

\section{Implementation}\label{sec-impl}

The authors implemented a prototype synthesizer \textsc{Myth} under the \textsc{Ocaml} environment. The artifact uses a relatively naive but balanced search strategy to alternate between $E$-guessing and increasing the number of nodes in the refinement tree. The startegy is described in Figure \ref{fig-stra}.\\

\begin{figure}[!ht]
  \begin{center}
    \begin{verbatim}
        SynthSaturate 0.25
      ; SynthGrowMatches
      ; SynthSaturate 0.25
      ; SynthGrowMatches
      ; SynthSaturate 0.25
      ; SynthGrowScrutinees 5
      ; SynthSaturate 0.25
      ; SynthGrowMatches
      ; SynthSaturate 0.25
      ; SynthGrowScrutinees 5
      ; SynthSaturate 0.25
    \end{verbatim}
  \end{center}
  \caption{Synthesis strategy of \textsc{Myth} by \citet{osera2015type}.}
  \label{fig-stra}
\end{figure}

\noindent where \texttt{SynthSaturate} performs a round of $E$-guessing with the given time constraint, \texttt{SynthGrowMatches} increases the depth of  the search tree by one, and finally \texttt{SynthGrowScrutinees} increases the search scrutinee by a specified size. Here the scrutinee growth size is fixed at five (which corresponds to the size of a binary function application \texttt{f e1 e2}) \cite{osera2015type}. \\

Using a benchmark testing suite, \citet{osera2015type} state that \textsc{Myth} matches or outperforms previous methods by synthesizing more programs as well as achieving it in shorter time on average.\\

\section{Testing}\label{sec-test}

In the context of this review project, a straightforward reproducibility test is first performed, using the method and benchmark test set from the paper, to confirm the results published by the authors. A smaller test set is then applied with minor modifications in the input-output example specifications, in order to assess the artifact's sensitivity to example specifications. Finally, a few new test cases are constructed to test the limits of \textsc{Myth}.\\

\section{Results}\label{sec-resu}

\subsection{Reproducibility test}\label{sec-repr}

In order to confirm the results published from the paper, a straightforward reproducibility test is first performed using the benchmark test suite and the standard method discribed in the artifact \citet{osera2015type}. The simulation is run on a Linux laptop machine with an Intel i5-4210H @ 2.90GHz and 8Gb of ram. The result of this reproducibility test is presented in Figure \ref{fig-repr}. Synthesis times using minimal context in the reproducibility test are generally longer than, but comparable to the ones published in the paper. The longer synthesis time can be explained by the mismatch in the specs of the equipments.\\

One interesting finding is that for several tests, such as \texttt{list\_append} and \texttt{list\_nth}, the numbers of examples used is significantly lower than the ones reported in the paper. This is likely caused by the fact that the example set of these tests are further optimized since the paper was submitted.\\

\begin{figure}[!ht]
  \begin{center}
  \footnotesize
  \begin{tabular}{ccccc}
  \hline
  \textbf{Test} & \textbf{ \#Ex } & \textbf{ \#N } & \multicolumn{2}{c}{\textbf{Time-Min (s)}} \\
   &  &  & test & paper \\
  \hline
\multicolumn{5}{c}{\textbf{Booleans}} \\
bool\_band & 4 & 6 & 0.0032 & 0.002 \\
bool\_bor & 4 & 6 & 0.0034 & 0.001 \\
bool\_impl & 4 & 6 & 0.0036 & 0.002 \\
bool\_neg & 2 & 5 & 0.001 & 0 \\
bool\_xor & 4 & 9 & 0.0036 & 0.002 \\
  \hline
\multicolumn{5}{c}{\textbf{Lists}} \\
list\_append & 6 & 12 & 0.007 & 0.003 \\
list\_compress & 13 & 28 & 0.116 & 0.073 \\
list\_concat & 6 & 11 & 0.011 & 0.006 \\
list\_drop & 11 & 13 & 0.023 & 0.013 \\
list\_even\_parity & 7 & 13 & 0.0086 & 0.004 \\
list\_filter & 8 & 15 & 0.0282 & 0.067 \\
list\_fold & 9 & 13 & 0.1986 & 0.139 \\
list\_hd & 3 & 5 & 0.002 & 0.001 \\
list\_inc & 4 & 8 & 0.0016 & 0 \\
list\_last & 6 & 11 & 0.005 & 0 \\
list\_length & 3 & 8 & 0.002 & 0.001 \\
list\_map & 8 & 12 & 0.0184 & 0.008 \\
list\_nth & 13 & 16 & 0.025 & 0.013 \\
list\_pairwise\_swap & 7 & 19 & 0.0146 & 0.007 \\
list\_rev\_append & 5 & 13 & 0.017 & 0.011 \\
list\_rev\_fold & 5 & 12 & 0.013 & 0.007 \\
list\_rev\_snoc & 5 & 11 & 0.01 & 0.006 \\
list\_rev\_tailcall & 8 & 12 & 0.0098 & 0.004 \\
list\_snoc & 8 & 14 & 0.007 & 0.003 \\
list\_sort\_sorted\_insert & 7 & 11 & 0.013 & 0.008 \\
list\_sorted\_insert & 12 & 24 & 0.1908 & 0.122 \\
list\_stutter & 3 & 11 & 0.0018 & 0.001 \\
list\_sum & 3 & 8 & 0.004 & 0.002 \\
list\_take & 12 & 15 & 0.1406 & 0.112 \\
list\_tl & 3 & 5 & 0.0016 & 0.001 \\
  \hline
\multicolumn{5}{c}{\textbf{Natural Numbers}} \\
nat\_add & 9 & 11 & 0.004 & 0.002 \\
nat\_iseven & 4 & 10 & 0.0016 & 0.001 \\
nat\_max & 9 & 14 & 0.0196 & 0.011 \\
nat\_pred & 3 & 5 & 0.001 & 0.001 \\
  \hline
\multicolumn{5}{c}{\textbf{Trees}} \\
tree\_binsert & 20 & 31 & 0.4856 & 0.374 \\
tree\_collect\_leaves & 6 & 15 & 0.0266 & 0.016 \\
tree\_count\_leaves & 7 & 14 & 0.0162 & 0.008 \\
tree\_count\_nodes & 6 & 14 & 0.016 & 0.009 \\
tree\_inorder & 5 & 15 & 0.026 & 0.012 \\
tree\_map & 7 & 15 & 0.029 & 0.014 \\
tree\_nodes\_at\_level & 11 & 22 & 1.0388 & 1.093 \\
tree\_postorder & 9 & 32 & 1.4258 & 1.136 \\
tree\_preorder & 5 & 15 & 0.0188 & 0.009 \\
  \hline
  \end{tabular}
  \end{center}
  \caption{\textsc{Myth} benchmark suite reproducibility test results using minimal context, where \#Ex is the number of examples used, \#N is the size of the result}
  \label{fig-repr}
\end{figure}

\begin{figure}[!ht]
  \noindent \small Test case for \texttt{list\_nth}:
  \scriptsize
  \begin{verbatim}
type nat =
  | O | S of nat

type list =
  | Nil | Cons of nat * list

let list_nth : list -> nat -> nat |>
  { [] => ( 0 => 0
          | 1 => 0 )
  | [2] => ( 0 => 2
           | 1 => 0 )
  | [1; 2] => ( 0 => 1
              | 1 => 2 )
  | [1] => ( 0 => 1
           | 1 => 0 )
  | [2; 1] => ( 0 => 2
              | 1 => 1 )
  | [3; 2; 1] => ( 0 => 3
                 | 1 => 2
                 | 2 => 1 )
  } = ?
  \end{verbatim}

  \noindent \small Output with original input:
  \scriptsize
  \begin{verbatim}
let list_nth : list -> nat -> nat =
  let rec f1 (l1:list) : nat -> nat =
    fun (n1:nat) ->
      match n1 with
        | O -> (match l1 with
                  | Nil -> 0
                  | Cons (n2, l2) -> n2)
        | S (n2) -> (match l1 with
                       | Nil -> 0
                       | Cons (n3, l2) -> f1 l2 n2)
  in
    f1
;;
  \end{verbatim}

  \noindent \small Output with modified input, by changing the order of the last example to \texttt{[1; 2; 3]}:
  \scriptsize
  \begin{verbatim}
let list_nth : list -> nat -> nat =
  let rec f1 (l1:list) : nat -> nat =
    fun (n1:nat) ->
      match l1 with
        | Nil -> O
        | Cons (n2, l2) -> ( match f1 l2 O with
                           | O -> ( match n1 with
                                  | O -> n2
                                  | S (n3) -> O)
                           | S (n3) -> ( match n1 with
                                       | O -> n2
                                       | S (n4) -> S (n3)))
  in
    f1
;;
  \end{verbatim}
  \caption{Difference in synthesized program given slightly modified example.}
  \label{fig-sensitivity}
\end{figure}

\subsection{Sensitivity test}\label{sec-sens}

Several test cases are slightly modified by changing the order in which the examples are presented, in order to test \textsc{Myth}'s sensitivity to example specifications. While programs dealing with simply data types such as \texttt{bool} or \texttt{nat} are synthesized identically to the original cases, \textsc{Myth} fails to synthesize the same program for more complex data types such as \texttt{list}. An example is shown in Figure \ref{fig-sensitivity}. This finding will be further discuss in Section \ref{sec-disc-sens}.\\

\subsection{New test cases}\label{sec-newc}

Five new test cases, as listed below, are successfully synthesized:

\begin{itemize}
  \item \texttt{bool\_iff : bool -> bool -> bool}, which checks the \emph{if and only if} condition of two \texttt{bool}.
  \item \texttt{nat\_eq : nat -> nat -> bool}, which checks if two \texttt{nat} numbers are equal.
  \item \texttt{list\_has : nat -> list -> bool}, which checks if a \texttt{list} contains a specific \texttt{nat} number.
  \item \texttt{list\_index : nat -> list -> nat}, which returns the index of the first instance of a specific \texttt{nat} number in a \texttt{list}, returns the index of the last element if specified element not found in list.
  \item \texttt{list\_eq : list -> list -> bool}, which checks whether two lists contain the exact same elements (in same order).
\end{itemize}

\texttt{bool\_iff} and \texttt{nat\_eq} are quite trivial, whereas the three test cases of \texttt{list} type require more careful tuning of the example specification and definition of helper functions. The synthesis data is listed in Figure \ref{fig-newc}. The detailed findings will again be further discussed in Section \ref{sec-disc-cont}.\\

\begin{figure}[!ht]
  \begin{center}
  \begin{tabular}{cccc}
  \hline
  \textbf{Test} & \textbf{ \#Ex } & \textbf{ \#N } & \textbf{Time (s)} \\
  \hline
  nat\_eq & 5 & 16 & 0.0104 \\
  list\_eq & 16 & 23 & 13.6328 \\
  list\_index & 10 & 19 & 1.751 \\
  list\_has & 7 & 19 & 0.638 \\
  bool\_band & 4 & 9 & 0.0038 \\
  \hline
  \end{tabular}
  \end{center}
  \caption{\textsc{Myth} test results using new test cases, where \#Ex is the number of examples used, \#N is the size of the result}
  \label{fig-newc}
\end{figure}

\section{Discussion}\label{sec-disc}

\subsection{Sensitivity to example specifications}\label{sec-disc-sens}
The most important finding from the tests is that, although not an issue with more premitive data types (\texttt{bool}, \texttt{nat}), \textsc{Myth} is extremely sensitive to example specifications for programs with more complex types. Sometimes, a very slight change in the example specification could result in vastely different results or even failure in synthsis. In some extreme cases, the synthesis changes significantly even by simply adding an extra redundant example. \citet{osera2015type} did make a note of this issue in their discussion, stating that the examples should be specified in such way that they imitate each recursive call of the target function, which is usually not case in real-life input-output examples available to be used for program synthesis. This is likely going to be the most important challenge to overcome in order for this method to have real-life applications.\\

\subsection{Context size and helper functions}\label{sec-disc-cont}
Some of the new test cases require a larger context, \emph{i.e.}, predefined helper functions. This allows the program to be synthesized correctly but significantly increased the synthsis time. This finding is in agreement of some cases presented by \citet{osera2015type} in the original publication. The authors attributed this issue to the significantly larger set of possible matches for $E$-guessing given by the helper function. They also proposed possible ways of mitigate this problem, such as optimizing search heuristic.\\

It was pointed out by \citet{osera2015type} that the synthesis tend to be driven into a counter-intuitive pattern: \emph{inside-out recursion}, where the synthesized function tends to match for output types from recursive calls itself, rather than input types. Although there are successful cases where a synthesized function with an \emph{inside-out recursion} does perform the correct task, it is observed during the testing that most of these functions are too specific to satisfying the given set of examples and generally correct. It is also observed, however, that extra context and helper functions tend to decrease the chance of getting an \emph{inside-out recursion}, at the cost of synthsis time.\\

\subsection{Other findings}\label{sec-disc-othe}
As already pointed out in Section \ref{sec-disc-cont}, one possible immediate improvement to this synthesis method is to further optimize the search strategy and/or heuristic. The current setting of \textsc{Myth} has a rather naive, but balanced alternation between term generation and refinement, with a generation timeout of 2.5ms. Based on the description by \citet{osera2015type} as well as the traces in the source code, it appears that the authors have tested several different possibilities and found the current setting to be the most stable one. During the testing, a few other search strategies, such as a longer timeout for term generation and increasing the size of scrutinee growth, have been attempted. They all prove to be less optimal than the existing stable strategy. Due to time and resource constraint, the different possible search strategies cannot be exhaustively tested, but this should definitely be the main concentration of future works on this topic.\\

Another minor finding of the \textsc{Myth} prototype is an issue in output formatting. Although \textsc{Myth} is not compatible with premitive data types in OCaml, such as \texttt{int} or \texttt{string}, the authors added an extra layer of parser to translate normal repersentation of a natural number or a list (\emph{e.g.}, \texttt{0, 1, [0,1]} etc) into algebraic types \texttt{nat} and \texttt{list} recognizable by \textsc{Myth}. This is certainly done for convenience in specifying input-output examples. During the output step of the synthesized program, the authors reformat the \texttt{nat} and \texttt{list} types back into a normal reprsentation. Althought this is more advantageous from an aesthetics point of view, it prevents the synthesized code from being run directly in the context of OCaml. This may potentially cause issues for future wrapper methods for test/application purposes. An adapted implementaion of \textsc{Myth} is created to resolve this issue by keeping the data types as they are during the output formatting step. \\

\section{Conclusion}\label{sec-conl}
This project provides an overview of the underlying theories of program synthesis with a concentrated attention on the new synthesis language $\lambda_{syn}$ - a proof-theory-based, example-and-type-directed synthesis algorithm - developped by \citet{osera2015type}. Reproducibility as well as sensitivity tests are performed on the prototype of $\lambda_{syn}$'s artifact: \textsc{Myth}, revealing strengths and weakenesses of this method. Five additional test cases are also successfully synthesized using the \textsc{Myth} artifact. Interesting results are discovered during the testing and discussed in this report. Optimization of the search strategy has been identified during this project to be the key component that needs to be improved in future works, if time and resources permit. An optimal search strategy will allow this method to accomodate for more formats of example-specification while keeping the synthesis search space reasonably small. Once achieved, this synthesis method has great potential of becoming a usable tool with broader applications.\\

\appendix
\section{Electronic Appendix}
All work done for this project, including an copy of the \textsc{Myth} artifact with customized implementation (output format fix and new test cases), as well as a copy of this report and its source code, can be found in a repository dedicated to this project at https://github.com/Hachiko99/Project-527.

\begin{thebibliography}{14}
\softraggedright

\bibitem[Basin et~al.(2004)Basin, Deville, Flener, Hamfelt, and
  Fischer~Nilsson]{Basin2004}
D.~Basin, Y.~Deville, P.~Flener, A.~Hamfelt, and J.~Fischer~Nilsson.
\newblock \emph{Program Development in Computational Logic: A Decade of
  Research Advances in Logic-Based Program Development}, chapter Synthesis of
  Programs in Computational Logic, pages 30--65.
\newblock Springer Berlin Heidelberg, Berlin, Heidelberg, 2004.
\newblock ISBN 978-3-540-25951-0.

\bibitem[Bjorner et~al.(1988)Bjorner, Jones, and Ershov]{bjorner1988partial}
D.~Bjorner, N.~D. Jones, and A.~Ershov.
\newblock \emph{Partial Evaluation and Mixed Computation: Proceedings of the
  IFIP TC2 Workshop, Gammel Avernaes, Denmark, 18-24 Oct., 1987}.
\newblock Elsevier Science Inc., 1988.

\bibitem[Burstall and Darlington(1977)]{burstall1977transformation}
R.~M. Burstall and J.~Darlington.
\newblock A transformation system for developing recursive programs.
\newblock \emph{Journal of the ACM (JACM)}, 24\penalty0 (1):\penalty0 44--67,
  1977.

\bibitem[Curry et~al.(1972)Curry, Feys, Craig, Hindley, and
  Seldin]{curry1972combinatory}
H.~B. Curry, R.~Feys, W.~Craig, J.~R. Hindley, and J.~P. Seldin.
\newblock Combinatory logic.
\newblock 1972.

\bibitem[Frankle et~al.(2016)Frankle, Osera, Walker, and
  Zdancewic]{frankle2016example}
J.~Frankle, P.-M. Osera, D.~Walker, and S.~Zdancewic.
\newblock Example-directed synthesis: a type-theoretic interpretation.
\newblock In \emph{Proceedings of the 43rd Annual ACM SIGPLAN-SIGACT Symposium
  on Principles of Programming Languages}, pages 802--815. ACM, 2016.

\bibitem[Freeman and Pfenning(1991)]{freeman1991refinement}
T.~Freeman and F.~Pfenning.
\newblock \emph{Refinement types for ML}, volume~26.
\newblock ACM, 1991.

\bibitem[Green(1969)]{green1969application}
C.~Green.
\newblock Application of theorem proving to problem solving.
\newblock Technical report, DTIC Document, 1969.

\bibitem[Kolmogorov(1932)]{kolmogorov1932theory}
A.~Kolmogorov.
\newblock The theory of functions of a real variable.
\newblock \emph{Science in the USSR during fifteen years: Mathematics}, 1932.

\bibitem[Kreitz(1998)]{kreitz1998program}
C.~Kreitz.
\newblock Program synthesis.
\newblock In \emph{Automated Deduction—A Basis for Applications}, pages
  105--134. Springer, 1998.

\bibitem[Manna and Waldinger(1971)]{manna1971toward}
Z.~Manna and R.~J. Waldinger.
\newblock Toward automatic program synthesis.
\newblock \emph{Communications of the ACM}, 14:\penalty0 151--165, 1971.

\bibitem[Osera and Zdancewic(2015)]{osera2015type}
P.-M. Osera and S.~Zdancewic.
\newblock Type-and-example-directed program synthesis.
\newblock In \emph{Proceedings of the 36th ACM SIGPLAN Conference on
  Programming Language Design and Implementation}, pages 619--630. ACM, 2015.

\bibitem[Paige and Koenig(1982)]{paige1982finite}
R.~Paige and S.~Koenig.
\newblock Finite differencing of computable expressions.
\newblock \emph{ACM Transactions on Programming Languages and Systems
  (TOPLAS)}, 4\penalty0 (3):\penalty0 402--454, 1982.

\bibitem[Pfenning(1993)]{pfenning1993refinement}
F.~Pfenning.
\newblock Refinement types for logical frameworks.
\newblock In \emph{Informal Proceedings of the Workshop on Types for Proofs and
  Programs}, pages 285--299, 1993.

\bibitem[Tait(1967)]{tait1967intensional}
W.~W. Tait.
\newblock Intensional interpretations of functionals of finite type i.
\newblock \emph{The journal of symbolic logic}, 32\penalty0 (02):\penalty0
  198--212, 1967.

\end{thebibliography}

\bibliographystyle{abbrvnat}

\end{document}