diff --git a/report/.gitignore b/report/.gitignore new file mode 100644 index 0000000..48f9c3f --- /dev/null +++ b/report/.gitignore @@ -0,0 +1,6 @@ +*.aux +*.log +*.out +*.ps +/auto +/auto/* diff --git a/report/puppylove.pdf b/report/puppylove.pdf new file mode 100644 index 0000000..1be4b8d Binary files /dev/null and b/report/puppylove.pdf differ diff --git a/report/puppylove.tex b/report/puppylove.tex new file mode 100644 index 0000000..54aa7ad --- /dev/null +++ b/report/puppylove.tex @@ -0,0 +1,356 @@ +% +% LaTeX template for prepartion of submissions to SIGTBD'16 +% +% Requires temporary version of sigplanconf style file provided on +% SIGTBD'16 web site. +% +\documentclass[sigtbd]{sigtbd-style} +% \documentclass[SIGTBD-cameraready]{sigplanconf-SIGTBD16} +% +% the following standard packages may be helpful, but are not required +% +\usepackage{courier} % standard fixed width font +\usepackage[scaled]{helvet} % see www.ctan.org/get/macros/latex/required/psnfss/psnfss2e.pdf +\usepackage{url} % format URLs +\usepackage{listings} % format code +\usepackage{epigraph} +\usepackage{enumitem} % adjust spacing in enums +\usepackage[colorlinks=true,allcolors=blue,breaklinks,draft=false]{hyperref} % hyperlinks, including DOIs and URLs in bibliography +% known bug: http://tex.stackexchange.com/questions/1522/pdfendlink-ended-up-in-different-nesting-level-than-pdfstartlink +\newcommand{\doi}[1]{doi:~\href{http://dx.doi.org/#1}{\Hurl{#1}}} % print a hyperlinked DOI + +% Comments +\newcommand{\va}[1]{\textcolor{red}{{\em VA:} #1}} +\newcommand{\sss}[1]{\textcolor{red}{{\em SS:} #1}} +\newcommand{\mv}[1]{\textcolor{red}{{\em MV:} #1}} + +\newcommand{\name}{\textit{Puppy Love}} + +\begin{document} + +\title{\name{}: Cryptographically secure anonymous couple matching} + +% +% any author declaration will be ignored when using 'SIGTBD' option (for double blind review) +% + +\authorinfo{Saksham Sharma} +{\makebox{Computer Science and Technology} \\ +\makebox{Indian Institute of Technology Kanpur} \\ +{sakshams@cse.iitk.ac.in}} + +\maketitle +\begin{abstract} + Anonymous and secure dating algorithms are not only hard to define, + but apparently tough to realize as well. Tinder et all have + succeeded in making this a mainstream application, and yet, there is + scope left in improving the anonymity of such platforms to provide + a guarantee to the users that their choices shall not be made + public, nor known to the administrators. + + We designed an algorithm for this problem which provides strong + guarantees about privacy of users, and implemented it inside our + campus, catering to almost 2000 users. The algorithm is designed to + be easily scalable, and was a success in the university setting. +\end{abstract} + +\section{Introduction} + +The queerly named \title{} platform has been running in IIT Kanpur +since 2014, meant to help shy nerds meet their crush. The platform +opens one week prior to the Valentine's Day every year, and lets people +choose up to 4 of their crushes. At the stroke of the midnight hour on +14th February, people who happen to like each other are informed about +the same. If your \textit{love} was unrequited (the other person +didn't like you), you will not get to know. More importantly, if you +did not like the other person, you would not know if that person liked +you or not. In addition, people can see the count of people who have +selected their names without finding out who they are. + +Since a campus is often a close knit circle, users are apprehensive +about revealing their crushes to others, including the administrators +(who are students themselves), lest it leak out. That makes it +necessary to design a technique to ensure that users are guaranteed +that obtaining their choices is either impossible or computationally +infeasible for anyone but them. + +We developed a new version of the platform which provides strong +privacy guarantees without compromising on performance or features. + +\section{Requirements from the algorithm} +The following discussion refers to $Alice$ and $Bob$. All +arguments apply to each of them.\\ +The security goals are the following: +\begin{enumerate} +\item $Alice$ should not find out the choice of person $Bob$ if $Alice$ + did not like $Bob$. +\item It should not be possible for $Alice$ to cheat and obtain + whether $Alice$ matched with the $Bob$, without this + information being made available for $Bob$. In other words, the + algorithm should be fair, and ideally symmetric. +\item The administrator should not be able to obtain the choices of + a person, or brute force the data in any way to deduce the likes + of a person. +\item The administrator should not find out which people matched, but + knowing the count of matches is reasonable. +\item The user should be able to verify that the frontend is not + sending any such information which could reveal their + choices. Thus, the privacy guarantees should hold whatever code is + running on the backend. +\item The counting technique should function independently without + revealing the identities of the users. +\item Security features should be practical to implement in a web + browser and should be completely transparent to the user. +\item It can be assumed that the server does not collude with + another involved party. Thus, the server is assumed to be + honest-but-curious and will not disrupt the service intentionally. +\end{enumerate} +Some other practical requirements: +\begin{enumerate} +\item The algorithm should have no false positives or false negatives. +\item It should ideally involve only $O(1)$ computation by each + involved party. +\item There should ideally be no to-and-fro communication between the + involved parties. +\end{enumerate} + +\section{Related work} +A similar problem was proposed and tackled in \cite{Senpai:1} where +the proposed various algorithms, including one which does present a +secure protocol. The drawback of such an algorithm is that it requires +all involved parties to take part in $O(n)$ computation, where $n$ is +the number of other parties. + +Our algorithm is completely different from this work, but it is +interesting to look at the mentioned paper nonetheless. + +\bibliographystyle{abbrvnat} + +\section{Initial approaches} +We went through a lot of approaches for this problem, before finally +arriving at the presented approach, which, although extremely simple, +is not obvious at first. + +We initially modelled the problem as computing the AND of $O(n^2)$ bits, +disregarding the requirement of $O(1)$ computations per person. + +\subsection{Homomorphic computation} + +Our initial attempts at homomorphic were foiled by the fact that +completely homomorphic systems are impractical. + +In contrast, partially homomorphic functions, although practical, do +not provide any function which can be used for this purpose. The +available computations are XOR, multiply, addition over 1 bit et +all. Composing any two of these functions provides enough information +to both parties to violate privacy concerns. + +\subsection{Yao's two party computation} +Yao presented a secure protocol to compute any arbitrary function +(which can be run using logic gates) across two parties in a shared +manner. The protocol was not originally intended to be fair though, +and one party could cheat in some respect. + +We describe the protocol here: +\begin{itemize} +\item Alice party creates a truth table for an AND gate, with columns + A (her choice), B (Bob's choice) and C (result). +\item She selects 6 random values $a_0, a_1, b_0, b_1, c_0, c_1$. She + then shuffles the table, and encrypts $((A = i) \& (B = j)) = Ck$ + with the value $a_i-b_j$. She then shares this table with Bob. +\item If Alice's boolean choice is $choice$, she sends $a_{choice}$ to + Bob as well. +\item Bob obtains $b_{bob's choice}$ from Alice using Oblivious + transfer, such that Alice will not know which bit value was obtained + by Bob. +\item Bob tries decrypting the table with the key $a_{alice}-b_{bob}$ + and finds out what value he obtained. He can then look up whether + they matched or not. +\end{itemize} + +We attempted to make the protocol fair by using the central server, +who would then match both parties and declare their result to them. + +A clever hack around this was found on noticing the asymmetry in the +algorithm. Alice could forge the truth table to return a $mismatch$ if +Bob likes Alice, and a $match$ otherwise. A false positive can be +borne easily, but if Bob did like Alice, he would not know that Alice +has cheated and has found out about his liking. This is certainly +unacceptable. + +\subsection{Public key encrypted messages} +This involves the following step: +\begin{itemize} +\item All parties get to send 4 values to the server. +\item If Alice likes Bob, she will send a message (string containing + their roll numbers) encrypted with Bob's + public key to the server. +\item Bob will encrypt the same message with his own public key and + store it on the server. +\item The person to use the other's public key is chosen using + lexicographic comparison. +\item The server will detect duplicates and declare matches. +\end{itemize} + +This is a very simple algorithm, but fails on a computationally +feasible brute force attack. The server can easily try out all +possible messages which Alice could have sent, and stop when it +produces a value which is the same as the one sent by Alice. + +\subsection{An O(n) algorithm using duplicates} +We observed that instead of trying to compute an AND, it may be +interesting to instead use the duplicate detection in another way. + +An algorithm for this is quite simple: +\begin{itemize} +\item Both parties establish an encrypted channel using their public + keys. +\item They both exchange a random token over this channel. Let the + tokens be $A, B$. +\item Both of them declare a value $hash(A+B)$ to the server, who + verifies that the values are the same. +\item Each party gets to send 4 new values to the server. +\item If Alice likes Bob, she will send the pre-decided $A$ to the + server. Otherwise she will send a random value. +\item Server computes $hash(A_{received}-B_{received})$ and matches it + with the values received earlier. If they are the same, it declares + a match. +\end{itemize} + +Although this algorithm has no obvious security concerns, it involves +a lot of computation, infact $O(n)$ computation per person. Our tests +showed a huge performance bottleneck on modern browsers while using +Stanford's $sjcl$ library for crypto-protocol implementations. + +The platform originally launched with this algorithm, but the +performance issues on scaling to $O(1000)$ people made it practically +impossible to run. + +\section{The Puppy Love algorithm} +The final algorithm was inspired by the previous $O(n)$ algorithm, +wherein it was identified that it is essential to come up with a +message which only the involved parties can create, and no one +else. This is the only step which was causing a $O(n)$ bottleneck. + +Apart from that, some other requirements (counting the number of +people who like you, stopping the server from knowing the matched +people) required some additions to this algorithm which are described +later. + +\subsection{Matching} +\begin{itemize} +\item There is a known generator field $g$. +\item Let the public key of Alice be $g^a$ and her private key be + $a$. The same is true for Bob's $g^b$ and $b$. +\item The value $g^{ab}$ cannot be computed by anyone other than Alice + and Bob, since it is the Discrete Logarithm problem, which is known + to not lie in PTime. +\item Both parties get to send 4 values to the server. +\item If Alice likes Bob, she will send $g^{ab}$ to + the server. The same applies to Bob. +\item The server declares a match if it detects a duplicate value. +\end{itemize} + +Some remarks: +\begin{enumerate} +\item The algorithm itself is quite simple, and does not present any + apparent privacy concerns. The only issue (to be resolved later) is + that the server will know which two people have matched. +\item It is extremely fast to implement, and running times are ideal + for browsers, since it involves only 4 maximum mathematical + computations. +\item Values received by the server appear completely random to it, + and cannot be brute forced. +\item The value of $g^{ab}$ is very easily obtained if the + Public-Private keypairs are ElGamal, as was in our case. This value + is simply the Diffie Hellman value computed in Elliptic Curve + Cryptography, and Stanford's $sjcl$ library provides a direct + function for this computation. +\end{enumerate} + +\subsection{Implementing the counting of people who like you} +We opted for a very simple solution to this, albeit it has a minor scope +for inconsistencies. + +When Alice sends her preferences, her client also encrypts a +random string with the public key of Bob (if Bob is among her +likes). This value is stored on the server in a list ordered by +timestamps. Other clients retrieve all new entries in this list +everytime they log back in, and try decrypting all received +values. The client can detect that some of the messages were encrypted +with the user's public key, but cannot detect the sender of the +message. + +\subsection{Ensuring that the server does not know the matches} +This was not implemented during 2017's deployment of the platform, but +should work fine regardless. +\begin{itemize} +\item Before sending the final chosen values to the server, the client + obtains the blind signatures of the values it plans to send. +\item The blind signatures, as well as the actual values which are + being sent will not be known to the server. +\item The client now switches IP (in our case, sends the packet + through the NAT of the university, re-entering the university + network using a reverse proxy, thus completely anonymizing the + identity of the sender), and sends its 4 tokens (with + signature) to the server without attaching its login cookie with + them. The server can only verify that the received values are + correctly signed. +\item The server declares all the matched tokens in the end, and + clients can check if their token is among this list of matched + tokens. +\end{itemize} + +\subsection{Miscellaneous security concerns} +There are some other concerns which are discussed here: +\begin{itemize} +\item IP switching is unreliable. The user may not be expected to + undertake this arduous task of accessing the platform behind a + VPN/Tor for the step of sending the tokens. Thankfully, our + university setup had a network which is known to be not in the + control of the students, and thus the packets may use the NAT to + ensure their identities are safe. +\item It is possible for the server to display fake public keys for + users. This surely is a concern, but can be easily verified. The + server does not ask for cookies while serving public keys, and thus, + it can be easily verified (by a concerned user) whether a different + public key is being server to some people. If the university + infrastructure allowed for reliable hosting of public keys, this + task could be eased. +\item The server may serve fake code for some users which reveals more + information. But in such a case, the hashes of the code received and + the code expected will not match, and a concerned user can verify + the same, or run a local copy of the code (which she has manually + verified to be safe). +\end{itemize} + +\section{Deployment} +The platform was well received, with more than 1800 students +registering on the website, and as many as 45 matched couples. There +were many people who had multiple matches, both among boys and girls. + +Although girls are outnumbered on the campus $1:10$, among the +registrants, the ratio was close to $1:5$. + +The backend was implemented in Golang, using the $iris$ web +framework. The frontend was written using Angular2 and TypeScript, +communicating with the backend using REST API of the backend. The +server resource usage was monitored and was observed to be very low +even during peak times, due to Golang's lightweight web +frameworks. MongoDB was used for data storage, and Redis was used to +ensure persistent sessions. + +\begin{thebibliography}{} +\softraggedright +\bibitem[(2015)]{Senpai:1} + Senpai: Solving the dating problem +\newblock SIGTBD 2017. + +\end{thebibliography} + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/report/sigtbd-style.cls b/report/sigtbd-style.cls new file mode 100644 index 0000000..8f724aa --- /dev/null +++ b/report/sigtbd-style.cls @@ -0,0 +1,1472 @@ +% +% IMPORTANT: Please only use this class file for submissions to PLDI'16 +% +% +% In the future, please use the 3.X official releases of this class +% file for subsequent SIGPLAN submissions, which is expected to +% become available soon. +% +% +%----------------------------------------------------------------------------- +% +% LaTeX Class/Style File +% +% Name: sigplanconf.cls +% +% Purpose: A LaTeX 2e class file for SIGPLAN conference proceedings. +% This class file supercedes acm_proc_article-sp, +% sig-alternate, and sigplan-proc. +% +% Author: Paul C. Anagnostopoulos +% Windfall Software +% 978 371-2316 +% paul [atsign] windfall.com +% +% Created: 12 September 2004 +% +% Revisions: See end of file. +% +% This work is licensed under the Creative Commons Attribution License. +% To view a copy of this license, visit +% http://creativecommons.org/licenses/by/3.0/ +% or send a letter to Creative Commons, 171 2nd Street, Suite 300, +% San Francisco, California, 94105, U.S.A. +% +%----------------------------------------------------------------------------- + + +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesClass{sigplanconf-tbd16}[2014/08/18 v3.0x ACM SIGPLAN Proceedings] + +% The following few pages contain LaTeX programming extensions adapted +% from the ZzTeX macro package. + +% Token Hackery +% ----- ------- + + +\def \@expandaftertwice {\expandafter\expandafter\expandafter} +\def \@expandafterthrice {\expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter} + +% This macro discards the next token. + +\def \@discardtok #1{}% token + +% This macro removes the `pt' following a dimension. + +{\catcode `\p = 12 \catcode `\t = 12 + +\gdef \@remover #1pt{#1} + +} % \catcode + +% This macro extracts the contents of a macro and returns it as plain text. +% Usage: \expandafter\@defof \meaning\macro\@mark + +\def \@defof #1:->#2\@mark{#2} + +% Control Sequence Names +% ------- -------- ----- + + +\def \@name #1{% {\tokens} + \csname \expandafter\@discardtok \string#1\endcsname} + +\def \@withname #1#2{% {\command}{\tokens} + \expandafter#1\csname \expandafter\@discardtok \string#2\endcsname} + +% Flags (Booleans) +% ----- ---------- + +% The boolean literals \@true and \@false are appropriate for use with +% the \if command, which tests the codes of the next two characters. + +\def \@true {TT} +\def \@false {FL} + +\def \@setflag #1=#2{\edef #1{#2}}% \flag = boolean + +% IF and Predicates +% -- --- ---------- + +% A "predicate" is a macro that returns \@true or \@false as its value. +% Such values are suitable for use with the \if conditional. For example: +% +% \if \@oddp{\x} \else \fi + +% A predicate can be used with \@setflag as follows: +% +% \@setflag \flag = {} + +% Here are the predicates for TeX's repertoire of conditional +% commands. These might be more appropriately interspersed with +% other definitions in this module, but what the heck. +% Some additional "obvious" predicates are defined. + +\def \@eqlp #1#2{\ifnum #1 = #2\@true \else \@false \fi} +\def \@neqlp #1#2{\ifnum #1 = #2\@false \else \@true \fi} +\def \@lssp #1#2{\ifnum #1 < #2\@true \else \@false \fi} +\def \@gtrp #1#2{\ifnum #1 > #2\@true \else \@false \fi} +\def \@zerop #1{\ifnum #1 = 0\@true \else \@false \fi} +\def \@onep #1{\ifnum #1 = 1\@true \else \@false \fi} +\def \@posp #1{\ifnum #1 > 0\@true \else \@false \fi} +\def \@negp #1{\ifnum #1 < 0\@true \else \@false \fi} +\def \@oddp #1{\ifodd #1\@true \else \@false \fi} +\def \@evenp #1{\ifodd #1\@false \else \@true \fi} +\def \@rangep #1#2#3{\if \@orp{\@lssp{#1}{#2}}{\@gtrp{#1}{#3}}\@false \else + \@true \fi} +\def \@tensp #1{\@rangep{#1}{10}{19}} + +\def \@dimeqlp #1#2{\ifdim #1 = #2\@true \else \@false \fi} +\def \@dimneqlp #1#2{\ifdim #1 = #2\@false \else \@true \fi} +\def \@dimlssp #1#2{\ifdim #1 < #2\@true \else \@false \fi} +\def \@dimgtrp #1#2{\ifdim #1 > #2\@true \else \@false \fi} +\def \@dimzerop #1{\ifdim #1 = 0pt\@true \else \@false \fi} +\def \@dimposp #1{\ifdim #1 > 0pt\@true \else \@false \fi} +\def \@dimnegp #1{\ifdim #1 < 0pt\@true \else \@false \fi} + +\def \@vmodep {\ifvmode \@true \else \@false \fi} +\def \@hmodep {\ifhmode \@true \else \@false \fi} +\def \@mathmodep {\ifmmode \@true \else \@false \fi} +\def \@textmodep {\ifmmode \@false \else \@true \fi} +\def \@innermodep {\ifinner \@true \else \@false \fi} + +\long\def \@codeeqlp #1#2{\if #1#2\@true \else \@false \fi} + +\long\def \@cateqlp #1#2{\ifcat #1#2\@true \else \@false \fi} + +\long\def \@tokeqlp #1#2{\ifx #1#2\@true \else \@false \fi} +\long\def \@xtokeqlp #1#2{\expandafter\ifx #1#2\@true \else \@false \fi} + +\long\def \@definedp #1{% + \expandafter\ifx \csname \expandafter\@discardtok \string#1\endcsname + \relax \@false \else \@true \fi} + +\long\def \@undefinedp #1{% + \expandafter\ifx \csname \expandafter\@discardtok \string#1\endcsname + \relax \@true \else \@false \fi} + +\def \@emptydefp #1{\ifx #1\@empty \@true \else \@false \fi}% {\name} + +\let \@emptylistp = \@emptydefp + +\long\def \@emptyargp #1{% {#n} + \@empargp #1\@empargq\@mark} +\long\def \@empargp #1#2\@mark{% + \ifx #1\@empargq \@true \else \@false \fi} +\def \@empargq {\@empargq} + +\def \@emptytoksp #1{% {\tokenreg} + \expandafter\@emptoksp \the#1\@mark} + +\long\def \@emptoksp #1\@mark{\@emptyargp{#1}} + +\def \@voidboxp #1{\ifvoid #1\@true \else \@false \fi} +\def \@hboxp #1{\ifhbox #1\@true \else \@false \fi} +\def \@vboxp #1{\ifvbox #1\@true \else \@false \fi} + +\def \@eofp #1{\ifeof #1\@true \else \@false \fi} + + +% Flags can also be used as predicates, as in: +% +% \if \flaga \else \fi + + +% Now here we have predicates for the common logical operators. + +\def \@notp #1{\if #1\@false \else \@true \fi} + +\def \@andp #1#2{\if #1% + \if #2\@true \else \@false \fi + \else + \@false + \fi} + +\def \@orp #1#2{\if #1% + \@true + \else + \if #2\@true \else \@false \fi + \fi} + +\def \@xorp #1#2{\if #1% + \if #2\@false \else \@true \fi + \else + \if #2\@true \else \@false \fi + \fi} + +% Arithmetic +% ---------- + +\def \@increment #1{\advance #1 by 1\relax}% {\count} + +\def \@decrement #1{\advance #1 by -1\relax}% {\count} + +% Options +% ------- + + +\@setflag \@authoryear = \@false +\@setflag \@blockstyle = \@false +\@setflag \@copyrightwanted = \@true +\@setflag \@explicitsize = \@false +\@setflag \@legacycopyright = \@false +\@setflag \@mathtime = \@false +\@setflag \@natbib = \@true +\@setflag \@ninepoint = \@true +\newcount{\@numheaddepth} \@numheaddepth = 3 +\@setflag \@onecolumn = \@false +\@setflag \@preprint = \@false +\@setflag \@reprint = \@false +\@setflag \@tenpoint = \@false +\@setflag \@times = \@false +\@setflag \@squareay = \@false +\@setflag \@blind = \@false +\@setflag \@pldi = \@false +\@setflag \@pldicrc = \@false +\@setflag \@clearpagebib = \@false + +% Note that all the dangerous article class options are trapped. + +\DeclareOption{9pt}{\@setflag \@ninepoint = \@true + \@setflag \@explicitsize = \@true} + +\DeclareOption{10pt}{\PassOptionsToClass{10pt}{article}% + \@setflag \@ninepoint = \@false + \@setflag \@tenpoint = \@true + \@setflag \@explicitsize = \@true} + +\DeclareOption{11pt}{\PassOptionsToClass{11pt}{article}% + \@setflag \@ninepoint = \@false + \@setflag \@explicitsize = \@true} + +\DeclareOption{12pt}{\@unsupportedoption{12pt}} + +\DeclareOption{a4paper}{\@unsupportedoption{a4paper}} + +\DeclareOption{a5paper}{\@unsupportedoption{a5paper}} + +\DeclareOption{authoryear}{\@setflag \@authoryear = \@true} + +\DeclareOption{b5paper}{\@unsupportedoption{b5paper}} + +\DeclareOption{blockstyle}{\@setflag \@blockstyle = \@true} + +\DeclareOption{cm}{\@setflag \@times = \@false} + +\DeclareOption{computermodern}{\@setflag \@times = \@false} + +\DeclareOption{executivepaper}{\@unsupportedoption{executivepaper}} + +\DeclareOption{indentedstyle}{\@setflag \@blockstyle = \@false} + +\DeclareOption{landscape}{\@unsupportedoption{landscape}} + +\DeclareOption{legacycopyright}{\@setflag \@legacycopyright = \@true} + +\DeclareOption{legalpaper}{\@unsupportedoption{legalpaper}} + +\DeclareOption{letterpaper}{\@unsupportedoption{letterpaper}} + +\DeclareOption{mathtime}{\@setflag \@mathtime = \@true} + +\DeclareOption{natbib}{\@setflag \@natbib = \@true} + +\DeclareOption{nonatbib}{\@setflag \@natbib = \@false} + +\DeclareOption{nocopyrightspace}{\@setflag \@copyrightwanted = \@false} + +\DeclareOption{notitlepage}{\@unsupportedoption{notitlepage}} + +\DeclareOption{numberedpars}{\@numheaddepth = 4} + +\DeclareOption{numbers}{\@setflag \@authoryear = \@false} + +%%%\DeclareOption{onecolumn}{\@setflag \@onecolumn = \@true} + +\DeclareOption{preprint}{\@setflag \@preprint = \@true} + +\DeclareOption{reprint}{\@setflag \@reprint = \@true} + +\DeclareOption{times}{\@setflag \@times = \@true} + +\DeclareOption{titlepage}{\@unsupportedoption{titlepage}} + +\DeclareOption{twocolumn}{\@setflag \@onecolumn = \@False} + +\DeclareOption{blind}{\@setflag \@blind = \@true} + +\DeclareOption{squareay}{\@setflag \@squareay = \@true} + +\DeclareOption{clearpagebib}{\@setflag \@clearpagebib = \@true} + +\DeclareOption{pldi}{\PassOptionsToClass{10pt}{article} % + \@setflag \@ninepoint = \@false + \@setflag \@tenpoint = \@true + \@setflag \@explicitsize = \@true + \@setflag \@authoryear = \@false + \@setflag \@squareay = \@true + \@setflag \@blind = \@true + \@setflag \@preprint = \@true + \@setflag \@clearpagebib = \@true + } + +\DeclareOption{pldi-cameraready}{\PassOptionsToClass{10pt}{article} % + \@setflag \@ninepoint = \@false + \@setflag \@tenpoint = \@true + \@setflag \@explicitsize = \@true + \@setflag \@authoryear = \@true + \@setflag \@squareay = \@true + \@setflag \@blind = \@false + \@setflag \@preprint = \@false + \@setflag \@clearpagebib = \@true + } + +\DeclareOption{pldinumbers}{\PassOptionsToClass{10pt}{article} % + \@setflag \@ninepoint = \@false + \@setflag \@tenpoint = \@true + \@setflag \@explicitsize = \@true + \@setflag \@authoryear = \@false + \@setflag \@squareay = \@true + \@setflag \@blind = \@true + \@setflag \@preprint = \@true + \@setflag \@clearpagebib = \@true + } + +\DeclareOption{pldiauthoryear}{\PassOptionsToClass{10pt}{article} % + \@setflag \@ninepoint = \@false + \@setflag \@tenpoint = \@true + \@setflag \@explicitsize = \@true + \@setflag \@authoryear = \@true + \@setflag \@squareay = \@true + \@setflag \@blind = \@true + \@setflag \@preprint = \@true + \@setflag \@clearpagebib = \@true + } + +\DeclareOption{pldicrc}{\@setflag \@authoryear = \@true + \@setflag \@squareay = \@true} + +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} + +\ExecuteOptions{9pt,indentedstyle,times} +\@setflag \@explicitsize = \@false +\ProcessOptions + +\if \@onecolumn + \if \@notp{\@explicitsize}% + \@setflag \@ninepoint = \@false + \PassOptionsToClass{11pt}{article}% + \fi + \PassOptionsToClass{twoside,onecolumn}{article} +\else + \PassOptionsToClass{twoside,twocolumn}{article} +\fi +\LoadClass{article} + +\def \@unsupportedoption #1{% + \ClassError{proc}{The standard '#1' option is not supported.}} + +% This can be used with the 'reprint' option to get the final folios. + +\def \setpagenumber #1{% + \setcounter{page}{#1}} + +\AtEndDocument{\label{sigplanconf@finalpage}} + +% Utilities +% --------- + + +\newcommand{\setvspace}[2]{% + #1 = #2 + \advance #1 by -1\parskip} + +% Document Parameters +% -------- ---------- + + +% Page: + +\setlength{\hoffset}{-1in} +\setlength{\voffset}{-1in} + +\setlength{\topmargin}{1in} +\setlength{\headheight}{0pt} +\setlength{\headsep}{0pt} + +\if \@onecolumn + \setlength{\evensidemargin}{.75in} + \setlength{\oddsidemargin}{.75in} +\else + \setlength{\evensidemargin}{.75in} + \setlength{\oddsidemargin}{.75in} +\fi + +% Text area: + +\newdimen{\standardtextwidth} +\setlength{\standardtextwidth}{42pc} + +\if \@onecolumn + \setlength{\textwidth}{40.5pc} +\else + \setlength{\textwidth}{\standardtextwidth} +\fi + +\setlength{\topskip}{8pt} +\setlength{\columnsep}{2pc} +\setlength{\textheight}{54.5pc} + +% Running foot: + +\setlength{\footskip}{30pt} + +% Paragraphs: + +\if \@blockstyle + \setlength{\parskip}{5pt plus .1pt minus .5pt} + \setlength{\parindent}{0pt} +\else + \setlength{\parskip}{0pt} + \setlength{\parindent}{12pt} +\fi + +\setlength{\lineskip}{.5pt} +\setlength{\lineskiplimit}{\lineskip} + +\frenchspacing +\pretolerance = 400 +\tolerance = \pretolerance +\setlength{\emergencystretch}{5pt} +\clubpenalty = 10000 +\widowpenalty = 10000 +\setlength{\hfuzz}{.5pt} + +% Standard vertical spaces: + +\newskip{\standardvspace} +\setvspace{\standardvspace}{5pt plus 1pt minus .5pt} + +% Margin paragraphs: + +\setlength{\marginparwidth}{36pt} +\setlength{\marginparsep}{2pt} +\setlength{\marginparpush}{8pt} + + +\setlength{\skip\footins}{8pt plus 3pt minus 1pt} +\setlength{\footnotesep}{9pt} + +\renewcommand{\footnoterule}{% + \hrule width .5\columnwidth height .33pt depth 0pt} + +\renewcommand{\@makefntext}[1]{% + \noindent \@makefnmark \hspace{1pt}#1} + +% Floats: + +\setcounter{topnumber}{4} +\setcounter{bottomnumber}{1} +\setcounter{totalnumber}{4} + +\renewcommand{\fps@figure}{tp} +\renewcommand{\fps@table}{tp} +\renewcommand{\topfraction}{0.90} +\renewcommand{\bottomfraction}{0.30} +\renewcommand{\textfraction}{0.10} +\renewcommand{\floatpagefraction}{0.75} + +\setcounter{dbltopnumber}{4} + +\renewcommand{\dbltopfraction}{\topfraction} +\renewcommand{\dblfloatpagefraction}{\floatpagefraction} + +\setlength{\floatsep}{18pt plus 4pt minus 2pt} +\setlength{\textfloatsep}{18pt plus 4pt minus 3pt} +\setlength{\intextsep}{10pt plus 4pt minus 3pt} + +\setlength{\dblfloatsep}{18pt plus 4pt minus 2pt} +\setlength{\dbltextfloatsep}{20pt plus 4pt minus 3pt} + +% Miscellaneous: + +\errorcontextlines = 5 + +% Fonts +% ----- + + +\if \@times + \renewcommand{\rmdefault}{ptm}% + \if \@mathtime + \usepackage[mtbold,noTS1]{mathtime}% + \else +%%% \usepackage{mathptm}% + \fi +\else + \relax +\fi + +\if \@ninepoint + +\renewcommand{\normalsize}{% + \@setfontsize{\normalsize}{9pt}{10pt}% + \setlength{\abovedisplayskip}{5pt plus 1pt minus .5pt}% + \setlength{\belowdisplayskip}{\abovedisplayskip}% + \setlength{\abovedisplayshortskip}{3pt plus 1pt minus 2pt}% + \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} + +\renewcommand{\tiny}{\@setfontsize{\tiny}{5pt}{6pt}} + +\renewcommand{\scriptsize}{\@setfontsize{\scriptsize}{7pt}{8pt}} + +\renewcommand{\small}{% + \@setfontsize{\small}{8pt}{9pt}% + \setlength{\abovedisplayskip}{4pt plus 1pt minus 1pt}% + \setlength{\belowdisplayskip}{\abovedisplayskip}% + \setlength{\abovedisplayshortskip}{2pt plus 1pt}% + \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} + +\renewcommand{\footnotesize}{% + \@setfontsize{\footnotesize}{8pt}{9pt}% + \setlength{\abovedisplayskip}{4pt plus 1pt minus .5pt}% + \setlength{\belowdisplayskip}{\abovedisplayskip}% + \setlength{\abovedisplayshortskip}{2pt plus 1pt}% + \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} + +\renewcommand{\large}{\@setfontsize{\large}{11pt}{13pt}} + +\renewcommand{\Large}{\@setfontsize{\Large}{14pt}{18pt}} + +\renewcommand{\LARGE}{\@setfontsize{\LARGE}{18pt}{20pt}} + +\renewcommand{\huge}{\@setfontsize{\huge}{20pt}{25pt}} + +\renewcommand{\Huge}{\@setfontsize{\Huge}{25pt}{30pt}} + +\else\if \@tenpoint + +\relax + +\else + +\relax + +\fi\fi + +% Abstract +% -------- + + +\renewenvironment{abstract}{% + \section*{Abstract}% + \normalsize}{% + } + +% Bibliography +% ------------ + + +\renewenvironment{thebibliography}[1] + {\section*{% + \if \@clearpagebib + \clearpage + \fi + \refname + \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}}% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \@openbib@code + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \bibfont + \clubpenalty4000 + \@clubpenalty \clubpenalty + \widowpenalty4000% + \sfcode`\.\@m} + {\def\@noitemerr + {\@latex@warning{Empty `thebibliography' environment}}% + \endlist} + +\if \@natbib + +\if \@authoryear + \typeout{Using natbib package with 'authoryear' citation style.} + \usepackage[authoryear,square]{natbib} + % Consistent with TOPLAS / ACM (http://www.acm.org/publications/latex_style/); + % citation separator to semicolon; + % eliminate comma between author and year. + \if \@squareay + \bibpunct{[}{]}{;}{a}{}{,} + \else + \bibpunct{(}{)}{;}{a}{}{,} + \fi + \let \cite = \citep +\else + \typeout{Using natbib package with 'numbers' citation style.} + \usepackage[numbers,sort&compress,square]{natbib} +\fi +\if \@clearpagebib + \renewcommand{\bibsection}{\clearpage\section*{\refname}} +\fi +\setlength{\bibsep}{3pt plus .5pt minus .25pt} + +\fi + +\def \bibfont {\small} + +% Categories +% ---------- + + +\@setflag \@firstcategory = \@true + +\newcommand{\category}[3]{% + \if \@firstcategory + \paragraph*{Categories and Subject Descriptors}% + \@setflag \@firstcategory = \@false + \else + \unskip ;\hspace{.75em}% + \fi + \@ifnextchar [{\@category{#1}{#2}{#3}}{\@category{#1}{#2}{#3}[]}} + +\def \@category #1#2#3[#4]{% + {\let \and = \relax + #1 [\textit{#2}]% + \if \@emptyargp{#4}% + \if \@notp{\@emptyargp{#3}}: #3\fi + \else + :\space + \if \@notp{\@emptyargp{#3}}#3---\fi + \textrm{#4}% + \fi}} + +% Copyright Notice +% --------- ------ + + +\def \ftype@copyrightbox {8} +\def \@toappear {} +\def \@permission {} +\def \@reprintprice {} + +%\def \@copyrightspace {% + %\@float{copyrightbox}[b]% + %\vbox to 1.5in{% + %\vfill + %\parbox[b]{20pc}{% + %\scriptsize + %\if \@preprint + %[Copyright notice will appear here + %once 'preprint' option is removed.]\par + %\else + %\if \@blind \else \@toappear \fi + %\fi + %\if \@reprint + %\noindent Reprinted from \@conferencename, + %\@proceedings, + %\@conferenceinfo, + %pp.~\number\thepage--\pageref{sigplanconf@finalpage}.\par + %\fi}}% + %\end@float} + +\def \@copyrightspace {} + +\long\def \toappear #1{% + \def \@toappear {#1}} + +\toappear{} +\def \publicationrights #1{} + +%\toappear{% + %\noindent \@permission \par + %\vspace{2pt} + %\noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + %\noindent Copyright \copyright\ \@copyrightyear\ ACM \@copyrightdata + %\dots \@reprintprice\par + %\noindent \setcopyrightdoi\par} + +%\def \publicationrights #1{% {type} + %\if \@definedp{\rightsstatement#1}% + %\gdef \@permission {\@name{\rightsstatement#1}}% + %\else + %\@latex@error{The publication right '#1' is invalid}{}% + %\fi} + +\expandafter\def \csname rightsstatementauthor-pays\endcsname{% + Permission to make digital or hard copies of part or all of this work for + personal or classroom use is granted without fee provided that copies are + not made or distributed for profit or commercial advantage and that copies + bear this notice and the full citation on the first page. Copyrights for + third-party components of this work must be honored. For all other uses, + contact the Owner/Author.} + +\def \rightsstatementlicensed {% + Permission to make digital or hard copies of part or all of this work for + personal or classroom use is granted without fee provided that copies are + not made or distributed for profit or commercial advantage and that copies + bear this notice and the full citation on the first page. Copyrights for + components of this work owned by others than ACM must be honored. + Abstracting with credit is permitted. To copy otherwise, to republish, to + post on servers, or to redistribute to lists, contact the Owner/Author. + Request permissions from permissions@acm.org or Publications Dept., ACM, + Inc., fax +1~(212) 869-0481. Copyright \@copyrightyear\ held by Owner/Author. + Publication Rights Licensed to ACM.} + +\publicationrights{licensed} + +\def \rightsstatementtransferred {% + Permission to make digital or hard copies of part or all of this work for + personal or classroom use is granted without fee provided that copies are + not made or distributed for profit or commercial advantage and that copies + bear this notice and the full citation on the first page. Copyrights for + components of this work owned by others than ACM must be honored. + Abstracting with credit is permitted. To copy otherwise, to republish, to + post on servers, or to redistribute to lists, requires prior specific + permission and/or a fee. Request permissions from permissions@acm.org or + Publications Dept., ACM, Inc., fax +1~(212) 869-0481.} + +\newcommand{\reprintprice}[1]{% + \gdef \@reprintprice {#1}} + +\reprintprice{\$15.00} + +\def \setcopyrightdoi {% + \if \@emptydefp{\@copyrightdoi}% + \if \@notp{\@preprint}% + \@latex@warning{Copyright DOI has not been provided + (\noexpand\copyrightdoi)}{}% + \gdef \@copyrightdoi {(to come)}% + \fi + \fi + DOI: http://dx.doi.org/10.1145/\@copyrightdoi} + +% Legacy commands. + +\newcommand{\permission}[1]{% + \gdef \@permission {#1}} + +%%%\permission{% +%%% Permission to make digital or hard copies of part or all of this work for +%%% personal or classroom use is granted without fee provided that copies are +%%% not made or distributed for profit or commercial advantage and that copies +%%% bear this notice and the full citation on the first page. Copyrights for +%%% components of this work owned by others than ACM must be honored. +%%% Abstracting with credit is permitted. To copy otherwise, to republish, to +%%% post on servers, or to redistribute to lists, requires prior specific +%%% permission and/or a fee. Request permissions from permissions@acm.org or +%%% Publications Dept., ACM, Inc., fax +1 (212) 869-0481.} + +% Here we have some alternate permission statements and copyright lines: + +\newcommand{\ACMCanadapermission}{% + \legacycopyrighterror{\ACMCanadapermission}% + \permission{% + Copyright \@copyrightyear\ Association for Computing Machinery. + ACM acknowledges that + this contribution was authored or co-authored by an affiliate of the + National Research Council of Canada (NRC). + As such, the Crown in Right of + Canada retains an equal interest in the copyright, however granting + nonexclusive, royalty-free right to publish or reproduce this article, + or to allow others to do so, provided that clear attribution + is also given to the authors and the NRC.}} + +\newcommand{\ACMUSpermission}{% + \legacycopyrighterror{\ACMUSpermission}% + \permission{% + Copyright \@copyrightyear\ Association for + Computing Machinery. ACM acknowledges that + this contribution was authored or co-authored + by a contractor or affiliate + of the U.S. Government. As such, the Government retains a nonexclusive, + royalty-free right to publish or reproduce this article, + or to allow others to do so, for Government purposes only.}} + +\newcommand{\authorpermission}{% + \legacycopyrighterror{\authorpermission}% + \permission{% + Permission to make digital or hard copies of part or all of this work for + personal or classroom use is granted without fee provided that copies are + not made or distributed for profit or commercial advantage and that copies + bear this notice and the full citation on the first page. Copyrights for + third-party components of this work must be honored. For all other uses, + contact the Owner/Authorxxx.}% + \toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + ACM \@copyrightdata.}} + +\newcommand{\Sunpermission}{% + \legacycopyrighterror{\Sunpermission}% + \permission{% + Copyright is held by Sun Microsystems, Inc.}% + \toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + ACM \@copyrightdata.}} + +\newcommand{\USpublicpermission}{% + \legacycopyrighterror{\USpublicpermission}% + \permission{% + This paper is authored by an employee(s) of the United States + Government and is in the public domain.}% + \toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + ACM \@copyrightdata.}} + +\newcommand{\authorversion}[4]{% + \legacycopyrighterror{\authorversion}% + \permission{% + Copyright \copyright\ ACM, #1. This is the author's version of the work. + It is posted here by permission of ACM for your personal use. + Not for redistribution. The definitive version was published in + #2, #3, http://doi.acm.org/10.1145/#4.}} + +\def \exclusivelicense {% + \@latex@error{Deprecated; + you probably want `\noexpand\publicationrights{licensed}'}{}} + +\def \permissiontopublish {% + \@latex@error{Deprecated; + you probably want `\noexpand\publicationrights{author-pays}'}{}} + +\def \legacycopyrighterror #1{% + \if \@notp{\@legacycopyright}% + \@latex@error{Copyright permission '\noexpand#1' is deprecated; use + 'legacycopyright' class option to allow it}{}% + \fi} + +% Enunciations +% ------------ + + +\def \@begintheorem #1#2{% {name}{number} + \trivlist + \item[\hskip \labelsep \textsc{#1 #2.}]% + \itshape\selectfont + \ignorespaces} + +\def \@opargbegintheorem #1#2#3{% {name}{number}{title} + \trivlist + \item[% + \hskip\labelsep \textsc{#1\ #2}% + \if \@notp{\@emptyargp{#3}}\nut (#3).\fi]% + \itshape\selectfont + \ignorespaces} + +% Figures +% ------- + + +\@setflag \@caprule = \@true + +\long\def \@makecaption #1#2{% + \addvspace{4pt} + \if \@caprule + \hrule width \hsize height .33pt + \vspace{4pt} + \fi + \setbox \@tempboxa = \hbox{\@setfigurenumber{#1.}\nut #2}% + \if \@dimgtrp{\wd\@tempboxa}{\hsize}% + \noindent \@setfigurenumber{#1.}\nut #2\par + \else + \centerline{\box\@tempboxa}% + \fi} + +\newcommand{\nocaptionrule}{% + \@setflag \@caprule = \@false} + +\def \@setfigurenumber #1{% + {\rmfamily \bfseries \selectfont #1}} + +% Hierarchy +% --------- + + +\setcounter{secnumdepth}{\@numheaddepth} + +\newskip{\@sectionaboveskip} +\setvspace{\@sectionaboveskip}{10pt plus 3pt minus 2pt} + +\newskip{\@sectionbelowskip} +\if \@blockstyle + \setlength{\@sectionbelowskip}{0.1pt}% +\else + \setlength{\@sectionbelowskip}{4pt}% +\fi + +\renewcommand{\section}{% + \@startsection + {section}% + {1}% + {0pt}% + {-\@sectionaboveskip}% + {\@sectionbelowskip}% + {\large \bfseries \raggedright}} + +\newskip{\@subsectionaboveskip} +\setvspace{\@subsectionaboveskip}{8pt plus 2pt minus 2pt} + +\newskip{\@subsectionbelowskip} +\if \@blockstyle + \setlength{\@subsectionbelowskip}{0.1pt}% +\else + \setlength{\@subsectionbelowskip}{4pt}% +\fi + +\renewcommand{\subsection}{% + \@startsection% + {subsection}% + {2}% + {0pt}% + {-\@subsectionaboveskip}% + {\@subsectionbelowskip}% + {\normalsize \bfseries \raggedright}} + +\renewcommand{\subsubsection}{% + \@startsection% + {subsubsection}% + {3}% + {0pt}% + {-\@subsectionaboveskip} + {\@subsectionbelowskip}% + {\normalsize \bfseries \raggedright}} + +\newskip{\@paragraphaboveskip} +\setvspace{\@paragraphaboveskip}{6pt plus 2pt minus 2pt} + +\renewcommand{\paragraph}{% + \@startsection% + {paragraph}% + {4}% + {0pt}% + {\@paragraphaboveskip} + {-1em}% + {\normalsize \bfseries \if \@times \itshape \fi}} + +\renewcommand{\subparagraph}{% + \@startsection% + {subparagraph}% + {4}% + {0pt}% + {\@paragraphaboveskip} + {-1em}% + {\normalsize \itshape}} + +% Standard headings: + +\newcommand{\acks}{\section*{Acknowledgments}} + +\newcommand{\keywords}{\paragraph*{Keywords}} + +\newcommand{\terms}{\paragraph*{General Terms}} + +% Identification +% -------------- + + +\def \@conferencename {} +\def \@conferenceinfo {} +\def \@copyrightyear {} +\def \@copyrightdata {[to be supplied]} +\def \@copyrightdoi {} +\def \@proceedings {[Unknown Proceedings]} + + +\newcommand{\conferenceinfo}[2]{% + \gdef \@conferencename {#1}% + \gdef \@conferenceinfo {#2}} + +\newcommand{\copyrightyear}[1]{% + \gdef \@copyrightyear {#1}} + +\let \CopyrightYear = \copyrightyear + +\newcommand{\copyrightdata}[1]{% + \gdef \@copyrightdata {#1}} + +\let \crdata = \copyrightdata + +\newcommand{\proceedings}[1]{% + \gdef \@proceedings {#1}} + +\def \copyrightDOI #1{% + \gdef \@copyrightdoi {#1}} + +\let \copyrightdoi = \copyrightDOI + +% Lists +% ----- + + +\setlength{\leftmargini}{13pt} +\setlength\leftmarginii{13pt} +\setlength\leftmarginiii{13pt} +\setlength\leftmarginiv{13pt} +\setlength{\labelsep}{3.5pt} + +\setlength{\topsep}{\standardvspace} +\if \@blockstyle + \setlength{\itemsep}{1pt} + \setlength{\parsep}{3pt} +\else + \setlength{\itemsep}{1pt} + \setlength{\parsep}{3pt} +\fi + +\renewcommand{\labelitemi}{{\small \centeroncapheight{\textbullet}}} +\renewcommand{\labelitemii}{\centeroncapheight{\rule{2.5pt}{2.5pt}}} +\renewcommand{\labelitemiii}{$-$} +\renewcommand{\labelitemiv}{{\Large \textperiodcentered}} + +\renewcommand{\@listi}{% + \leftmargin = \leftmargini + \listparindent = 0pt} +%%% \itemsep = 1pt +%%% \parsep = 3pt} +%%% \listparindent = \parindent} + +\let \@listI = \@listi + +\renewcommand{\@listii}{% + \leftmargin = \leftmarginii + \topsep = 1pt + \labelwidth = \leftmarginii + \advance \labelwidth by -\labelsep + \listparindent = \parindent} + +\renewcommand{\@listiii}{% + \leftmargin = \leftmarginiii + \labelwidth = \leftmarginiii + \advance \labelwidth by -\labelsep + \listparindent = \parindent} + +\renewcommand{\@listiv}{% + \leftmargin = \leftmarginiv + \labelwidth = \leftmarginiv + \advance \labelwidth by -\labelsep + \listparindent = \parindent} + +% Mathematics +% ----------- + + +\def \theequation {\arabic{equation}} + +% Miscellaneous +% ------------- + + +\newcommand{\balancecolumns}{% + \vfill\eject + \global\@colht = \textheight + \global\ht\@cclv = \textheight} + +\newcommand{\nut}{\hspace{.5em}} + +\newcommand{\softraggedright}{% + \let \\ = \@centercr + \leftskip = 0pt + \rightskip = 0pt plus 10pt} + +% Program Code +% ------- ---- + + +\newcommand{\mono}[1]{% + {\@tempdima = \fontdimen2\font + \texttt{\spaceskip = 1.1\@tempdima #1}}} + +% Running Heads and Feet +% ------- ----- --- ---- + + +\def \@preprintfooter {} + +\newcommand{\preprintfooter}[1]{% + \gdef \@preprintfooter {#1}} + +\if \@preprint + +\def \ps@plain {% + \let \@mkboth = \@gobbletwo + \let \@evenhead = \@empty + \def \@evenfoot {\scriptsize + \rlap{\if \@blind \else \textit{\@preprintfooter}\fi}\hfil + \thepage \hfil + \llap{\if \@blind \else \textit{\@formatyear}\fi}}% + \let \@oddhead = \@empty + \let \@oddfoot = \@evenfoot} + +\else\if \@reprint + +\def \ps@plain {% + \let \@mkboth = \@gobbletwo + \let \@evenhead = \@empty + \def \@evenfoot {\scriptsize \hfil \thepage \hfil}% + \let \@oddhead = \@empty + \let \@oddfoot = \@evenfoot} + +\else + +\let \ps@plain = \ps@empty +\let \ps@headings = \ps@empty +\let \ps@myheadings = \ps@empty + +\fi\fi + +\def \@formatyear {% + \number\year/\number\month/\number\day} + +% Special Characters +% ------- ---------- + + +\DeclareRobustCommand{\euro}{% + \protect{\rlap{=}}{\sf \kern .1em C}} + +% Title Page +% ----- ---- + + +\@setflag \@addauthorsdone = \@false + +\def \@titletext {\@latex@error{No title was provided}{}} +\def \@subtitletext {} + +\newcount{\@authorcount} + +\newcount{\@titlenotecount} +\newtoks{\@titlenotetext} + +\def \@titlebanner {} + +\renewcommand{\title}[1]{% + \gdef \@titletext {#1}} + +\newcommand{\subtitle}[1]{% + \gdef \@subtitletext {#1}} + +\newcommand{\authorinfo}[3]{% {names}{affiliation}{email/URL} + \global\@increment \@authorcount + \@withname\gdef {\@authorname\romannumeral\@authorcount}{#1}% + \@withname\gdef {\@authoraffil\romannumeral\@authorcount}{#2}% + \@withname\gdef {\@authoremail\romannumeral\@authorcount}{#3}} + +\renewcommand{\author}[1]{% + \@latex@error{The \string\author\space command is obsolete; + use \string\authorinfo}{}} + +\newcommand{\titlebanner}[1]{% + \gdef \@titlebanner {#1}} + +\renewcommand{\maketitle}{% + \pagestyle{plain}% + \if \@onecolumn + {\hsize = \standardtextwidth + \@maketitle}% + \else + \twocolumn[\@maketitle]% + \fi + \@placetitlenotes + \if \@copyrightwanted \@copyrightspace \fi} + +\def \@maketitle {% + \begin{center} + \@settitlebanner + \let \thanks = \titlenote + {\leftskip = 0pt plus 0.25\linewidth + \rightskip = 0pt plus 0.25 \linewidth + \parfillskip = 0pt + \spaceskip = .7em + \noindent \LARGE \bfseries \@titletext \par} + \vskip 6pt + \noindent \Large \@subtitletext \par + \vskip 12pt + \if \@blind + \vskip 64pt% vspace to compensate for missing author info + \else + \ifcase \@authorcount + \@latex@error{No authors were specified for this paper}{}\or + \@titleauthors{i}{}{}\or + \@titleauthors{i}{ii}{}\or + \@titleauthors{i}{ii}{iii}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{xi}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{xi}{xii}% + \else + \@latex@error{Cannot handle more than 12 authors}{}% + \fi + \fi + \vspace{1.75pc} + \end{center}} + +\def \@settitlebanner {% + \if \@andp{\@preprint}{\@notp{\@emptydefp{\@titlebanner}}}% + \vbox to 0pt{% + \vskip -32pt + \noindent \textbf{\@titlebanner}\par + \vss}% + \nointerlineskip + \fi} + +\def \@titleauthors #1#2#3{% + \if \@andp{\@emptyargp{#2}}{\@emptyargp{#3}}% + \noindent \@setauthor{40pc}{#1}{\@false}\par + \else\if \@emptyargp{#3}% + \noindent \@setauthor{17pc}{#1}{\@false}\hspace{3pc}% + \@setauthor{17pc}{#2}{\@false}\par + \else + \noindent \@setauthor{12.5pc}{#1}{\@false}\hspace{2pc}% + \@setauthor{12.5pc}{#2}{\@false}\hspace{2pc}% + \@setauthor{12.5pc}{#3}{\@true}\par + \relax + \fi\fi + \vspace{20pt}} + +\def \@setauthor #1#2#3{% {width}{text}{unused} + \vtop{% + \def \and {% + \hspace{16pt}} + \hsize = #1 + \normalfont + \centering + \large \@name{\@authorname#2}\par + \vspace{5pt} + \normalsize \@name{\@authoraffil#2}\par + \vspace{2pt} + \textsf{\@name{\@authoremail#2}}\par}} + +\def \@maybetitlenote #1{% + \if \@andp{#1}{\@gtrp{\@authorcount}{3}}% + \titlenote{See page~\pageref{@addauthors} for additional authors.}% + \fi} + +\newtoks{\@fnmark} + +\newcommand{\titlenote}[1]{% + \global\@increment \@titlenotecount + \ifcase \@titlenotecount \relax \or + \@fnmark = {\ast}\or + \@fnmark = {\dagger}\or + \@fnmark = {\ddagger}\or + \@fnmark = {\S}\or + \@fnmark = {\P}\or + \@fnmark = {\ast\ast}% + \fi + \,$^{\the\@fnmark}$% + \edef \reserved@a {\noexpand\@appendtotext{% + \noexpand\@titlefootnote{\the\@fnmark}}}% + \reserved@a{#1}} + +\def \@appendtotext #1#2{% + \global\@titlenotetext = \expandafter{\the\@titlenotetext #1{#2}}} + +\newcount{\@authori} + +\iffalse +\def \additionalauthors {% + \if \@gtrp{\@authorcount}{3}% + \section{Additional Authors}% + \label{@addauthors}% + \noindent + \@authori = 4 + {\let \\ = ,% + \loop + \textbf{\@name{\@authorname\romannumeral\@authori}}, + \@name{\@authoraffil\romannumeral\@authori}, + email: \@name{\@authoremail\romannumeral\@authori}.% + \@increment \@authori + \if \@notp{\@gtrp{\@authori}{\@authorcount}} \repeat}% + \par + \fi + \global\@setflag \@addauthorsdone = \@true} +\fi + +\let \addauthorsection = \additionalauthors + +\def \@placetitlenotes { + \the\@titlenotetext} + +% Utilities +% --------- + + +\newcommand{\centeroncapheight}[1]{% + {\setbox\@tempboxa = \hbox{#1}% + \@measurecapheight{\@tempdima}% % Calculate ht(CAP) - ht(text) + \advance \@tempdima by -\ht\@tempboxa % ------------------ + \divide \@tempdima by 2 % 2 + \raise \@tempdima \box\@tempboxa}} + +\newbox{\@measbox} + +\def \@measurecapheight #1{% {\dimen} + \setbox\@measbox = \hbox{ABCDEFGHIJKLMNOPQRSTUVWXYZ}% + #1 = \ht\@measbox} + +\long\def \@titlefootnote #1#2{% + \insert\footins{% + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore +%%% \protected@edef\@currentlabel{% +%%% \csname p@footnote\endcsname\@thefnmark}% + \color@begingroup + \def \@makefnmark {$^{#1}$}% + \@makefntext{% + \rule\z@\footnotesep\ignorespaces#2\@finalstrut\strutbox}% + \color@endgroup}} + +% LaTeX Modifications +% ----- ------------- + +\def \@seccntformat #1{% + \@name{\the#1}% + \@expandaftertwice\@seccntformata \csname the#1\endcsname.\@mark + \quad} + +\def \@seccntformata #1.#2\@mark{% + \if \@emptyargp{#2}.\fi} + +% Revision History +% -------- ------- + + +% Date Person Ver. Change +% ---- ------ ---- ------ + +% 2004.09.12 PCA 0.1--4 Preliminary development. + +% 2004.11.18 PCA 0.5 Start beta testing. + +% 2004.11.19 PCA 0.6 Obsolete \author and replace with +% \authorinfo. +% Add 'nocopyrightspace' option. +% Compress article opener spacing. +% Add 'mathtime' option. +% Increase text height by 6 points. + +% 2004.11.28 PCA 0.7 Add 'cm/computermodern' options. +% Change default to Times text. + +% 2004.12.14 PCA 0.8 Remove use of mathptm.sty; it cannot +% coexist with latexsym or amssymb. + +% 2005.01.20 PCA 0.9 Rename class file to sigplanconf.cls. + +% 2005.03.05 PCA 0.91 Change default copyright data. + +% 2005.03.06 PCA 0.92 Add at-signs to some macro names. + +% 2005.03.07 PCA 0.93 The 'onecolumn' option defaults to '11pt', +% and it uses the full type width. + +% 2005.03.15 PCA 0.94 Add at-signs to more macro names. +% Allow margin paragraphs during review. + +% 2005.03.22 PCA 0.95 Implement \euro. +% Remove proof and newdef environments. + +% 2005.05.06 PCA 1.0 Eliminate 'onecolumn' option. +% Change footer to small italic and eliminate +% left portion if no \preprintfooter. +% Eliminate copyright notice if preprint. +% Clean up and shrink copyright box. + +% 2005.05.30 PCA 1.1 Add alternate permission statements. + +% 2005.06.29 PCA 1.1 Publish final first edition of guide. + +% 2005.07.14 PCA 1.2 Add \subparagraph. +% Use block paragraphs in lists, and adjust +% spacing between items and paragraphs. + +% 2006.06.22 PCA 1.3 Add 'reprint' option and associated +% commands. + +% 2006.08.24 PCA 1.4 Fix bug in \maketitle case command. + +% 2007.03.13 PCA 1.5 The title banner only displays with the +% 'preprint' option. + +% 2007.06.06 PCA 1.6 Use \bibfont in \thebibliography. +% Add 'natbib' option to load and configure +% the natbib package. + +% 2007.11.20 PCA 1.7 Balance line lengths in centered article +% title (thanks to Norman Ramsey). + +% 2009.01.26 PCA 1.8 Change natbib \bibpunct values. + +% 2009.03.24 PCA 1.9 Change natbib to use the 'numbers' option. +% Change templates to use 'natbib' option. + +% 2009.09.01 PCA 2.0 Add \reprintprice command (suggested by +% Stephen Chong). + +% 2009.09.08 PCA 2.1 Make 'natbib' the default; add 'nonatbib'. +% SB Add 'authoryear' and 'numbers' (default) to +% control citation style when using natbib. +% Add \bibpunct to change punctuation for +% 'authoryear' style. + +% 2009.09.21 PCA 2.2 Add \softraggedright to the thebibliography +% environment. Also add to template so it will +% happen with natbib. + +% 2009.09.30 PCA 2.3 Remove \softraggedright from thebibliography. +% Just include in the template. + +% 2010.05.24 PCA 2.4 Obfuscate class author's email address. + +% 2011.11.08 PCA 2.5 Add copyright notice to this file. +% Remove 'sort' option from natbib when using +% 'authoryear' style. +% Add the \authorversion command. + +% 2013.02.22 PCA 2.6 Change natbib fences to parentheses when +% using 'authoryear' style. + +% 2013.05.17 PCA 2.7 Change standard and author copyright text. + +% 2.8 (retracted) + +% 2014.07.30 PCA 2.9 Created just to replace version 2.8. + +% 2014.08.14 PCA 3.0 Implement new copyright command as specified +% at github.com/SIGPLAN/online/wiki/ +% ACM-SIGPLAN-%28c%29-Messages +% Deprecate the old commands, but allow their +% use with the 'legacycopyright' Option. + +% 2014.09.14 SB 3.0x Add pldi and pldicrc options +% Add support for TOPLAS-style authorname +% references with square brackets. Add blind option +% that does not Print author names. Add clearpagebib +% option that creates a clearpage for the references +% section.