Browse files

Add style file and modify paper to use it

  • Loading branch information...
1 parent 9354377 commit 8e4c81059b7c284b0d5f14a5def9d1bab46b566c @kostis kostis committed Mar 22, 2012
Showing with 2,574 additions and 0 deletions.
  1. +577 −0 WebServicePropEr.tex
  2. +309 −0 breakurl.sty
  3. +1,425 −0 eptcs.bst
  4. +263 −0 eptcs.cls
View
577 WebServicePropEr.tex
@@ -0,0 +1,577 @@
+\documentclass[submission,copyright]{eptcs}
+\providecommand{\event}{WWV 2012}
+\usepackage{breakurl}
+
+\usepackage[utf8]{inputenc} % set input encoding (not needed with XeLaTeX)
+
+%%% Examples of Article customizations
+% These packages are optional, depending whether you want the features they provide.
+% See the LaTeX Companion or other references for full information.
+
+%%% PAGE DIMENSIONS
+\usepackage{geometry} % to change the page dimensions
+\geometry{a4paper} % or letterpaper (US) or a5paper or....
+% \geometry{margin=2in} % for example, change the margins to 2 inches all round
+% \geometry{landscape} % set up the page for landscape
+% read geometry.pdf for detailed page layout information
+
+\usepackage{graphicx} % support the \includegraphics command and options
+
+% \usepackage[parfill]{parskip} % Activate to begin paragraphs with an empty line rather than an indent
+
+%%% PACKAGES
+\usepackage{booktabs} % for much better looking tables
+\usepackage{array} % for better arrays (eg matrices) in maths
+\usepackage{paralist} % very flexible & customisable lists (eg. enumerate/itemize, etc.)
+\usepackage{verbatim} % adds environment for commenting out blocks of text & for better verbatim
+\usepackage{subfig} % make it possible to include more than one captioned figure/table in a single float
+\usepackage{listings}
+% These packages are all incorporated in the memoir class to one degree or another...
+
+%%% HEADERS & FOOTERS
+\usepackage{fancyhdr} % This should be set AFTER setting up the page geometry
+\pagestyle{fancy} % options: empty , plain , fancy
+\renewcommand{\headrulewidth}{0pt} % customise the layout...
+\lhead{}\chead{}\rhead{}
+\lfoot{}\cfoot{\thepage}\rfoot{}
+
+%%% ToC (table of contents) APPEARANCE
+\usepackage[nottoc,notlof,notlot]{tocbibind} % Put the bibliography in the ToC
+\usepackage[titles,subfigure]{tocloft} % Alter the style of the Table of Contents
+\renewcommand{\cftsecfont}{\rmfamily\mdseries\upshape}
+\renewcommand{\cftsecpagefont}{\rmfamily\mdseries\upshape} % No bold!
+
+%%% END Article customizations
+
+%%% The "real" document content comes below...
+
+\title{Automatic WSDL-based Testing of Web Services using PropEr} % keep PropEr?
+\author{Leonidas Lampropoulos \and Konstantinos Sagonas}
+\def\titlerunning{Automatic WSDL-based Testing of Web Services using PropEr}
+\def\authorrunning{L. Lampropoulos and K. Sagonas}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+ This will be the greatest paper ever written...
+\end{abstract}
+
+\section{Introduction}
+
+We describe an extension of PropEr to accomodate property based testing of web services. This extension receives the URL of a Web Service (or more accurately the url of the Web Service's WSDL specification), parses the specification and creates an output file containing generators, calling functions and sample properties for all the input messages and types required by the Web Service to be invoked. The output file can be automatically compiled and used for response testing of web services with random, yet structurally valid testcases. In addition, the automatically created PropEr generators and properties can be easily modified, allowing the user to write properties the web service should have (? Edw dn m aresei to have), utilizing the full power of Erlang and PropEr.
+
+\section{Preliminaries}
+
+To use the extension required are an Erlang distribution (with xmerl), Proper and Yaws.
+To run some of the examples below, Eclipse and Tomcat have been used, but any means of creating a Web Service should be an option.
+
+\subsection{PropEr}
+
+Include here:
+
+-What property based testing is
+
+-What PropEr is
+
+-Small Example?
+
+\subsection{WSDL}
+
+WSDL is the leading specification for web services in XML format, describing the web service in full: Operations, Input and output message types, locations, etc. Every WSDL specification contains (or references) an XSD schema inside, describing the types of the messages needed to invoke the web service.
+
+\subsection{Yaws}
+
+Yaws is the most widely used Erlang HTTP webserver. We basically use only its soap library to handle the interaction between our erlang code and the web services, wrapping our types and generated data in valid soap structure, communicating with the web service, and returning the result. Yaws uses an XML parser called Erlsom to handle its soap message encoding/decoding, a parser module faster and more user friendly than the xmerl module of the Erlang distribution, imposing however a few additional limitations.
+
+\section{Overview}
+
+The main idea behind the extension is to use PropEr to do property based testing on web services. This extension helps the user by creating generators, sample properties and call functions so that the user focuses on the important task - writing the property.
+
+\subsection{Generators}
+
+The most important part of the extension is automatically creating PropEr generators for each input message type of the operations supported. To that end, we parse the XSD schema of the WSDL specification using the xmerl module and create the most generic generators for the types described, in the format Yaws and Erlsom expect their arguments. While parsing the XSD schema, we use a small tuple format as an intermediate representation of the types of the Web Service, so that the resulting generators can be directly mapped from these tuples while being able to give the generators unique and descriptive names. These tuples are never encountered by the user, yet are extremely helpful in holding all the necessary information (and only that) to create the PropEr generators and overcome some important limitations that would otherwise be imposed by Erlsom. (? Thelei kati allo edw prin apo to paradeigma ?)
+
+For our example we will use an existing free web service for converting cooking units from one form to another. This web service is hosted in webservicex.net and its WSDL specification can be found at "http://www.webservicex.net/ConvertCooking.asmx?WSDL". Here we show the schema part of the specification which describes the type of the soap message to be sent:
+
+\begin{lstlisting}
+<s:schema elementFormDefault="qualified"
+ targetNamespace="http://www.webserviceX.NET/">
+ <s:element name="ChangeCookingUnit">
+ <s:complexType>
+ <s:sequence>
+ <s:element minOccurs="1" maxOccurs="1"
+ name="CookingValue" type="s:double"/>
+ <s:element minOccurs="1" maxOccurs="1"
+ name="fromCookingUnit" type="tns:Cookings"/>
+ <s:element minOccurs="1" maxOccurs="1"
+ name="toCookingUnit" type="tns:Cookings"/>
+ </s:sequence>
+ </s:complexType>
+ </s:element>
+ <s:simpleType name="Cookings">
+ <s:restriction base="s:string">
+ <s:enumeration value="drop"/>
+ <s:enumeration value="dash"/>
+ <s:enumeration value="pinch"/>
+ <s:enumeration value="milliliterPerCC"/>
+ <s:enumeration value="deciliter"/>
+ <s:enumeration value="coffeeSpoon"/>
+ <s:enumeration value="fluidDram"/>
+ <s:enumeration value="teaspoonUS"/>
+ <s:enumeration value="teaspoonUK"/>
+ <s:enumeration value="tablespoonUS"/>
+ <s:enumeration value="tablespoonUK"/>
+ <s:enumeration value="fluidOunceUS"/>
+ <s:enumeration value="fluidOunceUK"/>
+ <s:enumeration value="cupUS"/>
+ <s:enumeration value="cubicInch"/>
+ <s:enumeration value="gillUS"/>
+ <s:enumeration value="gillUK"/>
+ <s:enumeration value="pintUS"/>
+ <s:enumeration value="pintUK"/>
+ <s:enumeration value="quartUS"/>
+ <s:enumeration value="liter"/>
+ <s:enumeration value="gallonUS"/>
+ <s:enumeration value="gallonUK"/>
+ <s:enumeration value="TwoPointFiveCan"/>
+ <s:enumeration value="TenCan"/>
+ </s:restriction>
+ </s:simpleType>
+ <s:element name="double" type="s:double"/>
+</s:schema>
+
+\end{lstlisting}
+
+In short, the above XSD schema describes one element ("ChangeCookingUnit") whose type is a complex one, a sequence (mapped as a list in the Yaws soap library) consisting of exactly 3 elements (the attributes min- and maxOccurs define that). These three ordered elements are: "CookingValue" with type double, and two more elements "fromCookingUnit" and "toCookingUnit" with type "tns:Cookings", which is described below the element to be a restriction of the generic string type, with only the values described in the enumeration tags as acceptable.
+
+The resulting generators created by the PropEr extension are:
+
+\begin{lstlisting}
+generate_ChangeCookingUnit_1_CookingValue() ->
+ ?LET(Gen, float(), float_to_list(Gen)).
+
+generate_ChangeCookingUnit_1_fromCookingUnit_Cookings() ->
+ elements(["drop","dash","pinch","milliliterPerCC","deciliter",
+ "coffeeSpoon", "fluidDram","teaspoonUS","teaspoonUK","tablespoonUS",
+ "tablespoonUK", "fluidOunceUS","fluidOunceUK","cupUS","cubicInch",
+ "gillUS","gillUK","pintUS","pintUK","quartUS","liter","gallonUS",
+ "gallonUK","TwoPointFiveCan","TenCan"]).
+
+generate_ChangeCookingUnit_1_toCookingUnit_Cookings() ->
+ elements(["drop","dash","pinch","milliliterPerCC","deciliter",
+ "coffeeSpoon", "fluidDram","teaspoonUS","teaspoonUK","tablespoonUS",
+ "tablespoonUK", "fluidOunceUS","fluidOunceUK","cupUS","cubicInch",
+ "gillUS","gillUK","pintUS","pintUK","quartUS","liter","gallonUS",
+ "gallonUK","TwoPointFiveCan","TenCan"]).
+
+generate_ChangeCookingUnit_1() ->
+ ?LET(
+ {Pr_ChangeCookingUnit_1_CookingValue,
+ Pr_ChangeCookingUnit_1_fromCookingUnit_Cookings,
+ Pr_ChangeCookingUnit_1_toCookingUnit_Cookings},
+ {generate_ChangeCookingUnit_1_CookingValue(),
+ generate_ChangeCookingUnit_1_fromCookingUnit_Cookings(),
+ generate_ChangeCookingUnit_1_toCookingUnit_Cookings()},
+ [Pr_ChangeCookingUnit_1_CookingValue,
+ Pr_ChangeCookingUnit_1_fromCookingUnit_Cookings,
+ Pr_ChangeCookingUnit_1_toCookingUnit_Cookings]
+ ).
+\end{lstlisting}
+
+The extension has created a single generator for the main element named "generate\_ChangeCookingUnit\_1()" which recursively calls 3 more generators for the 3 elements described above, and using the instances created to form a 3-element list.
+
+One thing worth noticing is that instead of simply using a float() generator for the double field of the Web Service, we use a wrapper that converts it to a string. This is done because of erlsom limitations. Specifically, erlsom treats some types defined in the XSD schemas natively while turns everything else to a string. This leads to irregularities such as using a long instead of an int in the schema to require a string instead of an integer (without considering the range). This sort of irregularity is taken into account by the extension which creates the string wrappers wherever necessary.
+
+\subsection{Response Property}
+
+The Proper extension also creates a function for each web service operation that invokes this operation with parameterized arguments and a small property to test that the Service always responds for random testcases without returning malformed XML or a Soap Fault for random (possibly corner) cases. For the Cooking service we described above there is a single soap operation supported, which is defined in the following WSDL specification exerpt:
+
+\begin{lstlisting}
+<wsdl:portType name="CookingUnitSoap">
+ <wsdl:operation name="ChangeCookingUnit">
+ <wsdl:input message="tns:ChangeCookingUnitSoapIn"/>
+ <wsdl:output message="tns:ChangeCookingUnitSoapOut"/>
+ </wsdl:operation>
+</wsdl:portType>
+\end{lstlisting}
+
+The code created to invoke this operation and the respective property is the following:
+
+\begin{lstlisting}
+call_ChangeCookingUnit(Arguments) ->
+ inets:start(),
+ Wsdl = yaws_soap_lib:initModel(?WSDL_URL),
+ yaws_soap_lib:call(Wsdl, "ChangeCookingUnit", Arguments).
+
+call_ChangeCookingUnit(WSDL, Arguments) ->
+ yaws_soap_lib:call(WSDL, "ChangeCookingUnit", Arguments).
+
+prop_ChangeCookingUnit_responds() ->
+ ?FORALL(Args, generate_ChangeCookingUnit_1(),
+ begin
+ Result = call_ChangeCookingUnit(Args),
+ case Result of
+ {ok, _Attribs, [#'soap:Fault'{}]}) -> false;
+ {ok, _Attribs, _Result_record} -> true;
+ _ -> false
+ end
+ end).
+\end{lstlisting}
+
+The first function simply calls the operation assuming nothing about the state of the connection (it tries to start a connection, (possibly re-)parses the WSDL specification and then invokes the operation, while the second function takes an already parsed WSDL specification structure and invokes the operation directly, which is far more efficient. Finally, the "responds" property simply creates the arguments using the previously created generator ("generate\_ChangeCookingUnit\_1()") and does a pattern matching on the resulting tuple after calling the web service. If this resulting tuple is a 'soap:Fault' record (or the resulting tuple is an\{error, Reason\} tuple) then the service failed to respond correctly (possibly raised an exception described in the record), otherwise we assume (conservatively) that the web service responded correctly.
+
+\subsection{Entire generated code}
+
+For the resulting file to be directly compilable, we include headers, defines, imports, etc. The resulting output file for the cooking service is:
+
+\begin{lstlisting}
+-module(proper_output).
+
+-include_lib("proper/include/proper.hrl").
+-include("proper_output.hrl").
+
+-define(PREFIX, "properns").
+-define(WSDL_URL, "http://www.webservicex.net/ConvertCooking.asmx?WSDL").
+
+-export([call_ChangeCookingUnit/1, call_ChangeCookingUnit/2]).
+-export([answer_ChangeCookingUnit/1]).
+
+generate_ChangeCookingUnit_1_CookingValue() ->
+ ?LET(Gen, float(), float_to_list(Gen)).
+
+generate_ChangeCookingUnit_1_fromCookingUnit_Cookings() ->
+ elements(["drop","dash","pinch","milliliterPerCC","deciliter",
+ "coffeeSpoon", "fluidDram","teaspoonUS","teaspoonUK","tablespoonUS",
+ "tablespoonUK", "fluidOunceUS","fluidOunceUK","cupUS","cubicInch",
+ "gillUS","gillUK","pintUS","pintUK","quartUS","liter","gallonUS",
+ "gallonUK","TwoPointFiveCan","TenCan"]).
+
+generate_ChangeCookingUnit_1_toCookingUnit_Cookings() ->
+ elements(["drop","dash","pinch","milliliterPerCC","deciliter",
+ "coffeeSpoon", "fluidDram","teaspoonUS","teaspoonUK","tablespoonUS",
+ "tablespoonUK", "fluidOunceUS","fluidOunceUK","cupUS","cubicInch",
+ "gillUS","gillUK","pintUS","pintUK","quartUS","liter","gallonUS",
+ "gallonUK","TwoPointFiveCan","TenCan"]).
+
+generate_ChangeCookingUnit_1() ->
+ ?LET(
+ {Pr_ChangeCookingUnit_1_CookingValue,
+ Pr_ChangeCookingUnit_1_fromCookingUnit_Cookings,
+ Pr_ChangeCookingUnit_1_toCookingUnit_Cookings},
+ {generate_ChangeCookingUnit_1_CookingValue(),
+ generate_ChangeCookingUnit_1_fromCookingUnit_Cookings(),
+ generate_ChangeCookingUnit_1_toCookingUnit_Cookings()},
+ [Pr_ChangeCookingUnit_1_CookingValue,
+ Pr_ChangeCookingUnit_1_fromCookingUnit_Cookings,
+ Pr_ChangeCookingUnit_1_toCookingUnit_Cookings]
+ ).
+
+call_ChangeCookingUnit(Arguments) ->
+ inets:start(),
+ Wsdl = yaws_soap_lib:initModel(?WSDL_URL),
+ yaws_soap_lib:call(Wsdl, "ChangeCookingUnit", Arguments).
+
+call_ChangeCookingUnit(WSDL, Arguments) ->
+ yaws_soap_lib:call(WSDL, "ChangeCookingUnit", Arguments).
+
+prop_ChangeCookingUnit_responds() ->
+ ?FORALL(Args, generate_ChangeCookingUnit_1(),
+ begin
+ Result = call_ChangeCookingUnit(Args),
+ case Result of
+ {ok, _Attribs, [Result_record]}
+ when is_record(Result_record, 'soap:Fault') -> false;
+ {ok, _Attribs, _Result_record} -> true;
+ _ -> false
+ end
+ end).
+
+answer_ChangeCookingUnit({ok, _, [Answer_record]}) -> Answer_record.
+
+% ---------- End of Auto Generated Code ----------
+\end{lstlisting}
+
+In addition to the headers, the only other thing created by the extension is a function called "answer\_ChangeCookingUnit" which shows how to extract the Answer (record) that is returned by yaws.
+
+Finally, the extension also uses erlsom to output a .hrl file that describes the records used for the responses of the Service. In our case:
+
+\begin{lstlisting}
+-record('properns:ChangeCookingUnit',
+ {anyAttribs, 'CookingValue', 'fromCookingUnit', 'toCookingUnit'}).
+-record('properns:ChangeCookingUnitResponse',
+ {anyAttribs, 'ChangeCookingUnitResult'}).
+-record('properns:double', {anyAttribs, 'double'}).
+-record('soap:Body', {anyAttribs, choice}).
+-record('soap:Envelope', {anyAttribs, 'Header', 'Body', choice}).
+-record('soap:Fault', {anyAttribs, 'faultcode', 'faultstring', 'faultactor', 'detail'}).
+-record('soap:Header', {anyAttribs, choice}).
+-record('soap:detail', {anyAttribs, choice}).
+\end{lstlisting}
+
+We will see how these can be used in later sections.
+
+\section{Response Testing}
+
+(? Den ekana akoma to change gia na kanei compile apeftheias ston kwdika gia response testing ?)
+
+The first kind of testing, that works without any user additions is response testing. Basically, the output file created by the extension contains a property that invokes an operation of the web service with random inputs and expects an answer for each different input. This can basically check if a web service crashes for a specific input or similar unwanted behaviors.
+
+Let's see how to use the extension on the cooking service:
+
+\begin{lstlisting}
+Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4]
+[async-threads:0] [hipe] [kernel-poll:false]
+
+Eshell V5.9 (abort with ^G)
+1> wsdl_handler:generate("http://www.webservicex.net/
+ConvertCooking.asmx?WSDL").
+ok
+2> c(proper_output).
+{ok,proper_output}
+3> proper:quickcheck(
+ proper_output:prop_ChangeCookingUnit_responds()).
+....(100 dots) .....
+OK: Passed 100 test(s).
+true
+\end{lstlisting}
+
+As we can see, the Cooking web service was invoked 100 times with random arguments and returned a correctly formed result each time.
+
+Now for an example of a service that crashes, we created our own web service using eclipse and tomcat. This example will also be used later on and is based on the first PropEr publication by Manos Papadakis, about a faulty delete function.
+
+We have a simple Java implementation of the web service:
+
+\begin{lstlisting}
+public Class Delete {
+ private String delete(String in, char c, StringBuffer acc){
+ if (in.equals("")) {
+ return acc.toString();
+ }
+ else if (in.charAt(0) == c) {
+ return acc.toString().concat(in.substring(1));
+ }
+ else {
+ return delete(in.substring(1), c, acc.append(in.charAt(0)));
+ }
+ }
+
+ public String delete(String in, String c){
+ return delete(in, c.charAt(0), new StringBuffer(""));
+ }
+}
+\end{lstlisting}
+
+We used this code to implement and publish a simple web service in tomcat. After using the PropEr extension to handle the WSDL specification of this web service, the output file was the following:
+
+(?Den dokimasa akoma to ascii\_list gia na to valw ki edw, opou vector(Len, integer(32,127)) theoroume string ?)
+
+\begin{lstlisting}
+-module(proper_output).
+
+-include_lib("proper/include/proper.hrl").
+-include("proper_output.hrl").
+
+-define(PREFIX, "properns").
+-define(WSDL_URL, "http://localhost:8080/
+ DeleteProject/services/Delete?WSDL").
+
+-export([call_delete/1, call_delete/2]).
+-export([answer_delete/1]).
+
+generate_delete_1_in() ->
+ ?LET(
+ Len,
+ range(0,inf),
+ vector(Len, integer(32,127))
+ ).
+
+generate_delete_1_c() ->
+ ?LET(
+ Len,
+ range(0,inf),
+ vector(Len, integer(32,127))
+ ).
+
+generate_delete_1() ->
+ ?LET(
+ {Pr_delete_1_in, Pr_delete_1_c},
+ {generate_delete_1_in(), generate_delete_1_c()},
+ [Pr_delete_1_in, Pr_delete_1_c]
+ ).
+
+call_delete(Arguments) ->
+ inets:start(),
+ Wsdl = yaws_soap_lib:initModel(?WSDL_URL),
+ yaws_soap_lib:call(Wsdl, "delete", Arguments).
+
+call_delete(WSDL, Arguments) ->
+ yaws_soap_lib:call(WSDL, "delete", Arguments).
+
+prop_delete_responds() ->
+ ?FORALL(Args, generate_delete_1(),
+ begin
+ Result = call_delete(Args),
+ case Result of
+ {ok, _Attribs, [Result_record]}
+ when is_record(Result_record, 'soap:Fault') -> false;
+ {ok, _Attribs, _Result_record} -> true;
+ _ -> false
+ end
+ end).
+
+answer_delete({ok, _, [Answer_record]}) -> Answer_record.
+
+% ---------- End of Auto Generated Code ----------
+\end{lstlisting}
+
+Calling quickcheck with this property reveals a flaw in our implementation.
+\begin{lstlisting}
+> proper:quickcheck(proper_output:prop_delete_responds()).
+.!
+Failed: After 2 test(s).
+[[46],[]]
+
+Shrinking .(1 time(s))
+[[],[]]
+false
+\end{lstlisting}
+
+In our implementation we assume that the string c which is supposed to contain at its first character the character that should be removed from the string, is not empty. We have two choices to fix it, either fix our implementation, or remove this testcase from the generator. To show how easy it is to change the generators created by the extension we choose the latter: we change the generator of c to:
+
+\begin{lstlisting}
+generate_delete_1_c() ->
+ ?LET(
+ Len,
+ range(1,1),
+ vector(Len, integer(32,127))
+ ).
+\end{lstlisting}
+We could change it to range(1,inf) or actually remove the ?LET macro, but we'd have to be carefull not to actually change the output of the generator to a char instead of a non-empty char list.
+
+Now only valid testcases are created. Testing the response property again we get:
+\begin{lstlisting}
+> proper:quickcheck(
+ proper_output:prop_delete_responds()).
+....(100 dots) .....
+OK: Passed 100 test(s).
+true
+\end{lstlisting}
+
+\section{RESTfull Property Based Testing}
+
+Restfull web services are web services compliant to a few constraints, the main one having to do with state: Each request from any client must contain all the information needed by the service to handle the request. This makes property-based testing of these services relatively easy, since each test is self-contained and does not affect the outcome of other tests.
+
+Let's see the delete example in more depth now.
+
+The answer\_result function shows how to extract the Answer record from the call response. This response is in the form of an erlsom-created record, described in the .hrl file created by the wsdl\_handler. In the .hrl file we see a record:
+\begin{lstlisting}
+-record('p:deleteResponse', {anyAttribs, 'deleteReturn'}).
+\end{lstlisting}
+
+This record is the record that contains the result (when there is no error).In the automatically generated code we can locate this function:
+
+\begin{lstlisting}
+answer_delete({ok, _, [Answer_record]}) -> Answer_record.
+\end{lstlisting}
+
+We see that the 'delete response' is a record containing a 'deleteReturn' value. This 'deleteReturn' value is the boolean we seek; therefore we change the answer function to:
+
+\begin{lstlisting}
+answer_delete({ok, _, [Answer_record]}) ->
+ Answer_record#'p:deleteResponse'.'deleteReturn'.
+\end{lstlisting}
+
+Finally we write our property in a similar form to the respond property:
+
+\begin{lstlisting}
+prop_delete_removes_every_x() ->
+ ?FORALL([_In, [C]]=Args, generate_delete_1(),
+ begin
+ R1 = call_delete(Args),
+ Result = answer_delete(R1),
+ not lists:member(C, Result)
+ end).
+\end{lstlisting}
+
+Now checking this property with proper yields the following results:
+\begin{lstlisting}
+> proper:quickcheck(proper_output:prop_delete_removes_every_x()).
+.......................!
+Failed: After 24 test(s).
+[[92,62,59,97,51,79,76,86,96,75,38,76,51,57,125,37,121,53,57,66,
+67,36,96,89,100,58,38,85,88,121,65,101,106,46,58,32,123,60,
+117,34,106,42,110,127,40,51,75,124,34,94,115,76],[57]]
+
+Shrinking ................................(32 time(s))
+[[32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,32,32,32,33,32,32],[32]]
+false
+\end{lstlisting}
+
+We see that we find after a while a counter-example, however the shrink does not work exactly as the non-web service case. This is mostly because of the different generators used to create these arguments, since the shrinking is now handled differently.
+
+(? Afou to parapanw ginei ascii list logika tha allaksei kai to shrinking behavior tou, twra ofeiletai sto oti to me to ?LET wraper dn kanei shrink parapanw ?)
+
+Now we show another example of testing a RestFul Web Service, to show some limitations of our implementation. Going back to the Cooking service, a simple property that should be valid in it would be if we convert something and then convert the answer back we should get the initial number.
+
+Let's change the answer function and write this property on the output file of the extension:
+
+\begin{lstlisting}
+answer_ChangeCookingUnit({ok, _, [Answer_record]}) ->
+ Answer_record#'p:ChangeCookingUnitResponse'.'ChangeCookingUnitResult'.
+
+prop_back_and_forth_is_equal() ->
+ ?FORALL([Value, From, To] = Args, generate_ChangeCookingUnit_1(),
+ begin
+ Result = call_ChangeCookingUnit(Args),
+ Conv_val = answer_ChangeCookingUnit(Result),
+ Result2 = call_ChangeCookingUnit([Conv_val, To, From]),
+ Initial = answer_ChangeCookingUnit(Result2),
+ Value == Initial
+ end).
+\end{lstlisting}
+
+Basically, we break down the arguments to the sub-elements, invoke the web service, reinvoke the web service with the answer and the other two arguments flipped and compare the result.
+
+Testing this property we receive a (not unexpected) failure:
+
+\begin{lstlisting}
+> proper:quickcheck(proper_output:prop_back_and_forth_is_equal(), 5).
+!
+Failed: After 1 test(s).
+[[45,49,46,54,50,55,56,54,56,51,51,53,48,55,51,56,50,48,55,50,54,57,52,101,45,48,49],[103,97,108,108,111,110,85,75],[116,97,98,108,101,115,112,111,111,110,85,83]]
+
+Shrinking ...(3 time(s))
+[[48,46,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,101,43,48,48],[100,114,111,112],[100,114,111,112]]
+false
+\end{lstlisting}
+
+Basically, it fails to produce the same result even if there is no change! A closer look with a few io:formats will reveal the problem : Floating point arithmetic. The floating point numbers created as arguments by proper are converted to Strings with some error in accuracy and the 2 subsequent calls include even more arithmetical errors. If we change the equality check to a small difference check (keeping in mind that erlsom represented those numbers as strings) we change the property to:
+
+\begin{lstlisting}
+prop_back_and_forth_is_equal() ->
+ ?FORALL([Value, From, To] = Args, generate_ChangeCookingUnit_1(),
+ begin
+ Result = call_ChangeCookingUnit(Args),
+ Conv_val = answer_ChangeCookingUnit(Result),
+ Result2 = call_ChangeCookingUnit([Conv_val, To, From]),
+ Initial = answer_ChangeCookingUnit(Result2),
+ F1 = list_to_float(Value),
+ F2 = list_to_float(Initial),
+ abs(F1 - F2) < 0.000001
+ end).
+\end{lstlisting}
+
+And checking the property now:
+
+\begin{lstlisting}
+8> c(proper_output).
+{ok,proper_output}
+9> proper:quickcheck(proper_output:prop_back_and_forth_is_equal()).
+......( 100 dots) .....
+OK: Passed 100 test(s).
+true
+\end{lstlisting}
+
+\end{document}
View
309 breakurl.sty
@@ -0,0 +1,309 @@
+%%
+%% This is file `breakurl.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% breakurl.dtx (with options: `package')
+%%
+%% This is a generated file.
+%%
+%% Copyright (C) 2005 by Vilar Camara Neto.
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.2 of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.2 or later is part of all distributions of
+%% LaTeX version 1999/12/01 or later.
+%%
+%% Currently this work has the LPPL maintenance status "maintained".
+%%
+%% The Current Maintainer of this work is Vilar Camara Neto.
+%%
+%% This work consists of the files breakurl.dtx and
+%% breakurl.ins and the derived file breakurl.sty.
+%%
+\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+\ProvidesPackage{breakurl}
+ [2009/01/24 v1.30 Breakable hyperref URLs]
+
+
+\RequirePackage{xkeyval}
+\RequirePackage{ifpdf}
+
+\ifpdf
+ % Dummy package options
+ \DeclareOptionX{preserveurlmacro}{}
+ \DeclareOptionX{hyphenbreaks}{}
+ \DeclareOptionX{vertfit}{}
+ \ProcessOptionsX\relax
+
+ \PackageWarning{breakurl}{%
+ You are using breakurl while processing via pdflatex.\MessageBreak
+ \string\burl\space will be just a synonym of \string\url.\MessageBreak}
+ \DeclareRobustCommand{\burl}{\url}
+ \DeclareRobustCommand*{\burlalt}{\hyper@normalise\burl@alt}
+ \def\burl@alt#1#2{\hyper@linkurl{\Hurl{#1}}{#2}}
+ \expandafter\endinput
+\fi
+
+\@ifpackageloaded{hyperref}{}{%
+ \PackageError{breakurl}{The breakurl depends on hyperref package}%
+ {I can't do anything. Please type X <return>, edit the source file%
+ \MessageBreak
+ and add \string\usepackage\string{hyperref\string} before
+ \string\usepackage\string{breakurl\string}.}
+ \endinput
+}
+
+\newif\if@preserveurlmacro\@preserveurlmacrofalse
+\newif\if@burl@fitstrut\@burl@fitstrutfalse
+\newif\if@burl@fitglobal\@burl@fitglobalfalse
+
+\newtoks\burl@toks
+
+\let\burl@charlistbefore\empty
+\let\burl@charlistafter\empty
+
+\def\burl@addtocharlistbefore{\g@addto@macro\burl@charlistbefore}
+\def\burl@addtocharlistafter{\g@addto@macro\burl@charlistafter}
+
+\bgroup
+ \catcode`\&=12\relax
+ \hyper@normalise\burl@addtocharlistbefore{%}
+ \hyper@normalise\burl@addtocharlistafter{:/.?#&_,;!}
+\egroup
+
+\def\burl@growmif#1#2{%
+ \g@addto@macro\burl@mif{\def\burl@ttt{#1}\ifx\burl@ttt\@nextchar#2\else}%
+}
+\def\burl@growmfi{%
+ \g@addto@macro\burl@mfi{\fi}%
+}
+\def\burl@defifstructure{%
+ \let\burl@mif\empty
+ \let\burl@mfi\empty
+ \expandafter\@tfor\expandafter\@nextchar\expandafter:\expandafter=%
+ \burl@charlistbefore\do{%
+ \expandafter\burl@growmif\@nextchar\@burl@breakbeforetrue
+ \burl@growmfi
+ }%
+ \expandafter\@tfor\expandafter\@nextchar\expandafter:\expandafter=%
+ \burl@charlistafter\do{%
+ \expandafter\burl@growmif\@nextchar\@burl@breakaftertrue
+ \burl@growmfi
+ }%
+}
+
+\AtEndOfPackage{\burl@defifstructure}
+
+\def\burl@setvertfit#1{%
+ \lowercase{\def\burl@temp{#1}}%
+ \def\burl@opt{local}\ifx\burl@temp\burl@opt
+ \@burl@fitstrutfalse\@burl@fitglobalfalse
+ \else\def\burl@opt{strut}\ifx\burl@temp\burl@opt
+ \@burl@fitstruttrue\@burl@fitglobalfalse
+ \else\def\burl@opt{global}\ifx\burl@temp\burl@opt
+ \@burl@fitstrutfalse\@burl@fitglobaltrue
+ \else
+ \PackageWarning{breakurl}{Unrecognized vertfit option `\burl@temp'.%
+ \MessageBreak
+ Adopting default `local'}
+ \@burl@fitstrutfalse\@burl@fitglobalfalse
+ \fi\fi\fi
+}
+
+\DeclareOptionX{preserveurlmacro}{\@preserveurlmacrotrue}
+\DeclareOptionX{hyphenbreaks}{%
+ \bgroup
+ \catcode`\&=12\relax
+ \hyper@normalise\burl@addtocharlistafter{-}%
+ \egroup
+}
+\DeclareOptionX{vertfit}[local]{\burl@setvertfit{#1}}
+
+\ProcessOptionsX\relax
+
+\def\burl@hyper@linkurl#1#2{%
+ \begingroup
+ \hyper@chars
+ \burl@condpdflink{#1}%
+ \endgroup
+}
+
+\def\burl@condpdflink#1{%
+ \literalps@out{
+ /burl@bordercolor {\@urlbordercolor} def
+ /burl@border {\@pdfborder} def
+ }%
+ \if@burl@fitstrut
+ \sbox\pdf@box{#1\strut}%
+ \else\if@burl@fitglobal
+ \sbox\pdf@box{\burl@url}%
+ \else
+ \sbox\pdf@box{#1}%
+ \fi\fi
+ \dimen@\ht\pdf@box\dimen@ii\dp\pdf@box
+ \sbox\pdf@box{#1}%
+ \ifdim\dimen@ii=\z@
+ \literalps@out{BU.SS}%
+ \else
+ \lower\dimen@ii\hbox{\literalps@out{BU.SS}}%
+ \fi
+ \ifHy@breaklinks\unhbox\else\box\fi\pdf@box
+ \ifdim\dimen@=\z@
+ \literalps@out{BU.SE}%
+ \else
+ \raise\dimen@\hbox{\literalps@out{BU.SE}}%
+ \fi
+ \pdf@addtoksx{H.B}%
+}
+
+\DeclareRobustCommand*{\burl}{%
+ \leavevmode
+ \begingroup
+ \let\hyper@linkurl=\burl@hyper@linkurl
+ \catcode`\&=12\relax
+ \hyper@normalise\burl@
+}
+
+\DeclareRobustCommand*{\burlalt}{%
+ \begingroup
+ \let\hyper@linkurl=\burl@hyper@linkurl
+ \catcode`\&=12\relax
+ \hyper@normalise\burl@alt
+}
+
+\newif\if@burl@breakbefore
+\newif\if@burl@breakafter
+\newif\if@burl@prevbreakafter
+
+\bgroup
+\catcode`\&=12\relax
+\gdef\burl@#1{%
+ \def\burl@url{#1}%
+ \def\burl@urltext{#1}%
+ \burl@doit
+}
+
+\gdef\burl@alt#1{%
+ \def\burl@url{#1}%
+ \hyper@normalise\burl@@alt
+}
+\gdef\burl@@alt#1{%
+ \def\burl@urltext{#1}%
+ \burl@doit
+}
+
+\gdef\burl@doit{%
+ \burl@toks{}%
+ \let\burl@UrlRight\UrlRight
+ \let\UrlRight\empty
+ \@burl@prevbreakafterfalse
+ \@ifundefined{@urlcolor}{\Hy@colorlink\@linkcolor}{\Hy@colorlink\@urlcolor}%
+ \expandafter\@tfor\expandafter\@nextchar\expandafter:\expandafter=%
+ \burl@urltext\do{%
+ \if@burl@breakafter\@burl@prevbreakaftertrue
+ \else\@burl@prevbreakafterfalse\fi
+ \@burl@breakbeforefalse
+ \@burl@breakafterfalse
+ \expandafter\burl@mif\burl@mfi
+ \if@burl@breakbefore
+ % Breakable if the current char is in the `can break before' list
+ \burl@flush\linebreak[0]%
+ \else
+ \if@burl@prevbreakafter
+ \if@burl@breakafter\else
+ % Breakable if the current char is not in any of the `can break'
+ % lists, but the previous is in the `can break after' list.
+ % This mechanism accounts for sequences of `break after' characters,
+ % where a break is allowed only after the last one
+ \burl@flush\linebreak[0]%
+ \fi
+ \fi
+ \fi
+ \expandafter\expandafter\expandafter\burl@toks
+ \expandafter\expandafter\expandafter{%
+ \expandafter\the\expandafter\burl@toks\@nextchar}%
+ }%
+ \let\UrlRight\burl@UrlRight
+ \burl@flush
+ \literalps@out{BU.E}%
+ \Hy@endcolorlink
+ \endgroup
+}
+\egroup
+
+\def\the@burl@toks{\the\burl@toks}
+
+\def\burl@flush{%
+ \expandafter\def\expandafter\burl@toks@def\expandafter{\the\burl@toks}%
+ \literalps@out{/BU.L (\burl@url) def}%
+ \hyper@linkurl{\expandafter\Hurl\expandafter{\burl@toks@def}}{\burl@url}%
+ \global\burl@toks{}%
+ \let\UrlLeft\empty
+}%
+
+\if@preserveurlmacro\else\let\url\burl\let\urlalt\burlalt\fi
+
+\AtBeginDvi{%
+ \headerps@out{%
+ /burl@stx null def
+ /BU.S {
+ /burl@stx null def
+ } def
+ /BU.SS {
+ currentpoint
+ /burl@lly exch def
+ /burl@llx exch def
+ burl@stx null ne {burl@endx burl@llx ne {BU.FL BU.S} if} if
+ burl@stx null eq {
+ burl@llx dup /burl@stx exch def /burl@endx exch def
+ burl@lly dup /burl@boty exch def /burl@topy exch def
+ } if
+ burl@lly burl@boty gt {/burl@boty burl@lly def} if
+ } def
+ /BU.SE {
+ currentpoint
+ /burl@ury exch def
+ dup /burl@urx exch def /burl@endx exch def
+ burl@ury burl@topy lt {/burl@topy burl@ury def} if
+ } def
+ /BU.E {
+ BU.FL
+ } def
+ /BU.FL {
+ burl@stx null ne {BU.DF} if
+ } def
+ /BU.DF {
+ BU.BB
+ [ /H /I /Border [burl@border] /Color [burl@bordercolor]
+ /Action << /Subtype /URI /URI BU.L >> /Subtype /Link BU.B /ANN pdfmark
+ /burl@stx null def
+ } def
+ /BU.BB {
+ burl@stx HyperBorder sub /burl@stx exch def
+ burl@endx HyperBorder add /burl@endx exch def
+ burl@boty HyperBorder add /burl@boty exch def
+ burl@topy HyperBorder sub /burl@topy exch def
+ } def
+ /BU.B {
+ /Rect[burl@stx burl@boty burl@endx burl@topy]
+ } def
+ /eop where {
+ begin
+ /@ldeopburl /eop load def
+ /eop { SDict begin BU.FL end @ldeopburl } def
+ end
+ } {
+ /eop { SDict begin BU.FL end } def
+ } ifelse
+ }%
+}
+\endinput
+%%
+%% End of file `breakurl.sty'.
View
1,425 eptcs.bst
@@ -0,0 +1,1425 @@
+%%
+%% This is file `eptcs.bst',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% merlin.mbs (with options: `vonx,ed-au,dt-beg,yr-par,xmth,yrp-col,tit-it,atit-u,volp-com,jwdpg,pp-last,num-xser,ser-vol,jnm-x,pre-edn,doi,blknt,pp,xedn,amper,and-xcom,etal-xc,url,url-blk,bibinfo,nfss,')
+%% ----------------------------------------
+%% *** Stylefile for EPTCS ***
+%%
+%% Copyright 1994-2004 Patrick W Daly
+ % ===============================================================
+ % NOTICE:
+ % This bibliographic style (bst) file has been generated from one or
+ % more master bibliographic style (mbs) files, listed above.
+ % Subsequently it has been edited by hand by Rob van Glabbeek
+ %
+ % This file can be redistributed and/or modified under the terms
+ % of the LaTeX Project Public License Distributed from CTAN
+ % archives in directory macros/latex/base/lppl.txt; either
+ % version 1 of the License, or any later version.
+ % ===============================================================
+ % Name and version information of the main mbs file:
+ % \ProvidesFile{merlin.mbs}[2004/02/09 4.13 (PWD, AO, DPC)]
+ % For use with BibTeX version 0.99a or later
+ %-------------------------------------------------------------------
+ % This bibliography style file is intended for texts in ENGLISH
+ % This is a numerical citation style, and as such is standard LaTeX.
+ % It requires no extra package to interface to the main text.
+ % The form of the \bibitem entries is
+ % \bibitem{key}...
+ % Usage of \cite is as follows:
+ % \cite{key} ==>> [#]
+ % \cite[chap. 2]{key} ==>> [#, chap. 2]
+ % where # is a number determined by the ordering in the reference list.
+ % The order in the reference list is alphabetical by authors.
+ %---------------------------------------------------------------------
+
+ENTRY
+ { address
+ author
+ booktitle
+ chapter
+ doi
+ edition
+ editor
+ eid
+ howpublished
+ institution
+ journal
+ key
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ url
+ ee
+ volume
+ year
+ }
+ {}
+ { label }
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+FUNCTION {init.state.consts}
+{ #0 'before.all :=
+ #1 'mid.sentence :=
+ #2 'after.sentence :=
+ #3 'after.block :=
+}
+STRINGS { s t}
+FUNCTION {output.nonnull}
+{ 's :=
+ output.state mid.sentence =
+ { ", " * write$ }
+ { output.state after.block =
+ { add.period$ write$
+ newline$
+ "\newblock " write$
+ }
+ { output.state before.all =
+ 'write$
+ { add.period$ " " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+FUNCTION {output}
+{ duplicate$ empty$
+ 'pop$
+ 'output.nonnull
+ if$
+}
+FUNCTION {output.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+FUNCTION {fin.entry}
+{ add.period$
+ write$
+ newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+ 'skip$
+ { after.block 'output.state := }
+ if$
+}
+FUNCTION {new.sentence}
+{ output.state after.block =
+ 'skip$
+ { output.state before.all =
+ 'skip$
+ { after.sentence 'output.state := }
+ if$
+ }
+ if$
+}
+FUNCTION {add.blank}
+{ " " * before.all 'output.state :=
+}
+
+FUNCTION {date.block}
+{
+ ":" *
+ add.blank
+}
+
+FUNCTION {not}
+{ { #0 }
+ { #1 }
+ if$
+}
+FUNCTION {and}
+{ 'skip$
+ { pop$ #0 }
+ if$
+}
+FUNCTION {or}
+{ { pop$ #1 }
+ 'skip$
+ if$
+}
+FUNCTION {new.block.checka}
+{ empty$
+ 'skip$
+ 'new.block
+ if$
+}
+FUNCTION {new.block.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.block
+ if$
+}
+FUNCTION {new.sentence.checka}
+{ empty$
+ 'skip$
+ 'new.sentence
+ if$
+}
+FUNCTION {new.sentence.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.sentence
+ if$
+}
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+ { pop$ "" }
+ 'skip$
+ if$
+}
+FUNCTION {emphasize}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "\emph{" swap$ * "}" * }
+ if$
+}
+FUNCTION {slant}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "{\sl " swap$ * "}" * }
+ if$
+}
+FUNCTION {tie.or.space.prefix}
+{ duplicate$ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$
+}
+
+FUNCTION {capitalize}
+{ "u" change.case$ "t" change.case$ }
+
+FUNCTION {space.word}
+{ " " swap$ * " " * }
+ % Here are the language-specific definitions for explicit words.
+ % Each function has a name bbl.xxx where xxx is the English word.
+ % The language selected here is ENGLISH
+FUNCTION {bbl.and}
+{ "and"}
+
+FUNCTION {bbl.etal}
+{ "et~al." }
+
+FUNCTION {bbl.editors}
+{ "editors" }
+
+FUNCTION {bbl.editor}
+{ "editor" }
+
+FUNCTION {bbl.edby}
+{ "edited by" }
+
+FUNCTION {bbl.edition}
+{ "edition" }
+
+FUNCTION {bbl.volume}
+{ "" }
+
+FUNCTION {bbl.of}
+{ "of" }
+
+FUNCTION {bbl.nr}
+{ "no." }
+
+FUNCTION {bbl.in}
+{ "in" }
+
+FUNCTION {bbl.pages}
+{ "pp." }
+
+FUNCTION {bbl.page}
+{ "p." }
+
+FUNCTION {bbl.chapter}
+{ "chapter" }
+
+FUNCTION {bbl.techrep}
+{ "Technical Report" }
+
+FUNCTION {bbl.mthesis}
+{ "Master's thesis" }
+
+FUNCTION {bbl.phdthesis}
+{ "Ph.D. thesis" }
+
+MACRO {jan} {"January"}
+
+MACRO {feb} {"February"}
+
+MACRO {mar} {"March"}
+
+MACRO {apr} {"April"}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"June"}
+
+MACRO {jul} {"July"}
+
+MACRO {aug} {"August"}
+
+MACRO {sep} {"September"}
+
+MACRO {oct} {"October"}
+
+MACRO {nov} {"November"}
+
+MACRO {dec} {"December"}
+
+MACRO {acmcs} {"ACM Computing Surveys"}
+
+MACRO {acta} {"Acta Informatica"}
+
+MACRO {cacm} {"Communications of the ACM"}
+
+MACRO {eptcs} {"Electronic Proceedings in Computer Science"}
+
+MACRO {ibmjrd} {"IBM Journal of Research and Development"}
+
+MACRO {ibmsj} {"IBM Systems Journal"}
+
+MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
+
+MACRO {ieeetc} {"IEEE Transactions on Computers"}
+
+MACRO {ieeetcad}
+ {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
+
+MACRO {ipl} {"Information Processing Letters"}
+
+MACRO {jacm} {"Journal of the ACM"}
+
+MACRO {jcss} {"Journal of Computer and System Sciences"}
+
+MACRO {scp} {"Science of Computer Programming"}
+
+MACRO {sicomp} {"SIAM Journal on Computing"}
+
+MACRO {tocs} {"ACM Transactions on Computer Systems"}
+
+MACRO {tods} {"ACM Transactions on Database Systems"}
+
+MACRO {tog} {"ACM Transactions on Graphics"}
+
+MACRO {toms} {"ACM Transactions on Mathematical Software"}
+
+MACRO {toois} {"ACM Transactions on Office Information Systems"}
+
+MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
+
+MACRO {tcs} {"Theoretical Computer Science"}
+FUNCTION {bibinfo.check}
+{ swap$
+ duplicate$ missing$
+ {
+ pop$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ pop$
+ }
+ { swap$
+ "\bibinfo{" swap$ * "}{" * swap$ * "}" *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {bibinfo.warn}
+{ swap$
+ duplicate$ missing$
+ {
+ swap$ "missing " swap$ * " in " * cite$ * warning$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ "empty " swap$ * " in " * cite$ * warning$
+ }
+ { swap$
+ "\bibinfo{" swap$ * "}{" * swap$ * "}" *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {either.or.check}
+{ empty$
+ 'pop$
+ { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+ if$
+}
+FUNCTION {format.ee}
+{ ee empty$
+ { "" }
+ { "\urlprefix\url{" ee * "}" * }
+ if$
+}
+FUNCTION {format.url}
+{ url empty$
+ { format.ee }
+ { "\urlprefix\url{" url * "}" *
+ "ee and url" ee either.or.check
+ }
+ if$
+}
+
+STRINGS { bibinfo}
+INTEGERS { nameptr namesleft numnames }
+
+FUNCTION {format.names}
+{ 'bibinfo :=
+ duplicate$ empty$ 'skip$ {
+ 's :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{ff~}\surnamestart {vv~}{ll}\surnameend{, jj}"
+ format.name$
+ bibinfo bibinfo.check
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal *
+ }
+ {
+ "\&"
+ space.word * t *
+ }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+ } if$
+}
+FUNCTION {format.names.ed}
+{
+ format.names
+}
+FUNCTION {format.authors}
+{ author "author" format.names
+}
+FUNCTION {get.bbl.editor}
+{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ }
+
+FUNCTION {format.editors}
+{ editor "editor" format.names duplicate$ empty$ 'skip$
+ {
+ "," *
+ " " *
+ get.bbl.editor
+ *
+ }
+ if$
+}
+FUNCTION {format.doi}
+{ doi
+ duplicate$ empty$ 'skip$
+ {
+ "\doi{" swap$ * "}" *
+ }
+ if$
+}
+FUNCTION {format.note}
+{
+ note empty$
+ { "" }
+ { note #1 #1 substring$
+ duplicate$ "{" =
+ 'skip$
+ { output.state mid.sentence =
+ { "l" }
+ { "u" }
+ if$
+ change.case$
+ }
+ if$
+ note #2 global.max$ substring$ * "note" bibinfo.check
+ }
+ if$
+}
+
+FUNCTION {format.title}
+{ title
+ "title" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ emphasize
+ }
+ if$
+}
+FUNCTION {output.bibitem}
+{ newline$
+ "\bibitemdeclare{" type$ "}{" cite$ "}" * * * * write$ newline$
+ "\bibitem{" write$
+ cite$ write$
+ "}" write$
+ newline$
+ ""
+ before.all 'output.state :=
+}
+
+FUNCTION {n.dashify}
+{
+ 't :=
+ ""
+ { t empty$ not }
+ { t #1 #1 substring$ "-" =
+ { t #1 #2 substring$ "--" = not
+ { "--" *
+ t #2 global.max$ substring$ 't :=
+ }
+ { { t #1 #1 substring$ "-" = }
+ { "-" *
+ t #2 global.max$ substring$ 't :=
+ }
+ while$
+ }
+ if$
+ }
+ { t #1 #1 substring$ *
+ t #2 global.max$ substring$ 't :=
+ }
+ if$
+ }
+ while$
+}
+
+FUNCTION {word.in}
+{ bbl.in capitalize
+ " " * }
+
+FUNCTION {format.date}
+{
+ ""
+ duplicate$ empty$
+ year "year" bibinfo.check duplicate$ empty$
+ { swap$ 'skip$
+ { "there's a month but no year in " cite$ * warning$ }
+ if$
+ *
+ }
+ { swap$ 'skip$
+ {
+ swap$
+ " " * swap$
+ }
+ if$
+ *
+ }
+ if$
+ duplicate$ empty$
+ 'skip$
+ {
+ before.all 'output.state :=
+ " (" swap$ * ")" *
+ }
+ if$
+}
+FUNCTION {format.btitle}
+{ title "title" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ emphasize
+ }
+ if$
+}
+FUNCTION {volume.or.number}
+{ volume missing$
+ { number }
+ { volume }
+ if$
+}
+FUNCTION {format.volume.number.series}
+{ volume.or.number missing$
+ { series "series" bibinfo.check field.or.null }
+ { series empty$
+ { volume.or.number "volume" bibinfo.check }
+ { volume.or.number tie.or.space.prefix "volume" bibinfo.check *
+ series "series" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { slant swap$ * }
+ if$
+ }
+ if$
+ volume missing$
+ 'skip$
+ { "volume and number" number either.or.check }
+ if$
+ }
+ if$
+}
+FUNCTION {format.edition}
+{ edition duplicate$ empty$ 'skip$
+ {
+ output.state mid.sentence =
+ { "l" }
+ { "t" }
+ if$ change.case$
+ "edition" bibinfo.check
+ " " * bbl.edition *
+ }
+ if$
+}
+INTEGERS { multiresult }
+FUNCTION {multi.page.check}
+{ 't :=
+ #0 'multiresult :=
+ { multiresult not
+ t empty$ not
+ and
+ }
+ { t #1 #1 substring$
+ duplicate$ "-" =
+ swap$ duplicate$ "," =
+ swap$ "+" =
+ or or
+ { #1 'multiresult := }
+ { t #2 global.max$ substring$ 't := }
+ if$
+ }
+ while$
+ multiresult
+}
+FUNCTION {format.pages}
+{ pages duplicate$ empty$ 'skip$
+ { duplicate$ multi.page.check
+ {
+ bbl.pages swap$
+ n.dashify
+ }
+ {
+ bbl.page swap$
+ }
+ if$
+ tie.or.space.prefix
+ "pages" bibinfo.check
+ * *
+ }
+ if$
+}
+FUNCTION {format.journal.pages}
+{ pages duplicate$ empty$ 'pop$
+ { swap$ duplicate$ empty$
+ { pop$ pop$ format.pages }
+ {
+ ", " *
+ swap$
+ n.dashify
+ pages multi.page.check
+ 'bbl.pages
+ 'bbl.page
+ if$
+ swap$ tie.or.space.prefix
+ "pages" bibinfo.check
+ * *
+ *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.journal.eid}
+{ eid "eid" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { swap$ duplicate$ empty$ 'skip$
+ {
+ ":" *
+ }
+ if$
+ swap$ *
+ "eid and pages" pages either.or.check
+ }
+ if$
+}
+FUNCTION {format.vol.num}
+{ volume field.or.null
+ duplicate$ empty$ 'skip$
+ {
+ "volume" bibinfo.check
+ }
+ if$
+ number "number" bibinfo.check duplicate$ empty$ 'skip$
+ {
+ swap$ duplicate$ empty$
+ { "there's a number but no volume in " cite$ * warning$ }
+ 'skip$
+ if$
+ swap$
+ "(" swap$ * ")" *
+ }
+ if$ *
+ duplicate$ empty$ 'skip$
+ {
+ swap$ duplicate$ empty$ 'skip$
+ {
+ " " *
+ }
+ if$ swap$
+ }
+ if$ *
+}
+
+FUNCTION {format.chapter}
+{ chapter empty$
+ { "" }
+ { type empty$
+ { bbl.chapter }
+ { type "l" change.case$
+ "type" bibinfo.check
+ }
+ if$
+ chapter tie.or.space.prefix
+ "chapter" bibinfo.check
+ * *
+ }
+ if$
+}
+
+FUNCTION {format.booktitle}
+{
+ booktitle "booktitle" bibinfo.check
+ slant
+}
+FUNCTION {format.in.ed.booktitle}
+{ format.booktitle duplicate$ empty$ 'skip$
+ { bbl.in capitalize
+ editor "editor" format.names.ed duplicate$ empty$ 'pop$
+ {
+ " " swap$ *
+ ", " *
+ get.bbl.editor *
+ * }
+ if$
+ ": " *
+ swap$ *
+ }
+ if$
+}
+FUNCTION {empty.misc.check}
+{ author empty$ title empty$ howpublished empty$
+ year empty$ note empty$
+ and and and and
+ key empty$ not and
+ { "all relevant fields are empty in " cite$ * warning$ }
+ 'skip$
+ if$
+}
+FUNCTION {format.thesis.type}
+{ type duplicate$ empty$
+ 'pop$
+ { swap$ pop$
+ "t" change.case$ "type" bibinfo.check
+ }
+ if$
+}
+FUNCTION {format.tr.number}
+{ number "number" bibinfo.check
+ type duplicate$ empty$
+ { pop$ bbl.techrep }
+ 'skip$
+ if$
+ "type" bibinfo.check
+ swap$ duplicate$ empty$
+ { pop$ "t" change.case$ }
+ { tie.or.space.prefix * * }
+ if$
+}
+FUNCTION {format.article.crossref}
+{
+ key duplicate$ empty$
+ { pop$
+ journal duplicate$ empty$
+ { "need key or journal for " cite$ * " to crossref " * crossref * warning$ }
+ { "journal" bibinfo.check slant word.in swap$ * }
+ if$
+ }
+ { word.in swap$ * " " *}
+ if$
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.crossref.editor}
+{ editor #1 "{vv~}{ll}" format.name$
+ "editor" bibinfo.check
+ editor num.names$ duplicate$
+ #2 >
+ { pop$
+ " " * bbl.etal
+ *
+ }
+ { #2 <
+ 'skip$
+ { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+ {
+ " " * bbl.etal
+ *
+ }
+ {
+ " \& "
+ * editor #2 "{vv~}{ll}" format.name$
+ "editor" bibinfo.check
+ *
+ }
+ if$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.book.crossref}
+{ volume duplicate$ empty$
+ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+ pop$ word.in
+ }
+ { bbl.volume
+ capitalize
+ swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word *
+ }
+ if$
+ editor empty$
+ editor field.or.null author field.or.null =
+ or
+ { key empty$
+ { series empty$
+ { "need editor, key, or series for " cite$ * " to crossref " *
+ crossref * warning$
+ "" *
+ }
+ { series slant * }
+ if$
+ }
+ { key * }
+ if$
+ }
+ { format.crossref.editor * }
+ if$
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.incoll.inproc.crossref}
+{
+ editor empty$
+ editor field.or.null author field.or.null =
+ or
+ { key empty$
+ { format.booktitle duplicate$ empty$
+ { "need editor, key, or booktitle for " cite$ * " to crossref " *
+ crossref * warning$
+ }
+ { word.in swap$ * }
+ if$
+ }
+ { word.in key * " " *}
+ if$
+ }
+ { word.in format.crossref.editor * " " *}
+ if$
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.org.or.pub}
+{ 't :=
+ ""
+ address empty$ t empty$ and
+ 'skip$
+ {
+ t empty$
+ { address "address" bibinfo.check *
+ }
+ { t *
+ address empty$
+ 'skip$
+ { ", " * address "address" bibinfo.check * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.publisher.address}
+{ publisher "publisher" bibinfo.warn format.org.or.pub
+}
+
+FUNCTION {format.organization.address}
+{ organization "organization" bibinfo.check format.org.or.pub
+}
+
+FUNCTION {article}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ {
+ journal
+ "journal" bibinfo.check
+ slant
+ "journal" output.check
+ format.vol.num
+ }
+ { format.article.crossref output.nonnull
+ }
+ if$
+ eid empty$
+ { format.journal.pages }
+ { format.journal.eid }
+ if$
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+FUNCTION {book}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ crossref missing$
+ { format.edition output
+ new.block
+ format.volume.number.series output
+ format.publisher.address output
+ }
+ {
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+FUNCTION {booklet}
+{ output.bibitem
+ format.authors output
+ format.date output
+ date.block
+ format.title "title" output.check
+ new.block
+ howpublished "howpublished" bibinfo.check output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {inbook}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ crossref missing$
+ {
+ format.edition output
+ format.chapter output
+ format.pages output
+ new.block
+ format.volume.number.series output
+ format.publisher.address output
+ }
+ {
+ format.chapter output
+ format.pages output
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {incollection}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.edition output
+ format.chapter output
+ format.volume.number.series output
+ format.publisher.address output
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.chapter output
+ }
+ if$
+ format.pages "pages" output.check
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+FUNCTION {inproceedings}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.volume.number.series output
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ }
+ if$
+ format.pages "pages" output.check
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+FUNCTION {conference} { inproceedings }
+FUNCTION {manual}
+{ output.bibitem
+ author empty$
+ { organization "organization" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { output
+ address "address" bibinfo.check output
+ }
+ if$
+ }
+ { format.authors output.nonnull }
+ if$
+ format.date output
+ date.block
+ format.btitle "title" output.check
+ format.edition output
+ author empty$
+ { organization empty$
+ {
+ address new.block.checka
+ address "address" bibinfo.check output
+ }
+ 'skip$
+ if$
+ }
+ {
+ organization address new.block.checkb
+ organization "organization" bibinfo.check output
+ address "address" bibinfo.check output
+ }
+ if$
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {mastersthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ bbl.mthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {misc}
+{ output.bibitem
+ format.authors output
+ format.date output
+ output.state before.all =
+ 'skip$
+ {date.block}
+ if$
+ title howpublished new.block.checkb
+ format.title output
+ howpublished new.block.checka
+ howpublished "howpublished" bibinfo.check output
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+ empty.misc.check
+}
+FUNCTION {phdthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ bbl.phdthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {proceedings}
+{ output.bibitem
+ editor empty$
+ { organization "organization" bibinfo.check output
+ }
+ { format.editors output.nonnull }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ editor empty$
+ { publisher empty$
+ { new.sentence format.volume.number.series output }
+ {
+ new.sentence
+ format.volume.number.series output
+ format.publisher.address output
+ }
+ if$
+ }
+ { publisher empty$
+ {
+ new.sentence
+ format.volume.number.series output
+ format.organization.address output }
+ {
+ new.sentence
+ format.volume.number.series output
+ organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ }
+ if$
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {techreport}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date "year" output.check
+ date.block
+ format.title
+ "title" output.check
+ new.block
+ format.tr.number output.nonnull
+ institution "institution" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note output
+ fin.entry
+}
+
+FUNCTION {unpublished}
+{ output.bibitem
+ format.authors "author" output.check
+ format.date output
+ date.block
+ format.title "title" output.check
+ format.doi output
+ new.block
+ format.url output
+ new.block
+ format.note "note" output.check
+ fin.entry
+}
+
+FUNCTION {default.type} { misc }
+READ
+FUNCTION {sortify}
+{ purify$
+ "l" change.case$
+}
+INTEGERS { len }
+FUNCTION {chop.word}
+{ 's :=
+ 'len :=
+ s #1 len substring$ =
+ { s len #1 + global.max$ substring$ }
+ 's
+ if$
+}
+FUNCTION {sort.format.names}
+{ 's :=
+ #1 'nameptr :=
+ ""
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{ll{ }}{ ff{ }}{ jj{ }}"
+ format.name$ 't :=
+ nameptr #1 >
+ {
+ " " *
+ namesleft #1 = t "others" = and
+ { "zzzzz" * }
+ { t sortify * }
+ if$
+ }
+ { t sortify * }
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {sort.format.title}
+{ 't :=
+ "A " #2
+ "An " #3
+ "The " #4 t chop.word
+ chop.word
+ chop.word
+ sortify
+ #1 global.max$ substring$
+}
+FUNCTION {author.sort}
+{ author empty$
+ { key empty$
+ { "to sort, need author or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {author.editor.sort}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { "to sort, need author, editor, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {author.organization.sort}
+{ author empty$
+ { organization empty$
+ { key empty$
+ { "to sort, need author, organization, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { "The " #4 organization chop.word sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {editor.organization.sort}
+{ editor empty$
+ { organization empty$
+ { key empty$
+ { "to sort, need editor, organization, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { "The " #4 organization chop.word sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+}
+FUNCTION {presort}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.sort
+ { type$ "proceedings" =
+ 'editor.organization.sort
+ { type$ "manual" =
+ 'author.organization.sort
+ 'author.sort
+ if$
+ }
+ if$
+ }
+ if$
+ " "
+ *
+ year field.or.null sortify
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+ITERATE {presort}
+SORT
+STRINGS { longest.label }
+INTEGERS { number.label longest.label.width }
+FUNCTION {initialize.longest.label}
+{ "" 'longest.label :=
+ #1 'number.label :=
+ #0 'longest.label.width :=
+}
+FUNCTION {longest.label.pass}
+{ number.label int.to.str$ 'label :=
+ number.label #1 + 'number.label :=
+ label width$ longest.label.width >
+ { label 'longest.label :=
+ label width$ 'longest.label.width :=
+ }
+ 'skip$
+ if$
+}
+EXECUTE {initialize.longest.label}
+ITERATE {longest.label.pass}
+FUNCTION {begin.bib}
+{ preamble$ empty$
+ 'skip$
+ { preamble$ write$ newline$ }
+ if$
+ "\begin{thebibliography}{" longest.label * "}" *
+ write$ newline$
+ "\providecommand{\bibitemdeclare}[2]{}"
+ write$ newline$
+ "\providecommand{\surnamestart}{}"
+ write$ newline$
+ "\providecommand{\surnameend}{}"
+ write$ newline$
+ "\providecommand{\urlprefix}{Available at }"
+ write$ newline$
+ "\providecommand{\url}[1]{\texttt{#1}}"
+ write$ newline$
+ "\providecommand{\href}[2]{\texttt{#2}}"
+ write$ newline$
+ "\providecommand{\urlalt}[2]{\href{#1}{#2}}"
+ write$ newline$
+ "\providecommand{\doi}[1]{doi:\urlalt{http://dx.doi.org/#1}{#1}}"
+ write$ newline$
+ "\providecommand{\bibinfo}[2]{#2}"
+ write$ newline$
+}
+EXECUTE {begin.bib}
+EXECUTE {init.state.consts}
+ITERATE {call.type$}
+FUNCTION {end.bib}
+{ newline$
+ "\end{thebibliography}" write$ newline$
+}
+EXECUTE {end.bib}
+%% End of customized bst file
+%%
+%% End of file `eptcs.bst'.
View
263 eptcs.cls
@@ -0,0 +1,263 @@
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesClass{eptcs}[2010/11/26 v1.5]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% options %%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newif\ifadraft
+\newif\ifsubmission
+\newif\ifpreliminary
+\newif\ifcopyright
+\newif\ifpublicdomain
+\newif\ifcreativecommons
+\newif\ifnoderivs
+\newif\ifsharealike
+\newif\ifnoncommercial
+\adraftfalse
+\submissionfalse
+\preliminaryfalse
+\copyrightfalse
+\publicdomainfalse
+\creativecommonsfalse
+\noderivsfalse
+\sharealikefalse
+\noncommercialfalse
+\DeclareOption{adraft}{\adrafttrue}
+\DeclareOption{submission}{\submissiontrue}
+\DeclareOption{preliminary}{\preliminarytrue}
+\DeclareOption{copyright}{\copyrighttrue}
+\DeclareOption{publicdomain}{\publicdomaintrue}
+\DeclareOption{creativecommons}{\creativecommonstrue}
+\DeclareOption{noderivs}{\noderivstrue}
+\DeclareOption{noncommercial}{\noncommercialtrue}
+\DeclareOption{sharealike}{\sharealiketrue}
+\ProcessOptions\relax
+
+\LoadClass[letterpaper,11pt,twoside]{article}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% On US letter paper the margins (left-top-right-bottom) are %%
+%% 2.795cm - 1.23cm - 2.795cm - 3.46cm %%
+%% Note: When \topmargin would be 0, the real top margin would be %%
+%% (72-25-12=35pt) + 1pt (unused portion of head) = .5in = 1.27cm. %%
+%% The bottom margin is 11in - 1in + 0.04cm - 623/72in = 3.46cm. %%
+%% On the first page the bottom margin contains various footers. %%
+%% When translating from US letter to A4 paper, without scaling, by %%
+%% leaving the centre of the paper invariant (as is possible when %%
+%% printing the paper with acroread), the resulting A4 margins are %%
+%% 2.5cm - 2.11cm - 2.5cm - 4.34cm %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\textwidth 16cm % A4 width is 21cm %
+\textheight 623.01pt % 46 lines exactly = 21.98cm %
+\oddsidemargin -0.04cm % +1 inch = 2.5cm %
+\evensidemargin -0.04cm % +1 inch = 2.5cm %
+\topmargin -0.04cm % +1 inch = 2.5cm %
+\advance\topmargin-\headheight % 12pt %
+\advance\topmargin-\headsep % 25pt %
+\marginparwidth 45pt % leaves 15pt from A4 edge %
+\advance\evensidemargin .295cm % centre w.r.t. letter paper %
+\advance\oddsidemargin .295cm % centre w.r.t. letter paper %
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% load eptcsdata when available %%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\IfFileExists{eptcsdata.tex}{\input{eptcsdata}}{}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Pagestyle and titlepage %%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagestyle{myheadings}
+\renewcommand\pagestyle[1]{} % ignore further \pagestyles
+
+\renewcommand\maketitle{\par
+ \begingroup
+ \providecommand{\event}{}
+ \ifadraft
+ \providecommand{\publicationstatus}{\Large DRAFT\quad\today}
+ \else\ifsubmission
+ \providecommand{\publicationstatus}{Submitted to:\\
+ \event}
+ \else\ifpreliminary
+ \providecommand{\publicationstatus}{Preliminary Report. Final version to appear in:\\
+ \event}
+ \else
+ \providecommand{\publicationstatus}{To appear in EPTCS.}
+ \fi\fi\fi
+ \providecommand{\titlerunning}{Please define {\tt $\backslash$titlerunning}}
+ \providecommand{\authorrunning}{Please define {\tt $\backslash$authorrunning}}
+ \providecommand{\copyrightholders}{\authorrunning}
+ \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
+ \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
+ \long\def\@makefntext##1{\parindent 1em\noindent
+ \hb@xt@1.8em{%
+ \hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
+ \newpage
+ \global\@topnum\z@ % Prevents figures from going at top of page.
+ \@maketitle
+ \thispagestyle{empty}\@thanks
+ \endgroup
+ \setcounter{footnote}{0}%
+ \label{FirstPage}
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\@maketitle\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+ \global\let\@title\@empty
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+}
+\def\@maketitle{% adapted from article.cls
+ \newpage
+\noindent
+\raisebox{-22.8cm}[0pt][0pt]{\footnotesize
+\begin{tabular}{@{}l}
+\publicationstatus
+\end{tabular}}
+\hfill\vspace{-1em}
+\raisebox{-22.8cm}[0pt][0pt]{\footnotesize
+\makebox[0pt][r]{
+\begin{tabular}{l@{}}
+\ifpublicdomain
+ This work is \href{http://creativecommons.org/licenses/publicdomain/}
+ {dedicated to the public domain}.
+\else
+ \ifcopyright
+ \copyright~\copyrightholders\\
+ \fi
+ \ifcreativecommons
+ This work is licensed under the
+ \ifnoncommercial
+ \href{http://creativecommons.org}{Creative Commons}\\
+ \ifnoderivs
+ \href{http://creativecommons.org/licenses/by-nc-nd/3.0/}
+ {Attribution-Noncommercial-No Derivative Works} License.
+ \else\ifsharealike
+ \href{http://creativecommons.org/licenses/by-nc-sa/3.0/}
+ {Attribution-Noncommercial-Share Alike} License.
+ \else
+ \href{http://creativecommons.org/licenses/by-nc/3.0/}
+ {Attribution-Noncommercial} License.
+ \fi\fi
+ \else
+ \ifnoderivs
+ \href{http://creativecommons.org}{Creative Commons}\\
+ \href{http://creativecommons.org/licenses/by-nd/3.0/}
+ {Attribution-No Derivative Works} License.
+ \else\ifsharealike
+ \href{http://creativecommons.org}{Creative Commons}\\
+ \href{http://creativecommons.org/licenses/by-sa/3.0/}
+ {Attribution-Share Alike} License.
+ \else
+ \\\href{http://creativecommons.org}{Creative Commons}
+ \href{http://creativecommons.org/licenses/by/3.0/}
+ {Attribution} License.
+ \fi\fi
+ \fi
+ \fi
+\fi
+\end{tabular}}}
+ \null
+ %\vskip 2em% a bit of space removed (< 2em)
+ \begin{center}%
+ \let \footnote \thanks
+ {\LARGE\bf \@title \par}% \bf added
+ \vskip 2em% was: 1.5em
+ {\large
+ \lineskip .5em%
+ \begin{tabular}[t]{c}%
+ \@author
+ \end{tabular}\par}%
+ \vskip 1em% \date and extra space removed
+ \end{center}%
+ \par
+ \markboth{\hfill\titlerunning}{\authorrunning\hfill}
+ \vskip .5em}
+
+\AtBeginDocument{
+ \providecommand{\firstpage}{1}
+ \setcounter{firstpage}{\firstpage}
+ \setcounter{page}{\firstpage}
+ \@ifpackageloaded{array}% Contributed by Wolfgang Jeltsch
+ {\newcommand{\IfArrayPackageLoaded}[2]{#1}}
+ {\newcommand{\IfArrayPackageLoaded}[2]{#2}}}
+\newcommand{\institute}[1]{\IfArrayPackageLoaded
+ {\\{\scriptsize\begin{tabular}[t]{@{}>{\footnotesize}c@{}}#1\end{tabular}}}
+ {\\{\scriptsize\begin{tabular}[t]{@{\footnotesize}c@{}}#1\end{tabular}}}}
+\newcommand{\email}[1]{\\{\footnotesize\tt #1}}
+
+\renewenvironment{abstract}{\begin{list}{}% header removed and noindent
+ {\rightmargin\leftmargin
+ \listparindent 1.5em
+ \parsep 0pt plus 1pt}
+ \small\item}{\end{list}
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage{hyperref} % add hyperlinks
+\RequirePackage{mathptmx} % Pick Times Roman as a base font
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Remember page numbers %%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newcounter{firstpage}
+\setcounter{firstpage}{1}
+\AtEndDocument{\clearpage
+ \addtocounter{page}{-1}
+ \immediate\write\@auxout{\string
+ \newlabel{LastPage}{{}{\thepage}{}{page.\thepage}{}}}%
+ \newwrite\pages
+ \immediate\openout\pages=\jobname.pag
+ \immediate\write\pages{\arabic{firstpage}-\arabic{page}}
+ \addtocounter{page}{1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% Less space in lists %%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\@listi{\leftmargin\leftmargini
+ \parsep 2.5\p@ \@plus1.5\p@ \@minus\p@
+ \topsep 5\p@ \@plus2\p@ \@minus5\p@
+ \itemsep2.5\p@ \@plus1.5\p@ \@minus\p@}
+\let\@listI\@listi
+\@listi
+\def\@listii {\leftmargin\leftmarginii
+ \labelwidth\leftmarginii
+ \advance\labelwidth-\labelsep
+ \topsep 1\p@ \@plus\p@ \@minus\p@
+ \parsep 1\p@ \@plus\p@ \@minus\p@
+ \itemsep \parsep}
+\def\@listiii{\leftmargin\leftmarginiii
+ \labelwidth\leftmarginiii
+ \advance\labelwidth-\labelsep
+ \topsep \z@
+ \parsep \z@
+ \itemsep \topsep}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% References small and with less space between items %%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewenvironment{thebibliography}[1]
+ {\section*{\refname}\small% small added
+ \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}}%
+ \sloppy
+ \clubpenalty4000
+ \@clubpenalty \clubpenalty
+ \widowpenalty4000%
+ \sfcode`\.\@m
+ \setlength{\parskip}{0pt}%
+ \setlength{\itemsep}{3pt plus 2pt}% less space between items
+ }
+ {\def\@noitemerr
+ {\@latex@warning{Empty `thebibliography' environment}}%
+ \endlist}

0 comments on commit 8e4c810

Please sign in to comment.