\usepackage{url}
\usepackage{pstricks,pst-node}
\usepackage{amssymb,amsmath}
\usepackage{longtable}

\newcommand{\hide}[1]{}
\newcommand{\defn}[1]{{\bf #1}\index{#1}}
\newcommand{\defni}[1]{{\bf #1}}

\newcommand{\eg}{{\it e.g.}}
\newcommand{\ie}{{\it i.e.}}
\newcommand{\etc}{{\it etc.}}
\newcommand{\etcp}{{\it etc}}

\newcommand{\skippable}{$\mbox{}^\bigstar$}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Modifications to style
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newenvironment{myexample}{\begin{example}}{\hspace*{\fill}$\blacksquare$\end{example}}
\newenvironment{myproof}{\begin{proof}}{\hspace*{\fill}$\blacksquare$\end{proof}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Math & Logic
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\true}{\top}
\newcommand{\false}{\bot}
\newcommand{\truev}{\mathsf{true}}
\newcommand{\falsev}{\mathsf{false}}

\newenvironment{multiline}{\begin{array}[t]{@{}l@{}}}{\end{array}}
\newenvironment{paren}{\left[\begin{array}{@{}l@{}}}{\end{array}\right]}

\newcommand{\set}[1]{\{#1\}}
\newcommand{\Set}[1]{\left\{#1\right\}}
\newcommand{\mlset}[1]{\{\begin{multiline}#1\}\end{multiline}}
\newcommand{\range}[2]{\set{#1,\ldots,#2}}
\newcommand{\tuple}[1]{\langle #1 \rangle}
\newcommand{\Tuple}[1]{\left\langle #1 \right\rangle}
\newcommand{\vectr}[1]{\overline{#1}}
\newcommand{\abs}[1]{\left|#1\right|}
\newcommand{\floor}[1]{\left\lfloor #1\right\rfloor}
\newcommand{\eclass}[2]{[#1]_{#2}}
\newcommand{\eqdef}{\stackrel{\mbox{\scriptsize def}}{=}}

\newcommand{\bnot}{\neg}
\newcommand{\band}{\ \wedge\ }
\newcommand{\bor}{\ \vee\ }
\newcommand{\bimplies}{\ \rightarrow\ }
\newcommand{\biff}{\ \leftrightarrow\ }
\newcommand{\nand}{\overline{\wedge}}
\newcommand{\Models}{\ \models\ }
\newcommand{\Nmodels}{\ \not\models\ }

\newcommand{\sbnot}{\neg}
\newcommand{\sband}{\wedge}
\newcommand{\sbor}{\vee}
\newcommand{\sbimplies}{\rightarrow}
\newcommand{\sbiff}{\leftrightarrow}
\newcommand{\snand}{\overline{\wedge}}
\newcommand{\sModels}{\models}
\newcommand{\sNmodels}{\not\models}

\newcommand{\Bimplies}{\ \Rightarrow\ }
\newcommand{\Bequiv}{\ \Leftrightarrow\ }

\newcommand{\sBimplies}{\Rightarrow}
\newcommand{\sBequiv}{\Leftrightarrow}

\newcommand{\wBimplies}{\ \Rightarrow^*\ }
\newcommand{\wBequiv}{\ \Leftrightarrow^*\ }
\newcommand{\swBimplies}{\Rightarrow^*}
\newcommand{\swBequiv}{\Leftrightarrow^*}

\newcommand{\Mapsto}{\ \mapsto\ }

\newenvironment{semantics}
	       {\begin{array}{rcl@{\hspace*{2em}}l}}
	       {\end{array}}
\newenvironment{nsemantics}
	       {\begin{array}{l@{\hspace*{1em}}rcl@{\hspace*{2em}}l}}
	       {\end{array}}

\newcommand{\sdom}{\mathsf{domain}}
\newcommand{\srng}{\mathsf{range}}

\newcommand{\freev}{\mathsf{free}}
\newcommand{\boundv}{\mathsf{bound}}

\newcommand{\Idom}[1]{D_{#1}}
\newcommand{\Iasgn}[1]{\alpha_{#1}}
\newcommand{\idom}{\Idom{I}}
\newcommand{\iasgn}{\Iasgn{I}}
\newcommand{\jdom}{\Idom{J}}
\newcommand{\jasgn}{\Iasgn{J}}
\newcommand{\icomp}[2]{\triangleleft \set{#1 \mapsto #2}}

\newcommand{\dval}[1]{\mathsf{#1}}
\newcommand{\qfr}{\mathsf{Q}}

\newcommand{\lpl}{L_{\mathsf{PL}}}
\newcommand{\lfol}{L_{\mathsf{FOL}}}

\newcommand{\prule}[2]{
  \begin{array}[t]{@{}l@{}}
    \begin{array}{@{}l@{}} #1 \end{array} \\
    \hline
    \begin{array}{@{}l@{}} #2 \end{array}
  \end{array}
}
\newcommand{\pbrule}[2]{
  \begin{array}[t]{@{}c@{}}
    \begin{array}{@{}c@{}} #1 \end{array} \\
    \hline
    \begin{array}{@{}c@{\hspace{1em}|\hspace{1em}}c@{}} #2 \end{array}
  \end{array}
}
\newcommand{\charf}[2]{\set{#1}\rightarrow\set{#2}}

\newcommand{\ptime}{\mathsf{P}}
\newcommand{\Ptime}{\mathsf{PTIME}}
\newcommand{\nptime}{\mathsf{NP}}
\newcommand{\nptimeind}{\@mathsf{NP}}
\newcommand{\NPtime}{\mathsf{NPTIME}}

\newcommand{\integers}{\mathbb{Z}}
\newcommand{\naturals}{\mathbb{N}}
\newcommand{\rationals}{\mathbb{Q}}
\newcommand{\reals}{\mathbb{R}}

\newcommand{\wpre}[2]{\mathsf{wp}(#1,\ #2)}
\newcommand{\Wpre}[2]{\mathsf{wp}(
  \begin{multiline} #1 \\ ,~#2)\end{multiline}}
\newcommand{\htrip}[3]{\set{#1}#2\set{#3}}

\newcommand{\spost}[2]{\mathsf{sp}(#1,\ #2)}

\newcommand{\Fninf}{F_{-\infty}}
\newcommand{\Fpinf}{F_{+\infty}}
\newcommand{\Finf}{F_{\infty}}

\newcommand{\sharedv}{\mathsf{shared}}
\newcommand{\thd}{\mathsf{hd}}

\newcommand{\tr}[1]{{#1}^{\mathsf{T}}}
\newcommand{\uv}{\mathsf{e}}
\newcommand{\va}{\vectr{a}}
\newcommand{\vb}{\vectr{b}}
\newcommand{\vc}{\vectr{c}}
\newcommand{\ve}{\vectr{g}}
\newcommand{\vi}{\vectr{i}}
\newcommand{\vn}{\vectr{n}}
\newcommand{\vp}{\vectr{p}}
\newcommand{\vr}{\vectr{r}}
\newcommand{\vu}{\vectr{u}}
\newcommand{\vv}{\vectr{v}}
\newcommand{\vx}{\vectr{x}}
\newcommand{\vy}{\vectr{y}}
\newcommand{\vz}{\vectr{z}}
\newcommand{\vone}{\vectr{1}}
\newcommand{\vzero}{\vectr{0}}
\newcommand{\opt}[1]{#1^*}
\newcommand{\dimm}{\mathsf{dim}}
\newcommand{\nullspc}{\mathsf{null}}

\newenvironment{mymatrix}[1]
	       {\left[\begin{array}{#1}}
	       {\end{array}\right]}
\newenvironment{optmax}[1]
	       {\begin{array}[t]{@{}ll@{}}
		   \mathbf{max}\ & #1 \\
		   \multicolumn{2}{@{}l}{\mathbf{subject\ to}} \\
		   & \begin{array}{@{}rcl@{}}}
	       {\end{array}\end{array}}
\newenvironment{optmaxn}[1]
	       {\begin{array}[t]{@{}ll@{}}
		   \mathbf{max}\ & #1 \\
		   \multicolumn{2}{@{}l}{\mathbf{subject\ to}} \\
		   & \begin{array}{@{}rcl@{\hspace{3em}}r@{}}}
	       {\end{array}\end{array}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Theories
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\peano}{\mathsf{PA}}
\newcommand{\tpeano}{T_{\peano}}
\newcommand{\presb}{\naturals}
\newcommand{\tpresb}{T_{\presb}}
\newcommand{\tint}{T_\integers}
\newcommand{\tinta}{\widehat{T_\integers}}

\newcommand{\equ}{\mathsf{E}}
\newcommand{\tequ}{T_\equ}
\newcommand{\euf}{\equ}
\newcommand{\teuf}{T_\euf}

\newcommand{\gcon}{\mathsf{C}}
\newcommand{\cons}{\mathsf{cons}}
\newcommand{\car}{\mathsf{car}}
\newcommand{\cdr}{\mathsf{cdr}}
\newcommand{\atom}{\mathsf{atom}}
\newcommand{\tcons}{T_\cons}
\newcommand{\rds}{\mathsf{RDS}}
\newcommand{\trds}{T_\rds}
\newcommand{\tconsa}{\tcons^+}
\newcommand{\trdsa}{\trds^+}
\newcommand{\trdse}{T_\rds^=}
\newcommand{\tconse}{T_\cons^=}
\newcommand{\tconsnil}{T_\cons^\atom}

\newcommand{\alg}{\reals}
\newcommand{\talg}{T_\alg}
\newcommand{\rat}{\rationals}
\newcommand{\trat}{T_\rat}

\newcommand{\arr}{\mathsf{A}}
\newcommand{\tarr}{T_\arr}
\newcommand{\tarre}{T_\arr^=}
\newcommand{\ard}[2]{#1[#2]}
\newcommand{\awt}[3]{#1\tuple{#2 \triangleleft #3}}
\newcommand{\tarrz}{T_\arr^\integers}

\newcommand{\indexaxiom}[1]{\index{axioms!#1@{\sf #1}}\index{#1@{\sf #1} [axiom]}}

\newcommand{\naxiom}[1]{\hspace*{\fill}{\sf (#1)}\indexaxiom{#1}}
\newcommand{\naxiomm}[1]{\hspace*{\fill}{\mbox{\sf (#1)}}\indexaxiom{#1}}
\newcommand{\naxiomi}[1]{\hspace*{\fill}{\sf (#1)}}
\newcommand{\axiom}[1]{{\sf (#1)}}

\newcommand{\thash}{T_\mathsf{H}}
\newcommand{\hput}{\mathsf{put}}
\newcommand{\hget}{\mathsf{get}}
\newcommand{\hempty}{\mathsf{empty}}
\newcommand{\hremove}{\mathsf{remove}}
\newcommand{\hkeys}{\mathsf{keys}}
\newcommand{\hinit}{\mathsf{init}}

\newcommand{\tpo}{T_{\preceq}}

\newcommand{\aband}[1]{\ \sqcap_{#1}\ }
\newcommand{\abor}[1]{\ \sqcup_{#1}\ }
\newcommand{\saband}[1]{\sqcap_{#1}}
\newcommand{\sabor}[1]{\sqcup_{#1}}
\newcommand{\maspost}{\overline{\mathsf{sp}}}
\newcommand{\aspost}[3]{\overline{\mathsf{sp}}_{#1}(#2,\ #3)}
\newcommand{\widen}[1]{\bigtriangledown_{#1}}
\newcommand{\domint}{D_\mathsf{I}}
\newcommand{\domkarr}{D_\mathsf{K}}
\newcommand{\affine}{\mathsf{affine}}
\newcommand{\atrans}[1]{[\hspace*{-.3ex}[#1]\hspace*{-.3ex}]}

\newcommand{\speano}{\Sigma_{\peano}}
\newcommand{\spresb}{\Sigma_{\presb}}
\newcommand{\sint}{\Sigma_\integers}
\newcommand{\sinta}{\widehat{\Sigma_\integers}}
\newcommand{\sequ}{\Sigma_\equ}
\newcommand{\scons}{\Sigma_\cons}
\newcommand{\sconsa}{\Sigma_\cons^+}
\newcommand{\sconse}{\Sigma_\cons^=}
\newcommand{\srds}{\Sigma_\rds}
\newcommand{\srdsa}{\Sigma_\rds^+}
\newcommand{\srdse}{\Sigma_\rds^=}
\newcommand{\salg}{\Sigma_\alg}
\newcommand{\srat}{\Sigma_\rat}
\newcommand{\sarr}{\Sigma_\arr}
\newcommand{\sarre}{\Sigma_\arr^=}
\newcommand{\sarrz}{\Sigma_\arr^\integers}
\newcommand{\shash}{\Sigma_\mathsf{H}}
\newcommand{\spo}{\Sigma_{\preceq}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Names
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\godel}{G\"{o}del}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Simple ML
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\mfn}[1]{\mathsf{#1}}
\newcommand{\mkwd}[1]{\mathtt{#1}}
\newcommand{\mletin}[2]{\mkwd{let}\ #1 = #2\ \mkwd{in}}
\newcommand{\mif}{\mkwd{if}\ }
\newcommand{\mthen}{\mkwd{then}\ }
\newcommand{\melse}{\mkwd{else}\ }
\newcommand{\mpseudo}[1]{\mbox{#1}}
\newenvironment{mprog}{\begin{array}{l}}{\end{array}}
\newenvironment{mblock}{\hspace*{1em}\begin{array}{l}}{\end{array}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Essentially O'Caml
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\memph}[1]{\mathit{#1}}

\newcommand{\mlkwd}[1]{\mathtt{#1}}
\newcommand{\mllet}{\mlkwd{let}\ }
\newcommand{\mlrec}{\mlkwd{rec}\ }
\newcommand{\mland}{\mlkwd{and}\ }
\newcommand{\mlor}{\mlkwd{or}\ }
\newcommand{\mlin}{\mlkwd{in}}
\newcommand{\mlraise}{\mlkwd{raise}\ }
\newcommand{\mlif}{\mlkwd{if}\ }
\newcommand{\mlthen}{\mlkwd{then}\ }
\newcommand{\mlelse}{\mlkwd{else}\ }
\newcommand{\mlref}{\mlkwd{ref}\ }
\newcommand{\mlfalse}{\mlkwd{false}\ }
\newcommand{\mltrue}{\mlkwd{true}\ }
\newcommand{\mlassign}{\ \mlkwd{:=}\ }
\newcommand{\mlarw}{\ \leftarrow\ }
\newcommand{\mlvar}[1]{\mathit{#1}}
\newcommand{\mlfni}[1]{\mbox{\sc #1}}
\newcommand{\mlfn}[1]{\mbox{\sc #1}\index{#1@{\sc #1} [function]}\index{functions!#1@{\sc #1}}}
\newcommand{\mltype}[1]{\mathbf{#1}}
\newcommand{\mlcons}[1]{\mathbf{#1}}
\newcommand{\mlcomment}[1]{\mbox{$\{${\it #1}$\}$}}
\newcommand{\mlexception}[1]{\mathbf{#1}}

\newcommand{\mlblank}{\underline{\hspace{1em}}}

\newcommand{\mlindent}{\hspace{1em}}
\newenvironment{mlblock}{\begin{array}[t]{@{}l@{}}}{\end{array}}
\newenvironment{mlmatchbody}
	       {\begin{array}{@{|\hspace{.5em}}l@{\hspace{1em}\rightarrow\hspace{1em}}l}}
	       {\end{array}}
\newenvironment{mlmatch}[1]
	       {\begin{mlblock}\mlkwd{match}\ #1\ \mlkwd{with} \\}
	       {\end{mlblock}}
\newenvironment{mltry}[1]
	       {\begin{mlblock}\mlkwd{try}\ #1\ \mlkwd{with} \\}
	       {\end{mlblock}}
\newenvironment{mlwhile}[1]
	       {\begin{mlblock}\mlkwd{while}\ #1\ \mlkwd{do} \\ \mlindent\begin{mlblock}}
	       {\end{mlblock} \\ \mlkwd{done;}\end{mlblock}}
\newenvironment{mlforeach}[1]
	       {\begin{mlblock}\mlkwd{foreach}\ #1\ \mlkwd{do} \\ \mlindent\begin{mlblock}}
	       {\end{mlblock} \\ \mlkwd{done;}\end{mlblock}}
\newcommand{\mlsmalllet}[2]{\mllet #1\ =\ #2\ \mlin}
\newenvironment{mlbiglet}[1]
	       {\begin{mlblock}\mllet #1\ = \\ \mlindent\begin{mlblock}}
	       {\end{mlblock}\\ \mlin\end{mlblock}}
\newenvironment{mlfunction}[2]
	       {\begin{mlblock}\mllet \mlfni{#1}\ #2 = \\ \mlindent\begin{mlblock}}
	       {\end{mlblock}\end{mlblock}}
\newenvironment{mlrecfunction}[2]
	       {\begin{mlblock}\mllet \mlrec \mlfni{#1}\ #2 = \\ \mlindent\begin{mlblock}}
	       {\end{mlblock}\end{mlblock}}
\newenvironment{mlmatchfunction}[2]
	       {\begin{mlblock}\mllet\ \mlfni{#1}\ #2 =\ \mlkwd{function} \\}
	       {\end{mlblock}}
\newenvironment{mlbeginend}
	       {\mlkwd{begin} \\ \mlindent\begin{mlblock}}
	       {\end{mlblock}\\ \mlkwd{end}}
\newenvironment{mlbeginendsc}
	       {\mlkwd{begin} \\ \mlindent\begin{mlblock}}
	       {\end{mlblock}\\ \mlkwd{end;}}

\newenvironment{mlrecordtype}[1]
	       {\begin{mlblock}
		   \mlkwd{type}\ \mltype{#1}\ =\ \{ \\
		   \mlindent\mlindent
		     \begin{array}{@{}l@{\hspace{1em}\mbox{:}\hspace{1em}}l@{}}}
	       {\end{array} \\ \mlindent \} \end{mlblock}}
\newcommand{\mlfield}[1]{\mathtt{#1}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pi
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\pvc}{$\mathsf{\pi VC}$}
\newcommand{\ppi}{{\sf pi}}

\newcommand{\pipre}{\mathsf{@pre}\ }
\newcommand{\pipost}{\mathsf{@post}\ }
\newcommand{\piassert}{\mathsf{@}\ }
\newcommand{\pirank}{\downarrow\hspace*{.15em}}

\newcommand{\piloc}[1]{\hspace*{-.8ex}#1}

\newcommand{\piassertion}[1]{\hspace*{-.5em}\left[\begin{array}{@{}l@{}} #1 \end{array}\right]}

\newcommand{\pikwd}[1]{{\mathtt{#1}}}

\newcommand{\pitype}[1]{\pikwd{#1}}
\newcommand{\pityp}[1]{\pitype{#1}\ }
\newcommand{\pistruct}{\pikwd{struct}\ }
\newcommand{\pitypedef}{\pikwd{typedef}\ }

\newcommand{\pifnin}[1]{\index{#1@{\sf #1} [program]}\index{programs!#1@{\sf #1}}}
\newcommand{\pifnib}[1]{\index{#1@{\sf #1} [program]|(}\index{programs!#1@{\sf #1}|(}}
\newcommand{\pifnie}[1]{\index{#1@{\sf #1} [program]|)}\index{programs!#1@{\sf #1}|)}}
\newcommand{\pifn}[1]{{\mathsf{#1}}\index{#1@{\sf #1} [program]}\index{programs!#1@{\sf #1}}}
\newcommand{\pifni}[1]{{\mathsf{#1}}}

\newcommand{\pia}{\ \mbox{:=}\ }
\newcommand{\piif}{\pikwd{if}\ }
\newcommand{\pielse}{\pikwd{else}\ }
\newcommand{\piwhile}{\pikwd{while}\ }
\newcommand{\pibreak}{\pikwd{break}}
\newcommand{\picontinue}{\pikwd{continue}}
\newcommand{\pifor}{\pikwd{for}\ }
\newcommand{\pireturn}{\pikwd{return}\ }
\newcommand{\pitrue}{\pikwd{true}}
\newcommand{\pifalse}{\pikwd{false}}
\newcommand{\pinew}{\pikwd{new}\ }
\newcommand{\pidefine}{\pikwd{define}\ }

\newcommand{\pidiv}{\ \pikwd{div}\ }

\newcommand{\pirv}{\mathit{rv}}
\newcommand{\pipc}{pc}

\newcommand{\sparam}[1]{\tuple{\mathit{#1}}}

\newcommand{\locs}{{\mathcal{L}}}
\newcommand{\pipres}{\mathsf{pres}}

\newenvironment{piprogram}{\begin{array}[t]{l}}{\end{array}}
\newcommand{\piblock}[1]{\ \{ \\ \hspace*{1em}\begin{array}{@{}l@{}} #1 \end{array} \\ \}}
\newcommand{\pisblock}[1]{\\ \hspace*{1em}\begin{array}{@{}l@{}} #1 \end{array} \\}

\newcommand{\pifunction}[6]{
  \begin{piprogram}
    \pipre #1 \\
    \pipost #2 \\
    \pityp{#3} \pifni{#4}(#5)
    \piblock{#6}
  \end{piprogram}
}
\newcommand{\piforstmt}[5]{
  \pifor \\
  \hspace*{1em} \piassert #1 \\
  \hspace*{1em} (#2;\ #3;\ #4)
  \piblock{#5}
}
\newcommand{\piforstmts}[4]{
  \pifor \piassert \true \\ 
  \hspace*{1em} (#1;\ #2;\ #3)
  \piblock{#4}
}
\newcommand{\piwhilestmt}[3]{
  \piwhile \\
  \hspace*{1em} \piassert #1 \\
  \hspace*{1em} (#2)
  \piblock{#3}
}
\newcommand{\piifstmt}[2]{
  \piif (#1)\
  \piblock{#2}
}
\newcommand{\pielsestmt}[1]{
  \pielse \piblock{#1}
}
\newcommand{\pitypestruct}[2]{
  \pitypedef \pistruct \pityp{#1} \piblock{#2}\ \pitype{#1};
}
\newcommand{\pistructinit}[1]{
  \\ \hspace*{1em} \begin{array}{l}
  \{\ \begin{array}[t]{l} #1 \end{array} \\ \};
  \end{array}
}

\newcommand{\pirffunction}[7]{
  \begin{piprogram}
    \pipre #1 \\
    \pipost #2 \\
    \pirank #3 \\
    \pityp{#4} \pifni{#5}(#6)
    \piblock{#7}
  \end{piprogram}
}
\newcommand{\pirfforstmt}[6]{
  \pifor \\
  \hspace*{1em} \piassert #1 \\
  \hspace*{1em} \pirank #2 \\
  \hspace*{1em} (#3;\ #4;\ #5)
  \piblock{#6}
}

\newenvironment{pilisting}
	       {\rule{\textwidth}{.5mm}\nopagebreak\newline$}
	       {$\nopagebreak\newline\rule{\textwidth}{.5mm}}
\newenvironment{spilisting}
	       {\begin{equation*}\begin{array}{@{}l@{}}}
	       {\end{array}\end{equation*}}

\newcommand{\piassume}{\pikwd{assume}\ }
\newcommand{\pipathn}[1]{{\bf (#1)}}
\newenvironment{pipath}[1]
	       {\newline\noindent\rule[.5ex]{.45\textwidth}{.5mm}
		 \hspace*{\fill}
		 \pipathn{#1}
		 \hspace*{\fill}
		 \rule[.5ex]{.45\textwidth}{.5mm}
		 \nopagebreak\newline$\begin{array}[t]{l}}
	       {\end{array}$\hspace*{\fill}
		 \nopagebreak\newline\rule[.5ex]{\textwidth}{.5mm}\newline}
\newenvironment{spipath}[1]
	       {\begin{equation*}\begin{array}{@{}l@{}}}
	       {\end{array}\end{equation*}}
\newenvironment{bpipath}[1]
	       {\rule{\textwidth}{.5mm}\nopagebreak\newline$}
	       {$\nopagebreak\newline\rule{\textwidth}{.5mm}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Example pi programs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\peq}{\mathsf{eq}}
\newcommand{\pbeq}{\mathsf{beq}}
\newcommand{\psort}{\mathsf{sorted}}
\newcommand{\ppart}{\mathsf{partitioned}}
\newcommand{\wperm}{\mathsf{wperm}}
\newcommand{\pperm}{\mathsf{perm}}

\newcommand{\qsort}{{\sf QuickSort}}

% ----------- LinearSearch---------------------- %

\newcommand{\lsearch}{{\sf LinearSearch}}

\newcommand{\lsearchUnspecified}{
  \pifunction{\true}{\true}{bool}{LinearSearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piforstmts{\pityp{int} i \pia \ell}{i \le u}{i \pia i + 1}{
      \piif (a[i] = e)\ \pireturn \pitrue;
    } \\
    \pireturn \pifalse;
  }
}

\newcommand{\lsearchSpecified}{
  \pifunction{
    0 \le \ell \band u < |a|
  }{
    \pirv \biff \exists i.\ \ell \le i \le u \band a[i] = e
  }{bool}{LinearSearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piforstmts{\pityp{int} i \pia \ell}{i \le u}{i \pia i + 1}{
      \piif (a[i] = e)\ \pireturn \pitrue;
    } \\
    \pireturn \pifalse;
  }
}

\newcommand{\lsearchProved}{
  \pifunction{
    0 \le \ell \band u < |a|
  }{
    \pirv \biff \exists i.\ \ell \le i \le u \band a[i] = e
  }{bool}{LinearSearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piforstmt{
      \piloc{L}:\ \ell \le i \band (\forall j.\ \ell \le j < i \bimplies a[j] \ne e)
    }{\pityp{int} i \pia \ell}{i \le u}{i \pia i + 1}{
      \piif (a[i] = e)\ \pireturn \pitrue;
    } \\
    \pireturn \pifalse;
  }
}

\newcommand{\lsearchRuntimeSpecified}{
  \pifunction{\true}{\true}{bool}{LinearSearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piforstmts{\pityp{int} i \pia \ell}{i \le u}{i \pia i + 1}{
      \piassert 0 \le i < |a|; \\
      \piif (a[i] = e)\ \pireturn \pitrue;
    } \\
    \pireturn \pifalse;
  }
}

\newcommand{\lsearchRuntimeProved}{
  \pifunction{
    0 \le \ell \band u < |a|
  }{\true}{bool}{LinearSearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piforstmt{
      0 \le \ell \le i \band u < |a|
    }{\pityp{int} i \pia \ell}{i \le u}{i \pia i + 1}{
      \piassert 0 \le i < |a|; \\
      \piif (a[i] = e)\ \pireturn \pitrue;
    } \\
    \pireturn \pifalse;
  }
}

\newcommand{\lsearchRobustSpecified}{
  \pifunction{
    \true
  }{
    \pirv \biff \exists i.\ 0 \le \ell \le i \le u < |a| \band a[i] = e
  }{bool}{LinearSearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piif (\ell < 0 \bor u \ge |a|)\ \pireturn \pifalse; \\
    \piforstmts{\pityp{int} i \pia \ell}{i \le u}{i \pia i + 1}{
      \piif (a[i] = e)\ \pireturn \pitrue;
    } \\
    \pireturn \pifalse;
  }
}

% ----------- BinarySearch---------------------- %

\newcommand{\bsearch}{{\sf BinarySearch}}

\newcommand{\bsearchUnspecified}{
  \pifunction{\true}{\true}{bool}{BinarySearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piif (\ell > u)\ \pireturn \pifalse; \\
    \pielsestmt{
      \pityp{int} m \pia (\ell + u) \pidiv 2; \\
      \piif (a[m] = e)\ \pireturn \pitrue; \\
      \pielse \piif (a[m] < e)\ \pireturn \pifni{BinarySearch}(a, m+1, u, e); \\
      \pielse \pireturn \pifni{BinarySearch}(a, \ell, m-1, e);
    }
  }
}

\newcommand{\bsearchSpecified}{
  \pifunction{
    0 \le \ell \band u < |a| \band \psort(a, \ell, u)
  }{
    \pirv \biff \exists i.\ \ell \le i \le u \band a[i] = e
  }{bool}{BinarySearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piif (\ell > u)\ \pireturn \pifalse; \\
    \pielsestmt{
      \pityp{int} m \pia (\ell + u) \pidiv 2; \\
      \piif (a[m] = e)\ \pireturn \pitrue; \\
      \pielse \piif (a[m] < e)\ \pireturn \pifni{BinarySearch}(a, m+1, u, e); \\
      \pielse \pireturn \pifni{BinarySearch}(a, \ell, m-1, e);
    }
  }
}

\newcommand{\bsearchProved}{
  \pifunction{
    0 \le \ell \band u < |a| \band \psort(a, \ell, u)
  }{
    \pirv \biff \exists i.\ \ell \le i \le u \band a[i] = e
  }{bool}{BinarySearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piif (\ell > u)\ \pireturn \pifalse; \\
    \pielsestmt{
      \pityp{int} m \pia (\ell + u) \pidiv 2; \\
      \piif (a[m] = e)\ \pireturn \pitrue; \\
      \pielse\ \piifstmt{a[m] < e}{
	\piassert\piloc{R_1}:\ 0 \le m+1 \band u < |a| \band \psort(a,m+1,u); \\
	\pireturn \pifni{BinarySearch}(a, m+1, u, e);
      }\ \pielsestmt{
	\piassert\piloc{R_2}:\ 0 \le \ell \band m-1 < |a| \band \psort(a,\ell,m-1); \\
	\pireturn \pifni{BinarySearch}(a, \ell, m-1, e);
      }
    }
  }
}

\newcommand{\bsearchRuntimeSpecified}{
  \pifunction{\true}{\true}{bool}{BinarySearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piif (\ell > u)\ \pireturn \pifalse; \\
    \pielsestmt{
      \piassert 2 \ne 0; \\
      \pityp{int} m \pia (\ell + u) \pidiv 2; \\
      \piassert 0 \le m < |a|; \\
      \piif (a[m] = e)\ \pireturn \pitrue; \\
      \pielsestmt{
	\piassert 0 \le m < |a|; \\
	\piif (a[m] < e)\ \pireturn \pifni{BinarySearch}(a, m+1, u, e); \\
	\pielse \pireturn \pifni{BinarySearch}(a, \ell, m-1, e);
      }
    }
  }
}

\newcommand{\bsearchRuntimeProved}{
  \pifunction{0 \le \ell \band u < |a|}{\true}{bool}{BinarySearch}{
    \pityp{int[]} a,\ \pityp{int} \ell,\ \pityp{int} u,\ \pityp{int} e
  }{
    \piif (\ell > u)\ \pireturn \pifalse; \\
    \pielsestmt{
      \piassert 2 \ne 0; \\
      \pityp{int} m \pia (\ell + u) \pidiv 2; \\
      \piassert 0 \le m < |a|; \\
      \piif (a[m] = e)\ \pireturn \pitrue; \\
      \pielse \piif (a[m] < e)\ \pireturn \pifni{BinarySearch}(a, m+1, u, e); \\
      \pielse \pireturn \pifni{BinarySearch}(a, \ell, m-1, e);
    }
  }
}

% ----------- BubbleSort ----------------------- %

\newcommand{\bbsort}{{$\pifni{BubbleSort}$}}

\newcommand{\bbsortUnspecified}{
  \pifunction{\true}{\true}{int[]}{BubbleSort}{\pityp{int[]} a_0}{
    \pityp{int[]} a \pia a_0; \\
    \piforstmts{\pityp{int} i \pia |a| - 1}{i > 0}{i \pia i - 1}{
      \piforstmts{\pityp{int} j \pia 0}{j < i}{j \pia j + 1}{
	\piifstmt{a[j] > a[j + 1]}{
	  \pityp{int} t \pia a[j]; \\
	  a[j] \pia a[j+1]; \\
	  a[j+1] \pia t;
    }}} \\
    \pireturn a;
  }
}

\newcommand{\bbsortSortedSpecified}{
  \pifunction{\true}{
    \psort(\pirv, 0, |\pirv| - 1)
  }{int[]}{BubbleSort}{\pityp{int[]} a_0}{
    \pityp{int[]} a \pia a_0; \\
    \piforstmts{\pityp{int} i \pia |a| - 1}{i > 0}{i \pia i - 1}{
      \piforstmts{\pityp{int} j \pia 0}{j < i}{j \pia j + 1}{
	\piifstmt{a[j] > a[j + 1]}{
	  \pityp{int} t \pia a[j]; \\
	  a[j] \pia a[j+1]; \\
	  a[j+1] \pia t;
    }}} \\
    \pireturn a;
  }
}

\newcommand{\bbsortSortedProved}{
  \pifunction{\true}{
    \psort(\pirv, 0, |\pirv| - 1)
  }{int[]}{BubbleSort}{\pityp{int[]} a_0}{
    \pityp{int[]} a \pia a_0; \\
    \piforstmt{\piloc{L_1}:\ \piassertion{
	-1 \le i < |a| \\
	\band \ppart(a, 0, i, i+1, |a|-1) \\
	\band \psort(a, i, |a|-1)
    }}{\pityp{int} i \pia |a| - 1}{i > 0}{i \pia i - 1}{
      \piforstmt{\piloc{L_2}:\ \piassertion{
	1 \le i < |a| \band 0 \le j \le i \\
	\band \ppart(a, 0, i, i+1, |a|-1) \\
	\band \ppart(a, 0, j-1, j, j) \\
	\band \psort(a, i, |a|-1)
      }}{\pityp{int} j \pia 0}{j < i}{j \pia j + 1}{
	\piifstmt{a[j] > a[j + 1]}{
	  \pityp{int} t \pia a[j]; \\
	  a[j] \pia a[j+1]; \\
	  a[j+1] \pia t;
    }}} \\
    \pireturn a;
  }
}

\newcommand{\bbsortRuntimeSpecified}{
  \pifunction{\true}{\true}{int[]}{BubbleSort}{\pityp{int[]} a_0}{
    \pityp{int[]} a \pia a_0; \\
    \piforstmts{\pityp{int} i \pia |a| - 1}{i > 0}{i \pia i - 1}{
      \piforstmts{\pityp{int} j \pia 0}{j < i}{j \pia j + 1}{
	\piassert 0 \le j < |a|; \\
	\piassert 0 \le j + 1 < |a|; \\
	\piifstmt{a[j] > a[j + 1]}{
	  \piassert 0 \le j < |a|; \\
	  \pityp{int} t \pia a[j]; \\
	  \piassert 0 \le j < |a|; \\
	  \piassert 0 \le j + 1 < |a|; \\
	  a[j] \pia a[j+1]; \\
	  \piassert 0 \le j + 1 < |a|; \\
	  a[j+1] \pia t;
    }}} \\
    \pireturn a;
  }
}

\newcommand{\bbsortRuntimeSpecifiedShort}{
  \pifunction{\true}{\true}{int[]}{BubbleSort}{\pityp{int[]} a_0}{
    \pityp{int[]} a \pia a_0; \\
    \piforstmts{\pityp{int} i \pia |a| - 1}{i > 0}{i \pia i - 1}{
      \piforstmts{\pityp{int} j \pia 0}{j < i}{j \pia j + 1}{
	\piassert 0 \le j < |a| \band 0 \le j + 1 < |a|; \\
	\piifstmt{a[j] > a[j + 1]}{
	  \pityp{int} t \pia a[j]; \\
	  a[j] \pia a[j+1]; \\
	  a[j+1] \pia t;
    }}} \\
    \pireturn a;
  }
}

\newcommand{\bbsortRuntimeProved}{
  \pifunction{\true}{\true}{int[]}{BubbleSort}{\pityp{int[]} a_0}{
    \pityp{int[]} a \pia a_0; \\
    \piforstmt{
      \piloc{L_1}:\ -1 \le i < |a|
    }{\pityp{int} i \pia |a| - 1}{i > 0}{i \pia i - 1}{
      \piforstmt{
	\piloc{L_2}:\ 0 < i < |a| \band 0 \le j \le i
      }{\pityp{int} j \pia 0}{j < i}{j \pia j + 1}{
	\piassert\piloc{L_3}:\ 0 \le j < |a| \band 0 \le j + 1 < |a|; \\
	\piifstmt{a[j] > a[j + 1]}{
	  \pityp{int} t \pia a[j]; \\
	  a[j] \pia a[j+1]; \\
	  a[j+1] \pia t;
    }}} \\
    \pireturn a;
  }
}

% ----------- LinkedList ----------------------- %

\newcommand{\lltype}{
  \begin{piprogram}
    \pitypestruct{list}{
      \pityp{int} elem; \\
      \pistruct \pityp{list} next; \\
      \pityp{bool} isNil;
    }
    \\ \\
    \pidefine \pityp{list} nil =
    \pistructinit{elem\ =\ ?; \\ next\ =\ ?; \\ isNil\ =\ \pitrue;}
  \end{piprogram}
}

\newcommand{\llcons}{
  \pifunction{\true}{\true}{\pitype{list}}{Cons}{
    \pityp{int} e,\ \pityp{list} \ell
  }{
    \pireturn \pistructinit{
      elem = e; \\
      next = \ell; \\
      isNil = \pifalse;}
  }
}

\newcommand{\llofarray}{
  \pifunction{\true}{\true}{\pitype{list}}{ListOfArray}{\pityp{int[]} elems}{
    \pityp{list} \ell \pia nil; \\
    \piforstmts{\pityp{int} i \pia |elems| - 1}{i \ge 0}{i \pia i - 1}{
      \ell \pia \pifni{Cons}(elems[i], \ell);
    } \\
    \pireturn \ell;
  }
}
