Christophe Weblog Wiki Code Publications Music
grab-bag of changes
authorChristophe Rhodes <csr21@cantab.net>
Sun, 2 Mar 2014 15:59:33 +0000 (15:59 +0000)
committerChristophe Rhodes <csr21@cantab.net>
Sun, 2 Mar 2014 15:59:33 +0000 (15:59 +0000)
Most of the text is now there; there's still work to do in the Related
Work and Conclusions sections.  Also, export through the required ACM
proceedings LaTeX class now "works"

acm_proc_article-sp.cls [new file with mode: 0644]
els-specializers.org

diff --git a/acm_proc_article-sp.cls b/acm_proc_article-sp.cls
new file mode 100644 (file)
index 0000000..9ec6f3c
--- /dev/null
@@ -0,0 +1,1670 @@
+% ACM_PROC_ARTICLE-SP.CLS - VERSION 3.2SP\r
+% COMPATIBLE WITH THE "SIG-ALTERNATE" V2.4\r
+% Gerald Murray - April 22nd. 2009\r
+%\r
+% ---- Start of 'updates'  ----\r
+%\r
+% April 22nd. 2009 - Fixed 'Natbib' incompatibility problem - Gerry\r
+% April 22nd. 2009 - Fixed 'Babel' incompatibility problem - Gerry\r
+% April 22nd. 2009 - Inserted various bug-fixes and improvements - Gerry\r
+%\r
+% To produce Type 1 fonts in the document plus allow for 'normal LaTeX accenting' in the critical areas;\r
+% title, author block, section-heads, etc. etc. \r
+% i.e. the whole purpose of this version update is to NOT resort to 'inelegant accent patches'.\r
+% After much research, three extra .sty packages were added to the the tail (ae, aecompl, aeguill) to solve,\r
+% in particular, the accenting problem(s). We _could_ ask authors (via instructions/sample file) to 'include' these in\r
+% the source .tex file - in the preamble - but if everything is already provided ('behind the scenes' - embedded IN the .cls)\r
+% then this is less work for authors and also makes everything appear 'vanilla'.\r
+% NOTE: all 'patchwork accenting" has been commented out (here) and is no longer 'used' in the sample .tex file (either).\r
+% Gerry June 2007\r
+%\r
+% Rule widths changed to .5, author count (>6) fixed, roll-back for Type 3 problem. Gerry March 20th. 2007\r
+% Changes made to 'modernize' the fontnames but esp. for MikTeX users V2.4/2.5 - Nov. 30th. 2006\r
+% Updated the \email definition to allow for its use inside of 'shared affiliations' - Nov. 30th. 2006\r
+% Fixed the 'section number depth value' - Nov. 30th. 2006\r
+%\r
+% Footnotes inside table cells using \minipage (Oct. 2002)\r
+% Georgia fixed bug in sub-sub-section numbering in paragraphs (July 29th. 2002)\r
+% JS/GM fix to vertical spacing before Proofs (July 30th. 2002)\r
+%\r
+% Allowance made to switch default fonts between those systems using\r
+% normal/modern font names and those using 'Type 1' or 'Truetype' fonts.\r
+% See LINE NUMBER 269 for details.\r
+% Also provided for enumerated/annotated Corollaries 'surrounded' by\r
+% enumerated Theorems (line 844).\r
+% Gerry November 11th. 1999\r
+%\r
+% This 'sp' version does NOT produce the permission block.\r
+%\r
+% Major change in January 2000 was to include a "blank line" in between\r
+% new paragraphs. This involved major changes to the, then, acmproc-sp.cls  1.0SP\r
+% file, precipitating a 'new' name: "acm_proc_article-sp.cls" V2.01SP.\r
+%\r
+% ---- End of 'updates' ----\r
+%\r
+\def\fileversion{V3.2SP}         % for ACM's tracking purposes\r
+\def\filedate{April 22, 2009}    % Gerry Murray's tracking data\r
+\def\docdate {Wednesday 22nd. April 2009} % Gerry Murray (with deltas to doc}\r
+\usepackage{epsfig}\r
+\usepackage{amssymb}\r
+\usepackage{amsmath}\r
+\usepackage{amsfonts}\r
+% Need this for accents in Arial/Helvetica\r
+%\usepackage[T1]{fontenc}  % Gerry March 12, 2007 - causes Type 3 problems (body text)\r
+%\usepackage{textcomp}\r
+%\r
+% ACM_PROC_ARTICLE-SP  DOCUMENT STYLE\r
+% G.K.M. Tobin August-October 1999\r
+%    adapted from ARTICLE document style by Ken Traub, Olin Shivers\r
+%    also using elements of esub2acm.cls\r
+% LATEST REVISION V3.2SP - APRIL 2009\r
+% ARTICLE DOCUMENT STYLE -- Released 16 March 1988\r
+%    for LaTeX version 2.09\r
+% Copyright (C) 1988 by Leslie Lamport\r
+%\r
+%\r
+%%% ACM_PROC_ARTICLE-SP is a document style for producing two-column camera-ready pages for\r
+%%% ACM conferences, according to ACM specifications.  The main features of\r
+%%% this style are:\r
+%%%\r
+%%% 1)  Two columns.\r
+%%% 2)  Side and top margins of 4.5pc, bottom margin of 6pc, column gutter of\r
+%%%     2pc, hence columns are 20pc wide and 55.5pc tall.  (6pc =3D 1in, approx)\r
+%%% 3)  First page has title information, and an extra 6pc of space at the\r
+%%%     bottom of the first column for the ACM copyright notice.\r
+%%% 4)  Text is 9pt on 10pt baselines; titles (except main) are 9pt bold.\r
+%%%\r
+%%%\r
+%%% There are a few restrictions you must observe:\r
+%%%\r
+%%% 1)  You cannot change the font size; ACM wants you to use 9pt.\r
+%%% 3)  You must start your paper with the \maketitle command.  Prior to the\r
+%%%     \maketitle you must have \title and \author commands.  If you have a\r
+%%%     \date command it will be ignored; no date appears on the paper, since\r
+%%%     the proceedings will have a date on the front cover.\r
+%%% 4)  Marginal paragraphs, tables of contents, lists of figures and tables,\r
+%%%     and page headings are all forbidden.\r
+%%% 5)  The `figure' environment will produce a figure one column wide; if you\r
+%%%     want one that is two columns wide, use `figure*'.\r
+%%%\r
+%\r
+%%% Copyright Space:\r
+%%% This style automatically leaves 1" blank space at the bottom of page 1/\r
+%%% column 1.  This space can optionally be filled with some text using the\r
+%%% \toappear{...} command.  If used, this command must be BEFORE the \maketitle\r
+%%% command.  If this command is defined AND [preprint] is on, then the\r
+%%% space is filled with the {...} text (at the bottom); otherwise, it is\r
+%%% blank.  If you use \toappearbox{...} instead of \toappear{...} then a\r
+%%% box will be drawn around the text (if [preprint] is on).\r
+%%%\r
+%%% A typical usage looks like this:\r
+%%%     \toappear{To appear in the Ninth AES Conference on Medievil Lithuanian\r
+%%%               Embalming Technique, June 1991, Alfaretta, Georgia.}\r
+%%% This will be included in the preprint, and left out of the conference\r
+%%% version.\r
+%%%\r
+%%% WARNING:\r
+%%% Some dvi-ps converters heuristically allow chars to drift from their\r
+%%% true positions a few pixels. This may be noticeable with the 9pt sans-serif\r
+%%% bold font used for section headers.\r
+%%% You may turn this hackery off via the -e option:\r
+%%%     dvips -e 0 foo.dvi >foo.ps\r
+%%%\r
+\typeout{Document Class 'acm_proc_article-sp' <22nd. April '09>.  Modified by G.K.M. Tobin}\r
+\typeout{Based in part upon document Style `acmconf' <22 May 89>. Hacked 4/91 by}\r
+\typeout{shivers@cs.cmu.edu, 4/93 by theobald@cs.mcgill.ca}\r
+\typeout{Excerpts were taken from (Journal Style) 'esub2acm.cls'.}\r
+\typeout{****** Bugs/comments/suggestions  to Gerry Murray -- murray@hq.acm.org ******}\r
+\r
+\oddsidemargin 4.5pc\r
+\evensidemargin 4.5pc\r
+\advance\oddsidemargin by -1in  % Correct for LaTeX gratuitousness\r
+\advance\evensidemargin by -1in % Correct for LaTeX gratuitousness\r
+\marginparwidth 0pt             % Margin pars are not allowed.\r
+\marginparsep 11pt              % Horizontal space between outer margin and\r
+                                % marginal note\r
+\r
+                                % Top of page:\r
+\topmargin 4.5pc                % Nominal distance from top of page to top of\r
+                                % box containing running head.\r
+\advance\topmargin by -1in      % Correct for LaTeX gratuitousness\r
+\headheight 0pt                 % Height of box containing running head.\r
+\headsep 0pt                    % Space between running head and text.\r
+                                % Bottom of page:\r
+\footskip 30pt                  % Distance from baseline of box containing foot\r
+                                % to baseline of last line of text.\r
+\@ifundefined{footheight}{\newdimen\footheight}{}% this is for LaTeX2e\r
+\footheight 12pt                % Height of box containing running foot.\r
+\r
+\r
+%% Must redefine the top margin so there's room for headers and\r
+%% page numbers if you are using the preprint option. Footers\r
+%% are OK as is. Olin.\r
+\advance\topmargin by -37pt     % Leave 37pt above text for headers\r
+\headheight 12pt                % Height of box containing running head.\r
+\headsep 25pt                   % Space between running head and text.\r
+\r
+\textheight 666pt       % 9 1/4 column height\r
+\textwidth 42pc         % Width of text line.\r
+                        % For two-column mode:\r
+\columnsep 2pc          %    Space between columns\r
+\columnseprule 0pt      %    Width of rule between columns.\r
+\hfuzz 1pt              % Allow some variation in column width, otherwise it's\r
+                        % too hard to typeset in narrow columns.\r
+\r
+\footnotesep 5.6pt      % Height of strut placed at the beginning of every\r
+                        % footnote =3D height of normal \footnotesize strut,\r
+                        % so no extra space between footnotes.\r
+\r
+\skip\footins 8.1pt plus 4pt minus 2pt  % Space between last line of text and\r
+                                        % top of first footnote.\r
+\floatsep 11pt plus 2pt minus 2pt       % Space between adjacent floats moved\r
+                                        % to top or bottom of text page.\r
+\textfloatsep 18pt plus 2pt minus 4pt   % Space between main text and floats\r
+                                        % at top or bottom of page.\r
+\intextsep 11pt plus 2pt minus 2pt      % Space between in-text figures and\r
+                                        % text.\r
+\@ifundefined{@maxsep}{\newdimen\@maxsep}{}% this is for LaTeX2e\r
+\@maxsep 18pt                           % The maximum of \floatsep,\r
+                                        % \textfloatsep and \intextsep (minus\r
+                                        % the stretch and shrink).\r
+\dblfloatsep 11pt plus 2pt minus 2pt    % Same as \floatsep for double-column\r
+                                        % figures in two-column mode.\r
+\dbltextfloatsep 18pt plus 2pt minus 4pt% \textfloatsep for double-column\r
+                                        % floats.\r
+\@ifundefined{@dblmaxsep}{\newdimen\@dblmaxsep}{}% this is for LaTeX2e\r
+\@dblmaxsep 18pt                        % The maximum of \dblfloatsep and\r
+                                        % \dbltexfloatsep.\r
+\@fptop 0pt plus 1fil    % Stretch at top of float page/column. (Must be\r
+                         % 0pt plus ...)\r
+\@fpsep 8pt plus 2fil    % Space between floats on float page/column.\r
+\@fpbot 0pt plus 1fil    % Stretch at bottom of float page/column. (Must be\r
+                         % 0pt plus ... )\r
+\@dblfptop 0pt plus 1fil % Stretch at top of float page. (Must be 0pt plus ...)\r
+\@dblfpsep 8pt plus 2fil % Space between floats on float page.\r
+\@dblfpbot 0pt plus 1fil % Stretch at bottom of float page. (Must be\r
+                         % 0pt plus ... )\r
+\marginparpush 5pt       % Minimum vertical separation between two marginal\r
+                         % notes.\r
+\r
+\parskip 0pt                % Extra vertical space between paragraphs.\r
+                    % Set to 0pt outside sections, to keep section heads\r
+                    % uniformly spaced.  The value of parskip is set\r
+                    % to leading value _within_ sections.\r
+                    % 12 Jan 2000 gkmt\r
+\parindent 0pt                % Width of paragraph indentation.\r
+\partopsep 2pt plus 1pt minus 1pt% Extra vertical space, in addition to\r
+                                 % \parskip and \topsep, added when user\r
+                                 % leaves blank line before environment.\r
+\r
+\@lowpenalty   51       % Produced by \nopagebreak[1] or \nolinebreak[1]\r
+\@medpenalty  151       % Produced by \nopagebreak[2] or \nolinebreak[2]\r
+\@highpenalty 301       % Produced by \nopagebreak[3] or \nolinebreak[3]\r
+\r
+\@beginparpenalty -\@lowpenalty % Before a list or paragraph environment.\r
+\@endparpenalty   -\@lowpenalty % After a list or paragraph environment.\r
+\@itempenalty     -\@lowpenalty % Between list items.\r
+\r
+%\@namedef{ds@10pt}{\@latexerr{The `10pt' option is not allowed in the `acmconf'\r
+\@namedef{ds@10pt}{\ClassError{The `10pt' option is not allowed in the `acmconf'       % January 2008\r
+  document style.}\@eha}\r
+%\@namedef{ds@11pt}{\@latexerr{The `11pt' option is not allowed in the `acmconf'\r
+\@namedef{ds@11pt}{\ClassError{The `11pt' option is not allowed in the `acmconf'       % January 2008\r
+  document style.}\@eha}\r
+%\@namedef{ds@12pt}{\@latexerr{The `12pt' option is not allowed in the `acmconf'\r
+\@namedef{ds@12pt}{\ClassError{The `12pt' option is not allowed in the `acmconf'       % January 2008\r
+  document style.}\@eha}\r
+\r
+\@options\r
+\r
+\lineskip 2pt           % \lineskip is 1pt for all font sizes.\r
+\normallineskip 2pt\r
+\def\baselinestretch{1}\r
+\r
+\abovedisplayskip 9pt plus2pt minus4.5pt%\r
+\belowdisplayskip \abovedisplayskip\r
+\abovedisplayshortskip  \z@ plus3pt%\r
+\belowdisplayshortskip  5.4pt plus3pt minus3pt%\r
+\let\@listi\@listI     % Setting of \@listi added 9 Jun 87\r
+\r
+\def\small{\@setsize\small{9pt}\viiipt\@viiipt\r
+\abovedisplayskip 7.6pt plus 3pt minus 4pt%\r
+\belowdisplayskip \abovedisplayskip\r
+\abovedisplayshortskip \z@ plus2pt%\r
+\belowdisplayshortskip 3.6pt plus2pt minus 2pt\r
+\def\@listi{\leftmargin\leftmargini %% Added 22 Dec 87\r
+\topsep 4pt plus 2pt minus 2pt\parsep 2pt plus 1pt minus 1pt\r
+\itemsep \parsep}}\r
+\r
+\def\footnotesize{\@setsize\footnotesize{9pt}\ixpt\@ixpt\r
+\abovedisplayskip 6.4pt plus 2pt minus 4pt%\r
+\belowdisplayskip \abovedisplayskip\r
+\abovedisplayshortskip \z@ plus 1pt%\r
+\belowdisplayshortskip 2.7pt plus 1pt minus 2pt\r
+\def\@listi{\leftmargin\leftmargini %% Added 22 Dec 87\r
+\topsep 3pt plus 1pt minus 1pt\parsep 2pt plus 1pt minus 1pt\r
+\itemsep \parsep}}\r
+\r
+\newcount\aucount\r
+\newcount\originalaucount\r
+\newdimen\auwidth\r
+\auwidth=\textwidth\r
+\newdimen\auskip\r
+\newcount\auskipcount\r
+\newdimen\auskip\r
+\global\auskip=1pc\r
+\newdimen\allauboxes\r
+\allauboxes=\auwidth\r
+\newtoks\addauthors\r
+\newcount\addauflag\r
+\global\addauflag=0 %Haven't shown additional authors yet\r
+\r
+\newtoks\subtitletext\r
+\gdef\subtitle#1{\subtitletext={#1}}\r
+\r
+\gdef\additionalauthors#1{\addauthors={#1}}\r
+\r
+\gdef\numberofauthors#1{\global\aucount=#1\r
+\ifnum\aucount>3\global\originalaucount=\aucount \global\aucount=3\fi %g}  % 3 OK - Gerry March 2007\r
+\global\auskipcount=\aucount\global\advance\auskipcount by 1\r
+\global\multiply\auskipcount by 2\r
+\global\multiply\auskip by \auskipcount\r
+\global\advance\auwidth by -\auskip\r
+\global\divide\auwidth by \aucount}\r
+\r
+% \and was modified to count the number of authors.  GKMT 12 Aug 1999\r
+\def\alignauthor{%                  % \begin{tabular}\r
+\end{tabular}%\r
+  \begin{tabular}[t]{p{\auwidth}}\centering}%\r
+\r
+\r
+%  *** NOTE *** NOTE *** NOTE *** NOTE ***\r
+%  If you have 'font problems' then you may need\r
+%  to change these, e.g. 'arialb' instead of "arialbd".\r
+%  Gerry Murray 11/11/1999\r
+%  *** OR ** comment out block A and activate block B or vice versa.\r
+% **********************************************\r
+%\r
+%  -- Start of block A -- (Type 1 or Truetype fonts)\r
+%\newfont{\secfnt}{timesbd at 12pt} % was timenrb originally - now is timesbd\r
+%\newfont{\secit}{timesbi at 12pt}   %13 Jan 00 gkmt\r
+%\newfont{\subsecfnt}{timesi at 11pt} % was timenrri originally - now is timesi\r
+%\newfont{\subsecit}{timesbi at 11pt} % 13 Jan 00 gkmt -- was times changed to timesbi gm 2/4/2000\r
+%                         % because "normal" is italic, "italic" is Roman\r
+%\newfont{\ttlfnt}{arialbd at 18pt} % was arialb originally - now is arialbd\r
+%\newfont{\ttlit}{arialbi at 18pt}    % 13 Jan 00 gkmt\r
+%\newfont{\subttlfnt}{arial at 14pt} % was arialr originally - now is arial\r
+%\newfont{\subttlit}{ariali at 14pt} % 13 Jan 00 gkmt\r
+%\newfont{\subttlbf}{arialbd at 14pt}  % 13 Jan 00 gkmt\r
+%\newfont{\aufnt}{arial at 12pt} % was arialr originally - now is arial\r
+%\newfont{\auit}{ariali at 12pt} % 13 Jan 00 gkmt\r
+%\newfont{\affaddr}{arial at 10pt} % was arialr originally - now is arial\r
+%\newfont{\affaddrit}{ariali at 10pt} %13 Jan 00 gkmt\r
+%\newfont{\eaddfnt}{arial at 12pt} % was arialr originally - now is arial\r
+%\newfont{\ixpt}{times at 9pt} % was timenrr originally - now is times\r
+%\newfont{\confname}{timesi at 8pt} % was timenrri - now is timesi\r
+%\newfont{\crnotice}{times at 8pt} % was timenrr originally - now is times\r
+%\newfont{\ninept}{times at 9pt} % was timenrr originally - now is times\r
+% *********************************************\r
+%  -- End of block A --\r
+%\r
+%\r
+% -- Start of block B -- UPDATED FONT NAMES\r
+% *********************************************\r
+% Gerry Murray 11/30/2006\r
+% *********************************************\r
+\newfont{\secfnt}{ptmb8t at 12pt}\r
+\newfont{\secit}{ptmbi8t at 12pt}    %13 Jan 00 gkmt\r
+\newfont{\subsecfnt}{ptmri8t at 11pt}\r
+\newfont{\subsecit}{ptmbi8t at 11pt}  % \r
+\newfont{\ttlfnt}{phvb8t at 18pt}\r
+\newfont{\ttlit}{phvbo8t at 18pt}    % GM 2/4/2000\r
+\newfont{\subttlfnt}{phvr8t at 14pt}\r
+\newfont{\subttlit}{phvro8t at 14pt} % GM 2/4/2000\r
+\newfont{\subttlbf}{phvb8t at 14pt}  % 13 Jan 00 gkmt\r
+\newfont{\aufnt}{phvr8t at 12pt}\r
+\newfont{\auit}{phvro8t at 12pt}     % GM 2/4/2000\r
+\newfont{\affaddr}{phvr8t at 10pt}\r
+\newfont{\affaddrit}{phvro8t at 10pt} % GM 2/4/2000\r
+\newfont{\eaddfnt}{phvr8t at 12pt}\r
+\newfont{\ixpt}{ptmr8t at 9pt}\r
+\newfont{\confname}{ptmri8t at 8pt}\r
+\newfont{\crnotice}{ptmr8t at 8pt}\r
+\newfont{\ninept}{ptmr8t at 9pt}\r
+% +++++++++++++++++++++++++++++++++++++++++++++\r
+% -- End of block B --\r
+\r
+%\def\email#1{{{\eaddfnt{\vskip 4pt#1}}}}\r
+% If we have an email, inside a "shared affiliation" then we need the following instead\r
+\def\email#1{{{\eaddfnt{\par #1}}}}       % revised  - GM - 11/30/2006\r
+\r
+\def\addauthorsection{\ifnum\originalaucount>6  % was 3 - Gerry March 2007\r
+    \section{Additional Authors}\the\addauthors\r
+  \fi}\r
+\r
+\newcount\savesection\r
+\newcount\sectioncntr\r
+\global\sectioncntr=1\r
+\r
+\setcounter{secnumdepth}{3}\r
+\r
+\def\appendix{\par\r
+\section*{APPENDIX}\r
+\setcounter{section}{0}\r
+ \setcounter{subsection}{0}\r
+ \def\thesection{\Alph{section}} }\r
+\r
+\r
+\leftmargini 22.5pt\r
+\leftmarginii 19.8pt    % > \labelsep + width of '(m)'\r
+\leftmarginiii 16.8pt   % > \labelsep + width of 'vii.'\r
+\leftmarginiv 15.3pt    % > \labelsep + width of 'M.'\r
+\leftmarginv 9pt\r
+\leftmarginvi 9pt\r
+\r
+\leftmargin\leftmargini\r
+\labelsep 4.5pt\r
+\labelwidth\leftmargini\advance\labelwidth-\labelsep\r
+\r
+\def\@listI{\leftmargin\leftmargini \parsep 3.6pt plus 2pt minus 1pt%\r
+\topsep 7.2pt plus 2pt minus 4pt%\r
+\itemsep 3.6pt plus 2pt minus 1pt}\r
+\r
+\let\@listi\@listI\r
+\@listi\r
+\r
+\def\@listii{\leftmargin\leftmarginii\r
+   \labelwidth\leftmarginii\advance\labelwidth-\labelsep\r
+   \topsep 3.6pt plus 2pt minus 1pt\r
+   \parsep 1.8pt plus 0.9pt minus 0.9pt\r
+   \itemsep \parsep}\r
+\r
+\def\@listiii{\leftmargin\leftmarginiii\r
+    \labelwidth\leftmarginiii\advance\labelwidth-\labelsep\r
+    \topsep 1.8pt plus 0.9pt minus 0.9pt\r
+    \parsep \z@ \partopsep 1pt plus 0pt minus 1pt\r
+    \itemsep \topsep}\r
+\r
+\def\@listiv{\leftmargin\leftmarginiv\r
+     \labelwidth\leftmarginiv\advance\labelwidth-\labelsep}\r
+\r
+\def\@listv{\leftmargin\leftmarginv\r
+     \labelwidth\leftmarginv\advance\labelwidth-\labelsep}\r
+\r
+\def\@listvi{\leftmargin\leftmarginvi\r
+     \labelwidth\leftmarginvi\advance\labelwidth-\labelsep}\r
+\r
+\def\labelenumi{\theenumi.}\r
+\def\theenumi{\arabic{enumi}}\r
+\r
+\def\labelenumii{(\theenumii)}\r
+\def\theenumii{\alph{enumii}}\r
+\def\p@enumii{\theenumi}\r
+\r
+\def\labelenumiii{\theenumiii.}\r
+\def\theenumiii{\roman{enumiii}}\r
+\def\p@enumiii{\theenumi(\theenumii)}\r
+\r
+\def\labelenumiv{\theenumiv.}\r
+\def\theenumiv{\Alph{enumiv}}\r
+\def\p@enumiv{\p@enumiii\theenumiii}\r
+\r
+\def\labelitemi{$\bullet$}\r
+\def\labelitemii{\bf --}\r
+\def\labelitemiii{$\ast$}\r
+\def\labelitemiv{$\cdot$}\r
+\r
+\def\verse{\let\\=\@centercr\r
+  \list{}{\itemsep\z@ \itemindent -1.5em\listparindent \itemindent\r
+          \rightmargin\leftmargin\advance\leftmargin 1.5em}\item[]}\r
+\let\endverse\endlist\r
+\r
+\def\quotation{\list{}{\listparindent 1.5em\r
+    \itemindent\listparindent\r
+    \rightmargin\leftmargin \parsep 0pt plus 1pt}\item[]}\r
+\let\endquotation=\endlist\r
+\r
+\def\quote{\list{}{\rightmargin\leftmargin}\item[]}\r
+\let\endquote=\endlist\r
+\r
+\def\descriptionlabel#1{\hspace\labelsep \bf #1}\r
+\def\description{\list{}{\labelwidth\z@ \itemindent-\leftmargin\r
+       \let\makelabel\descriptionlabel}}\r
+\r
+\let\enddescription\endlist\r
+\r
+\def\theequation{\arabic{equation}}\r
+\r
+\arraycolsep 4.5pt   % Half the space between columns in an array environment.\r
+\tabcolsep 5.4pt     % Half the space between columns in a tabular environment.\r
+\arrayrulewidth .5pt % Width of rules in array and tabular environment. % (was .4) updated Gerry March 20 2007\r
+\doublerulesep 1.8pt % Space between adjacent rules in array or tabular env.\r
+\r
+\tabbingsep \labelsep   % Space used by the \' command.  (See LaTeX manual.)\r
+\r
+\skip\@mpfootins =\skip\footins\r
+\r
+\fboxsep =2.7pt      % Space left between box and text by \fbox and \framebox.\r
+\fboxrule =.5pt      % Width of rules in box made by \fbox and \framebox. % (was .4) updated Gerry March 20 2007\r
+\r
+\def\thepart{\Roman{part}} % Roman numeral part numbers.\r
+\def\thesection       {\arabic{section}}\r
+\def\thesubsection    {\thesection.\arabic{subsection}}\r
+%\def\thesubsubsection {\thesubsection.\arabic{subsubsection}} % GM 7/30/2002\r
+%\def\theparagraph     {\thesubsubsection.\arabic{paragraph}}  % GM 7/30/2002\r
+\def\thesubparagraph  {\theparagraph.\arabic{subparagraph}}\r
+\r
+\def\@pnumwidth{1.55em}\r
+\def\@tocrmarg {2.55em}\r
+\def\@dotsep{4.5}\r
+\setcounter{tocdepth}{3}\r
+\r
+%\def\tableofcontents{\@latexerr{\tableofcontents: Tables of contents are not\r
+%  allowed in the `acmconf' document style.}\@eha}\r
+\r
+\def\tableofcontents{\ClassError{%\r
+    \string\tableofcontents\space is not allowed in the `acmconf' document     % January 2008\r
+    style}\@eha}\r
+\r
+\def\l@part#1#2{\addpenalty{\@secpenalty}\r
+   \addvspace{2.25em plus 1pt}  % space above part line\r
+   \begingroup\r
+   \@tempdima 3em       % width of box holding part number, used by\r
+     \parindent \z@ \rightskip \@pnumwidth      %% \numberline\r
+     \parfillskip -\@pnumwidth\r
+     {\large \bf        % set line in \large boldface\r
+     \leavevmode        % TeX command to enter horizontal mode.\r
+     #1\hfil \hbox to\@pnumwidth{\hss #2}}\par\r
+     \nobreak           % Never break after part entry\r
+   \endgroup}\r
+\r
+\def\l@section#1#2{\addpenalty{\@secpenalty} % good place for page break\r
+   \addvspace{1.0em plus 1pt}   % space above toc entry\r
+   \@tempdima 1.5em             % width of box holding section number\r
+   \begingroup\r
+     \parindent \z@ \rightskip \@pnumwidth\r
+     \parfillskip -\@pnumwidth\r
+     \bf                        % Boldface.\r
+     \leavevmode                % TeX command to enter horizontal mode.\r
+      \advance\leftskip\@tempdima %% added 5 Feb 88 to conform to\r
+      \hskip -\leftskip           %% 25 Jan 88 change to \numberline\r
+     #1\nobreak\hfil \nobreak\hbox to\@pnumwidth{\hss #2}\par\r
+   \endgroup}\r
+\r
+\r
+\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}}\r
+\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}}\r
+\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}}\r
+\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}}\r
+\r
+%\def\listoffigures{\@latexerr{\listoffigures: Lists of figures are not\r
+%  allowed in the `acmconf' document style.}\@eha}\r
+\r
+\def\listoffigures{\ClassError{%\r
+    \string\listoffigures\space is not allowed in the `acmconf' document       % January 2008\r
+    style}\@eha}\r
+\r
+\def\l@figure{\@dottedtocline{1}{1.5em}{2.3em}}\r
+\r
+%\def\listoftables{\@latexerr{\listoftables: Lists of tables are not\r
+%  allowed in the `acmconf' document style.}\@eha}\r
+%\let\l@table\l@figure\r
+\r
+\def\listoftables{\ClassError{%\r
+    \string\listoftables\space is not allowed in the `acmconf' document                % January 2008\r
+    style}\@eha}\r
+ \let\l@table\l@figure\r
+\r
+\def\footnoterule{\kern-3\p@\r
+  \hrule width .5\columnwidth   % (was .4) updated Gerry March 20 2007\r
+  \kern 2.6\p@}                 % The \hrule has default height of .4pt % (was .4) updated Gerry March 20 2007\r
+% ------\r
+\long\def\@makefntext#1{\noindent \r
+%\hbox to .5em{\hss$^{\@thefnmark}$}#1}   % original\r
+\hbox to .5em{\hss\textsuperscript{\@thefnmark}}#1}  % C. Clifton / GM Oct. 2nd. 2002\r
+% -------\r
+\r
+\long\def\@maketntext#1{\noindent\r
+#1}\r
+\r
+\long\def\@maketitlenotetext#1#2{\noindent\r
+            \hbox to 1.8em{\hss$^{#1}$}#2}\r
+\r
+\setcounter{topnumber}{2}\r
+\def\topfraction{.7}\r
+\setcounter{bottomnumber}{1}\r
+\def\bottomfraction{.3}\r
+\setcounter{totalnumber}{3}\r
+\def\textfraction{.2}\r
+\def\floatpagefraction{.5}\r
+\setcounter{dbltopnumber}{2}\r
+\def\dbltopfraction{.7}\r
+\def\dblfloatpagefraction{.5}\r
+\r
+\long\def\@makecaption#1#2{\r
+   \vskip \baselineskip\r
+   \setbox\@tempboxa\hbox{\textbf{#1: #2}}\r
+   \ifdim \wd\@tempboxa >\hsize % IF longer than one line:\r
+       \textbf{#1: #2}\par               %   THEN set as ordinary paragraph.\r
+     \else                      %   ELSE  center.\r
+       \hbox to\hsize{\hfil\box\@tempboxa\hfil}\par\r
+   \fi}\r
+\r
+\@ifundefined{figure}{\newcounter {figure}} % this is for LaTeX2e\r
+\r
+\def\fps@figure{tbp}\r
+\def\ftype@figure{1}\r
+\def\ext@figure{lof}\r
+\def\fnum@figure{Figure \thefigure}\r
+\def\figure{\@float{figure}}\r
+%\let\endfigure\end@float\r
+\def\endfigure{\end@float}             % Gerry January 2008\r
+\@namedef{figure*}{\@dblfloat{figure}}\r
+\@namedef{endfigure*}{\end@dblfloat}\r
+\r
+\@ifundefined{table}{\newcounter {table}} % this is for LaTeX2e\r
+\r
+\def\fps@table{tbp}\r
+\def\ftype@table{2}\r
+\def\ext@table{lot}\r
+\def\fnum@table{Table \thetable}\r
+\def\table{\@float{table}}\r
+%\let\endtable\end@float\r
+\def\endtable{\end@float}              % Gerry January 2008\r
+\@namedef{table*}{\@dblfloat{table}}\r
+\@namedef{endtable*}{\end@dblfloat}\r
+\r
+\newtoks\titleboxnotes\r
+\newcount\titleboxnoteflag\r
+\r
+\def\maketitle{\par\r
+ \begingroup\r
+   \def\thefootnote{\fnsymbol{footnote}}\r
+   \def\@makefnmark{\hbox\r
+       to 0pt{$^{\@thefnmark}$\hss}}\r
+     \twocolumn[\@maketitle]\r
+\@thanks\r
+ \endgroup\r
+ \setcounter{footnote}{0}\r
+ \let\maketitle\relax\r
+ \let\@maketitle\relax\r
+ \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\gdef\@subtitle{}\let\thanks\relax\r
+ \@copyrightspace}\r
+\r
+%% CHANGES ON NEXT LINES\r
+\newif\if@ll % to record which version of LaTeX is in use\r
+\r
+\expandafter\ifx\csname LaTeXe\endcsname\relax % LaTeX2.09 is used\r
+\else% LaTeX2e is used, so set ll to true\r
+\global\@lltrue\r
+\fi\r
+\r
+\if@ll\r
+  \NeedsTeXFormat{LaTeX2e}\r
+  \ProvidesClass{acm_proc_article-sp} [2009/04/22 - V3.2SP - based on esub2acm.sty <23 April 96>]\r
+  \RequirePackage{latexsym}% QUERY: are these two really needed?\r
+  \let\dooptions\ProcessOptions\r
+\else\r
+  \let\dooptions\@options\r
+\fi\r
+%% END CHANGES\r
+\r
+\def\@height{height}\r
+\def\@width{width}\r
+\def\@minus{minus}\r
+\def\@plus{plus}\r
+\def\hb@xt@{\hbox to}\r
+\newif\if@faircopy\r
+\@faircopyfalse\r
+\def\ds@faircopy{\@faircopytrue}\r
+\r
+\def\ds@preprint{\@faircopyfalse}\r
+\r
+\@twosidetrue\r
+\@mparswitchtrue\r
+\def\ds@draft{\overfullrule 5\p@}\r
+%% CHANGE ON NEXT LINE\r
+\dooptions\r
+\r
+\lineskip \p@\r
+\normallineskip \p@\r
+\def\baselinestretch{1}\r
+\def\@ptsize{0} %needed for amssymbols.sty\r
+\r
+%% CHANGES ON NEXT LINES\r
+\if@ll% allow use of old-style font change commands in LaTeX2e\r
+\@maxdepth\maxdepth\r
+%\r
+\DeclareOldFontCommand{\rm}{\ninept\rmfamily}{\mathrm}\r
+\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}\r
+\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}\r
+\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}\r
+\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}\r
+\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}\r
+\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}\r
+\DeclareRobustCommand*{\cal}{\@fontswitch{\relax}{\mathcal}}\r
+\DeclareRobustCommand*{\mit}{\@fontswitch{\relax}{\mathnormal}}\r
+\fi\r
+%\r
+\if@ll\r
+ \renewcommand{\rmdefault}{cmr}  % was 'ttm'\r
+% Note! I have also found 'mvr' to work ESPECIALLY well.\r
+% Gerry - October 1999\r
+% You may need to change your LV1times.fd file so that sc is\r
+% mapped to cmcsc - -for smallcaps -- that is if you decide\r
+% to change {cmr} to {times} above. (Not recommended)\r
+  \renewcommand{\@ptsize}{}\r
+  \renewcommand{\normalsize}{%\r
+    \@setfontsize\normalsize\@ixpt{10.5\p@}%\ninept%\r
+    \abovedisplayskip 6\p@ \@plus2\p@ \@minus\p@\r
+    \belowdisplayskip \abovedisplayskip\r
+    \abovedisplayshortskip 6\p@ \@minus 3\p@\r
+    \belowdisplayshortskip 6\p@ \@minus 3\p@\r
+    \let\@listi\@listI\r
+  }\r
+\else\r
+  \def\@normalsize{%changed next to 9 from 10\r
+    \@setsize\normalsize{9\p@}\ixpt\@ixpt\r
+   \abovedisplayskip 6\p@ \@plus2\p@ \@minus\p@\r
+    \belowdisplayskip \abovedisplayskip\r
+    \abovedisplayshortskip 6\p@ \@minus 3\p@\r
+    \belowdisplayshortskip 6\p@ \@minus 3\p@\r
+    \let\@listi\@listI\r
+  }%\r
+\fi\r
+\if@ll\r
+  \newcommand\scriptsize{\@setfontsize\scriptsize\@viipt{8\p@}}\r
+  \newcommand\tiny{\@setfontsize\tiny\@vpt{6\p@}}\r
+  \newcommand\large{\@setfontsize\large\@xiipt{14\p@}}\r
+  \newcommand\Large{\@setfontsize\Large\@xivpt{18\p@}}\r
+  \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{20\p@}}\r
+  \newcommand\huge{\@setfontsize\huge\@xxpt{25\p@}}\r
+  \newcommand\Huge{\@setfontsize\Huge\@xxvpt{30\p@}}\r
+\else\r
+  \def\scriptsize{\@setsize\scriptsize{8\p@}\viipt\@viipt}\r
+  \def\tiny{\@setsize\tiny{6\p@}\vpt\@vpt}\r
+  \def\large{\@setsize\large{14\p@}\xiipt\@xiipt}\r
+  \def\Large{\@setsize\Large{18\p@}\xivpt\@xivpt}\r
+  \def\LARGE{\@setsize\LARGE{20\p@}\xviipt\@xviipt}\r
+  \def\huge{\@setsize\huge{25\p@}\xxpt\@xxpt}\r
+  \def\Huge{\@setsize\Huge{30\p@}\xxvpt\@xxvpt}\r
+\fi\r
+\normalsize\r
+\r
+% make aubox hsize/number of authors up to 3, less gutter\r
+% then showbox gutter showbox gutter showbox -- GKMT Aug 99\r
+\newbox\@acmtitlebox\r
+\def\@maketitle{\newpage\r
+ \null\r
+ \setbox\@acmtitlebox\vbox{%\r
+\baselineskip 20pt\r
+\vskip 2em                   % Vertical space above title.\r
+   \begin{center}\r
+    {\ttlfnt \@title\par}       % Title set in 18pt Helvetica (Arial) bold size.\r
+    \vskip 1.5em                % Vertical space after title.\r
+%This should be the subtitle.\r
+{\subttlfnt \the\subtitletext\par}\vskip 1.25em%\fi\r
+    {\baselineskip 16pt\aufnt   % each author set in \12 pt Arial, in a\r
+     \lineskip .5em             % tabular environment\r
+     \begin{tabular}[t]{c}\@author\r
+     \end{tabular}\par}\r
+    \vskip 1.5em               % Vertical space after author.\r
+   \end{center}}\r
+ \dimen0=\ht\@acmtitlebox\r
+ \advance\dimen0 by -12.75pc\relax % Increased space for title box -- KBT\r
+ \unvbox\@acmtitlebox\r
+ \ifdim\dimen0<0.0pt\relax\vskip-\dimen0\fi}\r
+\r
+\r
+\newcount\titlenotecount\r
+\global\titlenotecount=0\r
+\newtoks\tntoks\r
+\newtoks\tntokstwo\r
+\newtoks\tntoksthree\r
+\newtoks\tntoksfour\r
+\newtoks\tntoksfive\r
+\r
+\def\abstract{\r
+\ifnum\titlenotecount>0 % was =1\r
+    \insert\footins{%\r
+    \reset@font\footnotesize\r
+        \interlinepenalty\interfootnotelinepenalty\r
+        \splittopskip\footnotesep\r
+        \splitmaxdepth \dp\strutbox \floatingpenalty \@MM\r
+        \hsize\columnwidth \@parboxrestore\r
+        \protected@edef\@currentlabel{%\r
+        }%\r
+        \color@begingroup\r
+\ifnum\titlenotecount=1\r
+      \@maketntext{%\r
+         \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\@finalstrut\strutbox}%\r
+\fi\r
+\ifnum\titlenotecount=2\r
+      \@maketntext{%\r
+      \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\@finalstrut\strutbox}%\r
+\fi\r
+\ifnum\titlenotecount=3\r
+      \@maketntext{%\r
+         \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\@finalstrut\strutbox}%\r
+\fi\r
+\ifnum\titlenotecount=4\r
+      \@maketntext{%\r
+         \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\S$}\rule\z@\footnotesep\ignorespaces\the\tntoksfour\@finalstrut\strutbox}%\r
+\fi\r
+\ifnum\titlenotecount=5\r
+      \@maketntext{%\r
+         \raisebox{4pt}{$\ast$}\rule\z@\footnotesep\ignorespaces\the\tntoks\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\dagger$}\rule\z@\footnotesep\ignorespaces\the\tntokstwo\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\ddagger$}\rule\z@\footnotesep\ignorespaces\the\tntoksthree\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\S$}\rule\z@\footnotesep\ignorespaces\the\tntoksfour\par\@finalstrut\strutbox}%\r
+\@maketntext{%\r
+         \raisebox{4pt}{$\P$}\rule\z@\footnotesep\ignorespaces\the\tntoksfive\@finalstrut\strutbox}%\r
+\fi\r
+   \color@endgroup} %g}\r
+\fi\r
+\setcounter{footnote}{0}\r
+\section*{ABSTRACT}\normalsize %\the\parskip \the\baselineskip%\ninept\r
+}\r
+\r
+\def\endabstract{\if@twocolumn\else\endquotation\fi}\r
+\r
+\def\keywords{\if@twocolumn\r
+\section*{Keywords}\r
+\else \small\r
+\quotation\r
+\fi}\r
+\r
+% I've pulled the check for 2 cols, since proceedings are _always_\r
+% two-column  11 Jan 2000 gkmt\r
+\def\terms{%\if@twocolumn\r
+\section*{General Terms}\r
+%\else \small\r
+%\quotation\the\parskip\r
+%\fi}\r
+}\r
+\r
+% -- Classification needs to be a bit smart due to optionals - Gerry/Georgia November 2nd. 1999\r
+\newcount\catcount\r
+\global\catcount=1\r
+\r
+\def\category#1#2#3{%\r
+\ifnum\catcount=1\r
+\section*{Categories and Subject Descriptors}\r
+\advance\catcount by 1\else{\unskip; }\fi\r
+    \@ifnextchar [{\@category{#1}{#2}{#3}}{\@category{#1}{#2}{#3}[]}%\r
+}\r
+\r
+\def\@category#1#2#3[#4]{%\r
+    \begingroup\r
+        \let\and\relax\r
+            #1 [\textbf{#2}]%\r
+            \if!#4!%\r
+                \if!#3!\else : #3\fi\r
+            \else\r
+                :\space\r
+                \if!#3!\else #3\kern\z@---\hskip\z@\fi\r
+                \textit{#4}%\r
+            \fi\r
+    \endgroup\r
+}\r
+%\r
+\r
+%%% This section (written by KBT) handles the 1" box in the lower left\r
+%%% corner of the left column of the first page by creating a picture,\r
+%%% and inserting the predefined string at the bottom (with a negative\r
+%%% displacement to offset the space allocated for a non-existent\r
+%%% caption).\r
+%%%\r
+\newtoks\copyrightnotice\r
+\def\ftype@copyrightbox{8}\r
+\def\@copyrightspace{\r
+\@float{copyrightbox}[b]\r
+\begin{center}\r
+\setlength{\unitlength}{1pc}\r
+\begin{picture}(20,6) %Space for copyright notice\r
+\put(0,-0.95){\crnotice{\@toappear}}\r
+\end{picture}\r
+\end{center}\r
+\end@float}\r
+\r
+\def\@toappear{} % Default setting blank - commands below change this.\r
+\long\def\toappear#1{\def\@toappear{\parbox[b]{20pc}{\baselineskip 9pt#1}}}\r
+\def\toappearbox#1{\def\@toappear{\raisebox{5pt}{\framebox[20pc]{\parbox[b]{19pc}{#1}}}}}\r
+\r
+\newtoks\conf\r
+\newtoks\confinfo\r
+\def\conferenceinfo#1#2{\global\conf={#1}\global\confinfo{#2}}\r
+\r
+\r
+%\def\marginpar{\@latexerr{The \marginpar command is not allowed in the\r
+%  `acmconf' document style.}\@eha}\r
+\r
+\def\marginpar{\ClassError{%\r
+    \string\marginpar\space is not allowed in the `acmconf' document           % January 2008\r
+    style}\@eha}\r
+\r
+\mark{{}{}}     % Initializes TeX's marks\r
+\r
+\def\today{\ifcase\month\or\r
+  January\or February\or March\or April\or May\or June\or\r
+  July\or August\or September\or October\or November\or December\fi\r
+  \space\number\day, \number\year}\r
+\r
+\def\@begintheorem#1#2{%\r
+    \trivlist\r
+    \item[%\r
+        \hskip 10\p@\r
+        \hskip \labelsep\r
+        {{\sc #1}\hskip 5\p@\relax#2.}%\r
+    ]\r
+    \it\r
+}\r
+\def\@opargbegintheorem#1#2#3{%\r
+    \trivlist\r
+    \item[%\r
+        \hskip 10\p@\r
+        \hskip \labelsep\r
+        {\sc #1\ #2\             % This mod by Gerry to enumerate corollaries\r
+   \setbox\@tempboxa\hbox{(#3)}  % and bracket the 'corollary title'\r
+        \ifdim \wd\@tempboxa>\z@ % and retain the correct numbering of e.g. theorems\r
+            \hskip 5\p@\relax    % if they occur 'around' said corollaries.\r
+            \box\@tempboxa       % Gerry - Nov. 1999.\r
+        \fi.}%\r
+    ]\r
+    \it\r
+}\r
+\newif\if@qeded\r
+\global\@qededfalse\r
+\r
+% -- original\r
+%\def\proof{%\r
+%  \vspace{-\parskip} % GM July 2000 (for tighter spacing)\r
+%    \global\@qededfalse\r
+%    \@ifnextchar[{\@xproof}{\@proof}%\r
+%}\r
+% -- end of original\r
+\r
+% (JSS) Fix for vertical spacing bug - Gerry Murray July 30th. 2002\r
+\def\proof{%\r
+\vspace{-\lastskip}\vspace{-\parsep}\penalty-51%\r
+\global\@qededfalse\r
+\@ifnextchar[{\@xproof}{\@proof}%\r
+}\r
+\r
+\def\endproof{%\r
+    \if@qeded\else\qed\fi\r
+    \endtrivlist\r
+}\r
+\def\@proof{%\r
+    \trivlist\r
+    \item[%\r
+        \hskip 10\p@\r
+        \hskip \labelsep\r
+        {\sc Proof.}%\r
+    ]\r
+    \ignorespaces\r
+}\r
+\def\@xproof[#1]{%\r
+    \trivlist\r
+    \item[\hskip 10\p@\hskip \labelsep{\sc Proof #1.}]%\r
+    \ignorespaces\r
+}\r
+\def\qed{%\r
+    \unskip\r
+    \kern 10\p@\r
+    \begingroup\r
+        \unitlength\p@\r
+        \linethickness{.4\p@}%\r
+        \framebox(6,6){}%\r
+    \endgroup\r
+    \global\@qededtrue\r
+}\r
+\r
+\def\newdef#1#2{%\r
+    \expandafter\@ifdefinable\csname #1\endcsname\r
+        {\@definecounter{#1}%\r
+         \expandafter\xdef\csname the#1\endcsname{\@thmcounter{#1}}%\r
+         \global\@namedef{#1}{\@defthm{#1}{#2}}%\r
+         \global\@namedef{end#1}{\@endtheorem}%\r
+    }%\r
+}\r
+\def\@defthm#1#2{%\r
+    \refstepcounter{#1}%\r
+    \@ifnextchar[{\@ydefthm{#1}{#2}}{\@xdefthm{#1}{#2}}%\r
+}\r
+\def\@xdefthm#1#2{%\r
+    \@begindef{#2}{\csname the#1\endcsname}%\r
+    \ignorespaces\r
+}\r
+\def\@ydefthm#1#2[#3]{%\r
+    \trivlist\r
+    \item[%\r
+        \hskip 10\p@\r
+        \hskip \labelsep\r
+        {\it #2%\r
+%         \savebox\@tempboxa{#3}%\r
+         \saveb@x\@tempboxa{#3}%               % January 2008\r
+         \ifdim \wd\@tempboxa>\z@\r
+            \ \box\@tempboxa\r
+         \fi.%\r
+        }]%\r
+    \ignorespaces\r
+}\r
+\def\@begindef#1#2{%\r
+    \trivlist\r
+    \item[%\r
+        \hskip 10\p@\r
+        \hskip \labelsep\r
+        {\it #1\ \rm #2.}%\r
+    ]%\r
+}\r
+\def\theequation{\arabic{equation}}\r
+\r
+\newcounter{part}\r
+\newcounter{section}\r
+\newcounter{subsection}[section]\r
+\newcounter{subsubsection}[subsection]\r
+\newcounter{paragraph}[subsubsection]\r
+\def\thepart{\Roman{part}}\r
+\def\thesection{\arabic{section}}\r
+\def\thesubsection{\thesection.\arabic{subsection}}\r
+\def\thesubsubsection{\thesubsection.\arabic{subsubsection}} %removed \subsecfnt 29 July 2002 gkmt\r
+\def\theparagraph{\thesubsubsection.\arabic{paragraph}} %removed \subsecfnt 29 July 2002 gkmt\r
+\r
+\newif\if@uchead\r
+\@ucheadfalse\r
+\r
+%% CHANGES: NEW NOTE\r
+%% NOTE: OK to use old-style font commands below, since they were\r
+%% suitably redefined for LaTeX2e\r
+%% END CHANGES\r
+\setcounter{secnumdepth}{3}\r
+\def\part{%\r
+    \@startsection{part}{9}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}\r
+        {4\p@}{\normalsize\@ucheadtrue}%\r
+}\r
+\r
+% Rationale for changes made in next four definitions:\r
+% "Before skip" is made elastic to provide some give in setting columns (vs.\r
+% parskip, which is non-elastic to keep section headers "anchored" to their\r
+% subsequent text.\r
+%\r
+% "After skip" is minimized -- BUT setting it to 0pt resulted in run-in heads, despite\r
+% the documentation asserted only after-skip < 0pt would have result.\r
+%\r
+% Baselineskip added to style to ensure multi-line section titles, and section heads\r
+% followed by another section head rather than text, are decently spaced vertically.\r
+% 12 Jan 2000 gkmt\r
+\def\section{%\r
+    \@startsection{section}{1}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}%\r
+    {0.5pt}{\baselineskip=14pt\secfnt\@ucheadtrue}%\r
+}\r
+\r
+\def\subsection{%\r
+    \@startsection{subsection}{2}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}\r
+    {0.5pt}{\baselineskip=14pt\secfnt}%\r
+}\r
+\def\subsubsection{%\r
+    \@startsection{subsubsection}{3}{\z@}{-10\p@ \@plus -4\p@ \@minus -2\p@}%\r
+    {0.5pt}{\baselineskip=14pt\subsecfnt}%\r
+}\r
+\r
+%\def\paragraph{%\r
+%    \vskip 12pt\@startsection{paragraph}{3}{\z@}{6\p@ \@plus \p@}% original\r
+%    {-5\p@}{\subsecfnt}%\r
+%}\r
+%  If one wants sections, subsections and subsubsections numbered,\r
+%  but not paragraphs, one usually sets secnumepth to 3.\r
+%  For that, the "depth" of paragraphs must be given correctly\r
+%  in the definition (``4'' instead of ``3'' as second argument\r
+%  of @startsection):\r
+\def\paragraph{%\r
+    \vskip 12pt\@startsection{paragraph}{4}{\z@}{6\p@ \@plus \p@}%    % GM and Wolfgang May - 11/30/06\r
+    {-5\p@}{\subsecfnt}%\r
+}\r
+\r
+\let\@period=.\r
+\def\@startsection#1#2#3#4#5#6{%\r
+        \if@noskipsec  %gkmt, 11 aug 99\r
+        \global\let\@period\@empty\r
+        \leavevmode\r
+        \global\let\@period.%\r
+    \fi\r
+    \par\r
+    \@tempskipa #4\relax\r
+    \@afterindenttrue\r
+    \ifdim \@tempskipa <\z@\r
+        \@tempskipa -\@tempskipa\r
+        \@afterindentfalse\r
+    \fi\r
+    %\if@nobreak  11 Jan 00 gkmt\r
+        %\everypar{}\r
+    %\else\r
+        \addpenalty\@secpenalty\r
+        \addvspace\@tempskipa\r
+    %\fi\r
+    \parskip=0pt\r
+    \@ifstar\r
+        {\@ssect{#3}{#4}{#5}{#6}}\r
+        {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}%\r
+}\r
+\r
+\r
+\def\@ssect#1#2#3#4#5{%\r
+  \@tempskipa #3\relax\r
+  \ifdim \@tempskipa>\z@\r
+    \begingroup\r
+      #4{%\r
+        \@hangfrom{\hskip #1}%\r
+          \interlinepenalty \@M #5\@@par}%\r
+    \endgroup\r
+  \else\r
+    \def\@svsechd{#4{\hskip #1\relax #5}}%\r
+  \fi\r
+  \vskip -10.5pt  %gkmt, 7 jan 00 -- had been -14pt, now set to parskip\r
+  \@xsect{#3}\parskip=10.5pt} % within the starred section, parskip = leading 12 Jan 2000 gkmt\r
+\r
+\r
+\def\@sect#1#2#3#4#5#6[#7]#8{%\r
+    \ifnum #2>\c@secnumdepth\r
+        \let\@svsec\@empty\r
+    \else\r
+        \refstepcounter{#1}%\r
+        \edef\@svsec{%\r
+            \begingroup\r
+                %\ifnum#2>2 \noexpand\rm \fi % changed to next 29 July 2002 gkmt\r
+            \ifnum#2>2 \noexpand#6 \fi\r
+                \csname the#1\endcsname\r
+            \endgroup\r
+            \ifnum #2=1\relax .\fi\r
+            \hskip 1em\r
+        }%\r
+    \fi\r
+    \@tempskipa #5\relax\r
+    \ifdim \@tempskipa>\z@\r
+        \begingroup\r
+            #6\relax\r
+            \@hangfrom{\hskip #3\relax\@svsec}%\r
+            \begingroup\r
+                \interlinepenalty \@M\r
+                \if@uchead\r
+                    \uppercase{#8}%\r
+                \else\r
+                    #8%\r
+                \fi\r
+                \par\r
+            \endgroup\r
+        \endgroup\r
+        \csname #1mark\endcsname{#7}%\r
+        \vskip -10.5pt  % -14pt gkmt, 11 aug 99 -- changed to -\parskip 11 Jan 2000\r
+      \addcontentsline{toc}{#1}{%\r
+            \ifnum #2>\c@secnumdepth \else\r
+                \protect\numberline{\csname the#1\endcsname}%\r
+            \fi\r
+            #7%\r
+        }%\r
+    \else\r
+        \def\@svsechd{%\r
+            #6%\r
+            \hskip #3\relax\r
+            \@svsec\r
+            \if@uchead\r
+                \uppercase{#8}%\r
+            \else\r
+                #8%\r
+            \fi\r
+            \csname #1mark\endcsname{#7}%\r
+            \addcontentsline{toc}{#1}{%\r
+                \ifnum #2>\c@secnumdepth \else\r
+                    \protect\numberline{\csname the#1\endcsname}%\r
+                \fi\r
+                #7%\r
+            }%\r
+        }%\r
+    \fi\r
+    \@xsect{#5}\parskip=10.5pt% within the section, parskip = leading 12 Jan 2000 gkmt\r
+}\r
+\def\@xsect#1{%\r
+    \@tempskipa #1\relax\r
+    \ifdim \@tempskipa>\z@\r
+        \par\r
+        \nobreak\r
+        \vskip \@tempskipa\r
+        \@afterheading\r
+    \else\r
+        \global\@nobreakfalse\r
+        \global\@noskipsectrue\r
+        \everypar{%\r
+            \if@noskipsec\r
+                \global\@noskipsecfalse\r
+                \clubpenalty\@M\r
+                \hskip -\parindent\r
+                \begingroup\r
+                    \@svsechd\r
+                    \@period\r
+                \endgroup\r
+                \unskip\r
+                \@tempskipa #1\relax\r
+                \hskip -\@tempskipa\r
+            \else\r
+                \clubpenalty \@clubpenalty\r
+                \everypar{}%\r
+            \fi\r
+        }%\r
+    \fi\r
+    \ignorespaces\r
+}\r
+\r
+\def\@trivlist{%\r
+    \@topsepadd\topsep\r
+    \if@noskipsec\r
+        \global\let\@period\@empty\r
+        \leavevmode\r
+        \global\let\@period.%\r
+    \fi\r
+    \ifvmode\r
+        \advance\@topsepadd\partopsep\r
+    \else\r
+        \unskip\r
+        \par\r
+    \fi\r
+    \if@inlabel\r
+        \@noparitemtrue\r
+        \@noparlisttrue\r
+    \else\r
+        \@noparlistfalse\r
+        \@topsep\@topsepadd\r
+    \fi\r
+    \advance\@topsep \parskip\r
+    \leftskip\z@skip\r
+    \rightskip\@rightskip\r
+    \parfillskip\@flushglue\r
+    \@setpar{\if@newlist\else{\@@par}\fi}\r
+    \global\@newlisttrue\r
+    \@outerparskip\parskip\r
+}\r
+\r
+%%% Actually, 'abbrev' works just fine as the default - Gerry Feb. 2000\r
+%%% Bibliography style.\r
+\r
+\parindent 0pt\r
+\typeout{Using 'Abbrev' bibliography style}\r
+\newcommand\bibyear[2]{%\r
+    \unskip\quad\ignorespaces#1\unskip\r
+    \if#2..\quad \else \quad#2 \fi\r
+}\r
+\newcommand{\bibemph}[1]{{\em#1}}\r
+\newcommand{\bibemphic}[1]{{\em#1\/}}\r
+\newcommand{\bibsc}[1]{{\sc#1}}\r
+\def\@normalcite{%\r
+    \def\@cite##1##2{[##1\if@tempswa , ##2\fi]}%\r
+}\r
+\def\@citeNB{%\r
+    \def\@cite##1##2{##1\if@tempswa , ##2\fi}%\r
+}\r
+\def\@citeRB{%\r
+    \def\@cite##1##2{##1\if@tempswa , ##2\fi]}%\r
+}\r
+\def\start@cite#1#2{%\r
+    \edef\citeauthoryear##1##2##3{%\r
+        ###1%\r
+        \ifnum#2=\z@ \else\ ###2\fi\r
+    }%\r
+    \ifnum#1=\thr@@\r
+        \let\@@cite\@citeyear\r
+    \else\r
+        \let\@@cite\@citenormal\r
+    \fi\r
+    \@ifstar{\@citeNB\@@cite}{\@normalcite\@@cite}%\r
+}\r
+%\def\cite{\start@cite23}\r
+\DeclareRobustCommand\cite{\start@cite23}              % January 2008\r
+\def\citeNP{\cite*}                                    % No Parentheses e.g. 5\r
+%\def\citeA{\start@cite10}\r
+\DeclareRobustCommand\citeA{\start@cite10}             % January 2008\r
+\def\citeANP{\citeA*}\r
+%\def\shortcite{\start@cite23}                         \r
+\DeclareRobustCommand\shortcite{\start@cite23}         % January 2008\r
+\def\shortciteNP{\shortcite*}\r
+%\def\shortciteA{\start@cite20}\r
+\DeclareRobustCommand\shortciteA{\start@cite20}                % January 2008\r
+\def\shortciteANP{\shortciteA*}\r
+%\def\citeyear{\start@cite30}\r
+\DeclareRobustCommand\citeyear{\start@cite30}          % January 2008\r
+\def\citeyearNP{\citeyear*}\r
+%\def\citeN{%\r
+\DeclareRobustCommand\citeN{%                          % January 2008\r
+    \@citeRB\r
+    \def\citeauthoryear##1##2##3{##1\ [##3%\r
+        \def\reserved@a{##1}%\r
+        \def\citeauthoryear####1####2####3{%\r
+            \def\reserved@b{####1}%\r
+            \ifx\reserved@a\reserved@b\r
+                ####3%\r
+            \else\r
+                \errmessage{Package acmart Error: author mismatch\r
+                         in \string\citeN^^J^^J%\r
+                    See the acmart package documentation for explanation}%\r
+            \fi\r
+        }%\r
+    }%\r
+    \@ifstar\@citeyear\@citeyear\r
+}\r
+%\def\shortciteN{%\r
+\DeclareRobustCommand\shortciteN{%                     % January 2008\r
+    \@citeRB\r
+    \def\citeauthoryear##1##2##3{##2\ [##3%\r
+        \def\reserved@a{##2}%\r
+        \def\citeauthoryear####1####2####3{%\r
+            \def\reserved@b{####2}%\r
+            \ifx\reserved@a\reserved@b\r
+                ####3%\r
+            \else\r
+                \errmessage{Package acmart Error: author mismatch\r
+                         in \string\shortciteN^^J^^J%\r
+                    See the acmart package documentation for explanation}%\r
+            \fi\r
+        }%\r
+    }%\r
+    \@ifstar\@citeyear\@citeyear % changed from  "\@ifstart" 12 Jan 2000 gkmt\r
+}\r
+\r
+\def\@citenormal{%\r
+    \@ifnextchar [{\@tempswatrue\@citex;}%\r
+% original                 {\@tempswafalse\@citex,[]}% was ; Gerry 2/24/00\r
+{\@tempswafalse\@citex[]}%     % GERRY FIX FOR BABEL 3/20/2009\r
+}\r
+\r
+\def\@citeyear{%\r
+    \@ifnextchar [{\@tempswatrue\@citex,}%\r
+% original                  {\@tempswafalse\@citex,[]}%\r
+{\@tempswafalse\@citex[]}%     %  GERRY FIX FOR BABEL 3/20/2009\r
+}\r
+\r
+\def\@citex#1[#2]#3{%\r
+    \let\@citea\@empty\r
+    \@cite{%\r
+        \@for\@citeb:=#3\do{%\r
+            \@citea\r
+% original            \def\@citea{#1 }%\r
+            \def\@citea{#1, }%         % GERRY FIX FOR BABEL 3/20/2009 -- SO THAT YOU GET [1, 2] IN THE BODY TEXT\r
+            \edef\@citeb{\expandafter\@iden\@citeb}%\r
+            \if@filesw\r
+                \immediate\write\@auxout{\string\citation{\@citeb}}%\r
+            \fi\r
+            \@ifundefined{b@\@citeb}{%\r
+                {\bf ?}%\r
+                \@warning{%\r
+                    Citation `\@citeb' on page \thepage\space undefined%\r
+                }%\r
+            }%\r
+            {\csname b@\@citeb\endcsname}%\r
+        }%\r
+    }{#2}%\r
+}\r
+%\let\@biblabel\@gobble   % Dec. 2008 - Gerry\r
+% ----\r
+\def\@biblabelnum#1{[#1]} % Gerry's solution #1 - for Natbib \r
+\let\@biblabel=\@biblabelnum  % Gerry's solution #1 - for Natbib\r
+\def\newblock{\relax} % Gerry Dec. 2008\r
+% ---\r
+\newdimen\bibindent\r
+\setcounter{enumi}{1}\r
+\bibindent=0em\r
+\def\thebibliography#1{% \r
+\ifnum\addauflag=0\addauthorsection\global\addauflag=1\fi\r
+     \section[References]{%    <=== OPTIONAL ARGUMENT ADDED HERE\r
+        {References} % was uppercased but this affects pdf bookmarks (SP/GM October 2004)\r
+         \@mkboth{{\refname}}{{\refname}}%\r
+     }%\r
+     \list{[\arabic{enumi}]}{%\r
+         \settowidth\labelwidth{[#1]}%\r
+         \leftmargin\labelwidth\r
+         \advance\leftmargin\labelsep\r
+         \advance\leftmargin\bibindent\r
+         \parsep=0pt\itemsep=1pt % GM July 2000\r
+         \itemindent -\bibindent\r
+         \listparindent \itemindent\r
+         \usecounter{enumi}\r
+     }%\r
+     \let\newblock\@empty\r
+     \raggedright % GM July 2000\r
+     \sloppy\r
+     \sfcode`\.=1000\relax\r
+}\r
+\r
+\r
+\gdef\balancecolumns\r
+{\vfill\eject\r
+\global\@colht=\textheight\r
+\global\ht\@cclv=\textheight\r
+}\r
+\r
+\newcount\colcntr\r
+\global\colcntr=0\r
+%\newbox\savebox\r
+\newbox\saveb@x                                % January 2008\r
+\r
+\gdef \@makecol {%\r
+\global\advance\colcntr by 1\r
+\ifnum\colcntr>2 \global\colcntr=1\fi\r
+   \ifvoid\footins\r
+     \setbox\@outputbox \box\@cclv\r
+   \else\r
+     \setbox\@outputbox \vbox{%\r
+\boxmaxdepth \@maxdepth\r
+       \@tempdima\dp\@cclv\r
+       \unvbox \@cclv\r
+       \vskip-\@tempdima\r
+       \vskip \skip\footins\r
+       \color@begingroup\r
+         \normalcolor\r
+         \footnoterule\r
+         \unvbox \footins\r
+       \color@endgroup\r
+       }%\r
+   \fi\r
+   \xdef\@freelist{\@freelist\@midlist}%\r
+   \global \let \@midlist \@empty\r
+   \@combinefloats\r
+   \ifvbox\@kludgeins\r
+     \@makespecialcolbox\r
+   \else\r
+     \setbox\@outputbox \vbox to\@colht {%\r
+\@texttop\r
+       \dimen@ \dp\@outputbox\r
+       \unvbox \@outputbox\r
+   \vskip -\dimen@\r
+       \@textbottom\r
+       }%\r
+   \fi\r
+   \global \maxdepth \@maxdepth\r
+}\r
+\def\titlenote{\@ifnextchar[\@xtitlenote{\stepcounter\@mpfn\r
+\global\advance\titlenotecount by 1\r
+\ifnum\titlenotecount=1\r
+    \raisebox{9pt}{$\ast$}\r
+\fi\r
+\ifnum\titlenotecount=2\r
+    \raisebox{9pt}{$\dagger$}\r
+\fi\r
+\ifnum\titlenotecount=3\r
+    \raisebox{9pt}{$\ddagger$}\r
+\fi\r
+\ifnum\titlenotecount=4\r
+\raisebox{9pt}{$\S$}\r
+\fi\r
+\ifnum\titlenotecount=5\r
+\raisebox{9pt}{$\P$}\r
+\fi\r
+         \@titlenotetext\r
+}}\r
+\r
+\long\def\@titlenotetext#1{\insert\footins{%\r
+\ifnum\titlenotecount=1\global\tntoks={#1}\fi\r
+\ifnum\titlenotecount=2\global\tntokstwo={#1}\fi\r
+\ifnum\titlenotecount=3\global\tntoksthree={#1}\fi\r
+\ifnum\titlenotecount=4\global\tntoksfour={#1}\fi\r
+\ifnum\titlenotecount=5\global\tntoksfive={#1}\fi\r
+    \reset@font\footnotesize\r
+    \interlinepenalty\interfootnotelinepenalty\r
+    \splittopskip\footnotesep\r
+    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM\r
+    \hsize\columnwidth \@parboxrestore\r
+    \protected@edef\@currentlabel{%\r
+    }%\r
+    \color@begingroup\r
+   \color@endgroup}}\r
+\r
+%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\ps@plain\r
+\baselineskip=11pt\r
+\let\thepage\relax % For  NO page numbers - Gerry Nov. 30th. 1999\r
+\def\setpagenumber#1{\global\setcounter{page}{#1}}\r
+%\pagenumbering{arabic}  % Arabic page numbers but commented out for NO page numbes - Gerry Nov. 30th. 1999\r
+\twocolumn             % Double column.\r
+\flushbottom           % Even bottom -- alas, does not balance columns at end of document\r
+\pagestyle{plain}\r
+\r
+% Need Copyright Year and Copyright Data to be user definable (in .tex file).\r
+% Gerry Nov. 30th. 1999\r
+\newtoks\copyrtyr\r
+\newtoks\acmcopyr\r
+\newtoks\boilerplate\r
+\def\CopyrightYear#1{\global\copyrtyr{#1}}\r
+\def\crdata#1{\global\acmcopyr{#1}}\r
+\def\permission#1{\global\boilerplate{#1}}\r
+%\r
+\newtoks\copyrightetc\r
+\global\copyrightetc{\ } %  Need to have 'something' so that adequate space is left for pasting in a line if "confinfo" is supplied.\r
+\r
+\toappear{\the\boilerplate\par\r
+{\confname{\the\conf}} \the\confinfo\par \the\copyrightetc}\r
+% End of ACM_PROC_ARTICLE-SP.CLS -- V3.2SP - 04/22/2009 --\r
+% Gerry Murray -- Wednesday April 22nd. 2009\r
+%\r
+% The following section (i.e. 3 .sty inclusions) was added in May 2007 so as to fix the problems that many\r
+% authors were having with accents. Sometimes accents would occur, but the letter-character would be of a different\r
+% font. Conversely the letter-character font would be correct but, e.g. a 'bar' would appear superimposed on the\r
+% character instead of, say, an unlaut/diaresis. Sometimes the letter-character would NOT appear at all.\r
+% Using [T1]{fontenc} outright was not an option as this caused 99% of the authors to 'produce' a Type-3 (bitmapped)\r
+% PDF file - useless for production. \r
+%\r
+% For proper (font) accenting we NEED these packages to be part of the .cls file i.e. 'ae', 'aecompl' and 'aeguil' \r
+% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+%% This is file `ae.sty' \r
+\def\fileversion{1.3}\r
+\def\filedate{2001/02/12}\r
+\NeedsTeXFormat{LaTeX2e}\r
+%\ProvidesPackage{ae}[\filedate\space\fileversion\space  % GM\r
+% Almost European Computer Modern]                       % GM - keeping the log file clean(er)\r
+\newif\if@ae@slides \@ae@slidesfalse\r
+\DeclareOption{slides}{\@ae@slidestrue}\r
+\ProcessOptions\r
+\fontfamily{aer}\r
+\RequirePackage[T1]{fontenc}\r
+\if@ae@slides\r
+    \renewcommand{\sfdefault}{laess}\r
+    \renewcommand{\rmdefault}{laess} % no roman\r
+    \renewcommand{\ttdefault}{laett}\r
+\else\r
+    \renewcommand{\sfdefault}{aess}\r
+    \renewcommand{\rmdefault}{aer}\r
+    \renewcommand{\ttdefault}{aett}\r
+\fi\r
+\endinput\r
+%% \r
+%% End of file `ae.sty'.\r
+%\r
+%\r
+\def\fileversion{0.9}\r
+\def\filedate{1998/07/23}\r
+\NeedsTeXFormat{LaTeX2e}\r
+%\ProvidesPackage{aecompl}[\filedate\space\fileversion\space   % GM\r
+%T1 Complements for AE fonts (D. Roegel)]                      % GM -- keeping the log file clean(er)\r
\r
+\def\@ae@compl#1{{\fontencoding{T1}\fontfamily{cmr}\selectfont\symbol{#1}}}\r
+\def\guillemotleft{\@ae@compl{19}}\r
+\def\guillemotright{\@ae@compl{20}}\r
+\def\guilsinglleft{\@ae@compl{14}}\r
+\def\guilsinglright{\@ae@compl{15}}\r
+\def\TH{\@ae@compl{222}}\r
+\def\NG{\@ae@compl{141}}\r
+\def\ng{\@ae@compl{173}}\r
+\def\th{\@ae@compl{254}}\r
+\def\DJ{\@ae@compl{208}}\r
+\def\dj{\@ae@compl{158}}\r
+\def\DH{\@ae@compl{208}}\r
+\def\dh{\@ae@compl{240}}\r
+\def\@perthousandzero{\@ae@compl{24}}\r
+\def\textperthousand{\%\@perthousandzero}\r
+\def\textpertenthousand{\%\@perthousandzero\@perthousandzero}\r
+\endinput\r
+%\r
+%\r
+%% This is file `aeguill.sty' \r
+% This file gives french guillemets (and not guillemots!)\r
+% built with the Polish CMR fonts (default), WNCYR fonts, the LASY fonts \r
+% or with the EC fonts. \r
+% This is useful in conjunction with the ae package\r
+% (this package loads the ae package in case it has not been loaded)\r
+%  and with or without the french(le) package.\r
+%\r
+% In order to get the guillemets, it is necessary to either type\r
+% \guillemotleft and \guillemotright, or to use an 8 bit encoding\r
+% (such as ISO-Latin1) which selects these two commands, \r
+% or, if you use the french package (but not the frenchle package), \r
+% to type << or >>.\r
+%\r
+% By default, you get the Polish CMR guillemets; if this package is loaded\r
+% with the `cm' option, you get the LASY guillemets; with `ec,' you\r
+% get the EC guillemets, and with `cyr,' you get the cyrillic guillemets.\r
+%\r
+% In verbatim mode, you always get the EC/TT guillemets.\r
+%\r
+% The default option is interesting in conjunction with PDF,\r
+% because there is a Type 1 version of the Polish CMR fonts\r
+% and these guillemets are very close in shape to the EC guillemets.\r
+% There are no free Type 1 versions of the EC fonts.\r
+%\r
+% Support for Polish CMR guillemets was kindly provided by \r
+% Rolf Niepraschk <niepraschk@ptb.de> in version 0.99 (2000/05/22).\r
+% Bernd Raichle provided extensive simplifications to the code\r
+% for version 1.00.\r
+%\r
+% This package is released under the LPPL.\r
+%\r
+% Changes:\r
+%   Date        version\r
+%   2001/04/12  1.01    the frenchle and french package are now distinguished.\r
+%\r
+\def\fileversion{1.01}\r
+\def\filedate{2001/04/12}\r
+\NeedsTeXFormat{LaTeX2e}\r
+%\ProvidesPackage{aeguill}[2001/04/12 1.01 %    % GM\r
+%AE fonts with french guillemets (D. Roegel)]   % GM - keeping the log file clean(er)\r
+%\RequirePackage{ae}  % GM May 2007 - already embedded here\r
+\r
+\newcommand{\@ae@switch}[4]{#4}\r
+\DeclareOption{ec}{\renewcommand\@ae@switch[4]{#1}}\r
+\DeclareOption{cm}{\renewcommand\@ae@switch[4]{#2}}\r
+\DeclareOption{cyr}{\renewcommand\@ae@switch[4]{#3}}\r
+\DeclareOption{pl}{\renewcommand\@ae@switch[4]{#4}}\r
+\ExecuteOptions{pl}\r
+\ProcessOptions\r
+\r
+%\r
+% Load necessary packages\r
+%\r
+\@ae@switch{% ec\r
+  % do nothing\r
+}{% cm\r
+  \RequirePackage{latexsym}%  GM - May 2007 - already 'mentioned as required' up above\r
+}{% cyr\r
+  \RequirePackage[OT2,T1]{fontenc}%\r
+}{% pl\r
+  \RequirePackage[OT4,T1]{fontenc}%\r
+}\r
+\r
+% The following command will be compared to \frenchname,\r
+% as defined in french.sty and frenchle.sty.\r
+\def\aeguillfrenchdefault{french}%\r
+\r
+\let\guill@verbatim@font\verbatim@font\r
+\def\verbatim@font{\guill@verbatim@font\ecguills{cmtt}%\r
+                   \let\guillemotleft\@oguills\let\guillemotright\@fguills}\r
+\r
+\begingroup \catcode`\<=13 \catcode`\>=13\r
+\def\x{\endgroup\r
+ \def\ae@lfguill{<<}%\r
+ \def\ae@rfguill{>>}%\r
+}\x\r
+\r
+\newcommand{\ecguills}[1]{%\r
+  \def\selectguillfont{\fontencoding{T1}\fontfamily{#1}\selectfont}%\r
+  \def\@oguills{{\selectguillfont\symbol{19}}}%\r
+  \def\@fguills{{\selectguillfont\symbol{20}}}%\r
+  } \r
+\r
+\newcommand{\aeguills}{%\r
+  \ae@guills\r
+  % We redefine \guillemotleft and \guillemotright\r
+  % in order to catch them when they are used \r
+  % with \DeclareInputText (in latin1.def for instance)\r
+  % We use \auxWARNINGi as a safe indicator that french.sty is used.\r
+  \gdef\guillemotleft{\ifx\auxWARNINGi\undefined\r
+                         \@oguills % neither french.sty nor frenchle.sty\r
+                      \else\r
+                         \ifx\aeguillfrenchdefault\frenchname\r
+                           \ae@lfguill  % french.sty\r
+                         \else\r
+                           \@oguills    % frenchle.sty\r
+                         \fi\r
+                      \fi}%\r
+  \gdef\guillemotright{\ifx\auxWARNINGi\undefined\r
+                         \@fguills % neither french.sty nor frenchle.sty\r
+                       \else\r
+                         \ifx\aeguillfrenchdefault\frenchname\r
+                           \ae@rfguill  % french.sty\r
+                         \else\r
+                           \@fguills    % frenchle.sty\r
+                         \fi\r
+                       \fi}%\r
+  }\r
+\r
+%\r
+% Depending on the class option\r
+% define the internal command \ae@guills\r
+\@ae@switch{% ec\r
+  \newcommand{\ae@guills}{%\r
+    \ecguills{cmr}}%\r
+}{% cm\r
+  \newcommand{\ae@guills}{%\r
+    \def\selectguillfont{\fontencoding{U}\fontfamily{lasy}%\r
+            \fontseries{m}\fontshape{n}\selectfont}%\r
+    \def\@oguills{\leavevmode\nobreak\r
+                \hbox{\selectguillfont (\kern-.20em(\kern.20em}\nobreak}%\r
+    \def\@fguills{\leavevmode\nobreak\r
+                \hbox{\selectguillfont \kern.20em)\kern-.2em)}%\r
+                \ifdim\fontdimen\@ne\font>\z@\/\fi}}%\r
+}{% cyr\r
+  \newcommand{\ae@guills}{%\r
+    \def\selectguillfont{\fontencoding{OT2}\fontfamily{wncyr}\selectfont}%\r
+    \def\@oguills{{\selectguillfont\symbol{60}}}%\r
+    \def\@fguills{{\selectguillfont\symbol{62}}}}\r
+}{% pl\r
+  \newcommand{\ae@guills}{%\r
+    \def\selectguillfont{\fontencoding{OT4}\fontfamily{cmr}\selectfont}%\r
+    \def\@oguills{{\selectguillfont\symbol{174}}}%\r
+    \def\@fguills{{\selectguillfont\symbol{175}}}}\r
+}\r
+\r
+\r
+\AtBeginDocument{%\r
+  \ifx\GOfrench\undefined\r
+    \aeguills\r
+  \else\r
+    \let\aeguill@GOfrench\GOfrench\r
+    \gdef\GOfrench{\aeguill@GOfrench \aeguills}%\r
+  \fi\r
+  }\r
+\r
+\endinput\r
+%\r
+\r
+\r
index 6e60f10e2aea8a528f47bc0889ea42b1cc05b87c..5b5731c4fda94d428d46019fc4c0de539a229f80 100644 (file)
@@ -2,7 +2,18 @@
 #+AUTHOR: Christophe Rhodes, Jan Moringen, David Lichteblau
 #+OPTIONS: toc:nil
 
-#+LaTeX_HEADER: \usepackage[margin=1in]{geometry}
+#+LaTeX_CLASS: acm_proc_article-sp
+#+LaTeX_HEADER: \DeclareTextFontCommand{\texttt}{\ttfamily\hyphenchar\font=45\relax}
+
+#+begin_src elisp :exports none
+(add-to-list 'org-latex-classes
+             '("acm_proc_article-sp" "\\documentclass{acm_proc_article-sp}"
+               ("\\section{%s}" . "\\section*{%s}")
+               ("\\subsection{%s}" . "\\subsection*{%s}")
+               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
+               ("\\paragraph{%s}" . "\\paragraph*{%s}")
+               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
+#+end_src
 
 #+begin_abstract
 1. This paper introduces a new metaobject, the generalizer, which
 #+end_abstract
 
 * Introduction
-  The revisions to the original Common Lisp language \cite{CLtL1}
+  The revisions to the original Common Lisp language \cite{CLtL}
   included the detailed specification of an object system, known as
   the Common Lisp Object System (CLOS), which was eventually
   standardized as part of the ANSI Common Lisp standard \cite{CLtS}.
   The object system as presented to the standardization committee was
-  formed of three parts, the first two of which covered XXX [what?]
-  and were incorporated into the final standard, and the third,
-  covering a Metaobject Protocol (MOP) for CLOS, was not.
+  formed of three chapters.  The first two chapters covered programmer
+  interface concepts and the functions in the programmer interface
+  \cite[Chapter 28]{CLtL2} and were largely incorporated into the
+  final standard; the third chapter, covering a Metaobject Protocol
+  (MOP) for CLOS, was not.
 
   Nevertheless, the CLOS MOP has proven to be a robust design, and
   while many implementations have derived their implementations of
   CLOS from either the Closette illustrative implementation in
   \cite{AMOP}, or the Portable Common Loops implementation of CLOS
   from Xerox Parc, there have been from-scratch reimplementations of
-  CLOS (in at least CLISP; check for others -- ABCL?  Lisp500?!)
-  incorporating the majority of the Metaobject Protocol as described.
-
-  Although it has stood the test of time, the MOP is neither without
-  issues (e.g. M-M-L considered harmful; slot-definition initargs
-  issue) nor a complete framework for the metaprogrammer to implement
-  all conceivable variations of object-oriented behaviour; indeed,
-  while metaprogramming offers some possibilities for customization of
+  CLOS (in at least CLISP; check for others -- Lisp500?  CCL?)
+  incorporating substantial fractions of the Metaobject Protocol as
+  described.
+
+  Although it has stood the test of time, the CLOS MOP is neither
+  without issues (e.g. semantic problems with =make-method-lambda=
+  \cite{Costanza.Herzeel:2008}; useful functions such as
+  =compute-effective-slot-definition-initargs= being missing from the
+  standard) nor is it a complete framework for the metaprogrammer to
+  implement all conceivable variations of object-oriented behaviour.
+  While metaprogramming offers some possibilities for customization of
   the object system behaviour, those possibilities cannot extend
   arbitrarily in all directions.  There is still an expectation that
   functionality is implemented with methods on generic functions,
-  acting on objects with slots.  [XXX find Paepke picture here?  Not
-  Paepke; AMOP?].  XXX include typical examples of MOP: object
-  persistence; maybe ref. Kizcales "MOPs: why we want them and what
-  else they can do"? (Fig. 2 in that is good) ORMs; sparse slots.
-  jmoringe:
-  + introspection, e.g. documentation generation
-  + programmatic construction of classes and generic functions
-    e.g. for IDL compilers, model transformations
+  acting on objects with slots.  Nevertheless, the MOP is flexible,
+  and is used for a number of things, including: documentation
+  generation (where introspective functionality in the MOP is used to
+  extract information from a running system); object-relational
+  mapping and other approaches to object persistence; alternative
+  backing stores for slots (hash-tables or symbols); and programmatic
+  construction of metaobjects, for example for IDL compilers and model
+  transformations.
+
+  [ A picture on MOP flexibility here would be good; I have in my mind
+  one where an object system is a point and the MOP opens up a blob
+  around that point, and I'm sure I've seen it somewhere but I can't
+  remember where.  Alternatively, there's Kiczales et al "MOPs: why we
+  want them and what else they can do", fig. 2 ]
 
   One area of functionality where there is scope for customization by
   the metaprogrammer is in the mechanics and semantics of method
   =compute-applicable-methods=,
   =compute-applicable-methods-using-classes=), for example, in
   practice implementation support for this was weak until relatively
-  recently (ref. closer, also check how ContextL and filtered dispatch
-  are implemented).
-  jmoringe: filtered dispatch uses a custom method combination, i
-  think
+  recently[fn:1].
 
   Another potential mechanism for customizing dispatch is implicit in
   the class structure defined by AMOP: standard specializer objects
   (instances of =class= and =eql-specializer=) are generalized
   instances of the =specializer= protocol class, and in principle
   there are no restrictions on the metaprogrammer constructing
-  additional subclasses.  Previous work [Newton/Rhodes] has explored
-  the potential for customizing generic function dispatch using
-  extended specializers, but as of that work the metaprogrammer must
-  override the entirety of the generic function invocation protocol
-  (from =compute-discriminating-function= on down), leading to toy
-  implementations and duplicated effort.
+  additional subclasses.  Previous work \cite{Newton.Rhodes:2008} has
+  explored the potential for customizing generic function dispatch
+  using extended specializers, but as of that work the metaprogrammer
+  must override the entirety of the generic function invocation
+  protocol (from =compute-discriminating-function= on down), leading
+  to toy implementations and duplicated effort.
 
   This paper introduces a protocol for efficient and controlled
-  handling of arbitrary subclasses of =specializer=.  In particular,
-  it introduces the =generalizer= protocol class, which generalizes
-  (ahem) the return value of =class-of=, and allows the metaprogrammer
-  to hook into cacheing schemes to avoid needless recomputation of
-  effective methods for sufficiently similar generic function
-  arguments (See Figure\nbsp\ref{fig:dispatch}).
+  handling of new subclasses of =specializer=.  In particular, it
+  introduces the =generalizer= protocol class, which generalizes the
+  return value of =class-of= in method applicability computation, and
+  allows the metaprogrammer to hook into cacheing schemes to avoid
+  needless recomputation of effective methods for sufficiently similar
+  generic function arguments (See Figure\nbsp\ref{fig:dispatch}).
 
   #+CAPTION:    Dispatch Comparison
   #+LABEL:      fig:dispatch
   [[file:figures/dispatch-comparison.pdf]]
 
   The remaining sections in this paper can be read in any order.  We
-  give some motivating examples in section XX, including
+  give some motivating examples in section [[#Examples]], including
   reimplementations of examples from previous work, as well as
   examples which are poorly supported by previous protocols.  We
-  describe the protocol itself in section YY, describing each protocol
-  function in detail and, where applicable, relating it to existing
-  protocol functions within the CLOS MOP.  We survey related work in
-  more detail in section ZZ, touching on work on customized dispatch
-  schemes in other environments.  Finally, we draw our conclusions
-  from this work, and indicate directions for further development, in
-  section WW; reading that section before the others indicates
-  substantial trust in the authors' work.
+  describe the protocol itself in section [[#Protocol]], describing each
+  protocol function in detail and, where applicable, relating it to
+  existing protocol functions within the CLOS MOP.  We survey related
+  work in more detail in section [[#Related Work]], touching on work on
+  customized dispatch schemes in other environments.  Finally, we draw
+  our conclusions from this work, and indicate directions for further
+  development, in section [[#Conclusions]]; reading that section before the
+  others indicates substantial trust in the authors' work.
 * Examples
+  :PROPERTIES:
+  :CUSTOM_ID: Examples
+  :END:
   In this section, we present a number of examples of dispatch
-  implemented using our protocol, which we describe in section YY.
-  For reasons of space, the metaprogram code examples in this section
-  do not include some of the necessary support code to run; complete
-  implementations of each of these cases are included in an appendix /
-  in the accompanying repository snapshot / at this location.
+  implemented using our protocol, which we describe in section
+  [[#Protocol]].  For reasons of space, the metaprogram code examples in
+  this section do not include some of the necessary support code to
+  run; complete implementations of each of these cases are included in
+  an appendix / in the accompanying repository snapshot / at this
+  location.
 
   A note on terminology: we will attempt to distinguish between the
   user of an individual case of generalized dispatch (the
   “programmer”), the implementor of a particular case of generalized
   dispatch (the “metaprogrammer”), and the authors as the designers
   and implementors of our generalized dispatch protocol (the
-  “metametaprogammer”, or more likely ”we”).
-
-  - [ ] =cons-specializer= (can be done using filtered dispatch)
-  - [ ] factorial (like filtered dispatch)
-  - [ ] HTTP Accept header
-  - [ ] xpattern
-  - [ ] prototype/multimethod
-** car-of-cons
+  “metametaprogammer”, or more likely “we”).
+** CONS specializers
+   :PROPERTIES:
+   :CUSTOM_ID: Cons
+   :END:
    We start by presenting our original use case, performing
    dispatching on the first element of lists.  Semantically, we allow
    the programmer to specialize any argument of methods with a new
    interoperating with all existing methods.
  
    The programmer code using these specializers is unchanged from
-   \cite{Newton.Rhodes.2008}; the benefits of the protocol described
-   here are centered on performance: in an application such as walking
-   source code, we would expect to encounter special forms
-   (distinguished by particular atoms in the =car= position) multiple
-   times, and hence to dispatch to the same effective method
-   repeatedly.
+   \cite{Newton.Rhodes:2008}; the benefits of the protocol described
+   here are centered on performance and generality: in an application
+   such as walking source code, we would expect to encounter special
+   forms (distinguished by particular atoms in the =car= position)
+   multiple times, and hence to dispatch to the same effective method
+   repeatedly.  We discuss this in more detail in section [[#Memoization]];
+   we present the metaprogrammer code below.
+
 #+begin_src lisp
 (defclass cons-specializer (specializer)
   ((%car :reader %car :initarg :car)))
 (defclass cons-generalizer (generalizer)
   ((%car :reader %car :initarg :car)))
-(defmethod generalizer-of-using-class ((gf cons-generic-function) arg)
+(defmethod generalizer-of-using-class
+    ((gf cons-generic-function) arg)
   (typecase arg
-    ((cons symbol) (make-instance 'cons-generalizer :car (car arg)))
+    ((cons symbol)
+     (make-instance 'cons-generalizer
+                    :car (car arg)))
     (t (call-next-method))))
-(defmethod generalizer-equal-hash-key ((gf cons-generic-function)
-                                       (g cons-generalizer))
+(defmethod generalizer-equal-hash-key
+    ((gf cons-generic-function)
+     (g cons-generalizer))
   (%car g))
-(defmethod specializer-accepts-generalizer-p ((gf cons-generic-function)
-                                              (s cons-specializer)
-                                              (g cons-generalizer))
+(defmethod specializer-accepts-generalizer-p
+    ((gf cons-generic-function)
+     (s cons-specializer)
+     (g cons-generalizer))
   (if (eql (%car s) (%car g))
       (values t t)
       (values nil t)))
-(defmethod specializer-accepts-p ((s cons-specializer) o)
+(defmethod specializer-accepts-p
+    ((s cons-specializer) o)
   (and (consp o) (eql (car o) (%car s))))
-
-#| less interesting methods elided: jmoringe: (un)parsing, specializer<?, more? |#
 #+end_src
+
+The code above shows the core of the use of our protocol.  We have
+elided some support code for parsing and unparsing specializers, and
+for handling introspective functions such as finding generic functions
+for a given specializer.  We have also elided methods on the protocol
+function =specializer<=; for =cons-specializers= here, specializer
+ordering is trivial, as only one =cons-specializer= can ever be
+applicable to any given argument.  See section [[#Accept]] for a case
+where specializer ordering is substantially different.
+
+As in \cite{Newton.Rhodes:2008}, we can use these specializers to
+implement a modular code walker, where we define one method per
+special operator.  We show two of those methods below, in the context
+of a walker which checks for unused bindings and uses of unbound
+variables.
+
 #+begin_src
-(defgeneric walk (form env vars)
+(defgeneric walk (form env stack)
   (:generic-function-class cons-generic-function))
 (defmethod walk ((expr (cons lambda)) env call-stack)
   (let ((lambda-list (cadr expr))
         (body (cddr expr)))
-    (with-checked-bindings ((bindings-from-ll lambda-list) env call-stack)
+    (with-checked-bindings
+        ((bindings-from-ll lambda-list) env call-stack)
       (dolist (form body)
         (walk form env (cons form call-stack))))))
 (defmethod walk ((expr (cons let)) env call-stack)
-  (with-checked-bindings ((mapcar (lambda (x) (walk (cadr x) env (cons (cadr x) call-stack)) (cons (car  x) (make-instance 'binding))) (cadr expr)) env call-stack)
-    (dolist (form (cddr expr))
-      (walk form env (cons form call-stack)))))
+  (flet ((let-binding (x)
+           (walk (cadr x) env (cons (cadr x) call-stack))
+           (cons (car x) (make-instance 'binding))))
+    (with-checked-bindings
+        ((mapcar #'let-binding (cadr expr)) env call-stack)
+      (dolist (form (cddr expr))
+        (walk form env (cons form call-stack))))))
 #+end_src
 
-   | implementation        | time (ms / 100k calls) | overhead |
-   |-----------------------+------------------------+----------|
-   | cons-gf/no-cache      |                   9000 |   +2700% |
-   | cons-gf               |                   1500 |    +370% |
-   | cons-gf/one-arg-cache |                    740 |    +130% |
-   | gf/methods            |                    360 |     +14% |
-   | function              |                    317 |          |
-
    Note that in this example there is no strict need for
    =cons-specializer= and =cons-generalizer= to be distinct classes –
    just as in the normal protocol involving
    for mediating dispatch contains the same information as the object
    representing the equivalence class of objects to which that
    specializer is applicable: here it is the =car= of the =cons=
-   object; in the standard dispatch it is the =class= of the object.
-   This feature also characterizes those use cases where the
-   metaprogrammer could straightforwardly use filtered dispatch
-   \cite{Costanza.etal:2008} to implement their dispatch semantics.
-   We will see in section XX.x an example of a case where filtered
-   dispatch is incapable of efficiently implementing the dispatch, but
-   first we present our implementation of the motivating case from
-   \cite{Costanza.etal:2008}.
-** signum
+   (which we wrap in a distinct object); in the standard dispatch it
+   is the =class= of the object.  This feature also characterizes
+   those use cases where the metaprogrammer could straightforwardly
+   use filtered dispatch \cite{Costanza.etal:2008} to implement their
+   dispatch semantics.  We will see in section [[#Accept]] an example
+   of a case where filtered dispatch is incapable of straightforwardly
+   expressing the dispatch, but first we present our implementation of
+   the motivating case from \cite{Costanza.etal:2008}.
+** SIGNUM specializers
+   :PROPERTIES:
+   :CUSTOM_ID: Signum
+   :END:
    Our second example of the implementation and use of generalized
    specializers is a reimplementation of one of the examples in
    \cite{Costanza.etal:2008}: specifically, the factorial function.
   ((%signum :reader %signum :initarg :signum)))
 (defclass signum-generalizer (generalizer)
   ((%signum :reader %signum :initarg :signum)))
-(defmethod generalizer-of-using-class ((gf signum-generic-function) arg)
+(defmethod generalizer-of-using-class
+    ((gf signum-generic-function) arg)
   (typecase arg
-    (real (make-instance 'signum-generalizer :signum (signum arg)))
+    (real (make-instance 'signum-generalizer
+                         :signum (signum arg)))
     (t (call-next-method))))
-(defmethod generalizer-equal-hash-key ((gf signum-generic-function)
-                                       (g signum-specializer))
-  (%signum g)) ; this will create multiple entries for the same emf, but that's OK
-(defmethod specializer-accepts-generalizer-p ((gf signum-generic-function)
-                                              (s signum-specializer)
-                                              (g signum-generalizer))
+(defmethod generalizer-equal-hash-key
+    ((gf signum-generic-function)
+     (g signum-specializer))
+  (%signum g))
+(defmethod specializer-accepts-generalizer-p
+    ((gf signum-generic-function)
+     (s signum-specializer)
+     (g signum-generalizer))
   (if (= (%signum s) (%signum g)) ; or EQL?
       (values t t)
       (values nil t)))
 
-;; this method is perhaps interesting enough to talk about?
-(defmethod specializer-accepts-generalizer-p ((gf signum-generic-function) (specializer sb-mop:specializer) (thing signum-specializer))
-  (specializer-accepts-generalizer-p gf specializer (class-of (%signum thing))))
+(defmethod specializer-accepts-generalizer-p
+    ((gf signum-generic-function)
+     (specializer sb-mop:specializer)
+     (thing signum-specializer))
+  (specializer-accepts-generalizer-p
+   gf specializer (class-of (%signum thing))))
 
-
-(defmethod specializer-accepts-p ((s signum-specializer) o)
+(defmethod specializer-accepts-p
+    ((s signum-specializer) o)
   (and (realp o) (= (%signum s) (signum o))))
-
-#| again elide more boring methods |#
 #+end_src
 
-   Given these definitions, and some more straightforward ones elided
-   for reasons of space, we can implement the factorial function as
-   follows:
+   Given these definitions, and once again some more straightforward
+   ones elided for reasons of space, we can implement the factorial
+   function as follows:
 
 #+begin_src lisp
 (defgeneric fact (n)
    We do not need to include a method on =(signum -1)=, as the
    standard =no-applicable-method= protocol will automatically apply to
    negative real or non-real arguments.
-
-   Benchmarketing: we chose to benchmark 20! because that is the
-   largest factorial whose answer fits in SBCL's 63-bit fixnums, so as
-   to attempt to measure the maximum effect of dispatch (unobscured by
-   allocation / gc issues)
-
-#+begin_src lisp
-(progn (gc :full t) (time (dotimes (i 10000) (%fact 20))))
-#+end_src
-
-   | implementation          | time (ms/10k calls) | overhead |
-   |-------------------------+---------------------+----------|
-   | signum-gf/no-cache      |                2400 |  +41000% |
-   | signum-gf               |                 230 |   +3800% |
-   | signum-gf/one-arg-cache |                  75 |   +1100% |
-   | gf/fixnum               |                  12 |    +100% |
-   | function                |                 6.0 |          |
-
-   We could allow the metaprogrammer to improve on the one-argument
-   performance by constructing a specialized cache: for =signum=
-   arguments of =rational= arguments, the logical cache structure is
-   to index a three-element vector with =(1+ signum)=.  The current
-   protocol does not provide a way of eliding the two generic function
-   calls for the generic cache; we discuss possible approaches in
-   section WW.
-** HTTP Accept header
+** Accept HTTP header specializers
+   :PROPERTIES:
+   :CUSTOM_ID: Accept
+   :END:
    In this section, we implement a non-trivial form of dispatch.  The
    application in question is a web server, and specifically to allow
    the programmer to support RFC 2616 \cite{rfc2616} content
    REST-style Web APIs.
 
    The basic mechanism in content negotiation is as follows: the web
-   client sends an HTTP request with an =Accept:= header, which is a
+   client sends an HTTP request with an =Accept= header, which is a
    string describing the media types it is willing to receive as a
    response to the request, along with numerical preferences.  The web
    server compares these stated client preferences with the resources
    it has available to satisfy this request, and sends the best
    matching resource in its response.
 
+   For example, a graphical web browser might by default send an
+   =Accept= header such as
+   =text/html,application/xml;q=0.9,*/*;q=0.8=.  This should be
+   interpreted by a web server as meaning that if for a given resource
+   the server can provide content of type =text/html= (i.e. HTML),
+   then it should do so.  Otherwise, if it can provide
+   =application/xml= content (i.e. XML of any schema), then that
+   should be provided; failing that, any other content type is
+   acceptable.
+
    In the case where there are static files on the filesystem, and the
    web server must merely select between them, there is not much more
    to say.  However, it is not unusual for a web service to be backed
    by some other form of data, and responses computed and sent on the
    fly, and in these circumstances the web server must compute which
    of its known output formats it can use to satisfy the request
-   before actually generating the best matching response.
+   before actually generating the best matching response.  This can be
+   modelled as one generic function responsible for generating the
+   response, with methods corresponding to content-types -- and the
+   generic function must then perform method selection against the
+   request's =Accept= header to compute the appropriate response.
 
    The =accept-specializer= below implements the dispatch.  It depends
    on a lazily-computed =tree= slot to represent the information in
    level.
 
 #+begin_src lisp
-(defclass accept-specializer (extended-specializer)
+(defclass accept-specializer (specializer)
   ((media-type :initarg :media-type :reader media-type)))
-(defclass accept-generalizer ()
+(defclass accept-generalizer (generalizer)
   ((header :initarg :header :reader header)
    (tree)
    (next :initarg :next :reader next)))
 (defmethod generalizer-equal-hash-key
-    ((gf accept-generic-function) (g accept-generalizer))
-   `(accept-generalizer ,(header g)))
-(defmethod specializer-accepts-generalizer-p ((gf accept-generic-function) (s acc
-ept-specializer) (generalizer accept-generalizer))
+    ((gf accept-generic-function)
+     (g accept-generalizer))
+  `(accept-generalizer ,(header g)))
+(defmethod specializer-accepts-generalizer-p
+    ((gf accept-generic-function)
+     (s accept-specializer)
+     (generalizer accept-generalizer))
   (values (q (media-type s) (tree generalizer)) t))
-(defmethod specializer-accepts-generalizer-p ((gf accept-generic-function) (s sb-
-mop:specializer) (generalizer accept-generalizer))
-  (specializer-accepts-generalizer-p gf s (next generalizer)))
-
-(defmethod specializer< ((gf accept-generic-function) (s1 accept-specializer) (s2
- accept-specializer) generalizer)
-  (cond
-    ((string= (media-type s1) (media-type s2)) '=)
-    (t (let ((q1 (q (media-type s1) (tree generalizer)))
-             (q2 (q (media-type s2) (tree generalizer))))
-         (cond
-           ((= q1 q2) '=)
-           ((< q1 q2) '>)
-           (t '<))))))
+(defmethod specializer-accepts-generalizer-p
+    ((gf accept-generic-function)
+     (s specializer)
+     (generalizer accept-generalizer))
+  (specializer-accepts-generalizer-p
+   gf s (next generalizer)))
+
+(defmethod specializer<
+    ((gf accept-generic-function)
+     (s1 accept-specializer)
+     (s2 accept-specializer)
+     (generalizer accept-generalizer))
+  (let ((m1 (media-type s1))
+        (m2 (media-type s2))
+        (tree (tree generalizer)))
+    (cond
+      ((string= m1 m2) '=)
+      (t (let ((q1 (q m1 tree)))
+               (q2 (q m2 tree))))
+           (cond
+             ((= q1 q2) '=)
+             ((< q1 q2) '>)
+             (t '<))))))
 #+end_src
 
+   The metaprogrammer can then support dispatching in this way for
+   suitable objects, such as the =request= object representing a
+   client request in the Hunchentoot web server.  The code below
+   implements this, by defining the computation of a suitable
+   =generalizer= object for a given request, and specifying how to
+   compute whether the specializer accepts the given request object
+   (=q= returns a number between 0 and 1 if any pattern in the =tree=
+   matches the media type, and =nil= if the media type cannot be
+   matched at all).
+
 #+begin_src
-(defmethod generalizer-of-using-class ((gf accept-generic-function) (arg tbnl:request))
+(defmethod generalizer-of-using-class
+    ((gf accept-generic-function)
+     (arg tbnl:request))
   (make-instance 'accept-generalizer
                  :header (tbnl:header-in :accept arg)
                  :next (class-of arg)))
-(defmethod specializer-accepts-p ((specializer accept-specializer) (obj tbnl:requ
-est))
-  (q (media-type specializer) (parse-accept-string (tbnl:header-in :accept obj)))
-)
+(defmethod specializer-accepts-p
+    ((specializer accept-specializer)
+     (obj tbnl:request))
+  (let* ((accept (tbnl:header-in :accept obj))
+         (tree (parse-accept-string accept))
+         (q (q (media-type specializer) tree)))
+    (and q (> q 0))))
 #+end_src
 
-   This dispatch can't be done with filtered dispatch, except by
-   generating anonymous classes with all the right mime-types as
+   This dispatch cannot be implemented using filtered dispatch, except
+   by generating anonymous classes with all the right mime-types as
    direct superclasses in dispatch order; the filter would generate
 #+begin_src lisp
-(ensure-class nil :direct-superclasses '(text/html image/webp ...))
+(ensure-class nil :direct-superclasses
+ '(text/html image/webp ...))
 #+end_src
-   and dispatch the operates using those anonymous classes.
-
-   While this is possible to do, it is awkward to express content-type
+   and dispatch the operates using those anonymous classes.  While
+   this is possible to do, it is awkward to express content-type
    negotiation in this way, as it means that the dispatcher must know
    about the universe of mime-types that clients might declare that
    they accept, rather than merely the set of mime-types that a
@@ -387,45 +453,243 @@ est))
 
    Note that in this example, the method on =specializer<= involves a
    nontrivial ordering of methods based on the =q= values specified in
-   the accept header (whereas in sections XX.1 and XX.2 only a single
-   extended specializer could be applicable to any given argument).
+   the accept header (whereas in sections [[#Cons]] and [[#Signum]] only a
+   single extended specializer could be applicable to any given
+   argument).
 
    Also note that the accept specializer protocol is straightforwardly
    extensible to other suitable objects; for example, one simple
    debugging aid is to define that an =accept-specializer= should be
    applicable to =string= objects.  This can be done in a modular
-   fashion (see source example NN), and generalizes to dealing with
-   multiple web server libraries, so that content-negotiation methods
-   are applicable to each web server's request objects.
+   fashion (see the code below, which can be completely disconnected
+   from the code for Hunchentoot request objects), and generalizes to
+   dealing with multiple web server libraries, so that
+   content-negotiation methods are applicable to each web server's
+   request objects.
 
 #+begin_src lisp
-(defmethod generalizer-of-using-class ((gf accept-generic-function) (s string))
+(defmethod generalizer-of-using-class
+    ((gf accept-generic-function)
+     (s string))
   (make-instance 'accept-generalizer
                  :header s
                  :next (class-of s)))
-(defmethod specializer-accepts-p ((s accept-specializer) (string string))
-  (q (media-type s) (parse-accept-string string)))
+(defmethod specializer-accepts-p
+    ((s accept-specializer) (string string))
+  (let* ((tree (parse-accept-string string))
+         (q (q (media-type s) tree)))
+    (and q (> q 0))))
 #+end_src
-   jmoringe: the name =accept-specializer=, while sensible, may
-   confusing in this context because "accept" occurs as part of the
-   protocol with a different semantic.
 ** Pattern / xpattern / regex / optima
    Here's the /really/ interesting bit, but on the other hand we're
    probably going to run out of space, and the full description of
    these is going to take us into =make-method-lambda= territory.
    A second paper?  Future work?
 * Protocol
-** Generalizer
-   - [ ] =generalizer-of-using-class= (NB class of gf not class of object)
-   - [ ] =compute-applicable-methods-using-generalizers=
-   - [ ] =generalizer-equal-hash-key=
-   - [ ] =specializer-accepts-generalizer-p=
-   - [ ] =specializer-accepts-p=
-   - [ ] =specializer<=
-     jmoringe: If I remember correctly, closette has
-     =method-more-specific-p= should we aim for parity with that and
-     use =specializer-more-specific-p=? The downside would be that
-     =-p= indicates a Boolean return value which is not the case here.
+  :PROPERTIES:
+  :CUSTOM_ID: Protocol
+  :END:
+
+  In section [[#Examples]], we have seen a number of code fragments as
+  partial implementations of particular non-standard method dispatch,
+  using =generalizer= metaobjects to mediate between the methods of
+  the generic function and the actual arguments passed to it.  In
+  section [[#Generalizer metaobjects]], we go into more detail regarding
+  these =generalizer= metaobjects, describing the generic function
+  invocation protocol in full, and showing how this protocol allows a
+  similar form of effective method cacheing as the standard one does.
+  In section [[#Generalizer performance]], we show the results of some
+  simple performance measurements to highlight the improvement that
+  this protocol can bring over a naïve implementation of generalized
+  dispatch, as well as highlighting the potential for further
+  improvement.
+
+** Generalizer metaobjects
+   :PROPERTIES:
+   :CUSTOM_ID: Generalizer metaobjects
+   :END:
+
+*** Generic function invocation
+    As in the standard generic function invocation protocol, the
+    generic function's actual functionality is provided by a
+    discriminating function.  The functionality described in this
+    protocol is implemented by having a distinct subclass of
+    =standard-generic-function=, and a method on
+    =compute-discriminating-function= which produces a custom
+    discriminating function.  The basic outline of the discriminating
+    function is the same as the standard one: it must first compute the
+    set of applicable methods given particular arguments; from that, it
+    must compute the effective method by combining the methods
+    appropriately according to the generic function's method
+    combination; finally, it must call the effective method with the
+    arguments.
+
+    Computing the set of applicable methods is done using a pair of
+    functions: =compute-applicable-methods=, the standard metaobject
+    function, and a new function
+    =compute-applicable-methods-using-generalizers=.  We define a
+    custom method on =compute-applicable-methods= which tests the
+    applicability of a particular specializer against a given argument
+    using =specializer-accepts-p=, a new protocol function with
+    default implementations on =class= and =eql-specializer= to
+    implement the expected behaviour.  In order to order the methods,
+    as required by the protocol, we define a pairwise comparison
+    operator =specializer<= which defines an ordering between
+    specializers for a given generalizer argument (remembering that
+    even in standard CLOS the ordering between =class= specializers
+    can change depending on the actual class of the argument).
+
+    The new =compute-applicable-methods-using-generalizers= is the
+    analogue of the MOP's =compute-applicable-methods-using-classes=.
+    Instead of calling it with the =class-of= each argument, we compute
+    the generalizers of each argument using the new function
+    =generalizer-of-using-class= (where the =-using-class= refers to
+    the class of the generic function rather than the class of the
+    object), and call it with the list of generalizers.  As with the
+    standard function, a secondary return value indicates whether the
+    result of the function is definitive for that list of generalizers.
+
+    Thus, in generic function invocation, we first compute the
+    generalizers of the arguments; we compute the ordered set of
+    applicable methods, either from the generalizers or (if that is
+    not definitive) from the arguments themselves; then the normal
+    effective method computation and call can occur.  Unfortunately,
+    the nature of an effective method object is not specified, so we
+    have to reach into implementation internals a little in order to
+    call it, but otherwise the remainder of the generic function
+    invocation protocol is unchanged from the standard one.  In
+    particular, method combination is completely unchanged;
+    programmers can choose arbitrary method combinations, including
+    user-defined long form combinations, for their generic functions
+    involving generalized dispatch.
+
+*** Effective method memoization
+    :PROPERTIES:
+    :CUSTOM_ID: Memoization
+    :END:
+    The potential efficiency benefit to having =generalizer=
+    metaobjects lies in the use of
+    =compute-applicable-methods-using-generalizers=.  If a particular
+    generalized specializer accepts a variety of objects (such as the
+    =signum= specializer accepting all reals with a given sign, or the
+    =accept= specializer accepting all HTTP requests with a particular
+    =Accept= header), then there is the possibility of cacheing and
+    reusing the results of the applicable and effective method
+    computation.  If the computation of the applicable method from
+    =compute-applicable-methods-using-generalizers= is definitive,
+    then the ordered set of applicable methods and the effective
+    method can be cached.
+
+    One issue is what to use as the key for that cache.  We cannot use
+    the generalizers themselves, as two generalizers that should be
+    considered equal for cache lookup will not compare as =equal= –
+    and indeed even the standard generalizer, the =class=, cannot be
+    used as we must be able to invalidate cache entries upon class
+    redefinition.  The issue of =class= generalizers we can solve as
+    in \cite{Kiczales.Rodriguez:1990} by using the =wrapper= of a
+    class, which is distinct for each distinct (re)definition of a
+    class; for arbitrary generalizers, however, there is /a priori/ no
+    good way of computing a suitable hash key automatically, so we
+    allow the metaprogrammer to specify one by defining a method on
+    =generalizer-equal-hash-key=, and combining the hash keys for all
+    required arguments in a list to use as a key in an =equal=
+    hash-table.
+
+    [XXX could we actually compute a suitable hash key using the
+    generalizer's class name and initargs?]
+
+    - [X] =generalizer-of-using-class= (NB class of gf not class of object)
+    - [X] =compute-applicable-methods-using-generalizers=
+    - [X] =generalizer-equal-hash-key=
+    - [X] =specializer-accepts-generalizer-p=
+    - [X] =specializer-accepts-p=
+    - [X] =specializer<=
+** Performance
+   :PROPERTIES:
+   :CUSTOM_ID: Generalizer performance
+   :END:
+   We have argued that the protocol presented here allows for
+   expressive control of method dispatch while preserving the
+   possibility of efficiency.  In this section, we quantify the
+   efficiency that the memoization protocol described in section
+   [[#Memoization]] achieves, by comparing it both to the same protocol
+   with no memoization, as well as with equivalent dispatch
+   implementations in the context of methods with regular
+   specializers, and with implementation in straightforward functions.
+
+   In the case of the =cons-specializer=, we benchmark the walker
+   acting on a small but non-trivial form.  The implementation
+   strategies in the table below refer to: an implementation in a
+   single function with a large =typecase= to dispatch between all the
+   cases; the natural implementation in terms of a standard generic
+   function with multiple methods (the method on =cons= having a
+   slightly reduced =typecase= to dispatch on the first element, and
+   other methods handling =symbol= and other atoms); and three
+   separate cases using =cons-specializer= objects.  As well as
+   measuring the effect of memoization against the full invocation
+   protocol, we can also introduce a special case: when only one
+   argument participates in method selection (all the other required
+   arguments only being specialized on =t=), we can avoid the
+   construction of a list of hash keys and simply use the key
+   from the single active generalizer directly.
+
+   Refer to \cite{Kiczales.Rodriguez:1990}
+
+   | implementation        | time (µs/call) | overhead |
+   |-----------------------+----------------+----------|
+   | function              |           3.17 |          |
+   | standard-gf/methods   |            3.6 |     +14% |
+   | cons-gf/one-arg-cache |            7.4 |    +130% |
+   | cons-gf               |             15 |    +370% |
+   | cons-gf/no-cache      |             90 |   +2700% |
+
+   The benchmarking results from this exercise are promising: in
+   particular, the introduction of the effective method cache speeds
+   up the use of generic specializers in this case by a factor of 6,
+   and the one-argument special case by another factor of 2.  For this
+   workload, even the one-argument special case only gets to within a
+   factor of 2-3 of the function and standard generic function
+   implementations, but the overall picture is that the memoizability
+   in the protocol does indeed drastically reduce the overhead
+   compared with the full invocation.
+
+   For the =signum-specializer= case, we choose to benchmark the
+   computation of 20!, because that is the largest factorial whose
+   answer fits in SBCL's 63-bit fixnums – in an attempt to measure the
+   worst case for generic dispatch, where the work done within the
+   methods is as small as possible without being meaningless, and in
+   particular does not cause allocation or garbage collection to
+   obscure the picture.
+
+#+begin_src lisp :exports none
+(progn (gc :full t) (time (dotimes (i 10000) (%fact 20))))
+#+end_src
+
+   | implementation          | time (µs/call) | overhead |
+   |-------------------------+----------------+----------|
+   | function                |            0.6 |          |
+   | standard-gf/fixnum      |            1.2 |    +100% |
+   | signum-gf/one-arg-cache |            7.5 |   +1100% |
+   | signum-gf               |             23 |   +3800% |
+   | signum-gf/no-cache      |            240 |  +41000% |
+
+   The relative picture is similar to the =cons-specializer= case;
+   including a cache saves a factor of 10 in this case, and another
+   factor of 3 for the one-argument cache special case.  The cost of
+   the genericity of the protocol here is starker; even the
+   one-argument cache is a factor of 6 slower than the standard
+   generic-function implementation, and a further factor of 2 away
+   from the implementation of factorial as a function.  We discuss
+   ways in which we expect to be able to improve performance in
+   section [[#Future Work]].
+
+   We could allow the metaprogrammer to improve on the one-argument
+   performance by constructing a specialized cache: for =signum=
+   arguments of =rational= arguments, the logical cache structure is
+   to index a three-element vector with =(1+ signum)=.  The current
+   protocol does not provide a way of eliding the two generic function
+   calls for the generic cache; we discuss possible approaches in
+   section [[#Conclusions]].
 ** Full protocol
    Description and specification left for reasons of space (we'll see?)
    - [ ] =same-specializer-p=
@@ -457,16 +721,25 @@ est))
      jmoringe: would only be relevant for pattern dispatch, right? I
      think, we didn't finish the discussion regarding special
      variables vs. environment vs. new protocol function
+
 * Related Work
-  - [ ] Newton/Rhodes, obv
+  :PROPERTIES:
+  :CUSTOM_ID: Related Work
+  :END:
+  - [ ] Newton/Rhodes, \cite{Newton.Rhodes:2008}
   - [ ] filtered dispatch -- the point is that our work continues to
     be useful in cases where there are unbounded numbers of
     equivalence classes but each given invokation involves a small
-    number of methods.
+    number of methods.  Filtered dispatch works by having a custom
+    discriminating function which wraps the usual one, and augments
+    the set of applicable methods computed with applicable methods
+    from other (hidden) generic functions (one per filter group).  It
+    then also has a custom method combination to handle combining
+    these applicable methods.  \cite{Costanza.etal:2008}
   - [ ] ContextL / context-oriented programming -- dispatch occurs on
     hidden layer argument being an instance of an anonymous class with
     suitably arranged superclasses -- OK because set of layers is
-    bounded and under programmer control
+    bounded and under programmer control.  \cite{Hirschfeld.etal:2008,Vallejos.etal:2010}
   - [ ] http://soft.vub.ac.be/Publications/2010/vub-tr-soft-10-04.pdf
   - [ ] http://soft.vub.ac.be/lambic/files/lambic-ilc09.pdf
   - [ ] http://soft.vub.ac.be/Publications/2011/vub-soft-phd-11-03.pdf
@@ -476,24 +749,79 @@ est))
     A good test case for our protocol; handled adequately with
     generalizer being the tuple of (roles,delegations), with some
     thought needed for method redefinitions but otherwise working
-    fine.
+    fine. \cite{Salzman.Aldrich:2005}
   - [ ] Sheeple
   - [ ] Multiple dispatch in Clojure
     http://clojure.org/multimethods -- seems to allow hierarchy-based,
     eql and the equivalent of filtered dispatch
 * Conclusions
+  :PROPERTIES:
+  :CUSTOM_ID: Conclusions
+  :END:
   - protocol for straightforward definition of custom dispatch
     + interoperates seamlessly with rest of CLOS: method combination,
       etc.
     + tolerably efficient: two extra standard gf invokations and one
       hash table lookup per call on the fast path (but more to be
       done)
-    + expressive: handles foms of dispatch not handled elsewhere; all
+    + expressive: handles forms of dispatch not handled elsewhere; all
       the usual niceties of redefinition, modularity, introspection
 ** Future Work
-   - compute-cache-handling-functions (and general speed issues)
-   - automatic pattern-specializer generalizer computation
-   - prototype-oriented progamming a la Slate.
+   :PROPERTIES:
+   :CUSTOM_ID: Future Work
+   :END:
+   Although the protocol described in this paper allows for a more
+   efficient implementation, as described in section [[#Memoization]],
+   than computing the applicable and effective methods at each generic
+   function call, the efficiency is still some way away from a
+   baseline of the standard generic-function, let alone a standard
+   function.  Most of the invocation protocol is memoized, but there
+   are still two full standard generic-function calls –
+   =generalizer-of-using-class= and =generalizer-equal-hash-key= – per
+   argument per call to a generic function with extended specializers,
+   not to mention a hash table lookup.
+
+   For many applications, the additional flexibility afforded by
+   generalized specializers might be worth the cost in efficiency, but
+   it would still be worth investigating how much the overhead from
+   generalized specializers can be reduced; one possible avenue for
+   investigation is giving greater control over the cacheing strategy
+   to the metaprogrammer.
+
+   As an example, consider the =signum-specializer=.  The natural
+   cache structure for a single argument generic function specializing
+   on =signum= is probably a four-element vector, where the first
+   three elements hold the effective methods for =signum= values of
+   -1, 0, and 1, and the fourth holds the cached effective methods for
+   everything else.  This would make the invocation of such functions
+   very fast for the (presumed) common case where the argument is in
+   fact a real number.  We hope to develop and show the effectiveness
+   of an appropriate protocol to allow the metaprogrammer to construct
+   and exploit such cacheing strategies, and (more speculatively) to
+   implement the lookup of an effective method function in other ways.
+
+   We also aim to demonstrate support within this protocol for some
+   particular cases of generalized specializers which seem to have
+   widespread demand (in as much as any language extension can be said
+   to be in “demand”).  In particular, we have preliminary work
+   towards supporting efficient dispatch over pattern specializers
+   such as implemented in the \textsf{Optima} library[fn:2], and over
+   a prototype object system similar to that in Slate
+   \cite{Salzman.Aldrich:2005}.  Our current source code for the work
+   described in this paper can be seen in the git source code
+   repository at [[http://christophe.rhodes.io/git/specializable.git]],
+   which will be updated with future developments.
 ** Acknowledgments
-   We thank Lee Salzman, Pascal Costanza, Mikel Evins for their
-   helpful discussions
+   We thank Lee Salzman, Pascal Costanza and Mikel Evins for helpful
+   and informative discussions, and all the respondents to one
+   author's call for imaginative uses for generalized specializers.
+
+\bibliographystyle{plain}
+\bibliography{crhodes,specializers}
+
+* Footnotes
+
+[fn:1] the \textsf{Closer to MOP} project attempts to harmonize the
+   different implementations of the metaobject protocol in Common Lisp.
+
+[fn:2] https://github.com/m2ym/optima